Exemplo n.º 1
0
        protected double rotational_derivative(double r)
        {
            DerivFunction df     = (x) => this.sagitta(x);
            DerivResult   result = Derivatives.central_derivative(df, r, 1e-4);

            return(result.result);
        }
Exemplo n.º 2
0
        public static DerivResult central_derivative(DerivFunction f, double x, double h)
        {
            double     r_0;
            EvalResult res   = central_deriv(f, x, h);
            double     error = res.abserr_round + res.abserr_trunc;

            r_0 = res.result;

            if (res.abserr_round < res.abserr_trunc && (res.abserr_round > 0 && res.abserr_trunc > 0))
            {
                double error_opt;

                /* Compute an optimised stepsize to minimize the total error,
                 * using the scaling of the truncation error (O(h^2)) and
                 * rounding error (O(1/h)). */

                double h_opt = h * Math.Pow(res.abserr_round / (2.0 * res.abserr_trunc), 1.0 / 3.0);
                res       = central_deriv(f, x, h_opt);
                error_opt = res.abserr_round + res.abserr_trunc;

                /* Check that the new error is smaller, and that the new derivative
                 * is consistent with the error bounds of the original estimate. */

                if (error_opt < error && Math.Abs(res.result - r_0) < 4.0 * error)
                {
                    r_0   = res.result;
                    error = error_opt;
                }
            }

            return(new DerivResult(r_0, error));
        }
Exemplo n.º 3
0
        protected Vector2 base_derivative(Vector2 xy)
        {
            //double abserr;
            DerivFunction dxf = (x) => this.sagitta(new Vector2(x, xy.y()));
            DerivFunction dyf = (y) => this.sagitta(new Vector2(xy.x(), y));

            DerivResult result = Derivatives.central_derivative(dxf, xy.x(), 1e-6);
            double      dx     = result.result;

            result = Derivatives.central_derivative(dyf, xy.y(), 1e-6);
            double dy = result.result;

            // TODO what do we do about error?
            return(new Vector2(dx, dy));
        }
Exemplo n.º 4
0
        static EvalResult central_deriv(DerivFunction f, double x, double h)
        {
            /* Compute the derivative using the 5-point rule (x-h, x-h/2, x,
             * x+h/2, x+h). Note that the central point is not used.
             *
             * Compute the error using the difference between the 5-point and
             * the 3-point rule (x-h,x,x+h). Again the central point is not
             * used. */

            double fm1 = f(x - h);
            double fp1 = f(x + h);

            double fmh = f(x - h / 2);
            double fph = f(x + h / 2);

            double r3 = 0.5 * (fp1 - fm1);
            double r5 = (4.0 / 3.0) * (fph - fmh) - (1.0 / 3.0) * r3;

            double e3 = (Math.Abs(fp1) + Math.Abs(fm1)) * GSL_DBL_EPSILON;
            double e5 = 2.0 * (Math.Abs(fph) + Math.Abs(fmh)) * GSL_DBL_EPSILON + e3;

            /* The next term is due to finite precision in x+h = O (eps * x) */

            double dy =
                Math.Max(Math.Abs(r3 / h), Math.Abs(r5 / h)) * (Math.Abs(x) / h) * GSL_DBL_EPSILON;

            /* The truncation error in the r5 approximation itself is O(h^4).
             * However, for safety, we estimate the error from r5-r3, which is
             * O(h^2).  By scaling h we will minimise this estimated error, not
             * the actual truncation error in r5. */
            EvalResult result = new EvalResult();

            result.result       = r5 / h;
            result.abserr_trunc = Math.Abs((r5 - r3) / h); /* Estimated truncation error O(h^2) */
            result.abserr_round = Math.Abs(e5 / h) + dy;   /* Rounding error (cancellations) */
            return(result);
        }