def test_dictionary_builder_addition(): db = DictionaryBuilder.from_mak_generator(number_of_states=2, max_order=2) assert len(db) == 3 db2 = DictionaryBuilder.from_mak_generator(number_of_states=1, max_order=2) assert len(db2) == 1 new_dictionary = db + db2 assert len(new_dictionary) == 4 with pytest.raises(ValueError, match=r"Dictionary cannot be empty!"): db3 = db + DictionaryBuilder(dict_fcns=[]) len(db3)
def test_negative_hill(): db = DictionaryBuilder.from_negative_hill_generator( state_variable="x1", Km_range=[0, 1], cooperativity_range=[1, 2]) assert len(db) == 4 # test positive behavior assert db.dict_fcns[0].symbolic_expression.subs( "x1", 100) == pytest.approx(1 / 100)
def refit(self, orig_data, data_vec, config, zero_th): # set the lambda to zero, pure data fit, no model selection lambda_param = [0] * len(self.state_name) all_selected_dict_fcns = [] dict_mtx = [] # select the non zero RHS indices and build a new dictionary for each state for sbl in self.batch_SBL.SBL_problems: selected_dict_fcns = sbl.get_results(zero_th=zero_th) all_selected_dict_fcns.append(selected_dict_fcns) sub_dict = DictionaryBuilder.from_dict_fcns(selected_dict_fcns) A = sub_dict.evaluate_dict(input_data=orig_data) dict_mtx.append(A) new_sbls = BatchSBL( dict_mtx=dict_mtx, data_vec=data_vec, lambda_param=lambda_param, dict_fcns=all_selected_dict_fcns, state_name=self.state_name, config=config, mode="state_batch", ) new_sbls.compute_model_structure(max_iter=1) return new_sbls
def test_evaluate_dict(): d_f = ["x1*x2", "x1**2"] dict_builder = DictionaryBuilder(dict_fcns=d_f) data_x1 = [1, 5, 10] data_x2 = [3, 7, 15] data = {"x1": data_x1, "x2": data_x2} A = dict_builder.evaluate_dict(input_data=data) sym_expr_df1 = parse_expr(s=d_f[0], evaluate=False) df1_eval = [ sym_expr_df1.evalf(subs=dict(x1=x1, x2=x2)) for x1, x2 in zip(data_x1, data_x2) ] sym_expr_df2 = parse_expr(s=d_f[1], evaluate=False) df2_eval = [ sym_expr_df2.evalf(subs=dict(x1=x1, x2=x2)) for x1, x2 in zip(data_x1, data_x2) ] B = np.array([df1_eval, df2_eval]).T assert np.array_equal(A, B)
def test_add_dict_fcn(): # test exponent conversion dict_builder = DictionaryBuilder(dict_fcns=[]) d_f = "x1^2" dict_builder.add_dict_fcn(d_f=d_f) dict_fcn = dict_builder.dict_fcns.pop() d_f_replaced = d_f.replace("^", "**") assert str(dict_fcn.symbolic_expression) == d_f_replaced # test an undefined function d_f = ["f(x1)"] dict_builder = DictionaryBuilder(dict_fcns=d_f) data = {"x1": [5, 2]} with pytest.raises(NameError): dict_builder.evaluate_dict(input_data=data)
def test_dictionary_builder(): d_f = ["x1", "x1*x2", "x2"] dict_builder = DictionaryBuilder(dict_fcns=d_f) assert len(d_f) == len(dict_builder.dict_fcns)
def test_from_mak_generator(): # test normal operation db = DictionaryBuilder.from_mak_generator(number_of_states=2, max_order=2) assert str(db) == " | ".join(["x1*x1", "x1*x2", "x2*x2"]) db = DictionaryBuilder.from_mak_generator(number_of_states=2, max_order=2, number_of_inputs=1) assert str(db) == " | ".join([ "x1*x1", "x1*x2", "u1*x1", "x2*x2", "u1*x2", "u1*u1", ]) # test negative arguments with pytest.raises(ValueError, match=r"Model has to have at least non-state"): DictionaryBuilder.from_mak_generator(number_of_states=0, max_order=2) with pytest.raises(ValueError, match=r"Model has to have at least non-state"): DictionaryBuilder.from_mak_generator(number_of_states=-5, max_order=2) with pytest.raises(ValueError, match=r"The max_order has to be at least one"): DictionaryBuilder.from_mak_generator(number_of_states=2, max_order=0) with pytest.raises(ValueError, match=r"The max_order has to be at least one"): DictionaryBuilder.from_mak_generator(number_of_states=2, max_order=-4) with pytest.raises(ValueError, match=r"The number of inputs cannot be negative"): DictionaryBuilder.from_mak_generator(number_of_states=2, max_order=2, number_of_inputs=-1)
plt.title("Observable state y") plt.legend(loc="best") plt.subplot(212) plt.plot(t, dx2, label="RHS diff") plt.plot(t, dy_spline, c='r', alpha=0.4, label="Spline diff") plt.plot(t_gp, dydt, c='orange', label="GP diff") plt.fill_between(t_gp, dydt - 2*dydt_std, dydt + 2*dydt_std, alpha=0.2, color='k') plt.ylabel("Value (AU)") plt.xlabel("time (s)") plt.title("Derivative of y") plt.legend(loc="best") plt.show() # step 1 define a dictionary d_f = ["1", "x", "y", "z", "x*z", "y*x"] dict_builder = DictionaryBuilder(dict_fcns=d_f) dict_functions = dict_builder.dict_fcns # associate variables with data data = {"x": y[0, :].T, "y": y[1, :].T, "z": y[2, :].T} #data = {"x": x_samples.T, "y": y_samples.T, "z": z_samples.T} A = dict_builder.evaluate_dict(input_data=data) # step 2 define an SBL problem # with the Lin reg model and solve it config_dict = { "solver": {"name": "ECOS", "show_time": False, "settings": {}}, "verbose": False, } norm_vect = np.linalg.norm(A, axis=0) A_norm = A / norm_vect
def test_sbl_on_lotka_volterra(): # define Lotka-Volerra model states = {"x1": "alpha*x1-beta*x1*x2", "x2": "delta*x1*x2-gamma*x2"} parameters = {"alpha": 2 / 3, "beta": 4 / 3, "delta": 1, "gamma": 1} ss = StateSpaceModel.from_string(states=states, parameters=parameters) states = ["x1", "x2"] t_span = [0, 30] x0 = {"x1": 1.2, "x2": 1.0} # simulate model gm = MeasurementsGenerator(ss=ss, time_span=t_span, initial_values=x0) t, y = gm.get_measurements() # compute the time derivative of the state variables rhs_preprop = RHSEvalSignalPreprocessor(t=t, y=y, rhs_function=ss.get_rhs, states=states) rhs_preprop.calculate_time_derivative() dydt_rhs = rhs_preprop.dydt dx1 = dydt_rhs[0, :] dx2 = dydt_rhs[1, :] # step 1 define a dictionary d_f = ["x1", "x2", "x1*x1", "x1*x2", "x2*x2"] dict_builder = DictionaryBuilder(dict_fcns=d_f) dict_functions = dict_builder.dict_fcns data = {"x1": y[0, :], "x2": y[1, :]} A = dict_builder.evaluate_dict(input_data=data) # step 2 define an SBL problem and solve it lambda_param_x1 = 0.1 lambda_param_x2 = 0.05 sbl_x1 = SBL( dict_mtx=A, data_vec=dx1, lambda_param=lambda_param_x1, state_name="x1", dict_fcns=dict_functions, ) sbl_x1.compute_model_structure() sbl_x2 = SBL( dict_mtx=A, data_vec=dx2, lambda_param=lambda_param_x2, state_name="x2", dict_fcns=dict_functions, ) sbl_x2.compute_model_structure() # test SBL results zero_th = 1e-8 x1_results = [ str(item.symbolic_expression) for item in sbl_x1.get_results(zero_th=zero_th) ] assert len(x1_results) == 2 assert "x1" in x1_results assert "x1*x2" in x1_results x2_results = [ str(item.symbolic_expression) for item in sbl_x2.get_results(zero_th=zero_th) ] assert len(x2_results) == 2 assert "x2" in x2_results assert "x1*x2" in x2_results