1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * This is not the original file distributed by the Apache Software Foundation
20 * It has been modified by the Hipparchus project
21 */
22 package org.hipparchus.stat.inference;
23
24 import org.hipparchus.distribution.continuous.TDistribution;
25 import org.hipparchus.exception.LocalizedCoreFormats;
26 import org.hipparchus.exception.MathIllegalArgumentException;
27 import org.hipparchus.exception.MathIllegalStateException;
28 import org.hipparchus.exception.NullArgumentException;
29 import org.hipparchus.stat.LocalizedStatFormats;
30 import org.hipparchus.stat.StatUtils;
31 import org.hipparchus.stat.descriptive.StatisticalSummary;
32 import org.hipparchus.util.FastMath;
33 import org.hipparchus.util.MathUtils;
34
35 /**
36 * An implementation for Student's t-tests.
37 * <p>
38 * Tests can be:
39 * <ul>
40 * <li>One-sample or two-sample</li>
41 * <li>One-sided or two-sided</li>
42 * <li>Paired or unpaired (for two-sample tests)</li>
43 * <li>Homoscedastic (equal variance assumption) or heteroscedastic
44 * (for two sample tests)</li>
45 * <li>Fixed significance level (boolean-valued) or returning p-values.</li>
46 * </ul>
47 * <p>
48 * Test statistics are available for all tests. Methods including "Test" in
49 * in their names perform tests, all other methods return t-statistics. Among
50 * the "Test" methods, <code>double-</code>valued methods return p-values;
51 * <code>boolean-</code>valued methods perform fixed significance level tests.
52 * Significance levels are always specified as numbers between 0 and 0.5
53 * (e.g. tests at the 95% level use <code>alpha=0.05</code>).
54 * <p>
55 * Input to tests can be either <code>double[]</code> arrays or
56 * {@link StatisticalSummary} instances.
57 * <p>
58 * Uses Hipparchus {@link org.hipparchus.distribution.continuous.TDistribution}
59 * implementation to estimate exact p-values.
60 */
61 public class TTest { // NOPMD - this is not a Junit test class, PMD false positive here
62
63 /** Empty constructor.
64 * <p>
65 * This constructor is not strictly necessary, but it prevents spurious
66 * javadoc warnings with JDK 18 and later.
67 * </p>
68 * @since 3.0
69 */
70 public TTest() { // NOPMD - unnecessary constructor added intentionally to make javadoc happy
71 // nothing to do
72 }
73
74 /**
75 * Computes a paired, 2-sample t-statistic based on the data in the input
76 * arrays. The t-statistic returned is equivalent to what would be returned by
77 * computing the one-sample t-statistic {@link #t(double, double[])}, with
78 * <code>mu = 0</code> and the sample array consisting of the (signed)
79 * differences between corresponding entries in <code>sample1</code> and
80 * <code>sample2.</code>
81 * <p>* <strong>Preconditions</strong>:</p>
82 * <ul>
83 * <li>The input arrays must have the same length and their common length
84 * must be at least 2.
85 * </li></ul>
86 *
87 * @param sample1 array of sample data values
88 * @param sample2 array of sample data values
89 * @return t statistic
90 * @throws NullArgumentException if the arrays are <code>null</code>
91 * @throws MathIllegalArgumentException if the arrays are empty
92 * @throws MathIllegalArgumentException if the length of the arrays is not equal
93 * @throws MathIllegalArgumentException if the length of the arrays is < 2
94 */
95 public double pairedT(final double[] sample1, final double[] sample2)
96 throws MathIllegalArgumentException, NullArgumentException {
97
98 checkSampleData(sample1);
99 checkSampleData(sample2);
100 double meanDifference = StatUtils.meanDifference(sample1, sample2);
101 return t(meanDifference, 0,
102 StatUtils.varianceDifference(sample1, sample2, meanDifference),
103 sample1.length);
104 }
105
106 /**
107 * Returns the <i>observed significance level</i>, or
108 * <i> p-value</i>, associated with a paired, two-sample, two-tailed t-test
109 * based on the data in the input arrays.
110 * <p>
111 * The number returned is the smallest significance level
112 * at which one can reject the null hypothesis that the mean of the paired
113 * differences is 0 in favor of the two-sided alternative that the mean paired
114 * difference is not equal to 0. For a one-sided test, divide the returned
115 * value by 2.</p>
116 * <p>
117 * This test is equivalent to a one-sample t-test computed using
118 * {@link #tTest(double, double[])} with <code>mu = 0</code> and the sample
119 * array consisting of the signed differences between corresponding elements of
120 * <code>sample1</code> and <code>sample2.</code></p>
121 * <p>
122 * <strong>Usage Note:</strong><br>
123 * The validity of the p-value depends on the assumptions of the parametric
124 * t-test procedure, as discussed
125 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
126 * here</a></p>
127 * <p><strong>Preconditions</strong>:</p>
128 * <ul>
129 * <li>The input array lengths must be the same and their common length must
130 * be at least 2.
131 * </li></ul>
132 *
133 * @param sample1 array of sample data values
134 * @param sample2 array of sample data values
135 * @return p-value for t-test
136 * @throws NullArgumentException if the arrays are <code>null</code>
137 * @throws MathIllegalArgumentException if the arrays are empty
138 * @throws MathIllegalArgumentException if the length of the arrays is not equal
139 * @throws MathIllegalArgumentException if the length of the arrays is < 2
140 * @throws MathIllegalStateException if an error occurs computing the p-value
141 */
142 public double pairedTTest(final double[] sample1, final double[] sample2)
143 throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {
144
145 double meanDifference = StatUtils.meanDifference(sample1, sample2);
146 return tTest(meanDifference, 0,
147 StatUtils.varianceDifference(sample1, sample2, meanDifference),
148 sample1.length);
149 }
150
151 /**
152 * Performs a paired t-test evaluating the null hypothesis that the
153 * mean of the paired differences between <code>sample1</code> and
154 * <code>sample2</code> is 0 in favor of the two-sided alternative that the
155 * mean paired difference is not equal to 0, with significance level
156 * <code>alpha</code>.
157 * <p>
158 * Returns <code>true</code> iff the null hypothesis can be rejected with
159 * confidence <code>1 - alpha</code>. To perform a 1-sided test, use
160 * <code>alpha * 2</code></p>
161 * <p>
162 * <strong>Usage Note:</strong><br>
163 * The validity of the test depends on the assumptions of the parametric
164 * t-test procedure, as discussed
165 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
166 * here</a></p>
167 * <p><strong>Preconditions</strong>:</p>
168 * <ul>
169 * <li>The input array lengths must be the same and their common length
170 * must be at least 2.
171 * </li>
172 * <li> <code> 0 < alpha < 0.5 </code>
173 * </li></ul>
174 *
175 * @param sample1 array of sample data values
176 * @param sample2 array of sample data values
177 * @param alpha significance level of the test
178 * @return true if the null hypothesis can be rejected with
179 * confidence 1 - alpha
180 * @throws NullArgumentException if the arrays are <code>null</code>
181 * @throws MathIllegalArgumentException if the arrays are empty
182 * @throws MathIllegalArgumentException if the length of the arrays is not equal
183 * @throws MathIllegalArgumentException if the length of the arrays is < 2
184 * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
185 * @throws MathIllegalStateException if an error occurs computing the p-value
186 */
187 public boolean pairedTTest(final double[] sample1, final double[] sample2,
188 final double alpha)
189 throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {
190
191 checkSignificanceLevel(alpha);
192 return pairedTTest(sample1, sample2) < alpha;
193
194 }
195
196 /**
197 * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula">
198 * t statistic </a> given observed values and a comparison constant.
199 * <p>
200 * This statistic can be used to perform a one sample t-test for the mean.
201 * </p>
202 * <p><strong>Preconditions</strong>:</p>
203 * <ul>
204 * <li>The observed array length must be at least 2.
205 * </li></ul>
206 *
207 * @param mu comparison constant
208 * @param observed array of values
209 * @return t statistic
210 * @throws NullArgumentException if <code>observed</code> is <code>null</code>
211 * @throws MathIllegalArgumentException if the length of <code>observed</code> is < 2
212 */
213 public double t(final double mu, final double[] observed)
214 throws MathIllegalArgumentException, NullArgumentException {
215
216 checkSampleData(observed);
217 // No try-catch or advertised exception because args have just been checked
218 return t(StatUtils.mean(observed), mu, StatUtils.variance(observed),
219 observed.length);
220 }
221
222 /**
223 * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula">
224 * t statistic </a> to use in comparing the mean of the dataset described by
225 * <code>sampleStats</code> to <code>mu</code>.
226 * <p>
227 * This statistic can be used to perform a one sample t-test for the mean.
228 * </p>
229 * <p><strong>Preconditions</strong>:</p>
230 * <ul>
231 * <li><code>observed.getN() ≥ 2</code>.
232 * </li></ul>
233 *
234 * @param mu comparison constant
235 * @param sampleStats DescriptiveStatistics holding sample summary statitstics
236 * @return t statistic
237 * @throws NullArgumentException if <code>sampleStats</code> is <code>null</code>
238 * @throws MathIllegalArgumentException if the number of samples is < 2
239 */
240 public double t(final double mu, final StatisticalSummary sampleStats)
241 throws MathIllegalArgumentException, NullArgumentException {
242
243 checkSampleData(sampleStats);
244 return t(sampleStats.getMean(), mu, sampleStats.getVariance(),
245 sampleStats.getN());
246 }
247
248 /**
249 * Computes a 2-sample t statistic, under the hypothesis of equal
250 * subpopulation variances. To compute a t-statistic without the
251 * equal variances hypothesis, use {@link #t(double[], double[])}.
252 * <p>
253 * This statistic can be used to perform a (homoscedastic) two-sample
254 * t-test to compare sample means.</p>
255 * <p>
256 * The t-statistic is</p>
257 * <p>
258 * <code> t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code>
259 * </p><p>
260 * where <strong><code>n1</code></strong> is the size of first sample;
261 * <strong><code> n2</code></strong> is the size of second sample;
262 * <strong><code> m1</code></strong> is the mean of first sample;
263 * <strong><code> m2</code></strong> is the mean of second sample
264 * and <strong><code>var</code></strong> is the pooled variance estimate:
265 * </p><p>
266 * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code>
267 * </p><p>
268 * with <strong><code>var1</code></strong> the variance of the first sample and
269 * <strong><code>var2</code></strong> the variance of the second sample.
270 * </p>
271 * <p><strong>Preconditions</strong>:</p>
272 * <ul>
273 * <li>The observed array lengths must both be at least 2.
274 * </li></ul>
275 *
276 * @param sample1 array of sample data values
277 * @param sample2 array of sample data values
278 * @return t statistic
279 * @throws NullArgumentException if the arrays are <code>null</code>
280 * @throws MathIllegalArgumentException if the length of the arrays is < 2
281 */
282 public double homoscedasticT(final double[] sample1, final double[] sample2)
283 throws MathIllegalArgumentException, NullArgumentException {
284
285 checkSampleData(sample1);
286 checkSampleData(sample2);
287 // No try-catch or advertised exception because args have just been checked
288 return homoscedasticT(StatUtils.mean(sample1), StatUtils.mean(sample2),
289 StatUtils.variance(sample1), StatUtils.variance(sample2),
290 sample1.length, sample2.length);
291 }
292
293 /**
294 * Computes a 2-sample t statistic, without the hypothesis of equal
295 * subpopulation variances. To compute a t-statistic assuming equal
296 * variances, use {@link #homoscedasticT(double[], double[])}.
297 * <p>
298 * This statistic can be used to perform a two-sample t-test to compare
299 * sample means.</p>
300 * <p>
301 * The t-statistic is</p>
302 * <p>
303 * <code> t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code>
304 * </p><p>
305 * where <strong><code>n1</code></strong> is the size of the first sample
306 * <strong><code> n2</code></strong> is the size of the second sample;
307 * <strong><code> m1</code></strong> is the mean of the first sample;
308 * <strong><code> m2</code></strong> is the mean of the second sample;
309 * <strong><code> var1</code></strong> is the variance of the first sample;
310 * <strong><code> var2</code></strong> is the variance of the second sample;
311 * </p>
312 * <p><strong>Preconditions</strong>:</p>
313 * <ul>
314 * <li>The observed array lengths must both be at least 2.
315 * </li></ul>
316 *
317 * @param sample1 array of sample data values
318 * @param sample2 array of sample data values
319 * @return t statistic
320 * @throws NullArgumentException if the arrays are <code>null</code>
321 * @throws MathIllegalArgumentException if the length of the arrays is < 2
322 */
323 public double t(final double[] sample1, final double[] sample2)
324 throws MathIllegalArgumentException, NullArgumentException {
325
326 checkSampleData(sample1);
327 checkSampleData(sample2);
328 // No try-catch or advertised exception because args have just been checked
329 return t(StatUtils.mean(sample1), StatUtils.mean(sample2),
330 StatUtils.variance(sample1), StatUtils.variance(sample2),
331 sample1.length, sample2.length);
332 }
333
334 /**
335 * Computes a 2-sample t statistic, comparing the means of the datasets
336 * described by two {@link StatisticalSummary} instances, without the
337 * assumption of equal subpopulation variances. Use
338 * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to
339 * compute a t-statistic under the equal variances assumption.
340 * <p>
341 * This statistic can be used to perform a two-sample t-test to compare
342 * sample means.</p>
343 * <p>
344 * The returned t-statistic is</p>
345 * <p>
346 * <code> t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code>
347 * </p><p>
348 * where <strong><code>n1</code></strong> is the size of the first sample;
349 * <strong><code> n2</code></strong> is the size of the second sample;
350 * <strong><code> m1</code></strong> is the mean of the first sample;
351 * <strong><code> m2</code></strong> is the mean of the second sample
352 * <strong><code> var1</code></strong> is the variance of the first sample;
353 * <strong><code> var2</code></strong> is the variance of the second sample
354 * </p>
355 * <p><strong>Preconditions</strong>:</p>
356 * <ul>
357 * <li>The datasets described by the two Univariates must each contain
358 * at least 2 observations.
359 * </li></ul>
360 *
361 * @param sampleStats1 StatisticalSummary describing data from the first sample
362 * @param sampleStats2 StatisticalSummary describing data from the second sample
363 * @return t statistic
364 * @throws NullArgumentException if the sample statistics are <code>null</code>
365 * @throws MathIllegalArgumentException if the number of samples is < 2
366 */
367 public double t(final StatisticalSummary sampleStats1,
368 final StatisticalSummary sampleStats2)
369 throws MathIllegalArgumentException, NullArgumentException {
370
371 checkSampleData(sampleStats1);
372 checkSampleData(sampleStats2);
373 return t(sampleStats1.getMean(), sampleStats2.getMean(),
374 sampleStats1.getVariance(), sampleStats2.getVariance(),
375 sampleStats1.getN(), sampleStats2.getN());
376 }
377
378 /**
379 * Computes a 2-sample t statistic, comparing the means of the datasets
380 * described by two {@link StatisticalSummary} instances, under the
381 * assumption of equal subpopulation variances. To compute a t-statistic
382 * without the equal variances assumption, use
383 * {@link #t(StatisticalSummary, StatisticalSummary)}.
384 * <p>
385 * This statistic can be used to perform a (homoscedastic) two-sample
386 * t-test to compare sample means.</p>
387 * <p>
388 * The t-statistic returned is</p>
389 * <p>
390 * <code> t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code>
391 * </p><p>
392 * where <strong><code>n1</code></strong> is the size of first sample;
393 * <strong><code> n2</code></strong> is the size of second sample;
394 * <strong><code> m1</code></strong> is the mean of first sample;
395 * <strong><code> m2</code></strong> is the mean of second sample
396 * and <strong><code>var</code></strong> is the pooled variance estimate:
397 * </p><p>
398 * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code>
399 * </p><p>
400 * with <strong><code>var1</code></strong> the variance of the first sample and
401 * <strong><code>var2</code></strong> the variance of the second sample.
402 * </p>
403 * <p><strong>Preconditions</strong>:</p>
404 * <ul>
405 * <li>The datasets described by the two Univariates must each contain
406 * at least 2 observations.
407 * </li></ul>
408 *
409 * @param sampleStats1 StatisticalSummary describing data from the first sample
410 * @param sampleStats2 StatisticalSummary describing data from the second sample
411 * @return t statistic
412 * @throws NullArgumentException if the sample statistics are <code>null</code>
413 * @throws MathIllegalArgumentException if the number of samples is < 2
414 */
415 public double homoscedasticT(final StatisticalSummary sampleStats1,
416 final StatisticalSummary sampleStats2)
417 throws MathIllegalArgumentException, NullArgumentException {
418
419 checkSampleData(sampleStats1);
420 checkSampleData(sampleStats2);
421 return homoscedasticT(sampleStats1.getMean(), sampleStats2.getMean(),
422 sampleStats1.getVariance(), sampleStats2.getVariance(),
423 sampleStats1.getN(), sampleStats2.getN());
424 }
425
426 /**
427 * Returns the <i>observed significance level</i>, or
428 * <i>p-value</i>, associated with a one-sample, two-tailed t-test
429 * comparing the mean of the input array with the constant <code>mu</code>.
430 * <p>
431 * The number returned is the smallest significance level
432 * at which one can reject the null hypothesis that the mean equals
433 * <code>mu</code> in favor of the two-sided alternative that the mean
434 * is different from <code>mu</code>. For a one-sided test, divide the
435 * returned value by 2.</p>
436 * <p>
437 * <strong>Usage Note:</strong><br>
438 * The validity of the test depends on the assumptions of the parametric
439 * t-test procedure, as discussed
440 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a>
441 * </p>
442 * <p><strong>Preconditions</strong>:</p>
443 * <ul>
444 * <li>The observed array length must be at least 2.
445 * </li></ul>
446 *
447 * @param mu constant value to compare sample mean against
448 * @param sample array of sample data values
449 * @return p-value
450 * @throws NullArgumentException if the sample array is <code>null</code>
451 * @throws MathIllegalArgumentException if the length of the array is < 2
452 * @throws MathIllegalStateException if an error occurs computing the p-value
453 */
454 public double tTest(final double mu, final double[] sample)
455 throws MathIllegalArgumentException, NullArgumentException,
456 MathIllegalStateException {
457
458 checkSampleData(sample);
459 // No try-catch or advertised exception because args have just been checked
460 return tTest(StatUtils.mean(sample), mu, StatUtils.variance(sample),
461 sample.length);
462 }
463
464 /**
465 * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
466 * two-sided t-test</a> evaluating the null hypothesis that the mean of the population from
467 * which <code>sample</code> is drawn equals <code>mu</code>.
468 * <p>
469 * Returns <code>true</code> iff the null hypothesis can be
470 * rejected with confidence <code>1 - alpha</code>. To
471 * perform a 1-sided test, use <code>alpha * 2</code></p>
472 * <p>* <strong>Examples:</strong></p>
473 * <ol>
474 * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
475 * the 95% level, use <br><code>tTest(mu, sample, 0.05) </code>
476 * </li>
477 * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code>
478 * at the 99% level, first verify that the measured sample mean is less
479 * than <code>mu</code> and then use
480 * <br><code>tTest(mu, sample, 0.02) </code>
481 * </li></ol>
482 * <p>
483 * <strong>Usage Note:</strong><br>
484 * The validity of the test depends on the assumptions of the one-sample
485 * parametric t-test procedure, as discussed
486 * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a>
487 * </p>
488 * <p><strong>Preconditions</strong>:</p>
489 * <ul>
490 * <li>The observed array length must be at least 2.
491 * </li></ul>
492 *
493 * @param mu constant value to compare sample mean against
494 * @param sample array of sample data values
495 * @param alpha significance level of the test
496 * @return p-value
497 * @throws NullArgumentException if the sample array is <code>null</code>
498 * @throws MathIllegalArgumentException if the length of the array is < 2
499 * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
500 * @throws MathIllegalStateException if an error computing the p-value
501 */
502 public boolean tTest(final double mu, final double[] sample, final double alpha)
503 throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {
504
505 checkSignificanceLevel(alpha);
506 return tTest(mu, sample) < alpha;
507 }
508
509 /**
510 * Returns the <i>observed significance level</i>, or
511 * <i>p-value</i>, associated with a one-sample, two-tailed t-test
512 * comparing the mean of the dataset described by <code>sampleStats</code>
513 * with the constant <code>mu</code>.
514 * <p>
515 * The number returned is the smallest significance level
516 * at which one can reject the null hypothesis that the mean equals
517 * <code>mu</code> in favor of the two-sided alternative that the mean
518 * is different from <code>mu</code>. For a one-sided test, divide the
519 * returned value by 2.</p>
520 * <p>
521 * <strong>Usage Note:</strong><br>
522 * The validity of the test depends on the assumptions of the parametric
523 * t-test procedure, as discussed
524 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
525 * here</a></p>
526 * <p><strong>Preconditions</strong>:</p>
527 * <ul>
528 * <li>The sample must contain at least 2 observations.
529 * </li></ul>
530 *
531 * @param mu constant value to compare sample mean against
532 * @param sampleStats StatisticalSummary describing sample data
533 * @return p-value
534 * @throws NullArgumentException if <code>sampleStats</code> is <code>null</code>
535 * @throws MathIllegalArgumentException if the number of samples is < 2
536 * @throws MathIllegalStateException if an error occurs computing the p-value
537 */
538 public double tTest(final double mu, final StatisticalSummary sampleStats)
539 throws MathIllegalArgumentException, NullArgumentException,
540 MathIllegalStateException {
541
542 checkSampleData(sampleStats);
543 return tTest(sampleStats.getMean(), mu, sampleStats.getVariance(),
544 sampleStats.getN());
545 }
546
547 /**
548 * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
549 * two-sided t-test</a> evaluating the null hypothesis that the mean of the
550 * population from which the dataset described by <code>stats</code> is
551 * drawn equals <code>mu</code>.
552 * <p>
553 * Returns <code>true</code> iff the null hypothesis can be rejected with
554 * confidence <code>1 - alpha</code>. To perform a 1-sided test, use
555 * <code>alpha * 2.</code></p>
556 * <p>* <strong>Examples:</strong></p>
557 * <ol>
558 * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
559 * the 95% level, use <br><code>tTest(mu, sampleStats, 0.05) </code>
560 * </li>
561 * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code>
562 * at the 99% level, first verify that the measured sample mean is less
563 * than <code>mu</code> and then use
564 * <br><code>tTest(mu, sampleStats, 0.02) </code>
565 * </li></ol>
566 * <p>
567 * <strong>Usage Note:</strong><br>
568 * The validity of the test depends on the assumptions of the one-sample
569 * parametric t-test procedure, as discussed
570 * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a>
571 * </p>
572 * <p><strong>Preconditions</strong>:</p>
573 * <ul>
574 * <li>The sample must include at least 2 observations.
575 * </li></ul>
576 *
577 * @param mu constant value to compare sample mean against
578 * @param sampleStats StatisticalSummary describing sample data values
579 * @param alpha significance level of the test
580 * @return p-value
581 * @throws NullArgumentException if <code>sampleStats</code> is <code>null</code>
582 * @throws MathIllegalArgumentException if the number of samples is < 2
583 * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
584 * @throws MathIllegalStateException if an error occurs computing the p-value
585 */
586 public boolean tTest(final double mu, final StatisticalSummary sampleStats,
587 final double alpha)
588 throws MathIllegalArgumentException, NullArgumentException,
589 MathIllegalStateException {
590
591 checkSignificanceLevel(alpha);
592 return tTest(mu, sampleStats) < alpha;
593 }
594
595 /**
596 * Returns the <i>observed significance level</i>, or
597 * <i>p-value</i>, associated with a two-sample, two-tailed t-test
598 * comparing the means of the input arrays.
599 * <p>
600 * The number returned is the smallest significance level
601 * at which one can reject the null hypothesis that the two means are
602 * equal in favor of the two-sided alternative that they are different.
603 * For a one-sided test, divide the returned value by 2.</p>
604 * <p>
605 * The test does not assume that the underlying popuation variances are
606 * equal and it uses approximated degrees of freedom computed from the
607 * sample data to compute the p-value. The t-statistic used is as defined in
608 * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation
609 * to the degrees of freedom is used,
610 * as described
611 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
612 * here.</a> To perform the test under the assumption of equal subpopulation
613 * variances, use {@link #homoscedasticTTest(double[], double[])}.</p>
614 * <p>
615 * <strong>Usage Note:</strong><br>
616 * The validity of the p-value depends on the assumptions of the parametric
617 * t-test procedure, as discussed
618 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
619 * here</a></p>
620 * <p><strong>Preconditions</strong>:</p>
621 * <ul>
622 * <li>The observed array lengths must both be at least 2.
623 * </li></ul>
624 *
625 * @param sample1 array of sample data values
626 * @param sample2 array of sample data values
627 * @return p-value for t-test
628 * @throws NullArgumentException if the arrays are <code>null</code>
629 * @throws MathIllegalArgumentException if the length of the arrays is < 2
630 * @throws MathIllegalStateException if an error occurs computing the p-value
631 */
632 public double tTest(final double[] sample1, final double[] sample2)
633 throws MathIllegalArgumentException, NullArgumentException,
634 MathIllegalStateException {
635
636 checkSampleData(sample1);
637 checkSampleData(sample2);
638 // No try-catch or advertised exception because args have just been checked
639 return tTest(StatUtils.mean(sample1), StatUtils.mean(sample2),
640 StatUtils.variance(sample1), StatUtils.variance(sample2),
641 sample1.length, sample2.length);
642 }
643
644 /**
645 * Returns the <i>observed significance level</i>, or
646 * <i>p-value</i>, associated with a two-sample, two-tailed t-test
647 * comparing the means of the input arrays, under the assumption that
648 * the two samples are drawn from subpopulations with equal variances.
649 * To perform the test without the equal variances assumption, use
650 * {@link #tTest(double[], double[])}.
651 * <p>
652 * The number returned is the smallest significance level
653 * at which one can reject the null hypothesis that the two means are
654 * equal in favor of the two-sided alternative that they are different.
655 * For a one-sided test, divide the returned value by 2.</p>
656 * <p>
657 * A pooled variance estimate is used to compute the t-statistic. See
658 * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes
659 * minus 2 is used as the degrees of freedom.</p>
660 * <p>
661 * <strong>Usage Note:</strong><br>
662 * The validity of the p-value depends on the assumptions of the parametric
663 * t-test procedure, as discussed
664 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
665 * here</a></p>
666 * <p><strong>Preconditions</strong>:</p>
667 * <ul>
668 * <li>The observed array lengths must both be at least 2.
669 * </li></ul>
670 *
671 * @param sample1 array of sample data values
672 * @param sample2 array of sample data values
673 * @return p-value for t-test
674 * @throws NullArgumentException if the arrays are <code>null</code>
675 * @throws MathIllegalArgumentException if the length of the arrays is < 2
676 * @throws MathIllegalStateException if an error occurs computing the p-value
677 */
678 public double homoscedasticTTest(final double[] sample1, final double[] sample2)
679 throws MathIllegalArgumentException, NullArgumentException,
680 MathIllegalStateException {
681
682 checkSampleData(sample1);
683 checkSampleData(sample2);
684 // No try-catch or advertised exception because args have just been checked
685 return homoscedasticTTest(StatUtils.mean(sample1),
686 StatUtils.mean(sample2),
687 StatUtils.variance(sample1),
688 StatUtils.variance(sample2),
689 sample1.length, sample2.length);
690 }
691
692 /**
693 * Performs a
694 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
695 * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code>
696 * and <code>sample2</code> are drawn from populations with the same mean,
697 * with significance level <code>alpha</code>. This test does not assume
698 * that the subpopulation variances are equal. To perform the test assuming
699 * equal variances, use
700 * {@link #homoscedasticTTest(double[], double[], double)}.
701 * <p>
702 * Returns <code>true</code> iff the null hypothesis that the means are
703 * equal can be rejected with confidence <code>1 - alpha</code>. To
704 * perform a 1-sided test, use <code>alpha * 2</code></p>
705 * <p>
706 * See {@link #t(double[], double[])} for the formula used to compute the
707 * t-statistic. Degrees of freedom are approximated using the
708 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
709 * Welch-Satterthwaite approximation.</a></p>
710 * <p>* <strong>Examples:</strong></p>
711 * <ol>
712 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
713 * the 95% level, use
714 * <br><code>tTest(sample1, sample2, 0.05). </code>
715 * </li>
716 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code>,
717 * at the 99% level, first verify that the measured mean of <code>sample 1</code>
718 * is less than the mean of <code>sample 2</code> and then use
719 * <br><code>tTest(sample1, sample2, 0.02) </code>
720 * </li></ol>
721 * <p>
722 * <strong>Usage Note:</strong><br>
723 * The validity of the test depends on the assumptions of the parametric
724 * t-test procedure, as discussed
725 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
726 * here</a></p>
727 * <p><strong>Preconditions</strong>:</p>
728 * <ul>
729 * <li>The observed array lengths must both be at least 2.
730 * </li>
731 * <li> <code> 0 < alpha < 0.5 </code>
732 * </li></ul>
733 *
734 * @param sample1 array of sample data values
735 * @param sample2 array of sample data values
736 * @param alpha significance level of the test
737 * @return true if the null hypothesis can be rejected with
738 * confidence 1 - alpha
739 * @throws NullArgumentException if the arrays are <code>null</code>
740 * @throws MathIllegalArgumentException if the length of the arrays is < 2
741 * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
742 * @throws MathIllegalStateException if an error occurs computing the p-value
743 */
744 public boolean tTest(final double[] sample1, final double[] sample2,
745 final double alpha)
746 throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {
747
748 checkSignificanceLevel(alpha);
749 return tTest(sample1, sample2) < alpha;
750 }
751
752 /**
753 * Performs a
754 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
755 * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code>
756 * and <code>sample2</code> are drawn from populations with the same mean,
757 * with significance level <code>alpha</code>, assuming that the
758 * subpopulation variances are equal. Use
759 * {@link #tTest(double[], double[], double)} to perform the test without
760 * the assumption of equal variances.
761 * <p>
762 * Returns <code>true</code> iff the null hypothesis that the means are
763 * equal can be rejected with confidence <code>1 - alpha</code>. To
764 * perform a 1-sided test, use <code>alpha * 2.</code> To perform the test
765 * without the assumption of equal subpopulation variances, use
766 * {@link #tTest(double[], double[], double)}.</p>
767 * <p>
768 * A pooled variance estimate is used to compute the t-statistic. See
769 * {@link #t(double[], double[])} for the formula. The sum of the sample
770 * sizes minus 2 is used as the degrees of freedom.</p>
771 * <p><strong>Examples:</strong></p>
772 * <ol>
773 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
774 * the 95% level, use <br><code>tTest(sample1, sample2, 0.05). </code>
775 * </li>
776 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2, </code>
777 * at the 99% level, first verify that the measured mean of
778 * <code>sample 1</code> is less than the mean of <code>sample 2</code>
779 * and then use
780 * <br><code>tTest(sample1, sample2, 0.02) </code>
781 * </li></ol>
782 * <p>
783 * <strong>Usage Note:</strong><br>
784 * The validity of the test depends on the assumptions of the parametric
785 * t-test procedure, as discussed
786 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
787 * here</a></p>
788 * <p><strong>Preconditions</strong>:</p>
789 * <ul>
790 * <li>The observed array lengths must both be at least 2.
791 * </li>
792 * <li> <code> 0 < alpha < 0.5 </code>
793 * </li></ul>
794 *
795 * @param sample1 array of sample data values
796 * @param sample2 array of sample data values
797 * @param alpha significance level of the test
798 * @return true if the null hypothesis can be rejected with
799 * confidence 1 - alpha
800 * @throws NullArgumentException if the arrays are <code>null</code>
801 * @throws MathIllegalArgumentException if the length of the arrays is < 2
802 * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
803 * @throws MathIllegalStateException if an error occurs computing the p-value
804 */
805 public boolean homoscedasticTTest(final double[] sample1, final double[] sample2,
806 final double alpha)
807 throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {
808
809 checkSignificanceLevel(alpha);
810 return homoscedasticTTest(sample1, sample2) < alpha;
811 }
812
813 /**
814 * Returns the <i>observed significance level</i>, or
815 * <i>p-value</i>, associated with a two-sample, two-tailed t-test
816 * comparing the means of the datasets described by two StatisticalSummary
817 * instances.
818 * <p>
819 * The number returned is the smallest significance level
820 * at which one can reject the null hypothesis that the two means are
821 * equal in favor of the two-sided alternative that they are different.
822 * For a one-sided test, divide the returned value by 2.</p>
823 * <p>
824 * The test does not assume that the underlying population variances are
825 * equal and it uses approximated degrees of freedom computed from the
826 * sample data to compute the p-value. To perform the test assuming
827 * equal variances, use
828 * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.</p>
829 * <p>
830 * <strong>Usage Note:</strong><br>
831 * The validity of the p-value depends on the assumptions of the parametric
832 * t-test procedure, as discussed
833 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
834 * here</a></p>
835 * <p><strong>Preconditions</strong>:</p>
836 * <ul>
837 * <li>The datasets described by the two Univariates must each contain
838 * at least 2 observations.
839 * </li></ul>
840 *
841 * @param sampleStats1 StatisticalSummary describing data from the first sample
842 * @param sampleStats2 StatisticalSummary describing data from the second sample
843 * @return p-value for t-test
844 * @throws NullArgumentException if the sample statistics are <code>null</code>
845 * @throws MathIllegalArgumentException if the number of samples is < 2
846 * @throws MathIllegalStateException if an error occurs computing the p-value
847 */
848 public double tTest(final StatisticalSummary sampleStats1,
849 final StatisticalSummary sampleStats2)
850 throws MathIllegalArgumentException, NullArgumentException,
851 MathIllegalStateException {
852
853 checkSampleData(sampleStats1);
854 checkSampleData(sampleStats2);
855 return tTest(sampleStats1.getMean(), sampleStats2.getMean(),
856 sampleStats1.getVariance(), sampleStats2.getVariance(),
857 sampleStats1.getN(), sampleStats2.getN());
858 }
859
860 /**
861 * Returns the <i>observed significance level</i>, or
862 * <i>p-value</i>, associated with a two-sample, two-tailed t-test
863 * comparing the means of the datasets described by two StatisticalSummary
864 * instances, under the hypothesis of equal subpopulation variances. To
865 * perform a test without the equal variances assumption, use
866 * {@link #tTest(StatisticalSummary, StatisticalSummary)}.
867 * <p>
868 * The number returned is the smallest significance level
869 * at which one can reject the null hypothesis that the two means are
870 * equal in favor of the two-sided alternative that they are different.
871 * For a one-sided test, divide the returned value by 2.</p>
872 * <p>
873 * See {@link #homoscedasticT(double[], double[])} for the formula used to
874 * compute the t-statistic. The sum of the sample sizes minus 2 is used as
875 * the degrees of freedom.</p>
876 * <p>
877 * <strong>Usage Note:</strong><br>
878 * The validity of the p-value depends on the assumptions of the parametric
879 * t-test procedure, as discussed
880 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a>
881 * </p><p><strong>Preconditions</strong>:</p>
882 * <ul>
883 * <li>The datasets described by the two Univariates must each contain
884 * at least 2 observations.
885 * </li></ul>
886 *
887 * @param sampleStats1 StatisticalSummary describing data from the first sample
888 * @param sampleStats2 StatisticalSummary describing data from the second sample
889 * @return p-value for t-test
890 * @throws NullArgumentException if the sample statistics are <code>null</code>
891 * @throws MathIllegalArgumentException if the number of samples is < 2
892 * @throws MathIllegalStateException if an error occurs computing the p-value
893 */
894 public double homoscedasticTTest(final StatisticalSummary sampleStats1,
895 final StatisticalSummary sampleStats2)
896 throws MathIllegalArgumentException, NullArgumentException,
897 MathIllegalStateException {
898
899 checkSampleData(sampleStats1);
900 checkSampleData(sampleStats2);
901 return homoscedasticTTest(sampleStats1.getMean(),
902 sampleStats2.getMean(),
903 sampleStats1.getVariance(),
904 sampleStats2.getVariance(),
905 sampleStats1.getN(), sampleStats2.getN());
906 }
907
908 /**
909 * Performs a
910 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
911 * two-sided t-test</a> evaluating the null hypothesis that
912 * <code>sampleStats1</code> and <code>sampleStats2</code> describe
913 * datasets drawn from populations with the same mean, with significance
914 * level <code>alpha</code>. This test does not assume that the
915 * subpopulation variances are equal. To perform the test under the equal
916 * variances assumption, use
917 * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.
918 * <p>
919 * Returns <code>true</code> iff the null hypothesis that the means are
920 * equal can be rejected with confidence <code>1 - alpha</code>. To
921 * perform a 1-sided test, use <code>alpha * 2</code></p>
922 * <p>
923 * See {@link #t(double[], double[])} for the formula used to compute the
924 * t-statistic. Degrees of freedom are approximated using the
925 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
926 * Welch-Satterthwaite approximation.</a></p>
927 * <p>* <strong>Examples:</strong></p>
928 * <ol>
929 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
930 * the 95%, use
931 * <br><code>tTest(sampleStats1, sampleStats2, 0.05) </code>
932 * </li>
933 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code>
934 * at the 99% level, first verify that the measured mean of
935 * <code>sample 1</code> is less than the mean of <code>sample 2</code>
936 * and then use
937 * <br><code>tTest(sampleStats1, sampleStats2, 0.02) </code>
938 * </li></ol>
939 * <p>
940 * <strong>Usage Note:</strong><br>
941 * The validity of the test depends on the assumptions of the parametric
942 * t-test procedure, as discussed
943 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
944 * here</a></p>
945 * <p><strong>Preconditions</strong>:</p>
946 * <ul>
947 * <li>The datasets described by the two Univariates must each contain
948 * at least 2 observations.
949 * </li>
950 * <li> <code> 0 < alpha < 0.5 </code>
951 * </li></ul>
952 *
953 * @param sampleStats1 StatisticalSummary describing sample data values
954 * @param sampleStats2 StatisticalSummary describing sample data values
955 * @param alpha significance level of the test
956 * @return true if the null hypothesis can be rejected with
957 * confidence 1 - alpha
958 * @throws NullArgumentException if the sample statistics are <code>null</code>
959 * @throws MathIllegalArgumentException if the number of samples is < 2
960 * @throws MathIllegalArgumentException if <code>alpha</code> is not in the range (0, 0.5]
961 * @throws MathIllegalStateException if an error occurs computing the p-value
962 */
963 public boolean tTest(final StatisticalSummary sampleStats1,
964 final StatisticalSummary sampleStats2,
965 final double alpha)
966 throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {
967
968 checkSignificanceLevel(alpha);
969 return tTest(sampleStats1, sampleStats2) < alpha;
970 }
971
972 //----------------------------------------------- Protected methods
973
974 /**
975 * Computes approximate degrees of freedom for 2-sample t-test.
976 *
977 * @param v1 first sample variance
978 * @param v2 second sample variance
979 * @param n1 first sample n
980 * @param n2 second sample n
981 * @return approximate degrees of freedom
982 */
983 protected double df(double v1, double v2, double n1, double n2) {
984 return (((v1 / n1) + (v2 / n2)) * ((v1 / n1) + (v2 / n2))) /
985 ((v1 * v1) / (n1 * n1 * (n1 - 1d)) + (v2 * v2) /
986 (n2 * n2 * (n2 - 1d)));
987 }
988
989 /**
990 * Computes t test statistic for 1-sample t-test.
991 *
992 * @param m sample mean
993 * @param mu constant to test against
994 * @param v sample variance
995 * @param n sample n
996 * @return t test statistic
997 */
998 protected double t(final double m, final double mu,
999 final double v, final double n) {
1000 return (m - mu) / FastMath.sqrt(v / n);
1001 }
1002
1003 /**
1004 * Computes t test statistic for 2-sample t-test.
1005 * <p>
1006 * Does not assume that subpopulation variances are equal.</p>
1007 *
1008 * @param m1 first sample mean
1009 * @param m2 second sample mean
1010 * @param v1 first sample variance
1011 * @param v2 second sample variance
1012 * @param n1 first sample n
1013 * @param n2 second sample n
1014 * @return t test statistic
1015 */
1016 protected double t(final double m1, final double m2,
1017 final double v1, final double v2,
1018 final double n1, final double n2) {
1019 return (m1 - m2) / FastMath.sqrt((v1 / n1) + (v2 / n2));
1020 }
1021
1022 /**
1023 * Computes t test statistic for 2-sample t-test under the hypothesis
1024 * of equal subpopulation variances.
1025 *
1026 * @param m1 first sample mean
1027 * @param m2 second sample mean
1028 * @param v1 first sample variance
1029 * @param v2 second sample variance
1030 * @param n1 first sample n
1031 * @param n2 second sample n
1032 * @return t test statistic
1033 */
1034 protected double homoscedasticT(final double m1, final double m2,
1035 final double v1, final double v2,
1036 final double n1, final double n2) {
1037 final double pooledVariance = ((n1 - 1) * v1 + (n2 -1) * v2 ) / (n1 + n2 - 2);
1038 return (m1 - m2) / FastMath.sqrt(pooledVariance * (1d / n1 + 1d / n2));
1039 }
1040
1041 /**
1042 * Computes p-value for 2-sided, 1-sample t-test.
1043 *
1044 * @param m sample mean
1045 * @param mu constant to test against
1046 * @param v sample variance
1047 * @param n sample n
1048 * @return p-value
1049 * @throws MathIllegalStateException if an error occurs computing the p-value
1050 * @throws MathIllegalArgumentException if n is not greater than 1
1051 */
1052 protected double tTest(final double m, final double mu,
1053 final double v, final double n)
1054 throws MathIllegalArgumentException, MathIllegalStateException {
1055
1056 final double t = FastMath.abs(t(m, mu, v, n));
1057 final TDistribution distribution = new TDistribution( n - 1);
1058 return 2.0 * distribution.cumulativeProbability(-t);
1059
1060 }
1061
1062 /**
1063 * Computes p-value for 2-sided, 2-sample t-test.
1064 * <p>
1065 * Does not assume subpopulation variances are equal. Degrees of freedom
1066 * are estimated from the data.</p>
1067 *
1068 * @param m1 first sample mean
1069 * @param m2 second sample mean
1070 * @param v1 first sample variance
1071 * @param v2 second sample variance
1072 * @param n1 first sample n
1073 * @param n2 second sample n
1074 * @return p-value
1075 * @throws MathIllegalStateException if an error occurs computing the p-value
1076 * @throws MathIllegalArgumentException if the estimated degrees of freedom is not
1077 * strictly positive
1078 */
1079 protected double tTest(final double m1, final double m2,
1080 final double v1, final double v2,
1081 final double n1, final double n2)
1082 throws MathIllegalArgumentException, MathIllegalStateException {
1083
1084 final double t = FastMath.abs(t(m1, m2, v1, v2, n1, n2));
1085 final double degreesOfFreedom = df(v1, v2, n1, n2);
1086 final TDistribution distribution = new TDistribution(degreesOfFreedom);
1087 return 2.0 * distribution.cumulativeProbability(-t);
1088
1089 }
1090
1091 /**
1092 * Computes p-value for 2-sided, 2-sample t-test, under the assumption
1093 * of equal subpopulation variances.
1094 * <p>
1095 * The sum of the sample sizes minus 2 is used as degrees of freedom.</p>
1096 *
1097 * @param m1 first sample mean
1098 * @param m2 second sample mean
1099 * @param v1 first sample variance
1100 * @param v2 second sample variance
1101 * @param n1 first sample n
1102 * @param n2 second sample n
1103 * @return p-value
1104 * @throws MathIllegalStateException if an error occurs computing the p-value
1105 * @throws MathIllegalArgumentException if the estimated degrees of freedom is not
1106 * strictly positive
1107 */
1108 protected double homoscedasticTTest(double m1, double m2,
1109 double v1, double v2,
1110 double n1, double n2)
1111 throws MathIllegalArgumentException, MathIllegalStateException {
1112
1113 final double t = FastMath.abs(homoscedasticT(m1, m2, v1, v2, n1, n2));
1114 final double degreesOfFreedom = n1 + n2 - 2;
1115 final TDistribution distribution = new TDistribution(degreesOfFreedom);
1116 return 2.0 * distribution.cumulativeProbability(-t);
1117
1118 }
1119
1120 /**
1121 * Check significance level.
1122 *
1123 * @param alpha significance level
1124 * @throws MathIllegalArgumentException if the significance level is out of bounds.
1125 */
1126 private void checkSignificanceLevel(final double alpha)
1127 throws MathIllegalArgumentException {
1128
1129 if (alpha <= 0 || alpha > 0.5) {
1130 throw new MathIllegalArgumentException(LocalizedStatFormats.SIGNIFICANCE_LEVEL,
1131 alpha, 0.0, 0.5);
1132 }
1133
1134 }
1135
1136 /**
1137 * Check sample data.
1138 *
1139 * @param data Sample data.
1140 * @throws NullArgumentException if {@code data} is {@code null}.
1141 * @throws MathIllegalArgumentException if there is not enough sample data.
1142 */
1143 private void checkSampleData(final double[] data)
1144 throws MathIllegalArgumentException, NullArgumentException {
1145
1146 MathUtils.checkNotNull(data, LocalizedCoreFormats.INPUT_ARRAY);
1147 if (data.length < 2) {
1148 throw new MathIllegalArgumentException(
1149 LocalizedStatFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC,
1150 data.length, 2, true);
1151 }
1152
1153 }
1154
1155 /**
1156 * Check sample data.
1157 *
1158 * @param stat Statistical summary.
1159 * @throws NullArgumentException if {@code data} is {@code null}.
1160 * @throws MathIllegalArgumentException if there is not enough sample data.
1161 */
1162 private void checkSampleData(final StatisticalSummary stat)
1163 throws MathIllegalArgumentException, NullArgumentException {
1164
1165 MathUtils.checkNotNull(stat);
1166 if (stat.getN() < 2) {
1167 throw new MathIllegalArgumentException(
1168 LocalizedStatFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC,
1169 stat.getN(), 2, true);
1170 }
1171
1172 }
1173
1174 }