def test_blockdiag(self): # Test blockdiag with DM correct_res = DM([[1, 1, 0, 0, 0], [1, 1, 0, 0, 0], [0, 0, 1, 1, 1], [0, 0, 1, 1, 1], [0, 0, 1, 1, 1]]) a = DM.ones(2, 2) b = DM.ones(3, 3) res = blockdiag(a, b) self.assertTrue(is_equal(res, correct_res)) # MX and DM mix a = MX.sym('a', 2, 2) b = DM.ones(1, 1) correct_res = MX.zeros(3, 3) correct_res[:2, :2] = a correct_res[2:, 2:] = b res = blockdiag(a, b) self.assertTrue(is_equal(res, correct_res, 30)) # SX and DM mix a = SX.sym('a', 2, 2) b = DM.ones(1, 1) correct_res = SX.zeros(3, 3) correct_res[:2, :2] = a correct_res[2:, 2:] = b res = blockdiag(a, b) self.assertTrue(is_equal(res, correct_res, 30)) # SX and MX a = SX.sym('a', 2, 2) b = MX.sym('b', 2, 2) self.assertRaises(ValueError, blockdiag, a, b)
def test_t_setter(self): new_t = SX.sym("t") self.ode_model.t = new_t self.dae_model.t = new_t self.assertTrue(is_equal(self.ode_model.t, new_t)) self.assertTrue(is_equal(self.dae_model.t, new_t))
def test_get_variables_by_names(self): model = self.dae_model.get_copy() # Variable does not exist self.assertEqual(model.get_variables_by_names("other_var"), []) # Multiple vars self.assertGreater(len(model.get_variables_by_names("x")), 0) res = model.get_variables_by_names("x") for ind in range(model.n_x): self.assertTrue(is_equal(res[ind], model.x[ind])) # Some var that exists and is unique res = model.get_variables_by_names("x_1") self.assertEqual(len(res), 1) self.assertTrue(is_equal(model.x[1], res[0])) # find var with var_type model2 = self.dae_model.get_copy() p_with_name_starting_with_x = model2.create_parameter("x_ref") res = model2.get_variables_by_names("x", var_type="p") self.assertEqual(len(res), 1) self.assertTrue(is_equal(p_with_name_starting_with_x, res[0])) # find var with list of names res = model.get_variables_by_names(["x_1", "u_2"]) self.assertEqual(len(res), 2) self.assertTrue(is_equal(model.x[1], res[0])) self.assertTrue(is_equal(model.u[2], res[1]))
def test_tau_setter(self): new_tau = SX.sym("tau") self.ode_model.tau = new_tau self.dae_model.tau = new_tau self.assertTrue(is_equal(self.ode_model.tau, new_tau)) self.assertTrue(is_equal(self.dae_model.tau, new_tau))
def test_concatenations(self): y = np.linspace(0, 1, 10)[:, np.newaxis] a = pybamm.Vector(y) b = pybamm.Scalar(16) c = pybamm.Scalar(3) conc = pybamm.NumpyConcatenation(a, b, c) self.assertTrue( casadi.is_equal(conc.to_casadi(), casadi.SX(conc.evaluate()))) # Domain concatenation mesh = get_mesh_for_testing() a_dom = ["negative electrode"] b_dom = ["positive electrode"] a = 2 * pybamm.Vector(np.ones_like(mesh[a_dom[0]][0].nodes), domain=a_dom) b = pybamm.Vector(np.ones_like(mesh[b_dom[0]][0].nodes), domain=b_dom) conc = pybamm.DomainConcatenation([b, a], mesh) self.assertTrue( casadi.is_equal(conc.to_casadi(), casadi.SX(conc.evaluate()))) # 2d disc = get_1p1d_discretisation_for_testing() a = pybamm.Variable("a", domain=a_dom) b = pybamm.Variable("b", domain=b_dom) conc = pybamm.Concatenation(a, b) disc.set_variable_slices([conc]) expr = disc.process_symbol(conc) y = casadi.SX.sym("y", expr.size) x = expr.to_casadi(None, y) f = casadi.Function("f", [x], [x]) y_eval = np.linspace(0, 1, expr.size) self.assertTrue( casadi.is_equal(f(y_eval), casadi.SX(expr.evaluate(y=y_eval))))
def test_include_variable_with_bounds(self): lb = -DM(range(1, 4)) ub = DM(range(5, 8)) aop = AbstractOptimizationProblem() x = MX.sym('x', 3) aop.include_variable(x, lb=lb, ub=ub) self.assertTrue(is_equal(aop.x_lb, lb)) self.assertTrue(is_equal(aop.x_ub, ub))
def test_include_equality_scalar_bound(self): rhs = 2 aop = AbstractOptimizationProblem() x = aop.create_variable('x', 2) g = 2 * x aop.include_equality(g, rhs=rhs) self.assertTrue(is_equal(aop.g_lb, repmat(rhs, 2))) self.assertTrue(is_equal(aop.g_ub, repmat(rhs, 2)))
def test_include_equality(self): aop = AbstractOptimizationProblem() x = aop.create_variable('x', 2) g = x[0] - x[1] aop.include_equality(g) self.assertTrue(is_equal(aop.g, g)) self.assertTrue(is_equal(aop.g_lb, 0)) self.assertTrue(is_equal(aop.g_ub, 0))
def has_delta_u(self): has_element_diff_from_inf = False for i in range(self.model.n_u): has_element_diff_from_inf = (not is_equal( self.delta_u_max[i], inf)) or has_element_diff_from_inf has_element_diff_from_inf = (not is_equal( self.delta_u_min[i], -inf)) or has_element_diff_from_inf return has_element_diff_from_inf
def test_include_equality_with_bounds(self): rhs = 2 aop = AbstractOptimizationProblem() x = aop.create_variable('x', 2) g = x[0] - x[1] aop.include_equality(g, rhs=rhs) self.assertTrue(is_equal(aop.g, g)) self.assertTrue(is_equal(aop.g_lb, rhs)) self.assertTrue(is_equal(aop.g_ub, rhs))
def test_include_inequality_scalar_bound(self): lb = 1 ub = 4 aop = AbstractOptimizationProblem() x = aop.create_variable('x', 2) g = 2 * x aop.include_inequality(g, lb=lb, ub=ub) self.assertTrue(is_equal(aop.g_lb, repmat(lb, 2))) self.assertTrue(is_equal(aop.g_ub, repmat(ub, 2)))
def test_include_parameter_twice(self): # Test to avoid override aop = AbstractOptimizationProblem() p1 = MX.sym('p1', 3) p2 = MX.sym('p2', 5) aop.include_parameter(p1) aop.include_parameter(p2) self.assertTrue(is_equal(aop.p[:p1.numel()], p1)) self.assertTrue(is_equal(aop.p[p1.numel():], p2))
def test_find_variables_in_vector_by_name(self): # Only search for one variable correct_var = self.x_vector[2] correct_var_name = correct_var.name() result = find_variables_in_vector_by_name(correct_var_name, self.x_vector) self.assertEqual(len(result), 1) self.assertTrue(is_equal(result[-1], correct_var)) # Only search for multiple variables correct_var = self.x_vector[[2, 4]] correct_var_name = [ correct_var[ind].name() for ind in range(correct_var.numel()) ] result = find_variables_in_vector_by_name(correct_var_name, self.x_vector) self.assertEqual(len(result), 2) for ind in range(correct_var.numel()): self.assertTrue(is_equal(result[ind], correct_var[ind])) # Search for name using regex correct_var = self.x_vector[[3, 4]] correct_var_name = 'foo' result = find_variables_in_vector_by_name(correct_var_name, self.x_vector) self.assertEqual(len(result), 2) for ind in range(correct_var.numel()): self.assertTrue(is_equal(result[ind], correct_var[ind])) # Search for name using exact correct_var = self.x_vector[3] correct_var_name = correct_var.name() result = find_variables_in_vector_by_name(correct_var_name, self.x_vector, exact=True) self.assertEqual(len(result), 1) self.assertTrue(is_equal(result[-1], correct_var)) # Search for variable that does not exists with exact result = find_variables_in_vector_by_name('wrong', self.x_vector, exact=True) self.assertEqual(len(result), 0) self.assertEqual(result, []) # Search for variable that does not exists with regex result = find_variables_in_vector_by_name('wrong', self.x_vector, exact=True) self.assertEqual(len(result), 0) self.assertEqual(result, [])
def test_include_variable_twice(self): # Test to avoid override aop = AbstractOptimizationProblem() x = MX.sym('x', 3) y = MX.sym('y', 5) aop.include_variable(x) aop.include_variable(y) self.assertTrue(is_equal(aop.x[:x.numel()], x)) self.assertTrue(is_equal(aop.x[x.numel():], y))
def test_include_equality_w_external_variable_in_expr(self): theta = MX.sym('theta') aop = AbstractOptimizationProblem() x = aop.create_variable('x', 2) g = theta * x[0] - x[1] aop.include_equality(g) self.assertTrue(is_equal(aop.g, g)) self.assertTrue(is_equal(aop.g_lb, 0)) self.assertTrue(is_equal(aop.g_ub, 0))
def test_include_inequality_with_bounds(self): lb = 2 ub = 3 aop = AbstractOptimizationProblem() x = aop.create_variable('x', 2) g = x[0] - x[1] aop.include_inequality(g, lb=lb, ub=ub) self.assertTrue(is_equal(aop.g, g)) self.assertTrue(is_equal(aop.g_lb, lb)) self.assertTrue(is_equal(aop.g_ub, ub))
def test_include_inequality_w_external_variable_in_bound(self): theta = MX.sym('theta') lb = -theta ub = theta aop = AbstractOptimizationProblem() x = aop.create_variable('x', 2) g = x[0] - x[1] aop.include_inequality(g, lb=lb, ub=ub) self.assertTrue(is_equal(aop.g, g)) self.assertTrue(is_equal(aop.g_lb, lb)) self.assertTrue(is_equal(aop.g_ub, ub))
def test_lamb_sym(self): self.assertEqual(self.ode_model.lamb_sym.numel(), 0) self.assertEqual(self.dae_model.lamb_sym.numel(), 0) # with adjoints ode_lamb = self.ode_model.create_state("lamb", self.ode_model.n_x) self.ode_model.has_adjoint_variables = True dae_lamb = self.dae_model.create_state("lamb", self.dae_model.n_x) self.dae_model.has_adjoint_variables = True self.assertTrue(is_equal(self.ode_model.lamb_sym, ode_lamb)) self.assertTrue(is_equal(self.dae_model.lamb_sym, dae_lamb))
def test_include_equations_list(empty_model): x = empty_model.create_state('x', 2) u = empty_model.create_control('u') y = empty_model.create_algebraic_variable('y', 3) # test for list input ode = [-x - y[:1] + u] alg = [2 * x[0] - y[0] + u, 2 * x[1] - y[1] + u, 2 * x[0] - y[2] + u] empty_model.include_equations(ode=ode, alg=alg) assert is_equal(empty_model.ode, vertcat(*ode), 20) assert is_equal(empty_model.alg, vertcat(*alg), 20)
def test_x_sys_sym(self): self.assertTrue(is_equal(self.ode_model.x_sys_sym, self.ode_model.x)) # with adjoints ode_x = self.ode_model.x[:] dae_x = self.dae_model.x[:] self.ode_model.create_state("lamb", self.ode_model.n_x) self.ode_model.has_adjoint_variables = True self.dae_model.create_state("lamb", self.dae_model.n_x) self.dae_model.has_adjoint_variables = True self.assertTrue(is_equal(self.ode_model.x_sys_sym, ode_x)) self.assertTrue(is_equal(self.dae_model.x_sys_sym, dae_x))
def exitIfStatement(self, tree): logger.debug('exitIfStatement') # We assume an equal number of statements per branch. # Furthermore, we assume that every branch assigns to the same variables. assert (len(tree.statements) % (len(tree.conditions) + 1) == 0) statements_per_condition = int( len(tree.statements) / (len(tree.conditions) + 1)) all_assignments = [] for statement_index in range(statements_per_condition): assignments = self.get_mx(tree.statements[-(statement_index + 1)]) for assignment in assignments: src = assignment.right for cond_index in range(len(tree.conditions)): cond = self.get_mx(tree.conditions[-(cond_index + 1)]) src1 = None for i in range(statements_per_condition): other_assignments = self.get_mx( tree.statements[-statements_per_condition * (cond_index + 1) - (i + 1)]) for j in range(len(other_assignments)): if ca.is_equal(assignment.left, other_assignments[j].left): src1 = other_assignments[j].right break if src1 is not None: break src = ca.if_else(cond, src1, src, True) all_assignments.append(Assignment(assignment.left, src)) self.src[tree] = all_assignments
def test_substitute_variable_p(self): # Make system x = SX.sym('x') y = SX.sym('y') p = SX.sym('p') t = SX.sym('t') tau = SX.sym('tau') ode = -2 * x + y * p alg = y - x - p sys = DAESystem(x=x, y=y, ode=ode, alg=alg, tau=tau, t=t, p=p) # Test new_p = SX.sym('new_p') sys.substitute_variable(p, new_p) res = { 'ode': -2 * x + y * new_p, 'alg': y - x - new_p, 'x': x, 'y': y, 'p': new_p, 't': t, 'tau': tau } for key in res: self.assertTrue(is_equal(res[key], sys.__dict__[key], 10))
def test_set_objective(self): aop = AbstractOptimizationProblem() x = aop.create_variable('x', 2) f = x[0]**2 + x[1]**2 aop.set_objective(f) self.assertTrue(is_equal(aop.f, f))
def test_include_equations_der(empty_model): x = empty_model.create_state('x') u = empty_model.create_control('u') empty_model.include_equations(der(x) == -x + u) assert empty_model.ode.numel() == 1 assert is_equal(empty_model.ode, -x + u, 20)
def test_join(self): # Make system 1 x = SX.sym('x') y = SX.sym('y') p = SX.sym('p') t = SX.sym('t') tau = SX.sym('tau') ode = -2 * x + y * p * tau alg = y - x - p * t sys = DAESystem(x=x, y=y, ode=ode, alg=alg, tau=tau, t=t, p=p) # Make system 2 x2 = SX.sym('x2') y2 = SX.sym('y2') p2 = SX.sym('p2') t2 = SX.sym('t2') tau2 = SX.sym('tau2') ode2 = -2 * x2 + y2 * p2 * tau2 alg2 = y2 - x2 - p2 * t2 sys2 = DAESystem(x=x2, y=y2, ode=ode2, alg=alg2, tau=tau2, t=t2, p=p2) # Test res_sys = copy.copy(sys) res_sys.join(sys2) # check if variables and equations were passed for key in ['x', 'y', 'ode', 'alg', 'p']: self.assertTrue( is_equal(res_sys.__dict__[key][0], sys.__dict__[key], 30)) self.assertTrue( is_equal( res_sys.__dict__[key][1], substitute(sys2.__dict__[key], vertcat(sys2.tau, sys2.t), vertcat(sys.tau, sys.t)), 30)) # check if t and tau was passed (it shouldn't) self.assertFalse(is_equal(res_sys.t, sys2.t)) self.assertFalse(is_equal(res_sys.tau, sys2.tau)) # if the joined equation still depends on sys2 time varibles self.assertFalse(res_sys.depends_on(sys2.t)) self.assertFalse(res_sys.depends_on(sys2.tau))
def test_convert_from_tau_to_time(self): # Make system x = SX.sym('x', 2) y = SX.sym('y', 1) p = SX.sym('p') t = SX.sym('t') tau = SX.sym('tau') ode = tau alg = 1 - tau sys = DAESystem(x=x, y=y, ode=ode, alg=alg, tau=tau, t=t, p=p) # Test res = {'ode': t / 5, 'alg': (1 - t / 5)} sys.convert_from_tau_to_time(0, 5) self.assertTrue(is_equal(res['ode'], sys.ode, 10)) self.assertTrue(is_equal(res['alg'], sys.alg, 10))
def test_convert_expr_from_tau_to_time(self): t = SX.sym('t') tau = SX.sym('tau') expr = tau t_0 = 5 t_f = 15 correct_res = (t - t_0) / (t_f - t_0) res = convert_expr_from_tau_to_time(expr, t, tau, t_0, t_f) self.assertTrue(is_equal(res, correct_res, 10))
def test_create_constant_theta(self): constant = 3 dimension = 4 finite_elements = 5 # test normal use res_dict = dict( zip(range(finite_elements), [constant * DM.ones(dimension, 1)] * finite_elements)) theta = create_constant_theta(constant, dimension, finite_elements) for el in range(finite_elements): self.assertTrue(is_equal(theta[el], res_dict[el])) # Test 0 dimension res_dict = dict( zip(range(finite_elements), [constant * DM.ones(0, 1)] * finite_elements)) theta = create_constant_theta(constant, 0, finite_elements) for el in range(finite_elements): self.assertTrue(is_equal(theta[el], res_dict[el]))
def test_include_equations_ode_multi_dim(empty_model): x = empty_model.create_state("x", 2) u = empty_model.create_control("u", 2) a = DM([[-1, -2], [5, -1]]) b = DM([[1, 0], [0, 1]]) ode = (mtimes(a, x) + mtimes(b, u)) empty_model.include_equations(ode=ode) assert empty_model.ode.shape == (2, 1) assert is_equal(empty_model.ode, ode)
def test_get_variable_by_name(self): model = self.dae_model.get_copy() # Variable does not exist: self.assertRaises(ValueError, model.get_variable_by_name, "other_var") # Multiple vars self.assertRaises(ValueError, model.get_variable_by_name, "x") # Some var that exists and is unique var = model.get_variable_by_name("x_1") self.assertTrue(is_equal(model.x[1], var))