예제 #1
0
def test_t_eval():
    rtol = 1e-3
    atol = 1e-6
    y0 = [1/3, 2/9]
    for t_span in ([5, 9], [5, 1]):
        t_eval = np.linspace(t_span[0], t_span[1], 10)
        res = solve_ivp(fun_rational, t_span, y0, rtol=rtol, atol=atol,
                        t_eval=t_eval)
        assert_equal(res.t, t_eval)
        assert_(res.t_events is None)
        assert_(res.success)
        assert_equal(res.status, 0)

        y_true = sol_rational(res.t)
        e = compute_error(res.y, y_true, rtol, atol)
        assert_(np.all(e < 5))

    t_eval = [5, 5.01, 7, 8, 8.01, 9]
    res = solve_ivp(fun_rational, [5, 9], y0, rtol=rtol, atol=atol,
                    t_eval=t_eval)
    assert_equal(res.t, t_eval)
    assert_(res.t_events is None)
    assert_(res.success)
    assert_equal(res.status, 0)

    y_true = sol_rational(res.t)
    e = compute_error(res.y, y_true, rtol, atol)
    assert_(np.all(e < 5))

    t_eval = [5, 4.99, 3, 1.5, 1.1, 1.01, 1]
    res = solve_ivp(fun_rational, [5, 1], y0, rtol=rtol, atol=atol,
                    t_eval=t_eval)
    assert_equal(res.t, t_eval)
    assert_(res.t_events is None)
    assert_(res.success)
    assert_equal(res.status, 0)

    t_eval = [5.01, 7, 8, 8.01]
    res = solve_ivp(fun_rational, [5, 9], y0, rtol=rtol, atol=atol,
                    t_eval=t_eval)
    assert_equal(res.t, t_eval)
    assert_(res.t_events is None)
    assert_(res.success)
    assert_equal(res.status, 0)

    y_true = sol_rational(res.t)
    e = compute_error(res.y, y_true, rtol, atol)
    assert_(np.all(e < 5))

    t_eval = [4.99, 3, 1.5, 1.1, 1.01]
    res = solve_ivp(fun_rational, [5, 1], y0, rtol=rtol, atol=atol,
                    t_eval=t_eval)
    assert_equal(res.t, t_eval)
    assert_(res.t_events is None)
    assert_(res.success)
    assert_equal(res.status, 0)

    t_eval = [4, 6]
    assert_raises(ValueError, solve_ivp, fun_rational, [5, 9], y0,
                  rtol=rtol, atol=atol, t_eval=t_eval)
예제 #2
0
def test_integration_complex():
    rtol = 1e-3
    atol = 1e-6
    y0 = [0.5 + 1j]
    t_span = [0, 1]
    tc = np.linspace(t_span[0], t_span[1])
    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        for method, jac in product(['RK23', 'RK45', 'BDF'],
                                   [None, jac_complex, jac_complex_sparse]):
            res = solve_ivp(fun_complex, t_span, y0, method=method,
                            dense_output=True, rtol=rtol, atol=atol, jac=jac)

            assert_equal(res.t[0], t_span[0])
            assert_(res.t_events is None)
            assert_(res.success)
            assert_equal(res.status, 0)

            assert_(res.nfev < 25)
            if method == 'BDF':
                assert_equal(res.njev, 1)
                assert_(res.nlu < 6)
            else:
                assert_equal(res.njev, 0)
                assert_equal(res.nlu, 0)

            y_true = sol_complex(res.t)
            e = compute_error(res.y, y_true, rtol, atol)
            assert_(np.all(e < 5))

            yc_true = sol_complex(tc)
            yc = res.sol(tc)
            e = compute_error(yc, yc_true, rtol, atol)

            assert_(np.all(e < 5))
예제 #3
0
def test_integration_const_jac():
    rtol = 1e-3
    atol = 1e-6
    y0 = [0, 2]
    t_span = [0, 2]
    J = jac_linear()
    J_sparse = csc_matrix(J)

    for method, jac in product(['Radau', 'BDF'], [J, J_sparse]):
        res = solve_ivp(fun_linear, t_span, y0, rtol=rtol, atol=atol,
                        method=method, dense_output=True, jac=jac)
        assert_equal(res.t[0], t_span[0])
        assert_(res.t_events is None)
        assert_(res.success)
        assert_equal(res.status, 0)

        assert_(res.nfev < 100)
        assert_equal(res.njev, 0)
        assert_(0 < res.nlu < 15)

        y_true = sol_linear(res.t)
        e = compute_error(res.y, y_true, rtol, atol)
        assert_(np.all(e < 10))

        tc = np.linspace(*t_span)
        yc_true = sol_linear(tc)
        yc = res.sol(tc)

        e = compute_error(yc, yc_true, rtol, atol)
        assert_(np.all(e < 15))

        assert_allclose(res.sol(res.t), res.y, rtol=1e-14, atol=1e-14)
