<?xml version="1.0"?>

<!--
   Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
  -->

<document>

  <properties>
    <title>Apache Commons Statistics</title>
  </properties>

  <body>

    <section name="Apache Commons Statistics" href="summary">
      <p>
        Apache Commons Statistics provides utilities for statistical applications.
      </p>


      <p>
        Descriptive statistics can be computed on array data or using the Java Stream API,
        for example:
      </p>

<source class="prettyprint">
int[] values = {1, 1, 2, 3, 5, 8, 13, 21};
double v = IntVariance.of(values).getAsDouble();   // 49.929

// A builder for specified statistics to allow
// parallel computation on a stream of values
IntStatistics.Builder builder = IntStatistics.builder(
    Statistic.MIN, Statistic.MAX, Statistic.MEAN);
IntStatistics stats =
    Stream.of("one", "two", "three", "four")
    .parallel()
    .mapToInt(String::length)
    .collect(builder::build, IntConsumer::accept, IntStatistics::combine);

stats.getAsInt(Statistic.MIN);       // 3
stats.getAsInt(Statistic.MAX);       // 5
stats.getAsDouble(Statistic.MEAN);   // 15.0 / 4
</source>

      <p>
        Support is provided for commonly used continuous and discrete distributions,
        for example:
      </p>

<source class="prettyprint">
TDistribution t = TDistribution.of(29);
double lowerTail = t.cumulativeProbability(-2.656);   // P(T(29) &lt;= -2.656)
double upperTail = t.survivalProbability(2.75);       // P(T(29) &gt; 2.75)

PoissonDistribution p = PoissonDistribution.of(4.56);
int x = p.inverseCumulativeProbability(0.99);
</source>

      <p>
        Hypothesis testing can be performed for various statistical tests, for example:
      </p>

<source class="prettyprint">
double[] math    = {53, 69, 65, 65, 67, 79, 86, 65, 62, 69};   // mean = 68.0
double[] science = {75, 65, 68, 63, 55, 65, 73, 45, 51, 52};   // mean = 61.2

SignificanceResult result = TTest.withDefaults()
                                 .with(AlternativeHypothesis.GREATER_THAN)
                                 .pairedTest(math, science);
result.getPValue();    // 0.05764
result.reject(0.05);   // false
</source>

      <p>
        For more examples and advanced usage, see the <a href="userguide/index.html">userguide</a>.
      </p>

    </section>

    <section name="Download Apache Commons Statistics">
      <subsection name="Releases">
        <p>
          Download the
          <a href="https://commons.apache.org/statistics/download_statistics.cgi">
            latest release</a> of Apache Commons Statistics.
        </p>
      </subsection>
    </section>

  </body>

</document>
