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;
018
019 import org.apache.commons.math.exception.util.LocalizedFormats;
020 import org.apache.commons.math.exception.NullArgumentException;
021 import org.apache.commons.math.util.MathUtils;
022 import org.apache.commons.math.util.Precision;
023
024 /**
025 *
026 * Abstract implementation of the {@link StorelessUnivariateStatistic} interface.
027 * <p>
028 * Provides default <code>evaluate()</code> and <code>incrementAll(double[])<code>
029 * implementations.</p>
030 * <p>
031 * <strong>Note that these implementations are not synchronized.</strong></p>
032 *
033 * @version $Id: AbstractStorelessUnivariateStatistic.java 1181282 2011-10-10 22:35:54Z erans $
034 */
035 public abstract class AbstractStorelessUnivariateStatistic
036 extends AbstractUnivariateStatistic
037 implements StorelessUnivariateStatistic {
038
039 /**
040 * This default implementation calls {@link #clear}, then invokes
041 * {@link #increment} in a loop over the the input array, and then uses
042 * {@link #getResult} to compute the return value.
043 * <p>
044 * Note that this implementation changes the internal state of the
045 * statistic. Its side effects are the same as invoking {@link #clear} and
046 * then {@link #incrementAll(double[])}.</p>
047 * <p>
048 * Implementations may override this method with a more efficient and
049 * possibly more accurate implementation that works directly with the
050 * input array.</p>
051 * <p>
052 * If the array is null, an IllegalArgumentException is thrown.</p>
053 * @param values input array
054 * @return the value of the statistic applied to the input array
055 * @see org.apache.commons.math.stat.descriptive.UnivariateStatistic#evaluate(double[])
056 */
057 @Override
058 public double evaluate(final double[] values) {
059 if (values == null) {
060 throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
061 }
062 return evaluate(values, 0, values.length);
063 }
064
065 /**
066 * This default implementation calls {@link #clear}, then invokes
067 * {@link #increment} in a loop over the specified portion of the input
068 * array, and then uses {@link #getResult} to compute the return value.
069 * <p>
070 * Note that this implementation changes the internal state of the
071 * statistic. Its side effects are the same as invoking {@link #clear} and
072 * then {@link #incrementAll(double[], int, int)}.</p>
073 * <p>
074 * Implementations may override this method with a more efficient and
075 * possibly more accurate implementation that works directly with the
076 * input array.</p>
077 * <p>
078 * If the array is null or the index parameters are not valid, an
079 * IllegalArgumentException is thrown.</p>
080 * @param values the input array
081 * @param begin the index of the first element to include
082 * @param length the number of elements to include
083 * @return the value of the statistic applied to the included array entries
084 * @see org.apache.commons.math.stat.descriptive.UnivariateStatistic#evaluate(double[], int, int)
085 */
086 @Override
087 public double evaluate(final double[] values, final int begin, final int length) {
088 if (test(values, begin, length)) {
089 clear();
090 incrementAll(values, begin, length);
091 }
092 return getResult();
093 }
094
095 /**
096 * {@inheritDoc}
097 */
098 @Override
099 public abstract StorelessUnivariateStatistic copy();
100
101 /**
102 * {@inheritDoc}
103 */
104 public abstract void clear();
105
106 /**
107 * {@inheritDoc}
108 */
109 public abstract double getResult();
110
111 /**
112 * {@inheritDoc}
113 */
114 public abstract void increment(final double d);
115
116 /**
117 * This default implementation just calls {@link #increment} in a loop over
118 * the input array.
119 * <p>
120 * Throws IllegalArgumentException if the input values array is null.</p>
121 *
122 * @param values values to add
123 * @throws IllegalArgumentException if values is null
124 * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#incrementAll(double[])
125 */
126 public void incrementAll(double[] values) {
127 if (values == null) {
128 throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
129 }
130 incrementAll(values, 0, values.length);
131 }
132
133 /**
134 * This default implementation just calls {@link #increment} in a loop over
135 * the specified portion of the input array.
136 * <p>
137 * Throws IllegalArgumentException if the input values array is null.</p>
138 *
139 * @param values array holding values to add
140 * @param begin index of the first array element to add
141 * @param length number of array elements to add
142 * @throws IllegalArgumentException if values is null
143 * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#incrementAll(double[], int, int)
144 */
145 public void incrementAll(double[] values, int begin, int length) {
146 if (test(values, begin, length)) {
147 int k = begin + length;
148 for (int i = begin; i < k; i++) {
149 increment(values[i]);
150 }
151 }
152 }
153
154 /**
155 * Returns true iff <code>object</code> is an
156 * <code>AbstractStorelessUnivariateStatistic</code> returning the same
157 * values as this for <code>getResult()</code> and <code>getN()</code>
158 * @param object object to test equality against.
159 * @return true if object returns the same value as this
160 */
161 @Override
162 public boolean equals(Object object) {
163 if (object == this ) {
164 return true;
165 }
166 if (object instanceof AbstractStorelessUnivariateStatistic == false) {
167 return false;
168 }
169 AbstractStorelessUnivariateStatistic stat = (AbstractStorelessUnivariateStatistic) object;
170 return Precision.equalsIncludingNaN(stat.getResult(), this.getResult()) &&
171 Precision.equalsIncludingNaN(stat.getN(), this.getN());
172 }
173
174 /**
175 * Returns hash code based on getResult() and getN()
176 *
177 * @return hash code
178 */
179 @Override
180 public int hashCode() {
181 return 31* (31 + MathUtils.hash(getResult())) + MathUtils.hash(getN());
182 }
183
184 }