Ejemplo n.º 1
0
        /// <summary>
        /// Differentiation of a one dimensional function after <c>f.Parameters[n]</c>.
        /// </summary>
        public static double dfdp(IParametricFunction2D f, double x, double y, int n, out double abserr)
        {
            // adapted from gsl_diff_central

            /* Construct a divided difference table with a fairly large step
             *      size to get a very rough estimate of f'''.  Use this to estimate
             *      the step size which will minimize the error in calculating f'. */

            IList <double> p = f.Parameters;
            int            i, k;
            double         h = GSL_SQRT_DBL_EPSILON, a3, temp, pn = p[n], f0, f1;

            double[] a = new double[4], d = new double[4];

            /* Algorithm based on description on pg. 204 of Conte and de Boor
            *       (CdB) - coefficients of Newton form of polynomial of degree 3. */

            for (i = 0; i < 4; i++)
            {
                a[i] = pn + (i - 2) * h;
                p[n] = a[i];
                d[i] = f.f(x, y);
                p[n] = pn;
            }

            for (k = 1; k < 5; k++)
            {
                for (i = 0; i < 4 - k; i++)
                {
                    d[i] = (d[i + 1] - d[i]) / (a[i + k] - a[i]);
                }
            }

            /* Adapt procedure described on pg. 282 of CdB to find best
             *      value of step size. */
            a3 = Math.Abs(d[0] + d[1] + d[2] + d[3]);

            if (a3 < 100 * GSL_SQRT_DBL_EPSILON)
            {
                a3 = 100 * GSL_SQRT_DBL_EPSILON;
            }

            h = Math.Pow(GSL_SQRT_DBL_EPSILON / (2 * a3), 1.0 / 3.0);

            if (h > 100 * GSL_SQRT_DBL_EPSILON)
            {
                h = 100 * GSL_SQRT_DBL_EPSILON;
            }

            abserr = Math.Abs(100.0 * a3 * h * h);
            temp   = pn + h;
            GetH(pn, ref h, temp);
            p[n] = pn + h;
            f0   = f.f(x, y);
            p[n] = pn - h;
            f1   = f.f(x, y);
            return((f0 - f1) / (2 * h));
        }
Ejemplo n.º 2
0
 /// <summary>
 /// An alias for the routine dfdp.
 /// </summary>
 public static double diffp(IParametricFunction2D f, double x, double y, int n, out double abserr)
 {
     return(dfdp(f, x, y, n, out abserr));
 }