def test_score(data): x, t = data model = SINDy() model.fit(x, t) assert model.score(x) <= 1 assert model.score(x, t) <= 1 assert model.score(x, x_dot=x) <= 1 assert model.score(x, t, x_dot=x) <= 1
def test_score(data): x, t, u, _ = data model = SINDy() model.fit(x, u=u, t=t) assert model.score(x, u=u) <= 1 assert model.score(x, u=u, t=t) <= 1 assert model.score(x, u=u, x_dot=x) <= 1 assert model.score(x, u=u, t=t, x_dot=x) <= 1
def test_extra_u_warn_discrete(data_discrete_time_c): x, u = data_discrete_time_c model = SINDy(discrete_time=True) model.fit(x) with pytest.warns(UserWarning): model.predict(x, u=u) with pytest.warns(UserWarning): model.score(x, u=u) with pytest.warns(UserWarning): model.simulate(x[0], u=u, t=10)
def test_extra_u_warn(data_lorenz_c_1d): x, t, u, _ = data_lorenz_c_1d model = SINDy() model.fit(x, t=t) with pytest.warns(UserWarning): model.predict(x, u=u) with pytest.warns(UserWarning): model.score(x, u=u) with pytest.warns(UserWarning): model.simulate(x[0], t=t, u=u)
def test_t_default(data): x, t, u, _ = data dt = t[1] - t[0] model = SINDy() model.fit(x, u=u, t=dt) model_t_default = SINDy(t_default=dt) model_t_default.fit(x, u=u) np.testing.assert_allclose(model.coefficients(), model_t_default.coefficients()) np.testing.assert_almost_equal(model.score(x, u=u, t=dt), model_t_default.score(x, u=u))
def test_u_omitted(data_lorenz_c_1d): x, t, u, _ = data_lorenz_c_1d model = SINDy() model.fit(x, u=u, t=t) with pytest.raises(TypeError): model.predict(x) with pytest.raises(TypeError): model.score(x) with pytest.raises(TypeError): model.simulate(x[0], t=t)
def test_fit_multiple_trajectores(data_multiple_trajctories): x, t = data_multiple_trajctories u = [np.ones((xi.shape[0], 2)) for xi in x] model = SINDy() # Should fail if multiple_trajectories flag is not set with pytest.raises(ValueError): model.fit(x, u=u, t=t) # Should fail if either x or u is not a list with pytest.raises(ValueError): model.fit(x, u=u[0], multiple_trajectories=True) with pytest.raises(ValueError): model.fit(x[0], u=u, multiple_trajectories=True) # x and u should be lists of the same length with pytest.raises(ValueError): model.fit([x[:-1]], u=u, multiple_trajectories=True) model.fit(x, u=u, multiple_trajectories=True) check_is_fitted(model) model.fit(x, u=u, t=t, multiple_trajectories=True) assert model.score(x, u=u, t=t, multiple_trajectories=True) > 0.8 model = SINDy() model.fit(x, u=u, x_dot=x, multiple_trajectories=True) check_is_fitted(model) model = SINDy() model.fit(x, u=u, t=t, x_dot=x, multiple_trajectories=True) check_is_fitted(model)
def test_score_discrete_time_multiple_trajectories( data_discrete_time_multiple_trajectories, ): x = data_discrete_time_multiple_trajectories model = SINDy(discrete_time=True) model.fit(x, multiple_trajectories=True) # Should fail if multiple_trajectories flag is not set with pytest.raises(ValueError): model.score(x) s = model.score(x, multiple_trajectories=True) assert s > 0.75 # x is not its own derivative, so we expect bad performance here s = model.score(x, x_dot=x, multiple_trajectories=True) assert s < 1
def test_libraries(data_lorenz, library): x, t = data_lorenz model = SINDy(feature_library=library) model.fit(x, t) s = model.score(x, t) assert s <= 1
def test_fit_multiple_trajectores(data_multiple_trajctories): x, t = data_multiple_trajctories model = SINDy() # Should fail if multiple_trajectories flag is not set with pytest.raises(ValueError): model.fit(x, t=t) model.fit(x, multiple_trajectories=True) check_is_fitted(model) model.fit(x, t=t, multiple_trajectories=True) assert model.score(x, t=t, multiple_trajectories=True) > 0.8 model = SINDy() model.fit(x, x_dot=x, multiple_trajectories=True) check_is_fitted(model) model = SINDy() model.fit(x, t=t, x_dot=x, multiple_trajectories=True) check_is_fitted(model) # Test validate_input t[0] = None with pytest.raises(ValueError): model.fit(x, t=t, multiple_trajectories=True)
def test_parallel(data_lorenz): x, t = data_lorenz model = SINDy(n_jobs=4) model.fit(x, t) x_dot = model.predict(x) s = model.score(x, x_dot=x_dot) assert s >= 0.95
def test_parallel(data_lorenz_c_1d): x, t, u, _ = data_lorenz_c_1d model = SINDy(n_jobs=4) model.fit(x, u=u, t=t) x_dot = model.predict(x, u=u) s = model.score(x, u=u, x_dot=x_dot) assert s >= 0.95
def test_t_default(data): x, t = data dt = t[1] - t[0] with pytest.raises(ValueError): model = SINDy(t_default=0) with pytest.raises(ValueError): model = SINDy(t_default="1") model = SINDy() model.fit(x, dt) model_t_default = SINDy(t_default=dt) model_t_default.fit(x) np.testing.assert_allclose(model.coefficients(), model_t_default.coefficients()) np.testing.assert_almost_equal(model.score(x, t=dt), model_t_default.score(x)) np.testing.assert_almost_equal( model.differentiate(x, t=dt), model_t_default.differentiate(x) )
def test_score_multiple_trajectories(data_multiple_trajctories): x, t = data_multiple_trajctories model = SINDy() model.fit(x, t=t, multiple_trajectories=True) # Should fail if multiple_trajectories flag is not set with pytest.raises(ValueError): model.score(x) s = model.score(x, multiple_trajectories=True) assert s <= 1 s = model.score(x, t=t, multiple_trajectories=True) assert s <= 1 s = model.score(x, x_dot=x, multiple_trajectories=True) assert s <= 1 s = model.score(x, t=t, x_dot=x, multiple_trajectories=True) assert s <= 1
def test_score_multiple_trajectories(data_multiple_trajctories): x, t = data_multiple_trajctories u = [np.ones((xi.shape[0], 2)) for xi in x] model = SINDy() model.fit(x, u=u, t=t, multiple_trajectories=True) # Should fail if multiple_trajectories flag is not set with pytest.raises(ValueError): model.score(x, u=u) s = model.score(x, u=u, multiple_trajectories=True) assert s <= 1 s = model.score(x, u=u, t=t, multiple_trajectories=True) assert s <= 1 s = model.score(x, u=u, x_dot=x, multiple_trajectories=True) assert s <= 1 s = model.score(x, u=u, t=t, x_dot=x, multiple_trajectories=True) assert s <= 1
def compressible_Framework(inner_prod, time, poly_order, threshold, r, tfac, SR3Enhanced, make_3Dphaseplots): """ Performs the entire vector_POD + SINDy framework for a given polynomial order and thresholding for the SINDy method. Parameters ---------- inner_prod: 2D numpy array of floats (M = number of time samples, M = number of time samples) The scaled matrix of inner products X*X time: numpy array of floats (M = number of time samples) Time in microseconds poly_order: int (1) Highest polynomial order to use in the SINDy library threshold: float (1) Threshold in the SINDy algorithm, below which coefficients will be zeroed out. r: int (1) Truncation number of the SVD tfac: float (1) Fraction of the data to treat as training data SR3Enhanced: SINDy optimizer object (1) The SR3 optimizer with linear equality constraints make_3Dphaseplots: bool (1) Flag to make 3D phase plots or not Returns ------- t_test: numpy array of floats (M_test = number of time samples in the test data region) Time in microseconds in the test data region x_true: 2D numpy array of floats (M_test = number of time samples in the test data region, r = truncation number of the SVD) The true evolution of the temporal BOD modes x_sim: 2D numpy array of floats (M_test = number of time samples in the test data region, r = truncation number of the SVD) The model evolution of the temporal BOD modes S2: 2D numpy array of floats (M = number of time samples, M = number of time samples) The singular value matrix """ plt.clf() plt.close('all') M_train = int(len(time) * tfac) t_train = time[:M_train] t_test = time[M_train:] x, feature_names, S2, Vh, = vector_POD(inner_prod, time, r) print('Now fitting SINDy model') if poly_order == 1: library_functions = [lambda x: x] library_function_names = [lambda x: x] if poly_order == 2: library_functions = [lambda x: x, lambda x, y: x * y, lambda x: x**2] library_function_names = [ lambda x: x, lambda x, y: x + y, lambda x: x + x ] if poly_order == 3: library_functions = [ lambda x: x, lambda x, y: x * y, lambda x: x**2, lambda x, y, z: x * y * z, lambda x, y: x**2 * y, lambda x, y: x * y**2, lambda x: x**3 ] library_function_names = [ lambda x: x, lambda x, y: x + y, lambda x: x + x, lambda x, y, z: x + y + z, lambda x, y: x + x + y, lambda x, y: x + y + y, lambda x: x + x + x ] if poly_order == 4: library_functions = [ lambda x: x, lambda x, y: x * y, lambda x: x**2, lambda x, y, z: x * y * z, lambda x, y: x**2 * y, lambda x, y: x * y**2, lambda x: x**3, lambda x, y, z, w: x * y * z * w, lambda x, y, z: x * y * z**2, lambda x, y: x**2 * y**2, lambda x, y: x**3 * y, lambda x: x**4 ] library_function_names = [ lambda x: x, lambda x, y: x + y, lambda x: x + x, lambda x, y, z: x + y + z, lambda x, y: x + x + y, lambda x, y: x + y + y, lambda x: x + x + x, lambda x, y, z, w: x + y + z + w, lambda x, y, z: x + y + z + z, lambda x, y: x + x + y + y, lambda x, y: x + x + x + y, lambda x: x + x + x + x ] sindy_library = CustomLibrary(library_functions=library_functions, \ function_names=library_function_names) constraint_zeros = np.zeros(int(r * (r + 1) / 2)) if poly_order == 1: constraint_matrix = np.zeros((int(r * (r + 1) / 2), r**2)) for i in range(r): constraint_matrix[i, i * (r + 1)] = 1.0 q = r for i in range(r): counter = 1 for j in range(i + 1, r): constraint_matrix[q, i * r + j] = 1.0 constraint_matrix[q, i * r + j + counter * (r - 1)] = 1.0 counter = counter + 1 q = q + 1 else: if poly_order == 2: #constraint_zeros = np.zeros(6+int(r*(r+1)/2)) #constraint_matrix = np.zeros((6+int(r*(r+1)/2),int(r*(r**2+3*r)/2))) constraint_matrix = np.zeros( (int(r * (r + 1) / 2), int(r * (r**2 + 3 * r) / 2))) if poly_order == 3: #constraint_matrix = np.zeros((int(r*(r+1)/2),int(r*(r**2+3*r)/2)+336)) constraint_matrix = np.zeros( (int(r * (r + 1) / 2), int(r * (r**2 + 3 * r) / 2) + 588)) # 30 if poly_order == 4: constraint_matrix = np.zeros( (int(r * (r + 1) / 2), int(r * (r**2 + 3 * r) / 2) + 60)) for i in range(r): constraint_matrix[i, i * (r + 1)] = 1.0 q = r for i in range(r): counter = 1 for j in range(i + 1, r): constraint_matrix[q, i * r + j] = 1.0 constraint_matrix[q, i * r + j + counter * (r - 1)] = 1.0 counter = counter + 1 q = q + 1 # linear_r4_mat or linear_r12_mat are initial guesses # for the optimization linear_r4_mat = np.zeros((r, r)) linear_r4_mat[0, 1] = 0.091 linear_r4_mat[1, 0] = -0.091 linear_r4_mat[2, 3] = 0.182 linear_r4_mat[3, 2] = -0.182 linear_r4_mat[5, 4] = -3 * 0.091 linear_r4_mat[4, 5] = 3 * 0.091 #linear_r4_mat[8,7] = -4*0.091 #linear_r4_mat[7,8] = 4*0.091 #linear_r4_mat[6,7] = 4*0.091 #linear_r4_mat[7,6] = -4*0.091 linear_r12_mat = np.zeros((12, 90)) linear_r12_mat[0, 1] = 0.089 linear_r12_mat[1, 0] = -0.089 linear_r12_mat[2, 3] = 0.172 linear_r12_mat[3, 2] = -0.172 linear_r12_mat[2, 5] = 0.03 linear_r12_mat[5, 2] = -0.03 linear_r12_mat[2, 6] = 0.022 linear_r12_mat[6, 2] = -0.022 linear_r12_mat[6, 4] = 0.022 linear_r12_mat[4, 6] = 0.023 linear_r12_mat[7, 5] = -0.023 linear_r12_mat[5, 7] = -0.123 linear_r12_mat[7, 5] = 0.123 sindy_opt = SR3Enhanced(threshold=threshold, nu=1, max_iter=20000, \ constraint_lhs=constraint_matrix,constraint_rhs=constraint_zeros, \ tol=1e-6,thresholder='l0',initial_guess=linear_r4_mat) model = SINDy(optimizer=sindy_opt, \ feature_library=sindy_library, \ differentiation_method=FiniteDifference(drop_endpoints=True), \ feature_names=feature_names) x_train = x[:M_train, :] x0_train = x[0, :] x_true = x[M_train:, :] x0_test = x[M_train, :] model.fit(x_train, t=t_train, unbias=False) t_cycle = np.linspace(time[M_train], time[M_train] * 1.3, int(len(time) / 2.0)) print(model.coefficients()) x_sim,output = model.simulate(x0_test,t_test, \ integrator=odeint,stop_condition=None,full_output=True, \ rtol=1e-20,h0=1e-5) #h0=1e-20 x_sim1,output = model.simulate(-0.4*np.ones(r),t_cycle, \ integrator=odeint,stop_condition=None,full_output=True, \ rtol=1e-20,h0=1e-5) x_sim2,output = model.simulate(0.15*np.ones(r),t_cycle, \ integrator=odeint,stop_condition=None,full_output=True, \ rtol=1e-20,h0=1e-5) x_dot = model.differentiate(x, t=time) x_dot_train = model.predict(x_train) x_dot_sim = model.predict(x_true) print('Model score: %f' % model.score(x, t=time)) make_evo_plots(x_dot,x_dot_train, \ x_dot_sim,x_true,x_sim,time,t_train,t_test) make_table(model, feature_names) # Makes 3D phase space plots if make_3Dphaseplots: make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 2) make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 3) make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 4) make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 5) make_3d_plots(x_true, x_sim, t_test, 'sim', 0, 1, 6) make_3d_plots(x_true, x_sim, t_test, 'sim', 3, 4, 5) make_3d_plots(x_true, x_sim, t_test, 'sim', 4, 5, 6) make_3d_plots(x_sim1, x_sim2, t_cycle, 'limitcycle') for i in range(r): x_sim[:, i] = x_sim[:, i] * sum(np.amax(abs(Vh), axis=1)[0:r]) x_true[:, i] = x_true[:, i] * sum(np.amax(abs(Vh), axis=1)[0:r]) return t_test, x_true, x_sim, S2
def test_score_discrete_time(data_discrete_time): x = data_discrete_time model = SINDy(discrete_time=True) model.fit(x) assert model.score(x) > 0.75 assert model.score(x, x_dot=x) < 1
def test_score_discrete_time(data_discrete_time_c): x, u = data_discrete_time_c model = SINDy(discrete_time=True) model.fit(x, u=u) assert model.score(x, u=u) > 0.75 assert model.score(x, u=u, x_dot=x) < 1