1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.jstats.distributions;
11
12 import cern.jet.stat.Gamma;
13 import nl.tudelft.simulation.jstats.streams.StreamInterface;
14
15 /***
16 * The Gamma distribution. For more information on this distribution see <a
17 * href="http://mathworld.wolfram.com/GammaDistribution.html">
18 * http://mathworld.wolfram.com/GammaDistribution.html </a>
19 * <p>
20 * (c) copyright 2002-2004 <a href="http://www.simulation.tudelft.nl">Delft
21 * University of Technology </a>, the Netherlands. <br>
22 * See for project information <a href="http://www.simulation.tudelft.nl">
23 * www.simulation.tudelft.nl </a> <br>
24 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
25 * License (GPL) </a>, no warranty <br>
26 *
27 * @author <a href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">
28 * Alexander Verbraeck </a> <br>
29 * <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm"> Peter
30 * Jacobs </a>
31 * @version 1.11 2004-03-22
32 * @since 1.2
33 */
34 public class DistGamma extends DistContinuous
35 {
36 /*** alpha is the alpha parameter of the distribution */
37 private double alpha;
38
39 /*** beta is the beta parameter of the distribution */
40 private double beta;
41
42 /***
43 * constructs a new gamma distribution. The gamma distribution represents
44 * the time to complete some task, e.g. customer service or machine repair
45 *
46 * @param stream the numberstream
47 * @param alpha is the shape parameter alpha>0
48 * @param beta is the scale parameter beta>0
49 */
50 public DistGamma(final StreamInterface stream, final double alpha,
51 final double beta)
52 {
53 super(stream);
54 if ((alpha > 0.0) && (beta > 0.0))
55 {
56 this.alpha = alpha;
57 this.beta = beta;
58 } else
59 {
60 throw new IllegalArgumentException(
61 "Error Gamma - alpha <= 0.0 or beta <= 0.0");
62 }
63 }
64
65 /***
66 * @see DistContinuous#draw()
67 */
68 public double draw()
69 {
70
71
72 if (this.alpha < 1.0)
73 {
74 double b = (Math.E + this.alpha) / Math.E;
75 long counter = 0;
76 while (counter < 1000)
77 {
78
79 double p = b * this.stream.nextDouble();
80 if (p <= 1.0d)
81 {
82
83 double y = Math.pow(p, 1.0d / this.alpha);
84 double u2 = this.stream.nextDouble();
85 if (u2 <= Math.exp(-y))
86 {
87 return this.beta * y;
88 }
89 } else
90 {
91
92 double y = -Math.log((b - p) / this.alpha);
93 double u2 = this.stream.nextDouble();
94 if (u2 <= Math.pow(y, this.alpha - 1.0d))
95 {
96 return this.beta * y;
97 }
98 }
99 }
100 new IllegalArgumentException("1000 tries for alpha<1.0");
101 return 1.0d;
102 } else if (this.alpha > 1.0)
103 {
104
105
106 double a = 1.0d / Math.sqrt(2.0d * this.alpha - 1.0d);
107 double b = this.alpha - Math.log(4.0d);
108 double q = this.alpha + (1.0d / a);
109 double theta = 4.5d;
110 double d = 1.0d + Math.log(theta);
111 long counter = 0;
112 while (counter < 1000)
113 {
114
115 double u1 = this.stream.nextDouble();
116 double u2 = this.stream.nextDouble();
117
118 double v = a * Math.log(u1 / (1.0d - u1));
119 double y = this.alpha * Math.exp(v);
120 double z = u1 * u1 * u2;
121 double w = b + q * v - y;
122
123 if ((w + d - theta * z) >= 0.0d)
124 {
125 return this.beta * y;
126 }
127
128 if (w > Math.log(z))
129 {
130 return this.beta * y;
131 }
132 }
133 new IllegalArgumentException("1000 tries for alpha>1.0");
134 return 1.0d;
135 } else
136
137 {
138
139 return -this.beta * Math.log(this.stream.nextDouble());
140 }
141 }
142
143 /***
144 * @see nl.tudelft.simulation.jstats.distributions.DistContinuous
145 * #probDensity(double)
146 */
147 public double probDensity(final double observation)
148 {
149 if (observation <= 0)
150 {
151 return 0.0;
152 }
153 return (Math.pow(this.beta, -this.alpha)
154 * Math.pow(observation, this.alpha - 1) * Math.exp(-1
155 * observation / this.beta))
156 / Gamma.gamma(this.alpha);
157 }
158
159 /***
160 * @see java.lang.Object#toString()
161 */
162 public String toString()
163 {
164 return "Gamma(" + this.alpha + "," + this.beta + ")";
165 }
166 }