def check_exact_predictors(exact, predictor):
        p1_func, y_np1_p1_expr = \
            generate_predictor_scheme(*predictor, symbolic=exact)

        # LTE for IMR: just natural lte:
        y_np1_imr_expr = y_np1_exact - imr_lte(Sdts[0], Sdddynph, SFddynph)

        # Generate another predictor
        p2_func, y_np1_p2_expr = \
            generate_predictor_scheme([PTInfo(sRat(1, 2), None, "imr"),
                                       PTInfo(2, "corr_val", None),
                                       PTInfo(3, "corr_val", None)], "ibdf2")

        A = system2matrix([y_np1_p1_expr, y_np1_p2_expr, y_np1_imr_expr],
                          [Sdddynph, SFddynph, y_np1_exact])

        # Solve for dddy and Fddy:
        x = A.inv()
        dddy_symb = sum([y_est * xi.factor() for xi, y_est in
                         zip(x.row(0), [y_np1_p1, y_np1_p2, y_np1_imr])])
        Fddy_symb = sum([y_est * xi.factor() for xi, y_est in
                         zip(x.row(1), [y_np1_p1, y_np1_p2, y_np1_imr])])

        # Check we got the right matrix and the right formulae
        if predictor[1] == "use exact dddy":
            assert A.row(0) == sympy.Matrix([[1, 0, 0]]).row(0)
            utils.assert_sym_eq(dddy_symb.simplify(), y_np1_p1)

        elif predictor[1] == "use exact Fddy":
            assert A.row(0) == sympy.Matrix([[0, 1, 0]]).row(0)
            utils.assert_sym_eq(Fddy_symb.simplify(), y_np1_p1)
        else:
            assert False
def test_sum_dts():

    # Check a simple fractional case
    utils.assert_sym_eq(sum_dts(sRat(1, 2), 1), Sdts[0]/2)

    # Check two numbers the same gives zero always
    utils.assert_sym_eq(sum_dts(1, 1), 0)
    utils.assert_sym_eq(sum_dts(0, 0), 0)
    utils.assert_sym_eq(sum_dts(sRat(1, 2), sRat(1, 2)), 0)

    def check_sum_dts(a, b):

        # Check we can swap the sign
        utils.assert_sym_eq(sum_dts(a, b), -sum_dts(b, a))

        # Starting half a step earlier
        utils.assert_sym_eq(sum_dts(a, b + sRat(1, 2)),
                            sRat(1, 2)*Sdts[int(b)] + sum_dts(a, b))

        # Check that we can split it up
        utils.assert_sym_eq(sum_dts(a, b),
                            sum_dts(a, b-1) + sum_dts(b-1, b))

    # Make sure b>=1 or the last check will fail due to negative b.
    cases = [(0, 1),
             (5, 8),
             (sRat(1, 2), 3),
             (sRat(2, 2), 3),
             (sRat(3, 2), 3),
             (0, sRat(9, 7)),
             (sRat(3/4), sRat(9, 7)),
             ]

    for a, b in cases:
        yield check_sum_dts, a, b
def test_imr_predictor_equivalence():
    # Check the we generate imr's lte if we plug in the right times and
    # approximations to ebdf2 (~explicit midpoint rule).
    ynp1_imr = y_np1_exact - imr_lte(Sdts[0], Sdddynph, SFddynph)

    _, ynp1_p1 = generate_predictor_scheme([PTInfo(0, None, None),
                                            PTInfo(
                                                sRat(1, 2), "bdf2 imr", "imr"),
                                            PTInfo(1, "corr_val", None)],
                                           "ebdf2")
    utils.assert_sym_eq(ynp1_imr, ynp1_p1)

    # Should be exactly the same with ebdf to calculate the y-est at the
    # midpoint (because the midpoint value is ignored).
    _, ynp1_p2 = generate_predictor_scheme([PTInfo(0, None, None),
                                            PTInfo(
                                                sRat(1, 2), "bdf3 imr", "imr"),
                                            PTInfo(1, "corr_val", None)],
                                           "ebdf2")
    utils.assert_sym_eq(ynp1_imr, ynp1_p2)
