source: src/main/java/agents/anac/y2019/harddealer/math3/stat/StatUtils.java

Last change on this file was 204, checked in by Katsuhide Fujita, 5 years ago

Fixed errors of ANAC2019 agents

  • Property svn:executable set to *
File size: 37.5 KB
Line 
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 * http://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 */
17package agents.anac.y2019.harddealer.math3.stat;
18
19import java.util.List;
20
21import agents.anac.y2019.harddealer.math3.exception.MathIllegalArgumentException;
22import agents.anac.y2019.harddealer.math3.exception.NotPositiveException;
23import agents.anac.y2019.harddealer.math3.exception.NullArgumentException;
24import agents.anac.y2019.harddealer.math3.exception.NumberIsTooSmallException;
25import agents.anac.y2019.harddealer.math3.exception.DimensionMismatchException;
26import agents.anac.y2019.harddealer.math3.exception.NoDataException;
27import agents.anac.y2019.harddealer.math3.exception.util.LocalizedFormats;
28import agents.anac.y2019.harddealer.math3.stat.descriptive.DescriptiveStatistics;
29import agents.anac.y2019.harddealer.math3.stat.descriptive.UnivariateStatistic;
30import agents.anac.y2019.harddealer.math3.stat.descriptive.moment.GeometricMean;
31import agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Mean;
32import agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance;
33import agents.anac.y2019.harddealer.math3.stat.descriptive.rank.Max;
34import agents.anac.y2019.harddealer.math3.stat.descriptive.rank.Min;
35import agents.anac.y2019.harddealer.math3.stat.descriptive.rank.Percentile;
36import agents.anac.y2019.harddealer.math3.stat.descriptive.summary.Product;
37import agents.anac.y2019.harddealer.math3.stat.descriptive.summary.Sum;
38import agents.anac.y2019.harddealer.math3.stat.descriptive.summary.SumOfLogs;
39import agents.anac.y2019.harddealer.math3.stat.descriptive.summary.SumOfSquares;
40
41/**
42 * StatUtils provides static methods for computing statistics based on data
43 * stored in double[] arrays.
44 *
45 */
46public final class StatUtils {
47
48 /** sum */
49 private static final UnivariateStatistic SUM = new Sum();
50
51 /** sumSq */
52 private static final UnivariateStatistic SUM_OF_SQUARES = new SumOfSquares();
53
54 /** prod */
55 private static final UnivariateStatistic PRODUCT = new Product();
56
57 /** sumLog */
58 private static final UnivariateStatistic SUM_OF_LOGS = new SumOfLogs();
59
60 /** min */
61 private static final UnivariateStatistic MIN = new Min();
62
63 /** max */
64 private static final UnivariateStatistic MAX = new Max();
65
66 /** mean */
67 private static final UnivariateStatistic MEAN = new Mean();
68
69 /** variance */
70 private static final Variance VARIANCE = new Variance();
71
72 /** percentile */
73 private static final Percentile PERCENTILE = new Percentile();
74
75 /** geometric mean */
76 private static final GeometricMean GEOMETRIC_MEAN = new GeometricMean();
77
78 /**
79 * Private Constructor
80 */
81 private StatUtils() {
82 }
83
84 /**
85 * Returns the sum of the values in the input array, or
86 * <code>Double.NaN</code> if the array is empty.
87 * <p>
88 * Throws <code>IllegalArgumentException</code> if the input array
89 * is null.</p>
90 *
91 * @param values array of values to sum
92 * @return the sum of the values or <code>Double.NaN</code> if the array
93 * is empty
94 * @throws MathIllegalArgumentException if the array is null
95 */
96 public static double sum(final double[] values)
97 throws MathIllegalArgumentException {
98 return SUM.evaluate(values);
99 }
100
101 /**
102 * Returns the sum of the entries in the specified portion of
103 * the input array, or <code>Double.NaN</code> if the designated subarray
104 * is empty.
105 * <p>
106 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
107 *
108 * @param values the input array
109 * @param begin index of the first array element to include
110 * @param length the number of elements to include
111 * @return the sum of the values or Double.NaN if length = 0
112 * @throws MathIllegalArgumentException if the array is null or the array index
113 * parameters are not valid
114 */
115 public static double sum(final double[] values, final int begin,
116 final int length) throws MathIllegalArgumentException {
117 return SUM.evaluate(values, begin, length);
118 }
119
120 /**
121 * Returns the sum of the squares of the entries in the input array, or
122 * <code>Double.NaN</code> if the array is empty.
123 * <p>
124 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
125 *
126 * @param values input array
127 * @return the sum of the squared values or <code>Double.NaN</code> if the
128 * array is empty
129 * @throws MathIllegalArgumentException if the array is null
130 */
131 public static double sumSq(final double[] values) throws MathIllegalArgumentException {
132 return SUM_OF_SQUARES.evaluate(values);
133 }
134
135 /**
136 * Returns the sum of the squares of the entries in the specified portion of
137 * the input array, or <code>Double.NaN</code> if the designated subarray
138 * is empty.
139 * <p>
140 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
141 *
142 * @param values the input array
143 * @param begin index of the first array element to include
144 * @param length the number of elements to include
145 * @return the sum of the squares of the values or Double.NaN if length = 0
146 * @throws MathIllegalArgumentException if the array is null or the array index
147 * parameters are not valid
148 */
149 public static double sumSq(final double[] values, final int begin,
150 final int length) throws MathIllegalArgumentException {
151 return SUM_OF_SQUARES.evaluate(values, begin, length);
152 }
153
154 /**
155 * Returns the product of the entries in the input array, or
156 * <code>Double.NaN</code> if the array is empty.
157 * <p>
158 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
159 *
160 * @param values the input array
161 * @return the product of the values or Double.NaN if the array is empty
162 * @throws MathIllegalArgumentException if the array is null
163 */
164 public static double product(final double[] values)
165 throws MathIllegalArgumentException {
166 return PRODUCT.evaluate(values);
167 }
168
169 /**
170 * Returns the product of the entries in the specified portion of
171 * the input array, or <code>Double.NaN</code> if the designated subarray
172 * is empty.
173 * <p>
174 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
175 *
176 * @param values the input array
177 * @param begin index of the first array element to include
178 * @param length the number of elements to include
179 * @return the product of the values or Double.NaN if length = 0
180 * @throws MathIllegalArgumentException if the array is null or the array index
181 * parameters are not valid
182 */
183 public static double product(final double[] values, final int begin,
184 final int length) throws MathIllegalArgumentException {
185 return PRODUCT.evaluate(values, begin, length);
186 }
187
188 /**
189 * Returns the sum of the natural logs of the entries in the input array, or
190 * <code>Double.NaN</code> if the array is empty.
191 * <p>
192 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
193 * <p>
194 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.summary.SumOfLogs}.
195 * </p>
196 *
197 * @param values the input array
198 * @return the sum of the natural logs of the values or Double.NaN if
199 * the array is empty
200 * @throws MathIllegalArgumentException if the array is null
201 */
202 public static double sumLog(final double[] values)
203 throws MathIllegalArgumentException {
204 return SUM_OF_LOGS.evaluate(values);
205 }
206
207 /**
208 * Returns the sum of the natural logs of the entries in the specified portion of
209 * the input array, or <code>Double.NaN</code> if the designated subarray
210 * is empty.
211 * <p>
212 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
213 * <p>
214 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.summary.SumOfLogs}.
215 * </p>
216 *
217 * @param values the input array
218 * @param begin index of the first array element to include
219 * @param length the number of elements to include
220 * @return the sum of the natural logs of the values or Double.NaN if
221 * length = 0
222 * @throws MathIllegalArgumentException if the array is null or the array index
223 * parameters are not valid
224 */
225 public static double sumLog(final double[] values, final int begin,
226 final int length) throws MathIllegalArgumentException {
227 return SUM_OF_LOGS.evaluate(values, begin, length);
228 }
229
230 /**
231 * Returns the arithmetic mean of the entries in the input array, or
232 * <code>Double.NaN</code> if the array is empty.
233 * <p>
234 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
235 * <p>
236 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Mean} for
237 * details on the computing algorithm.</p>
238 *
239 * @param values the input array
240 * @return the mean of the values or Double.NaN if the array is empty
241 * @throws MathIllegalArgumentException if the array is null
242 */
243 public static double mean(final double[] values)
244 throws MathIllegalArgumentException {
245 return MEAN.evaluate(values);
246 }
247
248 /**
249 * Returns the arithmetic mean of the entries in the specified portion of
250 * the input array, or <code>Double.NaN</code> if the designated subarray
251 * is empty.
252 * <p>
253 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
254 * <p>
255 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Mean} for
256 * details on the computing algorithm.</p>
257 *
258 * @param values the input array
259 * @param begin index of the first array element to include
260 * @param length the number of elements to include
261 * @return the mean of the values or Double.NaN if length = 0
262 * @throws MathIllegalArgumentException if the array is null or the array index
263 * parameters are not valid
264 */
265 public static double mean(final double[] values, final int begin,
266 final int length) throws MathIllegalArgumentException {
267 return MEAN.evaluate(values, begin, length);
268 }
269
270 /**
271 * Returns the geometric mean of the entries in the input array, or
272 * <code>Double.NaN</code> if the array is empty.
273 * <p>
274 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
275 * <p>
276 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.GeometricMean}
277 * for details on the computing algorithm.</p>
278 *
279 * @param values the input array
280 * @return the geometric mean of the values or Double.NaN if the array is empty
281 * @throws MathIllegalArgumentException if the array is null
282 */
283 public static double geometricMean(final double[] values)
284 throws MathIllegalArgumentException {
285 return GEOMETRIC_MEAN.evaluate(values);
286 }
287
288 /**
289 * Returns the geometric mean of the entries in the specified portion of
290 * the input array, or <code>Double.NaN</code> if the designated subarray
291 * is empty.
292 * <p>
293 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
294 * <p>
295 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.GeometricMean}
296 * for details on the computing algorithm.</p>
297 *
298 * @param values the input array
299 * @param begin index of the first array element to include
300 * @param length the number of elements to include
301 * @return the geometric mean of the values or Double.NaN if length = 0
302 * @throws MathIllegalArgumentException if the array is null or the array index
303 * parameters are not valid
304 */
305 public static double geometricMean(final double[] values, final int begin,
306 final int length) throws MathIllegalArgumentException {
307 return GEOMETRIC_MEAN.evaluate(values, begin, length);
308 }
309
310
311 /**
312 * Returns the variance of the entries in the input array, or
313 * <code>Double.NaN</code> if the array is empty.
314 *
315 * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
316 * the denominator). Use {@link #populationVariance(double[])} for the non-bias-corrected
317 * population variance.</p>
318 * <p>
319 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance} for
320 * details on the computing algorithm.</p>
321 * <p>
322 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
323 * <p>
324 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
325 *
326 * @param values the input array
327 * @return the variance of the values or Double.NaN if the array is empty
328 * @throws MathIllegalArgumentException if the array is null
329 */
330 public static double variance(final double[] values) throws MathIllegalArgumentException {
331 return VARIANCE.evaluate(values);
332 }
333
334 /**
335 * Returns the variance of the entries in the specified portion of
336 * the input array, or <code>Double.NaN</code> if the designated subarray
337 * is empty.
338 *
339 * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
340 * the denominator). Use {@link #populationVariance(double[], int, int)} for the non-bias-corrected
341 * population variance.</p>
342 * <p>
343 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance} for
344 * details on the computing algorithm.</p>
345 * <p>
346 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
347 * <p>
348 * Throws <code>MathIllegalArgumentException</code> if the array is null or the
349 * array index parameters are not valid.</p>
350 *
351 * @param values the input array
352 * @param begin index of the first array element to include
353 * @param length the number of elements to include
354 * @return the variance of the values or Double.NaN if length = 0
355 * @throws MathIllegalArgumentException if the array is null or the array index
356 * parameters are not valid
357 */
358 public static double variance(final double[] values, final int begin,
359 final int length) throws MathIllegalArgumentException {
360 return VARIANCE.evaluate(values, begin, length);
361 }
362
363 /**
364 * Returns the variance of the entries in the specified portion of
365 * the input array, using the precomputed mean value. Returns
366 * <code>Double.NaN</code> if the designated subarray is empty.
367 *
368 * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
369 * the denominator). Use {@link #populationVariance(double[], double, int, int)} for the non-bias-corrected
370 * population variance.</p>
371 * <p>
372 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance} for
373 * details on the computing algorithm.</p>
374 * <p>
375 * The formula used assumes that the supplied mean value is the arithmetic
376 * mean of the sample data, not a known population parameter. This method
377 * is supplied only to save computation when the mean has already been
378 * computed.</p>
379 * <p>
380 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
381 * <p>
382 * Throws <code>MathIllegalArgumentException</code> if the array is null or the
383 * array index parameters are not valid.</p>
384 *
385 * @param values the input array
386 * @param mean the precomputed mean value
387 * @param begin index of the first array element to include
388 * @param length the number of elements to include
389 * @return the variance of the values or Double.NaN if length = 0
390 * @throws MathIllegalArgumentException if the array is null or the array index
391 * parameters are not valid
392 */
393 public static double variance(final double[] values, final double mean,
394 final int begin, final int length) throws MathIllegalArgumentException {
395 return VARIANCE.evaluate(values, mean, begin, length);
396 }
397
398 /**
399 * Returns the variance of the entries in the input array, using the
400 * precomputed mean value. Returns <code>Double.NaN</code> if the array
401 * is empty.
402 *
403 * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
404 * the denominator). Use {@link #populationVariance(double[], double)} for the non-bias-corrected
405 * population variance.</p>
406 * <p>
407 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance} for
408 * details on the computing algorithm.</p>
409 * <p>
410 * The formula used assumes that the supplied mean value is the arithmetic
411 * mean of the sample data, not a known population parameter. This method
412 * is supplied only to save computation when the mean has already been
413 * computed.</p>
414 * <p>
415 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
416 * <p>
417 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
418 *
419 * @param values the input array
420 * @param mean the precomputed mean value
421 * @return the variance of the values or Double.NaN if the array is empty
422 * @throws MathIllegalArgumentException if the array is null
423 */
424 public static double variance(final double[] values, final double mean)
425 throws MathIllegalArgumentException {
426 return VARIANCE.evaluate(values, mean);
427 }
428
429 /**
430 * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
431 * population variance</a> of the entries in the input array, or
432 * <code>Double.NaN</code> if the array is empty.
433 * <p>
434 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance} for
435 * details on the formula and computing algorithm.</p>
436 * <p>
437 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
438 * <p>
439 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
440 *
441 * @param values the input array
442 * @return the population variance of the values or Double.NaN if the array is empty
443 * @throws MathIllegalArgumentException if the array is null
444 */
445 public static double populationVariance(final double[] values)
446 throws MathIllegalArgumentException {
447 return new Variance(false).evaluate(values);
448 }
449
450 /**
451 * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
452 * population variance</a> of the entries in the specified portion of
453 * the input array, or <code>Double.NaN</code> if the designated subarray
454 * is empty.
455 * <p>
456 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance} for
457 * details on the computing algorithm.</p>
458 * <p>
459 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
460 * <p>
461 * Throws <code>MathIllegalArgumentException</code> if the array is null or the
462 * array index parameters are not valid.</p>
463 *
464 * @param values the input array
465 * @param begin index of the first array element to include
466 * @param length the number of elements to include
467 * @return the population variance of the values or Double.NaN if length = 0
468 * @throws MathIllegalArgumentException if the array is null or the array index
469 * parameters are not valid
470 */
471 public static double populationVariance(final double[] values, final int begin,
472 final int length) throws MathIllegalArgumentException {
473 return new Variance(false).evaluate(values, begin, length);
474 }
475
476 /**
477 * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
478 * population variance</a> of the entries in the specified portion of
479 * the input array, using the precomputed mean value. Returns
480 * <code>Double.NaN</code> if the designated subarray is empty.
481 * <p>
482 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance} for
483 * details on the computing algorithm.</p>
484 * <p>
485 * The formula used assumes that the supplied mean value is the arithmetic
486 * mean of the sample data, not a known population parameter. This method
487 * is supplied only to save computation when the mean has already been
488 * computed.</p>
489 * <p>
490 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
491 * <p>
492 * Throws <code>MathIllegalArgumentException</code> if the array is null or the
493 * array index parameters are not valid.</p>
494 *
495 * @param values the input array
496 * @param mean the precomputed mean value
497 * @param begin index of the first array element to include
498 * @param length the number of elements to include
499 * @return the population variance of the values or Double.NaN if length = 0
500 * @throws MathIllegalArgumentException if the array is null or the array index
501 * parameters are not valid
502 */
503 public static double populationVariance(final double[] values, final double mean,
504 final int begin, final int length) throws MathIllegalArgumentException {
505 return new Variance(false).evaluate(values, mean, begin, length);
506 }
507
508 /**
509 * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
510 * population variance</a> of the entries in the input array, using the
511 * precomputed mean value. Returns <code>Double.NaN</code> if the array
512 * is empty.
513 * <p>
514 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.moment.Variance} for
515 * details on the computing algorithm.</p>
516 * <p>
517 * The formula used assumes that the supplied mean value is the arithmetic
518 * mean of the sample data, not a known population parameter. This method
519 * is supplied only to save computation when the mean has already been
520 * computed.</p>
521 * <p>
522 * Returns 0 for a single-value (i.e. length = 1) sample.</p>
523 * <p>
524 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
525 *
526 * @param values the input array
527 * @param mean the precomputed mean value
528 * @return the population variance of the values or Double.NaN if the array is empty
529 * @throws MathIllegalArgumentException if the array is null
530 */
531 public static double populationVariance(final double[] values, final double mean)
532 throws MathIllegalArgumentException {
533 return new Variance(false).evaluate(values, mean);
534 }
535
536 /**
537 * Returns the maximum of the entries in the input array, or
538 * <code>Double.NaN</code> if the array is empty.
539 * <p>
540 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
541 * <p>
542 * <ul>
543 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
544 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
545 * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
546 * the result is <code>Double.POSITIVE_INFINITY.</code></li>
547 * </ul></p>
548 *
549 * @param values the input array
550 * @return the maximum of the values or Double.NaN if the array is empty
551 * @throws MathIllegalArgumentException if the array is null
552 */
553 public static double max(final double[] values) throws MathIllegalArgumentException {
554 return MAX.evaluate(values);
555 }
556
557 /**
558 * Returns the maximum of the entries in the specified portion of
559 * the input array, or <code>Double.NaN</code> if the designated subarray
560 * is empty.
561 * <p>
562 * Throws <code>MathIllegalArgumentException</code> if the array is null or
563 * the array index parameters are not valid.</p>
564 * <p>
565 * <ul>
566 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
567 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
568 * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
569 * the result is <code>Double.POSITIVE_INFINITY.</code></li>
570 * </ul></p>
571 *
572 * @param values the input array
573 * @param begin index of the first array element to include
574 * @param length the number of elements to include
575 * @return the maximum of the values or Double.NaN if length = 0
576 * @throws MathIllegalArgumentException if the array is null or the array index
577 * parameters are not valid
578 */
579 public static double max(final double[] values, final int begin,
580 final int length) throws MathIllegalArgumentException {
581 return MAX.evaluate(values, begin, length);
582 }
583
584 /**
585 * Returns the minimum of the entries in the input array, or
586 * <code>Double.NaN</code> if the array is empty.
587 * <p>
588 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
589 * <p>
590 * <ul>
591 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
592 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
593 * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
594 * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
595 * </ul> </p>
596 *
597 * @param values the input array
598 * @return the minimum of the values or Double.NaN if the array is empty
599 * @throws MathIllegalArgumentException if the array is null
600 */
601 public static double min(final double[] values) throws MathIllegalArgumentException {
602 return MIN.evaluate(values);
603 }
604
605 /**
606 * Returns the minimum of the entries in the specified portion of
607 * the input array, or <code>Double.NaN</code> if the designated subarray
608 * is empty.
609 * <p>
610 * Throws <code>MathIllegalArgumentException</code> if the array is null or
611 * the array index parameters are not valid.</p>
612 * <p>
613 * <ul>
614 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
615 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
616 * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
617 * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
618 * </ul></p>
619 *
620 * @param values the input array
621 * @param begin index of the first array element to include
622 * @param length the number of elements to include
623 * @return the minimum of the values or Double.NaN if length = 0
624 * @throws MathIllegalArgumentException if the array is null or the array index
625 * parameters are not valid
626 */
627 public static double min(final double[] values, final int begin,
628 final int length) throws MathIllegalArgumentException {
629 return MIN.evaluate(values, begin, length);
630 }
631
632 /**
633 * Returns an estimate of the <code>p</code>th percentile of the values
634 * in the <code>values</code> array.
635 * <p>
636 * <ul>
637 * <li>Returns <code>Double.NaN</code> if <code>values</code> has length
638 * <code>0</code></li></p>
639 * <li>Returns (for any value of <code>p</code>) <code>values[0]</code>
640 * if <code>values</code> has length <code>1</code></li>
641 * <li>Throws <code>IllegalArgumentException</code> if <code>values</code>
642 * is null or p is not a valid quantile value (p must be greater than 0
643 * and less than or equal to 100)</li>
644 * </ul></p>
645 * <p>
646 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.rank.Percentile} for
647 * a description of the percentile estimation algorithm used.</p>
648 *
649 * @param values input array of values
650 * @param p the percentile value to compute
651 * @return the percentile value or Double.NaN if the array is empty
652 * @throws MathIllegalArgumentException if <code>values</code> is null
653 * or p is invalid
654 */
655 public static double percentile(final double[] values, final double p)
656 throws MathIllegalArgumentException {
657 return PERCENTILE.evaluate(values,p);
658 }
659
660 /**
661 * Returns an estimate of the <code>p</code>th percentile of the values
662 * in the <code>values</code> array, starting with the element in (0-based)
663 * position <code>begin</code> in the array and including <code>length</code>
664 * values.
665 * <p>
666 * <ul>
667 * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li>
668 * <li>Returns (for any value of <code>p</code>) <code>values[begin]</code>
669 * if <code>length = 1 </code></li>
670 * <li>Throws <code>MathIllegalArgumentException</code> if <code>values</code>
671 * is null , <code>begin</code> or <code>length</code> is invalid, or
672 * <code>p</code> is not a valid quantile value (p must be greater than 0
673 * and less than or equal to 100)</li>
674 * </ul></p>
675 * <p>
676 * See {@link agents.anac.y2019.harddealer.math3.stat.descriptive.rank.Percentile} for
677 * a description of the percentile estimation algorithm used.</p>
678 *
679 * @param values array of input values
680 * @param p the percentile to compute
681 * @param begin the first (0-based) element to include in the computation
682 * @param length the number of array elements to include
683 * @return the percentile value
684 * @throws MathIllegalArgumentException if the parameters are not valid or the
685 * input array is null
686 */
687 public static double percentile(final double[] values, final int begin,
688 final int length, final double p) throws MathIllegalArgumentException {
689 return PERCENTILE.evaluate(values, begin, length, p);
690 }
691
692 /**
693 * Returns the sum of the (signed) differences between corresponding elements of the
694 * input arrays -- i.e., sum(sample1[i] - sample2[i]).
695 *
696 * @param sample1 the first array
697 * @param sample2 the second array
698 * @return sum of paired differences
699 * @throws DimensionMismatchException if the arrays do not have the same
700 * (positive) length.
701 * @throws NoDataException if the sample arrays are empty.
702 */
703 public static double sumDifference(final double[] sample1, final double[] sample2)
704 throws DimensionMismatchException, NoDataException {
705 int n = sample1.length;
706 if (n != sample2.length) {
707 throw new DimensionMismatchException(n, sample2.length);
708 }
709 if (n <= 0) {
710 throw new NoDataException(LocalizedFormats.INSUFFICIENT_DIMENSION);
711 }
712 double result = 0;
713 for (int i = 0; i < n; i++) {
714 result += sample1[i] - sample2[i];
715 }
716 return result;
717 }
718
719 /**
720 * Returns the mean of the (signed) differences between corresponding elements of the
721 * input arrays -- i.e., sum(sample1[i] - sample2[i]) / sample1.length.
722 *
723 * @param sample1 the first array
724 * @param sample2 the second array
725 * @return mean of paired differences
726 * @throws DimensionMismatchException if the arrays do not have the same
727 * (positive) length.
728 * @throws NoDataException if the sample arrays are empty.
729 */
730 public static double meanDifference(final double[] sample1, final double[] sample2)
731 throws DimensionMismatchException, NoDataException{
732 return sumDifference(sample1, sample2) / sample1.length;
733 }
734
735 /**
736 * Returns the variance of the (signed) differences between corresponding elements of the
737 * input arrays -- i.e., var(sample1[i] - sample2[i]).
738 *
739 * @param sample1 the first array
740 * @param sample2 the second array
741 * @param meanDifference the mean difference between corresponding entries
742 * @see #meanDifference(double[],double[])
743 * @return variance of paired differences
744 * @throws DimensionMismatchException if the arrays do not have the same
745 * length.
746 * @throws NumberIsTooSmallException if the arrays length is less than 2.
747 */
748 public static double varianceDifference(final double[] sample1,
749 final double[] sample2, double meanDifference) throws DimensionMismatchException,
750 NumberIsTooSmallException {
751 double sum1 = 0d;
752 double sum2 = 0d;
753 double diff = 0d;
754 int n = sample1.length;
755 if (n != sample2.length) {
756 throw new DimensionMismatchException(n, sample2.length);
757 }
758 if (n < 2) {
759 throw new NumberIsTooSmallException(n, 2, true);
760 }
761 for (int i = 0; i < n; i++) {
762 diff = sample1[i] - sample2[i];
763 sum1 += (diff - meanDifference) *(diff - meanDifference);
764 sum2 += diff - meanDifference;
765 }
766 return (sum1 - (sum2 * sum2 / n)) / (n - 1);
767 }
768
769 /**
770 * Normalize (standardize) the sample, so it is has a mean of 0 and a standard deviation of 1.
771 *
772 * @param sample Sample to normalize.
773 * @return normalized (standardized) sample.
774 * @since 2.2
775 */
776 public static double[] normalize(final double[] sample) {
777 DescriptiveStatistics stats = new DescriptiveStatistics();
778
779 // Add the data from the series to stats
780 for (int i = 0; i < sample.length; i++) {
781 stats.addValue(sample[i]);
782 }
783
784 // Compute mean and standard deviation
785 double mean = stats.getMean();
786 double standardDeviation = stats.getStandardDeviation();
787
788 // initialize the standardizedSample, which has the same length as the sample
789 double[] standardizedSample = new double[sample.length];
790
791 for (int i = 0; i < sample.length; i++) {
792 // z = (x- mean)/standardDeviation
793 standardizedSample[i] = (sample[i] - mean) / standardDeviation;
794 }
795 return standardizedSample;
796 }
797
798 /**
799 * Returns the sample mode(s). The mode is the most frequently occurring
800 * value in the sample. If there is a unique value with maximum frequency,
801 * this value is returned as the only element of the output array. Otherwise,
802 * the returned array contains the maximum frequency elements in increasing
803 * order. For example, if {@code sample} is {0, 12, 5, 6, 0, 13, 5, 17},
804 * the returned array will have length two, with 0 in the first element and
805 * 5 in the second.
806 *
807 * <p>NaN values are ignored when computing the mode - i.e., NaNs will never
808 * appear in the output array. If the sample includes only NaNs or has
809 * length 0, an empty array is returned.</p>
810 *
811 * @param sample input data
812 * @return array of array of the most frequently occurring element(s) sorted in ascending order.
813 * @throws MathIllegalArgumentException if the indices are invalid or the array is null
814 * @since 3.3
815 */
816 public static double[] mode(double[] sample) throws MathIllegalArgumentException {
817 if (sample == null) {
818 throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
819 }
820 return getMode(sample, 0, sample.length);
821 }
822
823 /**
824 * Returns the sample mode(s). The mode is the most frequently occurring
825 * value in the sample. If there is a unique value with maximum frequency,
826 * this value is returned as the only element of the output array. Otherwise,
827 * the returned array contains the maximum frequency elements in increasing
828 * order. For example, if {@code sample} is {0, 12, 5, 6, 0, 13, 5, 17},
829 * the returned array will have length two, with 0 in the first element and
830 * 5 in the second.
831 *
832 * <p>NaN values are ignored when computing the mode - i.e., NaNs will never
833 * appear in the output array. If the sample includes only NaNs or has
834 * length 0, an empty array is returned.</p>
835 *
836 * @param sample input data
837 * @param begin index (0-based) of the first array element to include
838 * @param length the number of elements to include
839 *
840 * @return array of array of the most frequently occurring element(s) sorted in ascending order.
841 * @throws MathIllegalArgumentException if the indices are invalid or the array is null
842 * @since 3.3
843 */
844 public static double[] mode(double[] sample, final int begin, final int length) {
845 if (sample == null) {
846 throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
847 }
848
849 if (begin < 0) {
850 throw new NotPositiveException(LocalizedFormats.START_POSITION, Integer.valueOf(begin));
851 }
852
853 if (length < 0) {
854 throw new NotPositiveException(LocalizedFormats.LENGTH, Integer.valueOf(length));
855 }
856
857 return getMode(sample, begin, length);
858 }
859
860 /**
861 * Private helper method.
862 * Assumes parameters have been validated.
863 * @param values input data
864 * @param begin index (0-based) of the first array element to include
865 * @param length the number of elements to include
866 * @return array of array of the most frequently occurring element(s) sorted in ascending order.
867 */
868 private static double[] getMode(double[] values, final int begin, final int length) {
869 // Add the values to the frequency table
870 Frequency freq = new Frequency();
871 for (int i = begin; i < begin + length; i++) {
872 final double value = values[i];
873 if (!Double.isNaN(value)) {
874 freq.addValue(Double.valueOf(value));
875 }
876 }
877 List<Comparable<?>> list = freq.getMode();
878 // Convert the list to an array of primitive double
879 double[] modes = new double[list.size()];
880 int i = 0;
881 for(Comparable<?> c : list) {
882 modes[i++] = ((Double) c).doubleValue();
883 }
884 return modes;
885 }
886
887}
Note: See TracBrowser for help on using the repository browser.