def check_lte(method_residual, lte, exact_symb, base_dt, implicit):

        exact, residual, dys, J = utils.symb2functions(exact_symb)
        dddy = dys[3]
        Fddy = lambda t, y: J(t, y) * dys[2](t, y)

        newton_tol = 1e-10

        # tmax varies with dt so that we can vary dt over orders of
        # magnitude.
        tmax = 50*dt

        # Run ode solver
        if implicit:
            ts, ys = ode._odeint(
                residual, [0.0], [sp.array([exact(0.0)], ndmin=1)],
                dt, tmax, method_residual,
                target_error=None,
                time_adaptor=ode.create_random_time_adaptor(base_dt),
                initialisation_actions=par(ode.higher_order_start, 3),
                newton_tol=newton_tol)

        else:
            ts, ys = ode.odeint_explicit(
                dys[1], exact(0.0), base_dt, tmax, method_residual,
                time_adaptor=ode.create_random_time_adaptor(base_dt))

        dts = utils.ts2dts(ts)

        # Check it's accurate-ish
        exact_ys = map(exact, ts)
        errors = map(op.sub, exact_ys, ys)
        utils.assert_list_almost_zero(errors, 1e-3)

        # Calculate ltes by two methods. Note that we need to drop a few
        # values because exact calculation (may) need a few dts. Could be
        # dodgy: exact dddys might not correspond to dddy in experiment if
        # done over long time and we've wandered away from the solution.
        exact_dddys = map(dddy, ts, ys)
        exact_Fddys = map(Fddy, ts, ys)
        exact_ltes = map(lte, dts[2:], dts[1:-1], dts[:-2],
                         exact_dddys[3:], exact_Fddys[3:])
        error_diff_ltes = map(op.sub, errors[1:], errors[:-1])[2:]

        # Print for debugging when something goes wrong
        print exact_ltes
        print error_diff_ltes

        # Probably the best test is that they give the same order of
        # magnitude and the same sign... Can't test much more than that
        # because we have no idea what the constant in front of the dt**4
        # term is. Effective zero (noise level) is either dt**4 or newton
        # tol, whichever is larger.
        z = 50 * max(dt**4, newton_tol)
        map(par(utils.assert_same_sign, fp_zero=z),
            exact_ltes, error_diff_ltes)
        map(par(utils.assert_same_order_of_magnitude, fp_zero=z),
            exact_ltes, error_diff_ltes)
    def check_explicit_stepper(stepper, exact_symb):

        exact, residual, dys, J = utils.symb2functions(exact_symb)

        base_dt = 1e-3
        ts, ys = odeint_explicit(dys[1], exact(0.0), base_dt, 1.0, stepper,
                                 time_adaptor=create_random_time_adaptor(base_dt))

        exact_ys = map(exact, ts)
        utils.assert_list_almost_equal(ys, exact_ys, 1e-4)
Пример #3
0
    def check_explicit_stepper(stepper, exact_symb):

        exact, residual, dys, J = utils.symb2functions(exact_symb)

        base_dt = 1e-3
        ts, ys = odeint_explicit(
            dys[1],
            exact(0.0),
            base_dt,
            1.0,
            stepper,
            time_adaptor=create_random_time_adaptor(base_dt))

        exact_ys = map(exact, ts)
        utils.assert_list_almost_equal(ys, exact_ys, 1e-4)
Пример #4
0
    def check_lte(method_residual, lte, exact_symb, base_dt, implicit):

        exact, residual, dys, J = utils.symb2functions(exact_symb)
        dddy = dys[3]
        Fddy = lambda t, y: J(t, y) * dys[2](t, y)

        newton_tol = 1e-10

        # tmax varies with dt so that we can vary dt over orders of
        # magnitude.
        tmax = 50 * dt

        # Run ode solver
        if implicit:
            ts, ys = ode._odeint(
                residual, [0.0], [sp.array([exact(0.0)], ndmin=1)],
                dt,
                tmax,
                method_residual,
                target_error=None,
                time_adaptor=ode.create_random_time_adaptor(base_dt),
                initialisation_actions=par(ode.higher_order_start, 3),
                newton_tol=newton_tol)

        else:
            ts, ys = ode.odeint_explicit(
                dys[1],
                exact(0.0),
                base_dt,
                tmax,
                method_residual,
                time_adaptor=ode.create_random_time_adaptor(base_dt))

        dts = utils.ts2dts(ts)

        # Check it's accurate-ish
        exact_ys = map(exact, ts)
        errors = map(op.sub, exact_ys, ys)
        utils.assert_list_almost_zero(errors, 1e-3)

        # Calculate ltes by two methods. Note that we need to drop a few
        # values because exact calculation (may) need a few dts. Could be
        # dodgy: exact dddys might not correspond to dddy in experiment if
        # done over long time and we've wandered away from the solution.
        exact_dddys = map(dddy, ts, ys)
        exact_Fddys = map(Fddy, ts, ys)
        exact_ltes = map(lte, dts[2:], dts[1:-1], dts[:-2], exact_dddys[3:],
                         exact_Fddys[3:])
        error_diff_ltes = map(op.sub, errors[1:], errors[:-1])[2:]

        # Print for debugging when something goes wrong
        print exact_ltes
        print error_diff_ltes

        # Probably the best test is that they give the same order of
        # magnitude and the same sign... Can't test much more than that
        # because we have no idea what the constant in front of the dt**4
        # term is. Effective zero (noise level) is either dt**4 or newton
        # tol, whichever is larger.
        z = 50 * max(dt**4, newton_tol)
        map(par(utils.assert_same_sign, fp_zero=z), exact_ltes,
            error_diff_ltes)
        map(par(utils.assert_same_order_of_magnitude, fp_zero=z), exact_ltes,
            error_diff_ltes)