Skip to content

Commit

Permalink
Remove deprecated predict_multistep
Browse files Browse the repository at this point in the history
  • Loading branch information
sdahdah committed Sep 26, 2024
1 parent e4b903f commit 030c41f
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 122 deletions.
83 changes: 0 additions & 83 deletions pykoop/koopman_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import sklearn.base
import sklearn.exceptions
import sklearn.metrics
from deprecated import deprecated
from matplotlib import pyplot as plt
from scipy import linalg

Expand Down Expand Up @@ -2410,88 +2409,6 @@ def score(self, X: np.ndarray, y: Optional[np.ndarray] = None) -> float:
score = scorer(self, X, None)
return score

@deprecated('Use `predict_trajectory` instead')
def predict_multistep(self, X: np.ndarray) -> np.ndarray:
"""Perform a multi-step prediction for the first state of each episode.
This function takes the first ``min_samples_`` states of the input,
along with all of its inputs, and predicts the next ``X.shape[0]``
states of the system. This action is performed on a per-episode basis.
The state features of ``X`` (other than the first ``min_samples_``
features) are not used at all.
If prediction fails numerically, missing predictions are filled with
``np.nan``.
Parameters
----------
X : np.ndarray
Data matrix.
Returns
-------
np.ndarray
Predicted data matrix.
Raises
------
ValueError
If an episode is shorter than ``min_samples_``.
Warning
-------
Deprecated in favour of
:func:`pykoop.KoopmanPipeline.predict_trajectory`.
"""
sklearn.utils.validation.check_is_fitted(self, 'regressor_fit_')
X = sklearn.utils.validation.check_array(X, **self._check_array_params)
# Split episodes
episodes = split_episodes(X, episode_feature=self.episode_feature_)
# Loop over episodes
predictions = []
for (i, X_i) in episodes:
# Check length of episode.
if X_i.shape[0] < self.min_samples_:
raise ValueError(f'Episode {i} has {X_i.shape[0]} samples but '
f'`min_samples_`={self.min_samples_} samples '
'are required.')
# Index where prediction blows up (if it does)
crash_index = None
# Extract initial state and input
x0 = X_i[:self.min_samples_, :self.n_states_in_]
u = X_i[:, self.n_states_in_:]
# Create array to hold predicted states
X_pred_i = np.zeros((X_i.shape[0], self.n_states_in_))
# Set the initial condition
X_pred_i[:self.min_samples_, :] = x0
# Predict all time steps
for k in range(self.min_samples_, X_i.shape[0]):
# Stack episode feature, previous predictions, and input
X_ik = combine_episodes(
[(i,
np.hstack((
X_pred_i[(k - self.min_samples_):k, :],
X_i[(k - self.min_samples_):k, self.n_states_in_:],
)))],
episode_feature=self.episode_feature_)
# Predict next step
try:
X_pred_ik = self.predict(X_ik)[[-1], :]
except ValueError:
crash_index = k
break
# Extract data matrix from prediction
X_pred_i[[k], :] = split_episodes(
X_pred_ik, episode_feature=self.episode_feature_)[0][1]
if crash_index is not None:
X_pred_i[crash_index:, :] = np.nan
predictions.append((i, X_pred_i))
# Combine episodes
X_p = combine_episodes(predictions,
episode_feature=self.episode_feature_)
return X_p

def predict_trajectory(
self,
X0_or_X: np.ndarray,
Expand Down
39 changes: 0 additions & 39 deletions tests/test_koopman_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -1097,8 +1097,6 @@ def test_strip_initial_conditons(self):
np.testing.assert_allclose(X1s, X2s)


@pytest.mark.filterwarnings(
'ignore:Call to deprecated method predict_multistep')
@pytest.mark.parametrize(
'kp',
[
Expand Down Expand Up @@ -1186,8 +1184,6 @@ def test_predict_trajectory_no_input(
np.testing.assert_allclose(X_sim, X_sim_exp)


@pytest.mark.filterwarnings(
'ignore:Call to deprecated method predict_multistep')
@pytest.mark.parametrize(
'kp',
[
Expand Down Expand Up @@ -1381,41 +1377,6 @@ def test_predict_trajectory_no_relift_state(self, ndarrays_regression, kp,
default_tolerance=dict(atol=1e-6, rtol=0),
)

def test_predict_multistep(self, kp, mass_spring_damper_sine_input):
"""Test :func:`predict_multistep` (deprecated)."""
msg = 'Test only works when there is no episode feature.'
assert (not mass_spring_damper_sine_input['episode_feature']), msg
# Extract initial conditions
x0 = pykoop.extract_initial_conditions(
mass_spring_damper_sine_input['X_train'],
kp.min_samples_,
n_inputs=mass_spring_damper_sine_input['n_inputs'],
episode_feature=mass_spring_damper_sine_input['episode_feature'],
)
# Extract input
u = pykoop.extract_input(
mass_spring_damper_sine_input['X_train'],
n_inputs=mass_spring_damper_sine_input['n_inputs'],
episode_feature=mass_spring_damper_sine_input['episode_feature'],
)
# Set up initial conditions and input
X_ic = np.zeros(mass_spring_damper_sine_input['X_train'].shape)
X_ic[:kp.min_samples_, :x0.shape[1]] = x0
X_ic[:, x0.shape[1]:] = u
# Predict using ``predict_multistep``
X_sim = kp.predict_multistep(X_ic)
# Predict manually
X_sim_exp = np.zeros(mass_spring_damper_sine_input['Xp_train'].shape)
X_sim_exp[:kp.min_samples_, :] = x0
for k in range(kp.min_samples_, u.shape[0]):
X = np.hstack((
X_sim_exp[(k - kp.min_samples_):k, :],
u[(k - kp.min_samples_):k, :],
))
Xp = kp.predict(X)
X_sim_exp[[k], :] = Xp[[-1], :]
np.testing.assert_allclose(X_sim, X_sim_exp)


@pytest.mark.parametrize(
'X, episodes, episode_feature',
Expand Down

0 comments on commit 030c41f

Please sign in to comment.