import numpy as np
[docs]
def logistic_map(parameters=[3.5], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The logistic map [1]_ was generated as
.. math::
x_{n+1} = rx_n(1-x_n)
where we chose the parameters :math:`x_0 = 0.5` and :math:`r = 3.6` for a chaotic state. You can set :math:`r = 3.5` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Logistic_map.png
Parameters:
parameters (Optional[float]): Array of 1 float [r]
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [1] May, Robert. "Simple mathematical models with very complicated dynamics". Nature, 1976.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 1
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
r = 3.5
elif dynamic_state == 'chaotic':
r = 3.6
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
else:
r = parameters[0]
if InitialConditions == None:
InitialConditions = [0.5]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = r*xn*(1-xn)
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def henon_map(parameters=[1.25, 0.3, 1.0], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Hénon map [2]_ was solved as
.. math::
x_{n+1} &= 1 -ax_n^2+y_n,
y_{n+1}&=bx_n
where we chose the parameters :math:`a = 1.20`, :math:`b = 0.30`, and :math:`c = 1.00` for a chaotic state with initial conditions :math:`x_0 = 0.1` and :math:`y_0 = 0.3`. You can set :math:`a = 1.25` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Henon_map.png
Parameters:
parameters (Optional[floats]): Array of 3 floats [a,b,c].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [2] Hénon, Michel. "A two-dimensional mapping with a strange attractor". Communications in Mathematical Physics, 1976.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 3
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a = 1.25
elif dynamic_state == 'chaotic':
a = 1.20
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
b, c = 0.3, 1.0
else:
a, b, c = parameters[0], parameters[1], parameters[2]
# defining simulation functions
def henon(a, b, c, x, y):
return y + c - a*x*x, b*x
if InitialConditions == None:
InitialConditions = [0.1, 0.3]
xtemp = InitialConditions[0]
ytemp = InitialConditions[1]
x, y = [], []
for n in range(0, int(L)):
xtemp, ytemp = henon(a, b, c, xtemp, ytemp)
x.append(xtemp)
y.append(ytemp)
ts = [x[-SampleSize:], y[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def sine_map(parameters=[0.8], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Sine map is defined as
.. math::
x_{n+1} = A\sin{(\pi x_n)}
where we chose the parameter :math:`A = 1.0` for a chaotic state with initial condition :math:`x_0 = 0.1`. You can also change :math:`A = 0.8` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Sine_map.png
Parameters:
parameters (Optional[floats]): Array of 1 float [A].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
"""
t = np.linspace(0, L, int(L*fs))
num_param = 1
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
A = 0.8
elif dynamic_state == 'chaotic':
A = 1.0
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
else:
A = parameters[0]
if InitialConditions == None:
InitialConditions = [0.1]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = A*np.sin(np.pi*xn)
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def tent_map(parameters=[1.05], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Tent map [3]_ was solved as
.. math::
x_{n+1} = A\min{([x_n, 1-x_n])}
where we chose the parameter :math:`A = 1.50` for a chaotic state with initial condition :math:`x_0 = 1/\sqrt{2}`. You can also change :math:`A = 1.05` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Tent_map.png
Parameters:
parameters (Optional[float]): Array of 1 float [A].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [3] Crampin, Michael. "On the chaotic behaviour of the tent map". Teaching Mathematics and its Applications, 1994.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 1
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
A = 1.05
elif dynamic_state == 'chaotic':
A = 1.5
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
else:
A = parameters[0]
if InitialConditions == None:
InitialConditions = [1/np.sqrt(2)]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = A*np.min([xn, 1-xn])
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def linear_congruential_generator_map(parameters=[0.9, 54773, 259200], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Linear Congruential Generator map is defined as
.. math::
x_{n+1}=(ax_n+b)\mod c
where we chose the parameter :math:`a = 1.1` for a chaotic state with initial condition :math:`x_0 = 0.1`. You can also change :math:`a = 0.9` for a periodic response. :math:`b` and :math:`c` are set to 54,773 and 259,200 respectively for both dynamic states. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Linear_Congruential_Generator_map.png
Parameters:
parameters (Optional[float]): Array of 3 floats [a,b,c].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
"""
t = np.linspace(0, L, int(L*fs))
num_param = 3
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a = 0.9
elif dynamic_state == 'chaotic':
a = 1.1
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
else:
a, b, c = parameters[0], parameters[1], parameters[2]
if InitialConditions == None:
InitialConditions = [0.1]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = (a*xn + b) % c
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def rickers_population_map(parameters=[13], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Ricker's Population map is defined [4]_ as
.. math::
x_{n+1}=ax_n e^{-x_n}
where we chose the parameter :math:`a = 20` for a chaotic state with initial condition :math:`x_0 = 0.1`. You can set :math:`a = 13` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Rickers_Popoulation_map.png
Parameters:
parameters (Optional[float]): Array of 1 parameter [a].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [4] Ricker, William Edwin. "Stock and recruitment". Journal of the Fisheries Research Board of Canada, 1954.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 1
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a = 13
elif dynamic_state == 'chaotic':
a = 20
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
else:
a = parameters[0]
if InitialConditions == None:
InitialConditions = [0.1]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = a*xn*np.exp(-xn)
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def gauss_map(parameters=[6.20, -0.20], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Gauss map is defined [5]_ as
.. math::
x_{n+1}=e^{-\\alpha x_n^2}+\\beta
where we chose the parameters :math:`\\alpha = 6.20` and :math:`\\beta = -0.35` for a chaotic state with initial condition :math:`x_0 = 0.1`. You can set :math:`\\beta = -0.20` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients. Taken from https://en.wikipedia.org/wiki/Gauss_iterated_map
.. figure:: ../../../figures/Maps/Gauss_map.png
Parameters:
parameters (Optional[floats]): Array of parameters [alpha, beta].
beta (Optional[float]): System parameter.
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [5] Hilborn, Robert C. "Chaos and nonlinear dynamics: an introduction for scientists and engineers". Oxford, Univ. Press, 2004.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 2
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
beta = -0.20
elif dynamic_state == 'chaotic':
beta = -0.35
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
alpha = 6.20
else:
alpha, beta = parameters[0], parameters[1]
if InitialConditions == None:
InitialConditions = [0.1]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = np.exp(-alpha*xn**2) + beta
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def cusp_map(parameters=[1.1], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Cusp map is defined [6]_ as
.. math::
x_{n+1} = 1 - a\sqrt{|x_n|}
where we chose the parameter :math:`a = 1.2` for a chaotic state with initial condition :math:`x_0 = 0.5`. You can set :math:`a = 1.1` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Cusp_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [a].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [6] Beck, Christian. "Thermodynamics of Chaotic Systems". Cambridge University Press, 2009.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 1
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a = 1.1
elif dynamic_state == 'chaotic':
a = 1.2
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
else:
a = parameters[0]
if InitialConditions == None:
InitialConditions = [0.5]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = 1-a*np.sqrt(np.abs(xn))
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def pinchers_map(parameters=[1.3, 0.5], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Pincher's map is defined [7]_ as
.. math::
x_{n+1} = |\\tanh{(s(x_n-c))}|
where we chose the parameters :math:`s = 1.6` and :math:`c = 0.5` for a chaotic state with initial condition :math:`x_0 = 0.0`. You can set :math:`s = 1.3` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Pinchers_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [s,c].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [7] Akgul, Akif. "Text Encryption by Using One-Dimensional Chaos Generators and Nonlinear Equations". International Conference on Electrical and Electronics Engineering, ELECO, 2013.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 2
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
s = 1.3
elif dynamic_state == 'chaotic':
s = 1.6
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
c = 0.5
else:
s, c = parameters[0], parameters[1]
if InitialConditions == None:
InitialConditions = [0.0]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = np.abs(np.tanh(s*(xn-c)))
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def sine_circle_map(parameters=[0.5, 1.5], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Sine Circle map is defined [8]_ as
.. math::
x_{n+1} = x_n + \\omega -\\left[\\frac{k}{2\\pi}\sin{(2\\pi x_n)}\\right]
where we chose the parameters :math:`\\omega = 0.5` and :math:`k = 2.0` for a chaotic state with initial condition :math:`x_0 = 0.0`. You can set :math:`k = 1.5` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Sine_Circle_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [omega, k].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [8] Arnold, V.I. "Small denominators. i. mapping the circle onto itself". Izv. Akad. Nauk SSSR Ser. Mat., 1961.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 2
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
k = 1.5
elif dynamic_state == 'chaotic':
k = 2.0
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
omega = 0.5
else:
omega, k = parameters[0], parameters[1]
if InitialConditions == None:
InitialConditions = [0.0]
xn = InitialConditions[0]
t, ts = [], []
for n in range(0, int(L)):
xn = xn + omega - (k/(2*np.pi))*np.sin(2*np.pi*xn) % 1
ts = np.append(ts, xn)
t = np.append(t, n)
ts = [ts[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def lozi_map(parameters=[1.5, 0.5], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Lozi map is defined [9]_ as
.. math::
x_{n+1} &= 1 - a|x_n| +by_n,
y_{n+1} &= x_n
where we chose the parameters :math:`a = 1.7` and :math:`b = 0.5` for a chaotic state with initial conditions :math:`x_0 = -0.1` and :math:`y_0 = 0.1`. You can set :math:`a = 1.5` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Lozi_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [a,b].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [9] Peitgen, Heinz-Otto. "Chaos and Fractals New Frontiers of Science". Springer-Verlag, 1992.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 2
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a = 1.5
elif dynamic_state == 'chaotic':
a = 1.7
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
b = 0.5
else:
a, b = parameters[0], parameters[1]
# defining simulation functions
def lozi(a, b, x, y):
return 1-a*np.abs(x) + b*y, x
if InitialConditions == None:
InitialConditions = [-0.1, 0.1]
xtemp = InitialConditions[0]
ytemp = InitialConditions[1]
x, y = [], []
for n in range(0, int(L)):
xtemp, ytemp = lozi(a, b, xtemp, ytemp)
x.append(xtemp)
y.append(ytemp)
ts = [x[-SampleSize:], y[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def delayed_logstic_map(parameters=[2.20], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Delayed Logistic map is defined [10]_ as
.. math::
x_{n+1} &= ax_n(1-y_n)
y_{n+1} &= x_n
where we chose the parameter :math:`a = 2.27` for a chaotic state with initial conditions :math:`x_0 = 0.001` and :math:`y_0 = 0.001`. You can set :math:`a = 2.20` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Delayed_Logistic_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [a].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [10] Ismail, Samar M. "Generalized Delayed Logistic Map Suitable For Pseudo-random Number Generation". International Conference on Science and Technology, 2015.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 1
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a = 2.20
elif dynamic_state == 'chaotic':
a = 2.27
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
else:
a = parameters[0]
# defining simulation functions
def delay_log(a, x, y):
return a*x*(1-y), x
if InitialConditions == None:
InitialConditions = [0.001, 0.001]
xtemp = InitialConditions[0]
ytemp = InitialConditions[1]
x, y = [], []
for n in range(0, int(L)):
xtemp, ytemp = delay_log(a, xtemp, ytemp)
x.append(xtemp)
y.append(ytemp)
ts = [x[-SampleSize:], y[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def tinkerbell_map(parameters=[0.7, -0.6, 2, 0.5], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Tinkerbell map is defined [11]_ as
.. math::
x_{n+1} &= x_n^2 - y_n^2 + ax_n + by_n,
y_{n+1} &= 2x_ny_n + cx_n + dy_n
where we chose the parameters :math:`a = 0.9`, :math:`b = -0.6`, :math:`c = 2.0`, and :math:`d = 0.5` for a chaotic state with initial conditions :math:`x_0 = 0.0` and :math:`y_0 = 0.5`. You can set :math:`a = 0.7` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Tinkerbell_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [a,b,c,d].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [11] Goldsztejn, Alexandre M. "Tinkerbell is chaotic". SIAM Journal on Applied Dynamical Systems, 2011.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 4
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a = 0.7
elif dynamic_state == 'chaotic':
a = 0.9
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
b, c, d = -0.6, 2, 0.5
else:
a, b, c, d = parameters[0], parameters[1], parameters[2], parameters[3]
# defining simulation functions
def tinkerbell(a, b, c, d, x, y):
return x**2 - y**2 + a*x + b*y, 2*x*y + c*x + d*y
if InitialConditions == None:
InitialConditions = [0.0, 0.5]
xtemp = InitialConditions[0]
ytemp = InitialConditions[1]
x, y = [], []
for n in range(0, int(L)):
xtemp, ytemp = tinkerbell(a, b, c, d, xtemp, ytemp)
x.append(xtemp)
y.append(ytemp)
ts = [x[-SampleSize:], y[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def burgers_map(parameters=[0.75, 1.6], dynamic_state=None, InitialConditions=None,
L=3000.0, fs=1, SampleSize=500):
"""
The Burger's map is defined [12]_ as
.. math::
x_{n+1} &= ax_n - y_n^2,
y_{n+1} &= by_n + x_ny_n
where we chose the parameters :math:`a = 0.75` and :math:`b = 1.75` for a chaotic state with initial conditions :math:`x_0 = -0.1` and :math:`y_0 = 0.5`. You can set :math:`b = 1.60` for a periodic response. We solve this system for 3000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Burgers_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [a,b].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [12] Burgers, J. M. "Mathematical examples illustrating relations occurring in the theory of turbulent fluid motion". Trans. Roy. Neth. Acad. Sci. Amsterdam., 1995.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 2
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
b = 1.6
elif dynamic_state == 'chaotic':
b = 1.75
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
a = 0.75
else:
a, b = parameters[0], parameters[1]
# defining simulation functions
def burgers(a, b, x, y):
return a*x - y**2, b*y + x*y
if InitialConditions == None:
InitialConditions = [-0.1, 0.1]
xtemp = InitialConditions[0]
ytemp = InitialConditions[1]
x, y = [], []
for n in range(0, int(L)):
xtemp, ytemp = burgers(a, b, xtemp, ytemp)
x.append(xtemp)
y.append(ytemp)
ts = [x[-SampleSize:], y[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def holmes_cubic_map(parameters=[0.27, 2.77], dynamic_state=None, InitialConditions=None,
L=3000.0, fs=1, SampleSize=500):
"""
The Holme's Cubic map is defined [13]_ as
.. math::
x_{n+1} &= y_n,
y_{n+1} &= -bx_n + dy_n - y_n^3
where we chose the parameters :math:`b = 0.20` and :math:`d = 2.77` for a chaotic state with initial conditions :math:`x_0 = -0.1` and :math:`y_0 = 0.5`. You can set :math:`b = 0.27` for a periodic response. We solve this system for 3000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Holmes_Cubic_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [b,d].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [13] Chavoya-Aceves, O. "Symbolic dynamics of the cubic map". Physica D: Nonlinear Phenomena., 1985.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 2
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
b = 0.27
elif dynamic_state == 'chaotic':
b = 0.20
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
d = 2.77
else:
b, d = parameters[0], parameters[1]
# defining simulation functions
def holmes(b, d, x, y):
return y, -b*x + +d*y - y**3
if InitialConditions == None:
InitialConditions = [1.6, 0.0]
xtemp = InitialConditions[0]
ytemp = InitialConditions[1]
x, y = [], []
for n in range(0, int(L)):
xtemp, ytemp = holmes(b, d, xtemp, ytemp)
x.append(xtemp)
y.append(ytemp)
ts = [x[-SampleSize:], y[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def kaplan_yorke_map(parameters=[-1.0, 0.2], dynamic_state=None, InitialConditions=None,
L=1000.0, fs=1, SampleSize=500):
"""
The Kaplan Yorke map is defined [14]_ as
.. math::
x_{n+1} &= [ax_n](\mod 1),
y_{n+1} &= by_n + \cos{(4\\pi x_n)}
where we chose the parameters :math:`a = -2.0` and :math:`b = 0.2` for a chaotic state with initial conditions :math:`x_0 = -0.1` and :math:`y_0 = 0.5`. You can set :math:`a = -1.0` for a periodic response. We solve this system for 1000 data points and keep the second 500 to avoid transients.
.. figure:: ../../../figures/Maps/Kaplan_Yorke_map.png
Parameters:
parameters (Optional[float]): Array of system parameters [a,b].
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [14] Peitgen, Heinz-Otto. "Functional Differential Equations and Approximation of Fixed Points". Springer., 1979.
"""
t = np.linspace(0, L, int(L*fs))
num_param = 2
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a = -1.0
elif dynamic_state == 'chaotic':
a = -2.0
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
b = 0.2
else:
a, b = parameters[0], parameters[1]
# defining simulation functions
def kaplan_yorke(a, b, x, y):
return (a*x) % 0.99995, (b*y + np.cos(4*np.pi*x))
if InitialConditions == None:
InitialConditions = [1/np.sqrt(2), -0.4]
xtemp = InitialConditions[0]
ytemp = InitialConditions[1]
x, y = [], []
for n in range(0, int(L)):
xtemp, ytemp = kaplan_yorke(a, b, xtemp, ytemp)
x.append(xtemp)
y.append(ytemp)
ts = [x[-SampleSize:], y[-SampleSize:]]
t = t[-SampleSize:]
return t, ts
[docs]
def gingerbread_man_map(parameters=[1.0, 1.0], dynamic_state=None, InitialConditions=None,
L=2000, fs=1, SampleSize=500):
"""
The Gingerbread Man Map is defined [15]_ [16]_ as
.. math::
x_{n+1} &= 1 - ay_n + n|x_n|,
y_{n+1} &= x_n
where we chose the parameters :math:`a = 1.0` and :math:`b = 1.0`. For a chaotic state, initial conditions :math:`x_0 = 0.5` and :math:`y_0 = 1.8`, and for a periodic response :math:`x_0 = 0.5` and :math:`y_0 = 1.5`. We solve this system for 2000 data points and keep the last 500 to avoid transients.
.. figure:: ../../../figures/Maps/Gingerbread_Man_map.png
Parameters:
a (Optional[float]): System parameter.
b (Optional[float]): System parameter.
dynamic_state (Optional[string]): Dynamic state ('periodic' or 'chaotic')
L (Optional[int]): Number of map iterations.
fs (Optional[int]): sampling rate for simulation.
SampleSize (Optional[int]): length of sample at end of entire time series
Returns:
array: Array of the time indices as `t` and the simulation time series `ts`
References
----------
.. [15] Devaney, Robert. "The gingerbreadman". Algorithms, 1992.
.. [16] Devaney, Robert. "A piecewise linear model for the zones of instability of an area-preserving map". Physica D: Nonlinear Phenomena, 1984.
"""
t = np.linspace(0, L, int(L*fs))
# defining simulation functions
num_param = 2
if len(parameters) != num_param:
raise ValueError(
f'Need {num_param} parameters as specified in documentation.')
elif dynamic_state != None:
if dynamic_state == 'periodic':
a, b = parameters[0], parameters[1]
InitialConditions = [0.5, 1.5]
elif dynamic_state == 'chaotic':
a, b = parameters[0], parameters[1]
InitialConditions = [0.5, 1.8]
else:
raise ValueError(
f'dynamic_state needs to be either "periodic" or "chaotic" or provide an array of length {num_param} in parameters.')
else:
a, b = parameters[0], parameters[1]
def gingerbread_man(a, b, x, y):
return 1 - a*y + b*np.abs(x), x
if InitialConditions == None:
InitialConditions = [0.5, 1.5]
xtemp = InitialConditions[0]
ytemp = InitialConditions[1]
x, y = [], []
for n in range(0, int(L)):
xtemp, ytemp = gingerbread_man(a, b, xtemp, ytemp)
x.append(xtemp)
y.append(ytemp)
ts = [x[-SampleSize:], y[-SampleSize:]]
t = t[-SampleSize:]
return t, ts