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