예제 #4
0
def test_imr_predictor_equivalence():
    # Check the we generate imr's lte if we plug in the right times and
    # approximations to ebdf2 (~explicit midpoint rule).
    ynp1_imr = y_np1_exact - imr_lte(Sdts[0], Sdddynph, SFddynph)

    _, ynp1_p1 = generate_predictor_scheme([
        PTInfo(0, None, None),
        PTInfo(sRat(1, 2), "bdf2 imr", "imr"),
        PTInfo(1, "corr_val", None)
    ], "ebdf2")
    utils.assert_sym_eq(ynp1_imr, ynp1_p1)

    # Should be exactly the same with ebdf to calculate the y-est at the
    # midpoint (because the midpoint value is ignored).
    _, ynp1_p2 = generate_predictor_scheme([
        PTInfo(0, None, None),
        PTInfo(sRat(1, 2), "bdf3 imr", "imr"),
        PTInfo(1, "corr_val", None)
    ], "ebdf2")
    utils.assert_sym_eq(ynp1_imr, ynp1_p2)
def test_symbolic_compare_step_time_residual():

    # Define the symbols we need
    St = sympy.symbols('t')
    Sdts = sympy.symbols('Delta0:9')
    Sys = sympy.symbols('y0:9')
    Sdys = sympy.symbols('dy0:9')

    # Generate the stuff needed to run the residual
    def fake_eqn_residual(ts, ys, dy):
        return Sdys[0] - dy
    fake_ts = utils.dts2ts(St, Sdts[::-1])
    fake_ys = Sys[::-1]

    # Check bdf2
    step_result_bdf2 = ibdf2_step(Sdts[0], Sys[1], Sdys[0], Sdts[1], Sys[2])
    res_result_bdf2 = bdf2_residual(fake_eqn_residual, fake_ts, fake_ys)
    res_bdf2_step = sympy.solve(res_result_bdf2, Sys[0])

    assert len(res_bdf2_step) == 1
    utils.assert_sym_eq(res_bdf2_step[0], step_result_bdf2)
예제 #6
0
def test_symbolic_compare_step_time_residual():

    # Define the symbols we need
    St = sympy.symbols('t')
    Sdts = sympy.symbols('Delta0:9')
    Sys = sympy.symbols('y0:9')
    Sdys = sympy.symbols('dy0:9')

    # Generate the stuff needed to run the residual
    def fake_eqn_residual(ts, ys, dy):
        return Sdys[0] - dy

    fake_ts = utils.dts2ts(St, Sdts[::-1])
    fake_ys = Sys[::-1]

    # Check bdf2
    step_result_bdf2 = ibdf2_step(Sdts[0], Sys[1], Sdys[0], Sdts[1], Sys[2])
    res_result_bdf2 = bdf2_residual(fake_eqn_residual, fake_ts, fake_ys)
    res_bdf2_step = sympy.solve(res_result_bdf2, Sys[0])

    assert len(res_bdf2_step) == 1
    utils.assert_sym_eq(res_bdf2_step[0], step_result_bdf2)
def test_bdf2_ebdf2_scheme_generation():
    """Make sure adaptive bdf2 can be derived using same methodology as I'm
    using (also checks lte expressions).
    """

    dddy = sympy.symbols("y'''")
    y_np1_bdf2 = sympy.symbols("y_{n+1}_bdf2")

    y_np1_ebdf2_expr = y_np1_exact - ebdf2_lte(Sdts[0], Sdts[1], dddy)
    y_np1_bdf2_expr = y_np1_exact - bdf2_lte(Sdts[0], Sdts[1], dddy)

    A = system2matrix([y_np1_ebdf2_expr, y_np1_bdf2_expr], [dddy, y_np1_exact])
    x = A.inv()

    exact_ynp1_symb = sum([y_est * xi.factor() for xi, y_est in
                           zip(x.row(1), [y_np1_p1, y_np1_bdf2])])

    answer = -(Sdts[1] + Sdts[0])*(
        y_np1_bdf2 - y_np1_p1)/(3*Sdts[0] + 2*Sdts[1])

    utils.assert_sym_eq(exact_ynp1_symb - y_np1_bdf2,
                        answer)
