コード例 #1
0
def est_lyapunov(kf, noise_level):
    # T = 1
    T = 10
    x0 = 0.05
    z0 = 9.0
    v0 = 0.85
    tol = 1e-8

    diff = 1e-10
    dt = 0.002
    nbr_itr = math.floor(T / dt)

    lyapunov = 0

    u = np.array([x0, z0, v0])
    v = np.array([x0 + diff, z0, v0])

    for i in range(0, nbr_itr):

        flow_diff = np.random.normal(loc=0, scale=noise_level)
        gf = GyorgyiFieldModel(kf + kf * flow_diff)

        solver = DOP853(gf.rhs, 0, u, dt, atol=tol, rtol=tol)
        while solver.status == "running":
            solver.step()
        u = solver.y

        solver = DOP853(gf.rhs, 0, v, dt, atol=tol, rtol=tol)
        while solver.status == "running":
            solver.step()
        v = solver.y

        delta = v - u
        d = np.linalg.norm(delta)
        if i >= 200:
            lyapunov += np.log(d / diff)

        v = u + diff * delta / d

    lyapunov = lyapunov / (dt * (nbr_itr - 200))
    return lyapunov
コード例 #2
0
 def reset(self):
     if self.has_integrator:
         if self.integrator_type == Integrators.lsoda:
             self.integrator = LSODA(self.dydt,
                                     self.t0,
                                     self.dydt_y0,
                                     np.inf,
                                     max_step=self.dydt_max_step,
                                     **self.dydt_solver_args)
         elif self.integrator_type == Integrators.dop853:
             self.integrator = DOP853(lambda t, y: self.dydt_y0,
                                      self.t0,
                                      self.dydt_y0,
                                      np.inf,
                                      max_step=self.dydt_max_step,
                                      **self.dydt_solver_args)
             self.integrator.fun = self.dydt
         elif self.integrator_type == Integrators.rk45:
             self.integrator = RK45(lambda t, y: self.dydt_y0,
                                    self.t0,
                                    self.dydt_y0,
                                    np.inf,
                                    max_step=self.dydt_max_step,
                                    **self.dydt_solver_args)
             self.integrator.fun = self.dydt
         elif self.integrator_type == Integrators.implicit_midpoint:
             self.integrator = ImplicitMidpoint(self.dydt,
                                                self.t0,
                                                self.dydt_y0,
                                                np.inf,
                                                max_step=self.dydt_max_step,
                                                **self.dydt_solver_args)
         else:
             raise ValueError(
                 f'Unsupported integrator type: {self.integrator_type}')
     for sys in self.systems[IterationMode.cvx] + self.systems[
             IterationMode.map]:
         sys.reset()
         self.discrete_y[sys.uuid] = sys._y.copy()
     for sys in self.systems[IterationMode.traj]:
         sys.reset()
