View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.statistics.descriptive;
18  
19  /**
20   * Returns the sum of the squares of the available values. Uses the following definition:
21   *
22   * <p>\[ \sum_{i=1}^n x_i^2 \]
23   *
24   * <p>where \( n \) is the number of samples.
25   *
26   * <ul>
27   *   <li>The result is zero if no values are observed.
28   *   <li>The result is {@code NaN} if any of the values is {@code NaN}.
29   *   <li>The result is {@code +infinity} if any of the values is {@code infinity},
30   *       or the sum overflows.
31   * </ul>
32   *
33   * <p>This class is designed to work with (though does not require)
34   * {@linkplain java.util.stream streams}.
35   *
36   * <p><strong>This instance is not thread safe.</strong>
37   * If multiple threads access an instance of this class concurrently,
38   * and at least one of the threads invokes the {@link java.util.function.DoubleConsumer#accept(double) accept} or
39   * {@link StatisticAccumulator#combine(StatisticResult) combine} method, it must be synchronized externally.
40   *
41   * <p>However, it is safe to use {@link java.util.function.DoubleConsumer#accept(double) accept}
42   * and {@link StatisticAccumulator#combine(StatisticResult) combine}
43   * as {@code accumulator} and {@code combiner} functions of
44   * {@link java.util.stream.Collector Collector} on a parallel stream,
45   * because the parallel instance of {@link java.util.stream.Stream#collect Stream.collect()}
46   * provides the necessary partitioning, isolation, and merging of results for
47   * safe and efficient parallel execution.
48   *
49   * @since 1.1
50   */
51  public final class SumOfSquares implements DoubleStatistic, StatisticAccumulator<SumOfSquares> {
52  
53      /** Sum of squares of all values. */
54      private double ss;
55  
56      /**
57       * Create an instance.
58       */
59      private SumOfSquares() {
60          // No-op
61      }
62  
63      /**
64       * Creates an instance.
65       *
66       * <p>The initial result is zero.
67       *
68       * @return {@code SumOfSquares} instance.
69       */
70      public static SumOfSquares create() {
71          return new SumOfSquares();
72      }
73  
74      /**
75       * Returns an instance populated using the input {@code values}.
76       *
77       * <p>The result is {@code NaN} if any of the values is {@code NaN}
78       * or the product at any point is a {@code NaN}.
79       *
80       * <p>When the input is an empty array, the result is zero.
81       *
82       * @param values Values.
83       * @return {@code SumOfSquares} instance.
84       */
85      public static SumOfSquares of(double... values) {
86          return Statistics.add(new SumOfSquares(), values);
87      }
88  
89      /**
90       * Updates the state of the statistic to reflect the addition of {@code value}.
91       *
92       * @param value Value.
93       */
94      @Override
95      public void accept(double value) {
96          ss += value * value;
97      }
98  
99      /**
100      * Gets the sum of squares of all input values.
101      *
102      * <p>When no values have been added, the result is zero.
103      *
104      * @return sum of squares of all values.
105      */
106     @Override
107     public double getAsDouble() {
108         return ss;
109     }
110 
111     @Override
112     public SumOfSquares combine(SumOfSquares other) {
113         ss += other.ss;
114         return this;
115     }
116 }