Ejemplo n.º 1
0
def bdf2_imr_ptinfos(pt):
    # assert pt == sRat(1,2)
    return [
        PTInfo(pt.time, None, "imr"),
        PTInfo(pt.time + sRat(1, 2) + 1, "corr_val", None),
        PTInfo(pt.time + sRat(1, 2) + 2, "corr_val", None)
    ]
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
Ejemplo n.º 3
0
def test_exact_predictors():
    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

    exacts = [
        sympy.exp(St),
        sympy.sin(St),
    ]

    exact_predictors = [
        ([PTInfo(0, None, None),
          PTInfo(sRat(1, 2), None, None)], "use exact dddy"),
        ([PTInfo(0, None, None),
          PTInfo(sRat(1, 2), None, None)], "use exact Fddy"),
    ]

    for exact in exacts:
        for p in exact_predictors:
            yield check_exact_predictors, exact, p
def test_exact_predictors():

    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

    exacts = [sympy.exp(St),
              sympy.sin(St),
              ]

    exact_predictors = [
        ([PTInfo(0, None, None),
          PTInfo(sRat(1, 2), None, None)],
         "use exact dddy"),

        ([PTInfo(0, None, None),
          PTInfo(sRat(1, 2), None, None)],
         "use exact Fddy"),
    ]

    for exact in exacts:
        for p in exact_predictors:
            yield check_exact_predictors, exact, p
Ejemplo n.º 5
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))
    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))
Ejemplo n.º 7
0
def test_t_at_time_point():
    tests = [
        0,
        1,
        sRat(1, 2),
        sRat(3, 2),
        1 + sRat(1, 2),
        sRat(4, 5),
    ]
    ts = range(11)
    for pt in tests:
        utils.assert_almost_equal(t_at_time_point(ts, pt), 10 - pt)
def test_is_half_integer():

    tests = [(0, False),
             (1239012424481273, False),
             (sRat(1, 2), True),
             (1.5, True),
             (sRat(5, 2), True),
             (2.0 + sRat(1, 2), True),
             (1.5 + 1e-15, False),  # 1e-16 fails (gives true)
             (1.51, False),
             ]

    for t, result in tests:
        assert is_half_integer(t) == result
Ejemplo n.º 9
0
def test_is_half_integer():

    tests = [
        (0, False),
        (1239012424481273, False),
        (sRat(1, 2), True),
        (1.5, True),
        (sRat(5, 2), True),
        (2.0 + sRat(1, 2), True),
        (1.5 + 1e-15, False),  # 1e-16 fails (gives true)
        (1.51, False),
    ]

    for t, result in tests:
        assert is_half_integer(t) == result
Ejemplo n.º 10
0
def rational_as_mixed(x):
    """Convert a rational number to (integer_part, remainder_as_fraction)
    """
    assert is_rational(x)  # Don't want to accidentally end up with floats
    # in here as very long rationals!
    x_int = int(x)
    return x_int, sRat(x - x_int)
def rational_as_mixed(x):
    """Convert a rational number to (integer_part, remainder_as_fraction)
    """
    assert is_rational(x)  # Don't want to accidentally end up with floats
                          # in here as very long rationals!
    x_int = int(x)
    return x_int, sRat(x - x_int)
def test_const_step_explicit():

    # Get explicit BDF2 (implicit midpoint)'s dydt approximation G&S pg 715
    a = sympy.solve(-y0 + y1 + (1 + Delta0/Delta1)*Delta0*Dy1
                    - (Delta0/Delta1)**2*(y1 - y2), Dy1)
    assert(len(a) == 1)
    IMR_bdf_form = a[0].subs({k: Delta0 for k in dts})

    orders = [1, 2, 3]
    exacts = [(y0 - y1)/Delta0,
              IMR_bdf_form,
              #Hairer pg 364
              (sRat(1, 3)*y0 + sRat(1, 2)*y1 - y2 + sRat(1, 6)*y3)/Delta0
              ]

    for order, exact in zip(orders, exacts):
        yield check_const_step, order, exact, 1
