Coverage Report - org.apache.commons.math.distribution.NormalDistributionImpl

Classes in this File Line Coverage Branch Coverage Complexity
NormalDistributionImpl
92% 
100% 
1.909

 1  
 /*
 2  
  * Copyright 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  
 
 17  
 package org.apache.commons.math.distribution;
 18  
 
 19  
 import java.io.Serializable;
 20  
 
 21  
 import org.apache.commons.math.MathException;
 22  
 import org.apache.commons.math.special.Erf;
 23  
 
 24  
 /**
 25  
  * Default implementation of
 26  
  * {@link org.apache.commons.math.distribution.NormalDistribution}.
 27  
  *
 28  
  * @version $Revision$ $Date: 2005-06-26 15:20:57 -0700 (Sun, 26 Jun 2005) $
 29  
  */
 30  
 public class NormalDistributionImpl extends AbstractContinuousDistribution 
 31  
         implements NormalDistribution, Serializable {
 32  
     
 33  
     /** Serializable version identifier */
 34  
     static final long serialVersionUID = 8589540077390120676L;
 35  
 
 36  
     /** The mean of this distribution. */
 37  32
     private double mean = 0;
 38  
     
 39  
     /** The standard deviation of this distribution. */
 40  32
     private double standardDeviation = 1;
 41  
     
 42  
     /**
 43  
      * Create a normal distribution using the given mean and standard deviation.
 44  
      * @param mean mean for this distribution
 45  
      * @param sd standard deviation for this distribution
 46  
      */
 47  
     public NormalDistributionImpl(double mean, double sd){
 48  32
         super();
 49  32
         setMean(mean);
 50  32
         setStandardDeviation(sd);
 51  32
     }
 52  
     
 53  
     /**
 54  
      * Creates normal distribution with the mean equal to zero and standard
 55  
      * deviation equal to one. 
 56  
      */
 57  
     public NormalDistributionImpl(){
 58  0
         this(0.0, 1.0);
 59  0
     }
 60  
     
 61  
     /**
 62  
      * Access the mean.
 63  
      * @return mean for this distribution
 64  
      */ 
 65  
     public double getMean() {
 66  52
         return mean;
 67  
     }
 68  
     
 69  
     /**
 70  
      * Modify the mean.
 71  
      * @param mean for this distribution
 72  
      */
 73  
     public void setMean(double mean) {
 74  34
         this.mean = mean;
 75  34
     }
 76  
 
 77  
     /**
 78  
      * Access the standard deviation.
 79  
      * @return standard deviation for this distribution
 80  
      */
 81  
     public double getStandardDeviation() {
 82  34
         return standardDeviation;
 83  
     }
 84  
 
 85  
     /**
 86  
      * Modify the standard deviation.
 87  
      * @param sd standard deviation for this distribution
 88  
      * @throws IllegalArgumentException if <code>sd</code> is not positive.
 89  
      */
 90  
     public void setStandardDeviation(double sd) {
 91  36
         if (sd <= 0.0) {
 92  2
             throw new IllegalArgumentException(
 93  
                 "Standard deviation must be positive.");
 94  
         }       
 95  34
         standardDeviation = sd;
 96  34
     }
 97  
 
 98  
     /**
 99  
      * For this disbution, X, this method returns P(X &lt; <code>x</code>).
 100  
      * @param x the value at which the CDF is evaluated.
 101  
      * @return CDF evaluted at <code>x</code>. 
 102  
      * @throws MathException if the algorithm fails to converge.
 103  
      */
 104  
     public double cumulativeProbability(double x) throws MathException {
 105  452
         return 0.5 * (1.0 + Erf.erf((x - mean) /
 106  
                 (standardDeviation * Math.sqrt(2.0))));
 107  
     }
 108  
     
 109  
     /**
 110  
      * For this distribution, X, this method returns the critical point x, such
 111  
      * that P(X &lt; x) = <code>p</code>.
 112  
      * <p>
 113  
      * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and 
 114  
      * <code>Double.POSITIVE_INFINITY</code> for p=1.
 115  
      *
 116  
      * @param p the desired probability
 117  
      * @return x, such that P(X &lt; x) = <code>p</code>
 118  
      * @throws MathException if the inverse cumulative probability can not be
 119  
      *         computed due to convergence or other numerical errors.
 120  
      * @throws IllegalArgumentException if <code>p</code> is not a valid
 121  
      *         probability.
 122  
      */
 123  
     public double inverseCumulativeProbability(final double p) 
 124  
     throws MathException {
 125  28
         if (p == 0) {
 126  2
             return Double.NEGATIVE_INFINITY;
 127  
         }
 128  26
         if (p == 1) {
 129  2
             return Double.POSITIVE_INFINITY;
 130  
         }
 131  24
         return super.inverseCumulativeProbability(p);
 132  
     }
 133  
     
 134  
     /**
 135  
      * Access the domain value lower bound, based on <code>p</code>, used to
 136  
      * bracket a CDF root.  This method is used by
 137  
      * {@link #inverseCumulativeProbability(double)} to find critical values.
 138  
      * 
 139  
      * @param p the desired probability for the critical value
 140  
      * @return domain value lower bound, i.e.
 141  
      *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code> 
 142  
      */
 143  
     protected double getDomainLowerBound(double p) {
 144  
         double ret;
 145  
 
 146  20
         if (p < .5) {
 147  10
             ret = -Double.MAX_VALUE;
 148  
         } else {
 149  10
             ret = getMean();
 150  
         }
 151  
         
 152  20
         return ret;
 153  
     }
 154  
 
 155  
     /**
 156  
      * Access the domain value upper bound, based on <code>p</code>, used to
 157  
      * bracket a CDF root.  This method is used by
 158  
      * {@link #inverseCumulativeProbability(double)} to find critical values.
 159  
      * 
 160  
      * @param p the desired probability for the critical value
 161  
      * @return domain value upper bound, i.e.
 162  
      *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code> 
 163  
      */
 164  
     protected double getDomainUpperBound(double p) {
 165  
         double ret;
 166  
 
 167  20
         if (p < .5) {
 168  10
             ret = getMean();
 169  
         } else {
 170  10
             ret = Double.MAX_VALUE;
 171  
         }
 172  
         
 173  20
         return ret;
 174  
     }
 175  
 
 176  
     /**
 177  
      * Access the initial domain value, based on <code>p</code>, used to
 178  
      * bracket a CDF root.  This method is used by
 179  
      * {@link #inverseCumulativeProbability(double)} to find critical values.
 180  
      * 
 181  
      * @param p the desired probability for the critical value
 182  
      * @return initial domain value
 183  
      */
 184  
     protected double getInitialDomain(double p) {
 185  
         double ret;
 186  
 
 187  20
         if (p < .5) {
 188  10
             ret = getMean() - getStandardDeviation();
 189  10
         } else if (p > .5) {
 190  10
             ret = getMean() + getStandardDeviation();
 191  
         } else {
 192  0
             ret = getMean();
 193  
         }
 194  
         
 195  20
         return ret;
 196  
     }
 197  
 }