Пример #1
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
Пример #2
0
def speedTest4(mutate=2):
    """Test wrt sympy.

    Results - sympy is 10 to 24 times faster without using arrays (ouch!).
            - diffpy.srfit.equation is slightly slower when using arrays, but
              not considerably worse than versus numpy alone.

    """

    from diffpy.srfit.equation.builder import EquationFactory
    factory = EquationFactory()

    x = numpy.arange(0, 20, 0.05)

    eqstr = """\
    b1 + b2*x + b3*x**2 + b4*x**3 + b5*x**4 + b6*x**5 + b7*x**6 + b8*x**7\
    """
    factory.registerConstant("x", x)
    eq = factory.makeEquation(eqstr)

    from sympy import var, lambdify
    from numpy import polyval
    b1, b2, b3, b4, b5, b6, b7, b8, xx = vars = var(
        "b1 b2 b3 b4 b5 b6 b7 b8 xx")
    f = lambdify(vars, polyval([b1, b2, b3, b4, b5, b6, b7, b8], xx), "numpy")

    tnpy = 0
    teq = 0
    # Randomly change variables
    numargs = len(eq.args)
    choices = range(numargs)
    args = [1.0] * (len(eq.args))
    args.append(x)

    # The call-loop
    random.seed()
    numcalls = 1000
    for _i in xrange(numcalls):
        # Mutate values
        n = mutate
        if n == 0:
            n = random.choice(choices)
        c = choices[:]
        for _j in xrange(n):
            idx = random.choice(c)
            c.remove(idx)
            args[idx] = random.random()

        # Time the different functions with these arguments
        teq += timeFunction(eq, *(args[:-1]))
        tnpy += timeFunction(f, *args)

    print("Average call time (%i calls, %i mutations/call):" %
          (numcalls, mutate))
    print("sympy: ", tnpy / numcalls)
    print("equation: ", teq / numcalls)
    print("ratio: ", teq / tnpy)

    return
Пример #3
0
    def __init__(self, name):
        RecipeContainer.__init__(self, name)
        self._restraints = set()
        self._constraints = {}
        self._eqfactory = EquationFactory()

        self._calculators = {}
        self._manage(self._calculators)
        return
Пример #4
0
def profileTest():

    from diffpy.srfit.builder import EquationFactory
    factory = EquationFactory()

    x = numpy.arange(0, 10, 0.001)
    qsig = 0.01
    sigma = 0.003

    eqstr = """\
    b1 + b2*x + b3*x**2 + b4*x**3 + b5*x**4 + b6*x**5 + b7*x**6 + b8*x**7\
    """
    factory.registerConstant("x", x)
    eq = factory.makeEquation(eqstr)

    eq.b1.setValue(0)
    eq.b2.setValue(1)
    eq.b3.setValue(2.0)
    eq.b4.setValue(2.0)
    eq.b5.setValue(2.0)
    eq.b6.setValue(2.0)
    eq.b7.setValue(2.0)
    eq.b8.setValue(2.0)

    mutate = 8
    numargs = len(eq.args)
    choices = range(numargs)
    args = [0.1] * numargs

    # The call-loop
    random.seed()
    numcalls = 1000
    for _i in xrange(numcalls):
        # Mutate values
        n = mutate
        if n == 0:
            n = random.choice(choices)
        c = choices[:]
        for _j in xrange(n):
            idx = random.choice(c)
            c.remove(idx)
            args[idx] = random.random()

        eq(*args)

    return
Пример #5
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
Пример #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.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
Пример #7
0
def weightedTest(mutate=2):
    """Show the benefits of a properly balanced equation tree."""

    from diffpy.srfit.equation.builder import EquationFactory
    factory = EquationFactory()

    x = numpy.arange(0, 10, 0.01)
    qsig = 0.01
    sigma = 0.003

    eqstr = """\
    b1 + b2*x + b3*x**2 + b4*x**3 + b5*x**4 + b6*x**5 + b7*x**6 + b8*x**7\
    """
    factory.registerConstant("x", x)
    eq = factory.makeEquation(eqstr)

    eq.b1.setValue(0)
    eq.b2.setValue(1)
    eq.b3.setValue(2.0)
    eq.b4.setValue(2.0)
    eq.b5.setValue(2.0)
    eq.b6.setValue(2.0)
    eq.b7.setValue(2.0)
    eq.b8.setValue(2.0)

    #scale = visitors.NodeWeigher()
    #eq.root.identify(scale)
    #print scale.output

    from numpy import polyval

    def f(b1, b2, b3, b4, b5, b6, b7, b8):
        return polyval([b8, b7, b6, b5, b4, b3, b2, b1], x)

    tnpy = 0
    teq = 0
    # Randomly change variables
    numargs = len(eq.args)
    choices = range(numargs)
    args = [0.1] * numargs

    # The call-loop
    random.seed()
    numcalls = 1000
    for _i in xrange(numcalls):
        # Mutate values
        n = mutate
        if n == 0:
            n = random.choice(choices)
        c = choices[:]
        for _j in xrange(n):
            idx = random.choice(c)
            c.remove(idx)
            args[idx] = random.random()

        #print args

        # Time the different functions with these arguments
        teq += timeFunction(eq, *args)
        tnpy += timeFunction(f, *args)

    print "Average call time (%i calls, %i mutations/call):" % (numcalls,
                                                                mutate)
    print "numpy: ", tnpy / numcalls
    print "equation: ", teq / numcalls
    print "ratio: ", teq / tnpy

    return
