def testRegisterOperator(self): """Try to use an operator without arguments in an equation.""" factory = builder.EquationFactory() v1, v2, v3, v4 = _makeArgs(4) op = literals.AdditionOperator() op.addLiteral(v1) op.addLiteral(v2) factory.registerArgument("v3", v3) factory.registerArgument("v4", v4) factory.registerOperator("op", op) # Build an equation where op is treated as a terminal node eq = factory.makeEquation("op") self.assertAlmostEqual(3, eq()) eq = factory.makeEquation("v3*op") self.assertAlmostEqual(9, eq()) # Now use the op like a function eq = factory.makeEquation("op(v3, v4)") self.assertAlmostEqual(7, eq()) # Make sure we can still access op as itself. eq = factory.makeEquation("op") self.assertAlmostEqual(3, eq()) self.assertTrue(noObserversInGlobalBuilders()) return
def testRegisterOperator(self): """Try to use an operator without arguments in an equation.""" factory = builder.EquationFactory() v1, v2, v3, v4 = _makeArgs(4) op = literals.AdditionOperator() op.addLiteral(v1) op.addLiteral(v2) factory.registerArgument("v3", v3) factory.registerArgument("v4", v4) factory.registerOperator("op", op) # Build an equation where op is treated as a terminal node eq = factory.makeEquation("op") self.assertAlmostEqual(3, eq()) eq = factory.makeEquation("v3*op") self.assertAlmostEqual(9, eq()) # Now use the op like a function eq = factory.makeEquation("op(v3, v4)") self.assertAlmostEqual(7, eq()) # Make sure we can still access op as itself. eq = factory.makeEquation("op") self.assertAlmostEqual(3, eq()) self.assertTrue(noObserversInGlobalBuilders()) return
def testSwapping(self): def g1(v1, v2, v3, v4): return (v1 + v2) * (v3 + v4) def g2(v1): return 0.5 * v1 factory = builder.EquationFactory() v1, v2, v3, v4, v5 = _makeArgs(5) factory.registerArgument("v1", v1) factory.registerArgument("v2", v2) factory.registerArgument("v3", v3) factory.registerArgument("v4", v4) b = factory.registerFunction("g", g1, ["v1", "v2", "v3", "v4"]) # Now associate args with the wrapped function op = b.literal self.assertTrue(op.operation == g1) self.assertTrue(v1 in op.args) self.assertTrue(v2 in op.args) self.assertTrue(v3 in op.args) self.assertTrue(v4 in op.args) self.assertAlmostEqual(21, op.value) eq1 = factory.makeEquation("g") self.assertTrue(eq1.root is op) self.assertAlmostEqual(21, eq1()) # Swap out an argument by registering it under a taken name b = factory.registerArgument("v4", v5) self.assertTrue(factory.builders["v4"] is b) self.assertTrue(b.literal is v5) self.assertTrue(op._value is None) self.assertTrue(op.args == [v1, v2, v3, v5]) self.assertAlmostEqual(24, eq1()) # Now swap out the function b = factory.registerFunction("g", g2, ["v1"]) op = b.literal self.assertTrue(op.operation == g2) self.assertTrue(v1 in op.args) self.assertTrue(eq1.root is op) self.assertAlmostEqual(0.5, op.value) self.assertAlmostEqual(0.5, eq1()) # Make an equation eqeq = factory.makeEquation("v1 + v2") # Register this "g" b = factory.registerFunction("g", eqeq, eqeq.argdict.keys()) op = b.literal self.assertTrue(v1 in op.args) self.assertTrue(v2 in op.args) self.assertTrue(eq1.root is op) self.assertAlmostEqual(3, op.value) self.assertAlmostEqual(3, eq1()) self.assertTrue(noObserversInGlobalBuilders()) return
def testSwapping(self): def g1(v1, v2, v3, v4): return (v1 + v2) * (v3 + v4) def g2(v1): return 0.5*v1 factory = builder.EquationFactory() v1, v2, v3, v4, v5 = _makeArgs(5) factory.registerArgument("v1", v1) factory.registerArgument("v2", v2) factory.registerArgument("v3", v3) factory.registerArgument("v4", v4) b = factory.registerFunction("g", g1, ["v1", "v2", "v3", "v4"]) # Now associate args with the wrapped function op = b.literal self.assertTrue(op.operation == g1) self.assertTrue(v1 in op.args) self.assertTrue(v2 in op.args) self.assertTrue(v3 in op.args) self.assertTrue(v4 in op.args) self.assertAlmostEqual(21, op.value) eq1 = factory.makeEquation("g") self.assertTrue(eq1.root is op) self.assertAlmostEqual(21, eq1()) # Swap out an argument by registering it under a taken name b = factory.registerArgument("v4", v5) self.assertTrue(factory.builders["v4"] is b) self.assertTrue(b.literal is v5) self.assertTrue(op._value is None) self.assertTrue(op.args == [v1, v2, v3, v5]) self.assertAlmostEqual(24, eq1()) # Now swap out the function b = factory.registerFunction("g", g2, ["v1"]) op = b.literal self.assertTrue(op.operation == g2) self.assertTrue(v1 in op.args) self.assertTrue(eq1.root is op) self.assertAlmostEqual(0.5, op.value) self.assertAlmostEqual(0.5, eq1()) # Make an equation eqeq = factory.makeEquation("v1 + v2") # Register this "g" b = factory.registerFunction("g", eqeq, eqeq.argdict.keys()) op = b.literal self.assertTrue(v1 in op.args) self.assertTrue(v2 in op.args) self.assertTrue(eq1.root is op) self.assertAlmostEqual(3, op.value) self.assertAlmostEqual(3, eq1()) self.assertTrue(noObserversInGlobalBuilders()) return
def test_getEquation(self): """Check getting the current profile simulation formula.""" fc = self.fitcontribution self.assertEqual('', fc.getEquation()) fc.setEquation("A * sin(x + 5)") self.assertEqual('(A * sin((x + 5)))', fc.getEquation()) self.assertTrue(noObserversInGlobalBuilders()) return
def test_getEquation(self): """Check getting the current profile simulation formula.""" fc = self.fitcontribution self.assertEqual('', fc.getEquation()) fc.setEquation("A * sin(x + 5)") self.assertEqual('(A * sin((x + 5)))', fc.getEquation()) self.assertTrue(noObserversInGlobalBuilders()) return
def testParseEquation(self): from numpy import sin, divide, sqrt, array_equal, e factory = builder.EquationFactory() # Scalar equation eq = factory.makeEquation("A*sin(0.5*x)+divide(B,C)") A = 1 x = numpy.pi B = 4.0 C = 2.0 eq.A.setValue(A) eq.x.setValue(x) eq.B.setValue(B) eq.C.setValue(C) f = lambda A, x, B, C: A*sin(0.5*x)+divide(B,C) self.assertTrue(array_equal(eq(), f(A,x,B,C))) # Make sure that the arguments of eq are listed in the order in which # they appear in the equations. self.assertEqual(eq.args, [eq.A, eq.x, eq.B, eq.C]) # Vector equation eq = factory.makeEquation("sqrt(e**(-0.5*(x/sigma)**2))") x = numpy.arange(0, 1, 0.05) sigma = 0.1 eq.x.setValue(x) eq.sigma.setValue(sigma) f = lambda x, sigma : sqrt(e**(-0.5*(x/sigma)**2)) self.assertTrue(numpy.allclose(eq(), f(x,sigma))) self.assertEqual(eq.args, [eq.x, eq.sigma]) # Equation with constants factory.registerConstant("x", x) eq = factory.makeEquation("sqrt(e**(-0.5*(x/sigma)**2))") self.assertTrue("sigma" in eq.argdict) self.assertTrue("x" not in eq.argdict) self.assertTrue(numpy.allclose(eq(sigma=sigma), f(x,sigma))) self.assertEqual(eq.args, [eq.sigma]) # Equation with user-defined functions factory.registerFunction("myfunc", eq, ["sigma"]) eq2 = factory.makeEquation("c*myfunc(sigma)") self.assertTrue(numpy.allclose(eq2(c=2, sigma=sigma), 2*f(x,sigma))) self.assertTrue("sigma" in eq2.argdict) self.assertTrue("c" in eq2.argdict) self.assertEqual(eq2.args, [eq2.c, eq2.sigma]) self.assertTrue(noObserversInGlobalBuilders()) return
def test_setEquation(self): """Check replacement of removed parameters.""" fc = self.fitcontribution fc.setEquation("x + 5") fc.x.setValue(2) self.assertEqual(7, fc.evaluate()) fc.removeParameter(fc.x) x = arange(0, 10, 0.5) fc.newParameter('x', x) self.assertTrue(array_equal(5 + x, fc.evaluate())) self.assertTrue(noObserversInGlobalBuilders()) return
def testParseEquation(self): from numpy import sin, divide, sqrt, array_equal, e factory = builder.EquationFactory() # Scalar equation eq = factory.makeEquation("A*sin(0.5*x)+divide(B,C)") A = 1 x = numpy.pi B = 4.0 C = 2.0 eq.A.setValue(A) eq.x.setValue(x) eq.B.setValue(B) eq.C.setValue(C) f = lambda A, x, B, C: A * sin(0.5 * x) + divide(B, C) self.assertTrue(array_equal(eq(), f(A, x, B, C))) # Make sure that the arguments of eq are listed in the order in which # they appear in the equations. self.assertEqual(eq.args, [eq.A, eq.x, eq.B, eq.C]) # Vector equation eq = factory.makeEquation("sqrt(e**(-0.5*(x/sigma)**2))") x = numpy.arange(0, 1, 0.05) sigma = 0.1 eq.x.setValue(x) eq.sigma.setValue(sigma) f = lambda x, sigma: sqrt(e**(-0.5 * (x / sigma)**2)) self.assertTrue(numpy.allclose(eq(), f(x, sigma))) self.assertEqual(eq.args, [eq.x, eq.sigma]) # Equation with constants factory.registerConstant("x", x) eq = factory.makeEquation("sqrt(e**(-0.5*(x/sigma)**2))") self.assertTrue("sigma" in eq.argdict) self.assertTrue("x" not in eq.argdict) self.assertTrue(numpy.allclose(eq(sigma=sigma), f(x, sigma))) self.assertEqual(eq.args, [eq.sigma]) # Equation with user-defined functions factory.registerFunction("myfunc", eq, ["sigma"]) eq2 = factory.makeEquation("c*myfunc(sigma)") self.assertTrue(numpy.allclose(eq2(c=2, sigma=sigma), 2 * f(x, sigma))) self.assertTrue("sigma" in eq2.argdict) self.assertTrue("c" in eq2.argdict) self.assertEqual(eq2.args, [eq2.c, eq2.sigma]) self.assertTrue(noObserversInGlobalBuilders()) return
def test_setEquation(self): """Check replacement of removed parameters.""" fc = self.fitcontribution fc.setEquation("x + 5") fc.x.setValue(2) self.assertEqual(7, fc.evaluate()) fc.removeParameter(fc.x) x = arange(0, 10, 0.5) fc.newParameter('x', x) self.assertTrue(array_equal(5 + x, fc.evaluate())) self.assertTrue(noObserversInGlobalBuilders()) return
def testRegisterArg(self): factory = builder.EquationFactory() v1 = _makeArgs(1)[0] b1 = factory.registerArgument("v1", v1) self.assertTrue(factory.builders["v1"] is b1) self.assertTrue(b1.literal is v1) eq = factory.makeEquation("v1") self.assertTrue(v1 is eq.args[0]) self.assertEqual(1, len(eq.args)) # Try to parse an equation with buildargs turned off self.assertRaises(ValueError, factory.makeEquation, "v1 + v2", False) # Make sure we can still use constants eq = factory.makeEquation("v1 + 2", False) self.assertTrue(v1 is eq.args[0]) self.assertEqual(1, len(eq.args)) self.assertTrue(noObserversInGlobalBuilders()) return
def testRegisterArg(self): factory = builder.EquationFactory() v1 = _makeArgs(1)[0] b1 = factory.registerArgument("v1", v1) self.assertTrue(factory.builders["v1"] is b1) self.assertTrue(b1.literal is v1) eq = factory.makeEquation("v1") self.assertTrue(v1 is eq.args[0]) self.assertEqual(1, len(eq.args)) # Try to parse an equation with buildargs turned off self.assertRaises(ValueError, factory.makeEquation, "v1 + v2", False) # Make sure we can still use constants eq = factory.makeEquation("v1 + 2", False) self.assertTrue(v1 is eq.args[0]) self.assertEqual(1, len(eq.args)) self.assertTrue(noObserversInGlobalBuilders()) return
def testBuildEquation(self): from numpy import array_equal # simple equation sin = builder.getBuilder("sin") a = builder.ArgumentBuilder(name="a", value = 1) A = builder.ArgumentBuilder(name="A", value = 2) x = numpy.arange(0, numpy.pi, 0.1) beq = A*sin(a*x) eq = beq.getEquation() self.assertTrue("a" in eq.argdict) self.assertTrue("A" in eq.argdict) self.assertTrue(array_equal(eq(), 2*numpy.sin(x))) self.assertEqual(eq.args, [eq.A, eq.a]) # Check the number of arguments self.assertRaises(ValueError, sin) # custom function def _f(a, b): return (a-b)*1.0/(a+b) f = builder.wrapFunction("f", _f, 2, 1) a = builder.ArgumentBuilder(name="a", value = 2) b = builder.ArgumentBuilder(name="b", value = 1) beq = sin(f(a,b)) eq = beq.getEquation() self.assertEqual(eq(), numpy.sin(_f(2, 1))) # complex function sqrt = builder.getBuilder("sqrt") e = numpy.e _x = numpy.arange(0, 1, 0.05) x = builder.ArgumentBuilder(name="x", value = _x, const = True) sigma = builder.ArgumentBuilder(name="sigma", value = 0.1) beq = sqrt(e**(-0.5*(x/sigma)**2)) eq = beq.getEquation() f = lambda x, sigma : sqrt(e**(-0.5*(x/sigma)**2)) self.assertTrue(numpy.allclose(eq(), numpy.sqrt(e**(-0.5*(_x/0.1)**2)))) # Equation with Equation A = builder.ArgumentBuilder(name="A", value = 2) B = builder.ArgumentBuilder(name="B", value = 4) beq = A + B eq = beq.getEquation() E = builder.wrapOperator("eq", eq) eq2 = (2*E).getEquation() # Make sure these evaulate to the same thing self.assertEqual(eq.args, [A.literal, B.literal]) self.assertEqual(2*eq(), eq2()) # Pass new arguments to the equation C = builder.ArgumentBuilder(name="C", value = 5) D = builder.ArgumentBuilder(name="D", value = 6) eq3 = (E(C, D)+1).getEquation() self.assertEqual(12, eq3()) # Pass old and new arguments to the equation # If things work right, A has been given the value of C in the last # evaluation (5) eq4 = (3*E(A, D)-1).getEquation() self.assertEqual(32, eq4()) # Try to pass the wrong number of arguments self.assertRaises(ValueError, E, A) self.assertRaises(ValueError, E, A, B, C) self.assertTrue(noObserversInGlobalBuilders()) return
def testResidual(self): """Test the residual, which requires all other methods.""" fc = self.fitcontribution profile = self.profile gen = self.gen # Add the calculator and profile fc.setProfile(profile) self.assertTrue(fc.profile is profile) fc.addProfileGenerator(gen, "I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) self.assertEqual(1, len(fc._generators)) self.assertTrue(gen.name in fc._generators) # Let's create some data xobs = arange(0, 10, 0.5) yobs = xobs profile.setObservedProfile(xobs, yobs) # Check our fitting equation. self.assertTrue(array_equal(fc._eq(), gen(xobs))) # Now calculate the residual chiv = fc.residual() self.assertAlmostEqual(0, dot(chiv, chiv)) # Now change the equation fc.setEquation("2*I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv)) # Try to add a parameter c = Parameter("c", 2) fc._addParameter(c) fc.setEquation("c*I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv)) # Try something more complex c.setValue(3) fc.setEquation("c**2*sin(I)") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) xobs = arange(0, 10, 0.5) yobs = 9 * sin(xobs) profile.setObservedProfile(xobs, yobs) self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(0, dot(chiv, chiv)) # Choose a new residual. fc.setEquation("2*I") fc.setResidualEquation("resv") chiv = fc.residual() self.assertAlmostEqual( sum((2 * xobs - yobs)**2) / sum(yobs**2), dot(chiv, chiv)) # Make a custom residual. fc.setResidualEquation("abs(eq-y)**0.5") chiv = fc.residual() self.assertAlmostEqual(sum(abs(2 * xobs - yobs)), dot(chiv, chiv)) # Test configuration checks fc1 = FitContribution('test1') self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv') fc1.setProfile(self.profile) self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv') fc1.setEquation('A * x') fc1.setResidualEquation('chiv') self.assertTrue(noObserversInGlobalBuilders()) return
def testSimpleFunction(self): """Test a simple function.""" # Make some variables v1, v2, v3, v4, c = _makeArgs(5) c.name = "c" c.const = True # Make some operations mult = literals.MultiplicationOperator() root = mult2 = literals.MultiplicationOperator() plus = literals.AdditionOperator() minus = literals.SubtractionOperator() # Create the equation c*(v1+v3)*(v4-v2) plus.addLiteral(v1) plus.addLiteral(v3) minus.addLiteral(v4) minus.addLiteral(v2) mult.addLiteral(plus) mult.addLiteral(minus) mult2.addLiteral(mult) mult2.addLiteral(c) # Set the values of the variables. # The equation should evaluate to 2.5*(1+3)*(4-2) = 20 v1.setValue(1) v2.setValue(2) v3.setValue(3) v4.setValue(4) c.setValue(2.5) # Make an equation and test eq = Equation("eq", mult2) self.assertTrue(eq._value is None) args = eq.args self.assertTrue(v1 in args) self.assertTrue(v2 in args) self.assertTrue(v3 in args) self.assertTrue(v4 in args) self.assertTrue(c not in args) self.assertTrue(root is eq.root) self.assertTrue(v1 is eq.v1) self.assertTrue(v2 is eq.v2) self.assertTrue(v3 is eq.v3) self.assertTrue(v4 is eq.v4) self.assertEqual(20, eq()) # 20 = 2.5*(1+3)*(4-2) self.assertEqual(20, eq.getValue()) # same as above self.assertEqual(20, eq.value) # same as above self.assertEqual(25, eq(v1=2)) # 25 = 2.5*(2+3)*(4-2) self.assertEqual(50, eq(v2=0)) # 50 = 2.5*(2+3)*(4-0) self.assertEqual(30, eq(v3=1)) # 30 = 2.5*(2+1)*(4-0) self.assertEqual(0, eq(v4=0)) # 20 = 2.5*(2+1)*(0-0) # Try some swapping eq.swap(v4, v1) self.assertTrue(eq._value is None) self.assertEqual(15, eq()) # 15 = 2.5*(2+1)*(2-0) args = eq.args self.assertTrue(v4 not in args) # Try to create a dependency loop self.assertRaises(ValueError, eq.swap, v1, eq.root) self.assertRaises(ValueError, eq.swap, v1, plus) self.assertRaises(ValueError, eq.swap, v1, minus) self.assertRaises(ValueError, eq.swap, v1, mult) self.assertRaises(ValueError, eq.swap, v1, root) # Swap the root eq.swap(eq.root, v1) self.assertTrue(eq._value is None) self.assertEqual(v1.value, eq()) self.assertTrue(noObserversInGlobalBuilders()) return
def testSimpleFunction(self): """Test a simple function.""" # Make some variables v1, v2, v3, v4, c = _makeArgs(5) c.name = "c" c.const = True # Make some operations mult = literals.MultiplicationOperator() root = mult2 = literals.MultiplicationOperator() plus = literals.AdditionOperator() minus = literals.SubtractionOperator() # Create the equation c*(v1+v3)*(v4-v2) plus.addLiteral(v1) plus.addLiteral(v3) minus.addLiteral(v4) minus.addLiteral(v2) mult.addLiteral(plus) mult.addLiteral(minus) mult2.addLiteral(mult) mult2.addLiteral(c) # Set the values of the variables. # The equation should evaluate to 2.5*(1+3)*(4-2) = 20 v1.setValue(1) v2.setValue(2) v3.setValue(3) v4.setValue(4) c.setValue(2.5) # Make an equation and test eq = Equation("eq", mult2) self.assertTrue(eq._value is None) args = eq.args self.assertTrue(v1 in args) self.assertTrue(v2 in args) self.assertTrue(v3 in args) self.assertTrue(v4 in args) self.assertTrue(c not in args) self.assertTrue(root is eq.root) self.assertTrue(v1 is eq.v1) self.assertTrue(v2 is eq.v2) self.assertTrue(v3 is eq.v3) self.assertTrue(v4 is eq.v4) self.assertEqual(20, eq()) # 20 = 2.5*(1+3)*(4-2) self.assertEqual(20, eq.getValue()) # same as above self.assertEqual(20, eq.value) # same as above self.assertEqual(25, eq(v1=2)) # 25 = 2.5*(2+3)*(4-2) self.assertEqual(50, eq(v2=0)) # 50 = 2.5*(2+3)*(4-0) self.assertEqual(30, eq(v3=1)) # 30 = 2.5*(2+1)*(4-0) self.assertEqual(0, eq(v4=0)) # 20 = 2.5*(2+1)*(0-0) # Try some swapping eq.swap(v4, v1) self.assertTrue(eq._value is None) self.assertEqual(15, eq()) # 15 = 2.5*(2+1)*(2-0) args = eq.args self.assertTrue(v4 not in args) # Try to create a dependency loop self.assertRaises(ValueError, eq.swap, v1, eq.root) self.assertRaises(ValueError, eq.swap, v1, plus) self.assertRaises(ValueError, eq.swap, v1, minus) self.assertRaises(ValueError, eq.swap, v1, mult) self.assertRaises(ValueError, eq.swap, v1, root) # Swap the root eq.swap(eq.root, v1) self.assertTrue(eq._value is None) self.assertEqual(v1.value, eq()) self.assertTrue(noObserversInGlobalBuilders()) return
def testBuildEquation(self): from numpy import array_equal # simple equation sin = builder.getBuilder("sin") a = builder.ArgumentBuilder(name="a", value=1) A = builder.ArgumentBuilder(name="A", value=2) x = numpy.arange(0, numpy.pi, 0.1) beq = A * sin(a * x) eq = beq.getEquation() self.assertTrue("a" in eq.argdict) self.assertTrue("A" in eq.argdict) self.assertTrue(array_equal(eq(), 2 * numpy.sin(x))) self.assertEqual(eq.args, [eq.A, eq.a]) # Check the number of arguments self.assertRaises(ValueError, sin) # custom function def _f(a, b): return (a - b) * 1.0 / (a + b) f = builder.wrapFunction("f", _f, 2, 1) a = builder.ArgumentBuilder(name="a", value=2) b = builder.ArgumentBuilder(name="b", value=1) beq = sin(f(a, b)) eq = beq.getEquation() self.assertEqual(eq(), numpy.sin(_f(2, 1))) # complex function sqrt = builder.getBuilder("sqrt") e = numpy.e _x = numpy.arange(0, 1, 0.05) x = builder.ArgumentBuilder(name="x", value=_x, const=True) sigma = builder.ArgumentBuilder(name="sigma", value=0.1) beq = sqrt(e**(-0.5 * (x / sigma)**2)) eq = beq.getEquation() f = lambda x, sigma: sqrt(e**(-0.5 * (x / sigma)**2)) self.assertTrue( numpy.allclose(eq(), numpy.sqrt(e**(-0.5 * (_x / 0.1)**2)))) # Equation with Equation A = builder.ArgumentBuilder(name="A", value=2) B = builder.ArgumentBuilder(name="B", value=4) beq = A + B eq = beq.getEquation() E = builder.wrapOperator("eq", eq) eq2 = (2 * E).getEquation() # Make sure these evaulate to the same thing self.assertEqual(eq.args, [A.literal, B.literal]) self.assertEqual(2 * eq(), eq2()) # Pass new arguments to the equation C = builder.ArgumentBuilder(name="C", value=5) D = builder.ArgumentBuilder(name="D", value=6) eq3 = (E(C, D) + 1).getEquation() self.assertEqual(12, eq3()) # Pass old and new arguments to the equation # If things work right, A has been given the value of C in the last # evaluation (5) eq4 = (3 * E(A, D) - 1).getEquation() self.assertEqual(32, eq4()) # Try to pass the wrong number of arguments self.assertRaises(ValueError, E, A) self.assertRaises(ValueError, E, A, B, C) self.assertTrue(noObserversInGlobalBuilders()) return
def testResidual(self): """Test the residual, which requires all other methods.""" fc = self.fitcontribution profile = self.profile gen = self.gen # Add the calculator and profile fc.setProfile(profile) self.assertTrue(fc.profile is profile) fc.addProfileGenerator(gen, "I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) self.assertEqual(1, len(fc._generators)) self.assertTrue(gen.name in fc._generators) # Let's create some data xobs = arange(0, 10, 0.5) yobs = xobs profile.setObservedProfile(xobs, yobs) # Check our fitting equation. self.assertTrue(array_equal(fc._eq(), gen(xobs))) # Now calculate the residual chiv = fc.residual() self.assertAlmostEqual(0, dot(chiv, chiv)) # Now change the equation fc.setEquation("2*I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv)) # Try to add a parameter c = Parameter("c", 2) fc._addParameter(c) fc.setEquation("c*I") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(dot(yobs, yobs), dot(chiv, chiv)) # Try something more complex c.setValue(3) fc.setEquation("c**2*sin(I)") self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) xobs = arange(0, 10, 0.5) yobs = 9*sin(xobs) profile.setObservedProfile(xobs, yobs) self.assertTrue(fc._eq._value is None) self.assertTrue(fc._reseq._value is None) chiv = fc.residual() self.assertAlmostEqual(0, dot(chiv, chiv)) # Choose a new residual. fc.setEquation("2*I") fc.setResidualEquation("resv") chiv = fc.residual() self.assertAlmostEqual(sum((2*xobs-yobs)**2)/sum(yobs**2), dot(chiv, chiv)) # Make a custom residual. fc.setResidualEquation("abs(eq-y)**0.5") chiv = fc.residual() self.assertAlmostEqual(sum(abs(2*xobs-yobs)), dot(chiv, chiv)) # Test configuration checks fc1 = FitContribution('test1') self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv') fc1.setProfile(self.profile) self.assertRaises(SrFitError, fc1.setResidualEquation, 'chiv') fc1.setEquation('A * x') fc1.setResidualEquation('chiv') self.assertTrue(noObserversInGlobalBuilders()) return