예제 #4
0
def test_equilibrium():
    def fun(t, y):
        kf = 0.2
        kr = 0.5

        a, b, c = y

        rf = kf * a * b
        rr = kr * c

        return [
            -rf + rr,
            -rf + rr,
            rf - rr,
        ]

    ic = [4, 3, 0]

    dynamic_reference = None
    known_reference = [4 - 3 / 2, 3 - 3 / 2, 3 / 2]  # Calculated by hand

    for method in all_methods:
        sol = solve_ivp(fun, ic, 0, 100, method=method)
        dynamic_result = sol(1.5)
        if dynamic_reference is None:
            dynamic_reference = dynamic_result
        else:
            assert_allclose(dynamic_result, dynamic_reference, rtol=1e-2)

        static_result = sol(100)
        assert_allclose(static_result, known_reference, rtol=1e-2)
예제 #5
0
def test_integration():
    rtol = 1e-3
    atol = 1e-6
    y0 = [1/3, 2/9]

    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        for vectorized, method, t_span, jac in product(
                [False, True],
                ['RK23', 'RK45', 'Radau', 'BDF', 'LSODA'],
                [[5, 9], [5, 1]],
                [None, jac_rational, jac_rational_sparse]):

            if vectorized:
                fun = fun_rational_vectorized
            else:
                fun = fun_rational

            res = solve_ivp(fun, t_span, y0, rtol=rtol,
                            atol=atol, method=method, dense_output=True,
                            jac=jac, vectorized=vectorized)
            assert_equal(res.t[0], t_span[0])
            assert_(res.t_events is None)
            assert_(res.success)
            assert_equal(res.status, 0)

            assert_(res.nfev < 40)

            if method in ['RK23', 'RK45', 'LSODA']:
                assert_equal(res.njev, 0)
                assert_equal(res.nlu, 0)
            else:
                assert_(0 < res.njev < 3)
                assert_(0 < res.nlu < 10)

            y_true = sol_rational(res.t)
            e = compute_error(res.y, y_true, rtol, atol)
            assert_(np.all(e < 5))

            tc = np.linspace(*t_span)
            yc_true = sol_rational(tc)
            yc = res.sol(tc)

            e = compute_error(yc, yc_true, rtol, atol)
            assert_(np.all(e < 5))

            tc = (t_span[0] + t_span[-1]) / 2
            yc_true = sol_rational(tc)
            yc = res.sol(tc)

            e = compute_error(yc, yc_true, rtol, atol)
            assert_(np.all(e < 5))

            # LSODA for some reasons doesn't pass the polynomial through the
            # previous points exactly after the order change. It might be some
            # bug in LSOSA implementation or maybe we missing something.
            if method != 'LSODA':
                assert_allclose(res.sol(res.t), res.y, rtol=1e-15, atol=1e-15)
예제 #6
0
    def __call__(self, model, rtol):
        def collected_ode(t, y):
            return model.f(t, y, model.k)

        sol = solve_ivp(collected_ode, [0.0, np.max(model.ts)],
                        model.y0,
                        method=self.name,
                        rtol=rtol,
                        t_eval=model.ts)

        return sol.y.transpose()
예제 #7
0
def test_solution():
    for method in all_methods:
        sol = solve_ivp(lambda t, y: -y, [2, 3], 0, 4, method=method)
        assert_equal(sol(0), [2, 3])
        assert_equal(sol(0, 1), 3)
        assert_equal(sol([0, 2, 4]).shape, (3, 2))
        assert_equal(sol([0, 2, 4], 0).shape, (3, ))
        assert_equal(sol([0, 2, 4], [0, 1]).shape, (3, 2))
        assert_equal(sol(2, [0, 1]).shape, (2, ))
        assert_raises(ValueError, sol, -1)
        assert_raises(ValueError, sol, [1, 4.00000001])
예제 #8
0
def test_events_and_infinity():
    def event(t, y):
        return y[1] - 0.1

    event.terminate = True

    for method in all_methods:
        sol = solve_ivp(lambda t, y: -y, [2, 3],
                        4,
                        np.inf,
                        method=method,
                        events=event)
        assert_allclose(sol(sol.t_events[0])[1], 0.1)
