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 */ 017package org.apache.commons.math3.stat; 018 019import java.util.List; 020 021import org.apache.commons.math3.exception.MathIllegalArgumentException; 022import org.apache.commons.math3.exception.NotPositiveException; 023import org.apache.commons.math3.exception.NullArgumentException; 024import org.apache.commons.math3.exception.NumberIsTooSmallException; 025import org.apache.commons.math3.exception.DimensionMismatchException; 026import org.apache.commons.math3.exception.NoDataException; 027import org.apache.commons.math3.exception.util.LocalizedFormats; 028import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; 029import org.apache.commons.math3.stat.descriptive.UnivariateStatistic; 030import org.apache.commons.math3.stat.descriptive.moment.GeometricMean; 031import org.apache.commons.math3.stat.descriptive.moment.Mean; 032import org.apache.commons.math3.stat.descriptive.moment.Variance; 033import org.apache.commons.math3.stat.descriptive.rank.Max; 034import org.apache.commons.math3.stat.descriptive.rank.Min; 035import org.apache.commons.math3.stat.descriptive.rank.Percentile; 036import org.apache.commons.math3.stat.descriptive.summary.Product; 037import org.apache.commons.math3.stat.descriptive.summary.Sum; 038import org.apache.commons.math3.stat.descriptive.summary.SumOfLogs; 039import org.apache.commons.math3.stat.descriptive.summary.SumOfSquares; 040 041/** 042 * StatUtils provides static methods for computing statistics based on data 043 * stored in double[] arrays. 044 * 045 */ 046public final class StatUtils { 047 048 /** sum */ 049 private static final UnivariateStatistic SUM = new Sum(); 050 051 /** sumSq */ 052 private static final UnivariateStatistic SUM_OF_SQUARES = new SumOfSquares(); 053 054 /** prod */ 055 private static final UnivariateStatistic PRODUCT = new Product(); 056 057 /** sumLog */ 058 private static final UnivariateStatistic SUM_OF_LOGS = new SumOfLogs(); 059 060 /** min */ 061 private static final UnivariateStatistic MIN = new Min(); 062 063 /** max */ 064 private static final UnivariateStatistic MAX = new Max(); 065 066 /** mean */ 067 private static final UnivariateStatistic MEAN = new Mean(); 068 069 /** variance */ 070 private static final Variance VARIANCE = new Variance(); 071 072 /** percentile */ 073 private static final Percentile PERCENTILE = new Percentile(); 074 075 /** geometric mean */ 076 private static final GeometricMean GEOMETRIC_MEAN = new GeometricMean(); 077 078 /** 079 * Private Constructor 080 */ 081 private StatUtils() { 082 } 083 084 /** 085 * Returns the sum of the values in the input array, or 086 * <code>Double.NaN</code> if the array is empty. 087 * <p> 088 * Throws <code>IllegalArgumentException</code> if the input array 089 * is null.</p> 090 * 091 * @param values array of values to sum 092 * @return the sum of the values or <code>Double.NaN</code> if the array 093 * is empty 094 * @throws MathIllegalArgumentException if the array is null 095 */ 096 public static double sum(final double[] values) 097 throws MathIllegalArgumentException { 098 return SUM.evaluate(values); 099 } 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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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 org.apache.commons.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}