def testGetRestraints(self):
        """Test the _getRestraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        r1 = self.m.restrain("p1 + p2")
        r2 = m2.restrain("2*p3 + p4")

        res = self.m._getRestraints()
        self.assertTrue(r1 in res)
        self.assertTrue(r2 in res)
        self.assertEquals(2, len(res))
        return
    def testGetConstraints(self):
        """Test the _getConstraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        self.m.constrain(p1, "p2")
        m2.constrain(p3, "p4")

        cons = self.m._getConstraints()
        self.assertTrue(p1 in cons)
        self.assertTrue(p3 in cons)
        self.assertEquals(2, len(cons))
        return
예제 #3
0
    def testGetRestraints(self):
        """Test the _getRestraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        r1 = self.m.restrain("p1 + p2")
        r2 = m2.restrain("2*p3 + p4")

        res = self.m._getRestraints()
        self.assertTrue(r1 in res)
        self.assertTrue(r2 in res)
        self.assertEqual(2, len(res))
        return
예제 #4
0
    def setUp(self):
        self.m = RecipeOrganizer("test")

        # Add a managed container so we can do more in-depth tests.
        self.m._containers = {}
        self.m._manage(self.m._containers)
        return
예제 #5
0
    def __init__(self, name):
        """Initialize.

        name    --  The name of this ParameterSet.

        """
        RecipeOrganizer.__init__(self, name)

        self._parsets = {}
        self._manage(self._parsets)
        return
예제 #6
0
    def __init__(self, name):
        """Initialize.

        name    --  The name of this ParameterSet.

        """
        RecipeOrganizer.__init__(self, name)

        self._parsets = {}
        self._manage(self._parsets)
        return
예제 #7
0
    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.

        This is overloaded to set the value of con if it represents a variable
        and its current value is None. A constrained variable will be set as
        fixed.

        par     --  The 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 eqstr, but not part of this object (default {}).

        Raises ValueError if ns uses a name that is already used for a
        variable.
        Raises ValueError if eqstr depends on a Parameter that is not part of
        the FitRecipe and that is not defined in ns.
        Raises ValueError if par is marked as constant.
        """
        if isinstance(par, six.string_types):
            name = par
            par = self.get(name)
            if par is None:
                par = ns.get(name)
            if par is None:
                raise ValueError("The parameter '%s' cannot be found"%name)

        if con in self._parameters.keys():
            con = self._parameters[con]

        if par.const:
            raise ValueError("The parameter '%s' is constant"%par)

        # This will pass the value of a constrained parameter to the initial
        # value of a parameter constraint.
        if con in self._parameters.values():
            val = con.getValue()
            if val is None:
                val = par.getValue()
                con.setValue(val)

        if par in self._parameters.values():
            self.fix(par)

        RecipeOrganizer.constrain(self, par, con, ns)
        return
예제 #8
0
    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.

        This is overloaded to set the value of con if it represents a variable
        and its current value is None. A constrained variable will be set as
        fixed.

        par     --  The 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 eqstr, but not part of this object (default {}).

        Raises ValueError if ns uses a name that is already used for a
        variable.
        Raises ValueError if eqstr depends on a Parameter that is not part of
        the FitRecipe and that is not defined in ns.
        Raises ValueError if par is marked as constant.
        """
        if isinstance(par, six.string_types):
            name = par
            par = self.get(name)
            if par is None:
                par = ns.get(name)
            if par is None:
                raise ValueError("The parameter '%s' cannot be found" % name)

        if con in self._parameters.keys():
            con = self._parameters[con]

        if par.const:
            raise ValueError("The parameter '%s' is constant" % par)

        # This will pass the value of a constrained parameter to the initial
        # value of a parameter constraint.
        if con in self._parameters.values():
            val = con.getValue()
            if val is None:
                val = par.getValue()
                con.setValue(val)

        if par in self._parameters.values():
            self.fix(par)

        RecipeOrganizer.constrain(self, par, con, ns)
        return
    def setUp(self):
        self.m = RecipeOrganizer("test")

        # Add a managed container so we can do more in-depth tests.
        self.m._containers = {}
        self.m._manage(self.m._containers)
        return
예제 #10
0
    def _newParameter(self, name, value, check=True):
        """Overloaded to tag variables.

        See RecipeOrganizer._newParameter
        """
        par = RecipeOrganizer._newParameter(self, name, value, check)
        # tag this
        self._tagmanager.tag(par, par.name)
        self._tagmanager.tag(par, "all")
        self.fix(par.name)
        return par
예제 #11
0
    def __init__(self, name="fit"):
        """Initialization."""
        RecipeOrganizer.__init__(self, name)
        self.fithooks = []
        self.pushFitHook(PrintFitHook())
        self._restraintlist = []
        self._oconstraints = []
        self._ready = False
        self._fixedtag = "__fixed"

        self._weights = []
        self._tagmanager = TagManager()

        self._parsets = {}
        self._manage(self._parsets)

        self._contributions = OrderedDict()
        self._manage(self._contributions)

        return
예제 #12
0
    def __init__(self, name = "fit"):
        """Initialization."""
        RecipeOrganizer.__init__(self, name)
        self.fithooks = []
        self.pushFitHook(PrintFitHook())
        self._restraintlist = []
        self._oconstraints = []
        self._ready = False
        self._fixedtag = "__fixed"

        self._weights = []
        self._tagmanager = TagManager()

        self._parsets = {}
        self._manage(self._parsets)

        self._contributions = OrderedDict()
        self._manage(self._contributions)

        return
예제 #13
0
    def _newParameter(self, name, value, check=True):
        """Overloaded to tag variables.

        See RecipeOrganizer._newParameter
        """
        par = RecipeOrganizer._newParameter(self, name, value, check)
        # tag this
        self._tagmanager.tag(par, par.name)
        self._tagmanager.tag(par, "all")
        self.fix(par.name)
        return par
예제 #14
0
    def testGetConstraints(self):
        """Test the _getConstraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        self.m.constrain(p1, "p2")
        m2.constrain(p3, "p4")

        cons = self.m._getConstraints()
        self.assertTrue(p1 in cons)
        self.assertTrue(p3 in cons)
        self.assertEqual(2, len(cons))
        return
