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
Beispiel #2
0
    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
Beispiel #3
0
    def testEquationFromString(self):
        """Test the equationFromString method."""

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

        factory = EquationFactory()

        factory.registerArgument("p1", p1)
        factory.registerArgument("p2", p2)

        # Check usage where all parameters are registered with the factory
        eq = equationFromString("p1+p2", factory)

        self.assertEqual(2, len(eq.args))
        self.assertTrue(p1 in eq.args)
        self.assertTrue(p2 in eq.args)
        self.assertEqual(3, eq())

        # Try to use a parameter that is not registered
        self.assertRaises(ValueError, equationFromString, "p1+p2+p3", factory)

        # Pass that argument in the ns dictionary
        eq = equationFromString("p1+p2+p3", factory, {"p3": p3})
        self.assertEqual(3, len(eq.args))
        self.assertTrue(p1 in eq.args)
        self.assertTrue(p2 in eq.args)
        self.assertTrue(p3 in eq.args)
        self.assertEqual(6, eq())

        # Make sure that there are no remnants of p3 in the factory
        self.assertTrue("p3" not in factory.builders)

        # Pass and use an unregistered parameter
        self.assertRaises(ValueError, equationFromString, "p1+p2+p3+p4",
                          factory, {"p3": p3})

        # Try to overload a registered parameter
        self.assertRaises(ValueError, equationFromString, "p1+p2", factory,
                          {"p2": p4})

        return
    def testEquationFromString(self):
        """Test the equationFromString method."""

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

        factory = EquationFactory()

        factory.registerArgument("p1", p1)
        factory.registerArgument("p2", p2)

        # Check usage where all parameters are registered with the factory
        eq = equationFromString("p1+p2", factory)

        self.assertEqual(2, len(eq.args))
        self.assertTrue(p1 in eq.args)
        self.assertTrue(p2 in eq.args)
        self.assertEqual(3, eq())

        # Try to use a parameter that is not registered
        self.assertRaises(ValueError, equationFromString, "p1+p2+p3", factory)

        # Pass that argument in the ns dictionary
        eq = equationFromString("p1+p2+p3", factory, {"p3":p3})
        self.assertEqual(3, len(eq.args))
        self.assertTrue(p1 in eq.args)
        self.assertTrue(p2 in eq.args)
        self.assertTrue(p3 in eq.args)
        self.assertEqual(6, eq())

        # Make sure that there are no remnants of p3 in the factory
        self.assertTrue("p3" not in factory.builders)

        # Pass and use an unregistered parameter
        self.assertRaises(ValueError, equationFromString, "p1+p2+p3+p4",
                factory, {"p3":p3})

        # Try to overload a registered parameter
        self.assertRaises(ValueError, equationFromString, "p1+p2",
                factory, {"p2":p3})

        return
    def testRestraint(self):
        """Test the Restraint class."""

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

        factory = EquationFactory()

        factory.registerArgument("p1", p1)
        factory.registerArgument("p2", p2)

        # Restrain 1 <  p1 + p2 < 5
        eq = equationFromString("p1 + p2", factory)
        r = Restraint(eq, 1, 5)

        # This should have no penalty
        p1.setValue(1)
        p2.setValue(1)
        self.assertEqual(0, r.penalty())

        # Make p1 + p2 = 0
        # This should have a penalty of 1*(1 - 0)**2 = 1
        p1.setValue(-1)
        p2.setValue(1)
        self.assertEqual(1, r.penalty())

        # Make p1 + p2 = 8
        # This should have a penalty of 1*(8 - 5)**2 = 9
        p1.setValue(4)
        p2.setValue(4)
        self.assertEqual(9, r.penalty())

        # Set the chi^2 to get a dynamic penalty
        r.scaled = True
        self.assertEqual(13.5, r.penalty(1.5))

        # Make a really large number to check the upper bound
        import numpy
        r.ub = numpy.inf
        p1.setValue(1e100)
        self.assertEqual(0, r.penalty())

        return
Beispiel #6
0
    def testRestraint(self):
        """Test the Restraint class."""

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

        factory = EquationFactory()

        factory.registerArgument("p1", p1)
        factory.registerArgument("p2", p2)

        # Restrain 1 <  p1 + p2 < 5
        eq = equationFromString("p1 + p2", factory)
        r = Restraint(eq, 1, 5)

        # This should have no penalty
        p1.setValue(1)
        p2.setValue(1)
        self.assertEquals(0, r.penalty())

        # Make p1 + p2 = 0
        # This should have a penalty of 1*(1 - 0)**2 = 1
        p1.setValue(-1)
        p2.setValue(1)
        self.assertEquals(1, r.penalty())

        # Make p1 + p2 = 8
        # This should have a penalty of 1*(8 - 5)**2 = 9
        p1.setValue(4)
        p2.setValue(4)
        self.assertEquals(9, r.penalty())

        # Set the chi^2 to get a dynamic penalty
        r.scaled = True
        self.assertEquals(13.5, r.penalty(1.5))

        # Make a really large number to check the upper bound
        import numpy
        r.ub = numpy.inf
        p1.setValue(1e100)
        self.assertEquals(0, r.penalty())

        return
