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 * https://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
18 /*
19 * This is not the original file distributed by the Apache Software Foundation
20 * It has been modified by the Hipparchus project
21 */
22 package org.hipparchus.stat.descriptive.summary;
23
24 import java.io.Serializable;
25
26 import org.hipparchus.exception.MathIllegalArgumentException;
27 import org.hipparchus.exception.NullArgumentException;
28 import org.hipparchus.stat.descriptive.AbstractStorelessUnivariateStatistic;
29 import org.hipparchus.stat.descriptive.AggregatableStatistic;
30 import org.hipparchus.stat.descriptive.WeightedEvaluation;
31 import org.hipparchus.util.MathArrays;
32 import org.hipparchus.util.MathUtils;
33
34
35 /**
36 * Returns the sum of the available values.
37 * <p>
38 * If there are no values in the dataset, then 0 is returned.
39 * If any of the values are
40 * <code>NaN</code>, then <code>NaN</code> is returned.
41 * <p>
42 * <strong>Note that this implementation is not synchronized.</strong> If
43 * multiple threads access an instance of this class concurrently, and at least
44 * one of the threads invokes the <code>increment()</code> or
45 * <code>clear()</code> method, it must be synchronized externally.
46 */
47 public class Sum extends AbstractStorelessUnivariateStatistic
48 implements AggregatableStatistic<Sum>, WeightedEvaluation, Serializable {
49
50 /** Serializable version identifier */
51 private static final long serialVersionUID = 20150412L;
52
53 /** The number of values that have been added */
54 private long n;
55
56 /** The currently running sum */
57 private double value;
58
59 /**
60 * Create a Sum instance.
61 */
62 public Sum() {
63 n = 0;
64 value = 0;
65 }
66
67 /**
68 * Copy constructor, creates a new {@code Sum} identical
69 * to the {@code original}.
70 *
71 * @param original the {@code Sum} instance to copy
72 * @throws NullArgumentException if original is null
73 */
74 public Sum(Sum original) throws NullArgumentException {
75 MathUtils.checkNotNull(original);
76 this.n = original.n;
77 this.value = original.value;
78 }
79
80 /** {@inheritDoc} */
81 @Override
82 public void increment(final double d) {
83 value += d;
84 n++;
85 }
86
87 /** {@inheritDoc} */
88 @Override
89 public double getResult() {
90 return value;
91 }
92
93 /** {@inheritDoc} */
94 @Override
95 public long getN() {
96 return n;
97 }
98
99 /** {@inheritDoc} */
100 @Override
101 public void clear() {
102 value = 0;
103 n = 0;
104 }
105
106 /** {@inheritDoc} */
107 @Override
108 public void aggregate(Sum other) {
109 MathUtils.checkNotNull(other);
110 if (other.n > 0) {
111 this.n += other.n;
112 this.value += other.value;
113 }
114 }
115
116 /**
117 * The sum of the entries in the specified portion of the input array,
118 * or 0 if the designated subarray is empty.
119 *
120 * @param values the input array
121 * @param begin index of the first array element to include
122 * @param length the number of elements to include
123 * @return the sum of the values or 0 if length = 0
124 * @throws MathIllegalArgumentException if the array is null or the array index
125 * parameters are not valid
126 */
127 @Override
128 public double evaluate(final double[] values, final int begin, final int length)
129 throws MathIllegalArgumentException {
130
131 double sum = Double.NaN;
132 if (MathArrays.verifyValues(values, begin, length, true)) {
133 sum = 0.0;
134 for (int i = begin; i < begin + length; i++) {
135 sum += values[i];
136 }
137 }
138 return sum;
139 }
140
141 /**
142 * The weighted sum of the entries in the specified portion of
143 * the input array, or 0 if the designated subarray
144 * is empty.
145 * <p>
146 * Throws <code>MathIllegalArgumentException</code> if any of the following are true:
147 * </p>
148 * <ul><li>the values array is null</li>
149 * <li>the weights array is null</li>
150 * <li>the weights array does not have the same length as the values array</li>
151 * <li>the weights array contains one or more infinite values</li>
152 * <li>the weights array contains one or more NaN values</li>
153 * <li>the weights array contains negative values</li>
154 * <li>the start and length arguments do not determine a valid array</li>
155 * </ul>
156 * <p>
157 * Uses the formula,</p><pre>
158 * weighted sum = Σ(values[i] * weights[i])
159 * </pre>
160 *
161 * @param values the input array
162 * @param weights the weights array
163 * @param begin index of the first array element to include
164 * @param length the number of elements to include
165 * @return the sum of the values or 0 if length = 0
166 * @throws MathIllegalArgumentException if the parameters are not valid
167 */
168 @Override
169 public double evaluate(final double[] values, final double[] weights,
170 final int begin, final int length) throws MathIllegalArgumentException {
171 double sum = Double.NaN;
172 if (MathArrays.verifyValues(values, weights, begin, length, true)) {
173 sum = 0.0;
174 for (int i = begin; i < begin + length; i++) {
175 sum += values[i] * weights[i];
176 }
177 }
178 return sum;
179 }
180
181 /** {@inheritDoc} */
182 @Override
183 public Sum copy() {
184 return new Sum(this);
185 }
186
187 }