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