예제 #9
0
def test_integration():
    rtol = 1e-3
    atol = 1e-6
    y0 = [1/3, 2/9]

    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        for vectorized, method, t_span, jac in product(
                [False, True],
                ['RK23', 'RK45', 'Radau', 'BDF'],
                [[5, 9], [5, 1]],
                [None, jac_rational, jac_rational_sparse]):

            if vectorized:
                fun = fun_rational_vectorized
            else:
                fun = fun_rational

            res = solve_ivp(fun, t_span, y0, rtol=rtol,
                            atol=atol, method=method, dense_output=True,
                            jac=jac, vectorized=vectorized)
            assert_equal(res.t[0], t_span[0])
            assert_(res.t_events is None)
            assert_(res.success)
            assert_equal(res.status, 0)

            assert_(res.nfev < 40)

            if method in ['RK23', 'RK45']:
                assert_equal(res.njev, 0)
                assert_equal(res.nlu, 0)
            else:
                assert_(0 < res.njev < 3)
                assert_(0 < res.nlu < 10)

            y_true = sol_rational(res.t)
            e = compute_error(res.y, y_true, rtol, atol)
            assert_(np.all(e < 5))

            tc = np.linspace(*t_span)
            yc_true = sol_rational(tc)
            yc = res.sol(tc)

            e = compute_error(yc, yc_true, rtol, atol)
            assert_(np.all(e < 5))

            assert_allclose(res.sol(res.t), res.y, rtol=1e-15, atol=1e-15)
예제 #10
0
def test_integration():
    rtol = 1e-3
    atol = 1e-6
    for method in all_methods:
        for x_span in ([5, 9], [5, 1]):
            res = solve_ivp(fun_rational, [1 / 3, 2 / 9],
                            x_span[0],
                            x_span[1],
                            rtol=rtol,
                            atol=atol,
                            method=method)
            assert_equal(res.t0, x_span[0])
            assert_equal(res.tF, x_span[-1])
            assert_(res.t_events is None)

            xc = np.linspace(*x_span)
            yc_true = sol_rational(xc)
            yc = res(xc)
            assert_allclose(yc, yc_true, rtol=1e-2)
예제 #11
0
def test_max_step():
    rtol = 1e-3
    atol = 1e-6
    y0 = [1/3, 2/9]
    for method in [RK23, RK45, Radau, BDF, LSODA]:
        for t_span in ([5, 9], [5, 1]):
            res = solve_ivp(fun_rational, t_span, y0, rtol=rtol,
                            max_step=0.5, atol=atol, method=method,
                            dense_output=True)
            assert_equal(res.t[0], t_span[0])
            assert_equal(res.t[-1], t_span[-1])
            assert_(np.all(np.abs(np.diff(res.t)) <= 0.5))
            assert_(res.t_events is None)
            assert_(res.success)
            assert_equal(res.status, 0)

            y_true = sol_rational(res.t)
            e = compute_error(res.y, y_true, rtol, atol)
            assert_(np.all(e < 5))

            tc = np.linspace(*t_span)
            yc_true = sol_rational(tc)
            yc = res.sol(tc)

            e = compute_error(yc, yc_true, rtol, atol)
            assert_(np.all(e < 5))

            # See comment in test_integration.
            if method is not LSODA:
                assert_allclose(res.sol(res.t), res.y, rtol=1e-15, atol=1e-15)

            assert_raises(ValueError, method, fun_rational, t_span[0], y0,
                          t_span[1], max_step=-1)

            if method is not LSODA:
                solver = method(fun_rational, t_span[0], y0, t_span[1],
                                rtol=rtol, atol=atol, max_step=1e-20)
                message = solver.step()

                assert_equal(solver.status, 'failed')
                assert_("step size is less" in message)
                assert_raises(RuntimeError, solver.step)
예제 #12
0
def test_integration_sparse_difference():
    n = 200
    t_span = [0, 20]
    y0 = np.zeros(2 * n)
    y0[1::2] = 1
    sparsity = medazko_sparsity(n)

    for method in ['BDF', 'Radau']:
        res = solve_ivp(fun_medazko, t_span, y0, method=method,
                        jac_sparsity=sparsity)

        assert_equal(res.t[0], t_span[0])
        assert_(res.t_events is None)
        assert_(res.success)
        assert_equal(res.status, 0)

        assert_allclose(res.y[78, -1], 0.233994e-3, rtol=1e-2)
        assert_allclose(res.y[79, -1], 0, atol=1e-3)
        assert_allclose(res.y[148, -1], 0.359561e-3, rtol=1e-2)
        assert_allclose(res.y[149, -1], 0, atol=1e-3)
        assert_allclose(res.y[198, -1], 0.117374129e-3, rtol=1e-2)
        assert_allclose(res.y[199, -1], 0.6190807e-5, atol=1e-3)
        assert_allclose(res.y[238, -1], 0, atol=1e-3)
        assert_allclose(res.y[239, -1], 0.9999997, rtol=1e-2)
