SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
BiNormalGenzDist.java
1/*
2 * Class: BiNormalGenzDist
3 * Description: bivariate normal distribution using Genz's algorithm
4 * Environment: Java
5 * Software: SSJ
6 * Organization: DIRO, Universite de Montreal
7 * @author
8 * @since
9 */
10package umontreal.ssj.probdistmulti;
11
12import umontreal.ssj.probdist.NormalDist;
13
23public class BiNormalGenzDist extends BiNormalDist {
24
25 private static final double[][] W = {
26 // Gauss Legendre points and weights, n = 6
27 { 0.1713244923791705, 0.3607615730481384, 0.4679139345726904 },
28
29 // Gauss Legendre points and weights, n = 12
30 { 0.4717533638651177e-1, 0.1069393259953183, 0.1600783285433464, 0.2031674267230659, 0.2334925365383547,
31 0.2491470458134029 },
32
33 // Gauss Legendre points and weights, n = 20
34 { 0.1761400713915212e-1, 0.4060142980038694e-1, 0.6267204833410906e-1, 0.8327674157670475e-1,
35 0.1019301198172404, 0.1181945319615184, 0.1316886384491766, 0.1420961093183821, 0.1491729864726037,
36 0.1527533871307259 } };
37
38 private static final double[][] X = {
39 // Gauss Legendre points and weights, n = 6
40 { 0.9324695142031522, 0.6612093864662647, 0.2386191860831970 },
41
42 // Gauss Legendre points and weights, n = 12
43 { 0.9815606342467191, 0.9041172563704750, 0.7699026741943050, 0.5873179542866171, 0.3678314989981802,
44 0.1252334085114692 },
45
46 // Gauss Legendre points and weights, n = 20
47 { 0.9931285991850949, 0.9639719272779138, 0.9122344282513259, 0.8391169718222188, 0.7463319064601508,
48 0.6360536807265150, 0.5108670019508271, 0.3737060887154196, 0.2277858511416451,
49 0.7652652113349733e-1 } };
50
57 public BiNormalGenzDist(double rho) {
58 super(rho);
59 }
60
67 public BiNormalGenzDist(double mu1, double sigma1, double mu2, double sigma2, double rho) {
68 super(mu1, sigma1, mu2, sigma2, rho);
69 }
70
82 public static double cdf(double x, double y, double rho) {
83 double bvn = specialCDF(x, y, rho, 40.0);
84 if (bvn >= 0.0)
85 return bvn;
86
87 /*
88 * // Copyright (C) 2005, Alan Genz, All rights reserved. // // Redistribution
89 * and use in source and binary forms, with or without // modification, are
90 * permitted provided the following conditions are met: // 1. Redistributions of
91 * source code must retain the above copyright // notice, this list of
92 * conditions and the following disclaimer. // 2. Redistributions in binary form
93 * must reproduce the above copyright // notice, this list of conditions and the
94 * following disclaimer in the // documentation and/or other materials provided
95 * with the distribution. // 3. The contributor name(s) may not be used to
96 * endorse or promote // products derived from this software without specific
97 * prior written // permission. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
98 * HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
99 * INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
100 * AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
101 * // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //
102 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT
103 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS // OF USE,
104 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY
105 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR // TORT
106 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF
107 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //
108 * function p = bvnl( dh, dk, r ) // // A function for computing bivariate
109 * normal probabilities. // bvnl calculates the probability that x < dh and y <
110 * dk. // parameters // dh 1st upper integration limit // dk 2nd upper
111 * integration limit // r correlation coefficient // // Author // Alan Genz //
112 * Department of Mathematics // Washington State University // Pullman, Wa
113 * 99164-3113 // Email : alangenz@wsu.edu // This function is based on the
114 * method described by // Drezner, Z and G.O. Wesolowsky, (1989), // On the
115 * computation of the bivariate normal inegral, // Journal of Statist. Comput.
116 * Simul. 35, pp. 101-107, // with major modifications for double precision, for
117 * |r| close to 1, // and for matlab by Alan Genz - last modifications 7/98. //
118 * // p = bvnu( -dh, -dk, r ); // return // // end bvnl // // function p = bvnu(
119 * dh, dk, r ) // // A function for computing bivariate normal probabilities. //
120 * bvnu calculates the probability that x > dh and y > dk. // parameters // dh
121 * 1st lower integration limit // dk 2nd lower integration limit // r
122 * correlation coefficient // // Author // Alan Genz // Department of
123 * Mathematics // Washington State University // Pullman, Wa 99164-3113 // Email
124 * : alangenz@wsu.edu // // This function is based on the method described by //
125 * Drezner, Z and G.O. Wesolowsky, (1989), // On the computation of the
126 * bivariate normal inegral, // Journal of Statist. Comput. Simul. 35, pp.
127 * 101-107, // with major modifications for double precision, for |r| close to
128 * 1, // and for matlab by Alan Genz - last modifications 7/98. // Note: to
129 * compute the probability that x < dh and y < dk, use // bvnu( -dh, -dk, r ).
130 * //
131 */
132
133 final double TWOPI = 2.0 * Math.PI;
134 final double sqrt2pi = 2.50662827463100050241; // sqrt(TWOPI)
135 double h, k, hk, hs, asr, sn, as, a, b, c, d, sp, rs, ep, bs, xs;
136 int i, lg, ng, is;
137
138 if (Math.abs(rho) < 0.3) {
139 ng = 0;
140 lg = 3;
141
142 } else if (Math.abs(rho) < 0.75) {
143 ng = 1;
144 lg = 6;
145
146 } else {
147 ng = 2;
148 lg = 10;
149 }
150
151 h = -x;
152 k = -y;
153 hk = h * k;
154 bvn = 0;
155 if (Math.abs(rho) < 0.925) {
156 hs = (h * h + k * k) / 2.0;
157 asr = Math.asin(rho);
158 for (i = 0; i < lg; ++i) {
159 sn = Math.sin(asr * (1.0 - X[ng][i]) / 2.0);
160 bvn += W[ng][i] * Math.exp((sn * hk - hs) / (1.0 - sn * sn));
161 sn = Math.sin(asr * (1.0 + X[ng][i]) / 2.0);
162 bvn += W[ng][i] * Math.exp((sn * hk - hs) / (1.0 - sn * sn));
163 }
164 bvn = bvn * asr / (4.0 * Math.PI) + NormalDist.cdf01(-h) * NormalDist.cdf01(-k);
165
166 } else {
167 if (rho < 0.0) {
168 k = -k;
169 hk = -hk;
170 }
171 if (Math.abs(rho) < 1.0) {
172 as = (1.0 - rho) * (1.0 + rho);
173 a = Math.sqrt(as);
174 bs = (h - k) * (h - k);
175 c = (4.0 - hk) / 8.0;
176 d = (12.0 - hk) / 16.0;
177 asr = -(bs / as + hk) / 2.0;
178 if (asr > -100.0)
179 bvn = a * Math.exp(asr) * (1.0 - c * (bs - as) * (1.0 - d * bs / 5.0) / 3.0 + c * d * as * as / 5.0);
180
181 if (-hk < 100.0) {
182 b = Math.sqrt(bs);
183 sp = sqrt2pi * NormalDist.cdf01(-b / a);
184 bvn = bvn - Math.exp(-hk / 2.0) * sp * b * (1.0 - c * bs * (1.0 - d * bs / 5.0) / 3.0);
185 }
186 a = a / 2.0;
187 for (i = 0; i < lg; ++i) {
188 for (is = -1; is <= 1; is += 2) {
189 xs = (a * (is * X[ng][i] + 1.0));
190 xs = xs * xs;
191 rs = Math.sqrt(1.0 - xs);
192 asr = -(bs / xs + hk) / 2.0;
193 if (asr > -100.0) {
194 sp = (1.0 + c * xs * (1.0 + d * xs));
195 ep = Math.exp(-hk * (1.0 - rs) / (2.0 * (1.0 + rs))) / rs;
196 bvn += a * W[ng][i] * Math.exp(asr) * (ep - sp);
197 }
198 }
199 }
200 bvn = -bvn / TWOPI;
201 }
202 if (rho > 0.0) {
203 if (k > h)
204 h = k;
205 bvn += NormalDist.cdf01(-h);
206 }
207 if (rho < 0.0) {
208 xs = NormalDist.cdf01(-h) - NormalDist.cdf01(-k);
209 if (xs < 0.0)
210 xs = 0.0;
211 bvn = -bvn + xs;
212 }
213 }
214 if (bvn <= 0.0)
215 return 0.0;
216 if (bvn >= 1.0)
217 return 1.0;
218 return bvn;
219
220 }
221
222 public static double cdf(double mu1, double sigma1, double x, double mu2, double sigma2, double y, double rho) {
223 if (sigma1 <= 0)
224 throw new IllegalArgumentException("sigma1 <= 0");
225 if (sigma2 <= 0)
226 throw new IllegalArgumentException("sigma2 <= 0");
227 double Z = (x - mu1) / sigma1;
228 double T = (y - mu2) / sigma2;
229 return cdf(Z, T, rho);
230 }
231
232 public double cdf(double x, double y) {
233 return cdf((x - mu1) / sigma1, (y - mu2) / sigma2, rho);
234 }
235
236 public double barF(double x, double y) {
237 return barF((x - mu1) / sigma1, (y - mu2) / sigma2, rho);
238 }
239
240 public static double barF(double mu1, double sigma1, double x, double mu2, double sigma2, double y, double rho) {
241 if (sigma1 <= 0)
242 throw new IllegalArgumentException("sigma1 <= 0");
243 if (sigma2 <= 0)
244 throw new IllegalArgumentException("sigma2 <= 0");
245 double Z = (x - mu1) / sigma1;
246 double T = (y - mu2) / sigma2;
247 return barF(Z, T, rho);
248 }
249
250 public static double barF(double x, double y, double rho) {
251 return cdf(-x, -y, rho);
252 }
253}
Extends the class ContinuousDistribution for the normal distribution (e.g., tjoh95a  (page 80)).
static double cdf01(double x)
Same as cdf(0, 1, x).
BiNormalDist(double rho)
Constructs a BiNormalDist object with default parameters , and correlation.
double barF(double x, double y)
Computes the upper cumulative distribution function.
static double barF(double x, double y, double rho)
Computes the standard upper binormal distribution with and .
double cdf(double x, double y)
Computes the distribution function :
static double barF(double mu1, double sigma1, double x, double mu2, double sigma2, double y, double rho)
Computes the upper binormal distribution function ( cdf3binormal ) with parameters = mu1,...
static double cdf(double mu1, double sigma1, double x, double mu2, double sigma2, double y, double rho)
Computes the binormal distribution function ( cdf1binormal ) with parameters = mu1,...
static double cdf(double x, double y, double rho)
Computes the standard binormal distribution ( cdf2binormal ) with the method described in tgen04a .
BiNormalGenzDist(double rho)
Constructs a BiNormalGenzDist object with default parameters.
BiNormalGenzDist(double mu1, double sigma1, double mu2, double sigma2, double rho)
Constructs a BiNormalGenzDist object with parameters = mu1, = mu2, = sigma1,.