def testConstraint(self): """Test the Constraint class.""" p1 = Parameter("p1", 1) p2 = Parameter("p2", 2) factory = EquationFactory() factory.registerArgument("p1", p1) factory.registerArgument("p2", p2) c = Constraint() # Constrain p1 = 2*p2 eq = equationFromString("2*p2", factory) c.constrain(p1, eq) self.assertTrue(p1.constrained) self.assertFalse(p2.constrained) eq2 = equationFromString("2*p2+1", factory) c2 = Constraint() self.assertRaises(ValueError, c2.constrain, p1, eq2) p2.setConst() eq3 = equationFromString("p1", factory) self.assertRaises(ValueError, c2.constrain, p2, eq3) p2.setValue(2.5) c.update() self.assertEquals(5.0, p1.getValue()) p2.setValue(8.1) self.assertEquals(5.0, p1.getValue()) c.update() self.assertEquals(16.2, p1.getValue()) return
def constrain(self, par, con, ns={}): """Constrain a parameter to an equation. Note that only one constraint can exist on a Parameter at a time. par -- The name of a Parameter or a Parameter to constrain. con -- A string representation of the constraint equation or a Parameter to constrain to. A constraint equation must consist of numpy operators and "known" Parameters. Parameters are known if they are in the ns argument, or if they are managed by this object. ns -- A dictionary of Parameters, indexed by name, that are used in the parameter, but not part of this object (default {}). Raises ValueError if ns uses a name that is already used for a variable. Raises ValueError if par is a string but not part of this object or in ns. Raises ValueError if par is marked as constant. """ if isinstance(par, basestring): name = par par = self.get(name) if par is None: par = ns.get(name) if par is None: raise ValueError("The parameter cannot be found") if par.const: raise ValueError("The parameter '%s' is constant" % par) if isinstance(con, basestring): eqstr = con eq = equationFromString(con, self._eqfactory, ns) else: eq = Equation(root=con) eqstr = con.name eq.name = "_constraint_%s" % par.name # Make and store the constraint con = Constraint() con.constrain(par, eq) # Store the equation string so it can be shown later. con.eqstr = eqstr self._constraints[par] = con # Our configuration changed self._updateConfiguration() return