예제 #15
0
    def test_show(self):
        """Verify output from the show function.
        """
        def capture_show(*args, **kwargs):
            sys.stdout = cStringIO.StringIO()
            self.m.show(*args, **kwargs)
            rv = sys.stdout.getvalue()
            sys.stdout = sys.__stdout__
            return rv

        self.assertEqual('', capture_show())
        self.m._newParameter('x', 1)
        self.m._newParameter('y', 2)
        out1 = capture_show()
        lines1 = out1.strip().split('\n')
        self.assertEqual(4, len(lines1))
        self.assertTrue('Parameters' in lines1)
        self.assertFalse('Constraints' in lines1)
        self.assertFalse('Restraints' in lines1)
        self.m._newParameter('z', 7)
        self.m.constrain('y', '3 * z')
        out2 = capture_show()
        lines2 = out2.strip().split('\n')
        self.assertEqual(9, len(lines2))
        self.assertTrue('Parameters' in lines2)
        self.assertTrue('Constraints' in lines2)
        self.assertFalse('Restraints' in lines2)
        self.m.restrain('z', lb=2, ub=3, sig=0.001)
        out3 = capture_show()
        lines3 = out3.strip().split('\n')
        self.assertEqual(13, len(lines3))
        self.assertTrue('Parameters' in lines3)
        self.assertTrue('Constraints' in lines3)
        self.assertTrue('Restraints' in lines3)
        out4 = capture_show(pattern='x')
        lines4 = out4.strip().split('\n')
        self.assertEqual(9, len(lines4))
        out5 = capture_show(pattern='^')
        self.assertEqual(out3, out5)
        # check output with another level of hierarchy
        self.m._addObject(RecipeOrganizer("foo"), self.m._containers)
        self.m.foo._newParameter("bar", 13)
        out6 = capture_show()
        self.assertTrue("foo.bar" in out6)
        # filter out foo.bar
        out7 = capture_show('^(?!foo).')
        self.assertFalse("foo.bar" in out7)
        self.assertEqual(out3, out7)
        return
