def testSimpleFunction(self): """Test a simple function.""" # Make some variables v1, v2, v3, v4 = _makeArgs(4) # Make some operations mult = literals.MultiplicationOperator() plus = literals.AdditionOperator() minus = literals.SubtractionOperator() # Create the equation (v1+v3)*(v4-v2) plus.addLiteral(v1) plus.addLiteral(v3) minus.addLiteral(v4) minus.addLiteral(v2) mult.addLiteral(plus) mult.addLiteral(minus) # Set the values of the variables. # The equation should evaluate to (1+3)*(4-2) = 8 v1.setValue(1) v2.setValue(2) v3.setValue(3) v4.setValue(4) # now get the args args = visitors.getArgs(mult) self.assertEqual(4, len(args)) self.assertTrue(v1 in args) self.assertTrue(v2 in args) self.assertTrue(v3 in args) self.assertTrue(v4 in args) 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 testArg(self): """Test just an Argument equation.""" # Make some variables v1 = _makeArgs(1)[0] args = visitors.getArgs(v1) self.assertEqual(1, len(args)) self.assertTrue(args[0] is v1) return
def makeLazyEquation(): """Make a lazy equation and see how fast it is.""" # Make some variables v1, v2, v3, v4, v5, v6, v7 = _makeArgs(7) # Make some operations mult = literals.MultiplicationOperator() plus = literals.AdditionOperator() minus = literals.SubtractionOperator() pow = literals.ExponentiationOperator() exp = literals.ExponentiationOperator() mult2 = literals.MultiplicationOperator() # Create the equation ((v1+v2)*(v3-v4))**v5 * v6^v7 plus.addLiteral(v1) plus.addLiteral(v2) minus.addLiteral(v3) minus.addLiteral(v4) mult.addLiteral(plus) mult.addLiteral(minus) pow.addLiteral(mult) pow.addLiteral(v5) exp.addLiteral(v6) exp.addLiteral(v7) mult2.addLiteral(pow) mult2.addLiteral(exp) v2.setValue(x) v3.setValue(50*x) v5.setValue(2.11) v6.setValue(numpy.e) evaluator = visitors.Evaluator() def _f(a, b, c, d, e): v1.setValue(a) v4.setValue(b) v5.setValue(c) v6.setValue(d) v7.setValue(e) mult2.identify(evaluator) evaluator.clicker.click() return evaluator.value return _f
def makeLazyEquation(): """Make a lazy equation and see how fast it is.""" # Make some variables v1, v2, v3, v4, v5, v6, v7 = _makeArgs(7) # Make some operations mult = literals.MultiplicationOperator() plus = literals.AdditionOperator() minus = literals.SubtractionOperator() pow = literals.ExponentiationOperator() exp = literals.ExponentiationOperator() mult2 = literals.MultiplicationOperator() # Create the equation ((v1+v2)*(v3-v4))**v5 * v6^v7 plus.addLiteral(v1) plus.addLiteral(v2) minus.addLiteral(v3) minus.addLiteral(v4) mult.addLiteral(plus) mult.addLiteral(minus) pow.addLiteral(mult) pow.addLiteral(v5) exp.addLiteral(v6) exp.addLiteral(v7) mult2.addLiteral(pow) mult2.addLiteral(exp) v2.setValue(x) v3.setValue(50 * x) v5.setValue(2.11) v6.setValue(numpy.e) evaluator = visitors.Evaluator() def _f(a, b, c, d, e): v1.setValue(a) v4.setValue(b) v5.setValue(c) v6.setValue(d) v7.setValue(e) mult2.identify(evaluator) evaluator.clicker.click() return evaluator.value return _f
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.assertEquals(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.assertEquals(1, len(eq.args)) return
def testSimpleFunction(self): """Test a simple function.""" # Make some variables v1, v2, v3, v4, v5 = _makeArgs(5) # Make some operations mult = literals.MultiplicationOperator() plus = literals.AdditionOperator() minus = literals.SubtractionOperator() # Create the equation (v1+v3)*(v4-v2) plus.addLiteral(v1) plus.addLiteral(v3) minus.addLiteral(v4) minus.addLiteral(v2) mult.addLiteral(plus) mult.addLiteral(minus) # Set the values of the variables. # The equation should evaluate to (1+3)*(4-2) = 8 v1.setValue(1) v2.setValue(2) v3.setValue(3) v4.setValue(4) v5.setValue(5) # Evaluate self.assertEqual(8, mult.value) # Now swap an argument visitors.swap(mult, v2, v5) # Check that the operator value is invalidated self.assertTrue(mult._value is None) self.assertFalse(v2.hasObserver(minus._flush)) self.assertTrue(v5.hasObserver(minus._flush)) # now get the args args = visitors.getArgs(mult) self.assertEqual(4, len(args)) self.assertTrue(v1 in args) self.assertTrue(v2 not in args) self.assertTrue(v3 in args) self.assertTrue(v4 in args) self.assertTrue(v5 in args) # Re-evaluate (1+3)*(4-5) = -4 self.assertEqual(-4, mult.value) # Swap out the "-" operator plus2 = literals.AdditionOperator() visitors.swap(mult, minus, plus2) self.assertTrue(mult._value is None) self.assertFalse(minus.hasObserver(mult._flush)) self.assertTrue(plus2.hasObserver(mult._flush)) # plus2 has no arguments yet. Verify this. self.assertRaises(ValueError, mult.getValue) # Add the arguments to plus2. plus2.addLiteral(v4) plus2.addLiteral(v5) # Re-evaluate (1+3)*(4+5) = 36 self.assertEqual(36, mult.value) 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()) return
def testSimpleFunction(self): """Test a simple function.""" # Make some variables v1, v2, v3, v4 = _makeArgs(4) # Make some operations mult = literals.MultiplicationOperator() plus = literals.AdditionOperator() minus = literals.SubtractionOperator() # Let's hobble the plus operator plus.name = None plus.symbol = None plus.operation = None # Partially define the equation (v1+v3)*(v4-v2). Let's only give one # variable to the '-' operation. plus.addLiteral(v1) plus.addLiteral(v3) minus.addLiteral(v4) mult.addLiteral(plus) mult.addLiteral(minus) # Now validate validator = visitors.Validator() mult.identify(validator) self.assertEqual(4, len(validator.errors)) # Fix the equation minus.addLiteral(v3) validator.reset() mult.identify(validator) self.assertEqual(3, len(validator.errors)) # Fix the name of plus plus.name = "add" validator.reset() mult.identify(validator) self.assertEqual(2, len(validator.errors)) # Fix the symbol of plus plus.symbol = "+" validator.reset() mult.identify(validator) self.assertEqual(1, len(validator.errors)) # Fix the operation of plus import numpy plus.operation = numpy.add validator.reset() mult.identify(validator) self.assertEqual(0, len(validator.errors)) # Add another literal to minus minus.addLiteral(v1) validator.reset() mult.identify(validator) self.assertEqual(1, len(validator.errors)) 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