def test_const_step_explicit():

    # Get explicit BDF2 (implicit midpoint)'s dydt approximation G&S pg 715
    a = sympy.solve(-y0 + y1 + (1 + Delta0/Delta1)*Delta0*Dy1
                    - (Delta0/Delta1)**2*(y1 - y2), Dy1)
    assert(len(a) == 1)
    IMR_bdf_form = a[0].subs({k: Delta0 for k in dts})

    orders = [1, 2, 3]
    exacts = [(y0 - y1)/Delta0,
              IMR_bdf_form,
              #Hairer pg 364
              (sRat(1, 3)*y0 + sRat(1, 2)*y1 - y2 + sRat(1, 6)*y3)/Delta0
              ]

    for order, exact in zip(orders, exacts):
        yield check_const_step, order, exact, 1
Ejemplo n.º 14
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_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_const_step_implicit():
    """Check that the implicit methods are correct for fixed step size by
    comparison with Hairer et. al. 1991 pg 366.
    """

    exacts = [(y0 - y1)/Delta0,
              (sRat(3, 2)*y0 - 2*y1 + sRat(1, 2)*y2)/Delta0,
              (sRat(11, 6)*y0 - 3*y1 + sRat(3, 2)*y2 - sRat(1, 3)*y3)/Delta0,
              (sRat(25, 12)*y0 - 4*y1 + 3*y2 - sRat(4, 3)*y3 + sRat(1, 4)*y4)/Delta0]

    orders = [1, 2, 3, 4]

    for order, exact in zip(orders, exacts):
        yield check_const_step, order, exact, 0
def test_const_step_implicit():
    """Check that the implicit methods are correct for fixed step size by
    comparison with Hairer et. al. 1991 pg 366.
    """

    exacts = [(y0 - y1)/Delta0,
              (sRat(3, 2)*y0 - 2*y1 + sRat(1, 2)*y2)/Delta0,
              (sRat(11, 6)*y0 - 3*y1 + sRat(3, 2)*y2 - sRat(1, 3)*y3)/Delta0,
              (sRat(25, 12)*y0 - 4*y1 + 3*y2 - sRat(4, 3)*y3 + sRat(1, 4)*y4)/Delta0]

    orders = [1, 2, 3, 4]

    for order, exact in zip(orders, exacts):
        yield check_const_step, order, exact, 0
Ejemplo n.º 18
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
Ejemplo n.º 19
0
def ptinfo2dyfunc(pt, dydt_func):
    """Construct a python function to calculate the approximation to dy
    requested. If not using "exact" for dy_est the dydt_func can/should
    be None.
    """

    # Use the dy estimate from implicit midpoint rule (obviously only works
    # at the midpoint).
    if pt.dy_est == "imr":
        if not is_half_integer(pt.time):
            raise ValueError(
                "imr dy approximation Only works for half integer " +
                "points but given the point " + str(pt.time))

        # Need to drop some of the later time values if time point is
        # not the midpoint of 0 and 1 points (i.e. 1/2). Specifically, we
        # need:
        # 1/2 -> ts[:None]
        # 3/2 -> ts[:-1]
        # 5/2 -> ts[:-2]
        if pt.time == sRat(1, 2):
            # dy_func = ode.imr_dydt
            def dy_func(ts, ys):
                val = ode.imr_dydt(ts, ys)
                print "imr f(t) =", val
                return val
        else:
            x = -math.floor(pt.time)

            def dy_func(ts, ys):
                val = ode.imr_dydt(ts[:-int(math.floor(pt.time))],
                                   ys[:-int(math.floor(pt.time))])
                print "imr f(t) =", val
                return val

    elif pt.dy_est == "fd4":

        def dy_func(ts, ys):
            coeffs = [-1 / 12, -2 / 3, 0, 2 / 3, -1 / 12]
            ys_used = ys[-6:-1]

            assert len(ys) >= 6

            # ??ds only for constant step! with variable steps we can put
            # the 0 at a midpoint to reduce n-prev-steps needed.

            return sp.dot(coeffs, ys_used)

    # ??ds Use real dydt for exp
    elif pt.dy_est == "exp test":

        def dy_func(ts, ys):
            return ys[-(pt.time + 1)]

    # Use the provided f with known values to calculate dydt. Only for
    # integer time points (i.e. where we already know y etc.) for now.
    elif pt.dy_est == "exact":
        assert dydt_func is not None

        if is_integer(pt.time):
            dy_func = lambda ts, ys: dydt_func(ts[pt.time])
        else:
            # Can't get y without additional approximations...
            def dy_func(ts, ys):
                val = dydt_func(t_at_time_point(ts, pt.time))
                print "f(t) =", val
                return val

    # None = "this value at this point should not be used"
    elif pt.dy_est is None:
        dy_func = None

    else:
        raise ValueError("Unrecognised dy_est name in function construction " +
                         str(pt.dy_est))

    return dy_func
