Exemple #1
0
def test_R18(const):
    def odefun(X, u, p, const):
        return -X[0] / const[0]

    def quadfun(X, u, p, const):
        return X[0]

    def bcfun(X0, q0, u0, Xf, qf, uf, p, ndp, const):
        return q0[0] - 1, qf[0] - np.exp(-1 / const[0])

    algo = Shooting(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)
Exemple #2
0
def test_Shooting_4():
    # This problem contains a quad and tests if the bvp solver correctly
    # integrates the quadfun. Also tests multiple shooting.

    def odefun(x, u, p, const):
        return -x[1], x[0]

    def quadfun(x, u, p, const):
        return x[0]

    def bcfun(X0, q0, u0, Xf, qf, uf, params, ndp, const):
        return X0[0], X0[1] - 1, qf[0] - 1.0

    algo = Shooting(odefun, quadfun, bcfun, num_arcs=4)
    solinit = Trajectory()
    solinit.t = np.linspace(0, np.pi / 2, 2)
    solinit.y = np.array([[1, 0], [1, 0]])
    solinit.q = np.array([[0], [0]])
    solinit.const = np.array([])
    out = algo.solve(solinit)['sol']
    assert (out.y[0, 0] - 0) < tol
    assert (out.y[0, 1] - 1) < tol
    assert (out.q[0, 0] - 2) < tol
    assert (out.q[-1, 0] - 1) < tol
Exemple #3
0
def test_R8(const):
    def odefun(X, u, p, const):
        return -X[0] / const[0]

    def quadfun(X, u, p, const):
        return X[0]

    def bcfun(X0, q0, u0, Xf, qf, uf, p, ndp, const):
        return q0[0] - 1, qf[0] - 2

    algo = Shooting(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)
Exemple #4
0
    def solve(self, solinit, **kwargs):

        solinit = copy.deepcopy(solinit)
        nstates = solinit.y.shape[1]

        def return_nil(*args, **kwargs):
            return np.array([])

        if solinit.q.size > 0:
            nquads = solinit.q.shape[1]
        else:
            nquads = 0
            self.quadrature_function = return_nil

        ndyn = solinit.dynamical_parameters.size
        nnondyn = solinit.nondynamical_parameters.size

        def _fun(t, y, params=np.array([]), const=solinit.const):
            y = y.T
            o1 = np.vstack([
                self.derivative_function(yi[:nstates], np.array([]),
                                         params[:ndyn], const) for yi in y
            ])
            o2 = np.vstack([
                self.quadrature_function(yi[:nstates], np.array([]),
                                         params[:ndyn], const) for yi in y
            ])
            return np.hstack((o1, o2)).T

        # TODO: The way parameters are used is inconsitent
        def _bc(ya, yb, params=np.array([]), const=solinit.const):
            return self.boundarycondition_function(
                ya[:nstates], ya[nstates:nstates + nquads], np.array(
                    ()), yb[:nstates], yb[nstates:nstates + nquads],
                np.array(()), params[:ndyn], params[ndyn:ndyn + nnondyn],
                const)

        if self.derivative_function_jac is not None:

            def _fun_jac(t, y, params=np.array([]), const=solinit.const):
                y = y.T
                df_dy = np.zeros((y[0].size, y[0].size, t.size))
                df_dp = np.zeros((y[0].size, ndyn + nnondyn, t.size))

                for ii, yi in enumerate(y):
                    df_dy[:, :, ii], _df_dp = self.derivative_function_jac(
                        yi, np.array([]), params[:ndyn], const)
                    if nstates > 1 and len(_df_dp.shape) == 1:
                        _df_dp = np.array([_df_dp]).T

                    df_dp[:, :, ii] = np.hstack(
                        (_df_dp, np.zeros((nstates, nnondyn))))

                if ndyn + nnondyn == 0:
                    return df_dy
                else:
                    return df_dy, df_dp
        else:
            _fun_jac = None

        if self.boundarycondition_function_jac is not None:

            def _bc_jac(ya, yb, params=np.array([]), const=solinit.const):
                dbc_dya, dbc_dyb, dbc_dp = self.boundarycondition_function_jac(
                    ya, yb, np.array([]), params, const)
                return dbc_dya, dbc_dyb, dbc_dp
        else:
            _bc_jac = None

        if nquads > 0:
            opt = solve_bvp(_fun,
                            _bc,
                            solinit.t,
                            np.hstack((solinit.y, solinit.q)).T,
                            np.hstack((solinit.dynamical_parameters,
                                       solinit.nondynamical_parameters)),
                            max_nodes=self.max_nodes,
                            fun_jac=_fun_jac,
                            bc_jac=_bc_jac)
        else:
            opt = solve_bvp(_fun,
                            _bc,
                            solinit.t,
                            solinit.y.T,
                            np.hstack((solinit.dynamical_parameters,
                                       solinit.nondynamical_parameters)),
                            max_nodes=self.max_nodes,
                            fun_jac=_fun_jac,
                            bc_jac=_bc_jac)

        sol = Trajectory(solinit)
        sol.t = opt['x']
        sol.y = opt['y'].T[:, :nstates]
        sol.q = opt['y'].T[:, nstates:nstates + nquads]
        sol.dual = np.zeros_like(sol.y)
        if opt['p'] is not None:
            sol.dynamical_parameters = opt['p'][:ndyn]
            sol.nondynamical_parameters = opt['p'][ndyn:ndyn + nnondyn]
        else:
            sol.dynamical_parameters = np.array([])
            sol.nondynamical_parameters = np.array([])

        sol.converged = opt['success']
        out = BVPResult(sol=sol,
                        success=opt['success'],
                        message=opt['message'],
                        rms_residuals=opt['rms_residuals'],
                        niter=opt['niter'])

        return out