1 2 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."); }
|