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.moment; 018 019 import java.io.Serializable; 020 021 import org.apache.commons.math3.exception.NullArgumentException; 022 import org.apache.commons.math3.util.MathUtils; 023 024 /** 025 * Computes a statistic related to the Second Central Moment. Specifically, 026 * what is computed is the sum of squared deviations from the sample mean. 027 * <p> 028 * The following recursive updating formula is used:</p> 029 * <p> 030 * Let <ul> 031 * <li> dev = (current obs - previous mean) </li> 032 * <li> n = number of observations (including current obs) </li> 033 * </ul> 034 * Then</p> 035 * <p> 036 * new value = old value + dev^2 * (n -1) / n.</p> 037 * <p> 038 * Returns <code>Double.NaN</code> if no data values have been added and 039 * returns <code>0</code> if there is just one value in the data set.</p> 040 * <p> 041 * <strong>Note that this implementation is not synchronized.</strong> If 042 * multiple threads access an instance of this class concurrently, and at least 043 * one of the threads invokes the <code>increment()</code> or 044 * <code>clear()</code> method, it must be synchronized externally.</p> 045 * 046 * @version $Id: SecondMoment.java 1416643 2012-12-03 19:37:14Z tn $ 047 */ 048 public class SecondMoment extends FirstMoment implements Serializable { 049 050 /** Serializable version identifier */ 051 private static final long serialVersionUID = 3942403127395076445L; 052 053 /** second moment of values that have been added */ 054 protected double m2; 055 056 /** 057 * Create a SecondMoment instance 058 */ 059 public SecondMoment() { 060 super(); 061 m2 = Double.NaN; 062 } 063 064 /** 065 * Copy constructor, creates a new {@code SecondMoment} identical 066 * to the {@code original} 067 * 068 * @param original the {@code SecondMoment} instance to copy 069 * @throws NullArgumentException if original is null 070 */ 071 public SecondMoment(SecondMoment original) 072 throws NullArgumentException { 073 super(original); 074 this.m2 = original.m2; 075 } 076 077 /** 078 * {@inheritDoc} 079 */ 080 @Override 081 public void increment(final double d) { 082 if (n < 1) { 083 m1 = m2 = 0.0; 084 } 085 super.increment(d); 086 m2 += ((double) n - 1) * dev * nDev; 087 } 088 089 /** 090 * {@inheritDoc} 091 */ 092 @Override 093 public void clear() { 094 super.clear(); 095 m2 = Double.NaN; 096 } 097 098 /** 099 * {@inheritDoc} 100 */ 101 @Override 102 public double getResult() { 103 return m2; 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 @Override 110 public SecondMoment copy() { 111 SecondMoment result = new SecondMoment(); 112 // no try-catch or advertised NAE because args are guaranteed non-null 113 copy(this, result); 114 return result; 115 } 116 117 /** 118 * Copies source to dest. 119 * <p>Neither source nor dest can be null.</p> 120 * 121 * @param source SecondMoment to copy 122 * @param dest SecondMoment to copy to 123 * @throws NullArgumentException if either source or dest is null 124 */ 125 public static void copy(SecondMoment source, SecondMoment dest) 126 throws NullArgumentException { 127 MathUtils.checkNotNull(source); 128 MathUtils.checkNotNull(dest); 129 FirstMoment.copy(source, dest); 130 dest.m2 = source.m2; 131 } 132 133 }