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

Classes in this File Line Coverage Branch Coverage Complexity
BinomialDistributionImpl
100% 
100% 
2.1

 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.distribution;
 17  
 
 18  
 import java.io.Serializable;
 19  
 
 20  
 import org.apache.commons.math.MathException;
 21  
 import org.apache.commons.math.special.Beta;
 22  
 import org.apache.commons.math.util.MathUtils;
 23  
 
 24  
 /**
 25  
  * The default implementation of {@link BinomialDistribution}.
 26  
  *
 27  
  * @version $Revision$ $Date: 2005-06-26 15:20:57 -0700 (Sun, 26 Jun 2005) $
 28  
  */
 29  
 public class BinomialDistributionImpl
 30  
     extends AbstractIntegerDistribution
 31  
     implements BinomialDistribution, Serializable {
 32  
 
 33  
     /** Serializable version identifier */
 34  
     static final long serialVersionUID = 6751309484392813623L;
 35  
 
 36  
     /** The number of trials. */
 37  
     private int numberOfTrials;
 38  
 
 39  
     /** The probability of success. */
 40  
     private double probabilityOfSuccess;
 41  
 
 42  
     /**
 43  
      * Create a binomial distribution with the given number of trials and
 44  
      * probability of success.
 45  
      * @param trials the number of trials.
 46  
      * @param p the probability of success.
 47  
      */
 48  
     public BinomialDistributionImpl(int trials, double p) {
 49  30
         super();
 50  30
         setNumberOfTrials(trials);
 51  28
         setProbabilityOfSuccess(p);
 52  24
     }
 53  
 
 54  
     /**
 55  
      * Access the number of trials for this distribution.
 56  
      * @return the number of trials.
 57  
      */
 58  
     public int getNumberOfTrials() {
 59  540
         return numberOfTrials;
 60  
     }
 61  
 
 62  
     /**
 63  
      * Access the probability of success for this distribution.
 64  
      * @return the probability of success.
 65  
      */
 66  
     public double getProbabilityOfSuccess() {
 67  258
         return probabilityOfSuccess;
 68  
     }
 69  
 
 70  
     /**
 71  
      * Change the number of trials for this distribution.
 72  
      * @param trials the new number of trials.
 73  
      * @throws IllegalArgumentException if <code>trials</code> is not a valid
 74  
      *         number of trials.
 75  
      */
 76  
     public void setNumberOfTrials(int trials) {
 77  30
         if (trials < 0) {
 78  2
             throw new IllegalArgumentException("number of trials must be non-negative.");
 79  
         }
 80  28
         numberOfTrials = trials;
 81  28
     }
 82  
 
 83  
     /**
 84  
      * Change the probability of success for this distribution.
 85  
      * @param p the new probability of success.
 86  
      * @throws IllegalArgumentException if <code>p</code> is not a valid
 87  
      *         probability.
 88  
      */
 89  
     public void setProbabilityOfSuccess(double p) {
 90  28
         if (p < 0.0 || p > 1.0) {
 91  4
             throw new IllegalArgumentException("probability of success must be between 0.0 and 1.0, inclusive.");
 92  
         }
 93  24
         probabilityOfSuccess = p;
 94  24
     }
 95  
 
 96  
     /**
 97  
      * Access the domain value lower bound, based on <code>p</code>, used to
 98  
      * bracket a PDF root.
 99  
      * 
 100  
      * @param p the desired probability for the critical value
 101  
      * @return domain value lower bound, i.e.
 102  
      *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code> 
 103  
      */
 104  
     protected int getDomainLowerBound(double p) {
 105  28
         return -1;
 106  
     }
 107  
 
 108  
     /**
 109  
      * Access the domain value upper bound, based on <code>p</code>, used to
 110  
      * bracket a PDF root.
 111  
      * 
 112  
      * @param p the desired probability for the critical value
 113  
      * @return domain value upper bound, i.e.
 114  
      *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code> 
 115  
      */
 116  
     protected int getDomainUpperBound(double p) {
 117  28
         return getNumberOfTrials();
 118  
     }
 119  
 
 120  
     /**
 121  
      * For this distribution, X, this method returns P(X &le; x).
 122  
      * @param x the value at which the PDF is evaluated.
 123  
      * @return PDF for this distribution. 
 124  
      * @throws MathException if the cumulative probability can not be
 125  
      *            computed due to convergence or other numerical errors.
 126  
      */
 127  
     public double cumulativeProbability(int x) throws MathException {
 128  
         double ret;
 129  226
         if (x < 0) {
 130  14
             ret = 0.0;
 131  212
         } else if (x >= getNumberOfTrials()) {
 132  22
             ret = 1.0;
 133  
         } else {
 134  190
             ret =
 135  
                 1.0 - Beta.regularizedBeta(
 136  
                         getProbabilityOfSuccess(),
 137  
                         x + 1.0,
 138  
                         getNumberOfTrials() - x);
 139  
         }
 140  226
         return ret;
 141  
     }
 142  
 
 143  
     /**
 144  
      * For this disbution, X, this method returns P(X = x).
 145  
      * 
 146  
      * @param x the value at which the PMF is evaluated.
 147  
      * @return PMF for this distribution. 
 148  
      */
 149  
     public double probability(int x) {
 150  
         double ret;
 151  48
         if (x < 0 || x > getNumberOfTrials()) {
 152  14
             ret = 0.0;
 153  
         } else {
 154  34
             ret = MathUtils.binomialCoefficientDouble(
 155  
                     getNumberOfTrials(), x) *
 156  
                   Math.pow(getProbabilityOfSuccess(), x) *
 157  
                   Math.pow(1.0 - getProbabilityOfSuccess(),
 158  
                         getNumberOfTrials() - x);
 159  
         }
 160  48
         return ret;
 161  
     }
 162  
     
 163  
     /**
 164  
      * For this distribution, X, this method returns the largest x, such
 165  
      * that P(X &le; x) &le; <code>p</code>.
 166  
      * <p>
 167  
      * Returns <code>-1</code> for p=0 and <code>Integer.MAX_VALUE</code> for
 168  
      * p=1.
 169  
      *
 170  
      * @param p the desired probability
 171  
      * @return the largest x such that P(X &le; x) <= p
 172  
      * @throws MathException if the inverse cumulative probability can not be
 173  
      *            computed due to convergence or other numerical errors.
 174  
      * @throws IllegalArgumentException if p < 0 or p > 1
 175  
      */
 176  
     public int inverseCumulativeProbability(final double p) throws MathException {
 177  
         // handle extreme values explicitly
 178  36
         if (p == 0) {
 179  2
             return -1;
 180  
         } 
 181  34
         if (p == 1) {
 182  2
             return Integer.MAX_VALUE; 
 183  
         }
 184  
         
 185  
         // use default bisection impl
 186  32
         return super.inverseCumulativeProbability(p);
 187  
     }
 188  
 }