def test_integrator_comparison(): f = lambda x: np.sin(x) F = lambda x: -np.cos(x) expected_answer = F(np.pi) - F(0) a, b, N = 0, np.pi, 129000 #Lowest N for normal integrate. a, b, B = 0, np.pi, 90700 #Lowest N for mid integrate. assert (Integrator.integrate(f, a, b, N) - expected_answer < 1E-10) assert (Integrator.midpoint_integrate(f, a, b, B) - expected_answer < 1E-10) assert (numpy_integrator.integrator(f, a, b, N) - expected_answer < 1E-10) assert (numpy_integrator.midpoint_integrator(f, a, b, B) - expected_answer < 1E-10) assert (abs(numba(f, a, b, N) - expected_answer) < 1E-10) assert (abs(numba_integrate(f, a, b, B) - expected_answer) < 1E-10) assert (abs( cython_integrator.integrate_g(a, b, N) - expected_answer < 1E-10)) assert (abs( cython_integrator.cython_integrate_mid(a, b, B) - expected_answer < 1E-10)) with open('report6.txt', 'a') as out: out.write("Lowest N for normal integrate is: {}.\n".format(N)) out.write("Lowest N for mid integrate is: {}.\n".format( B)) #Printing result to report3.txt
def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.ndim = x0.shape[0] rep_ndim = self.ndim * (self.ndim + 1) # representational dimension def f(t, state, z_t, F_t): x_t, P_t = self.load_vars(state) z_t = z_t[:, np.newaxis] K_t = P_t @ self.H @ np.linalg.inv(self.R) d_x = F_t @ x_t + K_t @ (z_t - self.H @ x_t) d_P = F_t @ P_t + P_t @ F_t.T + self.Q - K_t @ self.R @ K_t.T d_state = np.concatenate((d_x, d_P), axis=1) return d_state.ravel() # Flatten for integrate.ode def g(t, state): return np.zeros((rep_ndim, rep_ndim)) x0 = x0[:, np.newaxis] P0 = np.eye(self.ndim) self.x_t = x0 self.P_t = P0 iv = np.concatenate((x0, P0), axis=1).ravel() # Flatten for integrate.ode self.r = Integrator(f, g, rep_ndim) self.r.set_initial_value(iv, 0.)
def func2(self, x): integrator = Integrator(self.hamiltonian) tstart = 0 tend = self.period xfinal = integrator.integrate(x, tstart, tend, self.integration_method) #print("difference = {}".format(x-xfinal)) #print("func output : {}".format(x-xfinal)) return x - xfinal
def main(): print("start!!") model = Rocket_Model_6DoF() # state and input list X = np.empty(shape=[model.n_x, K]) U = np.empty(shape=[model.n_u, K]) # INITIALIZATION sigma = model.t_f_guess X, U = model.initialize_trajectory(X, U) integrator = Integrator(model, K) problem = SCProblem(model, K) converged = False w_delta = W_DELTA for it in range(iterations): t0_it = time() print('-' * 18 + ' Iteration {str(it + 1).zfill(2)} ' + '-' * 18) A_bar, B_bar, C_bar, S_bar, z_bar = integrator.calculate_discretization(X, U, sigma) problem.set_parameters(A_bar=A_bar, B_bar=B_bar, C_bar=C_bar, S_bar=S_bar, z_bar=z_bar, X_last=X, U_last=U, sigma_last=sigma, weight_sigma=W_SIGMA, weight_nu=W_NU, weight_delta=w_delta, weight_delta_sigma=W_DELTA_SIGMA) problem.solve() X = problem.get_variable('X') U = problem.get_variable('U') sigma = problem.get_variable('sigma') delta_norm = problem.get_variable('delta_norm') sigma_norm = problem.get_variable('sigma_norm') nu_norm = np.linalg.norm(problem.get_variable('nu'), np.inf) print('delta_norm', delta_norm) print('sigma_norm', sigma_norm) print('nu_norm', nu_norm) if delta_norm < 1e-3 and sigma_norm < 1e-3 and nu_norm < 1e-7: converged = True w_delta *= 1.5 print('Time for iteration', time() - t0_it, 's') if converged: print('Converged after {it + 1} iterations.') break plot_animation(X, U) print("done!!")
class TestIntegrator(unittest.TestCase): def setUp(self): self.integrator = Integrator() def test_integrated(self): packageA = pk.Package.make(value=numpy.array((1, 2, 3)), timestamp=0) packageB = pk.Package.make(value=numpy.array((1, 2, 3)), timestamp=2) self.integrator.handle(packageA) expected = (3, 6, 9) actual = tuple(self.integrator.handle(packageB).value) self.assertEqual(actual, expected)
def test_integral_of_linear_function(): """Integral of f(x) = 2x from 0 to 1 with 1m steps""" f = lambda x: 2 * x F = lambda x: 2 * x**2 / 2 expected_answer = F(1) - F(0) a, b, N = 0, 1, 1000000 assert abs(Integrator.integrate(f, a, b, N) - expected_answer) < 1E-5
def test_integral_of_constant_function(): """ Integral of f(x) = 2. From 0 to 1 with 100k steps """ f = lambda x: 2 F = lambda x: 2 * x expected_answer = F(1) - F(0) a, b, N = 0, 1, 100000 assert abs(Integrator.integrate(f, a, b, N) - expected_answer) < 1E-11
def setup_integrator(self, context): """ Setup the additional particle arrays for integration. Parameters: ----------- context -- the OpenCL context setup_cl on the calcs must be called when all particle properties on the particle array are created. This is important as all device buffers will created. """ Integrator.setup_integrator(self) self.setup_cl(context) self.cl_precision = self.particles.get_cl_precision()
def compute_trajectory(self, dev_max, dev_var, dev_thr): n_chunks, chunk_size_ms, last_chunk_ms = self._get_integration_chunks() init_cond = self.init_cond idx = None for i in range(n_chunks): if i == n_chunks - 1: integrator = Integrator(self.m, last_chunk_ms, self.dt) else: integrator = Integrator(self.m, chunk_size_ms, self.dt) integrator.set_initial_conditions(init_cond) idx = integrator.find_limit_cycle(dev_max, dev_var, dev_thr, methods.EULER) if idx[1] > idx[0] or i == n_chunks - 1: return integrator.data[:, idx[0]:idx[1]].copy() else: init_cond = integrator.data[:, -1].copy()
def main(): system_state = System_State() system_state.initialize() initial_print(system_state.current_state) integrator = Integrator() integrator.write_run_informations() integrator.integrate(system_state) final_print(system_state.current_state)
def update_system_properties(self, steps=1): ''' Updated the properties of all the particles in the system according to the integrator scheme provided in the integrator class ''' updated_properties = {} integrator = Integrator() for particle in self.particles: neighbours = self.get_neighbours(particle) updated_properties = integrator.get_updated_properties\ (particle, neighbours, self.h, \ kernel='cubic-spline') particle.set_properties(udated_properties)
def integrator(self, name_of_integrator): if self.__integrators is None: self.__integrators = Integrator.load_integrators() print(('Setting the integrator to %s' % name_of_integrator)) # populate the parameters to the integrator if name_of_integrator in self.__integrators: self.__integrator = getattr(self.__integrators[name_of_integrator], name_of_integrator)() self.__integrator.CONST_G = self.CONST_G self.__integrator.t_end = self.__t_end self.__integrator.h = self.__h self.__integrator.t_start = self.__t_start self.__integrator.output_file = self.output_file self.__integrator.collision_output_file = self.collision_output_file self.__integrator.close_encounter_output_file = self.close_encounter_output_file self.__integrator.store_dt = self.__store_dt self.__integrator.buffer_len = self.__buffer_len
def initialize(self, config=None): # Initialize the integrator self.__integrators = Integrator.load_integrators() if self.__integrator is None: print('Use GaussRadau15 as the default integrator...') self.integrator = 'GaussRadau15' self.integrator.initialize() self.integrator.acceleration_method = 'ctypes' else: self.__integrator.CONST_G = self.CONST_G self.__integrator.t_end = self.__t_end self.__integrator.h = self.__h self.__integrator.t_start = self.__t_start self.__integrator.output_file = self.output_file self.__integrator.store_dt = self.__store_dt self.__integrator.buffer_len = self.__buffer_len if config is not None: # Gravitational parameter self.integrator.CONST_G = np.array(config['physical_params']['G']) # Integration parameters self.integrator = config['integration']['integrator'] self.integrator.initialize() self.integrator.h = float(config['integration']['h']) if 'acc_method' in config['integration']: self.integrator.acceleration_method = config['integration']['acc_method'] else: self.integrator.acceleration_method = 'ctypes' # Load sequence of object names if 'names' in config: names = config['names'] else: names = None # Initial and final times if self.integrator.t_start == 0: self.integrator.t_start = float(config['integration']['t0']) if self.integrator.t_end == 0: self.integrator.t_end = float(config['integration']['tf']) self.integrator.active_integrator = config['integration']['integrator'] DataIO.ic_populate(config['initial_conds'], self, names=names)
def test_integral_task_42_43_44_45(): """approximate the integral of f(x) = x2 from 0 to 1 with 100k steps. This is where I generate all my reportX.txt files as well.""" f = lambda x: x**2 F = lambda x: x**3 / 3 expected_answer = F(1) - F(0) a, b, N = 0, 1, 100000000 ###Comparing the selfmade "pure" version with the Numpy one### t0 = time.clock() assert abs(Integrator.integrate(f, a, b, N) - expected_answer) < 1E-5 #Normal integrate function t1 = time.clock() t2 = time.clock() assert abs(numpy_integrator.integrator(f, a, b, N) - expected_answer) < 1E-5 #Numpy integrate function t3 = time.clock() t6 = time.clock() assert abs(numba(f, a, b, N) - expected_answer) < 1E-5 #Numba integrate function t7 = time.clock() t8 = time.clock() assert abs(cython_integrator.integrate_f(a, b, N) - expected_answer) < 1E-5 #Cython integrate function t9 = time.clock() with open('report3.txt', 'a') as out: out.write("N is: {}\nPure function time: {}\n".format( N, (t1 - t0))) #Printing result to report3.txt out.write("Numpy function time: {}\n".format( t3 - t2)) #Printing result to report3.txt with open('report4.txt', 'a') as out: out.write("N is: {}\nPure function time: {}\n".format( N, (t1 - t0))) #Printing result to report3.txt out.write("Numpy function time: {}\n".format( t3 - t2)) #Printing result to report3.txt out.write("Numba function time: {}\n".format( t7 - t6)) #Printing result to report3.txt with open('report5.txt', 'a') as out: out.write("N is: {}\nPure function time: {}\n".format( N, (t1 - t0))) #Printing result to report3.txt out.write("Numpy function time: {}\n".format( t3 - t2)) #Printing result to report3.txt out.write("Numba function time: {}\n".format( t7 - t6)) #Printing result to report3.txt out.write("Cython function time: {}\n".format(t9 - t8))
class KF(LSProcess): def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.ndim = x0.shape[0] rep_ndim = self.ndim * (self.ndim + 1) # representational dimension def f(t, state, z_t, F_t): x_t, P_t = self.load_vars(state) z_t = z_t[:, np.newaxis] K_t = P_t @ self.H @ np.linalg.inv(self.R) d_x = F_t @ x_t + K_t @ (z_t - self.H @ x_t) d_P = F_t @ P_t + P_t @ F_t.T + self.Q - K_t @ self.R @ K_t.T d_state = np.concatenate((d_x, d_P), axis=1) return d_state.ravel() # Flatten for integrate.ode def g(t, state): return np.zeros((rep_ndim, rep_ndim)) x0 = x0[:, np.newaxis] P0 = np.eye(self.ndim) self.x_t = x0 self.P_t = P0 iv = np.concatenate((x0, P0), axis=1).ravel() # Flatten for integrate.ode self.r = Integrator(f, g, rep_ndim) self.r.set_initial_value(iv, 0.) def load_vars(self, state: np.ndarray): state = state.reshape((self.ndim, self.ndim + 1)) x_t, P_t = state[:, :1], state[:, 1:] return x_t, P_t def __call__(self, z_t: np.ndarray): ''' Observe through filter ''' self.r.set_f_params(z_t, self.F(self.t)) self.r.integrate(self.t + self.dt) x_t, P_t = self.load_vars(self.r.y) self.x_t, self.P_t = x_t, P_t x_t = np.squeeze(x_t) err_t = z_t - x_t @ self.H.T return x_t.copy(), err_t # x_t variable gets reused somewhere...
def estimate_constants(update_json=False): # estimate L_phi_x, L_phi_u using max norm of Jacobians # max attained at x1 = 1, x2 = -1 L_phi_u = np.sqrt((par.mu + (1 - par.mu))**2 + \ (par.mu -4*(1-par.mu))**2) n_points = 100 u_grid = np.linspace(-par.umax, +par.umax, n_points) norm_dphi_dx = np.zeros((n_points, 1)) for i in range(n_points): u = u_grid[i] dphi_dx = np.array([[u * (1 - par.mu), 1], [1, -4 * u * (1 - par.mu)]]) norm_dphi_dx[i] = np.linalg.norm(dphi_dx) L_phi_x = np.max(norm_dphi_dx) nsim = int(par.Tf / par.Ts) x0 = par.x0_v[0] n_scenarios = len(par.x0_v) n_sqp_it = 3 # estimate a_1, a_2, a_3, sigma, mu_tilde constants based on sampling VEXACT = np.zeros((nsim, 1, n_scenarios)) SOLEXACTNORM = np.zeros((nsim, 1, n_scenarios)) DELTAVEXACT = np.zeros((nsim - 1, 1, n_scenarios)) XNORMSQ = np.zeros((nsim, 1, n_scenarios)) XNORM = np.zeros((nsim, 1, n_scenarios)) XSIMEXACT = np.zeros((nsim + 1, 2, n_scenarios)) USIMEXACT = np.zeros((nsim, 1, n_scenarios)) exact_ocp_solver = OcpSolver() for j in range(n_scenarios): x0 = par.x0_v[j] # closed loop simulation XSIMEXACT[0, :, j] = x0 integrator = Integrator(par.ode) exact_ocp_solver = OcpSolver() exact_ocp_solver.nlp_eval() for i in range(nsim): XNORMSQ[i, 0, j] = np.linalg.norm(XSIMEXACT[i, :, j])**2 XNORM[i, 0, j] = np.linalg.norm(XSIMEXACT[i, :, j]) # update state in OCP solver exact_ocp_solver.update_x0(XSIMEXACT[i, :, j]) solver_out = exact_ocp_solver.nlp_eval() status = exact_ocp_solver.get_status() if status != 'Solve_Succeeded': raise Exception('Solver returned status {} at iteration {}'\ .format(status, i)) # get primal-dual solution x = solver_out['x'].full() lam_g = solver_out['lam_g'].full() SOLEXACTNORM[i, :, j] = np.linalg.norm(np.vstack([x, lam_g])) # get first control move u = solver_out['x'].full()[2] USIMEXACT[i, 0, j] = u VEXACT[i, 0, j] = solver_out['f'].full() XSIMEXACT[i+1,:,j] = integrator.eval(par.Ts, XSIMEXACT[i,:,j], \ u).full().transpose() for i in range(nsim - 1): DELTAVEXACT[i, 0, j] = VEXACT[i + 1, 0, j] - VEXACT[i, 0, j] XSIMEXACT = XSIMEXACT[0:-1, :, :] VEXACT_OVER_XNORMSQ = [] DELTAVEXACT_OVER_XNORMSQ = [] SOLEXACTNORM_OVER_XNORM = [] VEXACTSQRT_OVER_XNORM = [] for j in range(n_scenarios): VEXACT_OVER_XNORMSQ.append(np.divide(VEXACT[:, 0, j], XNORMSQ[:, 0, j])) DELTAVEXACT_OVER_XNORMSQ.append(np.divide(DELTAVEXACT[:,0,j], \ XNORMSQ[0:-1,0,j])) SOLEXACTNORM_OVER_XNORM.append(np.divide( \ SOLEXACTNORM[:,0,j], XNORM[:,0,j])) VEXACTSQRT_OVER_XNORM.append(np.divide(np.sqrt(VEXACT[:,0,j]), \ XNORM[:,0,j])) # compute constants a1 = np.min(VEXACT_OVER_XNORMSQ) a2 = np.max(VEXACT_OVER_XNORMSQ) a3 = np.min(-1.0 / par.Ts * np.array(DELTAVEXACT_OVER_XNORMSQ)) sigma = np.max(SOLEXACTNORM_OVER_XNORM) mu_tilde = np.max(VEXACTSQRT_OVER_XNORM) print('a1 = {}, a2 = {}, a3 = {}, sigma = {}, mu_tilde = {}' \ .format(a1, a2, a3, sigma, mu_tilde)) if a1 < 0 or a2 < 0 or a3 < 0: raise Exception('One of the a constants is \ negative (a1 = {}, a2 = {}, a3 = {})'.format(a1, a2, a3)) # estimate \hat{\kappa} ocp_solver = OcpSolver() lqr_solver = LqrSolver() ocp_solver.nlp_eval() XSIM = np.zeros((nsim + 1, 2, n_scenarios)) USIM = np.zeros((nsim, 1, n_scenarios)) VSIMSQRT = np.zeros((nsim, 1, n_scenarios)) ZSIM = np.zeros((nsim, 1, n_scenarios)) DELTAZSIM = np.zeros((nsim, 1, n_scenarios)) VSOSIM = np.zeros((nsim, 1, n_scenarios)) kappa = 0.0 for j in range(len(par.x0_v)): x0 = par.x0_v[j] XSIM[0, :, j] = x0 # closed loop simulation integrator = Integrator(par.ode) ocp_solver = OcpSolver() ocp_solver.rti_eval() ocp_solver.nlp_eval() ocp_solver.update_x0(XSIM[0, :, j]) for i in range(nsim): # update state in OCP solver ocp_solver.update_x0(XSIM[i, :, j]) DELTAZSIM = np.zeros((n_sqp_it, 1)) if LQR_INIT: lqr_solver.update_x0(XSIM[i, :, j]) lqr_solver.lqr_eval() lqr_sol = lqr_solver.get_lqr_sol() ocp_solver.set_sol_lin(lqr_sol) for k in range(n_sqp_it): # get primal dual solution (equalities only) rti_sol = ocp_solver.get_rti_sol() lam_g = rti_sol['lam_g'].full() x = rti_sol['x'].full() z = np.vstack((x, lam_g)) # get primal dual exact sol exact_sol = ocp_solver.nlp_eval() nlp_sol = ocp_solver.get_nlp_sol() exact_lam_g = nlp_sol['lam_g'].full() exact_x = nlp_sol['x'].full() exact_z = np.vstack((exact_x, exact_lam_g)) DELTAZSIM[k, 0] = np.linalg.norm(z - exact_z) # call solver solver_out = ocp_solver.rti_eval() status = ocp_solver.get_status() if status != 'Solve_Succeeded': raise Exception('Solver returned status {} at iteration {}'\ .format(status, i)) # estimate \hat{kappa} KAPPAESTIMATE = np.zeros((n_sqp_it, 1)) for k in range(n_sqp_it - 1): KAPPAESTIMATE[k, 0] = DELTAZSIM[k + 1, 0] / (DELTAZSIM[k, 0]) kappa = np.max([np.max(KAPPAESTIMATE), kappa]) # get first control move u = solver_out['x'].full()[2] USIM[i, 0, j] = u XSIM[i+1,:,j] = integrator.eval(par.Ts, XSIM[i,:,j], \ u).full().transpose() print('kappa = {}'.format(kappa)) if kappa > 1.0: raise Exception('kappa bigger than 1.0!') const = dict() const['a1'] = a1 const['a2'] = a2 const['a3'] = a3 const['sigma'] = sigma const['kappa_hat'] = kappa const['mu_tilde'] = mu_tilde const['L_phi_x'] = L_phi_x const['L_phi_u'] = L_phi_u if update_json: with open('constants.json', 'w') as outfile: json.dump(const, outfile) return const
class LKF(LSProcess): def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float, tau: float = float('inf'), eps=1e-4): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.tau = tau self.eps = eps self.eta_mu = eta_mu self.eta_var = eta_var self.ndim = x0.shape[0] self.e_zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_inv_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.kf_err_hist = [] self.kf = KF(x0, F, H, Q, R, dt) def f(t, state, z_t, err_hist, F_t): # TODO fix all stateful references in this body x_t, P_t, eta_t = self.load_vars(state) z_t = z_t[:, np.newaxis] K_t = [email protected]@np.linalg.inv(self.R) d_eta = np.zeros((self.ndim, self.ndim)) if t > self.tau: # TODO warmup case? H_inv = np.linalg.inv(self.H) P_kf_t = self.kf.P_t P_inv = np.linalg.solve(P_kf_t.T@P_kf_t + self.eps*np.eye(self.ndim), P_kf_t.T) self.p_inv_t = P_inv tau_n = int(self.tau / self.dt) err_t, err_tau = err_hist[-1][:,np.newaxis], err_hist[-tau_n][:,np.newaxis] d_zz = (err_t@err_t.T - err_tau@err_tau.T) / self.tau self.e_zz_t = d_zz # E_z = sum(err_hist[-tau_n:])[:,np.newaxis] / tau_n # d_uu = ((err_t - err_tau)/self.tau)@(E_z.T) + E_z@(((err_t - err_tau)/self.tau).T) # self.e_zz_t = d_zz - d_uu # if np.linalg.norm(d_zz) >= 1.0: # d_zz = np.zeros((self.ndim, self.ndim)) d_eta = (H_inv@d_zz@H_inv.T@P_inv / 2 - eta_t) / self.tau F_est = F_t - eta_t d_x = F_est@x_t + K_t@(z_t - self.H@x_t) d_P = F_est@P_t + P_t@F_est.T + self.Q - [email protected]@K_t.T d_state = np.concatenate((d_x, d_P, d_eta), axis=1) return d_state.ravel() # Flatten for integrator def g(t, state): return np.zeros((self.ode_ndim, self.ode_ndim)) # state x0 = x0[:, np.newaxis] self.x_t = x0 # covariance P0 = np.eye(self.ndim) self.P_t = P0 # model variation eta0 = np.zeros((self.ndim, self.ndim)) self.eta_t = eta0 iv = np.concatenate((x0, P0, eta0), axis=1).ravel() # Flatten for integrator self.r = Integrator(f, g, self.ode_ndim) self.r.set_initial_value(iv, 0.) def load_vars(self, state: np.ndarray): state = state.reshape(self.ode_shape) x_t, P_t, eta_t = state[:, :1], state[:, 1:1+self.ndim], state[:, 1+self.ndim:] return x_t, P_t, eta_t def __call__(self, z_t: np.ndarray): ''' Observe through filter ''' _, kf_err_t = self.kf(z_t) self.kf_err_hist.append(kf_err_t) self.r.set_f_params(z_t, self.kf_err_hist, self.F(self.t)) self.r.integrate(self.t + self.dt) x_t, P_t, eta_t = self.load_vars(self.r.y) self.x_t, self.P_t, self.eta_t = x_t, P_t, eta_t x_t = np.squeeze(x_t) err_t = z_t - [email protected] return x_t.copy(), err_t # x_t variable gets reused somewhere... @property def ode_shape(self): return (self.ndim, 1 + 2*self.ndim) # representational dimension: x_t, P_t, eta_t @property def ode_ndim(self): return self.ode_shape[0] * self.ode_shape[1] # for raveled representation def f_eta(self, eta: np.ndarray): """ density function of variations """ return stats.multivariate_normal.pdf(eta.ravel(), mean=self.eta_mu.ravel(), cov=self.eta_var.ravel())
def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float, tau: float = float('inf'), eps=1e-4): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.tau = tau self.eps = eps self.eta_mu = eta_mu self.eta_var = eta_var self.ndim = x0.shape[0] self.e_zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_inv_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.kf_err_hist = [] self.kf = KF(x0, F, H, Q, R, dt) def f(t, state, z_t, err_hist, F_t): # TODO fix all stateful references in this body x_t, P_t, eta_t = self.load_vars(state) z_t = z_t[:, np.newaxis] K_t = [email protected]@np.linalg.inv(self.R) d_eta = np.zeros((self.ndim, self.ndim)) if t > self.tau: # TODO warmup case? H_inv = np.linalg.inv(self.H) P_kf_t = self.kf.P_t P_inv = np.linalg.solve(P_kf_t.T@P_kf_t + self.eps*np.eye(self.ndim), P_kf_t.T) self.p_inv_t = P_inv tau_n = int(self.tau / self.dt) err_t, err_tau = err_hist[-1][:,np.newaxis], err_hist[-tau_n][:,np.newaxis] d_zz = (err_t@err_t.T - err_tau@err_tau.T) / self.tau self.e_zz_t = d_zz # E_z = sum(err_hist[-tau_n:])[:,np.newaxis] / tau_n # d_uu = ((err_t - err_tau)/self.tau)@(E_z.T) + E_z@(((err_t - err_tau)/self.tau).T) # self.e_zz_t = d_zz - d_uu # if np.linalg.norm(d_zz) >= 1.0: # d_zz = np.zeros((self.ndim, self.ndim)) d_eta = (H_inv@d_zz@H_inv.T@P_inv / 2 - eta_t) / self.tau F_est = F_t - eta_t d_x = F_est@x_t + K_t@(z_t - self.H@x_t) d_P = F_est@P_t + P_t@F_est.T + self.Q - [email protected]@K_t.T d_state = np.concatenate((d_x, d_P, d_eta), axis=1) return d_state.ravel() # Flatten for integrator def g(t, state): return np.zeros((self.ode_ndim, self.ode_ndim)) # state x0 = x0[:, np.newaxis] self.x_t = x0 # covariance P0 = np.eye(self.ndim) self.P_t = P0 # model variation eta0 = np.zeros((self.ndim, self.ndim)) self.eta_t = eta0 iv = np.concatenate((x0, P0, eta0), axis=1).ravel() # Flatten for integrator self.r = Integrator(f, g, self.ode_ndim) self.r.set_initial_value(iv, 0.)
def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float, tau_rng: list = [float('inf')], eta_mu: float = 0., eta_var: float = 1., eps=1e-4): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.tau_rng = tau_rng self.eps = eps self.eta_mu = eta_mu self.eta_var = max(eta_var, 1e-3) # to avoid singular matrix self.ndim = x0.shape[0] self.err_hist = [] self.e_zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_inv_t = np.zeros((self.ndim, self.ndim)) # temp var.. def f(t, state, z_t, err_hist, F_t): # TODO fix all stateful references in this body state = state.reshape(self.ode_shape) x_t, P_t, eta_t = state[:, :1], state[:, 1:1 + self.ndim], state[:, 1 + self.ndim:] z_t = z_t[:, np.newaxis] K_t = P_t @ self.H @ np.linalg.inv(self.R) d_eta = np.zeros((self.ndim, self.ndim)) if t > self.tau_rng[-1]: # TODO warmup case? H_inv = np.linalg.inv(self.H) P_inv = np.linalg.solve( P_t.T @ P_t + self.eps * np.eye(self.ndim), P_t.T) self.p_inv_t = P_inv eta_new = np.zeros((self.ndim, self.ndim)) for tau in self.tau_rng: tau_n = int(tau / self.dt) err_t, err_tau = err_hist[-1][:, np.newaxis], err_hist[ -tau_n][:, np.newaxis] d_zz = (err_t @ err_t.T - err_tau @ err_tau.T) / tau self.e_zz_t = d_zz # if np.linalg.norm(d_zz) >= 1.0: # d_zz = np.zeros((self.ndim, self.ndim)) # E_z = sum(err_hist[-tau_n:])[:,np.newaxis] / tau_n # d_uu = ((err_t - err_tau)/self.tau)@(E_z.T) + E_z@(((err_t - err_tau)/self.tau).T) # self.e_zz_t = d_zz - d_uu eta_new += H_inv @ d_zz @ H_inv.T @ P_inv / 2 eta_new /= len(self.tau_rng) d_eta = eta_new - eta_t # alpha = self.f_eta(d_eta_new) / self.f_eta(np.zeros((2,2))) # if stats.uniform.rvs() <= alpha: # d_eta = d_eta_new / self.dt F_est = F_t - eta_t d_x = F_est @ x_t + K_t @ (z_t - self.H @ x_t) d_P = F_est @ P_t + P_t @ F_est.T + self.Q - K_t @ self.R @ K_t.T d_state = np.concatenate((d_x, d_P, d_eta), axis=1) return d_state.ravel() # Flatten for integrator def g(t, state): return np.zeros((self.ode_ndim, self.ode_ndim)) # state x0 = x0[:, np.newaxis] self.x_t = x0 # covariance P0 = np.eye(self.ndim) self.P_t = P0 # model variation eta0 = np.zeros((self.ndim, self.ndim)) self.eta_t = eta0 iv = np.concatenate((x0, P0, eta0), axis=1).ravel() # Flatten for integrator self.r = Integrator(f, g, self.ode_ndim) self.r.set_initial_value(iv, 0.)
0.0, # s_ampa 0.0, # x_nmda 0.0])# s_nmda #traj = np.load('sgy_period_ref.npy') m = SGY_neuron() m.set_parameters(**reference_set) # unstable parameters m.par.g_ampa = 0 m.par.g_nmda = 0.09 m.par.w = 1.0 msfi = MSF_Integrator(m) i = Integrator(m, tmax, dt) i.set_initial_conditions(init) # compute periodic trajectory idx1, idx2 = i.find_limit_cycle(1e-5, test_var_thr=-55) traj = i.data[:, idx1:idx2].copy() del i def floq(gamma): msfi.compute_Floquet(gamma, dt, traj) evals,_ = np.linalg.eig(msfi.X[-1]) return np.sort(np.abs(evals))[::-1]#import time #t1 = time.time() #msfer.compute_Floquet(1, 0.0005, traj) #t2 = time.time()
tmax = 5e3 # ms dt = 0.0005 # ms n = 100 init = np.array([0.0, # x 0.0, # y 0.0])# z m = HR_neuron() m.set_parameters(**reference_set) m.par.I_ext = 2.5 m.par.eps = 0.1 m.par.row_sum = 1 i = Integrator(m, tmax, dt) i.set_initial_conditions(init) msfi = MSF_Integrator(m) #def plot_traces(idx=0, skip = 10): #t = np.linspace(0, tmax, np.floor(i.data.shape[1] / skip) + 1) #plt.figure() #plt.plot(t, i.data[idx, ::skip]) #plt.show() def timeit(closure, n): total_t = 0 for j in range(n): t1 = time.time() closure() t2 = time.time()
def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float, tau=float('inf'), eta_bnd=float('inf'), eps=1e-4, gamma=1.): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.tau = tau self.eps = eps self.eta_bnd = eta_bnd self.gamma = gamma self.ndim = x0.shape[0] self.err_hist = [] self.P_hist = [] self.e_zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_inv_t = np.zeros((self.ndim, self.ndim)) # temp var.. def f(t, state, z_t, err_hist, F_t): # TODO fix all stateful references in this body state = state.reshape(self.ode_shape) x_t, P_t, eta_t = state[:, :1], state[:, 1:1 + self.ndim], state[:, 1 + self.ndim:] z_t = z_t[:, np.newaxis] K_t = P_t @ self.H @ np.linalg.inv(self.R) d_eta = np.zeros((self.ndim, self.ndim)) if t > self.tau: # TODO warmup case? H_inv = np.linalg.inv(self.H) P_inv = np.linalg.solve( P_t.T @ P_t + self.eps * np.eye(self.ndim), P_t.T) self.p_inv_t = P_inv tau_n = int(self.tau / self.dt) err_t, err_tau = err_hist[-1][:, np.newaxis], err_hist[ -tau_n][:, np.newaxis] p_t, p_tau = self.P_hist[-1], self.P_hist[-tau_n] # d_zz = (err_t@err_t.T - err_tau@err_tau.T) d_zz = (err_t @ err_t.T - err_tau @ err_tau.T) / self.tau - self.H @ ( p_t - p_tau) @ self.H.T / self.tau self.e_zz_t = d_zz eta_new = self.gamma * H_inv @ d_zz @ H_inv.T @ P_inv / 2 if np.linalg.norm(eta_new) <= eta_bnd: d_eta = (eta_new - eta_t) / self.dt F_est = F_t - eta_t d_x = F_est @ x_t + K_t @ (z_t - self.H @ x_t) d_P = F_est @ P_t + P_t @ F_est.T + self.Q - K_t @ self.R @ K_t.T d_state = np.concatenate((d_x, d_P, d_eta), axis=1) return d_state.ravel() # Flatten for integrator def g(t, state): return np.zeros((self.ode_ndim, self.ode_ndim)) # state x0 = x0[:, np.newaxis] self.x_t = x0 # covariance P0 = np.eye(self.ndim) self.P_t = P0 # model variation eta0 = np.zeros((self.ndim, self.ndim)) self.eta_t = eta0 iv = np.concatenate((x0, P0, eta0), axis=1).ravel() # Flatten for integrator self.r = Integrator(f, g, self.ode_ndim) self.r.set_initial_value(iv, 0.)
def __init__(self): Integrator.__init__(self)
def __init__(self): Td = par.Tp / par.N # linearize model X_lin = ca.MX.sym('X_lin', 2, 1) U_lin = ca.MX.sym('U_lin', 1, 1) A_c = ca.Function('A_c', \ [X_lin, U_lin], [ca.jacobian(par.ode(X_lin, U_lin), X_lin)]) A_c = A_c([0, 0], 0).full() B_c = ca.Function('B_c', \ [X_lin, U_lin], [ca.jacobian(par.ode(X_lin, U_lin), U_lin)]) B_c = B_c([0, 0], 0).full() # solve continuous-time Riccati equation Qt, e, K = cn.care(A_c, B_c, par.Q, par.R) # this is the value used in Chen1998!! # they do not use LQR, but a modified linear controller # Qt = np.array([[16.5926, 11.5926], [11.5926, 16.5926]]) self.integrator = Integrator(par.ode) self.x = self.integrator.x self.u = self.integrator.u self.Td = Td # start with an empty NLP w = [] w0 = [] lbw = [] ubw = [] g = [] lbg = [] ubg = [] Xk = ca.MX.sym('X0', 2, 1) w += [Xk] lbw += [0, 0] ubw += [0, 0] w0 += [0, 0] f = 0 # formulate the NLP for k in range(par.N): # new NLP variable for the control Uk = ca.MX.sym('U_' + str(k), 1, 1) f = f + Td*ca.mtimes(ca.mtimes(Xk.T, par.Q), Xk) \ + Td*ca.mtimes(ca.mtimes(Uk.T, par.R), Uk) w += [Uk] lbw += [-par.umax] ubw += [par.umax] w0 += [0.0] # integrate till the end of the interval Xk_end = self.integrator.eval(Td, Xk, Uk) # new NLP variable for state at end of interval Xk = ca.MX.sym('X_' + str(k + 1), 2, 1) w += [Xk] lbw += [-np.inf, -np.inf] ubw += [np.inf, np.inf] w0 += [0, 0] # add equality constraint g += [Xk_end - Xk] lbg += [0, 0] ubg += [0, 0] f = f + ca.mtimes(ca.mtimes(Xk_end.T, Qt), Xk_end) g = ca.vertcat(*g) w = ca.vertcat(*w) # create an NLP solver prob = {'f': f, 'x': w, 'g': g} self.__nlp_solver = ca.nlpsol('solver', 'ipopt', prob) self.__lbw = lbw self.__ubw = ubw self.__lbg = lbg self.__ubg = ubg self.__w0 = np.array(w0) self.__sol_lin = np.array(w0).transpose() self.__rti_sol = [] self.__nlp_sol = [] # create QP solver nw = len(w0) # define linearization point w_lin = ca.MX.sym('w_lin', nw, 1) w_qp = ca.MX.sym('w_qp', nw, 1) # linearized objective = original LLS objective f_lin = ca.substitute( f, w, w_qp) + par.alpha * ca.dot(w_qp - w_lin, w_qp - w_lin) nabla_g = ca.jacobian(g, w).T g_lin = ca.substitute(g, w, w_lin) + \ ca.mtimes(ca.substitute(nabla_g, w, w_lin).T, w_qp - w_lin) # create a QP solver prob = {'f': f_lin, 'x': w_qp, 'g': g_lin, 'p': w_lin} self.__rti_solver = ca.nlpsol('solver', 'ipopt', prob)
class LKF(LSProcess): def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float, tau=float('inf'), eps=1e-3): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.tau = tau self.eps = eps self.ndim = x0.shape[0] self.err_hist = [] self.eta_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.e_zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_inv_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.n_est = 20 def f(t, state, z_t, err_hist, F_t): state = state.reshape(self.ode_shape) x_t, P_t, eta_t = state[:, :1], state[:, 1:3], state[:, 3:] self.p_t = P_t z_t = z_t[:, np.newaxis] eta_t = np.zeros((self.ndim, self.ndim)) if self.history_loaded(): # TODO: warmup case? H_inv = np.linalg.inv(self.H) P_inv = np.linalg.solve(P_t.T @ P_t + eps * np.eye(2), P_t.T) self.p_inv_t = P_inv tau_n = int(self.tau / self.dt) d_zz = np.zeros((self.ndim, self.ndim)) for i in range(self.n_est): err_t, err_tau = err_hist[-1 - i][:, np.newaxis], err_hist[ -tau_n - i][:, np.newaxis] d_zz += (err_t @ err_t.T - err_tau @ err_tau.T) / self.tau d_zz /= self.n_est self.e_zz_t = d_zz eta_t = H_inv @ d_zz @ H_inv.T @ P_inv / 2 # eta_t = np.clip(eta_t, -10, 10) self.eta_t = eta_t # TODO fix hack F_est = F_t - eta_t K_t = P_t @ self.H @ np.linalg.inv(self.R) d_x = F_est @ x_t + K_t @ (z_t - self.H @ x_t) d_P = F_est @ P_t + P_t @ F_est.T + self.Q - K_t @ self.R @ K_t.T d_eta = np.zeros( (self.ndim, self.ndim) ) # H_inv@(err_t@err_t.T - err_tau@err_tau.T)@H_inv.T@P_inv / (2*tau) d_state = np.concatenate((d_x, d_P, d_eta), axis=1) return d_state.ravel() # Flatten for integrator def g(t, state): return np.zeros((self.ode_ndim, self.ode_ndim)) # state x0 = x0[:, np.newaxis] # covariance P0 = np.eye(self.ndim) # model variation eta0 = np.zeros((self.ndim, self.ndim)) iv = np.concatenate((x0, P0, eta0), axis=1).ravel() # Flatten for integrator self.r = Integrator(f, g, self.ode_ndim) self.r.set_initial_value(iv, 0.) def __call__(self, z_t: np.ndarray): ''' Observe through filter ''' self.r.set_f_params(z_t, self.err_hist, self.F(self.t)) self.r.integrate(self.t + self.dt) x_t = np.squeeze(self.r.y.reshape(self.ode_shape)[:, :1]) err_t = z_t - x_t @ self.H.T self.err_hist.append(err_t) if self.history_loaded(): self.err_hist = self.err_hist[1:] return x_t.copy(), err_t # x_t variable gets reused somewhere... def history_loaded(self): return self.t > self.tau + self.n_est * self.dt @property def ode_shape(self): return (self.ndim, 1 + 2 * self.ndim ) # representational dimension: x_t, P_t, eta_t @property def ode_ndim(self): return self.ode_shape[0] * self.ode_shape[ 1] # for raveled representation
def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float, tau=float('inf'), eps=1e-3): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.tau = tau self.eps = eps self.ndim = x0.shape[0] self.err_hist = [] self.eta_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.e_zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_inv_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.n_est = 20 def f(t, state, z_t, err_hist, F_t): state = state.reshape(self.ode_shape) x_t, P_t, eta_t = state[:, :1], state[:, 1:3], state[:, 3:] self.p_t = P_t z_t = z_t[:, np.newaxis] eta_t = np.zeros((self.ndim, self.ndim)) if self.history_loaded(): # TODO: warmup case? H_inv = np.linalg.inv(self.H) P_inv = np.linalg.solve(P_t.T @ P_t + eps * np.eye(2), P_t.T) self.p_inv_t = P_inv tau_n = int(self.tau / self.dt) d_zz = np.zeros((self.ndim, self.ndim)) for i in range(self.n_est): err_t, err_tau = err_hist[-1 - i][:, np.newaxis], err_hist[ -tau_n - i][:, np.newaxis] d_zz += (err_t @ err_t.T - err_tau @ err_tau.T) / self.tau d_zz /= self.n_est self.e_zz_t = d_zz eta_t = H_inv @ d_zz @ H_inv.T @ P_inv / 2 # eta_t = np.clip(eta_t, -10, 10) self.eta_t = eta_t # TODO fix hack F_est = F_t - eta_t K_t = P_t @ self.H @ np.linalg.inv(self.R) d_x = F_est @ x_t + K_t @ (z_t - self.H @ x_t) d_P = F_est @ P_t + P_t @ F_est.T + self.Q - K_t @ self.R @ K_t.T d_eta = np.zeros( (self.ndim, self.ndim) ) # H_inv@(err_t@err_t.T - err_tau@err_tau.T)@H_inv.T@P_inv / (2*tau) d_state = np.concatenate((d_x, d_P, d_eta), axis=1) return d_state.ravel() # Flatten for integrator def g(t, state): return np.zeros((self.ode_ndim, self.ode_ndim)) # state x0 = x0[:, np.newaxis] # covariance P0 = np.eye(self.ndim) # model variation eta0 = np.zeros((self.ndim, self.ndim)) iv = np.concatenate((x0, P0, eta0), axis=1).ravel() # Flatten for integrator self.r = Integrator(f, g, self.ode_ndim) self.r.set_initial_value(iv, 0.)
def run(self, t_end, dt, max_steps=1000, solver="odeint", output="dataframes", terminate=False): """Run the parcel model. After initializing the parcel model, it can be immediately run by calling this function. Before the model is integrated, a routine :func:`_setup_run()` is performed to equilibrate the initial aerosol population to the ambient meteorology if it hasn't already been done. Then, the initial conditions are passed to a user-specified solver which integrates the system forward in time. By default, the integrator wraps ODEPACK's LSODA routine through SciPy's :func:`odeint` method, but extensions to use other solvers can be written easily (for instance, two methods from :mod:`odespy` are given below). The user can specify the timesteps to evaluate the trace of the parcel in one of two ways: #. Setting ``dt`` will automatically specify a timestep to use and \ the model will use it to automatically populate the array to \ pass to the solver. #. Otherwise, the user can specify ``ts`` as a list or array of the \ timesteps where the model should be evaluated. **Args**: * *z_top* -- Vertical extent to which the model should be integrated. * *dt* -- Timestep intervals to report model output. * *ts* -- Pre-computed array of timestamps where output is requested. * *max_steps* -- Maximum number of steps allowed by solver to achieve \ tolerance during integration. * *solver* -- A string indicating which solver to use: * ``"odeint"``: LSODA implementation from ODEPACK via \ SciPy's ``integrate`` module * ``"lsoda"``: LSODA implementation from ODEPACK via odespy * ``"lsode"``: LSODE implementation from ODEPACK via odespy * *output* -- A string indicating the format in which the output of the run should be returned **Returns**: Depending on what was passed to the *output* argument, different types of data might be returned: * ``"dataframes"``: (default) will process the output into \ two pandas DataFrames - the first one containing profiles \ of the meteorological quantities tracked in the model, \ and the second a dictionary of DataFrames with one for \ each AerosolSpecies, tracking the growth in each bin \ for those species. * ``"arrays"``: will return the raw output from the solver \ used internally by the parcel model - the state vector \ ``x`` and the evaluated timesteps converted into height \ coordinates. * ``"smax"``: will only return the maximum supersaturation \ value achieved in the simulation. A tuple whose first element is a DataFrame containing the profiles of the meteorological quantities tracked in the parcel model, and whose second element is a dictionary of DataFrames corresponding to each aerosol species and their droplet sizes. **Raises**: ``ParcelModelError``: The parcel model failed to complete successfully or failed to initialize. """ if not output in ["dataframes", "arrays", "smax"]: raise ParcelModelError("Invalid value ('%s') specified for output format." % output) if not self._model_set: _ = self._setup_run() y0 = self.y0 r_drys = self._r_drys kappas = self._kappas Nis = self._Nis nr = self._nr ## Setup run time conditions t = np.arange(0., t_end+dt, dt) if self.console: print "\n"+"n_steps = %d" % (len(t))+"\n" ## Setup/run integrator try: from parcel_aux import der as der_fcn except ImportError: print "Could not load Cython derivative; using Python version." from parcel import der as der_fcn args = (nr, r_drys, Nis, self.V, kappas) integrator = Integrator.solver(solver) ## Is the updraft speed a function? v_is_func = hasattr(self.V, '__call__') if v_is_func: # Re-wrap the function to correctly figure out V orig_der_fcn = der_fcn def der_fcn(y, t, nr, r_drys, Nis, V, kappas): V_t = self.V(t) return orig_der_fcn(y, t, nr, r_drys, Nis, V_t, kappas) try: x, t, success = integrator(der_fcn, t, y0, args, self.console, max_steps, terminate) except ValueError, e: raise ParcelModelError("Something failed during model integration: %r" % e)
if __name__ == '__main__': if len(sys.argv) == 3: dt = 0.01 bodies = [[], []] interactions = [[], [], [], [], []] app = QtGui.QApplication(sys.argv) init_system(sys.argv[1], bodies, interactions) integrator = Integrator(bodies, interactions) viewer = GridViewer(integrator, dt, k_list) configure_system(sys.argv[2], integrator) integrator.integrate(dt) integrator.max_energy = integrator.normalize(integrator.get_max_energy()) viewer.prepare_color_key() timer = QTimer() timer.timeout.connect(run) timer.start(10) sys.exit(app.exec_()) else:
def setUp(self): self.integrator = Integrator()
def test_create_plot(): """Just creating the plot""" f = lambda x: x**3 / 3 a, b, N = 0, 1, 10 Integrator.plot_dat(f, a, b, N)
def run(self, t_end, output_dt=1., solver_dt=None, max_steps=1000, solver="odeint", output="dataframes", terminate=False, terminate_depth=100., **solver_args): """ Run the parcel model simulation. Once the model has been instantiated, a simulation can immediately be performed by invoking this method. The numerical details underlying the simulation and the times over which to integrate can be flexibly set here. **Time** -- The user must specify two timesteps: `output_dt`, which is the timestep between output snapshots of the state of the parcel model, and `solver_dt`, which is the the interval of time before the ODE integrator is paused and re-started. It's usually okay to use a very large `solver_dt`, as `output_dt` can be interpolated from the simulation. In some cases though a small `solver_dt` could be useful to force the solver to use smaller internal timesteps. **Numerical Solver** -- By default, the model will use the `odeint` wrapper of LSODA shipped by default with scipy. Some fine-tuning of the solver tolerances is afforded here through the `max_steps`. For other solvers, a set of optional arguments `solver_args` can be passed. **Solution Output** -- Several different output formats are available by default. Additionally, the output arrays are saved with the `ParcelModel` instance so they can be used later. Parameters ---------- t_end : float Total time over interval over which the model should be integrated output_dt : float Timestep intervals to report model output. solver_dt : float Timestep interval for calling solver integration routine. max_steps : int Maximum number of steps allowed by solver to satisfy error tolerances per timestep. solver : {'odeint', 'lsoda', 'lsode', 'vode', cvode'} Choose which numerical solver to use: * `'odeint'`: LSODA implementation from ODEPACK via SciPy's integrate module * `'lsoda'`: LSODA implementation from ODEPACK via odespy * `'lsode'`: LSODE implementation from ODEPACK via odespy * `'vode'` : VODE implementation from ODEPACK via odespy * `'cvode'` : CVODE implementation from Sundials via Assimulo * `'lsodar'` : LSODAR implementation from Sundials via Assimulo output : {'dataframes', 'arrays', 'smax'} Choose format of solution output. terminate : boolean End simulation at or shortly after a maximum supersaturation has been achieved terminate_depth : float, optional (default=100.) Additional depth (in meters) to integrate after termination criterion eached. Returns ------- DataFrames, array, or float Depending on what was passed to the *output* argument, different types of data might be returned: - `dataframes': (default) will process the output into two pandas DataFrames - the first one containing profiles of the meteorological quantities tracked in the model, and the second a dictionary of DataFrames with one for each AerosolSpecies, tracking the growth in each bin for those species. - 'arrays': will return the raw output from the solver used internally by the parcel model - the state vector `y` and the evaluated timesteps converted into height coordinates. - 'smax': will only return the maximum supersaturation value achieved in the simulation. Raises ------ ParcelModelError The parcel model failed to complete successfully or failed to initialize. See Also -------- der : right-hand side derivative evaluated during model integration. """ if not output in ["dataframes", "arrays", "smax"]: raise ParcelModelError("Invalid value ('%s') specified for output format." % output) if solver_dt is None: solver_dt = 10.*output_dt if not self._model_set: self._setup_run() y0 = self.y0 r_drys = self._r_drys kappas = self._kappas Nis = self._Nis nr = self._nr ## Setup/run integrator try: from parcel_aux import der as der_fcn except ImportError: print "Could not load Cython derivative; using Python version." from parcel import der as der_fcn ## Is the updraft speed a function of time? v_is_func = hasattr(self.V, '__call__') if v_is_func: # Re-wrap the function to correctly figure out V orig_der_fcn = der_fcn def der_fcn(y, t, *args): V_t = self.V(t) args[3] = V_t return orig_der_fcn(y, t, *args) ## Will the simulation terminate early? if not terminate: terminate_depth = 0. else: if terminate_depth <= 0.: raise ParcelModelError("`terminate_depth` must be greater than 0!") if self.console: print print "Integration control" print "----------------------------" print " output dt: ", output_dt print " max solver dt: ", solver_dt print " solver int steps: ", int(solver_dt/output_dt ) print " termination: %r (%5dm)" % (terminate, terminate_depth) args = [nr, r_drys, Nis, self.V, kappas, self.accom] integrator_type = Integrator.solver(solver) integrator = integrator_type(der_fcn, output_dt, solver_dt, y0, args, terminate=terminate, terminate_depth=terminate_depth, console=self.console, **solver_args) try: ## Pack args as tuple for solvers args = tuple(args) if self.console: print "\nBEGIN INTEGRATION ->\n" x, t, success = integrator.integrate(t_end) except ValueError, e: raise ParcelModelError("Something failed during model integration: %r" % e)
class LKF(LSProcess): def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float, tau: float = float('inf'), eta_mu: float = 0., eta_var: float = 1., eps=1e-2): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.tau = tau self.eps = eps self.eta_mu = eta_mu self.eta_var = eta_var self.ndim = x0.shape[0] self.err_hist = [] self.eta_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.e_zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_inv_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.zz_tau = np.zeros((self.ndim, self.ndim)) # temp var.. alpha = 0.05 def f(t, state, z_t, err_hist, F_t): # TODO fix all stateful references in this body state = state.reshape(self.ode_shape) x_t, P_t, eta_t = state[:, :1], state[:, 1:1+self.ndim], state[:, 1+self.ndim:] z_t = z_t[:, np.newaxis] K_t = [email protected]@np.linalg.inv(self.R) self.p_t = P_t eta_t = np.zeros((self.ndim, self.ndim)) # TODO warmup case? if t > self.tau: H_inv = np.linalg.inv(self.H) P_inv = np.linalg.solve(P_t.T@P_t + self.eps*np.eye(self.ndim), P_t.T) self.p_inv_t = P_inv err_t, err_tau = err_hist[-1][:,np.newaxis], err_hist[0][:,np.newaxis] self.zz_t = (1 - alpha)*self.zz_t + alpha*err_t@err_t.T self.zz_tau = (1 - alpha)*self.zz_tau + alpha*err_tau@err_tau.T d_zz = (self.zz_t - self.zz_tau) / self.tau # if np.linalg.norm(d_zz) >= 1.0: # d_zz = np.zeros((self.ndim, self.ndim)) self.e_zz_t = d_zz # E_z = sum(err_hist)[:,np.newaxis] / len(err_hist) # d_uu = ((err_t - err_tau)/self.tau)@(E_z.T) + E_z@(((err_t - err_tau)/self.tau).T) eta_t = H_inv@d_zz@H_inv.T@P_inv / 2 self.propose_eta(eta_t) F_est = F_t - self.eta_t d_x = F_est@x_t + K_t@(z_t - self.H@x_t) d_P = F_est@P_t + P_t@F_est.T + self.Q - [email protected]@K_t.T d_eta = np.zeros((self.ndim, self.ndim)) d_state = np.concatenate((d_x, d_P, d_eta), axis=1) return d_state.ravel() # Flatten for integrator def g(t, state): return np.zeros((self.ode_ndim, self.ode_ndim)) # state x0 = x0[:, np.newaxis] # covariance P0 = np.eye(self.ndim) # model variation eta0 = np.zeros((self.ndim, self.ndim)) iv = np.concatenate((x0, P0, eta0), axis=1).ravel() # Flatten for integrator self.r = Integrator(f, g, self.ode_ndim) self.r.set_initial_value(iv, 0.) def __call__(self, z_t: np.ndarray): ''' Observe through filter ''' self.r.set_f_params(z_t, self.err_hist, self.F(self.t)) self.r.integrate(self.t + self.dt) x_t = np.squeeze(self.r.y.reshape(self.ode_shape)[:, :1]) err_t = z_t - [email protected] self.err_hist.append(err_t) if self.t > self.tau: self.err_hist = self.err_hist[1:] return x_t.copy(), err_t # x_t variable gets reused somewhere... @property def ode_shape(self): return (self.ndim, 1 + 2*self.ndim) # representational dimension: x_t, P_t, eta_t @property def ode_ndim(self): return self.ode_shape[0] * self.ode_shape[1] # for raveled representation def propose_eta(self, eta_new: np.ndarray): """ Metropolis-Hastings on variation """ # alpha = self.f_eta(eta_new) / self.f_eta(self.eta_mu) # # pdb.set_trace() # if stats.uniform.rvs() <= alpha: # self.eta_t = eta_new # eta_new = np.clip(eta_new, -.2, .2) self.eta_t = eta_new def f_eta(self, eta: np.ndarray): """ density function of variations """ return stats.multivariate_normal.pdf(eta.ravel(), mean=self.eta_mu.ravel(), cov=self.eta_var.ravel())
XSIM = np.zeros((nsim + 1, 2, n_scenarios)) XSIMEXACT = np.zeros((nsim + 1, 2, n_scenarios)) USIM = np.zeros((nsim, 1, n_scenarios)) VSIMSQRT = np.zeros((nsim, 1, n_scenarios)) ZSIM = np.zeros((nsim, 1, n_scenarios)) DELTAZSIM = np.zeros((nsim, 1, n_scenarios)) VSOSIM = np.zeros((nsim, 1, n_scenarios)) for j in range(len(par.x0_v)): x0 = par.x0_v[j] XSIM[0, :, j] = x0 XSIMEXACT[0, :, j] = x0 # closed loop simulation integrator = Integrator(par.ode) ocp_solver = OcpSolver() ocp_solver.rti_eval() ocp_solver.nlp_eval() if LQR_INIT: if FLIP_LQR_INIT: x0_lqr = -par.x0_v[j] else: x0_lqr = par.x0_v[j] lqr_solver.update_x0(x0_lqr) lqr_solver.lqr_eval() lqr_sol = lqr_solver.get_lqr_sol()
def __init__(self, x_lin=[0, 0], u_lin=0): Td = par.Tp / par.N # linearize model X_lin = ca.MX.sym('X_lin', 2, 1) U_lin = ca.MX.sym('U_lin', 1, 1) A_c = ca.Function('A_c', \ [X_lin, U_lin], [ca.jacobian(par.ode(X_lin, U_lin), X_lin)]) A_c = A_c([0, 0], 0).full() B_c = ca.Function('B_c', \ [X_lin, U_lin], [ca.jacobian(par.ode(X_lin, U_lin), U_lin)]) B_c = B_c([0, 0], 0).full() # solve continuous-time Riccati equation Qt, e, K = cn.care(A_c, B_c, par.Q, par.R) self.integrator = Integrator(par.ode) self.x = self.integrator.x self.u = self.integrator.u self.Td = Td # start with an empty NLP w = [] w0 = [] w_lin = [] lbw = [] ubw = [] g = [] lbg = [] ubg = [] Xk = ca.MX.sym('X0', 2, 1) w += [Xk] lbw += [0, 0] ubw += [0, 0] w0 += [0, 0] w_lin += x_lin f = 0 # formulate the NLP for k in range(par.N): # new NLP variable for the control Uk = ca.MX.sym('U_' + str(k), 1, 1) f = f + Td*ca.mtimes(ca.mtimes(Xk.T, par.Q), Xk) \ + Td*ca.mtimes(ca.mtimes(Uk.T, par.R), Uk) w += [Uk] lbw += [-np.inf] ubw += [np.inf] w0 += [0.0] w_lin += [u_lin] # integrate till the end of the interval Xk_end = self.integrator.eval(Td, Xk, Uk) # new NLP variable for state at end of interval Xk = ca.MX.sym('X_' + str(k + 1), 2, 1) w += [Xk] lbw += [-np.inf, -np.inf] ubw += [np.inf, np.inf] w0 += [0, 0] w_lin += x_lin # add equality constraint g += [Xk_end - Xk] lbg += [0, 0] ubg += [0, 0] f = f + ca.mtimes(ca.mtimes(Xk_end.T, Qt), Xk_end) g = ca.vertcat(*g) w = ca.vertcat(*w) # create an NLP solver self.__lbw = lbw self.__ubw = ubw self.__lbg = lbg self.__ubg = ubg self.__w0 = np.array(w0) self.__lqr_sol = [] # create QP solver nw = len(w0) # define linearization point # w_lin = ca.MX.sym('w_lin', nw, 1) w_qp = ca.MX.sym('w_qp', nw, 1) # linearized objective = original LLS objective f_lin = ca.substitute(f, w, w_qp) nabla_g = ca.jacobian(g, w).T g_lin = ca.substitute(g, w, w_lin) + \ ca.mtimes(ca.substitute(nabla_g, w, w_lin).T, w_qp - w_lin) # create a QP solver prob = {'f': f_lin, 'x': w_qp, 'g': g_lin} self.__lqr_solver = ca.nlpsol('solver', 'ipopt', prob)
def __init__(self, x0: np.ndarray, F: Callable, H: np.ndarray, Q: np.ndarray, R: np.ndarray, dt: float, tau: float = float('inf'), eta_mu: float = 0., eta_var: float = 1., eps=1e-2): self.F = F self.H = H self.Q = Q self.R = R self.dt = dt self.tau = tau self.eps = eps self.eta_mu = eta_mu self.eta_var = eta_var self.ndim = x0.shape[0] self.err_hist = [] self.eta_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.e_zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_inv_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.p_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.zz_t = np.zeros((self.ndim, self.ndim)) # temp var.. self.zz_tau = np.zeros((self.ndim, self.ndim)) # temp var.. alpha = 0.05 def f(t, state, z_t, err_hist, F_t): # TODO fix all stateful references in this body state = state.reshape(self.ode_shape) x_t, P_t, eta_t = state[:, :1], state[:, 1:1+self.ndim], state[:, 1+self.ndim:] z_t = z_t[:, np.newaxis] K_t = [email protected]@np.linalg.inv(self.R) self.p_t = P_t eta_t = np.zeros((self.ndim, self.ndim)) # TODO warmup case? if t > self.tau: H_inv = np.linalg.inv(self.H) P_inv = np.linalg.solve(P_t.T@P_t + self.eps*np.eye(self.ndim), P_t.T) self.p_inv_t = P_inv err_t, err_tau = err_hist[-1][:,np.newaxis], err_hist[0][:,np.newaxis] self.zz_t = (1 - alpha)*self.zz_t + alpha*err_t@err_t.T self.zz_tau = (1 - alpha)*self.zz_tau + alpha*err_tau@err_tau.T d_zz = (self.zz_t - self.zz_tau) / self.tau # if np.linalg.norm(d_zz) >= 1.0: # d_zz = np.zeros((self.ndim, self.ndim)) self.e_zz_t = d_zz # E_z = sum(err_hist)[:,np.newaxis] / len(err_hist) # d_uu = ((err_t - err_tau)/self.tau)@(E_z.T) + E_z@(((err_t - err_tau)/self.tau).T) eta_t = H_inv@d_zz@H_inv.T@P_inv / 2 self.propose_eta(eta_t) F_est = F_t - self.eta_t d_x = F_est@x_t + K_t@(z_t - self.H@x_t) d_P = F_est@P_t + P_t@F_est.T + self.Q - [email protected]@K_t.T d_eta = np.zeros((self.ndim, self.ndim)) d_state = np.concatenate((d_x, d_P, d_eta), axis=1) return d_state.ravel() # Flatten for integrator def g(t, state): return np.zeros((self.ode_ndim, self.ode_ndim)) # state x0 = x0[:, np.newaxis] # covariance P0 = np.eye(self.ndim) # model variation eta0 = np.zeros((self.ndim, self.ndim)) iv = np.concatenate((x0, P0, eta0), axis=1).ravel() # Flatten for integrator self.r = Integrator(f, g, self.ode_ndim) self.r.set_initial_value(iv, 0.)
tmax = 2e3 # ms dt = 0.0005 # ms #init = np.array([18, # V, mvolt #0.1, # h #0.7, # n #0.07, # z #0.1, # s_ampa #0.1, # x_nmda #0.8])# s_nmda init = np.array([-50, # V, mvolt 0.83, # h 0.11, # n 0.002, # z 0.0, # s_ampa 0.0, # x_nmda 0.0])# s_nmda #init = np.zeros(7) m = SGY_neuron() m.set_parameters(**reference_set) # unstable parameters m.par.g_ampa = 0 m.par.g_nmda = 0.09 m.par.w = 1.0 i = Integrator(m, tmax, dt) i.set_initial_conditions(init)
def main(): H = Hamiltonian() locator = Locator(H) integrator = Integrator(H) J = get_metric_mat(2) locate_po = True x = np.array([0.7,1.0,0.3,-0.3]) # print ("Locate minimum by minimum search of Hamiltonian") # mini = locator.find_min(x,method='SLSQP',bounds=((0,2),(0,2),(-1,1),(-1,1))) # if mini.success: # print("found minimum at : {}".format(mini.x)) # else: # print("couldn't find minimum : {}".format(mini.message)) print ("Locate minimum by root finding of Hamiltonian gradient") mini = locator.find_saddle(x,root_method='hybr') if mini.success: print("found critical pt at : {}\n".format(mini.x)) # analyse stability of critical pt eig, eigv, periods = analyse_equilibrium(H, 0.0, mini.x) else: print("couldn't find minimum : {}".format(mini.message)) # just to get options for specific solver # show_options(solver='root', method='broyden1', disp=True) if locate_po and mini.success: print ("\n\n########################\nTrying to locate PO...") period = periods[0] + periods[0]*0.05 dev = np.array([0.5,0,0.1,0]) xini = mini.x + dev #0.1*eigv[:,0] # variational_0 = np.array(np.identity(2*H.dof)).flatten() # xstart = np.concatenate((xini, variational_0)) # print("xstart:\n{}".format(xstart)) # traj = integrator.integrate_variational_plot(x=xstart, tstart=0., tend=period, npts=50) # # traj = integrator.integrate_plot(x=xini, tstart=0., tend=period, npts=50) # print("trajectory:\n{}".format(traj[-1])) # plot_traj(traj,H.dof,'traj.pdf') PO_sol = locator.locatePO(xini,period,root_method='broyden1',integration_method="dop853") if PO_sol.success: print("success : {}".format(PO_sol.success)) print("PO initial conditions {}".format(PO_sol.x)) # compute monodromy matrix variational_0 = np.array(np.identity(2*H.dof)).flatten() xstart = np.concatenate((PO_sol.x, variational_0)) print("xstart:\n{}".format(xstart)) traj = integrator.integrate_variational(x=xstart, tstart=0., tend=period,method="dop853") # last = traj[-1] monod = np.reshape(traj[2*H.dof:], (2*H.dof, 2*H.dof)) print("monodromy matrix:\n{}".format(monod)) eig, eigenvec = compute_eigenval_mat(monod) for i in range(eig.size): print("eigenvalue: {}".format(eig[i])) # PO = integrator.integrate_plot(PO_sol.x,0,period,'dop853',100) # print("PO:\n{}".format(PO)) # plot_traj(traj,H.dof,'PO.pdf') else: print("Couldn't find PO : {}".format(PO_sol.message))