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