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 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
def __init__(self, name): RecipeContainer.__init__(self, name) self._restraints = set() self._constraints = {} self._eqfactory = EquationFactory() self._calculators = {} self._manage(self._calculators) return
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
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 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
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
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
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