Beispiel #7
0
    def setResidualEquation(self, eqstr):
        """Set the residual equation for the FitContribution.

        eqstr   --  A string representation of the residual. If eqstr is None
                    (default), then the previous residual equation will be
                    used, or the chi2 residual will be used if that does not
                    exist.

        Two residuals are preset for convenience, "chiv" and "resv".
        chiv is defined such that dot(chiv, chiv) = chi^2.
        resv is defined such that dot(resv, resv) = Rw^2.
        You can call on these in your residual equation. Note that the quantity
        that will be optimized is the summed square of the residual equation.
        Keep that in mind when defining a new residual or using the built-in
        ones.

        Raises SrFitError if the Profile is not yet defined.
        Raises ValueError if eqstr depends on a Parameter that is not part of
        the FitContribution.

        """
        if self.profile is None:
            raise SrFitError("Assign the Profile first")
        if self._eq is None:
            raise SrFitError("Assign the Equation first")

        chivstr = "(eq - %s)/%s" % (self._yname, self._dyname)
        resvstr = "(eq - %s)/sum(%s**2)**0.5" % (self._yname, self._yname)

        # Get the equation string if it is not defined
        if eqstr == "chiv":
            eqstr = chivstr
        elif eqstr == "resv":
            eqstr = resvstr

        reseq = equationFromString(eqstr, self._eqfactory)
        self._eqfactory.wipeout(self._reseq)
        self._reseq = reseq

        return
Beispiel #8
0
    def setEquation(self, eqstr, ns = {}):
        """Set the profile equation for the FitContribution.

        This sets the equation that will be used when generating the residual
        for this FitContribution.  The equation will be usable within
        setResidualEquation as "eq", and it takes no arguments.

        eqstr   --  A string representation of the equation. Any Parameter
                    registered by addParameter or setProfile, or function
                    registered by setCalculator, registerFunction or
                    registerStringFunction can be can be used in the equation
                    by name. Other names will be turned into Parameters of this
                    FitContribution.
        ns      --  A dictionary of Parameters, indexed by name, that are used
                    in the eqstr, but not registered (default {}).

        Raises ValueError if ns uses a name that is already used for a
        variable.

        """
        # Build the equation instance.
        eq = equationFromString(eqstr, self._eqfactory,
                                buildargs=True, ns=ns)
        eq.name = "eq"

        # Register any new Parameters.
        for par in self._eqfactory.newargs:
            self._addParameter(par)

        # Register eq as an operator
        self._eqfactory.registerOperator("eq", eq)
        self._eqfactory.wipeout(self._eq)
        self._eq = eq

        # Set the residual if we need to
        if self.profile is not None and self._reseq is None:
            self.setResidualEquation('chiv')

        return
    def setResidualEquation(self, eqstr = None):
        """Set the residual equation for the FitContribution.

        eqstr   --  A string representation of the residual. If eqstr is None
                    (default), then the previous residual equation will be
                    used, or the chi2 residual will be used if that does not
                    exist.

        Two residuals are preset for convenience, "chiv" and "resv".
        chiv is defined such that dot(chiv, chiv) = chi^2.
        resv is defined such that dot(resv, resv) = Rw^2.
        You can call on these in your residual equation. Note that the quantity
        that will be optimized is the summed square of the residual equation.
        Keep that in mind when defining a new residual or using the built-in
        ones.

        Raises AttributeError if the Profile is not yet defined.
        Raises ValueError if eqstr depends on a Parameter that is not part of
        the FitContribution.

        """
        if self.profile is None:
            raise AttributeError("Assign the Profile first")
        if self._eq is None:
            raise AttributeError("Assign the Equation first")

        chivstr = "(eq - %s)/%s" % (self._yname, self._dyname)
        resvstr = "(eq - %s)/sum(%s**2)**0.5" % (self._yname, self._yname)

        # Get the equation string if it is not defined
        if eqstr == "chiv" or eqstr is None:
            eqstr = chivstr
        elif eqstr == "resv":
            eqstr = resvstr

        self._reseq = equationFromString(eqstr, self._eqfactory)

        return
    def setEquation(self, eqstr, ns = {}):
        """Set the profile equation for the FitContribution.

        This sets the equation that will be used when generating the residual
        for this FitContribution.  The equation will be usable within
        setResidualEquation as "eq", and it takes no arguments.

        eqstr   --  A string representation of the equation. Any Parameter
                    registered by addParameter or setProfile, or function
                    registered by setCalculator, registerFunction or
                    registerStringFunction can be can be used in the equation
                    by name. Other names will be turned into Parameters of this
                    FitContribution.
        ns      --  A dictionary of Parameters, indexed by name, that are used
                    in the eqstr, but not registered (default {}).

        Raises ValueError if ns uses a name that is already used for a
        variable.

        """
        # Build the equation instance.
        eq = equationFromString(eqstr, self._eqfactory, buildargs = True, ns =
                ns)
        eq.name = "eq"

        # Register any new Parameters.
        for par in self._eqfactory.newargs:
            self._addParameter(par)

        # Register eq as an operator
        self._eqfactory.registerOperator("eq", eq)
        self._eq = eq

        # Set the residual if we need to
        if self.profile is not None and self._reseq is None:
            self.setResidualEquation()

        return