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