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