TTest.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.stat.inference;

  22. import org.hipparchus.distribution.continuous.TDistribution;
  23. import org.hipparchus.exception.LocalizedCoreFormats;
  24. import org.hipparchus.exception.MathIllegalArgumentException;
  25. import org.hipparchus.exception.MathIllegalStateException;
  26. import org.hipparchus.exception.NullArgumentException;
  27. import org.hipparchus.stat.LocalizedStatFormats;
  28. import org.hipparchus.stat.StatUtils;
  29. import org.hipparchus.stat.descriptive.StatisticalSummary;
  30. import org.hipparchus.util.FastMath;
  31. import org.hipparchus.util.MathUtils;

  32. /**
  33.  * An implementation for Student's t-tests.
  34.  * <p>
  35.  * Tests can be:
  36.  * <ul>
  37.  * <li>One-sample or two-sample</li>
  38.  * <li>One-sided or two-sided</li>
  39.  * <li>Paired or unpaired (for two-sample tests)</li>
  40.  * <li>Homoscedastic (equal variance assumption) or heteroscedastic
  41.  * (for two sample tests)</li>
  42.  * <li>Fixed significance level (boolean-valued) or returning p-values.</li>
  43.  * </ul>
  44.  * <p>
  45.  * Test statistics are available for all tests.  Methods including "Test" in
  46.  * in their names perform tests, all other methods return t-statistics.  Among
  47.  * the "Test" methods, <code>double-</code>valued methods return p-values;
  48.  * <code>boolean-</code>valued methods perform fixed significance level tests.
  49.  * Significance levels are always specified as numbers between 0 and 0.5
  50.  * (e.g. tests at the 95% level  use <code>alpha=0.05</code>).
  51.  * <p>
  52.  * Input to tests can be either <code>double[]</code> arrays or
  53.  * {@link StatisticalSummary} instances.
  54.  * <p>
  55.  * Uses Hipparchus {@link org.hipparchus.distribution.continuous.TDistribution}
  56.  * implementation to estimate exact p-values.
  57.  */
  58. public class TTest { // NOPMD - this is not a Junit test class, PMD false positive here

  59.     /** Empty constructor.
  60.      * <p>
  61.      * This constructor is not strictly necessary, but it prevents spurious
  62.      * javadoc warnings with JDK 18 and later.
  63.      * </p>
  64.      * @since 3.0
  65.      */
  66.     public TTest() { // NOPMD - unnecessary constructor added intentionally to make javadoc happy
  67.         // nothing to do
  68.     }

  69.     /**
  70.      * Computes a paired, 2-sample t-statistic based on the data in the input
  71.      * arrays.  The t-statistic returned is equivalent to what would be returned by
  72.      * computing the one-sample t-statistic {@link #t(double, double[])}, with
  73.      * <code>mu = 0</code> and the sample array consisting of the (signed)
  74.      * differences between corresponding entries in <code>sample1</code> and
  75.      * <code>sample2.</code>
  76.      * <p>* <strong>Preconditions</strong>:</p>
  77.      * <ul>
  78.      * <li>The input arrays must have the same length and their common length
  79.      * must be at least 2.
  80.      * </li></ul>
  81.      *
  82.      * @param sample1 array of sample data values
  83.      * @param sample2 array of sample data values
  84.      * @return t statistic
  85.      * @throws NullArgumentException if the arrays are <code>null</code>
  86.      * @throws MathIllegalArgumentException if the arrays are empty
  87.      * @throws MathIllegalArgumentException if the length of the arrays is not equal
  88.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  89.      */
  90.     public double pairedT(final double[] sample1, final double[] sample2)
  91.         throws MathIllegalArgumentException, NullArgumentException {

  92.         checkSampleData(sample1);
  93.         checkSampleData(sample2);
  94.         double meanDifference = StatUtils.meanDifference(sample1, sample2);
  95.         return t(meanDifference, 0,
  96.                  StatUtils.varianceDifference(sample1, sample2, meanDifference),
  97.                  sample1.length);
  98.     }

  99.     /**
  100.      * Returns the <i>observed significance level</i>, or
  101.      * <i> p-value</i>, associated with a paired, two-sample, two-tailed t-test
  102.      * based on the data in the input arrays.
  103.      * <p>
  104.      * The number returned is the smallest significance level
  105.      * at which one can reject the null hypothesis that the mean of the paired
  106.      * differences is 0 in favor of the two-sided alternative that the mean paired
  107.      * difference is not equal to 0. For a one-sided test, divide the returned
  108.      * value by 2.</p>
  109.      * <p>
  110.      * This test is equivalent to a one-sample t-test computed using
  111.      * {@link #tTest(double, double[])} with <code>mu = 0</code> and the sample
  112.      * array consisting of the signed differences between corresponding elements of
  113.      * <code>sample1</code> and <code>sample2.</code></p>
  114.      * <p>
  115.      * <strong>Usage Note:</strong><br>
  116.      * The validity of the p-value depends on the assumptions of the parametric
  117.      * t-test procedure, as discussed
  118.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  119.      * here</a></p>
  120.      * <p><strong>Preconditions</strong>:</p>
  121.      * <ul>
  122.      * <li>The input array lengths must be the same and their common length must
  123.      * be at least 2.
  124.      * </li></ul>
  125.      *
  126.      * @param sample1 array of sample data values
  127.      * @param sample2 array of sample data values
  128.      * @return p-value for t-test
  129.      * @throws NullArgumentException if the arrays are <code>null</code>
  130.      * @throws MathIllegalArgumentException if the arrays are empty
  131.      * @throws MathIllegalArgumentException if the length of the arrays is not equal
  132.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  133.      * @throws MathIllegalStateException if an error occurs computing the p-value
  134.      */
  135.     public double pairedTTest(final double[] sample1, final double[] sample2)
  136.         throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {

  137.         double meanDifference = StatUtils.meanDifference(sample1, sample2);
  138.         return tTest(meanDifference, 0,
  139.                 StatUtils.varianceDifference(sample1, sample2, meanDifference),
  140.                 sample1.length);
  141.     }

  142.     /**
  143.      * Performs a paired t-test evaluating the null hypothesis that the
  144.      * mean of the paired differences between <code>sample1</code> and
  145.      * <code>sample2</code> is 0 in favor of the two-sided alternative that the
  146.      * mean paired difference is not equal to 0, with significance level
  147.      * <code>alpha</code>.
  148.      * <p>
  149.      * Returns <code>true</code> iff the null hypothesis can be rejected with
  150.      * confidence <code>1 - alpha</code>.  To perform a 1-sided test, use
  151.      * <code>alpha * 2</code></p>
  152.      * <p>
  153.      * <strong>Usage Note:</strong><br>
  154.      * The validity of the test depends on the assumptions of the parametric
  155.      * t-test procedure, as discussed
  156.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  157.      * here</a></p>
  158.      * <p><strong>Preconditions</strong>:</p>
  159.      * <ul>
  160.      * <li>The input array lengths must be the same and their common length
  161.      * must be at least 2.
  162.      * </li>
  163.      * <li> <code> 0 &lt; alpha &lt; 0.5 </code>
  164.      * </li></ul>
  165.      *
  166.      * @param sample1 array of sample data values
  167.      * @param sample2 array of sample data values
  168.      * @param alpha significance level of the test
  169.      * @return true if the null hypothesis can be rejected with
  170.      * confidence 1 - alpha
  171.      * @throws NullArgumentException if the arrays are <code>null</code>
  172.      * @throws MathIllegalArgumentException if the arrays are empty
  173.      * @throws MathIllegalArgumentException if the length of the arrays is not equal
  174.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  175.      * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
  176.      * @throws MathIllegalStateException if an error occurs computing the p-value
  177.      */
  178.     public boolean pairedTTest(final double[] sample1, final double[] sample2,
  179.                                final double alpha)
  180.         throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {

  181.         checkSignificanceLevel(alpha);
  182.         return pairedTTest(sample1, sample2) < alpha;

  183.     }

  184.     /**
  185.      * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula">
  186.      * t statistic </a> given observed values and a comparison constant.
  187.      * <p>
  188.      * This statistic can be used to perform a one sample t-test for the mean.
  189.      * </p>
  190.      * <p><strong>Preconditions</strong>:</p>
  191.      * <ul>
  192.      * <li>The observed array length must be at least 2.
  193.      * </li></ul>
  194.      *
  195.      * @param mu comparison constant
  196.      * @param observed array of values
  197.      * @return t statistic
  198.      * @throws NullArgumentException if <code>observed</code> is <code>null</code>
  199.      * @throws MathIllegalArgumentException if the length of <code>observed</code> is &lt; 2
  200.      */
  201.     public double t(final double mu, final double[] observed)
  202.         throws MathIllegalArgumentException, NullArgumentException {

  203.         checkSampleData(observed);
  204.         // No try-catch or advertised exception because args have just been checked
  205.         return t(StatUtils.mean(observed), mu, StatUtils.variance(observed),
  206.                  observed.length);
  207.     }

  208.     /**
  209.      * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula">
  210.      * t statistic </a> to use in comparing the mean of the dataset described by
  211.      * <code>sampleStats</code> to <code>mu</code>.
  212.      * <p>
  213.      * This statistic can be used to perform a one sample t-test for the mean.
  214.      * </p>
  215.      * <p><strong>Preconditions</strong>:</p>
  216.      * <ul>
  217.      * <li><code>observed.getN() &ge; 2</code>.
  218.      * </li></ul>
  219.      *
  220.      * @param mu comparison constant
  221.      * @param sampleStats DescriptiveStatistics holding sample summary statitstics
  222.      * @return t statistic
  223.      * @throws NullArgumentException if <code>sampleStats</code> is <code>null</code>
  224.      * @throws MathIllegalArgumentException if the number of samples is &lt; 2
  225.      */
  226.     public double t(final double mu, final StatisticalSummary sampleStats)
  227.         throws MathIllegalArgumentException, NullArgumentException {

  228.         checkSampleData(sampleStats);
  229.         return t(sampleStats.getMean(), mu, sampleStats.getVariance(),
  230.                  sampleStats.getN());
  231.     }

  232.     /**
  233.      * Computes a 2-sample t statistic,  under the hypothesis of equal
  234.      * subpopulation variances.  To compute a t-statistic without the
  235.      * equal variances hypothesis, use {@link #t(double[], double[])}.
  236.      * <p>
  237.      * This statistic can be used to perform a (homoscedastic) two-sample
  238.      * t-test to compare sample means.</p>
  239.      * <p>
  240.      * The t-statistic is</p>
  241.      * <p>
  242.      * &nbsp;&nbsp;<code>  t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code>
  243.      * </p><p>
  244.      * where <strong><code>n1</code></strong> is the size of first sample;
  245.      * <strong><code> n2</code></strong> is the size of second sample;
  246.      * <strong><code> m1</code></strong> is the mean of first sample;
  247.      * <strong><code> m2</code></strong> is the mean of second sample
  248.      * and <strong><code>var</code></strong> is the pooled variance estimate:
  249.      * </p><p>
  250.      * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code>
  251.      * </p><p>
  252.      * with <strong><code>var1</code></strong> the variance of the first sample and
  253.      * <strong><code>var2</code></strong> the variance of the second sample.
  254.      * </p>
  255.      * <p><strong>Preconditions</strong>:</p>
  256.      * <ul>
  257.      * <li>The observed array lengths must both be at least 2.
  258.      * </li></ul>
  259.      *
  260.      * @param sample1 array of sample data values
  261.      * @param sample2 array of sample data values
  262.      * @return t statistic
  263.      * @throws NullArgumentException if the arrays are <code>null</code>
  264.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  265.      */
  266.     public double homoscedasticT(final double[] sample1, final double[] sample2)
  267.         throws MathIllegalArgumentException, NullArgumentException {

  268.         checkSampleData(sample1);
  269.         checkSampleData(sample2);
  270.         // No try-catch or advertised exception because args have just been checked
  271.         return homoscedasticT(StatUtils.mean(sample1), StatUtils.mean(sample2),
  272.                               StatUtils.variance(sample1), StatUtils.variance(sample2),
  273.                               sample1.length, sample2.length);
  274.     }

  275.     /**
  276.      * Computes a 2-sample t statistic, without the hypothesis of equal
  277.      * subpopulation variances.  To compute a t-statistic assuming equal
  278.      * variances, use {@link #homoscedasticT(double[], double[])}.
  279.      * <p>
  280.      * This statistic can be used to perform a two-sample t-test to compare
  281.      * sample means.</p>
  282.      * <p>
  283.      * The t-statistic is</p>
  284.      * <p>
  285.      * &nbsp;&nbsp; <code>  t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code>
  286.      * </p><p>
  287.      *  where <strong><code>n1</code></strong> is the size of the first sample
  288.      * <strong><code> n2</code></strong> is the size of the second sample;
  289.      * <strong><code> m1</code></strong> is the mean of the first sample;
  290.      * <strong><code> m2</code></strong> is the mean of the second sample;
  291.      * <strong><code> var1</code></strong> is the variance of the first sample;
  292.      * <strong><code> var2</code></strong> is the variance of the second sample;
  293.      * </p>
  294.      * <p><strong>Preconditions</strong>:</p>
  295.      * <ul>
  296.      * <li>The observed array lengths must both be at least 2.
  297.      * </li></ul>
  298.      *
  299.      * @param sample1 array of sample data values
  300.      * @param sample2 array of sample data values
  301.      * @return t statistic
  302.      * @throws NullArgumentException if the arrays are <code>null</code>
  303.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  304.      */
  305.     public double t(final double[] sample1, final double[] sample2)
  306.         throws MathIllegalArgumentException, NullArgumentException {

  307.         checkSampleData(sample1);
  308.         checkSampleData(sample2);
  309.         // No try-catch or advertised exception because args have just been checked
  310.         return t(StatUtils.mean(sample1), StatUtils.mean(sample2),
  311.                  StatUtils.variance(sample1), StatUtils.variance(sample2),
  312.                  sample1.length, sample2.length);
  313.     }

  314.     /**
  315.      * Computes a 2-sample t statistic, comparing the means of the datasets
  316.      * described by two {@link StatisticalSummary} instances, without the
  317.      * assumption of equal subpopulation variances.  Use
  318.      * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to
  319.      * compute a t-statistic under the equal variances assumption.
  320.      * <p>
  321.      * This statistic can be used to perform a two-sample t-test to compare
  322.      * sample means.</p>
  323.      * <p>
  324.       * The returned  t-statistic is</p>
  325.      * <p>
  326.      * &nbsp;&nbsp; <code>  t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code>
  327.      * </p><p>
  328.      * where <strong><code>n1</code></strong> is the size of the first sample;
  329.      * <strong><code> n2</code></strong> is the size of the second sample;
  330.      * <strong><code> m1</code></strong> is the mean of the first sample;
  331.      * <strong><code> m2</code></strong> is the mean of the second sample
  332.      * <strong><code> var1</code></strong> is the variance of the first sample;
  333.      * <strong><code> var2</code></strong> is the variance of the second sample
  334.      * </p>
  335.      * <p><strong>Preconditions</strong>:</p>
  336.      * <ul>
  337.      * <li>The datasets described by the two Univariates must each contain
  338.      * at least 2 observations.
  339.      * </li></ul>
  340.      *
  341.      * @param sampleStats1 StatisticalSummary describing data from the first sample
  342.      * @param sampleStats2 StatisticalSummary describing data from the second sample
  343.      * @return t statistic
  344.      * @throws NullArgumentException if the sample statistics are <code>null</code>
  345.      * @throws MathIllegalArgumentException if the number of samples is &lt; 2
  346.      */
  347.     public double t(final StatisticalSummary sampleStats1,
  348.                     final StatisticalSummary sampleStats2)
  349.         throws MathIllegalArgumentException, NullArgumentException {

  350.         checkSampleData(sampleStats1);
  351.         checkSampleData(sampleStats2);
  352.         return t(sampleStats1.getMean(), sampleStats2.getMean(),
  353.                  sampleStats1.getVariance(), sampleStats2.getVariance(),
  354.                  sampleStats1.getN(), sampleStats2.getN());
  355.     }

  356.     /**
  357.      * Computes a 2-sample t statistic, comparing the means of the datasets
  358.      * described by two {@link StatisticalSummary} instances, under the
  359.      * assumption of equal subpopulation variances.  To compute a t-statistic
  360.      * without the equal variances assumption, use
  361.      * {@link #t(StatisticalSummary, StatisticalSummary)}.
  362.      * <p>
  363.      * This statistic can be used to perform a (homoscedastic) two-sample
  364.      * t-test to compare sample means.</p>
  365.      * <p>
  366.      * The t-statistic returned is</p>
  367.      * <p>
  368.      * &nbsp;&nbsp;<code>  t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code>
  369.      * </p><p>
  370.      * where <strong><code>n1</code></strong> is the size of first sample;
  371.      * <strong><code> n2</code></strong> is the size of second sample;
  372.      * <strong><code> m1</code></strong> is the mean of first sample;
  373.      * <strong><code> m2</code></strong> is the mean of second sample
  374.      * and <strong><code>var</code></strong> is the pooled variance estimate:
  375.      * </p><p>
  376.      * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code>
  377.      * </p><p>
  378.      * with <strong><code>var1</code></strong> the variance of the first sample and
  379.      * <strong><code>var2</code></strong> the variance of the second sample.
  380.      * </p>
  381.      * <p><strong>Preconditions</strong>:</p>
  382.      * <ul>
  383.      * <li>The datasets described by the two Univariates must each contain
  384.      * at least 2 observations.
  385.      * </li></ul>
  386.      *
  387.      * @param sampleStats1 StatisticalSummary describing data from the first sample
  388.      * @param sampleStats2 StatisticalSummary describing data from the second sample
  389.      * @return t statistic
  390.      * @throws NullArgumentException if the sample statistics are <code>null</code>
  391.      * @throws MathIllegalArgumentException if the number of samples is &lt; 2
  392.      */
  393.     public double homoscedasticT(final StatisticalSummary sampleStats1,
  394.                                  final StatisticalSummary sampleStats2)
  395.         throws MathIllegalArgumentException, NullArgumentException {

  396.         checkSampleData(sampleStats1);
  397.         checkSampleData(sampleStats2);
  398.         return homoscedasticT(sampleStats1.getMean(), sampleStats2.getMean(),
  399.                               sampleStats1.getVariance(), sampleStats2.getVariance(),
  400.                               sampleStats1.getN(), sampleStats2.getN());
  401.     }

  402.     /**
  403.      * Returns the <i>observed significance level</i>, or
  404.      * <i>p-value</i>, associated with a one-sample, two-tailed t-test
  405.      * comparing the mean of the input array with the constant <code>mu</code>.
  406.      * <p>
  407.      * The number returned is the smallest significance level
  408.      * at which one can reject the null hypothesis that the mean equals
  409.      * <code>mu</code> in favor of the two-sided alternative that the mean
  410.      * is different from <code>mu</code>. For a one-sided test, divide the
  411.      * returned value by 2.</p>
  412.      * <p>
  413.      * <strong>Usage Note:</strong><br>
  414.      * The validity of the test depends on the assumptions of the parametric
  415.      * t-test procedure, as discussed
  416.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a>
  417.      * </p>
  418.      * <p><strong>Preconditions</strong>:</p>
  419.      * <ul>
  420.      * <li>The observed array length must be at least 2.
  421.      * </li></ul>
  422.      *
  423.      * @param mu constant value to compare sample mean against
  424.      * @param sample array of sample data values
  425.      * @return p-value
  426.      * @throws NullArgumentException if the sample array is <code>null</code>
  427.      * @throws MathIllegalArgumentException if the length of the array is &lt; 2
  428.      * @throws MathIllegalStateException if an error occurs computing the p-value
  429.      */
  430.     public double tTest(final double mu, final double[] sample)
  431.         throws MathIllegalArgumentException, NullArgumentException,
  432.         MathIllegalStateException {

  433.         checkSampleData(sample);
  434.         // No try-catch or advertised exception because args have just been checked
  435.         return tTest(StatUtils.mean(sample), mu, StatUtils.variance(sample),
  436.                      sample.length);
  437.     }

  438.     /**
  439.      * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
  440.      * two-sided t-test</a> evaluating the null hypothesis that the mean of the population from
  441.      * which <code>sample</code> is drawn equals <code>mu</code>.
  442.      * <p>
  443.      * Returns <code>true</code> iff the null hypothesis can be
  444.      * rejected with confidence <code>1 - alpha</code>.  To
  445.      * perform a 1-sided test, use <code>alpha * 2</code></p>
  446.      * <p>* <strong>Examples:</strong></p>
  447.      * <ol>
  448.      * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
  449.      * the 95% level, use <br><code>tTest(mu, sample, 0.05) </code>
  450.      * </li>
  451.      * <li>To test the (one-sided) hypothesis <code> sample mean &lt; mu </code>
  452.      * at the 99% level, first verify that the measured sample mean is less
  453.      * than <code>mu</code> and then use
  454.      * <br><code>tTest(mu, sample, 0.02) </code>
  455.      * </li></ol>
  456.      * <p>
  457.      * <strong>Usage Note:</strong><br>
  458.      * The validity of the test depends on the assumptions of the one-sample
  459.      * parametric t-test procedure, as discussed
  460.      * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a>
  461.      * </p>
  462.      * <p><strong>Preconditions</strong>:</p>
  463.      * <ul>
  464.      * <li>The observed array length must be at least 2.
  465.      * </li></ul>
  466.      *
  467.      * @param mu constant value to compare sample mean against
  468.      * @param sample array of sample data values
  469.      * @param alpha significance level of the test
  470.      * @return p-value
  471.      * @throws NullArgumentException if the sample array is <code>null</code>
  472.      * @throws MathIllegalArgumentException if the length of the array is &lt; 2
  473.      * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
  474.      * @throws MathIllegalStateException if an error computing the p-value
  475.      */
  476.     public boolean tTest(final double mu, final double[] sample, final double alpha)
  477.         throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {

  478.         checkSignificanceLevel(alpha);
  479.         return tTest(mu, sample) < alpha;
  480.     }

  481.     /**
  482.      * Returns the <i>observed significance level</i>, or
  483.      * <i>p-value</i>, associated with a one-sample, two-tailed t-test
  484.      * comparing the mean of the dataset described by <code>sampleStats</code>
  485.      * with the constant <code>mu</code>.
  486.      * <p>
  487.      * The number returned is the smallest significance level
  488.      * at which one can reject the null hypothesis that the mean equals
  489.      * <code>mu</code> in favor of the two-sided alternative that the mean
  490.      * is different from <code>mu</code>. For a one-sided test, divide the
  491.      * returned value by 2.</p>
  492.      * <p>
  493.      * <strong>Usage Note:</strong><br>
  494.      * The validity of the test depends on the assumptions of the parametric
  495.      * t-test procedure, as discussed
  496.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  497.      * here</a></p>
  498.      * <p><strong>Preconditions</strong>:</p>
  499.      * <ul>
  500.      * <li>The sample must contain at least 2 observations.
  501.      * </li></ul>
  502.      *
  503.      * @param mu constant value to compare sample mean against
  504.      * @param sampleStats StatisticalSummary describing sample data
  505.      * @return p-value
  506.      * @throws NullArgumentException if <code>sampleStats</code> is <code>null</code>
  507.      * @throws MathIllegalArgumentException if the number of samples is &lt; 2
  508.      * @throws MathIllegalStateException if an error occurs computing the p-value
  509.      */
  510.     public double tTest(final double mu, final StatisticalSummary sampleStats)
  511.         throws MathIllegalArgumentException, NullArgumentException,
  512.         MathIllegalStateException {

  513.         checkSampleData(sampleStats);
  514.         return tTest(sampleStats.getMean(), mu, sampleStats.getVariance(),
  515.                      sampleStats.getN());
  516.     }

  517.     /**
  518.      * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
  519.      * two-sided t-test</a> evaluating the null hypothesis that the mean of the
  520.      * population from which the dataset described by <code>stats</code> is
  521.      * drawn equals <code>mu</code>.
  522.      * <p>
  523.      * Returns <code>true</code> iff the null hypothesis can be rejected with
  524.      * confidence <code>1 - alpha</code>.  To  perform a 1-sided test, use
  525.      * <code>alpha * 2.</code></p>
  526.      * <p>* <strong>Examples:</strong></p>
  527.      * <ol>
  528.      * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
  529.      * the 95% level, use <br><code>tTest(mu, sampleStats, 0.05) </code>
  530.      * </li>
  531.      * <li>To test the (one-sided) hypothesis <code> sample mean &lt; mu </code>
  532.      * at the 99% level, first verify that the measured sample mean is less
  533.      * than <code>mu</code> and then use
  534.      * <br><code>tTest(mu, sampleStats, 0.02) </code>
  535.      * </li></ol>
  536.      * <p>
  537.      * <strong>Usage Note:</strong><br>
  538.      * The validity of the test depends on the assumptions of the one-sample
  539.      * parametric t-test procedure, as discussed
  540.      * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a>
  541.      * </p>
  542.      * <p><strong>Preconditions</strong>:</p>
  543.      * <ul>
  544.      * <li>The sample must include at least 2 observations.
  545.      * </li></ul>
  546.      *
  547.      * @param mu constant value to compare sample mean against
  548.      * @param sampleStats StatisticalSummary describing sample data values
  549.      * @param alpha significance level of the test
  550.      * @return p-value
  551.      * @throws NullArgumentException if <code>sampleStats</code> is <code>null</code>
  552.      * @throws MathIllegalArgumentException if the number of samples is &lt; 2
  553.      * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
  554.      * @throws MathIllegalStateException if an error occurs computing the p-value
  555.      */
  556.     public boolean tTest(final double mu, final StatisticalSummary sampleStats,
  557.                          final double alpha)
  558.         throws MathIllegalArgumentException, NullArgumentException,
  559.                MathIllegalStateException {

  560.         checkSignificanceLevel(alpha);
  561.         return tTest(mu, sampleStats) < alpha;
  562.     }

  563.     /**
  564.      * Returns the <i>observed significance level</i>, or
  565.      * <i>p-value</i>, associated with a two-sample, two-tailed t-test
  566.      * comparing the means of the input arrays.
  567.      * <p>
  568.      * The number returned is the smallest significance level
  569.      * at which one can reject the null hypothesis that the two means are
  570.      * equal in favor of the two-sided alternative that they are different.
  571.      * For a one-sided test, divide the returned value by 2.</p>
  572.      * <p>
  573.      * The test does not assume that the underlying popuation variances are
  574.      * equal  and it uses approximated degrees of freedom computed from the
  575.      * sample data to compute the p-value.  The t-statistic used is as defined in
  576.      * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation
  577.      * to the degrees of freedom is used,
  578.      * as described
  579.      * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
  580.      * here.</a>  To perform the test under the assumption of equal subpopulation
  581.      * variances, use {@link #homoscedasticTTest(double[], double[])}.</p>
  582.      * <p>
  583.      * <strong>Usage Note:</strong><br>
  584.      * The validity of the p-value depends on the assumptions of the parametric
  585.      * t-test procedure, as discussed
  586.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  587.      * here</a></p>
  588.      * <p><strong>Preconditions</strong>:</p>
  589.      * <ul>
  590.      * <li>The observed array lengths must both be at least 2.
  591.      * </li></ul>
  592.      *
  593.      * @param sample1 array of sample data values
  594.      * @param sample2 array of sample data values
  595.      * @return p-value for t-test
  596.      * @throws NullArgumentException if the arrays are <code>null</code>
  597.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  598.      * @throws MathIllegalStateException if an error occurs computing the p-value
  599.      */
  600.     public double tTest(final double[] sample1, final double[] sample2)
  601.         throws MathIllegalArgumentException, NullArgumentException,
  602.                MathIllegalStateException {

  603.         checkSampleData(sample1);
  604.         checkSampleData(sample2);
  605.         // No try-catch or advertised exception because args have just been checked
  606.         return tTest(StatUtils.mean(sample1), StatUtils.mean(sample2),
  607.                      StatUtils.variance(sample1), StatUtils.variance(sample2),
  608.                      sample1.length, sample2.length);
  609.     }

  610.     /**
  611.      * Returns the <i>observed significance level</i>, or
  612.      * <i>p-value</i>, associated with a two-sample, two-tailed t-test
  613.      * comparing the means of the input arrays, under the assumption that
  614.      * the two samples are drawn from subpopulations with equal variances.
  615.      * To perform the test without the equal variances assumption, use
  616.      * {@link #tTest(double[], double[])}.
  617.      * <p>
  618.      * The number returned is the smallest significance level
  619.      * at which one can reject the null hypothesis that the two means are
  620.      * equal in favor of the two-sided alternative that they are different.
  621.      * For a one-sided test, divide the returned value by 2.</p>
  622.      * <p>
  623.      * A pooled variance estimate is used to compute the t-statistic.  See
  624.      * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes
  625.      * minus 2 is used as the degrees of freedom.</p>
  626.      * <p>
  627.      * <strong>Usage Note:</strong><br>
  628.      * The validity of the p-value depends on the assumptions of the parametric
  629.      * t-test procedure, as discussed
  630.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  631.      * here</a></p>
  632.      * <p><strong>Preconditions</strong>:</p>
  633.      * <ul>
  634.      * <li>The observed array lengths must both be at least 2.
  635.      * </li></ul>
  636.      *
  637.      * @param sample1 array of sample data values
  638.      * @param sample2 array of sample data values
  639.      * @return p-value for t-test
  640.      * @throws NullArgumentException if the arrays are <code>null</code>
  641.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  642.      * @throws MathIllegalStateException if an error occurs computing the p-value
  643.      */
  644.     public double homoscedasticTTest(final double[] sample1, final double[] sample2)
  645.         throws MathIllegalArgumentException, NullArgumentException,
  646.         MathIllegalStateException {

  647.         checkSampleData(sample1);
  648.         checkSampleData(sample2);
  649.         // No try-catch or advertised exception because args have just been checked
  650.         return homoscedasticTTest(StatUtils.mean(sample1),
  651.                                   StatUtils.mean(sample2),
  652.                                   StatUtils.variance(sample1),
  653.                                   StatUtils.variance(sample2),
  654.                                   sample1.length, sample2.length);
  655.     }

  656.     /**
  657.      * Performs a
  658.      * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
  659.      * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code>
  660.      * and <code>sample2</code> are drawn from populations with the same mean,
  661.      * with significance level <code>alpha</code>.  This test does not assume
  662.      * that the subpopulation variances are equal.  To perform the test assuming
  663.      * equal variances, use
  664.      * {@link #homoscedasticTTest(double[], double[], double)}.
  665.      * <p>
  666.      * Returns <code>true</code> iff the null hypothesis that the means are
  667.      * equal can be rejected with confidence <code>1 - alpha</code>.  To
  668.      * perform a 1-sided test, use <code>alpha * 2</code></p>
  669.      * <p>
  670.      * See {@link #t(double[], double[])} for the formula used to compute the
  671.      * t-statistic.  Degrees of freedom are approximated using the
  672.      * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
  673.      * Welch-Satterthwaite approximation.</a></p>
  674.      * <p>* <strong>Examples:</strong></p>
  675.      * <ol>
  676.      * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
  677.      * the 95% level,  use
  678.      * <br><code>tTest(sample1, sample2, 0.05). </code>
  679.      * </li>
  680.      * <li>To test the (one-sided) hypothesis <code> mean 1 &lt; mean 2 </code>,
  681.      * at the 99% level, first verify that the measured  mean of <code>sample 1</code>
  682.      * is less than the mean of <code>sample 2</code> and then use
  683.      * <br><code>tTest(sample1, sample2, 0.02) </code>
  684.      * </li></ol>
  685.      * <p>
  686.      * <strong>Usage Note:</strong><br>
  687.      * The validity of the test depends on the assumptions of the parametric
  688.      * t-test procedure, as discussed
  689.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  690.      * here</a></p>
  691.      * <p><strong>Preconditions</strong>:</p>
  692.      * <ul>
  693.      * <li>The observed array lengths must both be at least 2.
  694.      * </li>
  695.      * <li> <code> 0 &lt; alpha &lt; 0.5 </code>
  696.      * </li></ul>
  697.      *
  698.      * @param sample1 array of sample data values
  699.      * @param sample2 array of sample data values
  700.      * @param alpha significance level of the test
  701.      * @return true if the null hypothesis can be rejected with
  702.      * confidence 1 - alpha
  703.      * @throws NullArgumentException if the arrays are <code>null</code>
  704.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  705.      * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
  706.      * @throws MathIllegalStateException if an error occurs computing the p-value
  707.      */
  708.     public boolean tTest(final double[] sample1, final double[] sample2,
  709.                          final double alpha)
  710.         throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {

  711.         checkSignificanceLevel(alpha);
  712.         return tTest(sample1, sample2) < alpha;
  713.     }

  714.     /**
  715.      * Performs a
  716.      * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
  717.      * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code>
  718.      * and <code>sample2</code> are drawn from populations with the same mean,
  719.      * with significance level <code>alpha</code>,  assuming that the
  720.      * subpopulation variances are equal.  Use
  721.      * {@link #tTest(double[], double[], double)} to perform the test without
  722.      * the assumption of equal variances.
  723.      * <p>
  724.      * Returns <code>true</code> iff the null hypothesis that the means are
  725.      * equal can be rejected with confidence <code>1 - alpha</code>.  To
  726.      * perform a 1-sided test, use <code>alpha * 2.</code>  To perform the test
  727.      * without the assumption of equal subpopulation variances, use
  728.      * {@link #tTest(double[], double[], double)}.</p>
  729.      * <p>
  730.      * A pooled variance estimate is used to compute the t-statistic. See
  731.      * {@link #t(double[], double[])} for the formula. The sum of the sample
  732.      * sizes minus 2 is used as the degrees of freedom.</p>
  733.      * <p><strong>Examples:</strong></p>
  734.      * <ol>
  735.      * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
  736.      * the 95% level, use <br><code>tTest(sample1, sample2, 0.05). </code>
  737.      * </li>
  738.      * <li>To test the (one-sided) hypothesis <code> mean 1 &lt; mean 2, </code>
  739.      * at the 99% level, first verify that the measured mean of
  740.      * <code>sample 1</code> is less than the mean of <code>sample 2</code>
  741.      * and then use
  742.      * <br><code>tTest(sample1, sample2, 0.02) </code>
  743.      * </li></ol>
  744.      * <p>
  745.      * <strong>Usage Note:</strong><br>
  746.      * The validity of the test depends on the assumptions of the parametric
  747.      * t-test procedure, as discussed
  748.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  749.      * here</a></p>
  750.      * <p><strong>Preconditions</strong>:</p>
  751.      * <ul>
  752.      * <li>The observed array lengths must both be at least 2.
  753.      * </li>
  754.      * <li> <code> 0 &lt; alpha &lt; 0.5 </code>
  755.      * </li></ul>
  756.      *
  757.      * @param sample1 array of sample data values
  758.      * @param sample2 array of sample data values
  759.      * @param alpha significance level of the test
  760.      * @return true if the null hypothesis can be rejected with
  761.      * confidence 1 - alpha
  762.      * @throws NullArgumentException if the arrays are <code>null</code>
  763.      * @throws MathIllegalArgumentException if the length of the arrays is &lt; 2
  764.      * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
  765.      * @throws MathIllegalStateException if an error occurs computing the p-value
  766.      */
  767.     public boolean homoscedasticTTest(final double[] sample1, final double[] sample2,
  768.                                       final double alpha)
  769.         throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {

  770.         checkSignificanceLevel(alpha);
  771.         return homoscedasticTTest(sample1, sample2) < alpha;
  772.     }

  773.     /**
  774.      * Returns the <i>observed significance level</i>, or
  775.      * <i>p-value</i>, associated with a two-sample, two-tailed t-test
  776.      * comparing the means of the datasets described by two StatisticalSummary
  777.      * instances.
  778.      * <p>
  779.      * The number returned is the smallest significance level
  780.      * at which one can reject the null hypothesis that the two means are
  781.      * equal in favor of the two-sided alternative that they are different.
  782.      * For a one-sided test, divide the returned value by 2.</p>
  783.      * <p>
  784.      * The test does not assume that the underlying population variances are
  785.      * equal  and it uses approximated degrees of freedom computed from the
  786.      * sample data to compute the p-value.   To perform the test assuming
  787.      * equal variances, use
  788.      * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.</p>
  789.      * <p>
  790.      * <strong>Usage Note:</strong><br>
  791.      * The validity of the p-value depends on the assumptions of the parametric
  792.      * t-test procedure, as discussed
  793.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  794.      * here</a></p>
  795.      * <p><strong>Preconditions</strong>:</p>
  796.      * <ul>
  797.      * <li>The datasets described by the two Univariates must each contain
  798.      * at least 2 observations.
  799.      * </li></ul>
  800.      *
  801.      * @param sampleStats1  StatisticalSummary describing data from the first sample
  802.      * @param sampleStats2  StatisticalSummary describing data from the second sample
  803.      * @return p-value for t-test
  804.      * @throws NullArgumentException if the sample statistics are <code>null</code>
  805.      * @throws MathIllegalArgumentException if the number of samples is &lt; 2
  806.      * @throws MathIllegalStateException if an error occurs computing the p-value
  807.      */
  808.     public double tTest(final StatisticalSummary sampleStats1,
  809.                         final StatisticalSummary sampleStats2)
  810.         throws MathIllegalArgumentException, NullArgumentException,
  811.         MathIllegalStateException {

  812.         checkSampleData(sampleStats1);
  813.         checkSampleData(sampleStats2);
  814.         return tTest(sampleStats1.getMean(), sampleStats2.getMean(),
  815.                      sampleStats1.getVariance(), sampleStats2.getVariance(),
  816.                      sampleStats1.getN(), sampleStats2.getN());
  817.     }

  818.     /**
  819.      * Returns the <i>observed significance level</i>, or
  820.      * <i>p-value</i>, associated with a two-sample, two-tailed t-test
  821.      * comparing the means of the datasets described by two StatisticalSummary
  822.      * instances, under the hypothesis of equal subpopulation variances. To
  823.      * perform a test without the equal variances assumption, use
  824.      * {@link #tTest(StatisticalSummary, StatisticalSummary)}.
  825.      * <p>
  826.      * The number returned is the smallest significance level
  827.      * at which one can reject the null hypothesis that the two means are
  828.      * equal in favor of the two-sided alternative that they are different.
  829.      * For a one-sided test, divide the returned value by 2.</p>
  830.      * <p>
  831.      * See {@link #homoscedasticT(double[], double[])} for the formula used to
  832.      * compute the t-statistic. The sum of the  sample sizes minus 2 is used as
  833.      * the degrees of freedom.</p>
  834.      * <p>
  835.      * <strong>Usage Note:</strong><br>
  836.      * The validity of the p-value depends on the assumptions of the parametric
  837.      * t-test procedure, as discussed
  838.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a>
  839.      * </p><p><strong>Preconditions</strong>:</p>
  840.      * <ul>
  841.      * <li>The datasets described by the two Univariates must each contain
  842.      * at least 2 observations.
  843.      * </li></ul>
  844.      *
  845.      * @param sampleStats1  StatisticalSummary describing data from the first sample
  846.      * @param sampleStats2  StatisticalSummary describing data from the second sample
  847.      * @return p-value for t-test
  848.      * @throws NullArgumentException if the sample statistics are <code>null</code>
  849.      * @throws MathIllegalArgumentException if the number of samples is &lt; 2
  850.      * @throws MathIllegalStateException if an error occurs computing the p-value
  851.      */
  852.     public double homoscedasticTTest(final StatisticalSummary sampleStats1,
  853.                                      final StatisticalSummary sampleStats2)
  854.         throws MathIllegalArgumentException, NullArgumentException,
  855.         MathIllegalStateException {

  856.         checkSampleData(sampleStats1);
  857.         checkSampleData(sampleStats2);
  858.         return homoscedasticTTest(sampleStats1.getMean(),
  859.                                   sampleStats2.getMean(),
  860.                                   sampleStats1.getVariance(),
  861.                                   sampleStats2.getVariance(),
  862.                                   sampleStats1.getN(), sampleStats2.getN());
  863.     }

  864.     /**
  865.      * Performs a
  866.      * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
  867.      * two-sided t-test</a> evaluating the null hypothesis that
  868.      * <code>sampleStats1</code> and <code>sampleStats2</code> describe
  869.      * datasets drawn from populations with the same mean, with significance
  870.      * level <code>alpha</code>.   This test does not assume that the
  871.      * subpopulation variances are equal.  To perform the test under the equal
  872.      * variances assumption, use
  873.      * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.
  874.      * <p>
  875.      * Returns <code>true</code> iff the null hypothesis that the means are
  876.      * equal can be rejected with confidence <code>1 - alpha</code>.  To
  877.      * perform a 1-sided test, use <code>alpha * 2</code></p>
  878.      * <p>
  879.      * See {@link #t(double[], double[])} for the formula used to compute the
  880.      * t-statistic.  Degrees of freedom are approximated using the
  881.      * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
  882.      * Welch-Satterthwaite approximation.</a></p>
  883.      * <p>* <strong>Examples:</strong></p>
  884.      * <ol>
  885.      * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
  886.      * the 95%, use
  887.      * <br><code>tTest(sampleStats1, sampleStats2, 0.05) </code>
  888.      * </li>
  889.      * <li>To test the (one-sided) hypothesis <code> mean 1 &lt; mean 2 </code>
  890.      * at the 99% level,  first verify that the measured mean of
  891.      * <code>sample 1</code> is less than  the mean of <code>sample 2</code>
  892.      * and then use
  893.      * <br><code>tTest(sampleStats1, sampleStats2, 0.02) </code>
  894.      * </li></ol>
  895.      * <p>
  896.      * <strong>Usage Note:</strong><br>
  897.      * The validity of the test depends on the assumptions of the parametric
  898.      * t-test procedure, as discussed
  899.      * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
  900.      * here</a></p>
  901.      * <p><strong>Preconditions</strong>:</p>
  902.      * <ul>
  903.      * <li>The datasets described by the two Univariates must each contain
  904.      * at least 2 observations.
  905.      * </li>
  906.      * <li> <code> 0 &lt; alpha &lt; 0.5 </code>
  907.      * </li></ul>
  908.      *
  909.      * @param sampleStats1 StatisticalSummary describing sample data values
  910.      * @param sampleStats2 StatisticalSummary describing sample data values
  911.      * @param alpha significance level of the test
  912.      * @return true if the null hypothesis can be rejected with
  913.      * confidence 1 - alpha
  914.      * @throws NullArgumentException if the sample statistics are <code>null</code>
  915.      * @throws MathIllegalArgumentException if the number of samples is &lt; 2
  916.      * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
  917.      * @throws MathIllegalStateException if an error occurs computing the p-value
  918.      */
  919.     public boolean tTest(final StatisticalSummary sampleStats1,
  920.                          final StatisticalSummary sampleStats2,
  921.                          final double alpha)
  922.         throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {

  923.         checkSignificanceLevel(alpha);
  924.         return tTest(sampleStats1, sampleStats2) < alpha;
  925.     }

  926.     //----------------------------------------------- Protected methods

  927.     /**
  928.      * Computes approximate degrees of freedom for 2-sample t-test.
  929.      *
  930.      * @param v1 first sample variance
  931.      * @param v2 second sample variance
  932.      * @param n1 first sample n
  933.      * @param n2 second sample n
  934.      * @return approximate degrees of freedom
  935.      */
  936.     protected double df(double v1, double v2, double n1, double n2) {
  937.         return (((v1 / n1) + (v2 / n2)) * ((v1 / n1) + (v2 / n2))) /
  938.         ((v1 * v1) / (n1 * n1 * (n1 - 1d)) + (v2 * v2) /
  939.                 (n2 * n2 * (n2 - 1d)));
  940.     }

  941.     /**
  942.      * Computes t test statistic for 1-sample t-test.
  943.      *
  944.      * @param m sample mean
  945.      * @param mu constant to test against
  946.      * @param v sample variance
  947.      * @param n sample n
  948.      * @return t test statistic
  949.      */
  950.     protected double t(final double m, final double mu,
  951.                        final double v, final double n) {
  952.         return (m - mu) / FastMath.sqrt(v / n);
  953.     }

  954.     /**
  955.      * Computes t test statistic for 2-sample t-test.
  956.      * <p>
  957.      * Does not assume that subpopulation variances are equal.</p>
  958.      *
  959.      * @param m1 first sample mean
  960.      * @param m2 second sample mean
  961.      * @param v1 first sample variance
  962.      * @param v2 second sample variance
  963.      * @param n1 first sample n
  964.      * @param n2 second sample n
  965.      * @return t test statistic
  966.      */
  967.     protected double t(final double m1, final double m2,
  968.                        final double v1, final double v2,
  969.                        final double n1, final double n2)  {
  970.         return (m1 - m2) / FastMath.sqrt((v1 / n1) + (v2 / n2));
  971.     }

  972.     /**
  973.      * Computes t test statistic for 2-sample t-test under the hypothesis
  974.      * of equal subpopulation variances.
  975.      *
  976.      * @param m1 first sample mean
  977.      * @param m2 second sample mean
  978.      * @param v1 first sample variance
  979.      * @param v2 second sample variance
  980.      * @param n1 first sample n
  981.      * @param n2 second sample n
  982.      * @return t test statistic
  983.      */
  984.     protected double homoscedasticT(final double m1, final double m2,
  985.                                     final double v1, final double v2,
  986.                                     final double n1, final double n2)  {
  987.         final double pooledVariance = ((n1  - 1) * v1 + (n2 -1) * v2 ) / (n1 + n2 - 2);
  988.         return (m1 - m2) / FastMath.sqrt(pooledVariance * (1d / n1 + 1d / n2));
  989.     }

  990.     /**
  991.      * Computes p-value for 2-sided, 1-sample t-test.
  992.      *
  993.      * @param m sample mean
  994.      * @param mu constant to test against
  995.      * @param v sample variance
  996.      * @param n sample n
  997.      * @return p-value
  998.      * @throws MathIllegalStateException if an error occurs computing the p-value
  999.      * @throws MathIllegalArgumentException if n is not greater than 1
  1000.      */
  1001.     protected double tTest(final double m, final double mu,
  1002.                            final double v, final double n)
  1003.         throws MathIllegalArgumentException, MathIllegalStateException {

  1004.         final double t = FastMath.abs(t(m, mu, v, n));
  1005.         final TDistribution distribution = new TDistribution( n - 1);
  1006.         return 2.0 * distribution.cumulativeProbability(-t);

  1007.     }

  1008.     /**
  1009.      * Computes p-value for 2-sided, 2-sample t-test.
  1010.      * <p>
  1011.      * Does not assume subpopulation variances are equal. Degrees of freedom
  1012.      * are estimated from the data.</p>
  1013.      *
  1014.      * @param m1 first sample mean
  1015.      * @param m2 second sample mean
  1016.      * @param v1 first sample variance
  1017.      * @param v2 second sample variance
  1018.      * @param n1 first sample n
  1019.      * @param n2 second sample n
  1020.      * @return p-value
  1021.      * @throws MathIllegalStateException if an error occurs computing the p-value
  1022.      * @throws MathIllegalArgumentException if the estimated degrees of freedom is not
  1023.      * strictly positive
  1024.      */
  1025.     protected double tTest(final double m1, final double m2,
  1026.                            final double v1, final double v2,
  1027.                            final double n1, final double n2)
  1028.         throws MathIllegalArgumentException, MathIllegalStateException {

  1029.         final double t = FastMath.abs(t(m1, m2, v1, v2, n1, n2));
  1030.         final double degreesOfFreedom = df(v1, v2, n1, n2);
  1031.         final TDistribution distribution = new TDistribution(degreesOfFreedom);
  1032.         return 2.0 * distribution.cumulativeProbability(-t);

  1033.     }

  1034.     /**
  1035.      * Computes p-value for 2-sided, 2-sample t-test, under the assumption
  1036.      * of equal subpopulation variances.
  1037.      * <p>
  1038.      * The sum of the sample sizes minus 2 is used as degrees of freedom.</p>
  1039.      *
  1040.      * @param m1 first sample mean
  1041.      * @param m2 second sample mean
  1042.      * @param v1 first sample variance
  1043.      * @param v2 second sample variance
  1044.      * @param n1 first sample n
  1045.      * @param n2 second sample n
  1046.      * @return p-value
  1047.      * @throws MathIllegalStateException if an error occurs computing the p-value
  1048.      * @throws MathIllegalArgumentException if the estimated degrees of freedom is not
  1049.      * strictly positive
  1050.      */
  1051.     protected double homoscedasticTTest(double m1, double m2,
  1052.                                         double v1, double v2,
  1053.                                         double n1, double n2)
  1054.         throws MathIllegalArgumentException, MathIllegalStateException {

  1055.         final double t = FastMath.abs(homoscedasticT(m1, m2, v1, v2, n1, n2));
  1056.         final double degreesOfFreedom = n1 + n2 - 2;
  1057.         final TDistribution distribution = new TDistribution(degreesOfFreedom);
  1058.         return 2.0 * distribution.cumulativeProbability(-t);

  1059.     }

  1060.     /**
  1061.      * Check significance level.
  1062.      *
  1063.      * @param alpha significance level
  1064.      * @throws MathIllegalArgumentException if the significance level is out of bounds.
  1065.      */
  1066.     private void checkSignificanceLevel(final double alpha)
  1067.         throws MathIllegalArgumentException {

  1068.         if (alpha <= 0 || alpha > 0.5) {
  1069.             throw new MathIllegalArgumentException(LocalizedStatFormats.SIGNIFICANCE_LEVEL,
  1070.                                           alpha, 0.0, 0.5);
  1071.         }

  1072.     }

  1073.     /**
  1074.      * Check sample data.
  1075.      *
  1076.      * @param data Sample data.
  1077.      * @throws NullArgumentException if {@code data} is {@code null}.
  1078.      * @throws MathIllegalArgumentException if there is not enough sample data.
  1079.      */
  1080.     private void checkSampleData(final double[] data)
  1081.         throws MathIllegalArgumentException, NullArgumentException {

  1082.         MathUtils.checkNotNull(data, LocalizedCoreFormats.INPUT_ARRAY);
  1083.         if (data.length < 2) {
  1084.             throw new MathIllegalArgumentException(
  1085.                     LocalizedStatFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC,
  1086.                     data.length, 2, true);
  1087.         }

  1088.     }

  1089.     /**
  1090.      * Check sample data.
  1091.      *
  1092.      * @param stat Statistical summary.
  1093.      * @throws NullArgumentException if {@code data} is {@code null}.
  1094.      * @throws MathIllegalArgumentException if there is not enough sample data.
  1095.      */
  1096.     private void checkSampleData(final StatisticalSummary stat)
  1097.         throws MathIllegalArgumentException, NullArgumentException {

  1098.         MathUtils.checkNotNull(stat);
  1099.         if (stat.getN() < 2) {
  1100.             throw new MathIllegalArgumentException(
  1101.                     LocalizedStatFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC,
  1102.                     stat.getN(), 2, true);
  1103.         }

  1104.     }

  1105. }