Source code for hetero.stims.maps


import numpy as np
from typing import Union
from hetero.stims.utils import get_seed, rand_generator, check_vector, RandomState

[docs] def henon_map( n_timesteps: int, a: float = 1.4, b: float = 0.3, x0: Union[list, np.ndarray] = [0.0, 0.0], **kwargs, ) -> np.ndarray: """Hénon map discrete timeseries [2]_ [3]_. .. math:: x(n+1) &= 1 - ax(n)^2 + y(n)\\\\ y(n+1) &= bx(n) Parameters ---------- n_timesteps : int Number of timesteps to generate. a : float, default to 1.4 :math:`a` parameter of the system. b : float, default to 0.3 :math:`b` parameter of the system. x0 : array-like of shape (2,), default to [0.0, 0.0] Initial conditions of the system. Returns ------- array of shape (n_timesteps, 2) Hénon map discrete timeseries. """ states = np.zeros((n_timesteps, 2)) states[0] = np.asarray(x0) for i in range(1, n_timesteps): states[i][0] = 1 - a * states[i - 1][0] ** 2 + states[i - 1][1] states[i][1] = b * states[i - 1][0] return states
[docs] def logistic_map(n_timesteps: int, r: float = 3.9, x0: float = 0.5, **kwargs) -> np.ndarray: """Logistic map discrete timeseries [4]_ [5]_. .. math:: x(n+1) = rx(n)(1-x(n)) Parameters ---------- n_timesteps : int Number of timesteps to generate. r : float, default to 3.9 :math:`r` parameter of the system. x0 : float, default to 0.5 Initial condition of the system. Returns ------- array of shape (n_timesteps, 1) Logistic map discrete timeseries. """ if r > 0 and 0 < x0 < 1: X = np.zeros(n_timesteps) X[0] = x0 for i in range(1, n_timesteps): X[i] = r * X[i - 1] * (1 - X[i - 1]) return X.reshape(-1, 1) elif r <= 0: raise ValueError("r should be positive.") else: raise ValueError("Initial condition x0 should be in ]0;1[.")
[docs] def narma( n_timesteps: int, order: int = 30, a1: float = 0.2, a2: float = 0.04, b: float = 1.5, c: float = 0.001, x0: Union[list, np.ndarray] = [0.0], seed: Union[int, RandomState] = None, ) -> np.ndarray: """Non-linear Autoregressive Moving Average (NARMA) timeseries, as first defined in [14]_, and as used in [15]_. NARMA n-th order dynamical system is defined by the recurrent relation: .. math:: y[t+1] = a_1 y[t] + a_2 y[t] (\\sum_{i=0}^{n-1} y[t-i]) + b u[t-( n-1)]u[t] + c where :math:`u[t]` are sampled following a uniform distribution in :math:`[0, 0.5]`. Parameters ---------- n_timesteps : int Number of timesteps to generate. order: int, default to 30 Order of the system. a1 : float, default to 0.2 :math:`a_1` parameter of the system. a2 : float, default to 0.04 :math:`a_2` parameter of the system. b : float, default to 1.5 :math:`b` parameter of the system. c : float, default to 0.001 :math:`c` parameter of the system. x0 : array-like of shape (init_steps,), default to [0.0] Initial conditions of the system. seed : int or :py:class:`numpy.random.Generator`, optional Random state seed for reproducibility. Returns ------- array of shape (n_timesteps, 1) NARMA timeseries. """ if seed is None: seed = get_seed() rs = rand_generator(seed) y = np.zeros((n_timesteps + order, 1)) x0 = check_vector(np.atleast_2d(np.asarray(x0))) y[: x0.shape[0], :] = x0 noise = rs.uniform(0, 0.5, size=(n_timesteps + order, 1)) for t in range(order, n_timesteps + order - 1): y[t + 1] = ( a1 * y[t] + a2 * y[t] * np.sum(y[t - order : t]) + b * noise[t - order] * noise[t] + c ) return y[order:, :]