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.math.stat.descriptive.summary;
018
019 import java.io.Serializable;
020
021 import org.apache.commons.math.exception.NullArgumentException;
022 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
023 import org.apache.commons.math.util.MathUtils;
024
025
026 /**
027 * Returns the sum of the available values.
028 * <p>
029 * If there are no values in the dataset, then 0 is returned.
030 * If any of the values are
031 * <code>NaN</code>, then <code>NaN</code> is returned.</p>
032 * <p>
033 * <strong>Note that this implementation is not synchronized.</strong> If
034 * multiple threads access an instance of this class concurrently, and at least
035 * one of the threads invokes the <code>increment()</code> or
036 * <code>clear()</code> method, it must be synchronized externally.</p>
037 *
038 * @version $Id: Sum.java 1132432 2011-06-05 14:59:29Z luc $
039 */
040 public class Sum extends AbstractStorelessUnivariateStatistic implements Serializable {
041
042 /** Serializable version identifier */
043 private static final long serialVersionUID = -8231831954703408316L;
044
045 /** */
046 private long n;
047
048 /**
049 * The currently running sum.
050 */
051 private double value;
052
053 /**
054 * Create a Sum instance
055 */
056 public Sum() {
057 n = 0;
058 value = 0;
059 }
060
061 /**
062 * Copy constructor, creates a new {@code Sum} identical
063 * to the {@code original}
064 *
065 * @param original the {@code Sum} instance to copy
066 */
067 public Sum(Sum original) {
068 copy(original, this);
069 }
070
071 /**
072 * {@inheritDoc}
073 */
074 @Override
075 public void increment(final double d) {
076 value += d;
077 n++;
078 }
079
080 /**
081 * {@inheritDoc}
082 */
083 @Override
084 public double getResult() {
085 return value;
086 }
087
088 /**
089 * {@inheritDoc}
090 */
091 public long getN() {
092 return n;
093 }
094
095 /**
096 * {@inheritDoc}
097 */
098 @Override
099 public void clear() {
100 value = 0;
101 n = 0;
102 }
103
104 /**
105 * The sum of the entries in the specified portion of
106 * the input array, or 0 if the designated subarray
107 * is empty.
108 * <p>
109 * Throws <code>IllegalArgumentException</code> if the array is null.</p>
110 *
111 * @param values the input array
112 * @param begin index of the first array element to include
113 * @param length the number of elements to include
114 * @return the sum of the values or 0 if length = 0
115 * @throws IllegalArgumentException if the array is null or the array index
116 * parameters are not valid
117 */
118 @Override
119 public double evaluate(final double[] values, final int begin, final int length) {
120 double sum = Double.NaN;
121 if (test(values, begin, length, true)) {
122 sum = 0.0;
123 for (int i = begin; i < begin + length; i++) {
124 sum += values[i];
125 }
126 }
127 return sum;
128 }
129
130 /**
131 * The weighted sum of the entries in the specified portion of
132 * the input array, or 0 if the designated subarray
133 * is empty.
134 * <p>
135 * Throws <code>IllegalArgumentException</code> if any of the following are true:
136 * <ul><li>the values array is null</li>
137 * <li>the weights array is null</li>
138 * <li>the weights array does not have the same length as the values array</li>
139 * <li>the weights array contains one or more infinite values</li>
140 * <li>the weights array contains one or more NaN values</li>
141 * <li>the weights array contains negative values</li>
142 * <li>the start and length arguments do not determine a valid array</li>
143 * </ul></p>
144 * <p>
145 * Uses the formula, <pre>
146 * weighted sum = Σ(values[i] * weights[i])
147 * </pre></p>
148 *
149 * @param values the input array
150 * @param weights the weights array
151 * @param begin index of the first array element to include
152 * @param length the number of elements to include
153 * @return the sum of the values or 0 if length = 0
154 * @throws IllegalArgumentException if the parameters are not valid
155 * @since 2.1
156 */
157 public double evaluate(final double[] values, final double[] weights,
158 final int begin, final int length) {
159 double sum = Double.NaN;
160 if (test(values, weights, begin, length, true)) {
161 sum = 0.0;
162 for (int i = begin; i < begin + length; i++) {
163 sum += values[i] * weights[i];
164 }
165 }
166 return sum;
167 }
168
169 /**
170 * The weighted sum of the entries in the the input array.
171 * <p>
172 * Throws <code>IllegalArgumentException</code> if any of the following are true:
173 * <ul><li>the values array is null</li>
174 * <li>the weights array is null</li>
175 * <li>the weights array does not have the same length as the values array</li>
176 * <li>the weights array contains one or more infinite values</li>
177 * <li>the weights array contains one or more NaN values</li>
178 * <li>the weights array contains negative values</li>
179 * </ul></p>
180 * <p>
181 * Uses the formula, <pre>
182 * weighted sum = Σ(values[i] * weights[i])
183 * </pre></p>
184 *
185 * @param values the input array
186 * @param weights the weights array
187 * @return the sum of the values or Double.NaN if length = 0
188 * @throws IllegalArgumentException if the parameters are not valid
189 * @since 2.1
190 */
191 public double evaluate(final double[] values, final double[] weights) {
192 return evaluate(values, weights, 0, values.length);
193 }
194
195 /**
196 * {@inheritDoc}
197 */
198 @Override
199 public Sum copy() {
200 Sum result = new Sum();
201 copy(this, result);
202 return result;
203 }
204
205 /**
206 * Copies source to dest.
207 * <p>Neither source nor dest can be null.</p>
208 *
209 * @param source Sum to copy
210 * @param dest Sum to copy to
211 * @throws NullArgumentException if either source or dest is null
212 */
213 public static void copy(Sum source, Sum dest)
214 throws NullArgumentException {
215 MathUtils.checkNotNull(source);
216 MathUtils.checkNotNull(dest);
217 dest.setData(source.getDataRef());
218 dest.n = source.n;
219 dest.value = source.value;
220 }
221
222 }