Пример #8
0
def speedTest3(mutate=2):
    """Test wrt sympy.

    Results - sympy is 10 to 24 times faster without using arrays (ouch!).
            - diffpy.srfit.equation is slightly slower when using arrays, but
              not considerably worse than versus numpy alone.

    """

    from diffpy.srfit.equation.builder import EquationFactory
    factory = EquationFactory()

    x = numpy.arange(0, 20, 0.05)
    qsig = 0.01
    sigma = 0.003

    eqstr = """\
    A0*exp(-(x*qsig)**2)*(exp(-((x-1.0)/sigma1)**2)+exp(-((x-2.0)/sigma2)**2))\
    + polyval(list(b1, b2, b3, b4, b5, b6, b7, b8), x)\
    """
    factory.registerConstant("x", x)
    eq = factory.makeEquation(eqstr)
    eq.qsig.setValue(qsig)
    eq.sigma1.setValue(sigma)
    eq.sigma2.setValue(sigma)
    eq.A0.setValue(1.0)
    eq.b1.setValue(0)
    eq.b2.setValue(1)
    eq.b3.setValue(2.0)
    eq.b4.setValue(2.0)
    eq.b5.setValue(2.0)
    eq.b6.setValue(2.0)
    eq.b7.setValue(2.0)
    eq.b8.setValue(2.0)

    from sympy import var, exp, lambdify
    from numpy import polyval
    A0, qsig, sigma1, sigma2, b1, b2, b3, b4, b5, b6, b7, b8, xx = vars = var(
        "A0 qsig sigma1 sigma2 b1 b2 b3 b4 b5 b6 b7 b8 xx")
    f = lambdify(
        vars,
        A0 * exp(-(xx * qsig)**2) *
        (exp(-((xx - 1.0) / sigma1)**2) + exp(-((xx - 2.0) / sigma2)**2)) +
        polyval([b1, b2, b3, b4, b5, b6, b7, b8], xx), "numpy")

    tnpy = 0
    teq = 0
    # Randomly change variables
    numargs = len(eq.args)
    choices = range(numargs)
    args = [1.0] * (len(eq.args))
    args.append(x)

    # The call-loop
    random.seed()
    numcalls = 1000
    for _i in xrange(numcalls):
        # Mutate values
        n = mutate
        if n == 0:
            n = random.choice(choices)
        c = choices[:]
        for _j in xrange(n):
            idx = random.choice(c)
            c.remove(idx)
            args[idx] = random.random()

        # Time the different functions with these arguments
        teq += timeFunction(eq, *(args[:-1]))
        tnpy += timeFunction(f, *args)

    print "Average call time (%i calls, %i mutations/call):" % (numcalls,
                                                                mutate)
    print "sympy: ", tnpy / numcalls
    print "equation: ", teq / numcalls
    print "ratio: ", teq / tnpy

    return
Пример #9
0
def speedTest2(mutate=2):

    from diffpy.srfit.equation.builder import EquationFactory
    factory = EquationFactory()

    x = numpy.arange(0, 20, 0.05)
    qsig = 0.01
    sigma = 0.003

    eqstr = """\
    A0*exp(-(x*qsig)**2)*(exp(-((x-1.0)/sigma1)**2)+exp(-((x-2.0)/sigma2)**2))\
    + polyval(list(b1, b2, b3, b4, b5, b6, b7, b8), x)\
    """
    factory.registerConstant("x", x)
    eq = factory.makeEquation(eqstr)
    eq.qsig.setValue(qsig)
    eq.sigma1.setValue(sigma)
    eq.sigma2.setValue(sigma)
    eq.A0.setValue(1.0)
    eq.b1.setValue(0)
    eq.b2.setValue(1)
    eq.b3.setValue(2.0)
    eq.b4.setValue(2.0)
    eq.b5.setValue(2.0)
    eq.b6.setValue(2.0)
    eq.b7.setValue(2.0)
    eq.b8.setValue(2.0)

    from numpy import exp
    from numpy import polyval

    def f(A0, qsig, sigma1, sigma2, b1, b2, b3, b4, b5, b6, b7, b8):
        return A0 * exp(-(x * qsig)**2) * (exp(-(
            (x - 1.0) / sigma1)**2) + exp(-((x - 2.0) / sigma2)**2)) + polyval(
                [b8, b7, b6, b5, b4, b3, b2, b1], x)

    tnpy = 0
    teq = 0
    # Randomly change variables
    numargs = len(eq.args)
    choices = range(numargs)
    args = [0.0] * (len(eq.args))

    # The call-loop
    random.seed()
    numcalls = 1000
    for _i in xrange(numcalls):
        # Mutate values
        n = mutate
        if n == 0:
            n = random.choice(choices)
        c = choices[:]
        for _j in xrange(n):
            idx = random.choice(c)
            c.remove(idx)
            args[idx] = random.random()

        # Time the different functions with these arguments
        tnpy += timeFunction(f, *args)
        teq += timeFunction(eq, *args)

    print "Average call time (%i calls, %i mutations/call):" % (numcalls,
                                                                mutate)
    print "numpy: ", tnpy / numcalls
    print "equation: ", teq / numcalls
    print "ratio: ", teq / tnpy

    return