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 }