Skip to content

Commit

Permalink
Added tests and slightly modified mackey_glass.
Browse files Browse the repository at this point in the history
  • Loading branch information
DuncDennis committed Oct 21, 2023
1 parent bff41fb commit 18fafea
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 20 deletions.
18 changes: 1 addition & 17 deletions src/lorenzpy/simulations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,8 @@
>>> data = sims.Lorenz63().simulate(1000)
>>> data.shape
(1000, 3)
TODO <below>
- Probably for each concrete simulation class + public methods. Compare with sklearn
- Find out which functionality is missing. E.g. Raising error when wrong values are
parsed.
- Check where to add proper tests and how to add them efficiently. Fixtures?
Parametrization?
- Implement all the other dynamical systems.
- Check if the names of files and functions make sense?
- Add functionality to add your own dynamical system? As my base-classes are
protected this is maybe not so easy? -> Make ABC public?
- Think about adding NARMA? Maybe I need a random number generator framework.
- Check if I can further reduce code duplication. Maybe regarding solvers.
- Check for proper doc-generation. It seems that the methods of inhereted members
is not implemented yet. See:
https://github.com/mkdocstrings/mkdocstrings/issues/78
"""

from . import solvers
from .autonomous_flows import (
Chen,
Expand Down
5 changes: 2 additions & 3 deletions src/lorenzpy/simulations/others.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,12 @@ def simulate(
if starting_point.size == self.history_steps + 1:
initial_history = starting_point
elif starting_point.size == 1:
initial_history = np.repeat(starting_point, self.history_steps)
initial_history = np.repeat(starting_point, self.history_steps + 1)
else:
raise ValueError("Wrong size of starting point.")

traj_w_hist = np.zeros((self.history_steps + time_steps, 1))
traj_w_hist[: self.history_steps, :] = initial_history[:, np.newaxis]
traj_w_hist[self.history_steps, :] = starting_point
traj_w_hist[: self.history_steps + 1, :] = initial_history[:, np.newaxis]

for t in range(1, time_steps + transient):
t_shifted = t + self.history_steps
Expand Down
50 changes: 50 additions & 0 deletions tests/test_simulations.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ def test_unsupported_solver():
sim_obj.simulate(2)


def test_unsupported_solver_mackey_glass():
"""Test the error raising of an unsupported solver."""
sim_obj = simulations.MackeyGlass(solver="WRONG_SOLVER")
with pytest.raises(ValueError):
sim_obj.simulate(2)


def test_custom_solver_as_forward_euler():
"""Test a custom solver, which behaves like forward_euler."""

Expand All @@ -151,6 +158,20 @@ def custom_solver(flow, dt, x):
assert (data_custom == data_forward_euler).all()


def test_custom_solver_as_forward_euler_mackey_glass():
"""Test a custom solver, which behaves like forward_euler for mackey glass."""

def custom_solver(flow, dt, x):
# is forward euler
return dt * flow(x) + x

data_custom = simulations.MackeyGlass(solver=custom_solver).simulate(2)

data_forward_euler = simulations.MackeyGlass(solver="forward_euler").simulate(2)

assert (data_custom == data_forward_euler).all()


def test_simplest_driven_chaotic_time_vs_no_time():
"""Test simplest driven chaotic system as an example of a driven system."""
sim_obj = simulations.SimplestDrivenChaotic()
Expand Down Expand Up @@ -191,3 +212,32 @@ def test_scipy_solvers_lorenz63(solver_method):
data_rk4 = simulations.Lorenz63(dt=dt, solver="rk4").simulate(5, starting_point)

np.testing.assert_almost_equal(data[-1, 0], data_rk4[-1, 0], decimal=5)


def test_long_starting_pnt_mackey_glass():
"""Test the option for long starting_point in mackey_glass."""
dt = 0.1
tau = 0.35
history_steps = int(tau / dt) # 3
starting_point = np.ones(history_steps + 1)

data_short_starting_point = simulations.MackeyGlass(dt=dt, tau=tau).simulate(
10, starting_point=np.array([1])
)

data_long_starting_point = simulations.MackeyGlass(dt=dt, tau=tau).simulate(
10, starting_point=starting_point
)

np.testing.assert_almost_equal(data_short_starting_point, data_long_starting_point)


def test_wrong_starting_point_size_mackey_glass():
"""Test ValueError in mackey_glass if long starting pnt is used but wrong shape."""
dt = 0.1
tau = 0.35
starting_point = np.ones(5) # should have length 4
with pytest.raises(ValueError):
_ = simulations.MackeyGlass(dt=dt, tau=tau).simulate(
10, starting_point=starting_point
)

0 comments on commit 18fafea

Please sign in to comment.