예제 #13
0
def test_no_integration():
    for method in ['RK23', 'RK45', 'Radau', 'BDF']:
        sol = solve_ivp(lambda t, y: -y, [4, 4], [2, 3],
                        method=method, dense_output=True)
        assert_equal(sol.sol(4), [2, 3])
예제 #14
0
def test_events():
    event_rational_3.terminal = True

    for method in ['RK23', 'RK45', 'Radau', 'BDF']:
        res = solve_ivp(fun_rational, [5, 8], [1/3, 2/9], method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.status, 0)
        assert_equal(res.t_events[0].size, 1)
        assert_equal(res.t_events[1].size, 1)
        assert_(5.3 < res.t_events[0][0] < 5.7)
        assert_(7.3 < res.t_events[1][0] < 7.7)

        event_rational_1.direction = 1
        event_rational_2.direction = 1
        res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.status, 0)
        assert_equal(res.t_events[0].size, 1)
        assert_equal(res.t_events[1].size, 0)
        assert_(5.3 < res.t_events[0][0] < 5.7)

        event_rational_1.direction = -1
        event_rational_2.direction = -1
        res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.status, 0)
        assert_equal(res.t_events[0].size, 0)
        assert_equal(res.t_events[1].size, 1)
        assert_(7.3 < res.t_events[1][0] < 7.7)

        event_rational_1.direction = 0
        event_rational_2.direction = 0

        res = solve_ivp(fun_rational, [5, 8], [1 / 3, 2 / 9], method=method,
                        events=(event_rational_1, event_rational_2,
                                event_rational_3), dense_output=True)
        assert_equal(res.status, 1)
        assert_equal(res.t_events[0].size, 1)
        assert_equal(res.t_events[1].size, 0)
        assert_equal(res.t_events[2].size, 1)
        assert_(5.3 < res.t_events[0][0] < 5.7)
        assert_(7.3 < res.t_events[2][0] < 7.5)

        # Also test that termination by event doesn't break interpolants.
        tc = np.linspace(res.t[0], res.t[-1])
        yc_true = sol_rational(tc)
        yc = res.sol(tc)
        e = compute_error(yc, yc_true, 1e-3, 1e-6)
        assert_(np.all(e < 5))

    # Test in backward direction.
    event_rational_1.direction = 0
    event_rational_2.direction = 0
    for method in ['RK23', 'RK45', 'Radau', 'BDF']:
        res = solve_ivp(fun_rational, [8, 5], [4/9, 20/81], method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.status, 0)
        assert_equal(res.t_events[0].size, 1)
        assert_equal(res.t_events[1].size, 1)
        assert_(5.3 < res.t_events[0][0] < 5.7)
        assert_(7.3 < res.t_events[1][0] < 7.7)

        event_rational_1.direction = -1
        event_rational_2.direction = -1
        res = solve_ivp(fun_rational, [8, 5], [4/9, 20/81], method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.status, 0)
        assert_equal(res.t_events[0].size, 1)
        assert_equal(res.t_events[1].size, 0)
        assert_(5.3 < res.t_events[0][0] < 5.7)

        event_rational_1.direction = 1
        event_rational_2.direction = 1
        res = solve_ivp(fun_rational, [8, 5], [4/9, 20/81], method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.status, 0)
        assert_equal(res.t_events[0].size, 0)
        assert_equal(res.t_events[1].size, 1)
        assert_(7.3 < res.t_events[1][0] < 7.7)

        event_rational_1.direction = 0
        event_rational_2.direction = 0

        res = solve_ivp(fun_rational, [8, 5], [4/9, 20/81], method=method,
                        events=(event_rational_1, event_rational_2,
                                event_rational_3), dense_output=True)
        assert_equal(res.status, 1)
        assert_equal(res.t_events[0].size, 0)
        assert_equal(res.t_events[1].size, 1)
        assert_equal(res.t_events[2].size, 1)
        assert_(7.3 < res.t_events[1][0] < 7.7)
        assert_(7.3 < res.t_events[2][0] < 7.5)

        # Also test that termination by event doesn't break interpolants.
        tc = np.linspace(res.t[-1], res.t[0])
        yc_true = sol_rational(tc)
        yc = res.sol(tc)
        e = compute_error(yc, yc_true, 1e-3, 1e-6)
        assert_(np.all(e < 5))