예제 #8
0
def test_bdf2_ebdf2_scheme_generation():
    """Make sure adaptive bdf2 can be derived using same methodology as I'm
    using (also checks lte expressions).
    """

    dddy = sympy.symbols("y'''")
    y_np1_bdf2 = sympy.symbols("y_{n+1}_bdf2")

    y_np1_ebdf2_expr = y_np1_exact - ebdf2_lte(Sdts[0], Sdts[1], dddy)
    y_np1_bdf2_expr = y_np1_exact - bdf2_lte(Sdts[0], Sdts[1], dddy)

    A = system2matrix([y_np1_ebdf2_expr, y_np1_bdf2_expr], [dddy, y_np1_exact])
    x = A.inv()

    exact_ynp1_symb = sum([
        y_est * xi.factor()
        for xi, y_est in zip(x.row(1), [y_np1_p1, y_np1_bdf2])
    ])

    answer = -(Sdts[1] + Sdts[0]) * (y_np1_bdf2 - y_np1_p1) / (3 * Sdts[0] +
                                                               2 * Sdts[1])

    utils.assert_sym_eq(exact_ynp1_symb - y_np1_bdf2, answer)
예제 #9
0
    def check_exact_predictors(exact, predictor):
        p1_func, y_np1_p1_expr = \
            generate_predictor_scheme(*predictor, symbolic=exact)

        # LTE for IMR: just natural lte:
        y_np1_imr_expr = y_np1_exact - imr_lte(Sdts[0], Sdddynph, SFddynph)

        # Generate another predictor
        p2_func, y_np1_p2_expr = \
            generate_predictor_scheme([PTInfo(sRat(1, 2), None, "imr"),
                                       PTInfo(2, "corr_val", None),
                                       PTInfo(3, "corr_val", None)], "ibdf2")

        A = system2matrix([y_np1_p1_expr, y_np1_p2_expr, y_np1_imr_expr],
                          [Sdddynph, SFddynph, y_np1_exact])

        # Solve for dddy and Fddy:
        x = A.inv()
        dddy_symb = sum([
            y_est * xi.factor()
            for xi, y_est in zip(x.row(0), [y_np1_p1, y_np1_p2, y_np1_imr])
        ])
        Fddy_symb = sum([
            y_est * xi.factor()
            for xi, y_est in zip(x.row(1), [y_np1_p1, y_np1_p2, y_np1_imr])
        ])

        # Check we got the right matrix and the right formulae
        if predictor[1] == "use exact dddy":
            assert A.row(0) == sympy.Matrix([[1, 0, 0]]).row(0)
            utils.assert_sym_eq(dddy_symb.simplify(), y_np1_p1)

        elif predictor[1] == "use exact Fddy":
            assert A.row(0) == sympy.Matrix([[0, 1, 0]]).row(0)
            utils.assert_sym_eq(Fddy_symb.simplify(), y_np1_p1)
        else:
            assert False
    def check_sum_dts(a, b):

        # Check we can swap the sign
        utils.assert_sym_eq(sum_dts(a, b), -sum_dts(b, a))

        # Starting half a step earlier
        utils.assert_sym_eq(sum_dts(a, b + sRat(1, 2)),
                            sRat(1, 2)*Sdts[int(b)] + sum_dts(a, b))

        # Check that we can split it up
        utils.assert_sym_eq(sum_dts(a, b),
                            sum_dts(a, b-1) + sum_dts(b-1, b))
