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 }