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.math3.stat.descriptive.summary;
18  
19  import java.io.Serializable;
20  
21  import org.apache.commons.math3.exception.MathIllegalArgumentException;
22  import org.apache.commons.math3.exception.NullArgumentException;
23  import org.apache.commons.math3.stat.descriptive.AbstractStorelessUnivariateStatistic;
24  import org.apache.commons.math3.util.MathUtils;
25  
26  
27  /**
28    * Returns the sum of the available values.
29   * <p>
30   * If there are no values in the dataset, then 0 is returned.
31   * If any of the values are
32   * <code>NaN</code>, then <code>NaN</code> is returned.</p>
33   * <p>
34   * <strong>Note that this implementation is not synchronized.</strong> If
35   * multiple threads access an instance of this class concurrently, and at least
36   * one of the threads invokes the <code>increment()</code> or
37   * <code>clear()</code> method, it must be synchronized externally.</p>
38   *
39   * @version $Id: Sum.java 1416643 2012-12-03 19:37:14Z tn $
40   */
41  public class Sum extends AbstractStorelessUnivariateStatistic implements Serializable {
42  
43      /** Serializable version identifier */
44      private static final long serialVersionUID = -8231831954703408316L;
45  
46      /** */
47      private long n;
48  
49      /**
50       * The currently running sum.
51       */
52      private double value;
53  
54      /**
55       * Create a Sum instance
56       */
57      public Sum() {
58          n = 0;
59          value = 0;
60      }
61  
62      /**
63       * Copy constructor, creates a new {@code Sum} identical
64       * to the {@code original}
65       *
66       * @param original the {@code Sum} instance to copy
67       * @throws NullArgumentException if original is null
68       */
69      public Sum(Sum original) throws NullArgumentException {
70          copy(original, this);
71      }
72  
73      /**
74       * {@inheritDoc}
75       */
76      @Override
77      public void increment(final double d) {
78          value += d;
79          n++;
80      }
81  
82      /**
83       * {@inheritDoc}
84       */
85      @Override
86      public double getResult() {
87          return value;
88      }
89  
90      /**
91       * {@inheritDoc}
92       */
93      public long getN() {
94          return n;
95      }
96  
97      /**
98       * {@inheritDoc}
99       */
100     @Override
101     public void clear() {
102         value = 0;
103         n = 0;
104     }
105 
106     /**
107      * The sum of the entries in the specified portion of
108      * the input array, or 0 if the designated subarray
109      * is empty.
110      * <p>
111      * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
112      *
113      * @param values the input array
114      * @param begin index of the first array element to include
115      * @param length the number of elements to include
116      * @return the sum of the values or 0 if length = 0
117      * @throws MathIllegalArgumentException if the array is null or the array index
118      *  parameters are not valid
119      */
120     @Override
121     public double evaluate(final double[] values, final int begin, final int length)
122     throws MathIllegalArgumentException {
123         double sum = Double.NaN;
124         if (test(values, begin, length, true)) {
125             sum = 0.0;
126             for (int i = begin; i < begin + length; i++) {
127                 sum += values[i];
128             }
129         }
130         return sum;
131     }
132 
133     /**
134      * The weighted sum of the entries in the specified portion of
135      * the input array, or 0 if the designated subarray
136      * is empty.
137      * <p>
138      * Throws <code>MathIllegalArgumentException</code> if any of the following are true:
139      * <ul><li>the values array is null</li>
140      *     <li>the weights array is null</li>
141      *     <li>the weights array does not have the same length as the values array</li>
142      *     <li>the weights array contains one or more infinite values</li>
143      *     <li>the weights array contains one or more NaN values</li>
144      *     <li>the weights array contains negative values</li>
145      *     <li>the start and length arguments do not determine a valid array</li>
146      * </ul></p>
147      * <p>
148      * Uses the formula, <pre>
149      *    weighted sum = &Sigma;(values[i] * weights[i])
150      * </pre></p>
151      *
152      * @param values the input array
153      * @param weights the weights array
154      * @param begin index of the first array element to include
155      * @param length the number of elements to include
156      * @return the sum of the values or 0 if length = 0
157      * @throws MathIllegalArgumentException if the parameters are not valid
158      * @since 2.1
159      */
160     public double evaluate(final double[] values, final double[] weights,
161         final int begin, final int length) throws MathIllegalArgumentException {
162         double sum = Double.NaN;
163         if (test(values, weights, begin, length, true)) {
164             sum = 0.0;
165             for (int i = begin; i < begin + length; i++) {
166                 sum += values[i] * weights[i];
167             }
168         }
169         return sum;
170     }
171 
172     /**
173      * The weighted sum of the entries in the the input array.
174      * <p>
175      * Throws <code>MathIllegalArgumentException</code> if any of the following are true:
176      * <ul><li>the values array is null</li>
177      *     <li>the weights array is null</li>
178      *     <li>the weights array does not have the same length as the values array</li>
179      *     <li>the weights array contains one or more infinite values</li>
180      *     <li>the weights array contains one or more NaN values</li>
181      *     <li>the weights array contains negative values</li>
182      * </ul></p>
183      * <p>
184      * Uses the formula, <pre>
185      *    weighted sum = &Sigma;(values[i] * weights[i])
186      * </pre></p>
187      *
188      * @param values the input array
189      * @param weights the weights array
190      * @return the sum of the values or Double.NaN if length = 0
191      * @throws MathIllegalArgumentException if the parameters are not valid
192      * @since 2.1
193      */
194     public double evaluate(final double[] values, final double[] weights)
195     throws MathIllegalArgumentException {
196         return evaluate(values, weights, 0, values.length);
197     }
198 
199     /**
200      * {@inheritDoc}
201      */
202     @Override
203     public Sum copy() {
204         Sum result = new Sum();
205         // No try-catch or advertised exception because args are valid
206         copy(this, result);
207         return result;
208     }
209 
210     /**
211      * Copies source to dest.
212      * <p>Neither source nor dest can be null.</p>
213      *
214      * @param source Sum to copy
215      * @param dest Sum to copy to
216      * @throws NullArgumentException if either source or dest is null
217      */
218     public static void copy(Sum source, Sum dest)
219         throws NullArgumentException {
220         MathUtils.checkNotNull(source);
221         MathUtils.checkNotNull(dest);
222         dest.setData(source.getDataRef());
223         dest.n = source.n;
224         dest.value = source.value;
225     }
226 
227 }