001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math3.stat.descriptive.summary;
018
019 import java.io.Serializable;
020
021 import org.apache.commons.math3.exception.MathIllegalArgumentException;
022 import org.apache.commons.math3.exception.NullArgumentException;
023 import org.apache.commons.math3.stat.descriptive.AbstractStorelessUnivariateStatistic;
024 import org.apache.commons.math3.util.MathUtils;
025
026
027 /**
028 * Returns the sum of the available values.
029 * <p>
030 * If there are no values in the dataset, then 0 is returned.
031 * If any of the values are
032 * <code>NaN</code>, then <code>NaN</code> is returned.</p>
033 * <p>
034 * <strong>Note that this implementation is not synchronized.</strong> If
035 * multiple threads access an instance of this class concurrently, and at least
036 * one of the threads invokes the <code>increment()</code> or
037 * <code>clear()</code> method, it must be synchronized externally.</p>
038 *
039 * @version $Id: Sum.java 1416643 2012-12-03 19:37:14Z tn $
040 */
041 public class Sum extends AbstractStorelessUnivariateStatistic implements Serializable {
042
043 /** Serializable version identifier */
044 private static final long serialVersionUID = -8231831954703408316L;
045
046 /** */
047 private long n;
048
049 /**
050 * The currently running sum.
051 */
052 private double value;
053
054 /**
055 * Create a Sum instance
056 */
057 public Sum() {
058 n = 0;
059 value = 0;
060 }
061
062 /**
063 * Copy constructor, creates a new {@code Sum} identical
064 * to the {@code original}
065 *
066 * @param original the {@code Sum} instance to copy
067 * @throws NullArgumentException if original is null
068 */
069 public Sum(Sum original) throws NullArgumentException {
070 copy(original, this);
071 }
072
073 /**
074 * {@inheritDoc}
075 */
076 @Override
077 public void increment(final double d) {
078 value += d;
079 n++;
080 }
081
082 /**
083 * {@inheritDoc}
084 */
085 @Override
086 public double getResult() {
087 return value;
088 }
089
090 /**
091 * {@inheritDoc}
092 */
093 public long getN() {
094 return n;
095 }
096
097 /**
098 * {@inheritDoc}
099 */
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 = Σ(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 = Σ(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 }