コード例 #3
0
def auto_test_Lorenz63(dt,
                       N,
                       lam,
                       deriv,
                       initial_state,
                       lib_combos,
                       nnoise=0,
                       vis=False):
    t0 = 0
    t_bound = dt * N
    solver_obj = DOP853(Lorenz63,
                        t0,
                        initial_state,
                        t_bound,
                        max_step=dt,
                        first_step=dt)
    X = np.zeros((N + 1, 3))
    X[0] = initial_state
    #compute output
    for i in range(N):
        solver_obj.step()
        X[i + 1] = solver_obj.y
    X_dot = np.zeros((N + 1, 3))
    for i in range(3):
        X_dot[:, i] = deriv(X[:, i], dt)
    sdsX = np.std(X)
    sdsXdot = np.std(X_dot)
    X_n = X + nnoise * sdsX * np.random.randn(N + 1, 3)
    X_dot_n = X_dot + nnoise * sdsXdot * np.random.randn(N + 1, 3)
    Theta = gen_Theta(lib_combos, N, X_n)
    Xi = xlstsq(Theta, X_dot_n)
    Xi = STLS(lam, Xi, X_dot_n, Theta)
    #print(Xi)
    (fx, fy, fz) = ret_eq(lib_combos, Xi)
    print_eq(lib_combos, Xi)

    def Lorenz_Reco(t, vals):
        x, y, z = vals[0], vals[1], vals[2]
        return [fx(x, y, z), fy(x, y, z), fz(x, y, z)]

    t0 = 0
    t_bound = dt * N
    #create solver object
    solver_obj_reco = DOP853(Lorenz_Reco,
                             t0,
                             initial_state,
                             t_bound,
                             max_step=dt,
                             first_step=dt)
    #set up data matrix
    X_reco = np.zeros((N + 1, 3))
    X_reco[0] = initial_state
    #compute output
    for i in range(N):
        solver_obj_reco.step()
        X_reco[i + 1] = solver_obj_reco.y
        if solver_obj_reco.status != 'running': break
    #transient and error time
    trans = int(2 / dt)
    end_t = int(10 / dt) + trans + 1
    errors = np.mean(np.abs(X[trans:end_t, :] - X_reco[trans:end_t, :]),
                     axis=0)
    #plots
    if vis:
        # this is whats used to generate the reconstructed trajectory and attractor plots
        # uncomment as required etc.
        #     num_dim = 1
        # #time series
        #     times = np.arange(0,dt*N+dt,dt)
        #     t**s = ['x','y','z']
        #     for i in range(num_dim):
        #         plt.subplot(3,1,i+1)
        #         plt.plot(times[trans:end_t], X[trans:end_t,i],'k', lw = 2, label = 'true TS')
        #         plt.plot(times[trans:end_t], X_reco[trans:end_t,i],'--r', lw = 1,  label = 'reco TS')
        #         plt.xlabel('time')
        #         plt.legend(loc='best')
        #         plt.ylabel(t**s[i])
        #     plt.show()
        # or attractor
        plt.rcParams["figure.figsize"] = (12, 12)
        plt.rcParams.update({'font.size': 16})
        fig = plt.figure()
        ax = plt.axes(projection='3d')
        ax.plot3D(X_reco[:, 0],
                  X_reco[:, 1],
                  X_reco[:, 2],
                  lw=0.4,
                  label='Traj 1')
        ax.plot3D(initial_state[0],
                  initial_state[1],
                  initial_state[2],
                  '*',
                  label='IC 1')
        ax.set(xlabel='x', ylabel='y', zlabel='z')
        ax.legend(loc='best')
        plt.show()
    return np.mean(errors)
コード例 #4
0
plt.plot(tests, fd_der, label='Finite Diff', lw=3)
plt.plot(tests, testsder, label='Analytical')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='best')
#%%
# Butterfly attractor plot (with two trajectories)
dt = 0.02
N = 10000
initial_state = [2, 10, 5]
initial_state_2 = [2.05, 9.95, 5.05]
t0 = 0
t_bound = dt * N
solver_obj = DOP853(Lorenz63,
                    t0,
                    initial_state,
                    t_bound,
                    max_step=dt,
                    first_step=dt)
solver_obj_2 = DOP853(Lorenz63,
                      t0,
                      initial_state_2,
                      t_bound,
                      max_step=dt,
                      first_step=dt)
#set up data matrix
X = np.zeros((N + 1, 3))
X[0] = initial_state
#compute output
for i in range(N):
    solver_obj.step()
    X[i + 1] = solver_obj.y
