public static double[][] NormalCdfRatioTable2(int nSteps, int nMax, int nTerms, double start, double step) { double[][] table = new double[nSteps + 1][]; double[] derivs = new double[nMax + nSteps * nTerms]; for (int n = 0; n < derivs.Length; n++) { //Console.WriteLine("ncdfmr({0}) = {1}", n, NormalCdfMomentRatioConFrac(n, start)); derivs[n] = MMath.NormalCdfMomentRatioConFrac(n, start); //Console.WriteLine("derivs[{0}] = {1}", n, derivs[n]); } table[0] = derivs; for (int i = 0; i < nSteps; i++) { int nMax2 = derivs.Length - nTerms; Console.WriteLine("{0} nMax2 = {1}", i, nMax2); double[] newDerivs = new double[nMax2]; for (int n = 0; n < nMax2; n++) { newDerivs[n] = MMath.NormalCdfMomentRatioTaylor(n, step, derivs); } table[i + 1] = newDerivs; derivs = newDerivs; } return(table); }
public static void NormalCdfRatioTest2() { // larger n requires more terms in the Taylor expansion // need nTerms=60 to get n=19, x=-4 from x=-8 // nTerms=40 can do it in 2 steps, even though the 60 values for x=-6 are not accurate // (n=19,x=-4) in 4 steps: nTerms=30 // (n=19,x=-4) in 1 step from x=-6: nTerms=100 // thus it makes a difference where you start from double start = -6; double step = 2; double[][] table = NormalCdfRatioTable2(1, 20, 100, start, step); double x = start; for (int i = 0; i < table.Length; i++) { for (int j = 0; j < table[i].Length; j++) { double r = MMath.NormalCdfMomentRatioConFrac(j, x); Console.WriteLine("({0},{1}) error = {2}", j, x, Math.Abs(table[i][j] - r) / r); } x += step; } }
public static void NormalCdfRatioTest3() { // x=-2,-4,-8 are good positions for Taylor expansion double x = -4; for (int i = 0; i < 100; i++) { // x=-10: nBase=20,30 is unusually good, nBase=50 doesn't work as well // x=-20: nBase=50 works well // larger x allows larger nBase // x=-8: nBase=100 // x=-6: nBase=10 works well // x=-5: poor // x=-4: nBase=40 // x=-3: poor results for any nBase // x=-2: nBase=100 works well double r2 = MMath.NormalCdfMomentRatioRecurrence2(i, x, 100); double r = MMath.NormalCdfMomentRatioConFrac(i, x); //Console.WriteLine("recurrence = {0}, confrac = {1}", r1, r2); //Console.WriteLine("ncdfmr = {0}, ncdfmr/(i-1)!! = {1}", r, r/DoubleFact(i-1)); //Console.WriteLine("ncdfmr = {0}, ncdfmr*i! = {1}", r, r*MMath.Gamma(i+1)); Console.WriteLine("error = {0}", Math.Abs(r - r2) / Math.Abs(r)); } }