dynamicslab / pysindy

A package for the sparse identification of nonlinear dynamical systems from data
https://pysindy.readthedocs.io/en/latest/
Other
1.36k stars 305 forks source link

[BUG] problem running Multiple Trajectories in the `1_feature_overview/example.ipynb` #402

Closed georgemilosh closed 10 months ago

georgemilosh commented 10 months ago

The issue with running the notebook ./pysindy/examples/1_feature_overview/example.ipynb when getting to Multiple Trajectories with pysindy=1.7.5

Note that as explained in README I tried installing with pip install pysindy[dev] which gave me WARNING: pysindy 1.7.5 does not provide the extra 'dev'

Reproducing code example:

import pysindy
import warnings
from contextlib import contextmanager
from copy import copy
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import solve_ivp
from scipy.linalg import LinAlgWarning
from sklearn.exceptions import ConvergenceWarning
from sklearn.linear_model import Lasso

import pysindy as ps
from pysindy.utils import enzyme
from pysindy.utils import lorenz
from pysindy.utils import lorenz_control

if __name__ != "testing":
    t_end_train = 10
    t_end_test = 15
else:
    t_end_train = 0.04
    t_end_test = 0.04

data = (Path() / "../data").resolve()

@contextmanager
def ignore_specific_warnings():
    filters = copy(warnings.filters)
    warnings.filterwarnings("ignore", category=ConvergenceWarning)
    warnings.filterwarnings("ignore", category=LinAlgWarning)
    warnings.filterwarnings("ignore", category=UserWarning)
    yield
    warnings.filters = filters

if __name__ == "testing":
    import sys
    import os

    sys.stdout = open(os.devnull, "w")
# %%
# Seed the random number generators for reproducibility
np.random.seed(100)

integrator_keywords = {}
integrator_keywords["rtol"] = 1e-12
integrator_keywords["method"] = "LSODA"
integrator_keywords["atol"] = 1e-12

dt = 0.002

t_train = np.arange(0, t_end_train, dt)
x0_train = [-8, 8, 27]
t_train_span = (t_train[0], t_train[-1])
x_train = solve_ivp(
    lorenz, t_train_span, x0_train, t_eval=t_train, **integrator_keywords
).y.T

# %% [markdown]
# ### Multiple trajectories
# We use the Lorenz equations to evolve multiple different initial conditions forward in time, passing all the trajectories into a single `SINDy` object. Note that `x_train_multi` is a list of 2D numpy arrays.

# %%
if __name__ != "testing":
    n_trajectories = 20
    sample_range = (500, 1500)
else:
    n_trajectories = 2
    sample_range = (10, 15)
x0s = np.array([36, 48, 41]) * (np.random.rand(n_trajectories, 3) - 0.5) + np.array(
    [0, 0, 25]
)
x_train_multi = []
for i in range(n_trajectories):
    x_train_multi.append(
        solve_ivp(
            lorenz, t_train_span, x0s[i], t_eval=t_train, **integrator_keywords
        ).y.T
    )

model = ps.SINDy()
model.fit(x_train_multi, t=dt)
model.print()

Error message:

Traceback (most recent call last):
  File "/net/nfs/ssd1/gmiloshe/pysindy/examples/1_feature_overview/test.py", line 85, in <module>
    model.fit(x_train_multi, t=dt)
  File "/net/nfs/ssd1/miniconda3/envs/pysindy/lib/python3.10/site-packages/pysindy/pysindy.py", line 314, in fit
    x, t, x_dot, u = _adapt_to_multiple_trajectories(x, t, x_dot, u)
  File "/net/nfs/ssd1/miniconda3/envs/pysindy/lib/python3.10/site-packages/pysindy/pysindy.py", line 934, in _adapt_to_multiple_trajectories
    raise ValueError(
ValueError: x is a Sequence, but multiple_trajectories not set.  Did you mean to set multiple trajectories?

PySINDy/Python version information:

1.7.5 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:40:32) [GCC 12.3.0]

Jacob-Stevens-Haas commented 10 months ago

The README, as well as certain example notebooks (1, 2, 5) are kept up to date with the master branch. That branch is backwards incompatible, as we prepare for a 2.0 release. It has removed the multiple_trajectories kwarg to SINDy.fit() and added the dev extras.

If you're on a 1.x release, you need to specify that x is a sequence of trajectories. You also will not have pysindy[dev].