View Javadoc

    1   /*
    2    * Copyright 2003-2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.math.stat.descriptive.moment;
    17
    18  import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
    19  import org.apache.commons.math.stat.descriptive.summary.SumOfLogs;
    20
    21  /***
    22   * Returns the <a href="http://www.xycoon.com/geometric_mean.htm">
    23   * geometric mean </a> of the available values.
    24   * <p>
    25   * Uses a {@link SumOfLogs} instance to compute sum of logs and returns
    26   * <code> exp( 1/n  (sum of logs) ).</code>  Therefore,
    27   * <ul>
    28   * <li>If any of values are < 0, the result is <code>NaN.</code></li>
    29   * <li>If all values are non-negative and less than
    30   * <code>Double.POSITIVE_INFINITY</code>,  but at least one value is 0, the
    31   * result is <code>0.</code></li>
    32   * <li>If both <code>Double.POSITIVE_INFINITY</code> and
    33   * <code>Double.NEGATIVE_INFINITY</code> are among the values, the result is
    34   * <code>NaN.</code></li>
    35   * </ul>
    36   * <p>
    37   * <strong>Note that this implementation is not synchronized.</strong> If
    38   * multiple threads access an instance of this class concurrently, and at least
    39   * one of the threads invokes the <code>increment()</code> or
    40   * <code>clear()</code> method, it must be synchronized externally.
    41   *
    42   *
    43   * @version $Revision: 348519 $ $Date: 2005-11-23 12:12:18 -0700 (Wed, 23 Nov 2005) $
    44   */
    45  public class GeometricMean extends AbstractStorelessUnivariateStatistic {
    46
    47      /*** Serializable version identifier */
    48      private static final long serialVersionUID = -8178734905303459453L;
    49
    50      /*** Wrapped SumOfLogs instance */
    51      private SumOfLogs sumOfLogs;
    52
    53      /***
    54       * Create a GeometricMean instance
    55       */
    56      public GeometricMean() {
    57          sumOfLogs = new SumOfLogs();
    58      }
    59
    60      /***
    61       * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double)
    62       */
    63      public void increment(final double d) {
    64          sumOfLogs.increment(d);
    65      }
    66
    67      /***
    68       * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getResult()
    69       */
    70      public double getResult() {
    71          if (sumOfLogs.getN() > 0) {
    72              return Math.exp(sumOfLogs.getResult() / (double) sumOfLogs.getN());
    73          } else {
    74              return Double.NaN;
    75          }
    76      }
    77
    78      /***
    79       * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#clear()
    80       */
    81      public void clear() {
    82          sumOfLogs.clear();
    83      }
    84
    85      /***
    86       * Returns the geometric mean of the entries in the specified portion
    87       * of the input array.
    88       * <p>
    89       * See {@link GeometricMean} for details on the computing algorithm.
    90       * <p>
    91       * Throws <code>IllegalArgumentException</code> if the array is null.
    92       *
    93       * @param values input array containing the values
    94       * @param begin first array element to include
    95       * @param length the number of elements to include
    96       * @return the geometric mean or Double.NaN if length = 0 or
    97       * any of the values are &lt;= 0.
    98       * @throws IllegalArgumentException if the input array is null or the array
    99       * index parameters are not valid
    100      */
    101     public double evaluate(
    102         final double[] values, final int begin, final int length) {
    103         return Math.exp(
    104             sumOfLogs.evaluate(values, begin, length) / (double) length);
    105     }
    106
    107     /***
    108      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getN()
    109      */
    110     public long getN() {
    111         return sumOfLogs.getN();
    112     }
    113
    114 }