def inv_map(self, sol: Solution) -> Solution: qinv = np.ones_like(sol.t) pinv = np.ones_like(sol.t) for ii, t in enumerate(sol.t): qinv[ii] = self.fn_q_inv(sol.y[ii], sol.lam[ii], sol.q[ii], sol.p, sol.k) pinv[ii] = self.fn_p_inv(sol.y[ii], sol.lam[ii], sol.p, sol.k) state = pinv qval = qinv if self.remove_parameter_dict['location'] == 'states': sol.y = np.column_stack( (sol.y[:, :self.remove_parameter_dict['index']], state, sol.y[:, self.remove_parameter_dict['index']:])) elif self.remove_parameter_dict['location'] == 'costates': sol.lam = np.column_stack( (sol.lam[:, :self.remove_parameter_dict['index']], state, sol.lam[:, self.remove_parameter_dict['index']:])) if self.remove_symmetry_dict['location'] == 'states': sol.y = np.column_stack( (sol.y[:, :self.remove_symmetry_dict['index']], qval, sol.y[:, self.remove_symmetry_dict['index']:])) elif self.remove_symmetry_dict['location'] == 'costates': sol.lam = np.column_stack( (sol.lam[:, :self.remove_symmetry_dict['index']], qval, sol.lam[:, self.remove_symmetry_dict['index']:])) sol.q = np.delete(sol.q, np.s_[-1], axis=1) sol.p = sol.p[:-1] return sol
def map(self, sol: Solution) -> Solution: cval = self.fn_p(sol.y[0], sol.lam[0], sol.p, sol.k) qval = np.ones_like(sol.t) sol.p = np.hstack((sol.p, cval)) for ii, t in enumerate(sol.t): qval[ii] = self.fn_q(sol.y[ii], sol.lam[ii], sol.p, sol.k) if self.remove_parameter_dict['location'] == 'states': sol.y = np.delete(sol.y, np.s_[self.remove_parameter_dict['index']], axis=1) elif self.remove_parameter_dict['location'] == 'costates': sol.lam = np.delete(sol.lam, np.s_[self.remove_parameter_dict['index']], axis=1) if self.remove_symmetry_dict['location'] == 'states': sol.y = np.delete(sol.y, np.s_[self.remove_symmetry_dict['index']], axis=1) elif self.remove_symmetry_dict['location'] == 'costates': sol.lam = np.delete(sol.lam, np.s_[self.remove_symmetry_dict['index']], axis=1) sol.q = np.column_stack((sol.q, qval)) return sol
def inv_map(self, sol: Solution) -> Solution: sol = copy.deepcopy(sol) if self.delta_ind_idx is None: self.delta_ind_idx = np.shape(sol.p)[0] - 1 sol.t = sol.t * sol.p[self.delta_ind_idx] sol.p = np.delete(sol.p, self.delta_ind_idx) return sol
def map(self, sol: Solution) -> Solution: sol = copy.deepcopy(sol) if self.delta_ind_idx is None: self.delta_ind_idx = np.shape(sol.p)[0] delta_t = sol.t[-1] - sol.t[0] sol.p = np.insert(sol.p, self.delta_ind_idx, delta_t) sol.t = (sol.t - sol.t[0]) / delta_t return sol
def test_spbvp_3(): # This problem contains a parameter, but it is not explicit in the BCs. # Since time is buried in the ODEs, this tests if the BVP solver calculates # sensitivities with respect to parameters. def odefun(_, p, __): return 1 * p[0] def bcfun(y0, yf, _, __, ___): return y0[0] - 0, yf[0] - 2 algo = SPBVP(odefun, None, bcfun) solinit = Trajectory() solinit.t = np.linspace(0, 1, 4) solinit.y = np.array([[0], [0], [0], [0]]) solinit.p = np.array([1]) solinit.k = np.array([]) out = algo.solve(solinit)['traj'] assert abs(out.p - 2) < tol
def scale_sol(sol: Trajectory, scale_factors, inv=False): sol = copy.deepcopy(sol) if inv: op = np.multiply else: op = np.divide sol.t = op(sol.t, scale_factors[0]) sol.y = op(sol.y, scale_factors[1]) sol.q = op(sol.q, scale_factors[2]) if sol.u.size > 0: sol.u = op(sol.u, scale_factors[3]) sol.p = op(sol.p, scale_factors[4]) sol.nu = op(sol.nu, scale_factors[5]) sol.k = op(sol.k, scale_factors[6]) return sol