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

Classes in this File Line Coverage Branch Coverage Complexity
AbstractIntegerDistribution
79% 
88% 
2.375

 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  
 
 22  
 
 23  
 /**
 24  
  * Base class for integer-valued discrete distributions.  Default
 25  
  * implementations are provided for some of the methods that do not vary
 26  
  * from distribution to distribution.
 27  
  *  
 28  
  * @version $Revision$ $Date: 2005-06-26 15:20:57 -0700 (Sun, 26 Jun 2005) $
 29  
  */
 30  
 public abstract class AbstractIntegerDistribution extends AbstractDistribution
 31  
     implements IntegerDistribution, Serializable {
 32  
         
 33  
     /** Serializable version identifier */
 34  
     static final long serialVersionUID = -1146319659338487221L;
 35  
     
 36  
     /**
 37  
      * Default constructor.
 38  
      */
 39  
     protected AbstractIntegerDistribution() {
 40  104
         super();
 41  104
     }
 42  
     
 43  
     /**
 44  
      * For a random variable X whose values are distributed according
 45  
      * to this distribution, this method returns P(X ≤ x).  In other words,
 46  
      * this method represents the  (cumulative) distribution function, or
 47  
      * CDF, for this distribution.
 48  
      * <p>
 49  
      * If <code>x</code> does not represent an integer value, the CDF is 
 50  
      * evaluated at the greatest integer less than x.
 51  
      * 
 52  
      * @param x the value at which the distribution function is evaluated.
 53  
      * @return cumulative probability that a random variable with this
 54  
      * distribution takes a value less than or equal to <code>x</code>
 55  
      * @throws MathException if the cumulative probability can not be
 56  
      * computed due to convergence or other numerical errors.
 57  
      */
 58  
     public double cumulativeProbability(double x) throws MathException {
 59  176
         return cumulativeProbability((int) Math.floor(x));  
 60  
     }
 61  
     
 62  
     /**
 63  
      * For a random variable X whose values are distributed according
 64  
      * to this distribution, this method returns P(X &le; x).  In other words,
 65  
      * this method represents the probability distribution function, or PDF,
 66  
      * for this distribution.
 67  
      * 
 68  
      * @param x the value at which the PDF is evaluated.
 69  
      * @return PDF for this distribution. 
 70  
      * @throws MathException if the cumulative probability can not be
 71  
      *            computed due to convergence or other numerical errors.
 72  
      */
 73  
     abstract public double cumulativeProbability(int x) throws MathException;
 74  
     
 75  
     /**
 76  
      * For a random variable X whose values are distributed according
 77  
      * to this distribution, this method returns P(X = x). In other words, this
 78  
      * method represents the probability mass function,  or PMF, for the distribution.
 79  
      * <p>
 80  
      * If <code>x</code> does not represent an integer value, 0 is returned.
 81  
      * 
 82  
      * @param x the value at which the probability density function is evaluated
 83  
      * @return the value of the probability density function at x
 84  
      */
 85  
     public double probability(double x) {
 86  0
         double fl = Math.floor(x);
 87  0
         if (fl == x) {
 88  0
             return this.probability((int) x);
 89  
         } else {
 90  0
             return 0;
 91  
         }
 92  
     }
 93  
     
 94  
     /**
 95  
     * For a random variable X whose values are distributed according
 96  
      * to this distribution, this method returns P(x0 &le; X &le; x1).
 97  
      * 
 98  
      * @param x0 the inclusive, lower bound
 99  
      * @param x1 the inclusive, upper bound
 100  
      * @return the cumulative probability. 
 101  
      * @throws MathException if the cumulative probability can not be
 102  
      *            computed due to convergence or other numerical errors.
 103  
      * @throws IllegalArgumentException if x0 > x1
 104  
      */
 105  
     public double cumulativeProbability(int x0, int x1) throws MathException {
 106  6
         if (x0 > x1) {
 107  6
             throw new IllegalArgumentException
 108  
                 ("lower endpoint must be less than or equal to upper endpoint");
 109  
         }
 110  0
         return cumulativeProbability(x1) - cumulativeProbability(x0 - 1);
 111  
     }
 112  
     
 113  
     /**
 114  
      * For a random variable X whose values are distributed according
 115  
      * to this distribution, this method returns the largest x, such
 116  
      * that P(X &le; x) &le; <code>p</code>.
 117  
      *
 118  
      * @param p the desired probability
 119  
      * @return the largest x such that P(X &le; x) <= p
 120  
      * @throws MathException if the inverse cumulative probability can not be
 121  
      *            computed due to convergence or other numerical errors.
 122  
      * @throws IllegalArgumentException if p < 0 or p > 1
 123  
      */
 124  
     public int inverseCumulativeProbability(final double p) throws MathException{
 125  258
         if (p < 0.0 || p > 1.0) {
 126  12
             throw new IllegalArgumentException(
 127  
                 "p must be between 0 and 1.0 (inclusive)");
 128  
         }
 129  
         
 130  
         // by default, do simple bisection.
 131  
         // subclasses can override if there is a better method.
 132  246
         int x0 = getDomainLowerBound(p);
 133  246
         int x1 = getDomainUpperBound(p);
 134  
         double pm;
 135  6256
         while (x0 < x1) {
 136  6010
             int xm = x0 + (x1 - x0) / 2;
 137  6010
             pm = cumulativeProbability(xm);
 138  6010
             if (pm > p) {
 139  
                 // update x1
 140  4734
                 if (xm == x1) {
 141  
                     // this can happen with integer division
 142  
                     // simply decrement x1
 143  0
                     --x1;
 144  
                 } else {
 145  
                     // update x1 normally
 146  4734
                     x1 = xm;
 147  
                 }
 148  
             } else {
 149  
                 // update x0
 150  1276
                 if (xm == x0) {
 151  
                     // this can happen with integer division
 152  
                     // simply increment x0
 153  220
                     ++x0;
 154  
                 } else {
 155  
                     // update x0 normally
 156  1056
                     x0 = xm;
 157  
                 }
 158  
             }
 159  
         }
 160  
         
 161  
         // insure x0 is the correct critical point
 162  246
         pm = cumulativeProbability(x0);
 163  488
         while (pm > p) {
 164  242
             --x0;
 165  242
             pm = cumulativeProbability(x0);
 166  
         }
 167  
     
 168  246
         return x0;        
 169  
     }
 170  
     
 171  
     /**
 172  
      * Access the domain value lower bound, based on <code>p</code>, used to
 173  
      * bracket a PDF root.  This method is used by
 174  
      * {@link #inverseCumulativeProbability(double)} to find critical values.
 175  
      * 
 176  
      * @param p the desired probability for the critical value
 177  
      * @return domain value lower bound, i.e.
 178  
      *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code> 
 179  
      */
 180  
     protected abstract int getDomainLowerBound(double p);
 181  
     
 182  
     /**
 183  
      * Access the domain value upper bound, based on <code>p</code>, used to
 184  
      * bracket a PDF root.  This method is used by
 185  
      * {@link #inverseCumulativeProbability(double)} to find critical values.
 186  
      * 
 187  
      * @param p the desired probability for the critical value
 188  
      * @return domain value upper bound, i.e.
 189  
      *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code> 
 190  
      */
 191  
     protected abstract int getDomainUpperBound(double p);
 192  
 }