You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by md...@apache.org on 2003/06/25 03:35:47 UTC
cvs commit: jakarta-commons-sandbox/math/src/java/org/apache/commons/math/stat TestStatisticImpl.java TestStatistic.java
mdiggory 2003/06/24 18:35:47
Modified: math/src/test/org/apache/commons/math/stat
TestStatisticTest.java
math/src/java/org/apache/commons/math/stat
TestStatisticImpl.java TestStatistic.java
Log:
PR: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21003
Submitted by: phil@steitz.com
Revision Changes Path
1.2 +194 -6 jakarta-commons-sandbox/math/src/test/org/apache/commons/math/stat/TestStatisticTest.java
Index: TestStatisticTest.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/math/src/test/org/apache/commons/math/stat/TestStatisticTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestStatisticTest.java 21 Jun 2003 23:00:39 -0000 1.1
+++ TestStatisticTest.java 25 Jun 2003 01:35:46 -0000 1.2
@@ -96,26 +96,61 @@
;
}
+ try {
+ testStatistic.chiSquareTest(tooShortObs,tooShortEx);
+ fail("arguments too short, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+
double[] unMatchedObs = {0,1,2,3};
double[] unMatchedEx = {1,1,2};
try {
testStatistic.chiSquare(unMatchedEx,unMatchedObs);
- fail("arrays have different lengths, IllegalArgumentException expected");
+ fail("arrays have different lengths," +
+ " IllegalArgumentException expected");
} catch (IllegalArgumentException ex) {
;
- }
-
+ }
expected[0] = 0;
- assertEquals("chi-square statistic", Double.POSITIVE_INFINITY,
- testStatistic.chiSquare(expected,observed),Double.MIN_VALUE);
+ try {
+ testStatistic.chiSquareTest(expected, observed, .01);
+ fail("bad expected count, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ /** from http://www.vsenvirginia.org/stat/classpractice/Voter_Preferences_CP.pdf */
+ double[] observed1 = {504, 523, 72, 70, 31};
+ double[] expected1 = {480, 540, 84, 60, 36};
+ assertEquals("chi-square test statistic", 5.81,
+ testStatistic.chiSquare(expected1,observed1),10E-2);
+ assertEquals("chi-square p-value", 0.21,
+ testStatistic.chiSquareTest(expected1, observed1),10E-2);
+ assertTrue("chi-square test reject",
+ testStatistic.chiSquareTest(expected1, observed1, 0.3));
+ assertTrue("chi-square test accept",
+ !testStatistic.chiSquareTest(expected1, observed1, 0.1));
+ try {
+ testStatistic.chiSquareTest(expected1, observed1, 95);
+ fail("alpha out of range, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
}
public void testT(){
- double[] observed = {93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0,
+ double[] observed = {93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0,
94.0, 101.0, 88.0, 98.0, 94.0, 101.0, 92.0, 95.0};
double mu = 100.0;
+ Univariate sampleStats = new UnivariateImpl();
+ for (int i = 0; i < observed.length; i++) {
+ sampleStats.addValue(observed[i]);
+ }
+
assertEquals("t statistic", -2.82, testStatistic.t(mu, observed),
10E-3);
+ assertEquals("t statistic", -2.82, testStatistic.t(mu, sampleStats),
+ 10E-3);
double[] nullObserved = null;
try {
@@ -125,6 +160,14 @@
;
}
+ UnivariateImpl nullStats = null;
+ try {
+ testStatistic.t(mu, nullStats);
+ fail("arguments too short, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+
double[] emptyObs = {};
try {
testStatistic.t(mu, emptyObs);
@@ -133,12 +176,157 @@
;
}
+ Univariate emptyStats = new UnivariateImpl();
+ try {
+ testStatistic.t(mu, emptyStats);
+ fail("arguments too short, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+
double[] tooShortObs = {1.0};
try {
testStatistic.t(mu, tooShortObs);
fail("arguments too short, IllegalArgumentException expected");
} catch (IllegalArgumentException ex) {
;
+ }
+ try {
+ testStatistic.tTest(mu, tooShortObs);
+ fail("arguments too short, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+
+ Univariate tooShortStats = new UnivariateImpl();
+ tooShortStats.addValue(0d);
+ tooShortStats.addValue(2d);
+ try {
+ testStatistic.t(mu, tooShortStats);
+ fail("arguments too short, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.tTest(mu, tooShortStats);
+ fail("arguments too short, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+
+ /** Moore and McCabe Example 8.3, p 516 */
+ double[] oneSidedP = {2d, 0d, 6d, 6d, 3d, 3d, 2d, 3d, -6d, 6d, 6d,
+ 6d, 3d, 0d, 1d, 1d, 0d, 2d, 3d, 3d};
+ Univariate oneSidedPStats = new UnivariateImpl();
+ for (int i = 0; i < oneSidedP.length; i++) {
+ oneSidedPStats.addValue(oneSidedP[i]);
+ }
+ assertEquals("one sample t stat",3.86,
+ testStatistic.t(0d,oneSidedP),0.01);
+ assertEquals("one sample t stat",3.86,
+ testStatistic.t(0d,oneSidedPStats),0.01);
+ assertEquals("one sample p value",0.00052,
+ testStatistic.tTest(0d,oneSidedP)/2d,10E-5);
+ assertEquals("one sample p value",0.00052,
+ testStatistic.tTest(0d,oneSidedPStats)/2d,10E-5);
+ assertTrue("one sample t-test reject",
+ testStatistic.tTest(0d,oneSidedP,0.01));
+ assertTrue("one sample t-test reject",
+ testStatistic.tTest(0d,oneSidedPStats,0.01));
+ assertTrue("one sample t-test accept",
+ !testStatistic.tTest(0d,oneSidedP,0.0001));
+ assertTrue("one sample t-test accept",
+ !testStatistic.tTest(0d,oneSidedPStats,0.0001));
+ try {
+ testStatistic.tTest(0d,oneSidedP, 95);
+ fail("alpha out of range, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.tTest(0d,oneSidedPStats, 95);
+ fail("alpha out of range, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+
+ /** Moore and McCabe Example 8.12, p 552 */
+ double[] sample1 = {7d, -4d, 18d, 17d, -3d, -5d, 1d, 10d, 11d, -2d};
+ double[] sample2 = {-1d, 12d, -1d, -3d, 3d, -5d, 5d, 2d, -11d, -1d, -3d};
+ Univariate sampleStats1 = new UnivariateImpl();
+ for (int i = 0; i < sample1.length; i++) {
+ sampleStats1.addValue(sample1[i]);
+ }
+ Univariate sampleStats2 = new UnivariateImpl();
+ for (int i = 0; i < sample2.length; i++) {
+ sampleStats2.addValue(sample2[i]);
+ }
+ //FIXME: textbook example reported t stat uses pooled variance
+ // should replace with R-verified example
+ assertEquals("two sample t stat",1.634,
+ testStatistic.t(sample1, sample2), 0.1);
+ assertEquals("two sample t stat",1.634,
+ testStatistic.t(sampleStats1, sampleStats2), 0.1);
+ // This test is OK, since book reports non-pooled exact p-value
+ assertEquals("two sample p value",0.059,
+ testStatistic.tTest(sample1, sample2)/2d, 10E-3);
+ assertEquals("two sample p value",0.059,
+ testStatistic.tTest(sampleStats1, sampleStats2)/2d, 10E-3);
+ assertTrue("two sample t-test reject",
+ testStatistic.tTest(sample1, sample2, 0.2));
+ assertTrue("two sample t-test reject",
+ testStatistic.tTest(sampleStats1, sampleStats2, 0.2));
+ assertTrue("two sample t-test accept",
+ !testStatistic.tTest(sample1, sample2,0.1));
+ assertTrue("two sample t-test accept",
+ !testStatistic.tTest(sampleStats1, sampleStats2,0.1));
+ try {
+ testStatistic.tTest(sample1, sample2, 95);
+ fail("alpha out of range, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.tTest(sampleStats1, sampleStats2, 95);
+ fail("alpha out of range, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.tTest(sample1, tooShortObs, .01);
+ fail("insufficient data, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.tTest(sampleStats1, tooShortStats, .01);
+ fail("insufficient data, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.tTest(sample1, tooShortObs);
+ fail("insufficient data, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.tTest(sampleStats1, tooShortStats);
+ fail("insufficient data, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.t(sample1, tooShortObs);
+ fail("insufficient data, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
+ }
+ try {
+ testStatistic.t(sampleStats1, tooShortStats);
+ fail("insufficient data, IllegalArgumentException expected");
+ } catch (IllegalArgumentException ex) {
+ ;
}
}
}
1.2 +330 -41 jakarta-commons-sandbox/math/src/java/org/apache/commons/math/stat/TestStatisticImpl.java
Index: TestStatisticImpl.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/stat/TestStatisticImpl.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestStatisticImpl.java 21 Jun 2003 23:00:39 -0000 1.1
+++ TestStatisticImpl.java 25 Jun 2003 01:35:46 -0000 1.2
@@ -54,18 +54,13 @@
package org.apache.commons.math.stat;
+import org.apache.commons.math.stat.distribution.DistributionFactory;
+import org.apache.commons.math.stat.distribution.TDistribution;
+import org.apache.commons.math.stat.distribution.ChiSquaredDistribution;
/**
- * Implements the following test statistics <ul>
- * <li>
- * <a href ="http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm">
- * Chi-Square</a>
- * </li>
- * <li>
- * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda352.htm">
- * One Sample t-test</a>
- * </li>
- * </ul>
+ * Implements test statistics defined in the TestStatistic interface.
+ *
* @author Phil Steitz
* @version $Revision$ $Date$
*
@@ -73,61 +68,355 @@
public class TestStatisticImpl implements TestStatistic {
/**
- * Default constructor.
+ * Default constructor
*/
public TestStatisticImpl() {
}
/**
- * Computes Chi-Square statistic given observed and expected counts <br>
- * <strong>Algorithm</strong>:
- * http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm <br>
- * <strong>Numerical considerations</strong>: none <br>
* @param observed array of observed frequency counts
* @param expected array of expected frequency counts
- * @throws IllegalArgumentException if input arrays have different lengths
+ * @return chi-square test statistic
+ * @throws IllegalArgumentException if preconditions are not met
* or length is less than 2
*/
- public double chiSquare(double[] expected, double[] observed) {
+ public double chiSquare(double[] expected, double[] observed)
+ throws IllegalArgumentException {
double sumSq = 0.0d;
double dev = 0.0d;
if ((expected.length < 2) || (expected.length != observed.length)) {
throw new IllegalArgumentException
("observed, expected array lengths incorrect");
}
+ if ((StatUtils.min(expected) <= 0) || (StatUtils.min(observed) < 0)) {
+ throw new IllegalArgumentException
+ ("observed counts must be non-negative," +
+ " expected counts must be postive");
+ }
for (int i = 0; i < observed.length; i++) {
dev = (observed[i] - expected[i]);
sumSq += dev * dev / expected[i];
}
return sumSq;
- }
+ }
+
+ /**
+ * @param observed array of observed frequency counts
+ * @param expected array of exptected frequency counts
+ * @return p-value
+ * @throws IllegalArgumentException if preconditions are not met
+ */
+ public double chiSquareTest(double[] expected, double[] observed)
+ throws IllegalArgumentException {
+ ChiSquaredDistribution chiSquaredDistribution =
+ DistributionFactory.newInstance().createChiSquareDistribution
+ ((double) expected.length - 1);
+ return 1 - chiSquaredDistribution.cummulativeProbability(
+ chiSquare(expected, observed));
+ }
+
+ /**
+ * @param observed array of observed frequency counts
+ * @param expected array of exptected frequency counts
+ * @param alpha significance level of the test
+ * @return true iff null hypothesis can be rejected with confidence
+ * 1 - alpha
+ * @throws IllegalArgumentException if preconditions are not met
+ */
+ public boolean chiSquareTest(double[] expected, double[] observed,
+ double alpha)
+ throws IllegalArgumentException {
+ if ((alpha <= 0) || (alpha > 0.5)) {
+ throw new IllegalArgumentException
+ ("bad significance level: " + alpha);
+ }
+ return (chiSquareTest(expected, observed) < alpha);
+ }
/**
- * Computes t statistic given observed values<br/>
- * <strong>Algorithm</strong>:
- * http://www.itl.nist.gov/div898/handbook/eda/section3/eda352.htm<br/>
- * <strong>Numerical considerations</strong>: none <br>
- * @param mu hypothesized mean value.
- * @param observed array of observed values
- * @return t-test statistic for the hypothesized mean and observed values.
- * @throws IllegalArgumentException if input array length is less than 2
+ * @param mu comparison constant
+ * @param observed array of values
+ * @return t statistic
+ * @throws IllegalArgumentException if input array length is less than 5
*/
- public double t(double mu, double[] observed) {
- if((observed == null) || (observed.length < 2)) {
+ public double t(double mu, double[] observed)
+ throws IllegalArgumentException {
+ if ((observed == null) || (observed.length < 5)) {
throw new IllegalArgumentException
- ("observed array length incorrect");
+ ("insufficient data for t statistic");
}
-
- // leverage Univariate to compute statistics
- Univariate univariate = new UnivariateImpl();
- for (int i = 0; i < observed.length; i++) {
- univariate.addValue(observed[i]);
- }
- double n = univariate.getN();
- double xbar = univariate.getMean();
- double std = univariate.getStandardDeviation();
-
- return (xbar - mu) / (std / Math.sqrt(n));
- }
+ return t(StatUtils.mean(observed), mu, StatUtils.variance(observed),
+ observed.length);
+ }
+
+ /**
+ * @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
+ */
+ public boolean tTest(double mu, double[] sample, double alpha)
+ throws IllegalArgumentException {
+ if ((alpha <= 0) || (alpha > 0.5)) {
+ throw new IllegalArgumentException
+ ("bad significance level: " + alpha);
+ }
+ return (tTest(mu, sample) < alpha);
+ }
+
+ /**
+ * @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 {
+ if ((sample1 == null) || (sample2 == null ||
+ Math.min(sample1.length, sample2.length) < 5)) {
+ throw new IllegalArgumentException
+ ("insufficient data for t statistic");
+ }
+ return t(StatUtils.mean(sample1), StatUtils.mean(sample2),
+ StatUtils.variance(sample1), StatUtils.variance(sample2),
+ (double) sample1.length, (double) sample2.length);
+ }
+
+ /**
+ *
+ * @param sample1 array of sample data values
+ * @param sample2 array of sample data values
+ * @return tTest p-value
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ public double tTest(double[] sample1, double[] sample2)
+ throws IllegalArgumentException {
+ if ((sample1 == null) || (sample2 == null ||
+ Math.min(sample1.length, sample2.length) < 5)) {
+ throw new IllegalArgumentException
+ ("insufficient data");
+ }
+ return tTest(StatUtils.mean(sample1), StatUtils.mean(sample2),
+ StatUtils.variance(sample1), StatUtils.variance(sample2),
+ (double) sample1.length, (double) sample2.length);
+ }
+
+ /**
+ * @param sample1 array of sample data values
+ * @param sample2 array of sample data values
+ * @param alpha significance level
+ * @return true if the null hypothesis can be rejected with
+ * confidence 1 - alpha
+ * @throws IllegalArgumentException if the preconditions are not met
+ */
+ public boolean tTest(double[] sample1, double[] sample2, double alpha)
+ throws IllegalArgumentException {
+ if ((alpha <= 0) || (alpha > 0.5)) {
+ throw new IllegalArgumentException
+ ("bad significance level: " + alpha);
+ }
+ return (tTest(sample1, sample2) < alpha);
+ }
+
+ /**
+ * @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
+ */
+ public double tTest(double mu, double[] sample)
+ throws IllegalArgumentException {
+ if ((sample == null) || (sample.length < 5)) {
+ throw new IllegalArgumentException
+ ("insufficient data for t statistic");
+ }
+ return tTest(StatUtils.mean(sample), mu, StatUtils.variance(sample),
+ sample.length);
+ }
+
+ /**
+ * @param mu comparison constant
+ * @param sampleStats Univariate holding sample summary statitstics
+ * @return t statistic
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ public double t(double mu, Univariate sampleStats)
+ throws IllegalArgumentException {
+ if ((sampleStats == null) || (sampleStats.getN() < 5)) {
+ throw new IllegalArgumentException
+ ("insufficient data for t statistic");
+ }
+ return t(sampleStats.getMean(), mu, sampleStats.getVariance(),
+ sampleStats.getN());
+ }
+
+ /**
+ * @param sampleStats1 Univariate describing data from the first sample
+ * @param sampleStats2 Univariate describing data from the second sample
+ * @return t statistic
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ public double t(Univariate sampleStats1, Univariate sampleStats2)
+ throws IllegalArgumentException {
+ if ((sampleStats1 == null) || (sampleStats2 == null ||
+ Math.min(sampleStats1.getN(), sampleStats2.getN()) < 5)) {
+ throw new IllegalArgumentException
+ ("insufficient data for t statistic");
+ }
+ return t(sampleStats1.getMean(), sampleStats2.getMean(),
+ sampleStats1.getVariance(), sampleStats2.getVariance(),
+ (double) sampleStats1.getN(), (double) sampleStats2.getN());
+ }
+
+ /**
+ * @param sampleStats1 Univariate describing data from the first sample
+ * @param sampleStats2 Univariate describing data from the second sample
+ * @return p-value for t-test
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ public double tTest(Univariate sampleStats1, Univariate sampleStats2)
+ throws IllegalArgumentException {
+ if ((sampleStats1 == null) || (sampleStats2 == null ||
+ Math.min(sampleStats1.getN(), sampleStats2.getN()) < 5)) {
+ throw new IllegalArgumentException
+ ("insufficient data for t statistic");
+ }
+ return tTest(sampleStats1.getMean(), sampleStats2.getMean(),
+ sampleStats1.getVariance(), sampleStats2.getVariance(),
+ (double) sampleStats1.getN(), (double) sampleStats2.getN());
+ }
+
+ /**
+ * @param sampleStats1 Univariate describing sample data values
+ * @param sampleStats2 Univariate 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
+ */
+ public boolean tTest(Univariate sampleStats1, Univariate sampleStats2,
+ double alpha) throws IllegalArgumentException {
+ if ((alpha <= 0) || (alpha > 0.5)) {
+ throw new IllegalArgumentException
+ ("bad significance level: " + alpha);
+ }
+ return (tTest(sampleStats1, sampleStats2) < alpha);
+ }
+
+ /**
+ * @param mu constant value to compare sample mean against
+ * @param sampleStats Univariate describing sample data values
+ * @param alpha significance level of the test
+ * @return p-value
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ public boolean tTest(double mu, Univariate sampleStats, double alpha)
+ throws IllegalArgumentException {
+ if ((alpha <= 0) || (alpha > 0.5)) {
+ throw new IllegalArgumentException
+ ("bad significance level: " + alpha);
+ }
+ return (tTest(mu, sampleStats) < alpha);
+ }
+
+ /**
+ * @param mu constant value to compare sample mean against
+ * @param sampleStats Univariate describing sample data
+ * @return p-value
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ public double tTest(double mu, Univariate sampleStats)
+ throws IllegalArgumentException {
+ if ((sampleStats == null) || (sampleStats.getN() < 5)) {
+ throw new IllegalArgumentException
+ ("insufficient data for t statistic");
+ }
+ return tTest(sampleStats.getMean(), mu, sampleStats.getVariance(),
+ sampleStats.getN());
+ }
+
+ //----------------------------------------------- Private 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
+ */
+ private 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 2-sample t-test.
+ *
+ * @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
+ */
+ private double t(double m1, double m2, double v1, double v2, double n1,
+ double n2) {
+ return (m1 - m2) / Math.sqrt((v1 / n1) + (v2 / n2));
+ }
+
+ /**
+ * 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
+ */
+ private double t(double m, double mu, double v, double n) {
+ return (m - mu) / Math.sqrt(v / n);
+ }
+
+ /**
+ * Computes p-value for 2-sided, 2-sample t-test.
+ *
+ * @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
+ */
+ private double tTest(double m1, double m2, double v1, double v2, double n1,
+ double n2) {
+ double t = Math.abs(t(m1, m2, v1, v2, n1, n2));
+ TDistribution tDistribution =
+ DistributionFactory.newInstance().createTDistribution
+ (df(v1, v2, n1, n2));
+ return 1.0 - tDistribution.cummulativeProbability(-t, t);
+ }
+
+ /**
+ * 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
+ */
+ private double tTest(double m, double mu, double v, double n) {
+ double t = Math.abs(t(m, mu, v, n));
+ TDistribution tDistribution =
+ DistributionFactory.newInstance().createTDistribution
+ (n - 1);
+ return 1.0 - tDistribution.cummulativeProbability(-t, t);
+ }
}
1.2 +463 -34 jakarta-commons-sandbox/math/src/java/org/apache/commons/math/stat/TestStatistic.java
Index: TestStatistic.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/math/src/java/org/apache/commons/math/stat/TestStatistic.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestStatistic.java 21 Jun 2003 23:00:39 -0000 1.1
+++ TestStatistic.java 25 Jun 2003 01:35:46 -0000 1.2
@@ -52,14 +52,8 @@
* <http://www.apache.org/>.
*/
package org.apache.commons.math.stat;
-
/**
- * Interfaces for the following test statistics <ul>
- * <li><a href ="http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm">
- * Chi-Square</a></li>
- * <li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda352.htm">
- * One Sample t-test</a></li>
- * </ul>
+ * A collection of commonly used test statistics and statistical tests.
*
* @author Phil Steitz
* @version $Revision$ $Date$
@@ -68,39 +62,474 @@
public interface TestStatistic {
/**
- * <strong>Description</strong>:
- * Computes Chi-Square statistic given observed and expected freqeuncy counts <br>
- * This statistic can be used to perform Chi-Square tests for goodness
- * of fit.<br>
- * <strong>Definition</strong>:
- * http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm <br>
- * <strong>Preconditions</strong>: <ul>
- * <li>Expected counts should all be positive. If any expected
- * counts are 0, the test will return INFINITY. Negative expected or observed counts
- * make the statistic meaningless.</li>
- * <li>The observed and expected arrays <i>must</i> have the same length and
- * their common length must be at least 2 </li>
- * </ul>
+ * Computes the <a href="http://www.itl.nist.gov/div898/handbook/eda
+ * /section3/eda35f.htm">Chi-Square statistic</a> comparing
+ * <code>observed</code> and <code>expected</code> freqeuncy counts.
+ * <p>
+ * This statistic can be used to perform Chi-Square tests.
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>Expected counts must all be positive.
+ * </li>
+ * <li>Observed counds must all be >= 0.
+ * </li>
+ * <li>The observed and expected arrays must have the same length and
+ * their common length must be at least 2.
+ * </li></ul><p>
+ * If any of the preconditions are not met, an
+ * <code>IllegalArgumentException</code> is thrown.
+ *
+ * @param observed array of observed frequency counts
+ * @param expected array of exptected frequency counts
+ * @return chiSquare statistic
+ * @throws IllegalArgumentException if preconditions are not met
+ */
+ double chiSquare(double[] expected, double[] observed)
+ throws IllegalArgumentException;
+
+ /**
+ * Returns the <i>observed significance level</i>, or <a href=
+ * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue">
+ * p-value</a>, associated with a <a href="http://www.itl.nist.gov/div898/
+ * handbook/eda/section3/eda35f.htm">Chi-square goodness of fit test</a>
+ * comparing the <code>observed</code> frequency counts to those in the
+ * <code>expected</code> array.
+ * <p>
+ * The number returned is the smallest significance level
+ * at which one can reject the null hypothesis that the observed counts
+ * conform to the frequency distribution described by the expected counts.
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>Expected counts must all be positive.
+ * </li>
+ * <li>Observed counds must all be >= 0.
+ * </li>
+ * <li>The observed and expected arrays must have the same length and
+ * their common length must be at least 2.
+ * </li></ul><p>
+ * If any of the preconditions are not met, an
+ * <code>IllegalArgumentException</code> is thrown.
+ *
* @param observed array of observed frequency counts
* @param expected array of exptected frequency counts
- * @throws IllegalArgumentException if input arrays have different lengths
- * or length is less than 2
+ * @return p-value
+ * @throws IllegalArgumentException if preconditions are not met
*/
- public double chiSquare(double[] expected, double[] observed);
+ double chiSquareTest(double[] expected, double[] observed)
+ throws IllegalArgumentException;
/**
- * <strong>Description</strong>:
- * Computes one sample, t-test statistic given observed values <br/>
- * This statistic can be used to perform one sample tests for means.<br/>
- * <strong>Definition</strong>:
- * http://www.itl.nist.gov/div898/handbook/eda/section3/eda352.htm<br/>
- * <strong>Preconditions</strong>: <ul>
- * <li>The observed array length <i>must</i> be at least 2.</li>
- * </ul>
- * @param mu hypothesized mean value.
- * @param observed array of observed values
+ * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/
+ * section3/eda35f.htm">Chi-square goodness of fit test</a> evaluating the
+ * null hypothesis that the observed counts conform to the frequency
+ * distribution described by the expected counts, with significance level
+ * <code>alpha</code>.
+ * <p>
+ * <strong>Example:</strong><br>
+ * To test the hypothesis that <code>observed</code> follows
+ * <code>expected</code> at the 99% level, use <p>
+ * <code>chiSquareTest(expected, observed, 0.01) </code>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>Expected counts must all be positive.
+ * </li>
+ * <li>Observed counds must all be >= 0.
+ * </li>
+ * <li>The observed and expected arrays must have the same length and
+ * their common length must be at least 2.
+ * <li> <code> 0 < alpha < 0.5 </code>
+ * </li></ul><p>
+ * If any of the preconditions are not met, an
+ * <code>IllegalArgumentException</code> is thrown.
+ *
+ * @param observed array of observed frequency counts
+ * @param expected array of exptected frequency counts
+ * @param alpha significance level of the test
+ * @return true iff null hypothesis can be rejected with confidence
+ * 1 - alpha
+ * @throws IllegalArgumentException if preconditions are not met
+ */
+ boolean chiSquareTest(double[] expected, double[] observed, double alpha)
+ throws IllegalArgumentException;
+
+ /**
+ * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/
+ * section2/prc22.htm#formula"> t statistic </a> given observed values and
+ * a comparison constant.
+ * <p>
+ * This statistic can be used to perform a one sample t-test for the mean.
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The observed array length must be at least 2.
+ * </li></ul>
+ *
+ * @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);
+ double t(double mu, double[] observed)
+ throws IllegalArgumentException;
+
+ /**
+ * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section3
+ * /prc31.htm">2-sample t statistic </a>, without the assumption of equal
+ * sample variances.
+ * <p>
+ * This statistic can be used to perform a two-sample t-test to compare
+ * sample means.
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The observed array lengths must both be at least 5.
+ * </li></ul>
+ *
+ * @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
+ */
+ double t(double[] sample1, double[] sample2)
+ throws IllegalArgumentException;
+
+ /**
+ * Returns the <i>observed significance level</i>, or <a href=
+ * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue">
+ * p-value</a>, associated with a two-sample, two-tailed t-test
+ * comparing the means of the input arrays.
+ * <p>
+ * 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.
+ * <p>
+ * The test does not assume that the underlying popuation variances are
+ * equal and it uses approximated degrees of freedom computed from the
+ * sample data as described <a href="http://www.itl.nist.gov/div898/
+ * handbook/prc/section3/prc31.htm">here</a>
+ * <p>
+ * <strong>Usage Note:</strong><br>
+ * The validity of the p-value depends on the assumptions of the parametric
+ * t-test procedure, as discussed <a href="http://www.basic.nwu.edu/
+ * statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The observed array lengths must both be at least 5.
+ * </li></ul>
+ *
+ * @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
+ */
+ double tTest(double[] sample1, double[] sample2)
+ throws IllegalArgumentException;
+
+ /**
+ * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/
+ * section3/eda353.htm">two-sided t-test</a> evaluating the null
+ * hypothesis that <code>sample1</code> and <code>sample2</code> are drawn
+ * from populations with the same mean, with significance level
+ * <code>alpha</code>.
+ * <p>
+ * Returns <code>true</code> iff the null hypothesis that the means are
+ * equal can be rejected with confidence <code>1 - alpha</code>. To
+ * perform a 1-sided test, use <code>alpha / 2</code>
+ * <p>
+ * <strong>Examples:</strong><br><ol>
+ * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
+ * the 95% level, use <br><code>tTest(sample1, sample2, 0.05) </code>
+ * </li>
+ * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code>
+ * at the 99% level, first verify that the measured mean of
+ * <code>sample 1</code> is less than the mean of <code>sample 2</code>
+ * and then use <br><code>tTest(sample1, sample2, 0.005) </code>
+ * </li></ol>
+ * <p>
+ * The test does not assume that the underlying popuation variances are
+ * equal and it uses approximated degrees of freedom computed from the
+ * sample data as described <a href="http://www.itl.nist.gov/div898/
+ * handbook/prc/section3/prc31.htm">here</a>
+ * <p>
+ * <strong>Usage Note:</strong><br>
+ * The validity of the test depends on the assumptions of the parametric
+ * t-test procedure, as discussed <a href="http://www.basic.nwu.edu/
+ * statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The observed array lengths must both be at least 5.
+ * </li>
+ * <li> <code> 0 < alpha < 0.5 </code>
+ * </li></ul>
+ *
+ * @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
+ */
+ boolean tTest(double[] sample1, double[] sample2, double alpha)
+ throws IllegalArgumentException;
+
+ /**
+ * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/
+ * section3/eda353.htm">two-sided t-test</a> evaluating the null
+ * hypothesis that the mean of the population from which
+ * <code>sample</code> is drawn equals <code>mu</code>.
+ * <p>
+ * Returns <code>true</code> iff the null hypothesis can be
+ * rejected with confidence <code>1 - alpha</code>. To
+ * perform a 1-sided test, use <code>alpha / 2</code>
+ * <p>
+ * <strong>Examples:</strong><br><ol>
+ * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
+ * the 95% level, use <br><code>tTest(mu, sample, 0.05) </code>
+ * </li>
+ * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code>
+ * at the 99% level, first verify that the measured sample mean is less
+ * than <code>mu</code> and then use
+ * <br><code>tTest(mu, sample, 0.005) </code>
+ * </li></ol>
+ * <p>
+ * <strong>Usage Note:</strong><br>
+ * The validity of the test depends on the assumptions of the one-sample
+ * parametric t-test procedure, as discussed
+ * <a href="http://www.basic.nwu.edu/statguidefiles/
+ * sg_glos.html#one-sample">here</a>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The observed array length must be at least 5.
+ * </li></ul>
+ *
+ * @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
+ */
+ boolean tTest(double mu, double[] sample, double alpha)
+ throws IllegalArgumentException;
+
+ /**
+ * Returns the <i>observed significance level</i>, or <a href=
+ * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue">
+ * p-value</a>, associated with a one-sample, two-tailed t-test
+ * comparing the mean of the input array with the constant <code>mu</code>.
+ * <p>
+ * The number returned is the smallest significance level
+ * at which one can reject the null hypothesis that the mean equals
+ * <code>mu</code> in favor of the two-sided alternative that the mean
+ * is different from <code>mu</code>. For a one-sided test, divide the
+ * returned value by 2.
+ * <p>
+ * <strong>Usage Note:</strong><br>
+ * The validity of the test depends on the assumptions of the parametric
+ * t-test procedure, as discussed <a href="http://www.basic.nwu.edu/
+ * statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The observed array length must be at least 5.
+ * </li></ul>
+ *
+ * @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
+ */
+ double tTest(double mu, double[] sample)
+ throws IllegalArgumentException;
+
+ /**
+ * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/
+ * section2/prc22.htm#formula"> t statistic </a> to use in comparing
+ * the dataset described by <code>sampleStats</code> to <code>mu</code>.
+ * <p>
+ * This statistic can be used to perform a one sample t-test for the mean.
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li><code>observed.getN() > = 2</code>.
+ * </li></ul>
+ *
+ * @param mu comparison constant
+ * @param sampleStats Univariate holding sample summary statitstics
+ * @return t statistic
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ double t(double mu, Univariate sampleStats)
+ throws IllegalArgumentException;
+
+ /**
+ * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section3
+ * /prc31.htm">2-sample t statistic </a>, comparing the datasets described
+ * by two Univariates without the assumption of equal sample variances.
+ * <p>
+ * This statistic can be used to perform a two-sample t-test to compare
+ * sample means.
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The datasets described by the two Univariates must each contain
+ * at least 5 observations.
+ * </li></ul>
+ *
+ * @param sampleStats1 Univariate describing data from the first sample
+ * @param sampleStats2 Univariate describing data from the second sample
+ * @return t statistic
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ double t(Univariate sampleStats1, Univariate sampleStats2)
+ throws IllegalArgumentException;
+
+ /**
+ * Returns the <i>observed significance level</i>, or <a href=
+ * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue">
+ * p-value</a>, associated with a two-sample, two-tailed t-test
+ * comparing the means of the datasets described by two Univariates.
+ * <p>
+ * 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.
+ * <p>
+ * The test does not assume that the underlying popuation variances are
+ * equal and it uses approximated degrees of freedom computed from the
+ * sample data as described <a href="http://www.itl.nist.gov/div898/
+ * handbook/prc/section3/prc31.htm">here</a>
+ * <p>
+ * <strong>Usage Note:</strong><br>
+ * The validity of the p-value depends on the assumptions of the parametric
+ * t-test procedure, as discussed <a href="http://www.basic.nwu.edu/
+ * statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The datasets described by the two Univariates must each contain
+ * at least 5 observations.
+ * </li></ul>
+ *
+ * @param sampleStats1 Univariate describing data from the first sample
+ * @param sampleStats2 Univariate describing data from the second sample
+ * @return p-value for t-test
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ double tTest(Univariate sampleStats1, Univariate sampleStats2)
+ throws IllegalArgumentException;
+
+ /**
+ * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/
+ * section3/eda353.htm">two-sided t-test</a> evaluating the null
+ * hypothesis that <code>sampleStats1</code> and <code>sampleStats2</code>
+ * describe datasets drawn from populations with the same mean, with
+ * significance level <code>alpha</code>.
+ * <p>
+ * Returns <code>true</code> iff the null hypothesis that the means are
+ * equal can be rejected with confidence <code>1 - alpha</code>. To
+ * perform a 1-sided test, use <code>alpha / 2</code>
+ * <p>
+ * <strong>Examples:</strong><br><ol>
+ * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
+ * the 95% level, use
+ * <br><code>tTest(sampleStats1, sampleStats2, 0.05) </code>
+ * </li>
+ * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code>
+ * at the 99% level, first verify that the measured mean of
+ * <code>sample 1</code> is less than the mean of <code>sample 2</code>
+ * and then use <br><code>tTest(sampleStats1, sampleStats2, 0.005) </code>
+ * </li></ol>
+ * <p>
+ * The test does not assume that the underlying popuation variances are
+ * equal and it uses approximated degrees of freedom computed from the
+ * sample data as described <a href="http://www.itl.nist.gov/div898/
+ * handbook/prc/section3/prc31.htm">here</a>
+ * <p>
+ * <strong>Usage Note:</strong><br>
+ * The validity of the test depends on the assumptions of the parametric
+ * t-test procedure, as discussed <a href="http://www.basic.nwu.edu/
+ * statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The datasets described by the two Univariates must each contain
+ * at least 5 observations.
+ * </li>
+ * <li> <code> 0 < alpha < 0.5 </code>
+ * </li></ul>
+ *
+ * @param sampleStats1 Univariate describing sample data values
+ * @param sampleStats2 Univariate 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
+ */
+ boolean tTest(Univariate sampleStats1, Univariate sampleStats2,
+ double alpha)
+ throws IllegalArgumentException;
+
+ /**
+ * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/
+ * section3/eda353.htm">two-sided t-test</a> evaluating the null
+ * hypothesis that the mean of the population from which the dataset
+ * described by <code>stats</code> is drawn equals <code>mu</code>.
+ * <p>
+ * Returns <code>true</code> iff the null hypothesis can be
+ * rejected with confidence <code>1 - alpha</code>. To
+ * perform a 1-sided test, use <code>alpha / 2</code>
+ * <p>
+ * <strong>Examples:</strong><br><ol>
+ * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
+ * the 95% level, use <br><code>tTest(mu, sampleStats, 0.05) </code>
+ * </li>
+ * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code>
+ * at the 99% level, first verify that the measured sample mean is less
+ * than <code>mu</code> and then use
+ * <br><code>tTest(mu, sampleStats, 0.005) </code>
+ * </li></ol>
+ * <p>
+ * <strong>Usage Note:</strong><br>
+ * The validity of the test depends on the assumptions of the one-sample
+ * parametric t-test procedure, as discussed
+ * <a href="http://www.basic.nwu.edu/statguidefiles/
+ * sg_glos.html#one-sample">here</a>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The sample must include at least 5 observations.
+ * </li></ul>
+ *
+ * @param mu constant value to compare sample mean against
+ * @param sampleStats Univariate describing sample data values
+ * @param alpha significance level of the test
+ * @return p-value
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ boolean tTest(double mu, Univariate sampleStats, double alpha)
+ throws IllegalArgumentException;
+
+ /**
+ * Returns the <i>observed significance level</i>, or <a href=
+ * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue">
+ * p-value</a>, associated with a one-sample, two-tailed t-test
+ * comparing the mean of the dataset described by <code>sampleStats</code>
+ * with the constant <code>mu</code>.
+ * <p>
+ * The number returned is the smallest significance level
+ * at which one can reject the null hypothesis that the mean equals
+ * <code>mu</code> in favor of the two-sided alternative that the mean
+ * is different from <code>mu</code>. For a one-sided test, divide the
+ * returned value by 2.
+ * <p>
+ * <strong>Usage Note:</strong><br>
+ * The validity of the test depends on the assumptions of the parametric
+ * t-test procedure, as discussed <a href="http://www.basic.nwu.edu/
+ * statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+ * <p>
+ * <strong>Preconditions</strong>: <ul>
+ * <li>The sample must contain at least 5 observations.
+ * </li></ul>
+ *
+ * @param mu constant value to compare sample mean against
+ * @param sampleStats Univariate describing sample data
+ * @return p-value
+ * @throws IllegalArgumentException if the precondition is not met
+ */
+ double tTest(double mu, Univariate sampleStats)
+ throws IllegalArgumentException;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org