View Javadoc

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   */
17  package org.apache.commons.math.stat.descriptive.summary;
18  
19  import java.io.Serializable;
20  
21  import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
22  
23  /**
24   * Returns the sum of the natural logs for this collection of values.  
25   * <p>
26   * Uses {@link java.lang.Math#log(double)} to compute the logs.  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>Double.NEGATIVE_INFINITY.</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></p>
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.</p>
41   * 
42   * @version $Revision: 762087 $ $Date: 2009-04-05 10:20:18 -0400 (Sun, 05 Apr 2009) $
43   */
44  public class SumOfLogs extends AbstractStorelessUnivariateStatistic implements Serializable {
45  
46      /** Serializable version identifier */
47      private static final long serialVersionUID = -370076995648386763L;    
48  
49      /**Number of values that have been added */
50      private int n;
51      
52      /**
53       * The currently running value
54       */
55      private double value;
56      
57      /**
58       * Create a SumOfLogs instance
59       */
60      public SumOfLogs() {
61         value = 0d;
62         n = 0;
63      }
64      
65      /**
66       * Copy constructor, creates a new {@code SumOfLogs} identical
67       * to the {@code original}
68       * 
69       * @param original the {@code SumOfLogs} instance to copy
70       */
71      public SumOfLogs(SumOfLogs original) {
72          copy(original, this);
73      }
74  
75      /**
76       * {@inheritDoc}
77       */
78      @Override
79      public void increment(final double d) {
80          value += Math.log(d);
81          n++;
82      }
83  
84      /**
85       * {@inheritDoc}
86       */
87      @Override
88      public double getResult() {
89          if (n > 0) {
90              return value;
91          } else {
92              return Double.NaN;
93          }
94      }
95  
96      /**
97       * {@inheritDoc}
98       */
99      public long getN() {
100         return n;
101     }
102     
103     /**
104      * {@inheritDoc}
105      */
106     @Override
107     public void clear() {
108         value = 0d;
109         n = 0;
110     }
111 
112     /**
113      * Returns the sum of the natural logs of the entries in the specified portion of
114      * the input array, or <code>Double.NaN</code> if the designated subarray
115      * is empty.
116      * <p>
117      * Throws <code>IllegalArgumentException</code> if the array is null.</p>
118      * <p>
119      * See {@link SumOfLogs}.</p>
120      * 
121      * @param values the input array
122      * @param begin index of the first array element to include
123      * @param length the number of elements to include
124      * @return the sum of the natural logs of the values or Double.NaN if 
125      * length = 0
126      * @throws IllegalArgumentException if the array is null or the array index
127      *  parameters are not valid
128      */
129     @Override
130     public double evaluate(final double[] values, final int begin, final int length) {
131         double sumLog = Double.NaN;
132         if (test(values, begin, length)) {
133             sumLog = 0.0;
134             for (int i = begin; i < begin + length; i++) {
135                 sumLog += Math.log(values[i]);
136             }
137         }
138         return sumLog;
139     }
140     
141     /**
142      * {@inheritDoc}
143      */
144     @Override
145     public SumOfLogs copy() {
146         SumOfLogs result = new SumOfLogs();
147         copy(this, result);
148         return result;
149     }
150     
151     /**
152      * Copies source to dest.
153      * <p>Neither source nor dest can be null.</p>
154      * 
155      * @param source SumOfLogs to copy
156      * @param dest SumOfLogs to copy to
157      * @throws NullPointerException if either source or dest is null
158      */
159     public static void copy(SumOfLogs source, SumOfLogs dest) {
160         dest.n = source.n;
161         dest.value = source.value;
162     }
163 }