| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 
 | using flow::model::utils::geq;using flow::model::utils::leq;
 using flow::model::utils::lt;
 using flow::model::utils::gt;
 using flow::model::norm_dist::cdf;
 
 
 double sign(const double &a) {
 if (lt(a , 0.))
 return -1.0;
 else if (gt(a , 0.))
 return 1.0;
 else
 return 0.0;
 }
 
 
 double f(const double &x, const double &y, const double &a_prime, const double &b_prime, const double &rho) {
 double r = a_prime * (2.0 * x - a_prime) + b_prime * (2.0 * y - b_prime) + 2.0 * rho * (x - a_prime) * (y - b_prime);
 return exp(r);
 }
 
 double bi_cdf(const double &a, const double &b, const double &rho) {
 double pi = 3.14159265359;
 if (leq(a, 0.0) && leq(b , 0.0) && leq(rho , 0.0)) {
 double a_prime = a / sqrt(2.0 * (1.0 - rho * rho));
 double b_prime = b / sqrt(2.0 * (1.0 - rho * rho));
 double A[] = {0.3253030, 0.4211071, 0.1334425, 0.006374323};
 double B[] = {0.1337764, 0.6243247, 1.3425378, 2.2626645};
 double sum = 0.0;
 for (int i = 0; i < 4; i++)
 for (int j = 0; j < 4; j++)
 sum = sum + A[i] * A[j] * f(B[i], B[j], a_prime, b_prime, rho);
 sum = sum * (sqrt(1.0 - rho * rho) / pi);
 return sum;
 } else if (leq(a * b * rho , 0.0)) {
 if (leq(a , 0.0) && geq(b , 0.0) && geq(rho , 0.0))
 return cdf(a) - bi_cdf(a, -1.0 * b, -1.0 * rho);
 else if (geq(a , 0.0) && leq(b , 0.0) && geq(rho , 0.0))
 return cdf(b) - bi_cdf(-1.0 * a, b, -1.0 * rho);
 else if (geq(a , 0.0) && geq(b , 0.0) && leq(rho , 0.0))
 return cdf(a) + cdf(b) - 1.0 + bi_cdf(-1.0 * a, -1.0 * b, rho);
 } else if (geq(a * b * rho , 0.0)) {
 double de_num = sqrt(a * a - 2.0 * rho * a * b + b * b);
 double rho1 = ((rho * a - b) * sign(a)) / de_num;
 double rho2 = ((rho * b - a) * sign(b)) / de_num;
 double delta = (1.0 - sign(a) * sign(b)) / 4.0;
 return bi_cdf(a, 0.0, rho1) + bi_cdf(b, 0.0, rho2) - delta;
 } else {
 throw std::out_of_range("This part of the code should never be reached.");
 }
 throw std::out_of_range("This part of the code should never be reached.");
 }
 
 |