25package umontreal.ssj.probdistmulti;
27import umontreal.ssj.probdist.NormalDist;
66 protected double mu1, mu2;
67 protected double sigma1, sigma2;
69 protected double racRho;
70 protected double detS;
71 protected static final double RHO_SMALL = 1.0e-8;
73 private static final double Z[] = { 0.04691008, 0.23076534, 0.5, 0.76923466, 0.95308992 };
75 private static final double W[] = { 0.018854042, 0.038088059, 0.0452707394, 0.038088059, 0.018854042 };
77 private static final double AGauss[] = { -0.72657601, 0.71070688, -0.142248368, 0.127414796 };
95 public BiNormalDist(
double mu1,
double sigma1,
double mu2,
double sigma2,
double rho) {
99 public double density(
double x,
double y) {
100 if (Math.abs(rho) == 1.)
101 throw new IllegalArgumentException(
"|rho| = 1");
102 double X = (x - mu1) / sigma1;
103 double Y = (y - mu2) / sigma2;
104 double T = (X * X - 2.0 * rho * X * Y + Y * Y) / (2.0 * racRho * racRho);
105 return Math.exp(-T) / detS;
113 public static double density(
double x,
double y,
double rho) {
114 return density(0.0, 1.0, x, 0.0, 1.0, y, rho);
125 public static double density(
double mu1,
double sigma1,
double x,
double mu2,
double sigma2,
double y,
double rho) {
127 throw new IllegalArgumentException(
"sigma1 <= 0");
129 throw new IllegalArgumentException(
"sigma2 <= 0");
130 if (Math.abs(rho) >= 1.)
131 throw new IllegalArgumentException(
"|rho| >= 1");
132 double X = (x - mu1) / sigma1;
133 double Y = (y - mu2) / sigma2;
134 double fRho = (1.0 - rho) * (1.0 + rho);
135 double T = (X * X - 2.0 * rho * X * Y + Y * Y) / (2.0 * fRho);
136 return Math.exp(-T) / (2.0 * Math.PI * sigma1 * sigma2 * Math.sqrt(fRho));
140 protected static double Gauss(
double z) {
145 final double x = 1.0 / (1.0 + 0.23164189 * Math.abs(z));
146 double G = 0.53070271;
147 for (
int i = 0; i < 4; ++i)
148 G = G * x + AGauss[i];
149 G = G * x * Math.exp(-z * z / 2.0);
155 protected static double specialCDF(
double x,
double y,
double rho,
double xbig) {
160 if (Math.abs(rho) > 1.0)
161 throw new IllegalArgumentException(
"|rho| > 1");
162 if (x == 0.0 && y == 0.0)
163 return 0.25 + Math.asin(rho) / (2.0 * Math.PI);
168 return NormalDist.cdf01(x);
174 return NormalDist.cdf01(x) - NormalDist.cdf01(-y);
176 if (Math.abs(rho) < RHO_SMALL)
178 return Gauss(x) * Gauss(y);
180 if ((x <= -xbig) || (y <= -xbig))
183 return NormalDist.cdf01(y);
185 return NormalDist.cdf01(x);
198 public static double cdf(
double x,
double y,
double rho) {
199 double bvn = specialCDF(x, y, rho, 20.0);
212 double r1, r2, r3, rr, aa, ab, h3, h5, h6, h7;
213 final double h1 = -x;
215 final double h12 = (h1 * h1 + h2 * h2) / 2.;
217 if (Math.abs(rho) >= 0.7) {
218 r2 = (1. - rho) * (1. + rho);
224 h7 = Math.exp(-h3 / 2.);
228 h6 = Math.abs(h1 - h2);
232 ab = 3. - 2. * aa * h5;
233 bvn = .13298076 * h6 * ab * (1.0 - Gauss(h6)) - Math.exp(-h5 / r2) * (ab + aa * r2) * 0.053051647;
235 for (i = 0; i < 5; i++) {
238 r2 = Math.sqrt(1. - rr);
239 bvn -= W[i] * Math.exp(-h5 / rr) * (Math.exp(-h3 / (1. + r2)) / r2 / h7 - 1. - aa * rr);
244 bvn = bvn * r3 * h7 + (1.0 - Gauss(Math.max(h1, h2)));
246 bvn = (h1 < h2 ? Gauss(h2) - Gauss(h1) : 0.) - bvn * r3 * h7;
250 for (i = 0; i < 5; i++) {
253 bvn += W[i] * Math.exp((r1 * h3 - h12) / r2) / Math.sqrt(r2);
255 bvn = (1.0 - Gauss(h1)) * (1.0 - Gauss(h2)) + rho * bvn;
265 public double cdf(
double x,
double y) {
266 return cdf((x - mu1) / sigma1, (y - mu2) / sigma2, rho);
279 public static double cdf(
double mu1,
double sigma1,
double x,
double mu2,
double sigma2,
double y,
double rho) {
281 throw new IllegalArgumentException(
"sigma1 <= 0");
283 throw new IllegalArgumentException(
"sigma2 <= 0");
284 double X = (x - mu1) / sigma1;
285 double Y = (y - mu2) / sigma2;
286 return cdf(X, Y, rho);
295 public static double barF(
double x,
double y,
double rho) {
296 return cdf(-x, -y, rho);
299 public double barF(
double x,
double y) {
300 return barF((x - mu1) / sigma1, (y - mu2) / sigma2, rho);
313 public static double barF(
double mu1,
double sigma1,
double x,
double mu2,
double sigma2,
double y,
double rho) {
315 throw new IllegalArgumentException(
"sigma1 <= 0");
317 throw new IllegalArgumentException(
"sigma2 <= 0");
318 double X = (x - mu1) / sigma1;
319 double Y = (y - mu2) / sigma2;
320 return barF(X, Y, rho);
324 return getMean(mu1, mu2, sigma1, sigma2, rho);
331 public static double[]
getMean(
double mu1,
double sigma1,
double mu2,
double sigma2,
double rho) {
333 throw new IllegalArgumentException(
"sigma1 <= 0");
335 throw new IllegalArgumentException(
"sigma2 <= 0");
336 if (Math.abs(rho) > 1.)
337 throw new IllegalArgumentException(
"|rho| > 1");
339 double mean[] =
new double[2];
354 public static double[][]
getCovariance(
double mu1,
double sigma1,
double mu2,
double sigma2,
double rho) {
356 throw new IllegalArgumentException(
"sigma1 <= 0");
358 throw new IllegalArgumentException(
"sigma2 <= 0");
359 if (Math.abs(rho) > 1.)
360 throw new IllegalArgumentException(
"|rho| > 1");
362 double cov[][] =
new double[2][2];
364 cov[0][0] = sigma1 * sigma1;
365 cov[0][1] = rho * sigma1 * sigma2;
366 cov[1][0] = cov[0][1];
367 cov[1][1] = sigma2 * sigma2;
379 public static double[][]
getCorrelation(
double mu1,
double sigma1,
double mu2,
double sigma2,
double rho) {
381 throw new IllegalArgumentException(
"sigma1 <= 0");
383 throw new IllegalArgumentException(
"sigma2 <= 0");
384 if (Math.abs(rho) > 1.)
385 throw new IllegalArgumentException(
"|rho| > 1");
387 double corr[][] =
new double[2][2];
431 protected void setParams(
double mu1,
double sigma1,
double mu2,
double sigma2,
double rho) {
433 throw new IllegalArgumentException(
"sigma1 <= 0");
435 throw new IllegalArgumentException(
"sigma2 <= 0");
436 if (Math.abs(rho) > 1.)
437 throw new IllegalArgumentException(
"|rho| > 1");
440 this.sigma1 = sigma1;
442 this.sigma2 = sigma2;
444 racRho = Math.sqrt((1.0 - rho) * (1.0 + rho));
445 detS = 2.0 * Math.PI * sigma1 * sigma2 * racRho;
static double barF(double x, double y, double rho)
Computes the standard upper binormal distribution with and .
static double density(double x, double y, double rho)
Computes the standard binormal density function ( f1binormal ) with and .
double density(double x, double y)
Returns , the density of evaluated at .
BiNormalDist(double mu1, double sigma1, double mu2, double sigma2, double rho)
Constructs a BiNormalDist object with parameters = mu1, = mu2, = sigma1,.
static double cdf(double x, double y, double rho)
Computes the standard binormal distribution ( cdf2binormal ) using the fast Drezner-Wesolowsky method...
double[] getMean()
Returns the mean vector of the distribution, defined as .
double cdf(double x, double y)
Computes the distribution function :
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,...
double getSigma1()
Returns the parameter .
double[][] getCorrelation()
Returns the correlation matrix of the distribution, defined as.
static double[][] getCorrelation(double mu1, double sigma1, double mu2, double sigma2, double rho)
Return the correlation matrix of the binormal distribution.
void setParams(double mu1, double sigma1, double mu2, double sigma2, double rho)
Sets the parameters = mu1, = mu2,.
BiNormalDist(double rho)
Constructs a BiNormalDist object with default parameters , and correlation.
double getMu2()
Returns the parameter .
double getMu1()
Returns the parameter .
double getSigma2()
Returns the parameter .
static double[][] getCovariance(double mu1, double sigma1, double mu2, double sigma2, double rho)
Return the covariance matrix of the binormal distribution.
double barF(double x, double y)
Computes the upper cumulative 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,...
double[][] getCovariance()
Returns the variance-covariance matrix of the distribution, defined as .
static double density(double mu1, double sigma1, double x, double mu2, double sigma2, double y, double rho)
Computes the binormal density function ( f1binormal ) with parameters = mu1, = mu2,...
static double[] getMean(double mu1, double sigma1, double mu2, double sigma2, double rho)
Return the mean vector of the binormal distribution.
Classes implementing 2-dimensional continuous distributions should inherit from this class.