View Javadoc
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 }