public static double CBivariateStandardNormal(double h, double k, double rho) { // Check the limiting cases of perfect correlation and negative correlation if (rho > 0.99999) { return(Distributions.CDistStandardNormal(Math.Min(h, k))); } else if (rho < -0.99999) { if (k <= -h) { return(0.0); } else { return(Distributions.CDistStandardNormal(h) + Distributions.CDistStandardNormal(k) - 1); } } if (h <= 0 && k <= 0 && rho <= 0) { return(CBivariateStandardNormal_UseForNegatives(h, k, rho)); } else if (h <= 0 && k >= 0 && rho >= 0) { return(Distributions.CDistStandardNormal(h) - CBivariateStandardNormal_UseForNegatives(h, -k, -rho)); } else if (h >= 0 && k <= 0 && rho >= 0) { return(Distributions.CDistStandardNormal(k) - CBivariateStandardNormal_UseForNegatives(-h, k, -rho)); } else if (h >= 0 && k >= 0 && rho <= 0) { return(Distributions.CDistStandardNormal(h) + Distributions.CDistStandardNormal(k) - 1 + CBivariateStandardNormal_UseForNegatives(-h, -k, rho)); } else { double denom = Math.Sqrt(h * h - 2 * rho * h * k + k * k); double rho_hk = (rho * h - k) * Math.Sign(h) / denom; double rho_kh = (rho * k - h) * Math.Sign(k) / denom; double delta = (1.0 - Math.Sign(h) * Math.Sign(k)) / 4.0; return(CBivariateStandardNormal(h, 0, rho_hk) + CBivariateStandardNormal(k, 0, rho_kh) - delta); } }
public static void TestHarness() { Console.WriteLine("Zero is {0}", CBivariateStandardNormal(-1000, -1000, 0)); Console.WriteLine("{0} is {1}", Distributions.CDistStandardNormal(0), CBivariateStandardNormal(+1000, 0, 0)); Console.WriteLine("{0} is {1}", Distributions.CDistStandardNormal(0.5), CBivariateStandardNormal(+1000, 0.5, 0)); Console.WriteLine("{0} is {1}", Distributions.CDistStandardNormal(-0.5), CBivariateStandardNormal(+1000, -0.5, 0)); Console.WriteLine("{0} is {1}", Distributions.CDistStandardNormal(-0.5), CBivariateStandardNormal(-0.5, -0.5, 1.0)); Console.WriteLine("{0} is {1}", Distributions.CDistStandardNormal(-0.5), CBivariateStandardNormal(-0.5, -0.2, 1.0)); Console.WriteLine("{0} is {1}", Distributions.CDistStandardNormal(-0.2), CBivariateStandardNormal(-0.1, -0.2, 1.0)); Console.WriteLine("{0} is {1}", 0, CBivariateStandardNormal(-0.5, -0.5, -1.0)); Console.WriteLine("{0} is {1}", 0, CBivariateStandardNormal(-0.5, -0.2, -1.0)); Console.WriteLine("{0} is {1}", 0, CBivariateStandardNormal(-0.1, -0.2, -1.0)); Console.WriteLine("{0} is {1}", Distributions.CDistStandardNormal(0.1) + Distributions.CDistStandardNormal(0.5) - 1, CBivariateStandardNormal(0.1, 0.5, -1.0)); Console.WriteLine("Pain is {0}", CBivariateStandardNormal(3.8922701863527047, -0.28284271247461906, -0.70710678118654757)); TestHarness_GUI(); }
public double getProb(Vector a, Vector b, double alpha, double epsilon, int N_max) { // A neat reference to match the document int m = correlation.rows; Matrix c = correlation_root; // Check that we are not in univariate land.... if (1 == m) { return(Distributions.CDistStandardNormal(b[0]) - Distributions.CDistStandardNormal(a[0])); } // Our variables double[] d = new double[m]; double[] e = new double[m]; double[] f = new double[m]; double[] y = new double[m]; double[] w = new double[m]; // Initialisation code double intsum = 0.0; int N = 0; double varsum = 0.0; d[0] = Distributions.CDistStandardNormal(a[0] / c[0, 0]); e[0] = Distributions.CDistStandardNormal(b[0] / c[0, 0]); f[0] = e[0] - d[0]; double error = 0.0; do { for (int i = 0; i < m - 1; ++i) { w[i] = random.NextDouble(); } for (int i = 1; i < m; ++i) { y[i - 1] = Distributions.InvDist_SN(d[i - 1] + w[i - 1] * (e[i - 1] - d[i - 1])); double sum_cij_yj = 0.0; for (int j = 0; j <= i - 1; ++j) { sum_cij_yj += c[i, j] * y[j]; } d[i] = Distributions.CDistStandardNormal((a[i] - sum_cij_yj) / c[i, i]); e[i] = Distributions.CDistStandardNormal((b[i] - sum_cij_yj) / c[i, i]); f[i] = (e[i] - d[i]) * f[i - 1]; ++N; double delta = (f[m - 1] - intsum) / N; intsum += delta; varsum = (N - 2) * varsum / N + delta * delta; error = alpha * Math.Sqrt(varsum); } } while (error > epsilon && N < N_max); if (N >= N_max) { //System.Console.WriteLine("Exceeded"); //throw new GenericException("Reached maximum number of iterations"); } return(intsum); }