def test_variable_already_defined(self): """ Test to see if a variable has two equations """ eqn = Equation(self.model, 'x = 32 + y') eqn.parse(self.model._local_context) with self.assertRaises(EquationError) as context: eqn2 = Equation(self.model, 'x = z') eqn2.parse(self.model._local_context) self.assertEquals('var-eqn-exists', context.exception.errorid)
def test_missing_left_hand_side(self): """ Test that the left-hand side contains a variable """ eqn = Equation(self.model, 'a = x') with self.assertRaises(EquationError) as context: eqn.parse(self.model._local_context) self.assertEquals('lhs-variables', context.exception.errorid) eqn = Equation(self.model, '13 = x') with self.assertRaises(EquationError) as context: eqn.parse(self.model._local_context) self.assertEquals('lhs-variables', context.exception.errorid)
def test_non_linear_left_hand_side(self): """ Test for non-linearity in definition """ with self.assertRaises(EquationError) as context: eqn = Equation(self.model, 'x**2 = y') eqn.parse(self.model._local_context) self.assertEquals('non-linear', context.exception.errorid) with self.assertRaises(EquationError) as context: eqn = Equation(self.model, 'log(x) = y') eqn.parse(self.model._local_context) self.assertEquals('non-linear', context.exception.errorid)
def test_simple_parse(self): """ Test very simple equation parsing """ eqn = Equation(self.model, 'x = y') self.assertIsNotNone(eqn) self.assertEquals('x = y', eqn.equation) eqn.parse(self.model._local_context) self.assertEquals('y', str(eqn.expr)) self.assertEquals(self.y, eqn.expr) self.assertEquals(eqn, self.x.equation) self.assertEquals(self.x, eqn.variable)
def test_coefficient_handling(self): """ Test for coefficients on the left-hand side """ self.x.equation = None eqn = Equation(self.model, '22*x = y') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, eqn.expr - (self.y / 22.)) self.x.equation = None eqn = Equation(self.model, '22*a*x = y') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, eqn.expr - (self.y / (22*self.a)))
def test_coefficient_handling(self): """ Test for coefficients on the left-hand side """ self.x.equation = None eqn = Equation(self.model, '22*x = y') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, eqn.expr - (self.y / 22.)) self.x.equation = None eqn = Equation(self.model, '22*a*x = y') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, eqn.expr - (self.y / (22 * self.a)))
def test_constant_expressions(self): """ Test the basic handling of simple constant expressions on the left-hand side of the expression. """ # simple constants eqn = Equation(self.model, 'x-32=0') eqn.parse(self.model._local_context) self.assertEquals(32, eqn.expr) self.assertIsNotNone(self.x.equation) self.assertIsNone(self.y.equation) self.assertEquals(self.x.equation, eqn) # constants that use parameters self.x.equation = None eqn = Equation(self.model, 'x + 22*a=13') eqn.parse(self.model._local_context) self.assertEquals(0, 13-22*self.a - eqn.expr) # constants that use sympy symbols (such as pi, E) self.x.equation = None eqn = Equation(self.model, 'x + 44*pi*E = 0') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, -44*sympy.pi*sympy.E - eqn.expr) # constant expressions that use functions self.x.equation = None eqn = Equation(self.model, 'x+99*log(10) = 43') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, 43 - 99*sympy.log(10) - eqn.expr) # multiple constant expressions self.x.equation = None eqn = Equation(self.model, 'x - 3*pi**2 + 99*log(10) = y') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, (self.y + 3*sympy.pi*sympy.pi - 99*sympy.log(10) - eqn.expr))
def add(self, equation, desc=None): """ Adds an equation to the model. Arguments: equation: A string containing the equation. There cannot be any free symbols in the equation, all non-numeric symbols must have been defined as a parameter, variable, or a sympy built-in variable (like pi or E). desc: A description of the equation Returns: an Equation """ eqn = Equation(self, equation, desc=desc) eqn.parse(self._local_context) self._need_function_update = True self.equations.append(eqn) return eqn
def test_constant_expressions(self): """ Test the basic handling of simple constant expressions on the left-hand side of the expression. """ # simple constants eqn = Equation(self.model, 'x-32=0') eqn.parse(self.model._local_context) self.assertEquals(32, eqn.expr) self.assertIsNotNone(self.x.equation) self.assertIsNone(self.y.equation) self.assertEquals(self.x.equation, eqn) # constants that use parameters self.x.equation = None eqn = Equation(self.model, 'x + 22*a=13') eqn.parse(self.model._local_context) self.assertEquals(0, 13 - 22 * self.a - eqn.expr) # constants that use sympy symbols (such as pi, E) self.x.equation = None eqn = Equation(self.model, 'x + 44*pi*E = 0') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, -44 * sympy.pi * sympy.E - eqn.expr) # constant expressions that use functions self.x.equation = None eqn = Equation(self.model, 'x+99*log(10) = 43') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals(0, 43 - 99 * sympy.log(10) - eqn.expr) # multiple constant expressions self.x.equation = None eqn = Equation(self.model, 'x - 3*pi**2 + 99*log(10) = y') eqn.parse(self.model._local_context) self.assertIsNotNone(self.x.equation) self.assertEquals(eqn, self.x.equation) self.assertEquals( 0, (self.y + 3 * sympy.pi * sympy.pi - 99 * sympy.log(10) - eqn.expr))
def test_parse_equals_sign_error(self): """ Test error handling for wrong number of "=" signs """ eqn = Equation(self.model, 'x == y') with self.assertRaises(EquationError) as context: eqn.parse(self.model._local_context) self.assertEquals('equals-sign', context.exception.errorid) eqn = Equation(self.model, 'x - y') with self.assertRaises(EquationError) as context: eqn.parse(self.model._local_context) self.assertEquals('equals-sign', context.exception.errorid) eqn = Equation(self.model, 'x = y =') with self.assertRaises(EquationError) as context: eqn.parse(self.model._local_context) self.assertEquals('equals-sign', context.exception.errorid)
def test_parameter_series_accessor(self): """ Test that the series accessor works with parameters """ eqn = Equation(self.model, 'x = a(-1)') eqn.parse(self.model._local_context) self.assertEquals('_a__1', str(eqn.expr))
def test_series_accessor(self): """ Test to see that the series accessor is converted correctly. """ # This should work for variables, but not work for parameters eqn = Equation(self.model, 'x = x(-1)') eqn.parse(self.model._local_context) self.assertEquals('_x__1', str(eqn.expr))
def test_missing_symbols(self): """ Unknown symbols in equation """ with self.assertRaises(NameError): eqn = Equation(self.model, '14*x = 23*ww') eqn.parse(self.model._local_context)
def test_multi_vars_left_hand_side(self): """ Test for more than one variable on left hand side """ eqn = Equation(self.model, 'x + y = 32') with self.assertRaises(EquationError) as context: eqn.parse(self.model._local_context) self.assertEquals('lhs-variables', context.exception.errorid)