예제 #11
0
    def check_sum_dts(a, b):

        # Check we can swap the sign
        utils.assert_sym_eq(sum_dts(a, b), -sum_dts(b, a))

        # Starting half a step earlier
        utils.assert_sym_eq(sum_dts(a, b + sRat(1, 2)),
                            sRat(1, 2) * Sdts[int(b)] + sum_dts(a, b))

        # Check that we can split it up
        utils.assert_sym_eq(sum_dts(a, b),
                            sum_dts(a, b - 1) + sum_dts(b - 1, b))
예제 #12
0
def test_sum_dts():

    # Check a simple fractional case
    utils.assert_sym_eq(sum_dts(sRat(1, 2), 1), Sdts[0] / 2)

    # Check two numbers the same gives zero always
    utils.assert_sym_eq(sum_dts(1, 1), 0)
    utils.assert_sym_eq(sum_dts(0, 0), 0)
    utils.assert_sym_eq(sum_dts(sRat(1, 2), sRat(1, 2)), 0)

    def check_sum_dts(a, b):

        # Check we can swap the sign
        utils.assert_sym_eq(sum_dts(a, b), -sum_dts(b, a))

        # Starting half a step earlier
        utils.assert_sym_eq(sum_dts(a, b + sRat(1, 2)),
                            sRat(1, 2) * Sdts[int(b)] + sum_dts(a, b))

        # Check that we can split it up
        utils.assert_sym_eq(sum_dts(a, b),
                            sum_dts(a, b - 1) + sum_dts(b - 1, b))

    # Make sure b>=1 or the last check will fail due to negative b.
    cases = [
        (0, 1),
        (5, 8),
        (sRat(1, 2), 3),
        (sRat(2, 2), 3),
        (sRat(3, 2), 3),
        (0, sRat(9, 7)),
        (sRat(3 / 4), sRat(9, 7)),
    ]

    for a, b in cases:
        yield check_sum_dts, a, b
def test_tr_ab2_scheme_generation():
    """Make sure tr-ab can be derived using same methodology as I'm using
    (also checks lte expressions).
    """

    dddy = sympy.symbols("y'''")
    y_np1_tr = sympy.symbols("y_{n+1}_tr")

    ab_pred, ynp1_ab2_expr = generate_predictor_scheme([PTInfo(0, None, None),
                                                        PTInfo(
                                                            1,
                                                            "corr_val",
                                                            "exp test"),
                                                        PTInfo(
                                                            2, "corr_val", "exp test")],
                                                       "ab2",
                                                       symbolic=sympy.exp(St))

    # ??ds hacky, have to change the symbol to represent where y''' is being
    # evaluated by hand!
    ynp1_ab2_expr = ynp1_ab2_expr.subs(Sdddynph, dddy)

    # Check that it gives the same result as we know from the lte
    utils.assert_sym_eq(y_np1_exact - ab2_lte(Sdts[0], Sdts[1], dddy),
                        ynp1_ab2_expr)

    # Now do the solve etc.
    y_np1_tr_expr = y_np1_exact - tr_lte(Sdts[0], dddy)
    A = system2matrix([ynp1_ab2_expr, y_np1_tr_expr], [dddy, y_np1_exact])
    x = A.inv()

    exact_ynp1_symb = sum([y_est * xi.factor() for xi, y_est in
                           zip(x.row(1), [y_np1_p1, y_np1_tr])])

    exact_ynp1_f = sympy.lambdify(
        (y_np1_p1,
         y_np1_tr,
         Sdts[0],
         Sdts[1]),
        exact_ynp1_symb)

    utils.assert_sym_eq(exact_ynp1_symb - y_np1_tr,
                        (y_np1_p1 - y_np1_tr)/(3*(1 + Sdts[1]/Sdts[0])))

    # Construct an lte estimator from this estimate
    def lte_est(ts, ys):
        ynp1_p = ab_pred(ts, ys)

        dtn = ts[-1] - ts[-2]
        dtnm1 = ts[-2] - ts[-3]

        ynp1_exact = exact_ynp1_f(ynp1_p, ys[-1], dtn, dtnm1)
        return ynp1_exact - ys[-1]

    # Solve exp using tr
    t0 = 0.0
    dt = 1e-2
    ts, ys = ode.odeint(er.exp_residual, er.exp_exact(t0),
                        tmax=2.0, dt=dt, method='tr')

    # Get error estimates using standard tr ab and the one we just
    # constructed here, then compare.
    this_ltes = ode.get_ltes_from_data(ts, ys, lte_est)

    tr_ab_lte = par(ode.tr_ab_lte_estimate, dydt_func=lambda t, y: y)
    standard_ltes = ode.get_ltes_from_data(ts, ys, tr_ab_lte)

    # Should be the same (actually the sign is different, but this doesn't
    # matter in lte).
    utils.assert_list_almost_equal(
        this_ltes, map(lambda a: a*-1, standard_ltes), 1e-8)
