    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.summary;
    018
    019    import java.io.Serializable;
    020
    021    import org.apache.commons.math3.exception.MathIllegalArgumentException;
    022    import org.apache.commons.math3.exception.NullArgumentException;
    023    import org.apache.commons.math3.stat.descriptive.AbstractStorelessUnivariateStatistic;
    024    import org.apache.commons.math3.util.MathUtils;
    025
    026    /**
    027     * Returns the sum of the squares of the available values.
    028     * <p>
    029     * If there are no values in the dataset, then 0 is returned.
    030     * If any of the values are
    031     * <code>NaN</code>, then <code>NaN</code> is returned.</p>
    032     * <p>
    033     * <strong>Note that this implementation is not synchronized.</strong> If
    034     * multiple threads access an instance of this class concurrently, and at least
    035     * one of the threads invokes the <code>increment()</code> or
    036     * <code>clear()</code> method, it must be synchronized externally.</p>
    037     *
    038     * @version $Id: SumOfSquares.java 1416643 2012-12-03 19:37:14Z tn $
    039     */
    040    public class SumOfSquares extends AbstractStorelessUnivariateStatistic implements Serializable {
    041
    042        /** Serializable version identifier */
    043        private static final long serialVersionUID = 1460986908574398008L;
    044
    045        /** */
    046        private long n;
    047
    048        /**
    049         * The currently running sumSq
    050         */
    051        private double value;
    052
    053        /**
    054         * Create a SumOfSquares instance
    055         */
    056        public SumOfSquares() {
    057            n = 0;
    058            value = 0;
    059        }
    060
    061        /**
    062         * Copy constructor, creates a new {@code SumOfSquares} identical
    063         * to the {@code original}
    064         *
    065         * @param original the {@code SumOfSquares} instance to copy
    066         * @throws NullArgumentException if original is null
    067         */
    068        public SumOfSquares(SumOfSquares original) throws NullArgumentException {
    069            copy(original, this);
    070        }
    071
    072        /**
    073         * {@inheritDoc}
    074         */
    075        @Override
    076        public void increment(final double d) {
    077            value += d * d;
    078            n++;
    079        }
    080
    081        /**
    082         * {@inheritDoc}
    083         */
    084        @Override
    085        public double getResult() {
    086            return value;
    087        }
    088
    089        /**
    090         * {@inheritDoc}
    091         */
    092        public long getN() {
    093            return n;
    094        }
    095
    096        /**
    097         * {@inheritDoc}
    098         */
    099        @Override
    100        public void clear() {
    101            value = 0;
    102            n = 0;
    103        }
    104
    105        /**
    106         * Returns the sum of the squares of the entries in the specified portion of
    107         * the input array, or <code>Double.NaN</code> if the designated subarray
    108         * is empty.
    109         * <p>
    110         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
    111         *
    112         * @param values the input array
    113         * @param begin index of the first array element to include
    114         * @param length the number of elements to include
    115         * @return the sum of the squares of the values or 0 if length = 0
    116         * @throws MathIllegalArgumentException if the array is null or the array index
    117         *  parameters are not valid
    118         */
    119        @Override
    120        public double evaluate(final double[] values,final int begin, final int length)
    121        throws MathIllegalArgumentException {
    122            double sumSq = Double.NaN;
    123            if (test(values, begin, length, true)) {
    124                sumSq = 0.0;
    125                for (int i = begin; i < begin + length; i++) {
    126                    sumSq += values[i] * values[i];
    127                }
    128            }
    129            return sumSq;
    130        }
    131
    132        /**
    133         * {@inheritDoc}
    134         */
    135        @Override
    136        public SumOfSquares copy() {
    137            SumOfSquares result = new SumOfSquares();
    138            // no try-catch or advertised exception here because args are valid
    139            copy(this, result);
    140            return result;
    141        }
    142
    143        /**
    144         * Copies source to dest.
    145         * <p>Neither source nor dest can be null.</p>
    146         *
    147         * @param source SumOfSquares to copy
    148         * @param dest SumOfSquares to copy to
    149         * @throws NullArgumentException if either source or dest is null
    150         */
    151        public static void copy(SumOfSquares source, SumOfSquares dest)
    152            throws NullArgumentException {
    153            MathUtils.checkNotNull(source);
    154            MathUtils.checkNotNull(dest);
    155            dest.setData(source.getDataRef());
    156            dest.n = source.n;
    157            dest.value = source.value;
    158        }
    159
    160    }