1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 * The default implementation of {@link ExponentialDistribution}.
24 *
25 * @version $Revision: 355770 $ $Date: 2005-12-10 12:48:57 -0700 (Sat, 10 Dec 2005) $
26 */
27 public class ExponentialDistributionImpl extends AbstractContinuousDistribution
28 implements ExponentialDistribution, Serializable {
29
30 /** Serializable version identifier */
31 private static final long serialVersionUID = 2401296428283614780L;
32
33 /** The mean of this distribution. */
34 private double mean;
35
36 /**
37 * Create a exponential distribution with the given mean.
38 * @param mean mean of this distribution.
39 */
40 public ExponentialDistributionImpl(double mean) {
41 super();
42 setMean(mean);
43 }
44
45 /**
46 * Modify the mean.
47 * @param mean the new mean.
48 * @throws IllegalArgumentException if <code>mean</code> is not positive.
49 */
50 public void setMean(double mean) {
51 if (mean <= 0.0) {
52 throw new IllegalArgumentException("mean must be positive.");
53 }
54 this.mean = mean;
55 }
56
57 /**
58 * Access the mean.
59 * @return the mean.
60 */
61 public double getMean() {
62 return mean;
63 }
64
65 /**
66 * For this disbution, X, this method returns P(X < x).
67 *
68 * The implementation of this method is based on:
69 * <ul>
70 * <li>
71 * <a href="http://mathworld.wolfram.com/ExponentialDistribution.html">
72 * Exponential Distribution</a>, equation (1).</li>
73 * </ul>
74 *
75 * @param x the value at which the CDF is evaluated.
76 * @return CDF for this distribution.
77 * @throws MathException if the cumulative probability can not be
78 * computed due to convergence or other numerical errors.
79 */
80 public double cumulativeProbability(double x) throws MathException{
81 double ret;
82 if (x <= 0.0) {
83 ret = 0.0;
84 } else {
85 ret = 1.0 - Math.exp(-x / getMean());
86 }
87 return ret;
88 }
89
90 /**
91 * For this distribution, X, this method returns the critical point x, such
92 * that P(X < x) = <code>p</code>.
93 * <p>
94 * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.
95 *
96 * @param p the desired probability
97 * @return x, such that P(X < x) = <code>p</code>
98 * @throws MathException if the inverse cumulative probability can not be
99 * computed due to convergence or other numerical errors.
100 * @throws IllegalArgumentException if p < 0 or p > 1.
101 */
102 public double inverseCumulativeProbability(double p) throws MathException {
103 double ret;
104
105 if (p < 0.0 || p > 1.0) {
106 throw new IllegalArgumentException
107 ("probability argument must be between 0 and 1 (inclusive)");
108 } else if (p == 1.0) {
109 ret = Double.POSITIVE_INFINITY;
110 } else {
111 ret = -getMean() * Math.log(1.0 - p);
112 }
113
114 return ret;
115 }
116
117 /**
118 * Access the domain value lower bound, based on <code>p</code>, used to
119 * bracket a CDF root.
120 *
121 * @param p the desired probability for the critical value
122 * @return domain value lower bound, i.e.
123 * P(X < <i>lower bound</i>) < <code>p</code>
124 */
125 protected double getDomainLowerBound(double p) {
126 return 0;
127 }
128
129 /**
130 * Access the domain value upper bound, based on <code>p</code>, used to
131 * bracket a CDF root.
132 *
133 * @param p the desired probability for the critical value
134 * @return domain value upper bound, i.e.
135 * P(X < <i>upper bound</i>) > <code>p</code>
136 */
137 protected double getDomainUpperBound(double p) {
138
139
140
141 if (p < .5) {
142
143 return getMean();
144 } else {
145
146 return Double.MAX_VALUE;
147 }
148 }
149
150 /**
151 * Access the initial domain value, based on <code>p</code>, used to
152 * bracket a CDF root.
153 *
154 * @param p the desired probability for the critical value
155 * @return initial domain value
156 */
157 protected double getInitialDomain(double p) {
158
159
160 if (p < .5) {
161
162 return getMean() * .5;
163 } else {
164
165 return getMean();
166 }
167 }
168 }