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.MathIllegalArgumentException; 022 import org.apache.commons.math3.exception.NullArgumentException; 023 import org.apache.commons.math3.stat.descriptive.AbstractStorelessUnivariateStatistic; 024 import org.apache.commons.math3.util.FastMath; 025 import org.apache.commons.math3.util.MathUtils; 026 027 /** 028 * Computes the sample standard deviation. The standard deviation 029 * is the positive square root of the variance. This implementation wraps a 030 * {@link Variance} instance. The <code>isBiasCorrected</code> property of the 031 * wrapped Variance instance is exposed, so that this class can be used to 032 * compute both the "sample standard deviation" (the square root of the 033 * bias-corrected "sample variance") or the "population standard deviation" 034 * (the square root of the non-bias-corrected "population variance"). See 035 * {@link Variance} for more information. 036 * <p> 037 * <strong>Note that this implementation is not synchronized.</strong> If 038 * multiple threads access an instance of this class concurrently, and at least 039 * one of the threads invokes the <code>increment()</code> or 040 * <code>clear()</code> method, it must be synchronized externally.</p> 041 * 042 * @version $Id: StandardDeviation.java 1416643 2012-12-03 19:37:14Z tn $ 043 */ 044 public class StandardDeviation extends AbstractStorelessUnivariateStatistic 045 implements Serializable { 046 047 /** Serializable version identifier */ 048 private static final long serialVersionUID = 5728716329662425188L; 049 050 /** Wrapped Variance instance */ 051 private Variance variance = null; 052 053 /** 054 * Constructs a StandardDeviation. Sets the underlying {@link Variance} 055 * instance's <code>isBiasCorrected</code> property to true. 056 */ 057 public StandardDeviation() { 058 variance = new Variance(); 059 } 060 061 /** 062 * Constructs a StandardDeviation from an external second moment. 063 * 064 * @param m2 the external moment 065 */ 066 public StandardDeviation(final SecondMoment m2) { 067 variance = new Variance(m2); 068 } 069 070 /** 071 * Copy constructor, creates a new {@code StandardDeviation} identical 072 * to the {@code original} 073 * 074 * @param original the {@code StandardDeviation} instance to copy 075 * @throws NullArgumentException if original is null 076 */ 077 public StandardDeviation(StandardDeviation original) throws NullArgumentException { 078 copy(original, this); 079 } 080 081 /** 082 * Contructs a StandardDeviation with the specified value for the 083 * <code>isBiasCorrected</code> property. If this property is set to 084 * <code>true</code>, the {@link Variance} used in computing results will 085 * use the bias-corrected, or "sample" formula. See {@link Variance} for 086 * details. 087 * 088 * @param isBiasCorrected whether or not the variance computation will use 089 * the bias-corrected formula 090 */ 091 public StandardDeviation(boolean isBiasCorrected) { 092 variance = new Variance(isBiasCorrected); 093 } 094 095 /** 096 * Contructs a StandardDeviation with the specified value for the 097 * <code>isBiasCorrected</code> property and the supplied external moment. 098 * If <code>isBiasCorrected</code> is set to <code>true</code>, the 099 * {@link Variance} used in computing results will use the bias-corrected, 100 * or "sample" formula. See {@link Variance} for details. 101 * 102 * @param isBiasCorrected whether or not the variance computation will use 103 * the bias-corrected formula 104 * @param m2 the external moment 105 */ 106 public StandardDeviation(boolean isBiasCorrected, SecondMoment m2) { 107 variance = new Variance(isBiasCorrected, m2); 108 } 109 110 /** 111 * {@inheritDoc} 112 */ 113 @Override 114 public void increment(final double d) { 115 variance.increment(d); 116 } 117 118 /** 119 * {@inheritDoc} 120 */ 121 public long getN() { 122 return variance.getN(); 123 } 124 125 /** 126 * {@inheritDoc} 127 */ 128 @Override 129 public double getResult() { 130 return FastMath.sqrt(variance.getResult()); 131 } 132 133 /** 134 * {@inheritDoc} 135 */ 136 @Override 137 public void clear() { 138 variance.clear(); 139 } 140 141 /** 142 * Returns the Standard Deviation of the entries in the input array, or 143 * <code>Double.NaN</code> if the array is empty. 144 * <p> 145 * Returns 0 for a single-value (i.e. length = 1) sample.</p> 146 * <p> 147 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p> 148 * <p> 149 * Does not change the internal state of the statistic.</p> 150 * 151 * @param values the input array 152 * @return the standard deviation of the values or Double.NaN if length = 0 153 * @throws MathIllegalArgumentException if the array is null 154 */ 155 @Override 156 public double evaluate(final double[] values) throws MathIllegalArgumentException { 157 return FastMath.sqrt(variance.evaluate(values)); 158 } 159 160 /** 161 * Returns the Standard Deviation of the entries in the specified portion of 162 * the input array, or <code>Double.NaN</code> if the designated subarray 163 * is empty. 164 * <p> 165 * Returns 0 for a single-value (i.e. length = 1) sample. </p> 166 * <p> 167 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p> 168 * <p> 169 * Does not change the internal state of the statistic.</p> 170 * 171 * @param values the input array 172 * @param begin index of the first array element to include 173 * @param length the number of elements to include 174 * @return the standard deviation of the values or Double.NaN if length = 0 175 * @throws MathIllegalArgumentException if the array is null or the array index 176 * parameters are not valid 177 */ 178 @Override 179 public double evaluate(final double[] values, final int begin, final int length) 180 throws MathIllegalArgumentException { 181 return FastMath.sqrt(variance.evaluate(values, begin, length)); 182 } 183 184 /** 185 * Returns the Standard Deviation of the entries in the specified portion of 186 * the input array, using the precomputed mean value. Returns 187 * <code>Double.NaN</code> if the designated subarray is empty. 188 * <p> 189 * Returns 0 for a single-value (i.e. length = 1) sample.</p> 190 * <p> 191 * The formula used assumes that the supplied mean value is the arithmetic 192 * mean of the sample data, not a known population parameter. This method 193 * is supplied only to save computation when the mean has already been 194 * computed.</p> 195 * <p> 196 * Throws <code>IllegalArgumentException</code> if the array is null.</p> 197 * <p> 198 * Does not change the internal state of the statistic.</p> 199 * 200 * @param values the input array 201 * @param mean the precomputed mean value 202 * @param begin index of the first array element to include 203 * @param length the number of elements to include 204 * @return the standard deviation of the values or Double.NaN if length = 0 205 * @throws MathIllegalArgumentException if the array is null or the array index 206 * parameters are not valid 207 */ 208 public double evaluate(final double[] values, final double mean, 209 final int begin, final int length) throws MathIllegalArgumentException { 210 return FastMath.sqrt(variance.evaluate(values, mean, begin, length)); 211 } 212 213 /** 214 * Returns the Standard Deviation of the entries in the input array, using 215 * the precomputed mean value. Returns 216 * <code>Double.NaN</code> if the designated subarray is empty. 217 * <p> 218 * Returns 0 for a single-value (i.e. length = 1) sample.</p> 219 * <p> 220 * The formula used assumes that the supplied mean value is the arithmetic 221 * mean of the sample data, not a known population parameter. This method 222 * is supplied only to save computation when the mean has already been 223 * computed.</p> 224 * <p> 225 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p> 226 * <p> 227 * Does not change the internal state of the statistic.</p> 228 * 229 * @param values the input array 230 * @param mean the precomputed mean value 231 * @return the standard deviation of the values or Double.NaN if length = 0 232 * @throws MathIllegalArgumentException if the array is null 233 */ 234 public double evaluate(final double[] values, final double mean) 235 throws MathIllegalArgumentException { 236 return FastMath.sqrt(variance.evaluate(values, mean)); 237 } 238 239 /** 240 * @return Returns the isBiasCorrected. 241 */ 242 public boolean isBiasCorrected() { 243 return variance.isBiasCorrected(); 244 } 245 246 /** 247 * @param isBiasCorrected The isBiasCorrected to set. 248 */ 249 public void setBiasCorrected(boolean isBiasCorrected) { 250 variance.setBiasCorrected(isBiasCorrected); 251 } 252 253 /** 254 * {@inheritDoc} 255 */ 256 @Override 257 public StandardDeviation copy() { 258 StandardDeviation result = new StandardDeviation(); 259 // No try-catch or advertised exception because args are guaranteed non-null 260 copy(this, result); 261 return result; 262 } 263 264 265 /** 266 * Copies source to dest. 267 * <p>Neither source nor dest can be null.</p> 268 * 269 * @param source StandardDeviation to copy 270 * @param dest StandardDeviation to copy to 271 * @throws NullArgumentException if either source or dest is null 272 */ 273 public static void copy(StandardDeviation source, StandardDeviation dest) 274 throws NullArgumentException { 275 MathUtils.checkNotNull(source); 276 MathUtils.checkNotNull(dest); 277 dest.setData(source.getDataRef()); 278 dest.variance = source.variance.copy(); 279 } 280 281 }