def ptinfo2dyfunc(pt, dydt_func):
    """Construct a python function to calculate the approximation to dy
    requested. If not using "exact" for dy_est the dydt_func can/should
    be None.
    """

    # Use the dy estimate from implicit midpoint rule (obviously only works
    # at the midpoint).
    if pt.dy_est == "imr":
        if not is_half_integer(pt.time):
            raise ValueError("imr dy approximation Only works for half integer "
                             + "points but given the point " + str(pt.time))

        # Need to drop some of the later time values if time point is
        # not the midpoint of 0 and 1 points (i.e. 1/2). Specifically, we
        # need:
        # 1/2 -> ts[:None]
        # 3/2 -> ts[:-1]
        # 5/2 -> ts[:-2]
        if pt.time == sRat(1, 2):
            # dy_func = ode.imr_dydt
            def dy_func(ts, ys):
                val = ode.imr_dydt(ts, ys)
                print "imr f(t) =", val
                return val
        else:
            x = -math.floor(pt.time)

            def dy_func(ts, ys):
                val = ode.imr_dydt(ts[:-int(math.floor(pt.time))],
                                   ys[:-int(math.floor(pt.time))])
                print "imr f(t) =", val
                return val

    elif pt.dy_est == "fd4":
        def dy_func(ts, ys):
            coeffs = [-1/12, -2/3, 0, 2/3, -1/12]
            ys_used = ys[-6:-1]

            assert len(ys) >= 6

            # ??ds only for constant step! with variable steps we can put
            # the 0 at a midpoint to reduce n-prev-steps needed.

            return sp.dot(coeffs, ys_used)

    # ??ds Use real dydt for exp
    elif pt.dy_est == "exp test":
        def dy_func(ts, ys):
            return ys[-(pt.time+1)]

    # Use the provided f with known values to calculate dydt. Only for
    # integer time points (i.e. where we already know y etc.) for now.
    elif pt.dy_est == "exact":
        assert dydt_func is not None

        if is_integer(pt.time):
            dy_func = lambda ts, ys: dydt_func(ts[pt.time])
        else:
            # Can't get y without additional approximations...
            def dy_func(ts, ys):
                val = dydt_func(t_at_time_point(ts, pt.time))
                print "f(t) =", val
                return val

    # None = "this value at this point should not be used"
    elif pt.dy_est is None:
        dy_func = None

    else:
        raise ValueError(
            "Unrecognised dy_est name in function construction " + str(pt.dy_est))

    return dy_func
def bdf3_imr_ptinfos(pt):
    # assert pt == sRat(1,2)
    return [PTInfo(pt.time, None, "imr"),
            PTInfo(pt.time + sRat(1, 2), "corr_val", None),
            PTInfo(pt.time + sRat(1, 2) + 1, "corr_val", None),
            PTInfo(pt.time + sRat(1, 2) + 2, "corr_val", None)]
def test_t_at_time_point():
    tests = [0, 1, sRat(1, 2), sRat(3, 2), 1 + sRat(1, 2), sRat(4, 5), ]
    ts = range(11)
    for pt in tests:
        utils.assert_almost_equal(t_at_time_point(ts, pt), 10 - pt)
def is_half_integer(x):
    return x == (math.floor(x) + float(sRat(1, 2)))
Ejemplo n.º 24
0
def is_half_integer(x):
    return x == (math.floor(x) + float(sRat(1, 2)))