diff --git a/src/main/java/org/apache/commons/math/stat/inference/TTest.java b/src/main/java/org/apache/commons/math/stat/inference/TTest.java index bfdf4da21..4d611fe39 100644 --- a/src/main/java/org/apache/commons/math/stat/inference/TTest.java +++ b/src/main/java/org/apache/commons/math/stat/inference/TTest.java @@ -16,11 +16,20 @@ */ package org.apache.commons.math.stat.inference; -import org.apache.commons.math.MathException; +import org.apache.commons.math.distribution.TDistribution; +import org.apache.commons.math.exception.DimensionMismatchException; +import org.apache.commons.math.exception.MaxCountExceededException; +import org.apache.commons.math.exception.NoDataException; +import org.apache.commons.math.exception.NullArgumentException; +import org.apache.commons.math.exception.NumberIsTooSmallException; +import org.apache.commons.math.exception.OutOfRangeException; +import org.apache.commons.math.exception.util.LocalizedFormats; +import org.apache.commons.math.stat.StatUtils; import org.apache.commons.math.stat.descriptive.StatisticalSummary; +import org.apache.commons.math.util.FastMath; /** - * An interface for Student's t-tests. + * An implementation for Student's t-tests. *

* Tests can be:

* * @param sample1 array of sample data values @@ -131,14 +165,23 @@ public interface TTest { * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha - * @throws IllegalArgumentException if the preconditions are not met - * @throws MathException if an error occurs performing the test + * @throws NullArgumentException if the arrays are null + * @throws NoDataException if the arrays are empty + * @throws DimensionMismatchException if the length of the arrays is not equal + * @throws NumberIsTooSmallException if the length of the arrays is < 2 + * @throws OutOfRangeException if alpha is not in the range (0, 0.5] + * @throws MaxCountExceededException if an error occurs computing the p-value */ - boolean pairedTTest( - double[] sample1, - double[] sample2, - double alpha) - throws IllegalArgumentException, MathException; + public boolean pairedTTest(final double[] sample1, final double[] sample2, + final double alpha) + throws NullArgumentException, NoDataException, DimensionMismatchException, + NumberIsTooSmallException, OutOfRangeException, MaxCountExceededException { + + checkSignificanceLevel(alpha); + return pairedTTest(sample1, sample2) < alpha; + + } + /** * Computes a * t statistic given observed values and a comparison constant. @@ -152,10 +195,18 @@ public interface TTest { * @param mu comparison constant * @param observed array of values * @return t statistic - * @throws IllegalArgumentException if input array length is less than 2 + * @throws NullArgumentException if observed is null + * @throws NumberIsTooSmallException if the length of observed is < 2 */ - double t(double mu, double[] observed) - throws IllegalArgumentException; + public double t(final double mu, final double[] observed) + throws NullArgumentException, NumberIsTooSmallException { + + checkSampleData(observed); + return t(StatUtils.mean(observed), mu, StatUtils.variance(observed), + observed.length); + + } + /** * Computes a * t statistic to use in comparing the mean of the dataset described by @@ -164,16 +215,24 @@ public interface TTest { * This statistic can be used to perform a one sample t-test for the mean. *

* Preconditions:

* * @param mu comparison constant * @param sampleStats DescriptiveStatistics holding sample summary statitstics * @return t statistic - * @throws IllegalArgumentException if the precondition is not met + * @throws NullArgumentException if sampleStats is null + * @throws NumberIsTooSmallException if the number of samples is < 2 */ - double t(double mu, StatisticalSummary sampleStats) - throws IllegalArgumentException; + public double t(final double mu, final StatisticalSummary sampleStats) + throws NullArgumentException, NumberIsTooSmallException { + + checkSampleData(sampleStats); + return t(sampleStats.getMean(), mu, sampleStats.getVariance(), + sampleStats.getN()); + + } + /** * Computes a 2-sample t statistic, under the hypothesis of equal * subpopulation variances. To compute a t-statistic without the @@ -182,7 +241,7 @@ public interface TTest { * This statistic can be used to perform a (homoscedastic) two-sample * t-test to compare sample means.

*

- * The t-statisitc is

+ * The t-statistic is

*

*    t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var)) *

@@ -205,10 +264,20 @@ public interface TTest { * @param sample1 array of sample data values * @param sample2 array of sample data values * @return t statistic - * @throws IllegalArgumentException if the precondition is not met + * @throws NullArgumentException if the arrays are null + * @throws NumberIsTooSmallException if the length of the arrays is < 2 */ - double homoscedasticT(double[] sample1, double[] sample2) - throws IllegalArgumentException; + public double homoscedasticT(final double[] sample1, final double[] sample2) + throws NullArgumentException, NumberIsTooSmallException { + + checkSampleData(sample1); + checkSampleData(sample2); + return homoscedasticT(StatUtils.mean(sample1), StatUtils.mean(sample2), + StatUtils.variance(sample1), StatUtils.variance(sample2), + sample1.length, sample2.length); + + } + /** * Computes a 2-sample t statistic, without the hypothesis of equal * subpopulation variances. To compute a t-statistic assuming equal @@ -217,7 +286,7 @@ public interface TTest { * This statistic can be used to perform a two-sample t-test to compare * sample means.

*

- * The t-statisitc is

+ * The t-statistic is

*

*    t = (m1 - m2) / sqrt(var1/n1 + var2/n2) *

@@ -235,10 +304,20 @@ public interface TTest { * @param sample1 array of sample data values * @param sample2 array of sample data values * @return t statistic - * @throws IllegalArgumentException if the precondition is not met + * @throws NullArgumentException if the arrays are null + * @throws NumberIsTooSmallException if the length of the arrays is < 2 */ - double t(double[] sample1, double[] sample2) - throws IllegalArgumentException; + public double t(final double[] sample1, final double[] sample2) + throws NullArgumentException, NumberIsTooSmallException { + + checkSampleData(sample1); + checkSampleData(sample2); + return t(StatUtils.mean(sample1), StatUtils.mean(sample2), + StatUtils.variance(sample1), StatUtils.variance(sample2), + sample1.length, sample2.length); + + } + /** * Computes a 2-sample t statistic , comparing the means of the datasets * described by two {@link StatisticalSummary} instances, without the @@ -249,7 +328,7 @@ public interface TTest { * This statistic can be used to perform a two-sample t-test to compare * sample means.

*

- * The returned t-statisitc is

+ * The returned t-statistic is

*

*    t = (m1 - m2) / sqrt(var1/n1 + var2/n2) *

@@ -268,12 +347,21 @@ public interface TTest { * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return t statistic - * @throws IllegalArgumentException if the precondition is not met + * @throws NullArgumentException if the sample statistics are null + * @throws NumberIsTooSmallException if the number of samples is < 2 */ - double t( - StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException; + public double t(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2) + throws NullArgumentException, NumberIsTooSmallException { + + checkSampleData(sampleStats1); + checkSampleData(sampleStats2); + return t(sampleStats1.getMean(), sampleStats2.getMean(), + sampleStats1.getVariance(), sampleStats2.getVariance(), + sampleStats1.getN(), sampleStats2.getN()); + + } + /** * Computes a 2-sample t statistic, comparing the means of the datasets * described by two {@link StatisticalSummary} instances, under the @@ -284,7 +372,7 @@ public interface TTest { * This statistic can be used to perform a (homoscedastic) two-sample * t-test to compare sample means.

*

- * The t-statisitc returned is

+ * The t-statistic returned is

*

*    t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var)) *

@@ -307,12 +395,21 @@ public interface TTest { * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return t statistic - * @throws IllegalArgumentException if the precondition is not met + * @throws NullArgumentException if the sample statistics are null + * @throws NumberIsTooSmallException if the number of samples is < 2 */ - double homoscedasticT( - StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException; + public double homoscedasticT(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2) + throws NullArgumentException, NumberIsTooSmallException { + + checkSampleData(sampleStats1); + checkSampleData(sampleStats2); + return homoscedasticT(sampleStats1.getMean(), sampleStats2.getMean(), + sampleStats1.getVariance(), sampleStats2.getVariance(), + sampleStats1.getN(), sampleStats2.getN()); + + } + /** * Returns the observed significance level, or * p-value, associated with a one-sample, two-tailed t-test @@ -336,11 +433,20 @@ public interface TTest { * @param mu constant value to compare sample mean against * @param sample array of sample data values * @return p-value - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value + * @throws NullArgumentException if the sample array is null + * @throws NumberIsTooSmallException if the length of the array is < 2 + * @throws MaxCountExceededException if an error occurs computing the p-value */ - double tTest(double mu, double[] sample) - throws IllegalArgumentException, MathException; + public double tTest(final double mu, final double[] sample) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { + + checkSampleData(sample); + return tTest(StatUtils.mean(sample), mu, StatUtils.variance(sample), + sample.length); + + } + /** * Performs a * two-sided t-test evaluating the null hypothesis that the mean of the population from @@ -373,11 +479,20 @@ public interface TTest { * @param sample array of sample data values * @param alpha significance level of the test * @return p-value - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error computing the p-value + * @throws NullArgumentException if the sample array is null + * @throws NumberIsTooSmallException if the length of the array is < 2 + * @throws OutOfRangeException if alpha is not in the range (0, 0.5] + * @throws MaxCountExceededException if an error computing the p-value */ - boolean tTest(double mu, double[] sample, double alpha) - throws IllegalArgumentException, MathException; + public boolean tTest(final double mu, final double[] sample, final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { + + checkSignificanceLevel(alpha); + return tTest(mu, sample) < alpha; + + } + /** * Returns the observed significance level, or * p-value, associated with a one-sample, two-tailed t-test @@ -403,11 +518,20 @@ public interface TTest { * @param mu constant value to compare sample mean against * @param sampleStats StatisticalSummary describing sample data * @return p-value - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value + * @throws NullArgumentException if sampleStats is null + * @throws NumberIsTooSmallException if the number of samples is < 2 + * @throws MaxCountExceededException if an error occurs computing the p-value */ - double tTest(double mu, StatisticalSummary sampleStats) - throws IllegalArgumentException, MathException; + public double tTest(final double mu, final StatisticalSummary sampleStats) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { + + checkSampleData(sampleStats); + return tTest(sampleStats.getMean(), mu, sampleStats.getVariance(), + sampleStats.getN()); + + } + /** * Performs a * two-sided t-test evaluating the null hypothesis that the mean of the @@ -441,14 +565,21 @@ public interface TTest { * @param sampleStats StatisticalSummary describing sample data values * @param alpha significance level of the test * @return p-value - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value + * @throws NullArgumentException if sampleStats is null + * @throws NumberIsTooSmallException if the number of samples is < 2 + * @throws OutOfRangeException if alpha is not in the range (0, 0.5] + * @throws MaxCountExceededException if an error occurs computing the p-value */ - boolean tTest( - double mu, - StatisticalSummary sampleStats, - double alpha) - throws IllegalArgumentException, MathException; + public boolean tTest(final double mu, final StatisticalSummary sampleStats, + final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { + + checkSignificanceLevel(alpha); + return tTest(mu, sampleStats) < alpha; + + } + /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test @@ -482,11 +613,22 @@ public interface TTest { * @param sample1 array of sample data values * @param sample2 array of sample data values * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value + * @throws NullArgumentException if the arrays are null + * @throws NumberIsTooSmallException if the length of the arrays is < 2 + * @throws MaxCountExceededException if an error occurs computing the p-value */ - double tTest(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException; + public double tTest(final double[] sample1, final double[] sample2) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { + + checkSampleData(sample1); + checkSampleData(sample2); + return tTest(StatUtils.mean(sample1), StatUtils.mean(sample2), + StatUtils.variance(sample1), StatUtils.variance(sample2), + sample1.length, sample2.length); + + } + /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test @@ -517,13 +659,24 @@ public interface TTest { * @param sample1 array of sample data values * @param sample2 array of sample data values * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value + * @throws NullArgumentException if the arrays are null + * @throws NumberIsTooSmallException if the length of the arrays is < 2 + * @throws MaxCountExceededException if an error occurs computing the p-value */ - double homoscedasticTTest( - double[] sample1, - double[] sample2) - throws IllegalArgumentException, MathException; + public double homoscedasticTTest(final double[] sample1, final double[] sample2) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { + + checkSampleData(sample1); + checkSampleData(sample2); + return homoscedasticTTest(StatUtils.mean(sample1), + StatUtils.mean(sample2), + StatUtils.variance(sample1), + StatUtils.variance(sample2), + sample1.length, sample2.length); + + } + /** * Performs a * @@ -571,14 +724,21 @@ public interface TTest { * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha - * @throws IllegalArgumentException if the preconditions are not met - * @throws MathException if an error occurs performing the test + * @throws NullArgumentException if the arrays are null + * @throws NumberIsTooSmallException if the length of the arrays is < 2 + * @throws OutOfRangeException if alpha is not in the range (0, 0.5] + * @throws MaxCountExceededException if an error occurs computing the p-value */ - boolean tTest( - double[] sample1, - double[] sample2, - double alpha) - throws IllegalArgumentException, MathException; + public boolean tTest(final double[] sample1, final double[] sample2, + final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { + + checkSignificanceLevel(alpha); + return tTest(sample1, sample2) < alpha; + + } + /** * Performs a * @@ -627,14 +787,21 @@ public interface TTest { * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha - * @throws IllegalArgumentException if the preconditions are not met - * @throws MathException if an error occurs performing the test + * @throws NullArgumentException if the arrays are null + * @throws NumberIsTooSmallException if the length of the arrays is < 2 + * @throws OutOfRangeException if alpha is not in the range (0, 0.5] + * @throws MaxCountExceededException if an error occurs computing the p-value */ - boolean homoscedasticTTest( - double[] sample1, - double[] sample2, - double alpha) - throws IllegalArgumentException, MathException; + public boolean homoscedasticTTest(final double[] sample1, final double[] sample2, + final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { + + checkSignificanceLevel(alpha); + return homoscedasticTTest(sample1, sample2) < alpha; + + } + /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test @@ -646,7 +813,7 @@ public interface TTest { * equal in favor of the two-sided alternative that they are different. * For a one-sided test, divide the returned value by 2.

*

- * The test does not assume that the underlying popuation variances are + * The test does not assume that the underlying population variances are * equal and it uses approximated degrees of freedom computed from the * sample data to compute the p-value. To perform the test assuming * equal variances, use @@ -666,13 +833,23 @@ public interface TTest { * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value + * @throws NullArgumentException if the sample statistics are null + * @throws NumberIsTooSmallException if the number of samples is < 2 + * @throws MaxCountExceededException if an error occurs computing the p-value */ - double tTest( - StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException, MathException; + public double tTest(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { + + checkSampleData(sampleStats1); + checkSampleData(sampleStats2); + return tTest(sampleStats1.getMean(), sampleStats2.getMean(), + sampleStats1.getVariance(), sampleStats2.getVariance(), + sampleStats1.getN(), sampleStats2.getN()); + + } + /** * Returns the observed significance level, or * p-value, associated with a two-sample, two-tailed t-test @@ -703,13 +880,25 @@ public interface TTest { * @param sampleStats1 StatisticalSummary describing data from the first sample * @param sampleStats2 StatisticalSummary describing data from the second sample * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value + * @throws NullArgumentException if the sample statistics are null + * @throws NumberIsTooSmallException if the number of samples is < 2 + * @throws MaxCountExceededException if an error occurs computing the p-value */ - double homoscedasticTTest( - StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException, MathException; + public double homoscedasticTTest(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { + + checkSampleData(sampleStats1); + checkSampleData(sampleStats2); + return homoscedasticTTest(sampleStats1.getMean(), + sampleStats2.getMean(), + sampleStats1.getVariance(), + sampleStats2.getVariance(), + sampleStats1.getN(), sampleStats2.getN()); + + } + /** * Performs a * @@ -760,12 +949,221 @@ public interface TTest { * @param alpha significance level of the test * @return true if the null hypothesis can be rejected with * confidence 1 - alpha - * @throws IllegalArgumentException if the preconditions are not met - * @throws MathException if an error occurs performing the test + * @throws NullArgumentException if the sample statistics are null + * @throws NumberIsTooSmallException if the number of samples is < 2 + * @throws OutOfRangeException if alpha is not in the range (0, 0.5] + * @throws MaxCountExceededException if an error occurs computing the p-value */ - boolean tTest( - StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2, - double alpha) - throws IllegalArgumentException, MathException; + public boolean tTest(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2, + final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { + + checkSignificanceLevel(alpha); + return tTest(sampleStats1, sampleStats2) < alpha; + + } + + //----------------------------------------------- Protected methods + + /** + * Computes approximate degrees of freedom for 2-sample t-test. + * + * @param v1 first sample variance + * @param v2 second sample variance + * @param n1 first sample n + * @param n2 second sample n + * @return approximate degrees of freedom + */ + protected double df(double v1, double v2, double n1, double n2) { + return (((v1 / n1) + (v2 / n2)) * ((v1 / n1) + (v2 / n2))) / + ((v1 * v1) / (n1 * n1 * (n1 - 1d)) + (v2 * v2) / + (n2 * n2 * (n2 - 1d))); + } + + /** + * Computes t test statistic for 1-sample t-test. + * + * @param m sample mean + * @param mu constant to test against + * @param v sample variance + * @param n sample n + * @return t test statistic + */ + protected double t(final double m, final double mu, + final double v, final double n) { + return (m - mu) / FastMath.sqrt(v / n); + } + + /** + * Computes t test statistic for 2-sample t-test. + *

+ * Does not assume that subpopulation variances are equal.

+ * + * @param m1 first sample mean + * @param m2 second sample mean + * @param v1 first sample variance + * @param v2 second sample variance + * @param n1 first sample n + * @param n2 second sample n + * @return t test statistic + */ + protected double t(final double m1, final double m2, + final double v1, final double v2, + final double n1, final double n2) { + return (m1 - m2) / FastMath.sqrt((v1 / n1) + (v2 / n2)); + } + + /** + * Computes t test statistic for 2-sample t-test under the hypothesis + * of equal subpopulation variances. + * + * @param m1 first sample mean + * @param m2 second sample mean + * @param v1 first sample variance + * @param v2 second sample variance + * @param n1 first sample n + * @param n2 second sample n + * @return t test statistic + */ + protected double homoscedasticT(final double m1, final double m2, + final double v1, final double v2, + final double n1, final double n2) { + final double pooledVariance = ((n1 - 1) * v1 + (n2 -1) * v2 ) / (n1 + n2 - 2); + return (m1 - m2) / FastMath.sqrt(pooledVariance * (1d / n1 + 1d / n2)); + } + + /** + * Computes p-value for 2-sided, 1-sample t-test. + * + * @param m sample mean + * @param mu constant to test against + * @param v sample variance + * @param n sample n + * @return p-value + * @throws MaxCountExceededException if an error occurs computing the p-value + */ + protected double tTest(final double m, final double mu, + final double v, final double n) + throws MaxCountExceededException { + + double t = FastMath.abs(t(m, mu, v, n)); + TDistribution distribution = new TDistribution(n - 1); + return 2.0 * distribution.cumulativeProbability(-t); + + } + + /** + * Computes p-value for 2-sided, 2-sample t-test. + *

+ * Does not assume subpopulation variances are equal. Degrees of freedom + * are estimated from the data.

+ * + * @param m1 first sample mean + * @param m2 second sample mean + * @param v1 first sample variance + * @param v2 second sample variance + * @param n1 first sample n + * @param n2 second sample n + * @return p-value + * @throws MaxCountExceededException if an error occurs computing the p-value + */ + protected double tTest(final double m1, final double m2, + final double v1, final double v2, + final double n1, final double n2) + throws MaxCountExceededException { + + final double t = FastMath.abs(t(m1, m2, v1, v2, n1, n2)); + final double degreesOfFreedom = df(v1, v2, n1, n2); + TDistribution distribution = new TDistribution(degreesOfFreedom); + return 2.0 * distribution.cumulativeProbability(-t); + + } + + /** + * Computes p-value for 2-sided, 2-sample t-test, under the assumption + * of equal subpopulation variances. + *

+ * The sum of the sample sizes minus 2 is used as degrees of freedom.

+ * + * @param m1 first sample mean + * @param m2 second sample mean + * @param v1 first sample variance + * @param v2 second sample variance + * @param n1 first sample n + * @param n2 second sample n + * @return p-value + * @throws MaxCountExceededException if an error occurs computing the p-value + */ + protected double homoscedasticTTest(double m1, double m2, + double v1, double v2, + double n1, double n2) + throws MaxCountExceededException { + + final double t = FastMath.abs(homoscedasticT(m1, m2, v1, v2, n1, n2)); + final double degreesOfFreedom = n1 + n2 - 2; + TDistribution distribution = new TDistribution(degreesOfFreedom); + return 2.0 * distribution.cumulativeProbability(-t); + + } + + /** + * Check significance level. + * + * @param alpha significance level + * @throws OutOfRangeException if the significance level is out of bounds. + */ + private void checkSignificanceLevel(final double alpha) + throws OutOfRangeException { + + if (alpha <= 0 || alpha > 0.5) { + throw new OutOfRangeException(LocalizedFormats.SIGNIFICANCE_LEVEL, + alpha, 0.0, 0.5); + } + + } + + /** + * Check sample data. + * + * @param data Sample data. + * @throws NullArgumentException if {@code data} is {@code null}. + * @throws NumberIsTooSmallException if there is not enough sample data. + */ + private void checkSampleData(final double[] data) + throws NullArgumentException, NumberIsTooSmallException { + + if (data == null) { + throw new NullArgumentException(); + } + if (data.length < 2) { + throw new NumberIsTooSmallException( + LocalizedFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC, + data.length, 2, true); + } + + } + + /** + * Check sample data. + * + * @param stat Statistical summary. + * @throws NullArgumentException if {@code data} is {@code null}. + * @throws NumberIsTooSmallException if there is not enough sample data. + */ + private void checkSampleData(final StatisticalSummary stat) + throws NullArgumentException, NumberIsTooSmallException { + + if (stat == null) { + throw new NullArgumentException(); + } + if (stat.getN() < 2) { + throw new NumberIsTooSmallException( + LocalizedFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC, + stat.getN(), 2, true); + } + + } + } diff --git a/src/main/java/org/apache/commons/math/stat/inference/TTestImpl.java b/src/main/java/org/apache/commons/math/stat/inference/TTestImpl.java deleted file mode 100644 index 7498f3029..000000000 --- a/src/main/java/org/apache/commons/math/stat/inference/TTestImpl.java +++ /dev/null @@ -1,1042 +0,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. - */ -package org.apache.commons.math.stat.inference; - -import org.apache.commons.math.MathException; -import org.apache.commons.math.exception.OutOfRangeException; -import org.apache.commons.math.exception.NullArgumentException; -import org.apache.commons.math.exception.NumberIsTooSmallException; -import org.apache.commons.math.distribution.TDistribution; -import org.apache.commons.math.exception.util.LocalizedFormats; -import org.apache.commons.math.stat.StatUtils; -import org.apache.commons.math.stat.descriptive.StatisticalSummary; -import org.apache.commons.math.util.FastMath; - -/** - * Implements t-test statistics defined in the {@link TTest} interface. - *

- * Uses commons-math {@link org.apache.commons.math.distribution.TDistribution} - * implementation to estimate exact p-values.

- * - * @version $Id$ - */ -public class TTestImpl implements TTest { - /** - * Computes a paired, 2-sample t-statistic based on the data in the input - * arrays. The t-statistic returned is equivalent to what would be returned by - * computing the one-sample t-statistic {@link #t(double, double[])}, with - * mu = 0 and the sample array consisting of the (signed) - * differences between corresponding entries in sample1 and - * sample2. - *

- * Preconditions:

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @return t statistic - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if the statistic can not be computed do to a - * convergence or other numerical error. - */ - public double pairedT(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException { - checkSampleData(sample1); - checkSampleData(sample2); - double meanDifference = StatUtils.meanDifference(sample1, sample2); - return t(meanDifference, 0, - StatUtils.varianceDifference(sample1, sample2, meanDifference), - sample1.length); - } - - /** - * Returns the observed significance level, or - * p-value, associated with a paired, two-sample, two-tailed t-test - * based on the data in the input arrays. - *

- * The number returned is the smallest significance level - * at which one can reject the null hypothesis that the mean of the paired - * differences is 0 in favor of the two-sided alternative that the mean paired - * difference is not equal to 0. For a one-sided test, divide the returned - * value by 2.

- *

- * This test is equivalent to a one-sample t-test computed using - * {@link #tTest(double, double[])} with mu = 0 and the sample - * array consisting of the signed differences between corresponding elements of - * sample1 and sample2.

- *

- * Usage Note:
- * The validity of the p-value depends on the assumptions of the parametric - * t-test procedure, as discussed - *
- * here

- *

- * Preconditions:

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value - */ - public double pairedTTest(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException { - double meanDifference = StatUtils.meanDifference(sample1, sample2); - return tTest(meanDifference, 0, - StatUtils.varianceDifference(sample1, sample2, meanDifference), - sample1.length); - } - - /** - * Performs a paired t-test evaluating the null hypothesis that the - * mean of the paired differences between sample1 and - * sample2 is 0 in favor of the two-sided alternative that the - * mean paired difference is not equal to 0, with significance level - * alpha. - *

- * Returns true iff the null hypothesis can be rejected with - * confidence 1 - alpha. To perform a 1-sided test, use - * alpha * 2

- *

- * Usage Note:
- * The validity of the test depends on the assumptions of the parametric - * t-test procedure, as discussed - * - * here

- *

- * Preconditions:

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @param alpha significance level of the test - * @return true if the null hypothesis can be rejected with - * confidence 1 - alpha - * @throws IllegalArgumentException if the preconditions are not met - * @throws MathException if an error occurs performing the test - */ - public boolean pairedTTest(double[] sample1, double[] sample2, double alpha) - throws IllegalArgumentException, MathException { - checkSignificanceLevel(alpha); - return pairedTTest(sample1, sample2) < alpha; - } - - /** - * Computes a - * t statistic given observed values and a comparison constant. - *

- * This statistic can be used to perform a one sample t-test for the mean. - *

- * Preconditions:

- * - * @param mu comparison constant - * @param observed array of values - * @return t statistic - * @throws IllegalArgumentException if input array length is less than 2 - */ - public double t(double mu, double[] observed) - throws IllegalArgumentException { - checkSampleData(observed); - return t(StatUtils.mean(observed), mu, StatUtils.variance(observed), - observed.length); - } - - /** - * Computes a - * t statistic to use in comparing the mean of the dataset described by - * sampleStats to mu. - *

- * This statistic can be used to perform a one sample t-test for the mean. - *

- * Preconditions:

- * - * @param mu comparison constant - * @param sampleStats DescriptiveStatistics holding sample summary statitstics - * @return t statistic - * @throws IllegalArgumentException if the precondition is not met - */ - public double t(double mu, StatisticalSummary sampleStats) - throws IllegalArgumentException { - checkSampleData(sampleStats); - return t(sampleStats.getMean(), mu, sampleStats.getVariance(), - sampleStats.getN()); - } - - /** - * Computes a 2-sample t statistic, under the hypothesis of equal - * subpopulation variances. To compute a t-statistic without the - * equal variances hypothesis, use {@link #t(double[], double[])}. - *

- * This statistic can be used to perform a (homoscedastic) two-sample - * t-test to compare sample means.

- *

- * The t-statisitc is

- *

- *    t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var)) - *

- * where n1 is the size of first sample; - * n2 is the size of second sample; - * m1 is the mean of first sample; - * m2 is the mean of second sample - * - * and var is the pooled variance estimate: - *

- * var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1))) - *

- * with var1 the variance of the first sample and - * var2 the variance of the second sample. - *

- * Preconditions:

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @return t statistic - * @throws IllegalArgumentException if the precondition is not met - */ - public double homoscedasticT(double[] sample1, double[] sample2) - throws IllegalArgumentException { - checkSampleData(sample1); - checkSampleData(sample2); - return homoscedasticT(StatUtils.mean(sample1), StatUtils.mean(sample2), - StatUtils.variance(sample1), StatUtils.variance(sample2), - sample1.length, sample2.length); - } - - /** - * Computes a 2-sample t statistic, without the hypothesis of equal - * subpopulation variances. To compute a t-statistic assuming equal - * variances, use {@link #homoscedasticT(double[], double[])}. - *

- * This statistic can be used to perform a two-sample t-test to compare - * sample means.

- *

- * The t-statisitc is

- *

- *    t = (m1 - m2) / sqrt(var1/n1 + var2/n2) - *

- * where n1 is the size of the first sample - * n2 is the size of the second sample; - * m1 is the mean of the first sample; - * m2 is the mean of the second sample; - * var1 is the variance of the first sample; - * var2 is the variance of the second sample; - *

- * Preconditions:

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @return t statistic - * @throws IllegalArgumentException if the precondition is not met - */ - public double t(double[] sample1, double[] sample2) - throws IllegalArgumentException { - checkSampleData(sample1); - checkSampleData(sample2); - return t(StatUtils.mean(sample1), StatUtils.mean(sample2), - StatUtils.variance(sample1), StatUtils.variance(sample2), - sample1.length, sample2.length); - } - - /** - * Computes a 2-sample t statistic , comparing the means of the datasets - * described by two {@link StatisticalSummary} instances, without the - * assumption of equal subpopulation variances. Use - * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to - * compute a t-statistic under the equal variances assumption. - *

- * This statistic can be used to perform a two-sample t-test to compare - * sample means.

- *

- * The returned t-statisitc is

- *

- *    t = (m1 - m2) / sqrt(var1/n1 + var2/n2) - *

- * where n1 is the size of the first sample; - * n2 is the size of the second sample; - * m1 is the mean of the first sample; - * m2 is the mean of the second sample - * var1 is the variance of the first sample; - * var2 is the variance of the second sample - *

- * Preconditions:

- * - * @param sampleStats1 StatisticalSummary describing data from the first sample - * @param sampleStats2 StatisticalSummary describing data from the second sample - * @return t statistic - * @throws IllegalArgumentException if the precondition is not met - */ - public double t(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException { - checkSampleData(sampleStats1); - checkSampleData(sampleStats2); - return t(sampleStats1.getMean(), sampleStats2.getMean(), - sampleStats1.getVariance(), sampleStats2.getVariance(), - sampleStats1.getN(), sampleStats2.getN()); - } - - /** - * Computes a 2-sample t statistic, comparing the means of the datasets - * described by two {@link StatisticalSummary} instances, under the - * assumption of equal subpopulation variances. To compute a t-statistic - * without the equal variances assumption, use - * {@link #t(StatisticalSummary, StatisticalSummary)}. - *

- * This statistic can be used to perform a (homoscedastic) two-sample - * t-test to compare sample means.

- *

- * The t-statisitc returned is

- *

- *    t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var)) - *

- * where n1 is the size of first sample; - * n2 is the size of second sample; - * m1 is the mean of first sample; - * m2 is the mean of second sample - * and var is the pooled variance estimate: - *

- * var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1))) - *

- * with var1 the variance of the first sample and - * var2 the variance of the second sample. - *

- * Preconditions:

- * - * @param sampleStats1 StatisticalSummary describing data from the first sample - * @param sampleStats2 StatisticalSummary describing data from the second sample - * @return t statistic - * @throws IllegalArgumentException if the precondition is not met - */ - public double homoscedasticT(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException { - checkSampleData(sampleStats1); - checkSampleData(sampleStats2); - return homoscedasticT(sampleStats1.getMean(), sampleStats2.getMean(), - sampleStats1.getVariance(), sampleStats2.getVariance(), - sampleStats1.getN(), sampleStats2.getN()); - } - - /** - * Returns the observed significance level, or - * p-value, associated with a one-sample, two-tailed t-test - * comparing the mean of the input array with the constant mu. - *

- * The number returned is the smallest significance level - * at which one can reject the null hypothesis that the mean equals - * mu in favor of the two-sided alternative that the mean - * is different from mu. For a one-sided test, divide the - * returned value by 2.

- *

- * Usage Note:
- * The validity of the test depends on the assumptions of the parametric - * t-test procedure, as discussed - * here - *

- * Preconditions:

    - *
  • The observed array length must be at least 2. - *

- * - * @param mu constant value to compare sample mean against - * @param sample array of sample data values - * @return p-value - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value - */ - public double tTest(double mu, double[] sample) - throws IllegalArgumentException, MathException { - checkSampleData(sample); - return tTest( StatUtils.mean(sample), mu, StatUtils.variance(sample), - sample.length); - } - - /** - * Performs a - * two-sided t-test evaluating the null hypothesis that the mean of the population from - * which sample is drawn equals mu. - *

- * Returns true iff the null hypothesis can be - * rejected with confidence 1 - alpha. To - * perform a 1-sided test, use alpha * 2 - *

- * Examples:

    - *
  1. To test the (2-sided) hypothesis sample mean = mu at - * the 95% level, use
    tTest(mu, sample, 0.05) - *
  2. - *
  3. To test the (one-sided) hypothesis sample mean < mu - * at the 99% level, first verify that the measured sample mean is less - * than mu and then use - *
    tTest(mu, sample, 0.02) - *

- *

- * Usage Note:
- * The validity of the test depends on the assumptions of the one-sample - * parametric t-test procedure, as discussed - * here - *

- * Preconditions:

    - *
  • The observed array length must be at least 2. - *

- * - * @param mu constant value to compare sample mean against - * @param sample array of sample data values - * @param alpha significance level of the test - * @return p-value - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error computing the p-value - */ - public boolean tTest(double mu, double[] sample, double alpha) - throws IllegalArgumentException, MathException { - checkSignificanceLevel(alpha); - return tTest(mu, sample) < alpha; - } - - /** - * Returns the observed significance level, or - * p-value, associated with a one-sample, two-tailed t-test - * comparing the mean of the dataset described by sampleStats - * with the constant mu. - *

- * The number returned is the smallest significance level - * at which one can reject the null hypothesis that the mean equals - * mu in favor of the two-sided alternative that the mean - * is different from mu. For a one-sided test, divide the - * returned value by 2.

- *

- * Usage Note:
- * The validity of the test depends on the assumptions of the parametric - * t-test procedure, as discussed - * - * here

- *

- * Preconditions:

    - *
  • The sample must contain at least 2 observations. - *

- * - * @param mu constant value to compare sample mean against - * @param sampleStats StatisticalSummary describing sample data - * @return p-value - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value - */ - public double tTest(double mu, StatisticalSummary sampleStats) - throws IllegalArgumentException, MathException { - checkSampleData(sampleStats); - return tTest(sampleStats.getMean(), mu, sampleStats.getVariance(), - sampleStats.getN()); - } - - /** - * Performs a - * two-sided t-test evaluating the null hypothesis that the mean of the - * population from which the dataset described by stats is - * drawn equals mu. - *

- * Returns true iff the null hypothesis can be rejected with - * confidence 1 - alpha. To perform a 1-sided test, use - * alpha * 2.

- *

- * Examples:

    - *
  1. To test the (2-sided) hypothesis sample mean = mu at - * the 95% level, use
    tTest(mu, sampleStats, 0.05) - *
  2. - *
  3. To test the (one-sided) hypothesis sample mean < mu - * at the 99% level, first verify that the measured sample mean is less - * than mu and then use - *
    tTest(mu, sampleStats, 0.02) - *

- *

- * Usage Note:
- * The validity of the test depends on the assumptions of the one-sample - * parametric t-test procedure, as discussed - * here - *

- * Preconditions:

    - *
  • The sample must include at least 2 observations. - *

- * - * @param mu constant value to compare sample mean against - * @param sampleStats StatisticalSummary describing sample data values - * @param alpha significance level of the test - * @return p-value - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value - */ - public boolean tTest( double mu, StatisticalSummary sampleStats, - double alpha) - throws IllegalArgumentException, MathException { - checkSignificanceLevel(alpha); - return tTest(mu, sampleStats) < alpha; - } - - /** - * Returns the observed significance level, or - * p-value, associated with a two-sample, two-tailed t-test - * comparing the means of the input arrays. - *

- * The number returned is the smallest significance level - * at which one can reject the null hypothesis that the two means are - * equal in favor of the two-sided alternative that they are different. - * For a one-sided test, divide the returned value by 2.

- *

- * The test does not assume that the underlying popuation variances are - * equal and it uses approximated degrees of freedom computed from the - * sample data to compute the p-value. The t-statistic used is as defined in - * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation - * to the degrees of freedom is used, - * as described - * - * here. To perform the test under the assumption of equal subpopulation - * variances, use {@link #homoscedasticTTest(double[], double[])}.

- *

- * Usage Note:
- * The validity of the p-value depends on the assumptions of the parametric - * t-test procedure, as discussed - * - * here

- *

- * Preconditions:

    - *
  • The observed array lengths must both be at least 2. - *

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value - */ - public double tTest(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException { - checkSampleData(sample1); - checkSampleData(sample2); - return tTest(StatUtils.mean(sample1), StatUtils.mean(sample2), - StatUtils.variance(sample1), StatUtils.variance(sample2), - sample1.length, sample2.length); - } - - /** - * Returns the observed significance level, or - * p-value, associated with a two-sample, two-tailed t-test - * comparing the means of the input arrays, under the assumption that - * the two samples are drawn from subpopulations with equal variances. - * To perform the test without the equal variances assumption, use - * {@link #tTest(double[], double[])}. - *

- * The number returned is the smallest significance level - * at which one can reject the null hypothesis that the two means are - * equal in favor of the two-sided alternative that they are different. - * For a one-sided test, divide the returned value by 2.

- *

- * A pooled variance estimate is used to compute the t-statistic. See - * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes - * minus 2 is used as the degrees of freedom.

- *

- * Usage Note:
- * The validity of the p-value depends on the assumptions of the parametric - * t-test procedure, as discussed - * - * here

- *

- * Preconditions:

    - *
  • The observed array lengths must both be at least 2. - *

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value - */ - public double homoscedasticTTest(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException { - checkSampleData(sample1); - checkSampleData(sample2); - return homoscedasticTTest(StatUtils.mean(sample1), - StatUtils.mean(sample2), StatUtils.variance(sample1), - StatUtils.variance(sample2), sample1.length, - sample2.length); - } - - - /** - * Performs a - * - * two-sided t-test evaluating the null hypothesis that sample1 - * and sample2 are drawn from populations with the same mean, - * with significance level alpha. This test does not assume - * that the subpopulation variances are equal. To perform the test assuming - * equal variances, use - * {@link #homoscedasticTTest(double[], double[], double)}. - *

- * Returns true iff the null hypothesis that the means are - * equal can be rejected with confidence 1 - alpha. To - * perform a 1-sided test, use alpha / 2

- *

- * See {@link #t(double[], double[])} for the formula used to compute the - * t-statistic. Degrees of freedom are approximated using the - * - * Welch-Satterthwaite approximation.

- - *

- * Examples:

    - *
  1. To test the (2-sided) hypothesis mean 1 = mean 2 at - * the 95% level, use - *
    tTest(sample1, sample2, 0.05). - *
  2. - *
  3. To test the (one-sided) hypothesis mean 1 < mean 2 at - * the 99% level, first verify that the measured mean of sample 1 - * is less than the mean of sample 2 and then use - *
    tTest(sample1, sample2, 0.02) - *

- *

- * Usage Note:
- * The validity of the test depends on the assumptions of the parametric - * t-test procedure, as discussed - * - * here

- *

- * Preconditions:

    - *
  • The observed array lengths must both be at least 2. - *
  • - *
  • 0 < alpha < 0.5 - *

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @param alpha significance level of the test - * @return true if the null hypothesis can be rejected with - * confidence 1 - alpha - * @throws IllegalArgumentException if the preconditions are not met - * @throws MathException if an error occurs performing the test - */ - public boolean tTest(double[] sample1, double[] sample2, - double alpha) - throws IllegalArgumentException, MathException { - checkSignificanceLevel(alpha); - return tTest(sample1, sample2) < alpha; - } - - /** - * Performs a - * - * two-sided t-test evaluating the null hypothesis that sample1 - * and sample2 are drawn from populations with the same mean, - * with significance level alpha, assuming that the - * subpopulation variances are equal. Use - * {@link #tTest(double[], double[], double)} to perform the test without - * the assumption of equal variances. - *

- * Returns true iff the null hypothesis that the means are - * equal can be rejected with confidence 1 - alpha. To - * perform a 1-sided test, use alpha * 2. To perform the test - * without the assumption of equal subpopulation variances, use - * {@link #tTest(double[], double[], double)}.

- *

- * A pooled variance estimate is used to compute the t-statistic. See - * {@link #t(double[], double[])} for the formula. The sum of the sample - * sizes minus 2 is used as the degrees of freedom.

- *

- * Examples:

    - *
  1. To test the (2-sided) hypothesis mean 1 = mean 2 at - * the 95% level, use
    tTest(sample1, sample2, 0.05). - *
  2. - *
  3. To test the (one-sided) hypothesis mean 1 < mean 2, - * at the 99% level, first verify that the measured mean of - * sample 1 is less than the mean of sample 2 - * and then use - *
    tTest(sample1, sample2, 0.02) - *

- *

- * Usage Note:
- * The validity of the test depends on the assumptions of the parametric - * t-test procedure, as discussed - * - * here

- *

- * Preconditions:

    - *
  • The observed array lengths must both be at least 2. - *
  • - *
  • 0 < alpha < 0.5 - *

- * - * @param sample1 array of sample data values - * @param sample2 array of sample data values - * @param alpha significance level of the test - * @return true if the null hypothesis can be rejected with - * confidence 1 - alpha - * @throws IllegalArgumentException if the preconditions are not met - * @throws MathException if an error occurs performing the test - */ - public boolean homoscedasticTTest(double[] sample1, double[] sample2, - double alpha) - throws IllegalArgumentException, MathException { - checkSignificanceLevel(alpha); - return homoscedasticTTest(sample1, sample2) < alpha; - } - - /** - * Returns the observed significance level, or - * p-value, associated with a two-sample, two-tailed t-test - * comparing the means of the datasets described by two StatisticalSummary - * instances. - *

- * The number returned is the smallest significance level - * at which one can reject the null hypothesis that the two means are - * equal in favor of the two-sided alternative that they are different. - * For a one-sided test, divide the returned value by 2.

- *

- * The test does not assume that the underlying popuation variances are - * equal and it uses approximated degrees of freedom computed from the - * sample data to compute the p-value. To perform the test assuming - * equal variances, use - * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.

- *

- * Usage Note:
- * The validity of the p-value depends on the assumptions of the parametric - * t-test procedure, as discussed - * - * here

- *

- * Preconditions:

    - *
  • The datasets described by the two Univariates must each contain - * at least 2 observations. - *

- * - * @param sampleStats1 StatisticalSummary describing data from the first sample - * @param sampleStats2 StatisticalSummary describing data from the second sample - * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value - */ - public double tTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) - throws IllegalArgumentException, MathException { - checkSampleData(sampleStats1); - checkSampleData(sampleStats2); - return tTest(sampleStats1.getMean(), sampleStats2.getMean(), sampleStats1.getVariance(), - sampleStats2.getVariance(), sampleStats1.getN(), - sampleStats2.getN()); - } - - /** - * Returns the observed significance level, or - * p-value, associated with a two-sample, two-tailed t-test - * comparing the means of the datasets described by two StatisticalSummary - * instances, under the hypothesis of equal subpopulation variances. To - * perform a test without the equal variances assumption, use - * {@link #tTest(StatisticalSummary, StatisticalSummary)}. - *

- * The number returned is the smallest significance level - * at which one can reject the null hypothesis that the two means are - * equal in favor of the two-sided alternative that they are different. - * For a one-sided test, divide the returned value by 2.

- *

- * See {@link #homoscedasticT(double[], double[])} for the formula used to - * compute the t-statistic. The sum of the sample sizes minus 2 is used as - * the degrees of freedom.

- *

- * Usage Note:
- * The validity of the p-value depends on the assumptions of the parametric - * t-test procedure, as discussed - * here - *

- * Preconditions:

    - *
  • The datasets described by the two Univariates must each contain - * at least 2 observations. - *

- * - * @param sampleStats1 StatisticalSummary describing data from the first sample - * @param sampleStats2 StatisticalSummary describing data from the second sample - * @return p-value for t-test - * @throws IllegalArgumentException if the precondition is not met - * @throws MathException if an error occurs computing the p-value - */ - public double homoscedasticTTest(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException, MathException { - checkSampleData(sampleStats1); - checkSampleData(sampleStats2); - return homoscedasticTTest(sampleStats1.getMean(), - sampleStats2.getMean(), sampleStats1.getVariance(), - sampleStats2.getVariance(), sampleStats1.getN(), - sampleStats2.getN()); - } - - /** - * Performs a - * - * two-sided t-test evaluating the null hypothesis that - * sampleStats1 and sampleStats2 describe - * datasets drawn from populations with the same mean, with significance - * level alpha. This test does not assume that the - * subpopulation variances are equal. To perform the test under the equal - * variances assumption, use - * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}. - *

- * Returns true iff the null hypothesis that the means are - * equal can be rejected with confidence 1 - alpha. To - * perform a 1-sided test, use alpha * 2

- *

- * See {@link #t(double[], double[])} for the formula used to compute the - * t-statistic. Degrees of freedom are approximated using the - * - * Welch-Satterthwaite approximation.

- *

- * Examples:

    - *
  1. To test the (2-sided) hypothesis mean 1 = mean 2 at - * the 95%, use - *
    tTest(sampleStats1, sampleStats2, 0.05) - *
  2. - *
  3. To test the (one-sided) hypothesis mean 1 < mean 2 - * at the 99% level, first verify that the measured mean of - * sample 1 is less than the mean of sample 2 - * and then use - *
    tTest(sampleStats1, sampleStats2, 0.02) - *

- *

- * Usage Note:
- * The validity of the test depends on the assumptions of the parametric - * t-test procedure, as discussed - * - * here

- *

- * Preconditions:

    - *
  • The datasets described by the two Univariates must each contain - * at least 2 observations. - *
  • - *
  • 0 < alpha < 0.5 - *

- * - * @param sampleStats1 StatisticalSummary describing sample data values - * @param sampleStats2 StatisticalSummary describing sample data values - * @param alpha significance level of the test - * @return true if the null hypothesis can be rejected with - * confidence 1 - alpha - * @throws IllegalArgumentException if the preconditions are not met - * @throws MathException if an error occurs performing the test - */ - public boolean tTest(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2, - double alpha) - throws MathException { - checkSignificanceLevel(alpha); - return tTest(sampleStats1, sampleStats2) < alpha; - } - - //----------------------------------------------- Protected methods - - /** - * Computes approximate degrees of freedom for 2-sample t-test. - * - * @param v1 first sample variance - * @param v2 second sample variance - * @param n1 first sample n - * @param n2 second sample n - * @return approximate degrees of freedom - */ - protected double df(double v1, double v2, double n1, double n2) { - return (((v1 / n1) + (v2 / n2)) * ((v1 / n1) + (v2 / n2))) / - ((v1 * v1) / (n1 * n1 * (n1 - 1d)) + (v2 * v2) / - (n2 * n2 * (n2 - 1d))); - } - - /** - * Computes t test statistic for 1-sample t-test. - * - * @param m sample mean - * @param mu constant to test against - * @param v sample variance - * @param n sample n - * @return t test statistic - */ - protected double t(double m, double mu, double v, double n) { - return (m - mu) / FastMath.sqrt(v / n); - } - - /** - * Computes t test statistic for 2-sample t-test. - *

- * Does not assume that subpopulation variances are equal.

- * - * @param m1 first sample mean - * @param m2 second sample mean - * @param v1 first sample variance - * @param v2 second sample variance - * @param n1 first sample n - * @param n2 second sample n - * @return t test statistic - */ - protected double t(double m1, double m2, double v1, double v2, double n1, - double n2) { - return (m1 - m2) / FastMath.sqrt((v1 / n1) + (v2 / n2)); - } - - /** - * Computes t test statistic for 2-sample t-test under the hypothesis - * of equal subpopulation variances. - * - * @param m1 first sample mean - * @param m2 second sample mean - * @param v1 first sample variance - * @param v2 second sample variance - * @param n1 first sample n - * @param n2 second sample n - * @return t test statistic - */ - protected double homoscedasticT(double m1, double m2, double v1, - double v2, double n1, double n2) { - double pooledVariance = ((n1 - 1) * v1 + (n2 -1) * v2 ) / (n1 + n2 - 2); - return (m1 - m2) / FastMath.sqrt(pooledVariance * (1d / n1 + 1d / n2)); - } - - /** - * Computes p-value for 2-sided, 1-sample t-test. - * - * @param m sample mean - * @param mu constant to test against - * @param v sample variance - * @param n sample n - * @return p-value - * @throws MathException if an error occurs computing the p-value - */ - protected double tTest(double m, double mu, double v, double n) - throws MathException { - double t = FastMath.abs(t(m, mu, v, n)); - TDistribution distribution = new TDistribution(n - 1); - return 2.0 * distribution.cumulativeProbability(-t); - } - - /** - * Computes p-value for 2-sided, 2-sample t-test. - *

- * Does not assume subpopulation variances are equal. Degrees of freedom - * are estimated from the data.

- * - * @param m1 first sample mean - * @param m2 second sample mean - * @param v1 first sample variance - * @param v2 second sample variance - * @param n1 first sample n - * @param n2 second sample n - * @return p-value - * @throws MathException if an error occurs computing the p-value - */ - protected double tTest(double m1, double m2, - double v1, double v2, - double n1, double n2) - throws MathException { - double t = FastMath.abs(t(m1, m2, v1, v2, n1, n2)); - double degreesOfFreedom = 0; - degreesOfFreedom = df(v1, v2, n1, n2); - TDistribution distribution = new TDistribution(degreesOfFreedom); - return 2.0 * distribution.cumulativeProbability(-t); - } - - /** - * Computes p-value for 2-sided, 2-sample t-test, under the assumption - * of equal subpopulation variances. - *

- * The sum of the sample sizes minus 2 is used as degrees of freedom.

- * - * @param m1 first sample mean - * @param m2 second sample mean - * @param v1 first sample variance - * @param v2 second sample variance - * @param n1 first sample n - * @param n2 second sample n - * @return p-value - * @throws MathException if an error occurs computing the p-value - */ - protected double homoscedasticTTest(double m1, double m2, - double v1, double v2, - double n1, double n2) - throws MathException { - double t = FastMath.abs(homoscedasticT(m1, m2, v1, v2, n1, n2)); - double degreesOfFreedom = n1 + n2 - 2; - TDistribution distribution = new TDistribution(degreesOfFreedom); - return 2.0 * distribution.cumulativeProbability(-t); - } - - /** - * Check significance level. - * - * @param alpha significance level - * @throws OutOfRangeException if the significance level is out of bounds. - */ - private void checkSignificanceLevel(final double alpha) { - if (alpha <= 0 || alpha > 0.5) { - throw new OutOfRangeException(LocalizedFormats.SIGNIFICANCE_LEVEL, - alpha, 0.0, 0.5); - } - } - - /** - * Check sample data. - * - * @param data Sample data. - * @throws NullArgumentException if {@code data} is {@code null}. - * @throws NumberIsTooSmallException if there is not enough sample data. - */ - private void checkSampleData(final double[] data) { - if (data == null) { - throw new NullArgumentException(); - } - if (data.length < 2) { - throw new NumberIsTooSmallException(LocalizedFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC, - data.length, 2, true); - } - } - - /** - * Check sample data. - * - * @param stat Statistical summary. - * @throws NullArgumentException if {@code data} is {@code null}. - * @throws NumberIsTooSmallException if there is not enough sample data. - */ - private void checkSampleData(final StatisticalSummary stat) { - if (stat == null) { - throw new NullArgumentException(); - } - if (stat.getN() < 2) { - throw new NumberIsTooSmallException(LocalizedFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC, - stat.getN(), 2, true); - } - } -} diff --git a/src/main/java/org/apache/commons/math/stat/inference/TestUtils.java b/src/main/java/org/apache/commons/math/stat/inference/TestUtils.java index 8f026ec6b..c92f1d28b 100644 --- a/src/main/java/org/apache/commons/math/stat/inference/TestUtils.java +++ b/src/main/java/org/apache/commons/math/stat/inference/TestUtils.java @@ -17,13 +17,14 @@ package org.apache.commons.math.stat.inference; import java.util.Collection; -import org.apache.commons.math.MathException; import org.apache.commons.math.exception.ConvergenceException; import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.exception.MaxCountExceededException; +import org.apache.commons.math.exception.NoDataException; import org.apache.commons.math.exception.NotPositiveException; import org.apache.commons.math.exception.NotStrictlyPositiveException; import org.apache.commons.math.exception.NullArgumentException; +import org.apache.commons.math.exception.NumberIsTooSmallException; import org.apache.commons.math.exception.OutOfRangeException; import org.apache.commons.math.exception.ZeroException; import org.apache.commons.math.stat.descriptive.StatisticalSummary; @@ -38,7 +39,7 @@ import org.apache.commons.math.stat.descriptive.StatisticalSummary; public class TestUtils { /** Singleton TTest instance. */ - private static final TTest T_TEST = new TTestImpl(); + private static final TTest T_TEST = new TTest(); /** Singleton ChiSquareTest instance. */ private static final ChiSquareTest CHI_SQUARE_TEST = new ChiSquareTest(); @@ -58,168 +59,182 @@ public class TestUtils { /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticT(double[], double[]) */ - public static double homoscedasticT(double[] sample1, double[] sample2) - throws IllegalArgumentException { + public static double homoscedasticT(final double[] sample1, final double[] sample2) + throws NullArgumentException, NumberIsTooSmallException { return T_TEST.homoscedasticT(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticT(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ - public static double homoscedasticT(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException { + public static double homoscedasticT(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2) + throws NullArgumentException, NumberIsTooSmallException { return T_TEST.homoscedasticT(sampleStats1, sampleStats2); } /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(double[], double[], double) */ - public static boolean homoscedasticTTest(double[] sample1, double[] sample2, - double alpha) - throws IllegalArgumentException, MathException { + public static boolean homoscedasticTTest(final double[] sample1, final double[] sample2, + final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { return T_TEST.homoscedasticTTest(sample1, sample2, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(double[], double[]) */ - public static double homoscedasticTTest(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException { + public static double homoscedasticTTest(final double[] sample1, final double[] sample2) + throws NullArgumentException, NumberIsTooSmallException, MaxCountExceededException { return T_TEST.homoscedasticTTest(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ - public static double homoscedasticTTest(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException, MathException { + public static double homoscedasticTTest(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2) + throws NullArgumentException, NumberIsTooSmallException, MaxCountExceededException { return T_TEST.homoscedasticTTest(sampleStats1, sampleStats2); } /** * @see org.apache.commons.math.stat.inference.TTest#pairedT(double[], double[]) */ - public static double pairedT(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException { + public static double pairedT(final double[] sample1, final double[] sample2) + throws NullArgumentException, NoDataException, + DimensionMismatchException, NumberIsTooSmallException { return T_TEST.pairedT(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#pairedTTest(double[], double[], double) */ - public static boolean pairedTTest(double[] sample1, double[] sample2, - double alpha) - throws IllegalArgumentException, MathException { + public static boolean pairedTTest(final double[] sample1, final double[] sample2, + final double alpha) + throws NullArgumentException, NoDataException, DimensionMismatchException, + NumberIsTooSmallException, OutOfRangeException, MaxCountExceededException { return T_TEST.pairedTTest(sample1, sample2, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#pairedTTest(double[], double[]) */ - public static double pairedTTest(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException { + public static double pairedTTest(final double[] sample1, final double[] sample2) + throws NullArgumentException, NoDataException, DimensionMismatchException, + NumberIsTooSmallException, MaxCountExceededException { return T_TEST.pairedTTest(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#t(double, double[]) */ - public static double t(double mu, double[] observed) - throws IllegalArgumentException { + public static double t(final double mu, final double[] observed) + throws NullArgumentException, NumberIsTooSmallException { return T_TEST.t(mu, observed); } /** * @see org.apache.commons.math.stat.inference.TTest#t(double, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ - public static double t(double mu, StatisticalSummary sampleStats) - throws IllegalArgumentException { + public static double t(final double mu, final StatisticalSummary sampleStats) + throws NullArgumentException, NumberIsTooSmallException { return T_TEST.t(mu, sampleStats); } /** * @see org.apache.commons.math.stat.inference.TTest#t(double[], double[]) */ - public static double t(double[] sample1, double[] sample2) - throws IllegalArgumentException { + public static double t(final double[] sample1, final double[] sample2) + throws NullArgumentException, NumberIsTooSmallException { return T_TEST.t(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#t(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ - public static double t(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException { + public static double t(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2) + throws NullArgumentException, NumberIsTooSmallException { return T_TEST.t(sampleStats1, sampleStats2); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double, double[], double) */ - public static boolean tTest(double mu, double[] sample, double alpha) - throws IllegalArgumentException, MathException { + public static boolean tTest(final double mu, final double[] sample, final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { return T_TEST.tTest(mu, sample, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double, double[]) */ - public static double tTest(double mu, double[] sample) - throws IllegalArgumentException, MathException { + public static double tTest(final double mu, final double[] sample) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { return T_TEST.tTest(mu, sample); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double, org.apache.commons.math.stat.descriptive.StatisticalSummary, double) */ - public static boolean tTest(double mu, StatisticalSummary sampleStats, - double alpha) - throws IllegalArgumentException, MathException { + public static boolean tTest(final double mu, final StatisticalSummary sampleStats, + final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { return T_TEST.tTest(mu, sampleStats, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ - public static double tTest(double mu, StatisticalSummary sampleStats) - throws IllegalArgumentException, MathException { + public static double tTest(final double mu, final StatisticalSummary sampleStats) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { return T_TEST.tTest(mu, sampleStats); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double[], double[], double) */ - public static boolean tTest(double[] sample1, double[] sample2, double alpha) - throws IllegalArgumentException, MathException { + public static boolean tTest(final double[] sample1, final double[] sample2, + final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { return T_TEST.tTest(sample1, sample2, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(double[], double[]) */ - public static double tTest(double[] sample1, double[] sample2) - throws IllegalArgumentException, MathException { + public static double tTest(final double[] sample1, final double[] sample2) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { return T_TEST.tTest(sample1, sample2); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary, double) */ - public static boolean tTest(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2, double alpha) - throws IllegalArgumentException, MathException { + public static boolean tTest(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2, + final double alpha) + throws NullArgumentException, NumberIsTooSmallException, + OutOfRangeException, MaxCountExceededException { return T_TEST.tTest(sampleStats1, sampleStats2, alpha); } /** * @see org.apache.commons.math.stat.inference.TTest#tTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) */ - public static double tTest(StatisticalSummary sampleStats1, - StatisticalSummary sampleStats2) - throws IllegalArgumentException, MathException { + public static double tTest(final StatisticalSummary sampleStats1, + final StatisticalSummary sampleStats2) + throws NullArgumentException, NumberIsTooSmallException, + MaxCountExceededException { return T_TEST.tTest(sampleStats1, sampleStats2); } diff --git a/src/test/java/org/apache/commons/math/stat/inference/TTestTest.java b/src/test/java/org/apache/commons/math/stat/inference/TTestTest.java index 42b18beae..441784410 100644 --- a/src/test/java/org/apache/commons/math/stat/inference/TTestTest.java +++ b/src/test/java/org/apache/commons/math/stat/inference/TTestTest.java @@ -17,7 +17,9 @@ package org.apache.commons.math.stat.inference; -import org.apache.commons.math.exception.MathIllegalArgumentException; +import org.apache.commons.math.exception.NullArgumentException; +import org.apache.commons.math.exception.NumberIsTooSmallException; +import org.apache.commons.math.exception.OutOfRangeException; import org.apache.commons.math.stat.descriptive.SummaryStatistics; import org.junit.Assert; import org.junit.Before; @@ -30,7 +32,7 @@ import org.junit.Test; */ public class TTestTest { - protected TTest testStatistic = new TTestImpl(); + protected TTest testStatistic = new TTest(); private double[] tooShortObs = { 1.0 }; private double[] emptyObs = {}; @@ -66,55 +68,55 @@ public class TTestTest { try { testStatistic.t(mu, (double[]) null); - Assert.fail("arguments too short, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("arguments too short, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } try { testStatistic.t(mu, (SummaryStatistics) null); - Assert.fail("arguments too short, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("arguments too short, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } try { testStatistic.t(mu, emptyObs); - Assert.fail("arguments too short, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("arguments too short, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.t(mu, emptyStats); - Assert.fail("arguments too short, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("arguments too short, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.t(mu, tooShortObs); - Assert.fail("insufficient data to compute t statistic, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data to compute t statistic, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.tTest(mu, tooShortObs); - Assert.fail("insufficient data to perform t test, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data to perform t test, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.t(mu, tooShortStats); - Assert.fail("insufficient data to compute t statistic, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data to compute t statistic, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.tTest(mu, tooShortStats); - Assert.fail("insufficient data to perform t test, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data to perform t test, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } } @@ -143,15 +145,15 @@ public class TTestTest { try { testStatistic.tTest(0d, oneSidedP, 95); - Assert.fail("alpha out of range, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("alpha out of range, OutOfRangeException expected"); + } catch (OutOfRangeException ex) { // expected } try { testStatistic.tTest(0d, oneSidedPStats, 95); - Assert.fail("alpha out of range, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("alpha out of range, OutOfRangeException expected"); + } catch (OutOfRangeException ex) { // expected } @@ -190,57 +192,57 @@ public class TTestTest { try { testStatistic.tTest(sample1, sample2, .95); - Assert.fail("alpha out of range, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("alpha out of range, OutOfRangeException expected"); + } catch (OutOfRangeException ex) { // expected } try { testStatistic.tTest(sampleStats1, sampleStats2, .95); - Assert.fail("alpha out of range, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("alpha out of range, OutOfRangeException expected"); + } catch (OutOfRangeException ex) { // expected } try { testStatistic.tTest(sample1, tooShortObs, .01); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.tTest(sampleStats1, tooShortStats, .01); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.tTest(sample1, tooShortObs); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.tTest(sampleStats1, tooShortStats); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.t(sample1, tooShortObs); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { testStatistic.t(sampleStats1, tooShortStats); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } } diff --git a/src/test/java/org/apache/commons/math/stat/inference/TestUtilsTest.java b/src/test/java/org/apache/commons/math/stat/inference/TestUtilsTest.java index 503b9f514..2b4c9892b 100644 --- a/src/test/java/org/apache/commons/math/stat/inference/TestUtilsTest.java +++ b/src/test/java/org/apache/commons/math/stat/inference/TestUtilsTest.java @@ -20,9 +20,10 @@ import java.util.ArrayList; import java.util.List; import org.apache.commons.math.exception.DimensionMismatchException; -import org.apache.commons.math.exception.MathIllegalArgumentException; import org.apache.commons.math.exception.NotPositiveException; import org.apache.commons.math.exception.NotStrictlyPositiveException; +import org.apache.commons.math.exception.NullArgumentException; +import org.apache.commons.math.exception.NumberIsTooSmallException; import org.apache.commons.math.exception.OutOfRangeException; import org.apache.commons.math.stat.descriptive.SummaryStatistics; import org.junit.Assert; @@ -218,55 +219,55 @@ public class TestUtilsTest { try { TestUtils.t(mu, (double[]) null); - Assert.fail("arguments too short, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("arguments too short, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } try { TestUtils.t(mu, (SummaryStatistics) null); - Assert.fail("arguments too short, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("arguments too short, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } try { TestUtils.t(mu, emptyObs); - Assert.fail("arguments too short, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("arguments too short, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { TestUtils.t(mu, emptyStats); - Assert.fail("arguments too short, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("arguments too short, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { TestUtils.t(mu, tooShortObs); - Assert.fail("insufficient data to compute t statistic, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data to compute t statistic, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { TestUtils.tTest(mu, tooShortObs); - Assert.fail("insufficient data to perform t test, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data to perform t test, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { TestUtils.t(mu, (SummaryStatistics) null); - Assert.fail("insufficient data to compute t statistic, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data to compute t statistic, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } try { TestUtils.tTest(mu, (SummaryStatistics) null); - Assert.fail("insufficient data to perform t test, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data to perform t test, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } } @@ -295,15 +296,15 @@ public class TestUtilsTest { try { TestUtils.tTest(0d, oneSidedP, 95); - Assert.fail("alpha out of range, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("alpha out of range, OutOfRangeException expected"); + } catch (OutOfRangeException ex) { // expected } try { TestUtils.tTest(0d, oneSidedPStats, 95); - Assert.fail("alpha out of range, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("alpha out of range, OutOfRangeException expected"); + } catch (OutOfRangeException ex) { // expected } @@ -342,57 +343,57 @@ public class TestUtilsTest { try { TestUtils.tTest(sample1, sample2, .95); - Assert.fail("alpha out of range, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("alpha out of range, OutOfRangeException expected"); + } catch (OutOfRangeException ex) { // expected } try { TestUtils.tTest(sampleStats1, sampleStats2, .95); - Assert.fail("alpha out of range, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("alpha out of range, OutOfRangeException expected"); + } catch (OutOfRangeException ex) { // expected } try { TestUtils.tTest(sample1, tooShortObs, .01); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { TestUtils.tTest(sampleStats1, (SummaryStatistics) null, .01); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } try { TestUtils.tTest(sample1, tooShortObs); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { TestUtils.tTest(sampleStats1, (SummaryStatistics) null); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } try { TestUtils.t(sample1, tooShortObs); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NumberIsTooSmallException expected"); + } catch (NumberIsTooSmallException ex) { // expected } try { TestUtils.t(sampleStats1, (SummaryStatistics) null); - Assert.fail("insufficient data, MathIllegalArgumentException expected"); - } catch (MathIllegalArgumentException ex) { + Assert.fail("insufficient data, NullArgumentException expected"); + } catch (NullArgumentException ex) { // expected } }