コード例 #5
0
    def __init__(self, *systems: Tuple[fds]):
        assert len(systems) >= 1, 'Pass one or more systems to couple'
        assert all([sys.t == 0. for sys in systems
                    ]), 'All systems must be at zero-time initial conditions.'
        assert all([sys.iter_mode != IterationMode.none for sys in systems
                    ]), 'All systems must have evolution laws.'
        self.t0 = 0.
        for sys in systems:
            sys.uuid = shortuuid.uuid()  # Hacky..
        self.systems = {
            IterationMode.dydt:
            list(
                filter(lambda sys: sys.iter_mode is IterationMode.dydt,
                       systems)),
            IterationMode.cvx:
            list(
                filter(lambda sys: sys.iter_mode is IterationMode.cvx,
                       systems)),
            IterationMode.map:
            list(
                filter(lambda sys: sys.iter_mode is IterationMode.map,
                       systems)),
            IterationMode.traj:
            list(
                filter(lambda sys: sys.iter_mode is IterationMode.traj,
                       systems)),
        }

        # Common state for discrete systems
        self.discrete_t = self.t0
        self.discrete_y = {
            sys.uuid: sys.y0
            for sys in self.systems[IterationMode.cvx] +
            self.systems[IterationMode.map]
        }

        # Common state for continuous systems
        self.has_integrator = len(self.systems[IterationMode.dydt]) > 0
        if self.has_integrator:
            self.integrator_type = self.systems[
                IterationMode.dydt][0].integrator_type
            assert all([
                sys.integrator_type is self.integrator_type
                for sys in self.systems[IterationMode.dydt]
            ]), 'All continuous dynamics must use the same integrator.'
            dydt_systems = self.systems[IterationMode.dydt]
            self.dydt_max_step = min([sys.max_step for sys in dydt_systems])
            self.dydt_solver_args = merge_dicts(
                [sys.solver_args for sys in dydt_systems])
            self.dydt_y0 = np.concatenate(
                [sys.y0 for sys in self.systems[IterationMode.dydt]])

            if self.integrator_type == Integrators.lsoda:
                self.integrator = LSODA(self.dydt,
                                        self.t0,
                                        self.dydt_y0,
                                        np.inf,
                                        max_step=self.dydt_max_step,
                                        **self.dydt_solver_args)
            elif self.integrator_type == Integrators.dop853:
                self.integrator = DOP853(lambda t, y: self.dydt_y0,
                                         self.t0,
                                         self.dydt_y0,
                                         np.inf,
                                         max_step=self.dydt_max_step,
                                         **self.dydt_solver_args)
                self.integrator.fun = self.dydt
            elif self.integrator_type == Integrators.rk45:
                self.integrator = RK45(lambda t, y: self.dydt_y0,
                                       self.t0,
                                       self.dydt_y0,
                                       np.inf,
                                       max_step=self.dydt_max_step,
                                       **self.dydt_solver_args)
                self.integrator.fun = self.dydt
            elif self.integrator_type == Integrators.implicit_midpoint:
                self.integrator = ImplicitMidpoint(self.dydt,
                                                   self.t0,
                                                   self.dydt_y0,
                                                   np.inf,
                                                   max_step=self.dydt_max_step,
                                                   **self.dydt_solver_args)
            else:
                raise ValueError(
                    f'Unsupported integrator type: {self.integrator_type}')

        # Attach views to state
        last_index = 0
        for sys in self.systems[IterationMode.dydt]:
            sys.view = slice(last_index, last_index + sys.y0.size)
            attach_dyn_props(
                sys, {
                    'y': lambda sys: self.integrator.y[sys.view],
                    't': lambda _: self.t
                })
            last_index += sys.y0.size

        for sys in self.systems[IterationMode.cvx]:
            attach_dyn_props(sys, {
                'y': lambda sys: self.discrete_y[sys.uuid],
                't': lambda _: self.t
            })

        for sys in self.systems[IterationMode.map]:
            attach_dyn_props(sys, {
                'y': lambda sys: self.discrete_y[sys.uuid],
                't': lambda _: self.t
            })
