dynamicslab / pysindy

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

ValueError: x and y arrays must be equal in length along interpolation axis. #418

Closed ziyinyuan closed 8 months ago

ziyinyuan commented 8 months ago

I got the model out, but I am not sure how to simulate it. Can anyone help me with this? Here's my code


def coupled_equations2(x, t, zeta, w, alpha):
    x1, x1_dot, x2, x2_dot = x

    dx1_dot_dt = -2 * zeta * x1_dot - w**2 * x1 + alpha * x2
    dx2_dot_dt = -2 * zeta * x2_dot - w**2 * x2 + alpha * x1

    return [x1_dot, dx1_dot_dt, x2_dot, dx2_dot_dt]

w_values = [1, 2, 3, 4, 5]
beta_values = [0.2, 0.4, 0.6, 0.8, 1]
alpha_values = []
zeta = 0

for i in range(len(w_values)):
    alpha = w_values[i] ** 2 * beta_values[i]
    alpha_values.append(alpha)

t = np.linspace(0, 5, 1000)  # Time values

result_list = []

for w_val, alpha_val in zip(w_values, alpha_values):
    x_initial = [0.0, 0.5, 0.0, -1.0] # Initial conditions for positions and velocities
    x_solution = odeint(coupled_equations2, x_initial, t, args=(zeta, w_val, alpha_val))
    result_list.append(np.array(x_solution))

# Convert the result list to an array
result_array = np.array(result_list)

u_trains = [[w_values[i],alpha_values[i]] for i in range(len(w_values))]

lib = ps.ParameterizedLibrary(
    feature_library=ps.PolynomialLibrary(),
    parameter_library=ps.PolynomialLibrary(),
    num_features=4, # each trajectories have x1,x2,x1dot,x2dot
    num_parameters=2, # 2 parameters (w and alpha)
)

model = ps.SINDy(
    feature_library=lib,
    optimizer=ps.STLSQ(threshold=0.1, normalize_columns=False),
    feature_names=["x1", "x1dot", "x2", "x2dot", "w","alpha"],
)
model.fit(result_list, u=u_trains, t=t, multiple_trajectories=True)
model.print()

All good up to this part, but when I want to simulate the model, it run into the value error: x and y arrays must be equal in length along interpolation axis.

y0 = [0.0, 0.5, 0.0, -1.0]
sim = model.simulate(y0, t, u_trains)
Jacob-Stevens-Haas commented 8 months ago

Yes, this makes sense. u_trains and t need to be the same length. That is, if your model includes control inputs, you need to supply them for every time point.

ziyinyuan commented 8 months ago

I have

u_test = [u_trains for _ in range(len(t))]

sim = model.simulate(y0, t, u_test)

The error this time shows: ValueError: Could not reshape control input to match the input data.

Jacob-Stevens-Haas commented 8 months ago

yeah, so check y0.shape and np.array(u_test).shape. y0 should be (n_time, n_features) and u_test should be (n_time, n_control_features).

ziyinyuan commented 8 months ago

thank you! it works!