001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math3.stat;
018
019 import org.apache.commons.math3.exception.MathIllegalArgumentException;
020 import org.apache.commons.math3.exception.NumberIsTooSmallException;
021 import org.apache.commons.math3.exception.DimensionMismatchException;
022 import org.apache.commons.math3.exception.NoDataException;
023 import org.apache.commons.math3.exception.util.LocalizedFormats;
024 import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
025 import org.apache.commons.math3.stat.descriptive.UnivariateStatistic;
026 import org.apache.commons.math3.stat.descriptive.moment.GeometricMean;
027 import org.apache.commons.math3.stat.descriptive.moment.Mean;
028 import org.apache.commons.math3.stat.descriptive.moment.Variance;
029 import org.apache.commons.math3.stat.descriptive.rank.Max;
030 import org.apache.commons.math3.stat.descriptive.rank.Min;
031 import org.apache.commons.math3.stat.descriptive.rank.Percentile;
032 import org.apache.commons.math3.stat.descriptive.summary.Product;
033 import org.apache.commons.math3.stat.descriptive.summary.Sum;
034 import org.apache.commons.math3.stat.descriptive.summary.SumOfLogs;
035 import org.apache.commons.math3.stat.descriptive.summary.SumOfSquares;
036
037 /**
038 * StatUtils provides static methods for computing statistics based on data
039 * stored in double[] arrays.
040 *
041 * @version $Id: StatUtils.java 1416643 2012-12-03 19:37:14Z tn $
042 */
043 public final class StatUtils {
044
045 /** sum */
046 private static final UnivariateStatistic SUM = new Sum();
047
048 /** sumSq */
049 private static final UnivariateStatistic SUM_OF_SQUARES = new SumOfSquares();
050
051 /** prod */
052 private static final UnivariateStatistic PRODUCT = new Product();
053
054 /** sumLog */
055 private static final UnivariateStatistic SUM_OF_LOGS = new SumOfLogs();
056
057 /** min */
058 private static final UnivariateStatistic MIN = new Min();
059
060 /** max */
061 private static final UnivariateStatistic MAX = new Max();
062
063 /** mean */
064 private static final UnivariateStatistic MEAN = new Mean();
065
066 /** variance */
067 private static final Variance VARIANCE = new Variance();
068
069 /** percentile */
070 private static final Percentile PERCENTILE = new Percentile();
071
072 /** geometric mean */
073 private static final GeometricMean GEOMETRIC_MEAN = new GeometricMean();
074
075 /**
076 * Private Constructor
077 */
078 private StatUtils() {
079 }
080
081 /**
082 * Returns the sum of the values in the input array, or
083 * <code>Double.NaN</code> if the array is empty.
084 * <p>
085 * Throws <code>IllegalArgumentException</code> if the input array
086 * is null.</p>
087 *
088 * @param values array of values to sum
089 * @return the sum of the values or <code>Double.NaN</code> if the array
090 * is empty
091 * @throws MathIllegalArgumentException if the array is null
092 */
093 public static double sum(final double[] values)
094 throws MathIllegalArgumentException {
095 return SUM.evaluate(values);
096 }
097
098 /**
099 * Returns the sum of the entries in the specified portion of
100 * the input array, or <code>Double.NaN</code> if the designated subarray
101 * is empty.
102 * <p>
103 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
104 *
105 * @param values the input array
106 * @param begin index of the first array element to include
107 * @param length the number of elements to include
108 * @return the sum of the values or Double.NaN if length = 0
109 * @throws MathIllegalArgumentException if the array is null or the array index
110 * parameters are not valid
111 */
112 public static double sum(final double[] values, final int begin,
113 final int length) throws MathIllegalArgumentException {
114 return SUM.evaluate(values, begin, length);
115 }
116
117 /**
118 * Returns the sum of the squares of the entries in the input array, or
119 * <code>Double.NaN</code> if the array is empty.
120 * <p>
121 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
122 *
123 * @param values input array
124 * @return the sum of the squared values or <code>Double.NaN</code> if the
125 * array is empty
126 * @throws MathIllegalArgumentException if the array is null
127 */
128 public static double sumSq(final double[] values) throws MathIllegalArgumentException {
129 return SUM_OF_SQUARES.evaluate(values);
130 }
131
132 /**
133 * Returns the sum of the squares of the entries in the specified portion of
134 * the input array, or <code>Double.NaN</code> if the designated subarray
135 * is empty.
136 * <p>
137 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
138 *
139 * @param values the input array
140 * @param begin index of the first array element to include
141 * @param length the number of elements to include
142 * @return the sum of the squares of the values or Double.NaN if length = 0
143 * @throws MathIllegalArgumentException if the array is null or the array index
144 * parameters are not valid
145 */
146 public static double sumSq(final double[] values, final int begin,
147 final int length) throws MathIllegalArgumentException {
148 return SUM_OF_SQUARES.evaluate(values, begin, length);
149 }
150
151 /**
152 * Returns the product of the entries in the input array, or
153 * <code>Double.NaN</code> if the array is empty.
154 * <p>
155 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
156 *
157 * @param values the input array
158 * @return the product of the values or Double.NaN if the array is empty
159 * @throws MathIllegalArgumentException if the array is null
160 */
161 public static double product(final double[] values)
162 throws MathIllegalArgumentException {
163 return PRODUCT.evaluate(values);
164 }
165
166 /**
167 * Returns the product of the entries in the specified portion of
168 * the input array, or <code>Double.NaN</code> if the designated subarray
169 * is empty.
170 * <p>
171 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
172 *
173 * @param values the input array
174 * @param begin index of the first array element to include
175 * @param length the number of elements to include
176 * @return the product of the values or Double.NaN if length = 0
177 * @throws MathIllegalArgumentException if the array is null or the array index
178 * parameters are not valid
179 */
180 public static double product(final double[] values, final int begin,
181 final int length) throws MathIllegalArgumentException {
182 return PRODUCT.evaluate(values, begin, length);
183 }
184
185 /**
186 * Returns the sum of the natural logs of the entries in the input array, or
187 * <code>Double.NaN</code> if the array is empty.
188 * <p>
189 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
190 * <p>
191 * See {@link org.apache.commons.math3.stat.descriptive.summary.SumOfLogs}.
192 * </p>
193 *
194 * @param values the input array
195 * @return the sum of the natural logs of the values or Double.NaN if
196 * the array is empty
197 * @throws MathIllegalArgumentException if the array is null
198 */
199 public static double sumLog(final double[] values)
200 throws MathIllegalArgumentException {
201 return SUM_OF_LOGS.evaluate(values);
202 }
203
204 /**
205 * Returns the sum of the natural logs of the entries in the specified portion of
206 * the input array, or <code>Double.NaN</code> if the designated subarray
207 * is empty.
208 * <p>
209 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
210 * <p>
211 * See {@link org.apache.commons.math3.stat.descriptive.summary.SumOfLogs}.
212 * </p>
213 *
214 * @param values the input array
215 * @param begin index of the first array element to include
216 * @param length the number of elements to include
217 * @return the sum of the natural logs of the values or Double.NaN if
218 * length = 0
219 * @throws MathIllegalArgumentException if the array is null or the array index
220 * parameters are not valid
221 */
222 public static double sumLog(final double[] values, final int begin,
223 final int length) throws MathIllegalArgumentException {
224 return SUM_OF_LOGS.evaluate(values, begin, length);
225 }
226
227 /**
228 * Returns the arithmetic mean of the entries in the input array, or
229 * <code>Double.NaN</code> if the array is empty.
230 * <p>
231 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
232 * <p>
233 * See {@link org.apache.commons.math3.stat.descriptive.moment.Mean} for
234 * details on the computing algorithm.</p>
235 *
236 * @param values the input array
237 * @return the mean of the values or Double.NaN if the array is empty
238 * @throws MathIllegalArgumentException if the array is null
239 */
240 public static double mean(final double[] values)
241 throws MathIllegalArgumentException {
242 return MEAN.evaluate(values);
243 }
244
245 /**
246 * Returns the arithmetic mean of the entries in the specified portion of
247 * the input array, or <code>Double.NaN</code> if the designated subarray
248 * is empty.
249 * <p>
250 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
251 * <p>
252 * See {@link org.apache.commons.math3.stat.descriptive.moment.Mean} for
253 * details on the computing algorithm.</p>
254 *
255 * @param values the input array
256 * @param begin index of the first array element to include
257 * @param length the number of elements to include
258 * @return the mean of the values or Double.NaN if length = 0
259 * @throws MathIllegalArgumentException if the array is null or the array index
260 * parameters are not valid
261 */
262 public static double mean(final double[] values, final int begin,
263 final int length) throws MathIllegalArgumentException {
264 return MEAN.evaluate(values, begin, length);
265 }
266
267 /**
268 * Returns the geometric mean of the entries in the input array, or
269 * <code>Double.NaN</code> if the array is empty.
270 * <p>
271 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
272 * <p>
273 * See {@link org.apache.commons.math3.stat.descriptive.moment.GeometricMean}
274 * for details on the computing algorithm.</p>
275 *
276 * @param values the input array
277 * @return the geometric mean of the values or Double.NaN if the array is empty
278 * @throws MathIllegalArgumentException if the array is null
279 */
280 public static double geometricMean(final double[] values)
281 throws MathIllegalArgumentException {
282 return GEOMETRIC_MEAN.evaluate(values);
283 }
284
285 /**
286 * Returns the geometric mean of the entries in the specified portion of
287 * the input array, or <code>Double.NaN</code> if the designated subarray
288 * is empty.
289 * <p>
290 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
291 * <p>
292 * See {@link org.apache.commons.math3.stat.descriptive.moment.GeometricMean}
293 * for details on the computing algorithm.</p>
294 *
295 * @param values the input array
296 * @param begin index of the first array element to include
297 * @param length the number of elements to include
298 * @return the geometric mean of the values or Double.NaN if length = 0
299 * @throws MathIllegalArgumentException if the array is null or the array index
300 * parameters are not valid
301 */
302 public static double geometricMean(final double[] values, final int begin,
303 final int length) throws MathIllegalArgumentException {
304 return GEOMETRIC_MEAN.evaluate(values, begin, length);
305 }
306
307
308 /**
309 * Returns the variance of the entries in the input array, or
310 * <code>Double.NaN</code> if the array is empty.
311 *
312 * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
313 * the denominator). Use {@link #populationVariance(double[])} for the non-bias-corrected
314 * population variance.</p>
315 * <p>
316 * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
317 * details on the computing algorithm.</p>
318 * <p>
319 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
320 * <p>
321 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
322 *
323 * @param values the input array
324 * @return the variance of the values or Double.NaN if the array is empty
325 * @throws MathIllegalArgumentException if the array is null
326 */
327 public static double variance(final double[] values) throws MathIllegalArgumentException {
328 return VARIANCE.evaluate(values);
329 }
330
331 /**
332 * Returns the variance of the entries in the specified portion of
333 * the input array, or <code>Double.NaN</code> if the designated subarray
334 * is empty.
335 *
336 * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
337 * the denominator). Use {@link #populationVariance(double[], int, int)} for the non-bias-corrected
338 * population variance.</p>
339 * <p>
340 * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
341 * details on the computing algorithm.</p>
342 * <p>
343 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
344 * <p>
345 * Throws <code>MathIllegalArgumentException</code> if the array is null or the
346 * array index parameters are not valid.</p>
347 *
348 * @param values the input array
349 * @param begin index of the first array element to include
350 * @param length the number of elements to include
351 * @return the variance of the values or Double.NaN if length = 0
352 * @throws MathIllegalArgumentException if the array is null or the array index
353 * parameters are not valid
354 */
355 public static double variance(final double[] values, final int begin,
356 final int length) throws MathIllegalArgumentException {
357 return VARIANCE.evaluate(values, begin, length);
358 }
359
360 /**
361 * Returns the variance of the entries in the specified portion of
362 * the input array, using the precomputed mean value. Returns
363 * <code>Double.NaN</code> if the designated subarray is empty.
364 *
365 * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
366 * the denominator). Use {@link #populationVariance(double[], double, int, int)} for the non-bias-corrected
367 * population variance.</p>
368 * <p>
369 * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
370 * details on the computing algorithm.</p>
371 * <p>
372 * The formula used assumes that the supplied mean value is the arithmetic
373 * mean of the sample data, not a known population parameter. This method
374 * is supplied only to save computation when the mean has already been
375 * computed.</p>
376 * <p>
377 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
378 * <p>
379 * Throws <code>MathIllegalArgumentException</code> if the array is null or the
380 * array index parameters are not valid.</p>
381 *
382 * @param values the input array
383 * @param mean the precomputed mean value
384 * @param begin index of the first array element to include
385 * @param length the number of elements to include
386 * @return the variance of the values or Double.NaN if length = 0
387 * @throws MathIllegalArgumentException if the array is null or the array index
388 * parameters are not valid
389 */
390 public static double variance(final double[] values, final double mean,
391 final int begin, final int length) throws MathIllegalArgumentException {
392 return VARIANCE.evaluate(values, mean, begin, length);
393 }
394
395 /**
396 * Returns the variance of the entries in the input array, using the
397 * precomputed mean value. Returns <code>Double.NaN</code> if the array
398 * is empty.
399 *
400 * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
401 * the denominator). Use {@link #populationVariance(double[], double)} for the non-bias-corrected
402 * population variance.</p>
403 * <p>
404 * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
405 * details on the computing algorithm.</p>
406 * <p>
407 * The formula used assumes that the supplied mean value is the arithmetic
408 * mean of the sample data, not a known population parameter. This method
409 * is supplied only to save computation when the mean has already been
410 * computed.</p>
411 * <p>
412 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
413 * <p>
414 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
415 *
416 * @param values the input array
417 * @param mean the precomputed mean value
418 * @return the variance of the values or Double.NaN if the array is empty
419 * @throws MathIllegalArgumentException if the array is null
420 */
421 public static double variance(final double[] values, final double mean)
422 throws MathIllegalArgumentException {
423 return VARIANCE.evaluate(values, mean);
424 }
425
426 /**
427 * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
428 * population variance</a> of the entries in the input array, or
429 * <code>Double.NaN</code> if the array is empty.
430 * <p>
431 * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
432 * details on the formula and computing algorithm.</p>
433 * <p>
434 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
435 * <p>
436 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
437 *
438 * @param values the input array
439 * @return the population variance of the values or Double.NaN if the array is empty
440 * @throws MathIllegalArgumentException if the array is null
441 */
442 public static double populationVariance(final double[] values)
443 throws MathIllegalArgumentException {
444 return new Variance(false).evaluate(values);
445 }
446
447 /**
448 * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
449 * population variance</a> of the entries in the specified portion of
450 * the input array, or <code>Double.NaN</code> if the designated subarray
451 * is empty.
452 * <p>
453 * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
454 * details on the computing algorithm.</p>
455 * <p>
456 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
457 * <p>
458 * Throws <code>MathIllegalArgumentException</code> if the array is null or the
459 * array index parameters are not valid.</p>
460 *
461 * @param values the input array
462 * @param begin index of the first array element to include
463 * @param length the number of elements to include
464 * @return the population variance of the values or Double.NaN if length = 0
465 * @throws MathIllegalArgumentException if the array is null or the array index
466 * parameters are not valid
467 */
468 public static double populationVariance(final double[] values, final int begin,
469 final int length) throws MathIllegalArgumentException {
470 return new Variance(false).evaluate(values, begin, length);
471 }
472
473 /**
474 * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
475 * population variance</a> of the entries in the specified portion of
476 * the input array, using the precomputed mean value. Returns
477 * <code>Double.NaN</code> if the designated subarray is empty.
478 * <p>
479 * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
480 * details on the computing algorithm.</p>
481 * <p>
482 * The formula used assumes that the supplied mean value is the arithmetic
483 * mean of the sample data, not a known population parameter. This method
484 * is supplied only to save computation when the mean has already been
485 * computed.</p>
486 * <p>
487 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
488 * <p>
489 * Throws <code>MathIllegalArgumentException</code> if the array is null or the
490 * array index parameters are not valid.</p>
491 *
492 * @param values the input array
493 * @param mean the precomputed mean value
494 * @param begin index of the first array element to include
495 * @param length the number of elements to include
496 * @return the population variance of the values or Double.NaN if length = 0
497 * @throws MathIllegalArgumentException if the array is null or the array index
498 * parameters are not valid
499 */
500 public static double populationVariance(final double[] values, final double mean,
501 final int begin, final int length) throws MathIllegalArgumentException {
502 return new Variance(false).evaluate(values, mean, begin, length);
503 }
504
505 /**
506 * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
507 * population variance</a> of the entries in the input array, using the
508 * precomputed mean value. Returns <code>Double.NaN</code> if the array
509 * is empty.
510 * <p>
511 * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
512 * details on the computing algorithm.</p>
513 * <p>
514 * The formula used assumes that the supplied mean value is the arithmetic
515 * mean of the sample data, not a known population parameter. This method
516 * is supplied only to save computation when the mean has already been
517 * computed.</p>
518 * <p>
519 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
520 * <p>
521 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
522 *
523 * @param values the input array
524 * @param mean the precomputed mean value
525 * @return the population variance of the values or Double.NaN if the array is empty
526 * @throws MathIllegalArgumentException if the array is null
527 */
528 public static double populationVariance(final double[] values, final double mean)
529 throws MathIllegalArgumentException {
530 return new Variance(false).evaluate(values, mean);
531 }
532
533 /**
534 * Returns the maximum of the entries in the input array, or
535 * <code>Double.NaN</code> if the array is empty.
536 * <p>
537 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
538 * <p>
539 * <ul>
540 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
541 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
542 * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
543 * the result is <code>Double.POSITIVE_INFINITY.</code></li>
544 * </ul></p>
545 *
546 * @param values the input array
547 * @return the maximum of the values or Double.NaN if the array is empty
548 * @throws MathIllegalArgumentException if the array is null
549 */
550 public static double max(final double[] values) throws MathIllegalArgumentException {
551 return MAX.evaluate(values);
552 }
553
554 /**
555 * Returns the maximum of the entries in the specified portion of
556 * the input array, or <code>Double.NaN</code> if the designated subarray
557 * is empty.
558 * <p>
559 * Throws <code>MathIllegalArgumentException</code> if the array is null or
560 * the array index parameters are not valid.</p>
561 * <p>
562 * <ul>
563 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
564 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
565 * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
566 * the result is <code>Double.POSITIVE_INFINITY.</code></li>
567 * </ul></p>
568 *
569 * @param values the input array
570 * @param begin index of the first array element to include
571 * @param length the number of elements to include
572 * @return the maximum of the values or Double.NaN if length = 0
573 * @throws MathIllegalArgumentException if the array is null or the array index
574 * parameters are not valid
575 */
576 public static double max(final double[] values, final int begin,
577 final int length) throws MathIllegalArgumentException {
578 return MAX.evaluate(values, begin, length);
579 }
580
581 /**
582 * Returns the minimum of the entries in the input array, or
583 * <code>Double.NaN</code> if the array is empty.
584 * <p>
585 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
586 * <p>
587 * <ul>
588 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
589 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
590 * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
591 * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
592 * </ul> </p>
593 *
594 * @param values the input array
595 * @return the minimum of the values or Double.NaN if the array is empty
596 * @throws MathIllegalArgumentException if the array is null
597 */
598 public static double min(final double[] values) throws MathIllegalArgumentException {
599 return MIN.evaluate(values);
600 }
601
602 /**
603 * Returns the minimum of the entries in the specified portion of
604 * the input array, or <code>Double.NaN</code> if the designated subarray
605 * is empty.
606 * <p>
607 * Throws <code>MathIllegalArgumentException</code> if the array is null or
608 * the array index parameters are not valid.</p>
609 * <p>
610 * <ul>
611 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
612 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
613 * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
614 * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
615 * </ul></p>
616 *
617 * @param values the input array
618 * @param begin index of the first array element to include
619 * @param length the number of elements to include
620 * @return the minimum of the values or Double.NaN if length = 0
621 * @throws MathIllegalArgumentException if the array is null or the array index
622 * parameters are not valid
623 */
624 public static double min(final double[] values, final int begin,
625 final int length) throws MathIllegalArgumentException {
626 return MIN.evaluate(values, begin, length);
627 }
628
629 /**
630 * Returns an estimate of the <code>p</code>th percentile of the values
631 * in the <code>values</code> array.
632 * <p>
633 * <ul>
634 * <li>Returns <code>Double.NaN</code> if <code>values</code> has length
635 * <code>0</code></li></p>
636 * <li>Returns (for any value of <code>p</code>) <code>values[0]</code>
637 * if <code>values</code> has length <code>1</code></li>
638 * <li>Throws <code>IllegalArgumentException</code> if <code>values</code>
639 * is null or p is not a valid quantile value (p must be greater than 0
640 * and less than or equal to 100)</li>
641 * </ul></p>
642 * <p>
643 * See {@link org.apache.commons.math3.stat.descriptive.rank.Percentile} for
644 * a description of the percentile estimation algorithm used.</p>
645 *
646 * @param values input array of values
647 * @param p the percentile value to compute
648 * @return the percentile value or Double.NaN if the array is empty
649 * @throws MathIllegalArgumentException if <code>values</code> is null
650 * or p is invalid
651 */
652 public static double percentile(final double[] values, final double p)
653 throws MathIllegalArgumentException {
654 return PERCENTILE.evaluate(values,p);
655 }
656
657 /**
658 * Returns an estimate of the <code>p</code>th percentile of the values
659 * in the <code>values</code> array, starting with the element in (0-based)
660 * position <code>begin</code> in the array and including <code>length</code>
661 * values.
662 * <p>
663 * <ul>
664 * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li>
665 * <li>Returns (for any value of <code>p</code>) <code>values[begin]</code>
666 * if <code>length = 1 </code></li>
667 * <li>Throws <code>MathIllegalArgumentException</code> if <code>values</code>
668 * is null , <code>begin</code> or <code>length</code> is invalid, or
669 * <code>p</code> is not a valid quantile value (p must be greater than 0
670 * and less than or equal to 100)</li>
671 * </ul></p>
672 * <p>
673 * See {@link org.apache.commons.math3.stat.descriptive.rank.Percentile} for
674 * a description of the percentile estimation algorithm used.</p>
675 *
676 * @param values array of input values
677 * @param p the percentile to compute
678 * @param begin the first (0-based) element to include in the computation
679 * @param length the number of array elements to include
680 * @return the percentile value
681 * @throws MathIllegalArgumentException if the parameters are not valid or the
682 * input array is null
683 */
684 public static double percentile(final double[] values, final int begin,
685 final int length, final double p) throws MathIllegalArgumentException {
686 return PERCENTILE.evaluate(values, begin, length, p);
687 }
688
689 /**
690 * Returns the sum of the (signed) differences between corresponding elements of the
691 * input arrays -- i.e., sum(sample1[i] - sample2[i]).
692 *
693 * @param sample1 the first array
694 * @param sample2 the second array
695 * @return sum of paired differences
696 * @throws DimensionMismatchException if the arrays do not have the same
697 * (positive) length.
698 * @throws NoDataException if the sample arrays are empty.
699 */
700 public static double sumDifference(final double[] sample1, final double[] sample2)
701 throws DimensionMismatchException, NoDataException {
702 int n = sample1.length;
703 if (n != sample2.length) {
704 throw new DimensionMismatchException(n, sample2.length);
705 }
706 if (n <= 0) {
707 throw new NoDataException(LocalizedFormats.INSUFFICIENT_DIMENSION);
708 }
709 double result = 0;
710 for (int i = 0; i < n; i++) {
711 result += sample1[i] - sample2[i];
712 }
713 return result;
714 }
715
716 /**
717 * Returns the mean of the (signed) differences between corresponding elements of the
718 * input arrays -- i.e., sum(sample1[i] - sample2[i]) / sample1.length.
719 *
720 * @param sample1 the first array
721 * @param sample2 the second array
722 * @return mean of paired differences
723 * @throws DimensionMismatchException if the arrays do not have the same
724 * (positive) length.
725 * @throws NoDataException if the sample arrays are empty.
726 */
727 public static double meanDifference(final double[] sample1, final double[] sample2)
728 throws DimensionMismatchException, NoDataException{
729 return sumDifference(sample1, sample2) / sample1.length;
730 }
731
732 /**
733 * Returns the variance of the (signed) differences between corresponding elements of the
734 * input arrays -- i.e., var(sample1[i] - sample2[i]).
735 *
736 * @param sample1 the first array
737 * @param sample2 the second array
738 * @param meanDifference the mean difference between corresponding entries
739 * @see #meanDifference(double[],double[])
740 * @return variance of paired differences
741 * @throws DimensionMismatchException if the arrays do not have the same
742 * length.
743 * @throws NumberIsTooSmallException if the arrays length is less than 2.
744 */
745 public static double varianceDifference(final double[] sample1,
746 final double[] sample2, double meanDifference) throws DimensionMismatchException,
747 NumberIsTooSmallException {
748 double sum1 = 0d;
749 double sum2 = 0d;
750 double diff = 0d;
751 int n = sample1.length;
752 if (n != sample2.length) {
753 throw new DimensionMismatchException(n, sample2.length);
754 }
755 if (n < 2) {
756 throw new NumberIsTooSmallException(n, 2, true);
757 }
758 for (int i = 0; i < n; i++) {
759 diff = sample1[i] - sample2[i];
760 sum1 += (diff - meanDifference) *(diff - meanDifference);
761 sum2 += diff - meanDifference;
762 }
763 return (sum1 - (sum2 * sum2 / n)) / (n - 1);
764 }
765
766 /**
767 * Normalize (standardize) the sample, so it is has a mean of 0 and a standard deviation of 1.
768 *
769 * @param sample Sample to normalize.
770 * @return normalized (standardized) sample.
771 * @since 2.2
772 */
773 public static double[] normalize(final double[] sample) {
774 DescriptiveStatistics stats = new DescriptiveStatistics();
775
776 // Add the data from the series to stats
777 for (int i = 0; i < sample.length; i++) {
778 stats.addValue(sample[i]);
779 }
780
781 // Compute mean and standard deviation
782 double mean = stats.getMean();
783 double standardDeviation = stats.getStandardDeviation();
784
785 // initialize the standardizedSample, which has the same length as the sample
786 double[] standardizedSample = new double[sample.length];
787
788 for (int i = 0; i < sample.length; i++) {
789 // z = (x- mean)/standardDeviation
790 standardizedSample[i] = (sample[i] - mean) / standardDeviation;
791 }
792 return standardizedSample;
793 }
794 }