コード例 #6
0
    def set_evolution(
        self,
        dydt: Callable[[Time, np.ndarray], np.ndarray] = None,
        order: int = 1,
        max_step: float = 1e-3,
        integrator=Integrators.lsoda,
        solver_args: Dict = {},
        lhs: Callable[[Time, np.ndarray], np.ndarray] = None,
        cost: Callable[[Time, np.ndarray], float] = None,
        refresh_cvx: float = True,
        map_fun: Callable[[Time, np.ndarray], np.ndarray] = None,
        dt: float = 1.0,
        traj_t: Iterable[Time] = None,
        traj_y: Iterable[np.ndarray] = None,
        nil: bool = False,
    ):
        ''' Define evolution law for the dynamics.

		Option 1: As a PDE
			dydt: Callable[Time]
				RHS of differential equation [uses LSODA for stiffness detection; falls back to DOP853 if not available]
			order: int
				[optional] Order of time-difference; if greater than one, automatically creates (order*ndim) state vector
			max_step: float
				[optional] Maximum allowed step size in the solver; default 1e-3
			solver_args: Dict
				[optional] Additional arguments to be passed to the solver

		Option 2: As a convex program
			lhs: Callable[Time]
				RHS of an equation set to 0
			cost: Callable[time]
				RHS of a disciplined-convex cost function (either array-like or scalar)
			solver_args: Dict
				[optional] Additional arguments to be passed to the solver
			refresh_cvx: bool (TODO)
				whether the problem is time-dependent.

		Option 3: As a recurrence relation
			map_fun: Callable[time]
				RHS of recurrence relation
			dt: float
				[default 1.0] time delta for stepping 

		Option 4: As a data-derived trajectory
			traj_t: Iterable[Time]
			traj_y: Iterable[np.ndarray]

		Option 5: As a nil-evolution (time-invariant system)
			nil: bool
		'''
        assert oneof([
            dydt != None, lhs != None, cost != None, map_fun != None,
            traj_t != None, nil
        ]), 'Exactly one evolution law must be specified'

        if dydt != None:
            self.iter_mode = IterationMode.dydt
            self.dydt_fun = dydt
            self.max_step = max_step
            self._dt = self.max_step
            self.order = order
            self.solver_args = solver_args
            self.y0 = np.zeros(self.ndim * order)

            self.integrator_type = integrator
            if self.integrator_type == Integrators.lsoda:
                self.integrator = LSODA(self.dydt,
                                        self.t0,
                                        self.y0,
                                        np.inf,
                                        max_step=max_step,
                                        **solver_args)
            elif self.integrator_type == Integrators.dop853:
                self.integrator = DOP853(lambda t, y: self.y0,
                                         self.t0,
                                         self.y0,
                                         np.inf,
                                         max_step=max_step,
                                         **solver_args)
                self.integrator.fun = self.dydt
            elif self.integrator_type == Integrators.rk45:
                self.integrator = RK45(lambda t, y: self.y0,
                                       self.t0,
                                       self.y0,
                                       np.inf,
                                       max_step=max_step,
                                       **solver_args)
                self.integrator.fun = self.dydt
            elif self.integrator_type == Integrators.implicit_midpoint:
                self.integrator = ImplicitMidpoint(self.dydt,
                                                   self.t0,
                                                   self.y0,
                                                   np.inf,
                                                   max_step=max_step,
                                                   **solver_args)
            else:
                raise ValueError(
                    f'Unsupported integrator type: {self.integrator_type}')

        elif lhs != None or cost != None:
            if lhs != None:
                cost = lambda t, y: cp.sum_squares(lhs(t, y))
            self.iter_mode = IterationMode.cvx
            self.cost_fun = cost
            self.solver_args = solver_args
            self.refresh_cvx = refresh_cvx
            self.initialized = False
            self.y0 = np.zeros(self.ndim)
            self._t = self.t0
            self._y = self.y0.copy()
            self._t_prb = cp.Parameter(nonneg=True)
            self._y_prb = cp.Variable(self._y.size)
            _cost = cost(self._t_prb, self._y_prb)
            assert _cost.shape == (), 'Cost is not scalar'
            assert _cost.is_dcp(), 'Problem is not disciplined-convex'
            self._prb = cp.Problem(cp.Minimize(_cost), [])

        elif map_fun != None:
            self.iter_mode = IterationMode.map
            self.map_fun = map_fun
            self.y0 = np.zeros(self.ndim)
            self._dt = dt
            self._t = self.t0
            self._n = self._t
            self._y = self.t0.copy()

        elif traj_t != None:
            assert traj_t[0] == self.t0, 'Ensure trajectory starts at t=0'
            self.iter_mode = IterationMode.traj
            self.traj_t, self.traj_y = traj_t, traj_y
            self._t = self.t0
            self._i = 0

        elif nil:
            self.iter_mode = IterationMode.nil
            self._t = 0
            self._y = np.zeros(self.ndim)
            self.y0 = np.zeros(self.ndim)
コード例 #7
0
noise_level = 0.1

dt = 0.0002
n_itr = math.floor(T / dt)

sol_x = [0] * n_itr
sol_z = [0] * n_itr
sol_v = [0] * n_itr

for i in range(0, n_itr):

    flow_diff = np.random.normal(loc=0, scale=noise_level)
    gf = GyorgyiFieldModel(kf + kf * flow_diff)

    solver = DOP853(gf.rhs, 0, np.array([x0, z0, v0]), dt, atol=tol, rtol=tol)
    while solver.status == "running":
        solver.step()

    x0 = solver.y[0]
    z0 = solver.y[1]
    v0 = solver.y[2]

    sol_x[i] = solver.y[0]
    sol_z[i] = solver.y[1]
    sol_v[i] = solver.y[2]

fig = plt.figure()
ax = plt.axes(projection="3d")
ax.plot(
    np.log10(np.abs(sol_x)),
コード例 #8
0
    x, y, z = vals[0], vals[1], vals[2]
    return [10 * (y - x), 28 * x - y - x * z, -8 / 3 * z + x * y]


#%%
#set up initial conditions
dt = 0.02
N = 10000
initial_state = [2, 10, 5]
t0 = 0
t_bound = dt * N

#create solver object
solver_obj = DOP853(Lorenz63,
                    t0,
                    initial_state,
                    t_bound,
                    max_step=dt,
                    first_step=dt)

#set up data matrix
X = np.zeros((N + 1, 3))
X[0] = initial_state
#%%
#compute output
for i in range(N):
    solver_obj.step()
    X[i + 1] = solver_obj.y
#%%
initial_state_2 = [2.05, 9.95, 5.05]
t0 = 0
t_bound = dt * N