Coverage Report - org.apache.commons.math.stat.descriptive.moment.Variance

Classes in this File Line Coverage Branch Coverage Complexity
Variance
95% 
100% 
2.286

 1  
 /*
 2  
  * Copyright 2003-2004 The Apache Software Foundation.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.apache.commons.math.stat.descriptive.moment;
 17  
 
 18  
 import java.io.Serializable;
 19  
 
 20  
 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
 21  
 
 22  
 /**
 23  
  * Computes the variance of the available values.   By default, the unbiased
 24  
  * "sample variance" definitional formula is used: 
 25  
  * <p>
 26  
  * variance = sum((x_i - mean)^2) / (n - 1)
 27  
  * <p>
 28  
  * where mean is the {@link Mean} and <code>n</code> is the number
 29  
  * of sample observations.  
 30  
  * <p>
 31  
  * The definitional formula does not have good numerical properties, so
 32  
  * this implementation uses updating formulas based on West's algorithm
 33  
  * as described in <a href="http://doi.acm.org/10.1145/359146.359152">
 34  
  * Chan, T. F. andJ. G. Lewis 1979, <i>Communications of the ACM</i>,
 35  
  * vol. 22 no. 9, pp. 526-531.</a>.
 36  
  * <p>
 37  
  * The "population variance"  ( sum((x_i - mean)^2) / n ) can also
 38  
  * be computed using this statistic.  The <code>isBiasCorrected</code>
 39  
  * property determines whether the "population" or "sample" value is
 40  
  * returned by the <code>evaluate</code> and <code>getResult</code> methods.
 41  
  * To compute population variances, set this property to <code>false.</code>
 42  
  *
 43  
  * <strong>Note that this implementation is not synchronized.</strong> If 
 44  
  * multiple threads access an instance of this class concurrently, and at least
 45  
  * one of the threads invokes the <code>increment()</code> or 
 46  
  * <code>clear()</code> method, it must be synchronized externally.
 47  
  * 
 48  
  * @version $Revision$ $Date: 2005-02-26 05:11:52 -0800 (Sat, 26 Feb 2005) $
 49  
  */
 50  
 public class Variance extends AbstractStorelessUnivariateStatistic implements Serializable {
 51  
 
 52  
     /** Serializable version identifier */
 53  
     static final long serialVersionUID = -9111962718267217978L;  
 54  
       
 55  
     /** SecondMoment is used in incremental calculation of Variance*/
 56  29736
     protected SecondMoment moment = null;
 57  
 
 58  
     /**
 59  
      * Boolean test to determine if this Variance should also increment
 60  
      * the second moment, this evaluates to false when this Variance is
 61  
      * constructed with an external SecondMoment as a parameter.
 62  
      */
 63  29736
     protected boolean incMoment = true;
 64  
     
 65  
     /**
 66  
      * Determines whether or not bias correction is applied when computing the
 67  
      * value of the statisic.  True means that bias is corrected.  See 
 68  
      * {@link Variance} for details on the formula.
 69  
      */
 70  29736
     private boolean isBiasCorrected = true;
 71  
 
 72  
     /**
 73  
      * Constructs a Variance with default (true) <code>isBiasCorrected</code>
 74  
      * property.
 75  
      */
 76  128
     public Variance() {
 77  128
         moment = new SecondMoment();
 78  128
     }
 79  
 
 80  
     /**
 81  
      * Constructs a Variance based on an external second moment.
 82  
      * 
 83  
      * @param m2 the SecondMoment (Thrid or Fourth moments work
 84  
      * here as well.)
 85  
      */
 86  29600
     public Variance(final SecondMoment m2) {
 87  29600
         incMoment = false;
 88  29600
         this.moment = m2;
 89  29600
     }
 90  
     
 91  
     /**
 92  
      * Constructs a Variance with the specified <code>isBiasCorrected</code>
 93  
      * property
 94  
      * 
 95  
      * @param isBiasCorrected  setting for bias correction - true means
 96  
      * bias will be corrected and is equivalent to using the argumentless
 97  
      * constructor
 98  
      */
 99  4
     public Variance(boolean isBiasCorrected) {
 100  4
         moment = new SecondMoment();
 101  4
         this.isBiasCorrected = isBiasCorrected;
 102  4
     }
 103  
     
 104  
     /**
 105  
      * Constructs a Variance with the specified <code>isBiasCorrected</code>
 106  
      * property and the supplied external second moment.
 107  
      * 
 108  
      * @param isBiasCorrected  setting for bias correction - true means
 109  
      * bias will be corrected
 110  
      * @param m2 the SecondMoment (Thrid or Fourth moments work
 111  
      * here as well.)
 112  
      */
 113  4
     public Variance(boolean isBiasCorrected, SecondMoment m2) {
 114  4
         incMoment = false;
 115  4
         this.moment = m2;
 116  4
         this.isBiasCorrected = isBiasCorrected;      
 117  4
     }
 118  
    
 119  
     /**
 120  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double)
 121  
      */
 122  
     public void increment(final double d) {
 123  748
         if (incMoment) {
 124  748
             moment.increment(d);
 125  
         }
 126  748
     }
 127  
 
 128  
     /**
 129  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getResult()
 130  
      */
 131  
     public double getResult() {
 132  29810
             if (moment.n == 0) {
 133  202
                 return Double.NaN;
 134  29608
             } else if (moment.n == 1) {
 135  76
                 return 0d;
 136  
             } else {
 137  29532
                 if (isBiasCorrected) {
 138  29520
                     return moment.m2 / ((double) moment.n - 1d);
 139  
                 } else {
 140  12
                     return moment.m2 / ((double) moment.n);
 141  
                 }
 142  
             }
 143  
     }
 144  
 
 145  
     /**
 146  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getN()
 147  
      */
 148  
     public long getN() {
 149  116
         return moment.getN();
 150  
     }
 151  
     
 152  
     /**
 153  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#clear()
 154  
      */
 155  
     public void clear() {
 156  286
         if (incMoment) {
 157  286
             moment.clear();
 158  
         }
 159  286
     }
 160  
     
 161  
     /**
 162  
      * Returns the variance of the entries in the input array, or 
 163  
      * <code>Double.NaN</code> if the array is empty.
 164  
      * <p>
 165  
      * See {@link Variance} for details on the computing algorithm.
 166  
      * <p>
 167  
      * Returns 0 for a single-value (i.e. length = 1) sample.
 168  
      * <p>
 169  
      * Throws <code>IllegalArgumentException</code> if the array is null.
 170  
      * <p>
 171  
      * Does not change the internal state of the statistic.
 172  
      * 
 173  
      * @param values the input array
 174  
      * @return the variance of the values or Double.NaN if length = 0
 175  
      * @throws IllegalArgumentException if the array is null
 176  
      */
 177  
     public double evaluate(final double[] values) {
 178  188
         if (values == null) {
 179  0
             throw new IllegalArgumentException("input values array is null");
 180  
         }
 181  188
         return evaluate(values, 0, values.length);
 182  
     }
 183  
 
 184  
     /**
 185  
      * Returns the variance of the entries in the specified portion of
 186  
      * the input array, or <code>Double.NaN</code> if the designated subarray
 187  
      * is empty.
 188  
      * <p>
 189  
      * See {@link Variance} for details on the computing algorithm.
 190  
      * <p>
 191  
      * Returns 0 for a single-value (i.e. length = 1) sample.
 192  
      * <p>
 193  
      * Does not change the internal state of the statistic.
 194  
      * <p>
 195  
      * Throws <code>IllegalArgumentException</code> if the array is null.
 196  
      * 
 197  
      * @param values the input array
 198  
      * @param begin index of the first array element to include
 199  
      * @param length the number of elements to include
 200  
      * @return the variance of the values or Double.NaN if length = 0
 201  
      * @throws IllegalArgumentException if the array is null or the array index
 202  
      *  parameters are not valid
 203  
      */
 204  
     public double evaluate(final double[] values, final int begin, final int length) {
 205  
 
 206  260
         double var = Double.NaN;
 207  
 
 208  260
         if (test(values, begin, length)) {
 209  242
             clear();
 210  242
             if (length == 1) {
 211  16
                 var = 0.0;
 212  226
             } else if (length > 1) {
 213  226
                 Mean mean = new Mean();
 214  226
                 double m = mean.evaluate(values, begin, length);
 215  226
                 var = evaluate(values, m, begin, length);
 216  
             }
 217  
         }
 218  258
         return var;
 219  
     }
 220  
     
 221  
     /**
 222  
      * Returns the variance of the entries in the specified portion of
 223  
      * the input array, using the precomputed mean value.  Returns 
 224  
      * <code>Double.NaN</code> if the designated subarray is empty.
 225  
      * <p>
 226  
      * See {@link Variance} for details on the computing algorithm.
 227  
      * <p>
 228  
      * The formula used assumes that the supplied mean value is the arithmetic
 229  
      * mean of the sample data, not a known population parameter.  This method
 230  
      * is supplied only to save computation when the mean has already been
 231  
      * computed.
 232  
      * <p>
 233  
      * Returns 0 for a single-value (i.e. length = 1) sample.
 234  
      * <p>
 235  
      * Throws <code>IllegalArgumentException</code> if the array is null.
 236  
      * <p>
 237  
      * Does not change the internal state of the statistic.
 238  
      * 
 239  
      * @param values the input array
 240  
      * @param mean the precomputed mean value
 241  
      * @param begin index of the first array element to include
 242  
      * @param length the number of elements to include
 243  
      * @return the variance of the values or Double.NaN if length = 0
 244  
      * @throws IllegalArgumentException if the array is null or the array index
 245  
      *  parameters are not valid
 246  
      */
 247  
     public double evaluate(final double[] values, final double mean, 
 248  
             final int begin, final int length) {
 249  
         
 250  230
         double var = Double.NaN;
 251  
 
 252  230
         if (test(values, begin, length)) {
 253  230
             if (length == 1) {
 254  0
                 var = 0.0;
 255  230
             } else if (length > 1) {
 256  230
                 double accum = 0.0;
 257  230
                 double accum2 = 0.0;
 258  13650
                 for (int i = begin; i < begin + length; i++) {
 259  13420
                     accum += Math.pow((values[i] - mean), 2.0);
 260  13420
                     accum2 += (values[i] - mean);
 261  
                 }
 262  230
                 if (isBiasCorrected) {
 263  222
                     var = (accum - (Math.pow(accum2, 2) / ((double) length))) /
 264  
                     (double) (length - 1);
 265  
                 } else {
 266  8
                     var = (accum - (Math.pow(accum2, 2) / ((double) length))) /
 267  
                     (double) length;
 268  
                 }
 269  
             }
 270  
         }
 271  230
         return var;
 272  
     }
 273  
     
 274  
     /**
 275  
      * Returns the variance of the entries in the input array, using the
 276  
      * precomputed mean value.  Returns <code>Double.NaN</code> if the array
 277  
      * is empty.
 278  
      * <p>
 279  
      * See {@link Variance} for details on the computing algorithm.
 280  
      * <p>
 281  
      * If <code>isBiasCorrected</code> is <code>true</code> the formula used
 282  
      * assumes that the supplied mean value is the arithmetic mean of the
 283  
      * sample data, not a known population parameter.  If the mean is a known
 284  
      * population parameter, or if the "population" version of the variance is
 285  
      * desired, set <code>isBiasCorrected</code> to <code>false</code> before
 286  
      * invoking this method.
 287  
      * <p>
 288  
      * Returns 0 for a single-value (i.e. length = 1) sample.
 289  
      * <p>
 290  
      * Throws <code>IllegalArgumentException</code> if the array is null.
 291  
      * <p>
 292  
      * Does not change the internal state of the statistic.
 293  
      * 
 294  
      * @param values the input array
 295  
      * @param mean the precomputed mean value
 296  
      * @return the variance of the values or Double.NaN if the array is empty
 297  
      * @throws IllegalArgumentException if the array is null
 298  
      */
 299  
     public double evaluate(final double[] values, final double mean) {
 300  2
         return evaluate(values, mean, 0, values.length);
 301  
     }
 302  
 
 303  
     /**
 304  
      * @return Returns the isBiasCorrected.
 305  
      */
 306  
     public boolean isBiasCorrected() {
 307  0
         return isBiasCorrected;
 308  
     }
 309  
 
 310  
     /**
 311  
      * @param isBiasCorrected The isBiasCorrected to set.
 312  
      */
 313  
     public void setBiasCorrected(boolean isBiasCorrected) {
 314  4
         this.isBiasCorrected = isBiasCorrected;
 315  4
     }
 316  
 
 317  
 }