Beispiel #1
0
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
Beispiel #2
0
    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.)
Beispiel #3
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
Beispiel #8
0
    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()
Beispiel #9
0
    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()
Beispiel #10
0
    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()
Beispiel #11
0
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)
Beispiel #13
0
 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
Beispiel #14
0
    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))
Beispiel #16
0
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
Beispiel #18
0
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())
Beispiel #19
0
	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.)
Beispiel #20
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.)
Beispiel #21
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()
Beispiel #22
0
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()
Beispiel #23
0
    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)
Beispiel #26
0
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
Beispiel #27
0
    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.)
Beispiel #28
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)
Beispiel #29
0

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)
Beispiel #32
0
    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)
Beispiel #33
0
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())
Beispiel #34
0
    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)
Beispiel #36
0
	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.)
Beispiel #37
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)
Beispiel #38
0
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))