SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
ContinuousDistribution.java
1/*
2 * Class: ContinuousDistribution
3 * Description: continuous distributions
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.probdist;
26
27import umontreal.ssj.util.PrintfFormat;
28import umontreal.ssj.util.Num;
29
43public abstract class ContinuousDistribution implements Distribution {
44 // @Deprecated
45 public int decPrec = 15;
46
47 public int getDecPrec() {
48 return decPrec;
49 }
50
51 // x infinity for some distributions
52 protected static final double XBIG = 100.0;
53 protected static final double XBIGM = 1000.0;
54
55 // [supportA, supportB] is the support of the pdf(x)
56 protected double supportA = Double.NEGATIVE_INFINITY;
57 protected double supportB = Double.POSITIVE_INFINITY;
58
59 // EPSARRAY[j]: Epsilon required for j decimal degits of precision
60 protected static final double[] EPSARRAY = { 0.5, 0.5E-1, 0.5E-2, 0.5E-3, 0.5E-4, 0.5E-5, 0.5E-6, 0.5E-7, 0.5E-8,
61 0.5E-9, 0.5E-10, 0.5E-11, 0.5E-12, 0.5E-13, 0.5E-14, 0.5E-15, 0.5E-16, 0.5E-17, 0.5E-18, 0.5E-19, 0.5E-20,
62 0.5E-21, 0.5E-22, 0.5E-23, 0.5E-24, 0.5E-25, 0.5E-26, 0.5E-27, 0.5E-28, 0.5E-29, 0.5E-30, 0.5E-31, 0.5E-32,
63 0.5E-33, 0.5E-34, 0.5E-35 };
64
71 public abstract double density(double x);
72
80 public double barF(double x) {
81 return 1.0 - cdf(x);
82 }
83
84 private void findInterval(double u, double[] iv) {
85 // Finds an interval [a, b] that certainly contains x defined as
86 // u = cdf(x). The result is written in iv[0] = a and iv[1] = b.
87
88 if (u > 1.0 || u < 0.0)
89 throw new IllegalArgumentException("u not in [0, 1]");
90 final double XLIM = Double.MAX_VALUE / 2.0;
91 final double B0 = 8.0;
92 double b = B0;
93 while (b < XLIM && u > cdf(b))
94 b *= 2.0;
95 if (b > B0) {
96 iv[0] = b / 2.0;
97 iv[1] = Math.min(b, supportB);
98 return;
99 }
100
101 double a = -B0;
102 while (a > -XLIM && u < cdf(a))
103 a *= 2.0;
104 if (a < -B0) {
105 iv[1] = a / 2.0;
106 iv[0] = Math.max(a, supportA);
107 return;
108 }
109 iv[0] = Math.max(a, supportA);
110 iv[1] = Math.min(b, supportB);
111 }
112
126 public double inverseBrent(double a, double b, double u, double tol) {
127 if (u > 1.0 || u < 0.0)
128 throw new IllegalArgumentException("u not in [0, 1]");
129 if (b < a) {
130 double ctemp = a;
131 a = b;
132 b = ctemp;
133 }
134 if (u <= 0.0) {
135 System.out.println("********** WARNING, inverseBrent: u = 0");
136 return supportA;
137 }
138 if (u >= 1.0) {
139 System.out.println("********** WARNING, inverseBrent: u = 1");
140 return supportB;
141 }
142 final int MAXITER = 50; // Maximum number of iterations
143 tol += EPSARRAY[decPrec] + Num.DBL_EPSILON; // in case tol is too small
144 double ua = cdf(a) - u;
145 if (ua > 0.0)
146 throw new IllegalArgumentException("u < cdf(a)");
147 double ub = cdf(b) - u;
148 if (ub < 0.0)
149 throw new IllegalArgumentException("u > cdf(b)");
150
151 final boolean DEBUG = false;
152 if (DEBUG) {
153 String ls = System.getProperty("line.separator");
154 System.out.println("-------------------------------------------------------------" + ls + "u = "
155 + PrintfFormat.g(20, 15, u));
156 System.out.println(ls + "iter b c F(x) - u" + ls);
157 }
158 // Initialize
159 double c = a;
160 double uc = ua;
161 double len = b - a;
162 double t = len;
163 if (Math.abs(uc) < Math.abs(ub)) {
164 a = b;
165 b = c;
166 c = a;
167 ua = ub;
168 ub = uc;
169 uc = ua;
170 }
171 int i;
172 for (i = 0; i < MAXITER; ++i) {
173 double tol1 = tol + 4.0 * Num.DBL_EPSILON * Math.abs(b);
174 double xm = 0.5 * (c - b);
175 if (DEBUG) {
176 System.out.println(PrintfFormat.d(3, i) + " " + PrintfFormat.g(18, decPrec, b) + " "
177 + PrintfFormat.g(18, decPrec, c) + " " + PrintfFormat.g(14, 4, ub));
178 }
179 if (Math.abs(ub) == 0.0 || (Math.abs(xm) <= tol1)) {
180 if (b <= supportA)
181 return supportA;
182 if (b >= supportB)
183 return supportB;
184 return b;
185 }
186
187 double s, p, q, r;
188 if ((Math.abs(t) >= tol1) && (Math.abs(ua) > Math.abs(ub))) {
189 if (a == c) {
190 // linear interpolation
191 s = ub / ua;
192 q = 1.0 - s;
193 p = 2.0 * xm * s;
194 } else {
195 // quadratic interpolation
196 q = ua / uc;
197 r = ub / uc;
198 s = ub / ua;
199 p = s * (2.0 * xm * q * (q - r) - (b - a) * (r - 1.0));
200 q = (q - 1.0) * (r - 1.0) * (s - 1.0);
201 }
202 if (p > 0.0)
203 q = -q;
204 p = Math.abs(p);
205
206 // Accept interpolation?
207 if ((2.0 * p >= (3.0 * xm * q - Math.abs(q * tol1))) || (p >= Math.abs(0.5 * t * q))) {
208 len = xm;
209 t = len;
210 } else {
211 t = len;
212 len = p / q;
213 }
214
215 } else {
216 len = xm;
217 t = len;
218 }
219
220 a = b;
221 ua = ub;
222 if (Math.abs(len) > tol1)
223 b += len;
224 else if (xm < 0.0)
225 b -= tol1;
226 else
227 b += tol1;
228 ub = cdf(b) - u;
229
230 if (ub * (uc / Math.abs(uc)) > 0.0) {
231 c = a;
232 uc = ua;
233 len = b - a;
234 t = len;
235 } else if (Math.abs(uc) < Math.abs(ub)) {
236 a = b;
237 b = c;
238 c = a;
239 ua = ub;
240 ub = uc;
241 uc = ua;
242 }
243 }
244 if (i >= MAXITER) {
245 String lineSep = System.getProperty("line.separator");
246 System.out.println(lineSep + "*********** inverseBrent: no convergence after " + MAXITER + " iterations");
247 }
248 return b;
249 }
250
261 public double inverseBisection(double u) {
262 final int MAXITER = 100; // Maximum number of iterations
263 final double EPSILON = EPSARRAY[decPrec]; // Absolute precision
264 final double XLIM = Double.MAX_VALUE / 2.0;
265 final boolean DEBUG = false;
266 final String lineSep = System.getProperty("line.separator");
267
268 if (u > 1.0 || u < 0.0)
269 throw new IllegalArgumentException("u not in [0, 1]");
270 if (decPrec > Num.DBL_DIG)
271 throw new IllegalArgumentException("decPrec too large");
272 if (decPrec <= 0)
273 throw new IllegalArgumentException("decPrec <= 0");
274 if (DEBUG) {
275 System.out.println(
276 "---------------------------" + " -----------------------------" + lineSep + PrintfFormat.f(10, 8, u));
277 }
278
279 double x = 0.0;
280 if (u <= 0.0) {
281 x = supportA;
282 if (DEBUG) {
283 System.out.println(lineSep + " x y" + lineSep + PrintfFormat.g(17, 2, x) + " "
284 + PrintfFormat.f(17, decPrec, u));
285 }
286 return x;
287 }
288 if (u >= 1.0) {
289 x = supportB;
290 if (DEBUG) {
291 System.out.println(lineSep + " x y" + lineSep + PrintfFormat.g(17, 2, x) + " "
292 + PrintfFormat.f(17, decPrec, u));
293 }
294 return x;
295 }
296
297 double[] iv = new double[2];
298 findInterval(u, iv);
299 double xa = iv[0];
300 double xb = iv[1];
301 double yb = cdf(xb) - u;
302 double ya = cdf(xa) - u;
303 double y;
304
305 if (DEBUG)
306 System.out.println(lineSep + "iter xa xb F - u");
307
308 boolean fini = false;
309 int i = 0;
310 while (!fini) {
311 if (DEBUG)
312 System.out.println(PrintfFormat.d(3, i) + " " + PrintfFormat.g(18, decPrec, xa) + " "
313 + PrintfFormat.g(18, decPrec, xb) + " " + PrintfFormat.g(14, 4, y));
314 x = (xa + xb) / 2.0;
315 y = cdf(x) - u;
316 if ((y == 0.0) || (Math.abs((xb - xa) / (x + Num.DBL_EPSILON)) <= EPSILON)) {
317 fini = true;
318 if (DEBUG)
319 System.out.println(lineSep + " x" + " u" + lineSep
320 + PrintfFormat.g(20, decPrec, x) + " " + PrintfFormat.g(18, decPrec, y + u));
321 } else if (y * ya < 0.0)
322 xb = x;
323 else
324 xa = x;
325 ++i;
326
327 if (i > MAXITER) {
328 // System.out.println (lineSep +
329 // "** inverseF:SEARCH DOES NOT SEEM TO CONVERGE");
330 fini = true;
331 }
332 }
333 return x;
334 }
335
346 public double inverseF(double u) {
347 double[] iv = new double[2];
348 findInterval(u, iv);
349 return inverseBrent(iv[0], iv[1], u, EPSARRAY[decPrec]);
350 }
351
357 public double getMean() {
358 throw new UnsupportedOperationException("getMean is not implemented ");
359 }
360
366 public double getVariance() {
367 throw new UnsupportedOperationException("getVariance is not implemented ");
368 }
369
375 public double getStandardDeviation() {
376 throw new UnsupportedOperationException("getStandardDeviation is not implemented ");
377 }
378
385 public double getXinf() {
386 return supportA;
387 }
388
395 public double getXsup() {
396 return supportB;
397 }
398
405 public void setXinf(double xa) {
406 supportA = xa;
407 }
408
415 public void setXsup(double xb) {
416 supportB = xb;
417 }
418}
Classes implementing continuous distributions should inherit from this base class.
double getStandardDeviation()
Returns the standard deviation.
void setXsup(double xb)
Sets the value xb, such that the probability density is 0 everywhere outside the interval .
double getXinf()
Returns such that the probability density is 0 everywhere outside the interval .
double inverseBisection(double u)
Computes and returns the inverse distribution function , using bisection.
double inverseBrent(double a, double b, double u, double tol)
Computes the inverse distribution function , using the Brent-Dekker method.
double inverseF(double u)
Returns the inverse distribution function .
double getXsup()
Returns such that the probability density is 0 everywhere outside the interval .
abstract double density(double x)
Returns , the density evaluated at .
void setXinf(double xa)
Sets the value xa, such that the probability density is 0 everywhere outside the interval .
double barF(double x)
Returns the complementary distribution function.
This class provides various constants and methods to compute numerical quantities such as factorials,...
Definition Num.java:35
static final int DBL_DIG
Number of decimal digits of precision in a double.
Definition Num.java:123
static final double DBL_EPSILON
Difference between 1.0 and the smallest double greater than 1.0.
Definition Num.java:90
This class acts like a StringBuffer which defines new types of append methods.
static String d(long x)
Same as d(0, 1, x).
static String f(double x)
Same as f(0, 6, x).
static String g(double x)
Same as g(0, 6, x).
This interface should be implemented by all classes supporting discrete and continuous distributions.
double cdf(double x)
Returns the distribution function .