def test_t33(const):
    def odefun(y, _, k):
        return y[1], (y[0] * y[3] - y[2] * y[1]) / k[0], y[3], y[4], y[5], (
            -y[2] * y[5] - y[0] * y[1]) / k[0]

    def odejac(y, _, k):
        df_dy = np.array(
            [[0, 1, 0, 0, 0, 0],
             [y[3] / k[0], -y[2] / k[0], -y[1] / k[0], y[0] / k[0], 0, 0],
             [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1],
             [-y[1] / k[0], -y[0] / k[0], -y[5] / k[0], 0, 0, -y[2] / k[0]]])
        df_dp = np.empty((6, 0))
        return df_dy, df_dp

    def bcfun(y0, yf, _, __, ___):
        return y0[0] + 1, y0[2], y0[3], yf[0] - 1, yf[2], yf[3]

    algo = SPBVP(odefun, None, bcfun)
    algo.set_derivative_jacobian(odejac)
    sol = Trajectory()
    sol.t = np.linspace(0, 1, 2)
    sol.y = np.array([[-1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0]])
    sol.const = np.array([const])
    sol = algo.solve(sol)['sol']

    assert sol.converged
def test_r18(const):
    def odefun(y, _, k):
        return -y[0] / k[0]

    def quadfun(y, _, __):
        return y[0]

    def bcfun(_, q0, __, qf, ___, ____, k):
        return q0[0] - 1, qf[0] - np.exp(-1 / k[0])

    algo = SPBVP(odefun, quadfun, bcfun)
    solinit = Trajectory()
    solinit.t = np.linspace(0, 1, 2)
    solinit.y = np.array([[1], [1]])
    solinit.q = np.array([[0], [0]])
    solinit.const = np.array([const])
    sol = algo.solve(solinit)['sol']

    e1 = np.exp(-sol.t / sol.const[0])
    e2 = -1 / (sol.const[0] * np.exp(sol.t / sol.const[0]))
    assert all(e1 - sol.q[:, 0] < tol)
    assert all(e2 - sol.y[:, 0] < tol)
def test_spbvp_1():
    # Full 2PBVP test problem
    # This is the simplest BVP

    def odefun(y, _, __):
        return y[1], -abs(y[0])

    def bcfun(y0, yf, _, __, ___):
        return y0[0], yf[0] + 2

    algo = SPBVP(odefun, None, bcfun)
    solinit = Trajectory()
    solinit.t = np.linspace(0, 4, 4)
    solinit.y = np.array([[0, 1], [0, 1], [0, 1], [0, 1]])
    solinit.const = np.array([])
    out = algo.solve(solinit)['sol']
    assert out.y[0][0] < tol
    assert out.y[0][1] - 2.06641646 < tol
    assert out.y[-1][0] + 2 < tol
    assert out.y[-1][1] + 2.87588998 < tol
    assert out.t[-1] - 4 < tol
    assert abs(out.y[0][1] - solinit.y[0][1]) > tol
    assert abs(out.y[-1][0] - solinit.y[-1][0]) - 2 < tol
def test_r8(const):
    def odefun(y, _, k):
        return -y[0] / k[0]

    def quadfun(y, _, __):
        return y[0]

    def bcfun(_, q0, __, qf, ___, ____, _____):
        return q0[0] - 1, qf[0] - 2

    algo = SPBVP(odefun, quadfun, bcfun)
    solinit = Trajectory()
    solinit.t = np.linspace(0, 1, 2)
    solinit.y = np.array([[1], [1]])
    solinit.q = np.array([[0], [0]])
    solinit.const = np.array([const])
    sol = algo.solve(solinit)['sol']

    e1 = (1.e0 - np.exp(
        (sol.t - 1.e0) / sol.const)) / (1.e0 - np.exp(-1.e0 / sol.const))
    e2 = np.exp((sol.t - 1) / sol.const) / (sol.const *
                                            (1 / np.exp(1 / sol.const) - 1))
    assert all(e1 - sol.q[:, 0] < tol)
    assert all(e2 - sol.y[:, 0] < tol)