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