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));
            }
        }