예제 #16
0
class TestRecipeOrganizer(unittest.TestCase):
    def setUp(self):
        self.m = RecipeOrganizer("test")

        # Add a managed container so we can do more in-depth tests.
        self.m._containers = {}
        self.m._manage(self.m._containers)
        return

    def testNewParameter(self):
        """Test the addParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        m._addParameter(p1)

        # Test duplication of Parameters
        self.assertRaises(ValueError, m._newParameter, "p1", 0)

        # Add a new Parameter
        p2 = m._newParameter("p2", 0)
        self.assertTrue(p2 is m.p2)

        return

    def testAddParameter(self):
        """Test the addParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        p2 = Parameter("p1", 2)

        # Check normal insert
        m._addParameter(p1)
        self.assertTrue(m.p1 is p1)
        self.assertTrue(p1.name in m._eqfactory.builders)

        # Try to insert another parameter with the same name
        self.assertRaises(ValueError, m._addParameter, p2)

        # Now allow this
        m._addParameter(p2, check=False)
        self.assertTrue(m.p1 is p2)
        self.assertTrue(p1.name in m._eqfactory.builders)

        # Try to insert a Parameter when a RecipeContainer with the same name
        # is already inside.
        c = RecipeContainer("test")
        m._addObject(c, m._containers)

        p3 = Parameter("test", 0)
        self.assertRaises(ValueError, m._addParameter, p3)

        p4 = Parameter("xyz", 0)
        m._addParameter(p4)

        # Check order
        self.assertEquals(m._parameters.keys(), ["p1", "xyz"])
        self.assertEquals(m._parameters.values(), [p2, p4])

        return

    def testRemoveParameter(self):
        """Test removeParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        p2 = Parameter("p1", 2)

        m._addParameter(p1)

        # Check for bad remove
        self.assertRaises(ValueError, m._removeParameter, p2)

        # Remove p1
        m._removeParameter(p1)
        self.assertTrue(p1.name not in m._eqfactory.builders)

        # Try to remove it again
        self.assertRaises(ValueError, m._removeParameter, p1)

        # Try to remove a RecipeContainer
        c = RecipeContainer("test")
        self.assertRaises(ValueError, m._removeParameter, c)
        return

    def testConstrain(self):
        """Test the constrain method."""

        p1 = self.m._newParameter("p1", 1)
        p2 = self.m._newParameter("p2", 2)
        p3 = Parameter("p3", 3)

        self.assertFalse(p1.constrained)
        self.assertEquals(0, len(self.m._constraints))
        self.m.constrain(p1, "2*p2")

        self.assertTrue(p1.constrained)
        self.assertTrue(p1 in self.m._constraints)
        self.assertEquals(1, len(self.m._constraints))
        self.assertTrue(self.m.isConstrained(p1))

        p2.setValue(10)
        self.m._constraints[p1].update()
        self.assertEquals(20, p1.getValue())

        # Check errors on unregistered parameters
        self.assertRaises(ValueError, self.m.constrain, p1, "2*p3")
        self.assertRaises(ValueError, self.m.constrain, p1, "2*p2", {"p2": p3})

        # Remove the constraint
        self.m.unconstrain(p1)
        self.assertFalse(p1.constrained)
        self.assertEquals(0, len(self.m._constraints))
        self.assertFalse(self.m.isConstrained(p1))

        # Try an straight constraint
        self.m.constrain(p1, p2)
        p2.setValue(7)
        self.m._constraints[p1].update()
        self.assertEquals(7, p1.getValue())
        return

    def testRestrain(self):
        """Test the restrain method."""

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        self.m._eqfactory.registerArgument("p1", p1)
        self.m._eqfactory.registerArgument("p2", p2)

        self.assertEquals(0, len(self.m._restraints))
        r = self.m.restrain("p1+p2", ub=10)
        self.assertEquals(1, len(self.m._restraints))
        p2.setValue(10)
        self.assertEquals(1, r.penalty())
        self.m.unrestrain(r)
        self.assertEquals(0, len(self.m._restraints))

        r = self.m.restrain(p1, ub=10)
        self.assertEquals(1, len(self.m._restraints))
        p1.setValue(11)
        self.assertEquals(1, r.penalty())

        # Check errors on unregistered parameters
        self.assertRaises(ValueError, self.m.restrain, "2*p3")
        self.assertRaises(ValueError, self.m.restrain, "2*p2", ns={"p2": p3})
        return

    def testGetConstraints(self):
        """Test the _getConstraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        self.m.constrain(p1, "p2")
        m2.constrain(p3, "p4")

        cons = self.m._getConstraints()
        self.assertTrue(p1 in cons)
        self.assertTrue(p3 in cons)
        self.assertEquals(2, len(cons))
        return

    def testGetRestraints(self):
        """Test the _getRestraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        r1 = self.m.restrain("p1 + p2")
        r2 = m2.restrain("2*p3 + p4")

        res = self.m._getRestraints()
        self.assertTrue(r1 in res)
        self.assertTrue(r2 in res)
        self.assertEquals(2, len(res))
        return

    def testRegisterCalculator(self):
        class GCalc(Calculator):
            def __init__(self, name):
                Calculator.__init__(self, name)
                self.newParameter("A", 1.0)
                self.newParameter("center", 0.0)
                self.newParameter("width", 0.1)
                return

            def __call__(self, x):
                A = self.A.getValue()
                c = self.center.getValue()
                w = self.width.getValue()
                return A * numpy.exp(-0.5 * ((x - c) / w)**2)

        # End class GCalc

        g = GCalc("g")

        self.m.registerCalculator(g)

        x = numpy.arange(0.5, 10, 0.5)
        self.m.x.setValue(x)

        self.m.g.center.setValue(3.0)

        self.assertTrue(
            numpy.array_equal(numpy.exp(-0.5 * ((x - 3.0) / 0.1)**2), g(x)))

        self.m.g.center.setValue(5.0)

        self.assertTrue(
            numpy.array_equal(numpy.exp(-0.5 * ((x - 5.0) / 0.1)**2), g(x)))

        # Use this in another equation

        eq = self.m.registerStringFunction("g/x - 1", "pdf")
        self.assertTrue(numpy.array_equal(g(x) / x - 1, eq()))

        return

    def testRegisterFunction(self):
        """Test registering various functions."""
        def g1(A, c, w, x):
            return A * numpy.exp(-0.5 * ((x - c) / w)**2)

        def g2(A):
            return A + 1

        eq = self.m.registerFunction(g1, "g")

        for p in eq.args:
            self.assertTrue(p in self.m._parameters.values())

        x = numpy.arange(0.5, 10, 0.5)
        self.m.x.setValue(x)
        self.m.A.setValue(1.0)
        self.m.c.setValue(3.0)
        self.m.w.setValue(0.1)

        self.assertTrue(
            numpy.array_equal(numpy.exp(-0.5 * ((x - 3.0) / 0.1)**2), eq()))

        # Use this in another equation
        eq2 = self.m.registerStringFunction("g/x - 1", "pdf")
        self.assertTrue(numpy.array_equal(eq() / x - 1, eq2()))

        # Make sure we can swap out "g".
        self.m.registerFunction(g2, "g")
        self.assertAlmostEquals(2.0, eq())

        # Try a bound method
        class temp(object):
            def eval(self):
                return 1.23

            def __call__(self):
                return 4.56

        t = temp()
        eq = self.m.registerFunction(t.eval, "eval")
        self.assertAlmostEquals(1.23, eq())

        # Now the callable
        eq2 = self.m.registerFunction(t, "eval2")
        self.assertAlmostEquals(4.56, eq2())

        return

    def testRegisterStringFunction(self):
        """Test registering string functions in various ways."""

        # Make an equation.
        eq1 = self.m.registerStringFunction("x**2 + 3", "eq1")
        eq1.x.setValue(0)

        for p in eq1.args:
            self.assertTrue(p in self.m._parameters.values())

        # Add a parameter
        self.m._newParameter("y", 3.0)

        # Make sure that x and y are in the organizer
        self.assertEquals(0, self.m.x.getValue())
        self.assertEquals(3.0, self.m.y.getValue())

        # Use eq1 in some equations

        # x**2 (x**2 + 3 - 3)
        eq2 = self.m.registerStringFunction("eq1 - 3", "eq2")
        # y**2
        eq3 = self.m.registerStringFunction("eq1(y) - 3", "eq3")

        # Test these equations.
        self.assertEquals(0, eq2())
        self.assertEquals(9.0, eq3())
        # Note that eq3 injects the value of y into the argument of eq1, which
        # is x. Thus, calling eq3 sets x to 3.
        self.assertEquals(9.0, eq2())

        # One more level of embedding
        # 2*y**2
        eq4 = self.m.registerStringFunction("2*eq3", "eq4")
        self.assertEquals(18.0, eq4())

        return
class TestRecipeOrganizer(unittest.TestCase):

    def setUp(self):
        self.m = RecipeOrganizer("test")

        # Add a managed container so we can do more in-depth tests.
        self.m._containers = {}
        self.m._manage(self.m._containers)
        return

    def testNewParameter(self):
        """Test the addParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        m._addParameter(p1)

        # Test duplication of Parameters
        self.assertRaises(ValueError, m._newParameter, "p1", 0)

        # Add a new Parameter
        p2 = m._newParameter("p2", 0)
        self.assertTrue(p2 is m.p2)

        return

    def testAddParameter(self):
        """Test the addParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        p2 = Parameter("p1", 2)

        # Check normal insert
        m._addParameter(p1)
        self.assertTrue(m.p1 is p1)
        self.assertTrue(p1.name in m._eqfactory.builders)

        # Try to insert another parameter with the same name
        self.assertRaises(ValueError, m._addParameter, p2)

        # Now allow this
        m._addParameter(p2, check=False)
        self.assertTrue(m.p1 is p2)
        self.assertTrue(p1.name in m._eqfactory.builders)

        # Try to insert a Parameter when a RecipeContainer with the same name
        # is already inside.
        c = RecipeContainer("test")
        m._addObject(c, m._containers)

        p3 = Parameter("test", 0)
        self.assertRaises(ValueError, m._addParameter, p3)

        p4 = Parameter("xyz", 0)
        m._addParameter(p4)

        # Check order
        self.assertEquals(m._parameters.keys(), ["p1", "xyz"])
        self.assertEquals(m._parameters.values(), [p2, p4])

        return

    def testRemoveParameter(self):
        """Test removeParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        p2 = Parameter("p1", 2)

        m._addParameter(p1)

        # Check for bad remove
        self.assertRaises(ValueError, m._removeParameter, p2)

        # Remove p1
        m._removeParameter(p1)
        self.assertTrue(p1.name not in m._eqfactory.builders)

        # Try to remove it again
        self.assertRaises(ValueError, m._removeParameter, p1)

        # Try to remove a RecipeContainer
        c = RecipeContainer("test")
        self.assertRaises(ValueError, m._removeParameter, c)
        return

    def testConstrain(self):
        """Test the constrain method."""

        p1 = self.m._newParameter("p1", 1)
        p2 = self.m._newParameter("p2", 2)
        p3 = Parameter("p3", 3)

        self.assertFalse(p1.constrained)
        self.assertEquals(0, len(self.m._constraints))
        self.m.constrain(p1, "2*p2")


        self.assertTrue(p1.constrained)
        self.assertTrue(p1 in self.m._constraints)
        self.assertEquals(1, len(self.m._constraints))
        self.assertTrue(self.m.isConstrained(p1))

        p2.setValue(10)
        self.m._constraints[p1].update()
        self.assertEquals(20, p1.getValue())

        # Check errors on unregistered parameters
        self.assertRaises(ValueError, self.m.constrain, p1, "2*p3")
        self.assertRaises(ValueError, self.m.constrain, p1, "2*p2", {"p2":p3})

        # Remove the constraint
        self.m.unconstrain(p1)
        self.assertFalse(p1.constrained)
        self.assertEquals(0, len(self.m._constraints))
        self.assertFalse(self.m.isConstrained(p1))

        # Try an straight constraint
        self.m.constrain(p1, p2)
        p2.setValue(7)
        self.m._constraints[p1].update()
        self.assertEquals(7, p1.getValue())
        return

    def testRestrain(self):
        """Test the restrain method."""

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        self.m._eqfactory.registerArgument("p1", p1)
        self.m._eqfactory.registerArgument("p2", p2)

        self.assertEquals(0, len(self.m._restraints))
        r = self.m.restrain("p1+p2", ub = 10)
        self.assertEquals(1, len(self.m._restraints))
        p2.setValue(10)
        self.assertEquals(1, r.penalty())
        self.m.unrestrain(r)
        self.assertEquals(0, len(self.m._restraints))

        r = self.m.restrain(p1, ub = 10)
        self.assertEquals(1, len(self.m._restraints))
        p1.setValue(11)
        self.assertEquals(1, r.penalty())

        # Check errors on unregistered parameters
        self.assertRaises(ValueError, self.m.restrain, "2*p3")
        self.assertRaises(ValueError, self.m.restrain, "2*p2", ns = {"p2":p3})
        return

    def testGetConstraints(self):
        """Test the _getConstraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        self.m.constrain(p1, "p2")
        m2.constrain(p3, "p4")

        cons = self.m._getConstraints()
        self.assertTrue(p1 in cons)
        self.assertTrue(p3 in cons)
        self.assertEquals(2, len(cons))
        return

    def testGetRestraints(self):
        """Test the _getRestraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        r1 = self.m.restrain("p1 + p2")
        r2 = m2.restrain("2*p3 + p4")

        res = self.m._getRestraints()
        self.assertTrue(r1 in res)
        self.assertTrue(r2 in res)
        self.assertEquals(2, len(res))
        return

    def testRegisterCalculator(self):

        class GCalc(Calculator):

            def __init__(self, name):
                Calculator.__init__(self, name)
                self.newParameter("A", 1.0)
                self.newParameter("center", 0.0)
                self.newParameter("width", 0.1)
                return

            def __call__(self, x):
                A = self.A.getValue()
                c = self.center.getValue()
                w = self.width.getValue()
                return A * numpy.exp(-0.5*((x-c)/w)**2)

        # End class GCalc

        g = GCalc("g")

        self.m.registerCalculator(g)

        x = numpy.arange(0.5, 10, 0.5)
        self.m.x.setValue(x)

        self.m.g.center.setValue(3.0)

        self.assertTrue(numpy.array_equal(numpy.exp(-0.5*((x-3.0)/0.1)**2),
            g(x)))

        self.m.g.center.setValue(5.0)

        self.assertTrue(numpy.array_equal(numpy.exp(-0.5*((x-5.0)/0.1)**2),
            g(x)))

        # Use this in another equation

        eq = self.m.registerStringFunction("g/x - 1", "pdf")
        self.assertTrue(numpy.array_equal(g(x)/x - 1, eq()))

        return

    def testRegisterFunction(self):
        """Test registering various functions."""
        def g1(A, c, w, x):
            return A * numpy.exp(-0.5*((x-c)/w)**2)
        def g2(A):
            return A+1

        eq = self.m.registerFunction(g1, "g")

        for p in eq.args:
            self.assertTrue(p in self.m._parameters.values())

        x = numpy.arange(0.5, 10, 0.5)
        self.m.x.setValue(x)
        self.m.A.setValue(1.0)
        self.m.c.setValue(3.0)
        self.m.w.setValue(0.1)

        self.assertTrue(numpy.array_equal(numpy.exp(-0.5*((x-3.0)/0.1)**2),
            eq()))

        # Use this in another equation
        eq2 = self.m.registerStringFunction("g/x - 1", "pdf")
        self.assertTrue(numpy.array_equal(eq()/x - 1, eq2()))

        # Make sure we can swap out "g".
        self.m.registerFunction(g2, "g")
        self.assertAlmostEquals(2.0, eq())

        # Try a bound method
        class temp(object):
            def eval(self): return 1.23
            def __call__(self): return 4.56

        t = temp()
        eq = self.m.registerFunction(t.eval, "eval")
        self.assertAlmostEquals(1.23, eq())

        # Now the callable
        eq2 = self.m.registerFunction(t, "eval2")
        self.assertAlmostEquals(4.56, eq2())

        return

    def testRegisterStringFunction(self):
        """Test registering string functions in various ways."""

        # Make an equation.
        eq1 = self.m.registerStringFunction("x**2 + 3", "eq1")
        eq1.x.setValue(0)

        for p in eq1.args:
            self.assertTrue(p in self.m._parameters.values())

        # Add a parameter
        self.m._newParameter("y", 3.0)

        # Make sure that x and y are in the organizer
        self.assertEquals(0, self.m.x.getValue())
        self.assertEquals(3.0, self.m.y.getValue())

        # Use eq1 in some equations

        # x**2 (x**2 + 3 - 3)
        eq2 = self.m.registerStringFunction("eq1 - 3", "eq2")
        # y**2
        eq3 = self.m.registerStringFunction("eq1(y) - 3", "eq3")

        # Test these equations.
        self.assertEquals(0, eq2())
        self.assertEquals(9.0, eq3())
        # Note that eq3 injects the value of y into the argument of eq1, which
        # is x. Thus, calling eq3 sets x to 3.
        self.assertEquals(9.0, eq2())

        # One more level of embedding
        # 2*y**2
        eq4 = self.m.registerStringFunction("2*eq3", "eq4")
        self.assertEquals(18.0, eq4())

        return
