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.util.MathArrays;
31 import org.hipparchus.util.MathUtils;
32
33 /**
34 * Returns the sum of the squares of the available values.
35 * <p>
36 * If there are no values in the dataset, then 0 is returned.
37 * If any of the values are
38 * <code>NaN</code>, then <code>NaN</code> is returned.
39 * <p>
40 * <strong>Note that this implementation is not synchronized.</strong> If
41 * multiple threads access an instance of this class concurrently, and at least
42 * one of the threads invokes the <code>increment()</code> or
43 * <code>clear()</code> method, it must be synchronized externally.
44 */
45 public class SumOfSquares extends AbstractStorelessUnivariateStatistic
46 implements AggregatableStatistic<SumOfSquares>, Serializable {
47
48 /** Serializable version identifier */
49 private static final long serialVersionUID = 20150412L;
50
51 /** Number of values that have been added */
52 private long n;
53
54 /** The currently running sumSq */
55 private double value;
56
57 /**
58 * Create a SumOfSquares instance.
59 */
60 public SumOfSquares() {
61 n = 0;
62 value = 0;
63 }
64
65 /**
66 * Copy constructor, creates a new {@code SumOfSquares} identical
67 * to the {@code original}.
68 *
69 * @param original the {@code SumOfSquares} instance to copy
70 * @throws NullArgumentException if original is null
71 */
72 public SumOfSquares(SumOfSquares original) throws NullArgumentException {
73 MathUtils.checkNotNull(original);
74 this.n = original.n;
75 this.value = original.value;
76 }
77
78 /** {@inheritDoc} */
79 @Override
80 public void increment(final double d) {
81 value += d * d;
82 n++;
83 }
84
85 /** {@inheritDoc} */
86 @Override
87 public double getResult() {
88 return value;
89 }
90
91 /** {@inheritDoc} */
92 @Override
93 public long getN() {
94 return n;
95 }
96
97 /** {@inheritDoc} */
98 @Override
99 public void clear() {
100 value = 0;
101 n = 0;
102 }
103
104 /** {@inheritDoc} */
105 @Override
106 public void aggregate(SumOfSquares other) {
107 MathUtils.checkNotNull(other);
108 if (other.n > 0) {
109 this.n += other.n;
110 this.value += other.value;
111 }
112 }
113
114 /**
115 * Returns the sum of the squares of the entries in the specified portion of
116 * the input array, or <code>Double.NaN</code> if the designated subarray
117 * is empty.
118 *
119 * @param values the input array
120 * @param begin index of the first array element to include
121 * @param length the number of elements to include
122 * @return the sum of the squares of the values or 0 if length = 0
123 * @throws MathIllegalArgumentException if the array is null or the array index
124 * parameters are not valid
125 */
126 @Override
127 public double evaluate(final double[] values,final int begin, final int length)
128 throws MathIllegalArgumentException {
129
130 double sumSq = Double.NaN;
131 if (MathArrays.verifyValues(values, begin, length, true)) {
132 sumSq = 0.0;
133 for (int i = begin; i < begin + length; i++) {
134 sumSq += values[i] * values[i];
135 }
136 }
137 return sumSq;
138 }
139
140 /** {@inheritDoc} */
141 @Override
142 public SumOfSquares copy() {
143 return new SumOfSquares(this);
144 }
145
146 }