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

Classes in this File Line Coverage Branch Coverage Complexity
Kurtosis
95% 
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 org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
 19  
 
 20  
 /**
 21  
  * Computes the Kurtosis of the available values.
 22  
  * <p>
 23  
  * We use the following (unbiased) formula to define kurtosis:
 24  
  *  <p>
 25  
  *  kurtosis = { [n(n+1) / (n -1)(n - 2)(n-3)] sum[(x_i - mean)^4] / std^4 } - [3(n-1)^2 / (n-2)(n-3)]
 26  
  *  <p>
 27  
  *  where n is the number of values, mean is the {@link Mean} and std is the
 28  
  * {@link StandardDeviation}
 29  
  * <p>
 30  
  *  Note that this statistic is undefined for n < 4.  <code>Double.Nan</code>
 31  
  *  is returned when there is not sufficient data to compute the statistic.
 32  
  * <p>
 33  
  * <strong>Note that this implementation is not synchronized.</strong> If 
 34  
  * multiple threads access an instance of this class concurrently, and at least
 35  
  * one of the threads invokes the <code>increment()</code> or 
 36  
  * <code>clear()</code> method, it must be synchronized externally.
 37  
  * 
 38  
  * @version $Revision$ $Date: 2005-02-26 05:11:52 -0800 (Sat, 26 Feb 2005) $
 39  
  */
 40  
 public class Kurtosis extends AbstractStorelessUnivariateStatistic  {
 41  
 
 42  
     /** Serializable version identifier */
 43  
     static final long serialVersionUID = 2784465764798260919L;  
 44  
       
 45  
     /**Fourth Moment on which this statistic is based */
 46  
     protected FourthMoment moment;
 47  
 
 48  
     /** 
 49  
      * Determines whether or not this statistic can be incremented or cleared.
 50  
      * <p>
 51  
      * Statistics based on (constructed from) external moments cannot
 52  
      * be incremented or cleared.
 53  
     */
 54  
     protected boolean incMoment;
 55  
 
 56  
     /**
 57  
      * Construct a Kurtosis
 58  
      */
 59  32
     public Kurtosis() {
 60  32
         incMoment = true;
 61  32
         moment = new FourthMoment();
 62  32
     }
 63  
 
 64  
     /**
 65  
      * Construct a Kurtosis from an external moment
 66  
      * 
 67  
      * @param m4 external Moment
 68  
      */
 69  2
     public Kurtosis(final FourthMoment m4) {
 70  2
         incMoment = false;
 71  2
         this.moment = m4;
 72  2
     }
 73  
 
 74  
     /**
 75  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double)
 76  
      */
 77  
     public void increment(final double d) {
 78  168
         if (incMoment) {
 79  168
             moment.increment(d);
 80  
         }  else  {
 81  0
             throw new IllegalStateException
 82  
             ("Statistics constructed from external moments cannot be incremented");
 83  
         }
 84  168
     }
 85  
 
 86  
     /**
 87  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getResult()
 88  
      */
 89  
     public double getResult() {
 90  98
         double kurtosis = Double.NaN;
 91  98
         if (moment.getN() > 3) {
 92  20
             double variance = moment.m2 / (double) (moment.n - 1);
 93  20
                 if (moment.n <= 3 || variance < 10E-20) {
 94  2
                     kurtosis = 0.0;
 95  
                 } else {
 96  18
                     double n = (double) moment.n;
 97  18
                     kurtosis =
 98  
                         (n * (n + 1) * moment.m4 -
 99  
                                 3 * moment.m2 * moment.m2 * (n - 1)) /
 100  
                                 ((n - 1) * (n -2) * (n -3) * variance * variance);
 101  
                 }
 102  
         }
 103  98
         return kurtosis;
 104  
     }
 105  
 
 106  
     /**
 107  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#clear()
 108  
      */
 109  
     public void clear() {
 110  22
         if (incMoment) {
 111  22
             moment.clear();
 112  
         } else  {
 113  0
             throw new IllegalStateException
 114  
                 ("Statistics constructed from external moments cannot be cleared");
 115  
         }
 116  22
     }
 117  
 
 118  
     /**
 119  
      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getN()
 120  
      */
 121  
     public long getN() {
 122  70
         return moment.getN();
 123  
     }
 124  
     
 125  
     /* UnvariateStatistic Approach  */
 126  
 
 127  
     /**
 128  
      * Returns the kurtosis of the entries in the specified portion of the
 129  
      * input array.  
 130  
      * <p>
 131  
      * See {@link Kurtosis} for details on the computing algorithm.
 132  
      * <p>
 133  
      * Throws <code>IllegalArgumentException</code> if the array is null.
 134  
      * 
 135  
      * @param values the input array
 136  
      * @param begin index of the first array element to include
 137  
      * @param length the number of elements to include
 138  
      * @return the kurtosis of the values or Double.NaN if length is less than
 139  
      * 4
 140  
      * @throws IllegalArgumentException if the input array is null or the array
 141  
      * index parameters are not valid
 142  
      */
 143  
     public double evaluate(final double[] values,final int begin, final int length) {
 144  
         // Initialize the kurtosis  
 145  30
         double kurt = Double.NaN;   
 146  
         
 147  30
         if (test(values, begin, length) && length > 3) {       
 148  
             
 149  
             // Compute the mean and standard deviation
 150  18
             Variance variance = new Variance();
 151  18
             variance.incrementAll(values, begin, length);
 152  18
             double mean = variance.moment.m1;
 153  18
             double stdDev = Math.sqrt(variance.getResult());
 154  
             
 155  
             // Sum the ^4 of the distance from the mean divided by the
 156  
             // standard deviation
 157  18
             double accum3 = 0.0;
 158  378
             for (int i = begin; i < begin + length; i++) {
 159  360
                 accum3 += Math.pow((values[i] - mean), 4.0);
 160  
             }
 161  18
             accum3 /= Math.pow(stdDev, 4.0d);
 162  
             
 163  
             // Get N
 164  18
             double n0 = length;
 165  
             
 166  18
             double coefficientOne =
 167  
                 (n0 * (n0 + 1)) / ((n0 - 1) * (n0 - 2) * (n0 - 3));
 168  18
             double termTwo =
 169  
                 ((3 * Math.pow(n0 - 1, 2.0)) / ((n0 - 2) * (n0 - 3)));
 170  
             
 171  
             // Calculate kurtosis
 172  18
             kurt = (coefficientOne * accum3) - termTwo;
 173  
         }       
 174  30
         return kurt;
 175  
     }
 176  
 
 177  
 }