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

Classes in this File Line Coverage Branch Coverage Complexity
Skewness
100% 
100% 
2.143

 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 skewness of the available values.
 24  
  * <p>
 25  
  * We use the following (unbiased) formula to define skewness:
 26  
  * <p>
 27  
  * skewness = [n / (n -1) (n - 2)] sum[(x_i - mean)^3] / std^3
 28  
  * <p>
 29  
  * where n is the number of values, mean is the {@link Mean} and std is the 
 30  
  * {@link StandardDeviation}
 31  
  * <p>
 32  
  * <strong>Note that this implementation is not synchronized.</strong> If 
 33  
  * multiple threads access an instance of this class concurrently, and at least
 34  
  * one of the threads invokes the <code>increment()</code> or 
 35  
  * <code>clear()</code> method, it must be synchronized externally.
 36  
  * 
 37  
  * @version $Revision$ $Date: 2005-02-26 05:11:52 -0800 (Sat, 26 Feb 2005) $
 38  
  */
 39  
 public class Skewness extends AbstractStorelessUnivariateStatistic implements Serializable {
 40  
 
 41  
     /** Serializable version identifier */
 42  
     static final long serialVersionUID = 7101857578996691352L;    
 43  
     
 44  
     /** Third moment on which this statistic is based */
 45  34
     protected ThirdMoment moment = null;
 46  
 
 47  
      /** 
 48  
      * Determines whether or not this statistic can be incremented or cleared.
 49  
      * <p>
 50  
      * Statistics based on (constructed from) external moments cannot
 51  
      * be incremented or cleared.
 52  
     */
 53  
     protected boolean incMoment;
 54  
 
 55  
     /**
 56  
      * Constructs a Skewness
 57  
      */
 58  32
     public Skewness() {
 59  32
         incMoment = true;
 60  32
         moment = new ThirdMoment();
 61  32
     }
 62  
 
 63  
     /**
 64  
      * Constructs a Skewness with an external moment
 65  
      * @param m3 external moment
 66  
      */
 67  2
     public Skewness(final ThirdMoment m3) {
 68  2
         incMoment = false;
 69  2
         this.moment = m3;
 70  2
     }
 71  
 
 72  
     /**
 73  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double)
 74  
      */
 75  
     public void increment(final double d) {
 76  166
         if (incMoment) {
 77  166
             moment.increment(d);
 78  
         }
 79  166
     }
 80  
 
 81  
     /**
 82  
      * Returns the value of the statistic based on the values that have been added.
 83  
      * <p>
 84  
      * See {@link Skewness} for the definition used in the computation.
 85  
      * 
 86  
      * @return the skewness of the available values.
 87  
      */
 88  
     public double getResult() {
 89  
         
 90  96
         if (moment.n < 3) {
 91  74
             return Double.NaN;
 92  
         }
 93  22
         double variance = moment.m2 / (double) (moment.n - 1);
 94  22
         double skewness = Double.NaN;
 95  22
         if (variance < 10E-20) {
 96  2
             skewness = 0.0;
 97  
         } else {
 98  20
             double n0 = (double) moment.getN();
 99  20
             skewness = (n0 * moment.m3) /
 100  
             ((n0 - 1) * (n0 -2) * Math.sqrt(variance) * variance);
 101  
         }
 102  22
         return skewness;
 103  
     }
 104  
 
 105  
     /**
 106  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getN()
 107  
      */
 108  
     public long getN() {
 109  70
         return moment.getN();
 110  
     }
 111  
     
 112  
     /**
 113  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#clear()
 114  
      */
 115  
     public void clear() {
 116  22
         if (incMoment) {
 117  22
             moment.clear();
 118  
         }
 119  22
     }
 120  
 
 121  
     /**
 122  
      * Returns the Skewness of the entries in the specifed portion of the
 123  
      * input array.
 124  
      * <p>
 125  
      * See {@link Skewness} for the definition used in the computation.
 126  
      * <p>
 127  
      * Throws <code>IllegalArgumentException</code> if the array is null.
 128  
      * 
 129  
      * @param values the input array
 130  
      * @param begin the index of the first array element to include
 131  
      * @param length the number of elements to include
 132  
      * @return the skewness of the values or Double.NaN if length is less than
 133  
      * 3
 134  
      * @throws IllegalArgumentException if the array is null or the array index
 135  
      *  parameters are not valid
 136  
      */
 137  
     public double evaluate(final double[] values,final int begin, 
 138  
             final int length) {
 139  
 
 140  
         // Initialize the skewness
 141  30
         double skew = Double.NaN;
 142  
 
 143  30
         if (test(values, begin, length) && length > 2 ){
 144  20
             Mean mean = new Mean();
 145  
             // Get the mean and the standard deviation
 146  20
             double m = mean.evaluate(values, begin, length);
 147  
             
 148  
             // Calc the std, this is implemented here instead
 149  
             // of using the standardDeviation method eliminate
 150  
             // a duplicate pass to get the mean
 151  20
             double accum = 0.0;
 152  20
             double accum2 = 0.0;
 153  386
             for (int i = begin; i < begin + length; i++) {
 154  366
                 accum += Math.pow((values[i] - m), 2.0);
 155  366
                 accum2 += (values[i] - m);
 156  
             }
 157  20
             double stdDev = Math.sqrt((accum - (Math.pow(accum2, 2) / ((double) length))) /
 158  
                     (double) (length - 1));
 159  
             
 160  20
             double accum3 = 0.0;
 161  386
             for (int i = begin; i < begin + length; i++) {
 162  366
                 accum3 += Math.pow(values[i] - m, 3.0d);
 163  
             }
 164  20
             accum3 /= Math.pow(stdDev, 3.0d);
 165  
             
 166  
             // Get N
 167  20
             double n0 = length;
 168  
             
 169  
             // Calculate skewness
 170  20
             skew = (n0 / ((n0 - 1) * (n0 - 2))) * accum3;
 171  
         }
 172  30
         return skew;
 173  
     }
 174  
 }