예제 #15
0
def test_events():
    event_rational_3.terminate = True

    for method in all_methods:
        res = solve_ivp(fun_rational, [1 / 3, 2 / 9],
                        5,
                        8,
                        method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.tF, 8)
        assert_equal(len(res.t_events[0]), 1)
        assert_equal(len(res.t_events[1]), 1)
        assert_(5.3 < res.t_events[0][0] < 5.7)
        assert_(7.3 < res.t_events[1][0] < 7.7)

        event_rational_1.direction = 1
        event_rational_2.direction = 1
        res = solve_ivp(fun_rational, [1 / 3, 2 / 9],
                        5,
                        8,
                        method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.tF, 8)
        assert_equal(len(res.t_events[0]), 1)
        assert_equal(len(res.t_events[1]), 0)
        assert_(5.3 < res.t_events[0][0] < 5.7)

        event_rational_1.direction = -1
        event_rational_2.direction = -1
        res = solve_ivp(fun_rational, [1 / 3, 2 / 9],
                        5,
                        8,
                        method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.tF, 8)
        assert_equal(len(res.t_events[0]), 0)
        assert_equal(len(res.t_events[1]), 1)
        assert_(7.3 < res.t_events[1][0] < 7.7)

        event_rational_1.direction = 0
        event_rational_2.direction = 0

        res = solve_ivp(fun_rational, [1 / 3, 2 / 9],
                        5,
                        8,
                        method=method,
                        events=(event_rational_1, event_rational_2,
                                event_rational_3))
        assert_allclose(res.tF, 7.4)
        assert_equal(len(res.t_events[0]), 1)
        assert_equal(len(res.t_events[1]), 0)
        assert_equal(len(res.t_events[2]), 1)
        assert_(5.3 < res.t_events[0][0] < 5.7)
        assert_(7.3 < res.t_events[2][0] < 7.5)

        # Also test that termination by event doesn't break interpolants.
        xc = np.linspace(res.t0, res.tF)
        yc_true = sol_rational(xc)
        yc = res(xc)
        assert_allclose(yc, yc_true, rtol=1e-2)

    # Test in backward direction.
    event_rational_1.direction = 0
    event_rational_2.direction = 0
    for method in all_methods:
        res = solve_ivp(fun_rational, [4 / 9, 20 / 81],
                        8,
                        5,
                        method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.tF, 5)
        assert_equal(len(res.t_events[0]), 1)
        assert_equal(len(res.t_events[1]), 1)
        assert_(5.3 < res.t_events[0][0] < 5.7)
        assert_(7.3 < res.t_events[1][0] < 7.7)

        event_rational_1.direction = -1
        event_rational_2.direction = -1
        res = solve_ivp(fun_rational, [4 / 9, 20 / 81],
                        8,
                        5,
                        method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.tF, 5)
        assert_equal(len(res.t_events[0]), 1)
        assert_equal(len(res.t_events[1]), 0)
        assert_(5.3 < res.t_events[0][0] < 5.7)

        event_rational_1.direction = 1
        event_rational_2.direction = 1
        res = solve_ivp(fun_rational, [4 / 9, 20 / 81],
                        8,
                        5,
                        method=method,
                        events=(event_rational_1, event_rational_2))
        assert_equal(res.tF, 5)
        assert_equal(len(res.t_events[0]), 0)
        assert_equal(len(res.t_events[1]), 1)
        assert_(7.3 < res.t_events[1][0] < 7.7)

        event_rational_1.direction = 0
        event_rational_2.direction = 0

        res = solve_ivp(fun_rational, [4 / 9, 20 / 81],
                        8,
                        5,
                        method=method,
                        events=(event_rational_1, event_rational_2,
                                event_rational_3))
        assert_allclose(res.tF, 7.4)
        assert_equal(len(res.t_events[0]), 0)
        assert_equal(len(res.t_events[1]), 1)
        assert_equal(len(res.t_events[2]), 1)
        assert_(7.3 < res.t_events[1][0] < 7.7)
        assert_(7.3 < res.t_events[2][0] < 7.5)

        # Also test that termination by event doesn't break interpolants.
        xc = np.linspace(res.t0, res.tF)
        yc_true = sol_rational(xc)
        yc = res(xc)
        assert_allclose(yc, yc_true, rtol=1e-2)
예제 #16
0
def test_no_integration():
    for method in all_methods:
        sol = solve_ivp(lambda t, y: -y, [2, 3], 4, 4, method=method)
        assert_equal(sol(4), [2, 3])
        assert_equal(sol([4, 4, 4]), [[2, 3], [2, 3], [2, 3]])