def test_parametrize_control_wrong_size(model): model.t = SX.sym('t') model.create_control('u', 1) # wrong size for expr k = SX.sym("k", 2) with pytest.raises(ValueError): model.parametrize_control(model.u, k * model.t, k)
def test_parametrize_control_already_parametrize(model): model.t = SX.sym('t') model.create_control('u', 3) # test parametrize a control already parametrized model.x = SX.sym('x') k = SX.sym("k") model.parametrize_control(model.u[0], -k * model.x[0], k) with pytest.raises(ValueError): model.parametrize_control(model.u[0], k * model.t, k)
def test_parametrize_control_time_dependent_polynomial(model): model.tau = SX.sym('tau') model.create_control('u', 3) # Test parametrize by a time dependent polynomial u_par = SX.sym("u_par", 3, 2) u_expr = model.tau * u_par[:, 0] + (1 - model.tau) * u_par[:, 1] model.parametrize_control(model.u, u_expr, vec(u_par)) assert is_equal(model.u_par, vec(u_par)) assert is_equal(model.u_expr, u_expr, 30) for ind in range(model.n_u): assert is_equal(model._parametrized_controls[ind], model.u[ind])
def test_control_is_parametrized(model: ControlMixin): model.create_control('u', 4) assert not model.control_is_parametrized(model.u[0]) # error multiple controls are passed with pytest.raises(ValueError): model.control_is_parametrized(model.u) k = SX.sym('k') model.x = SX.sym('x') model.parametrize_control(model.u[0], -k * model.x[0], k) assert model.control_is_parametrized(model.u[0])
def test_include_theta(model): new_theta_1 = SX.sym("new_theta") new_theta_2 = SX.sym("new_theta_2", 2) model_n_theta = model.n_theta model.include_theta(new_theta_1) assert model.n_theta == model_n_theta + 1 assert is_equal(model.theta[-1], new_theta_1) model.include_theta(new_theta_2) assert model.n_theta == model_n_theta + 1 + 2 assert is_equal(model.theta[-3], new_theta_1) assert is_equal(model.theta[-2:], new_theta_2)
def test_include_parameter(model): new_p_1 = SX.sym("new_p") new_p_2 = SX.sym("new_p_2", 2) model_n_p = model.n_p model.include_parameter(new_p_1) assert model.n_p == model_n_p + 1 assert is_equal(model.p[-1], new_p_1) model.include_parameter(new_p_2) assert model.n_p == model_n_p + 1 + 2 assert is_equal(model.p[-3], new_p_1) assert is_equal(model.p[-2:], new_p_2)
def test_include_control(model: ControlMixin): new_u_1 = SX.sym("new_u") new_u_2 = SX.sym("new_u_2", 2) model_n_u = model.n_u model.include_control(new_u_1) assert model.n_u == model_n_u + 1 assert (is_equal(model.u[-1], new_u_1)) model.include_control(new_u_2) assert model.n_u == model_n_u + 1 + 2 assert is_equal(model.u[-3], new_u_1) assert is_equal(model.u[-2:], new_u_2)
def test_include_algebraic(model): new_y_1 = SX.sym("new_y") new_y_2 = SX.sym("new_y_2", 2) model_n_y = model.n_y alg = new_y_1 - 3 model.include_algebraic(new_y_1, alg=alg) assert model.n_y == model_n_y + 1 assert is_equal(model.y[-1], new_y_1) assert is_equal(model.alg[-1], alg, 10) model.include_algebraic(new_y_2) assert model.n_y == model_n_y + 1 + 2 assert is_equal(model.y[-3], new_y_1) assert is_equal(model.y[-2:], new_y_2)
def test_replace_variable_u_par(model): # replace a u_par new_u_par = SX.sym("new_u", model.n_u) new_u_expr = new_u_par model.replace_variable(model.u_par, new_u_par) assert is_equal(model.u_expr, new_u_expr, 30)
def create_state(self, name="x", size=1): """ Create a new state with the name "name" and size "size". Size can be an int or a tuple (e.g. (2,2)). However, the new state will be vectorized (casadi.vec) to be included in the state vector (model.x). :param name: str :param size: int|tuple :return: """ if callable(getattr(self, 'name_variable', None)): name = self.name_variable(name) new_x = SX.sym(name, size) new_x_0 = SX.sym(name + "_0_sym", size) self.include_state(vec(new_x), ode=None, x_0=vec(new_x_0)) return new_x
def test_parametrize_control_list_input(model): model.tau = SX.sym('tau') model.create_control('u', 3) # Test for list inputs, parametrize by a time dependent polynomial u_par = SX.sym("u_par", 3, 2) u_expr = model.tau * u_par[:, 0] + (1 - model.tau) * u_par[:, 1] model.parametrize_control( [model.u[ind] for ind in range(model.n_u)], [u_expr[ind] for ind in range(model.n_u)], [vec(u_par)[ind] for ind in range(u_par.numel())], ) assert is_equal(model.u_par, vec(u_par)) assert is_equal(model.u_expr, u_expr, 30) for ind in range(model.n_u): assert is_equal(model._parametrized_controls[ind], model.u[ind])
def test_include_state(model): new_x_1 = SX.sym("new_x") new_x_2 = SX.sym("new_x_2", 2) model_n_x = model.n_x new_x_0_1 = model.include_state(new_x_1) assert model.n_x == model_n_x + 1 assert model.x_0.numel() == model_n_x + 1 assert new_x_0_1.numel() == new_x_1.numel() assert is_equal(model.x[-1], new_x_1) model_n_x = model.n_x new_x_0_2 = model.include_state(new_x_2) assert model.n_x == model_n_x + 2 assert model.x_0.numel(), model_n_x + 2 assert new_x_0_2.numel() == new_x_2.numel() assert is_equal(model.x[-3], new_x_1) assert is_equal(model.x[-2:], new_x_2)
def test_replace_variable_alg(model: AlgebraicMixin): y = model.create_algebraic_variable('y', 3) model.include_equations(alg=[-y]) # replace y original = model.y[1] replacement = SX.sym("new_y", original.numel()) model.replace_variable(original, replacement) assert not depends_on(model.alg, original) assert depends_on(model.alg, replacement)
def test_replace_variable_state(model: StateMixin): x = model.create_state('x', 3) model.include_equations(ode=[-x], x=x) # replace x original = model.x[1] replacement = SX.sym("new_x", original.numel()) model.replace_variable(original, replacement) assert not depends_on(model.ode, original) assert depends_on(model.ode, replacement)
def create_theta(self, name="theta", size=1): """ Create a new parameter name "name" and size "size" :param name: str :param size: int :return: """ if callable(getattr(self, 'name_variable', None)): name = self.name_variable(name) new_theta = SX.sym(name, size) self.include_theta(vec(new_theta)) return new_theta
def create_algebraic_variable(self, name="y", size=1): """ Create a new algebraic variable with the name "name" and size "size". Size can be an int or a tuple (e.g. (2,2)). However, the new algebraic variable will be vectorized (casadi.vec) to be included in the algebraic vector (model.y). :param str name: :param int||tuple size: :return: """ if callable(getattr(self, 'name_variable', None)): name = self.name_variable(name) new_y = SX.sym(name, size) self.include_algebraic(vec(new_y)) return new_y
def create_control(self, name="u", size=1): """ Create a new control variable name "name" and size "size". Size can be an int or a tuple (e.g. (2,2)). However, the new control variable will be vectorized (casadi.vec) to be included in the control vector (model.u). :param name: str :param size: int :return: """ if callable(getattr(self, 'name_variable', None)): name = self.name_variable(name) new_u = SX.sym(name, size) self.include_control(vec(new_u)) return new_u
def include_state(self, var, ode=None, x_0=None): n_x = var.numel() self.x = vertcat(self.x, var) if x_0 is None: x_0 = vertcat(*[SX.sym(var_i.name()) for var_i in var.nz]) self.x_0 = vertcat(self.x_0, x_0) # crate entry for included state for ind, x_i in enumerate(var.nz): if x_i in self._ode: raise ValueError(f'State "{x_i}" already in this model') self._ode[x_i] = None if ode is not None: self.include_equations(ode=ode, x=var) return x_0
def test_n_p(model): assert model.n_p == 0 model.p = SX.sym("p", 4) assert model.n_p == 4
def test_n_theta(model): assert model.n_theta == 0 model.theta = SX.sym("theta", 4) assert model.n_theta == 4