예제 #18
0
class TestRecipeOrganizer(unittest.TestCase):
    def setUp(self):
        self.m = RecipeOrganizer("test")
        # Add a managed container so we can do more in-depth tests.
        self.m._containers = {}
        self.m._manage(self.m._containers)
        return

    def tearDown(self):
        sys.stdout = sys.__stdout__
        return

    def testNewParameter(self):
        """Test the addParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        m._addParameter(p1)

        # Test duplication of Parameters
        self.assertRaises(ValueError, m._newParameter, "p1", 0)

        # Add a new Parameter
        p2 = m._newParameter("p2", 0)
        self.assertTrue(p2 is m.p2)
        return

    def testAddParameter(self):
        """Test the addParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        p2 = Parameter("p1", 2)

        # Check normal insert
        m._addParameter(p1)
        self.assertTrue(m.p1 is p1)
        self.assertTrue(p1.name in m._eqfactory.builders)

        # Try to insert another parameter with the same name
        self.assertRaises(ValueError, m._addParameter, p2)

        # Now allow this
        m._addParameter(p2, check=False)
        self.assertTrue(m.p1 is p2)
        self.assertTrue(p1.name in m._eqfactory.builders)

        # Try to insert a Parameter when a RecipeContainer with the same name
        # is already inside.
        c = RecipeContainer("test")
        m._addObject(c, m._containers)

        p3 = Parameter("test", 0)
        self.assertRaises(ValueError, m._addParameter, p3)

        p4 = Parameter("xyz", 0)
        m._addParameter(p4)

        # Check order
        self.assertEqual(m._parameters.keys(), ["p1", "xyz"])
        self.assertEqual(m._parameters.values(), [p2, p4])

        return

    def testRemoveParameter(self):
        """Test removeParameter method."""

        m = self.m

        p1 = Parameter("p1", 1)
        p2 = Parameter("p1", 2)

        m._addParameter(p1)

        # Check for bad remove
        self.assertRaises(ValueError, m._removeParameter, p2)

        # Remove p1
        m._removeParameter(p1)
        self.assertTrue(p1.name not in m._eqfactory.builders)

        # Try to remove it again
        self.assertRaises(ValueError, m._removeParameter, p1)

        # Try to remove a RecipeContainer
        c = RecipeContainer("test")
        self.assertRaises(ValueError, m._removeParameter, c)
        return

    def testConstrain(self):
        """Test the constrain method."""

        p1 = self.m._newParameter("p1", 1)
        p2 = self.m._newParameter("p2", 2)
        p3 = Parameter("p3", 3)

        self.assertFalse(p1.constrained)
        self.assertEqual(0, len(self.m._constraints))
        self.m.constrain(p1, "2*p2")

        self.assertTrue(p1.constrained)
        self.assertTrue(p1 in self.m._constraints)
        self.assertEqual(1, len(self.m._constraints))
        self.assertTrue(self.m.isConstrained(p1))

        p2.setValue(10)
        self.m._constraints[p1].update()
        self.assertEqual(20, p1.getValue())

        # Check errors on unregistered parameters
        self.assertRaises(ValueError, self.m.constrain, p1, "2*p3")
        self.assertRaises(ValueError, self.m.constrain, p1, "2*p2", {"p2": p3})

        # Remove the constraint
        self.m.unconstrain(p1)
        self.assertFalse(p1.constrained)
        self.assertEqual(0, len(self.m._constraints))
        self.assertFalse(self.m.isConstrained(p1))

        # Try an straight constraint
        self.m.constrain(p1, p2)
        p2.setValue(7)
        self.m._constraints[p1].update()
        self.assertEqual(7, p1.getValue())
        return

    def testRestrain(self):
        """Test the restrain method."""

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        self.m._eqfactory.registerArgument("p1", p1)
        self.m._eqfactory.registerArgument("p2", p2)

        self.assertEqual(0, len(self.m._restraints))
        r = self.m.restrain("p1+p2", ub=10)
        self.assertEqual(1, len(self.m._restraints))
        p2.setValue(10)
        self.assertEqual(1, r.penalty())
        self.m.unrestrain(r)
        self.assertEqual(0, len(self.m._restraints))

        r = self.m.restrain(p1, ub=10)
        self.assertEqual(1, len(self.m._restraints))
        p1.setValue(11)
        self.assertEqual(1, r.penalty())

        # Check errors on unregistered parameters
        self.assertRaises(ValueError, self.m.restrain, "2*p3")
        self.assertRaises(ValueError, self.m.restrain, "2*p2", ns={"p2": p3})
        return

    def testGetConstraints(self):
        """Test the _getConstraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        self.m.constrain(p1, "p2")
        m2.constrain(p3, "p4")

        cons = self.m._getConstraints()
        self.assertTrue(p1 in cons)
        self.assertTrue(p3 in cons)
        self.assertEqual(2, len(cons))
        return

    def testGetRestraints(self):
        """Test the _getRestraints method."""
        m2 = RecipeOrganizer("m2")
        self.m._organizers = {}
        self.m._manage(self.m._organizers)
        self.m._addObject(m2, self.m._organizers)

        p1 = Parameter("p1", 1)
        p2 = Parameter("p2", 2)
        p3 = Parameter("p3", 3)
        p4 = Parameter("p4", 4)

        self.m._addParameter(p1)
        self.m._addParameter(p2)

        m2._addParameter(p3)
        m2._addParameter(p4)

        r1 = self.m.restrain("p1 + p2")
        r2 = m2.restrain("2*p3 + p4")

        res = self.m._getRestraints()
        self.assertTrue(r1 in res)
        self.assertTrue(r2 in res)
        self.assertEqual(2, len(res))
        return

    def testRegisterCalculator(self):
        class GCalc(Calculator):
            def __init__(self, name):
                Calculator.__init__(self, name)
                self.newParameter("A", 1.0)
                self.newParameter("center", 0.0)
                self.newParameter("width", 0.1)
                return

            def __call__(self, x):
                A = self.A.getValue()
                c = self.center.getValue()
                w = self.width.getValue()
                return A * numpy.exp(-0.5 * ((x - c) / w)**2)

        # End class GCalc

        g = GCalc("g")

        self.m.registerCalculator(g)

        x = numpy.arange(0.5, 10, 0.5)
        self.m.x.setValue(x)

        self.m.g.center.setValue(3.0)

        self.assertTrue(
            numpy.array_equal(numpy.exp(-0.5 * ((x - 3.0) / 0.1)**2), g(x)))

        self.m.g.center.setValue(5.0)

        self.assertTrue(
            numpy.array_equal(numpy.exp(-0.5 * ((x - 5.0) / 0.1)**2), g(x)))

        # Use this in another equation

        eq = self.m.registerStringFunction("g/x - 1", "pdf")
        self.assertTrue(numpy.array_equal(g(x) / x - 1, eq()))

        return

    def testRegisterFunction(self):
        """Test registering various functions."""
        def g1(A, c, w, x):
            return A * numpy.exp(-0.5 * ((x - c) / w)**2)

        def g2(A):
            return A + 1

        eq = self.m.registerFunction(g1, "g")

        for p in eq.args:
            self.assertTrue(p in self.m._parameters.values())

        x = numpy.arange(0.5, 10, 0.5)
        self.m.x.setValue(x)
        self.m.A.setValue(1.0)
        self.m.c.setValue(3.0)
        self.m.w.setValue(0.1)

        self.assertTrue(
            numpy.array_equal(numpy.exp(-0.5 * ((x - 3.0) / 0.1)**2), eq()))

        # Use this in another equation
        eq2 = self.m.registerStringFunction("g/x - 1", "pdf")
        self.assertTrue(numpy.array_equal(eq() / x - 1, eq2()))

        # Make sure we can swap out "g".
        self.m.registerFunction(g2, "g")
        self.assertAlmostEqual(2.0, eq())

        # Try a bound method
        class temp(object):
            def eval(self):
                return 1.23

            def __call__(self):
                return 4.56

        t = temp()
        eq = self.m.registerFunction(t.eval, "eval")
        self.assertAlmostEqual(1.23, eq())

        # Now the callable
        eq2 = self.m.registerFunction(t, "eval2")
        self.assertAlmostEqual(4.56, eq2())

        return

    def testRegisterStringFunction(self):
        """Test registering string functions in various ways."""

        # Make an equation.
        eq1 = self.m.registerStringFunction("x**2 + 3", "eq1")
        eq1.x.setValue(0)

        for p in eq1.args:
            self.assertTrue(p in self.m._parameters.values())

        # Add a parameter
        self.m._newParameter("y", 3.0)

        # Make sure that x and y are in the organizer
        self.assertEqual(0, self.m.x.getValue())
        self.assertEqual(3.0, self.m.y.getValue())

        # Use eq1 in some equations

        # x**2 (x**2 + 3 - 3)
        eq2 = self.m.registerStringFunction("eq1 - 3", "eq2")
        # y**2
        eq3 = self.m.registerStringFunction("eq1(y) - 3", "eq3")

        # Test these equations.
        self.assertEqual(0, eq2())
        self.assertEqual(9.0, eq3())
        # Note that eq3 injects the value of y into the argument of eq1, which
        # is x. Thus, calling eq3 sets x to 3.
        self.assertEqual(9.0, eq2())

        # One more level of embedding
        # 2*y**2
        eq4 = self.m.registerStringFunction("2*eq3", "eq4")
        self.assertEqual(18.0, eq4())

        return

    def test_releaseOldEquations(self):
        """Verify EquationFactory does not hold temporary equations.
        """
        self.m._newParameter('x', 12)
        self.assertEqual(36, self.m.evaluateEquation('3 * x'))
        self.assertEqual(0, len(self.m._eqfactory.equations))
        return

    def test_show(self):
        """Verify output from the show function.
        """
        def capture_show(*args, **kwargs):
            sys.stdout = cStringIO.StringIO()
            self.m.show(*args, **kwargs)
            rv = sys.stdout.getvalue()
            sys.stdout = sys.__stdout__
            return rv

        self.assertEqual('', capture_show())
        self.m._newParameter('x', 1)
        self.m._newParameter('y', 2)
        out1 = capture_show()
        lines1 = out1.strip().split('\n')
        self.assertEqual(4, len(lines1))
        self.assertTrue('Parameters' in lines1)
        self.assertFalse('Constraints' in lines1)
        self.assertFalse('Restraints' in lines1)
        self.m._newParameter('z', 7)
        self.m.constrain('y', '3 * z')
        out2 = capture_show()
        lines2 = out2.strip().split('\n')
        self.assertEqual(9, len(lines2))
        self.assertTrue('Parameters' in lines2)
        self.assertTrue('Constraints' in lines2)
        self.assertFalse('Restraints' in lines2)
        self.m.restrain('z', lb=2, ub=3, sig=0.001)
        out3 = capture_show()
        lines3 = out3.strip().split('\n')
        self.assertEqual(13, len(lines3))
        self.assertTrue('Parameters' in lines3)
        self.assertTrue('Constraints' in lines3)
        self.assertTrue('Restraints' in lines3)
        out4 = capture_show(pattern='x')
        lines4 = out4.strip().split('\n')
        self.assertEqual(9, len(lines4))
        out5 = capture_show(pattern='^')
        self.assertEqual(out3, out5)
        # check output with another level of hierarchy
        self.m._addObject(RecipeOrganizer("foo"), self.m._containers)
        self.m.foo._newParameter("bar", 13)
        out6 = capture_show()
        self.assertTrue("foo.bar" in out6)
        # filter out foo.bar
        out7 = capture_show('^(?!foo).')
        self.assertFalse("foo.bar" in out7)
        self.assertEqual(out3, out7)
        return