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;
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.exception.util.LocalizedFormats;
22 import org.apache.commons.math4.legacy.core.MathArrays;
23 import org.apache.commons.numbers.core.Precision;
24
25 /**
26 * Abstract base class for implementations of the
27 * {@link StorelessUnivariateStatistic} interface.
28 * <p>
29 * Provides default {@code evaluate(double[],...)} and {@code incrementAll(double[])}
30 * implementations.
31 * <p>
32 * <strong>Note that these implementations are not synchronized.</strong>
33 */
34 public abstract class AbstractStorelessUnivariateStatistic
35 implements StorelessUnivariateStatistic {
36
37 /**
38 * This default implementation creates a copy of this {@link StorelessUnivariateStatistic}
39 * instance, calls {@link #clear} on it, then calls {@link #incrementAll} with the specified
40 * portion of the input array, and then uses {@link #getResult} to compute the return value.
41 * <p>
42 * Note that this implementation does not change the internal state of the statistic.
43 * <p>
44 * Implementations may override this method with a more efficient and possibly more
45 * accurate implementation that works directly with the input array.
46 * <p>
47 * If the array is null, a MathIllegalArgumentException is thrown.
48 *
49 * @param values input array
50 * @return the value of the statistic applied to the input array
51 * @throws MathIllegalArgumentException if values is null
52 * @see org.apache.commons.math4.legacy.stat.descriptive.UnivariateStatistic#evaluate(double[])
53 */
54 @Override
55 public double evaluate(final double[] values) throws MathIllegalArgumentException {
56 if (values == null) {
57 throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
58 }
59 return evaluate(values, 0, values.length);
60 }
61
62 /**
63 * This default implementation creates a copy of this {@link StorelessUnivariateStatistic}
64 * instance, calls {@link #clear} on it, then calls {@link #incrementAll} with the specified
65 * portion of the input array, and then uses {@link #getResult} to compute the return value.
66 * <p>
67 * Note that this implementation does not change the internal state of the statistic.
68 * <p>
69 * Implementations may override this method with a more efficient and possibly more
70 * accurate implementation that works directly with the input array.
71 * <p>
72 * If the array is null or the index parameters are not valid, an
73 * MathIllegalArgumentException is thrown.
74 *
75 * @param values the input array
76 * @param begin the index of the first element to include
77 * @param length the number of elements to include
78 * @return the value of the statistic applied to the included array entries
79 * @throws MathIllegalArgumentException if the array is null or the indices are not valid
80 * @see org.apache.commons.math4.legacy.stat.descriptive.UnivariateStatistic#evaluate(double[], int, int)
81 */
82 @Override
83 public double evaluate(final double[] values, final int begin, final int length)
84 throws MathIllegalArgumentException {
85
86 if (MathArrays.verifyValues(values, begin, length)) {
87 final StorelessUnivariateStatistic stat = copy();
88 stat.clear();
89 stat.incrementAll(values, begin, length);
90 return stat.getResult();
91 }
92 return Double.NaN;
93 }
94
95 /**
96 * {@inheritDoc}
97 */
98 @Override
99 public abstract StorelessUnivariateStatistic copy();
100
101 /**
102 * {@inheritDoc}
103 */
104 @Override
105 public abstract void clear();
106
107 /**
108 * {@inheritDoc}
109 */
110 @Override
111 public abstract double getResult();
112
113 /**
114 * {@inheritDoc}
115 */
116 @Override
117 public abstract void increment(double d);
118
119 /**
120 * This default implementation just calls {@link #increment} in a loop over
121 * the input array.
122 * <p>
123 * Throws IllegalArgumentException if the input values array is null.
124 *
125 * @param values values to add
126 * @throws MathIllegalArgumentException if values is null
127 * @see StorelessUnivariateStatistic#incrementAll(double[])
128 */
129 @Override
130 public void incrementAll(double[] values) throws MathIllegalArgumentException {
131 if (values == null) {
132 throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
133 }
134 incrementAll(values, 0, values.length);
135 }
136
137 /**
138 * This default implementation just calls {@link #increment} in a loop over
139 * the specified portion of the input array.
140 * <p>
141 * Throws IllegalArgumentException if the input values array is null.
142 *
143 * @param values array holding values to add
144 * @param begin index of the first array element to add
145 * @param length number of array elements to add
146 * @throws MathIllegalArgumentException if values is null
147 * @see StorelessUnivariateStatistic#incrementAll(double[], int, int)
148 */
149 @Override
150 public void incrementAll(double[] values, int begin, int length) throws MathIllegalArgumentException {
151 if (MathArrays.verifyValues(values, begin, length)) {
152 int k = begin + length;
153 for (int i = begin; i < k; i++) {
154 increment(values[i]);
155 }
156 }
157 }
158
159 /**
160 * Returns true iff <code>object</code> is the same type of
161 * {@link StorelessUnivariateStatistic} (the object's class equals this
162 * instance) returning the same values as this for <code>getResult()</code>
163 * and <code>getN()</code>.
164 *
165 * @param object object to test equality against.
166 * @return true if object returns the same value as this
167 */
168 @Override
169 public boolean equals(Object object) {
170 if (object == this ) {
171 return true;
172 }
173 if (object == null || object.getClass() != this.getClass()) {
174 return false;
175 }
176 StorelessUnivariateStatistic stat = (StorelessUnivariateStatistic) object;
177 return Precision.equalsIncludingNaN(stat.getResult(), this.getResult()) &&
178 Precision.equalsIncludingNaN(stat.getN(), this.getN());
179 }
180
181 /**
182 * Returns hash code based on getResult() and getN().
183 *
184 * @return hash code
185 */
186 @Override
187 public int hashCode() {
188 return 31 * (31 + Double.hashCode(getResult())) + Double.hashCode(getN());
189 }
190 }