예제 #14
0
def test_tr_ab2_scheme_generation():
    """Make sure tr-ab can be derived using same methodology as I'm using
    (also checks lte expressions).
    """

    dddy = sympy.symbols("y'''")
    y_np1_tr = sympy.symbols("y_{n+1}_tr")

    ab_pred, ynp1_ab2_expr = generate_predictor_scheme([
        PTInfo(0, None, None),
        PTInfo(1, "corr_val", "exp test"),
        PTInfo(2, "corr_val", "exp test")
    ],
                                                       "ab2",
                                                       symbolic=sympy.exp(St))

    # ??ds hacky, have to change the symbol to represent where y''' is being
    # evaluated by hand!
    ynp1_ab2_expr = ynp1_ab2_expr.subs(Sdddynph, dddy)

    # Check that it gives the same result as we know from the lte
    utils.assert_sym_eq(y_np1_exact - ab2_lte(Sdts[0], Sdts[1], dddy),
                        ynp1_ab2_expr)

    # Now do the solve etc.
    y_np1_tr_expr = y_np1_exact - tr_lte(Sdts[0], dddy)
    A = system2matrix([ynp1_ab2_expr, y_np1_tr_expr], [dddy, y_np1_exact])
    x = A.inv()

    exact_ynp1_symb = sum([
        y_est * xi.factor()
        for xi, y_est in zip(x.row(1), [y_np1_p1, y_np1_tr])
    ])

    exact_ynp1_f = sympy.lambdify((y_np1_p1, y_np1_tr, Sdts[0], Sdts[1]),
                                  exact_ynp1_symb)

    utils.assert_sym_eq(exact_ynp1_symb - y_np1_tr,
                        (y_np1_p1 - y_np1_tr) / (3 * (1 + Sdts[1] / Sdts[0])))

    # Construct an lte estimator from this estimate
    def lte_est(ts, ys):
        ynp1_p = ab_pred(ts, ys)

        dtn = ts[-1] - ts[-2]
        dtnm1 = ts[-2] - ts[-3]

        ynp1_exact = exact_ynp1_f(ynp1_p, ys[-1], dtn, dtnm1)
        return ynp1_exact - ys[-1]

    # Solve exp using tr
    t0 = 0.0
    dt = 1e-2
    ts, ys = ode.odeint(er.exp_residual,
                        er.exp_exact(t0),
                        tmax=2.0,
                        dt=dt,
                        method='tr')

    # Get error estimates using standard tr ab and the one we just
    # constructed here, then compare.
    this_ltes = ode.get_ltes_from_data(ts, ys, lte_est)

    tr_ab_lte = par(ode.tr_ab_lte_estimate, dydt_func=lambda t, y: y)
    standard_ltes = ode.get_ltes_from_data(ts, ys, tr_ab_lte)

    # Should be the same (actually the sign is different, but this doesn't
    # matter in lte).
    utils.assert_list_almost_equal(this_ltes,
                                   map(lambda a: a * -1, standard_ltes), 1e-8)