Initial commit. Please see the README
[golden_search.git] / operators.py
bloba28cb35b4d5be3681aa3eda2a534e08965a800b2
1 from math import sqrt
3 import number
4 from exc import IncompatibleUnits
8 OPERATORS_ALL=[]
10 OP_CLASSES=[]
11 OPERATORS_ARITHMETIC=[]
13 def register_operator(cl):
14 OP_CLASSES.append(cl)
15 return cl
17 class GenericOp(object):
18 def __init__(self, arity, commutativity, name):
19 self.arity = arity
20 self.commutativity = commutativity
21 self.name = name
23 def __call__(self, args):
24 assert len(args) == self.getArity()
25 values = map(lambda n: n.getValue(), args)
26 sdsqs = map(lambda n: n.getSdSquare(), args)
27 units = map(lambda n: n.getUnits(), args)
29 new_value, new_sdsq, new_units = self.computeNewNumber(values, sdsqs, units)
30 return number.Number(new_value, sdsq=new_sdsq, string=self.name, units=new_units, parents=args)
32 def computeNewNumber(self, values, sdsqs, units):
33 raise NotImplementedError
35 def getArity(self):
36 return self.arity
38 def isCommutative(self):
39 return self.commutativity
42 # Arithmetic Operators
45 @register_operator
46 class Plus(GenericOp):
47 def __init__(self):
48 super(Plus, self).__init__(2, True, "Plus")
50 def computeNewNumber(self, (n1v, n2v), (n1sdsq, n2sdsq), (u1, u2)):
51 if u1 != u2:
52 raise IncompatibleUnits
53 new_value = n1v + n2v
54 new_sdsq = n1sdsq + n2sdsq
55 return new_value, new_sdsq, u1
57 @register_operator
58 class Minus(GenericOp):
59 def __init__(self):
60 super(Minus, self).__init__(2, False, "Minus")
62 def computeNewNumber(self, (n1v, n2v), (n1sdsq, n2sdsq), (u1, u2)):
63 if u1 != u2:
64 raise IncompatibleUnits
65 new_value = n1v - n2v
66 new_sdsq = n1sdsq + n2sdsq
67 return new_value, new_sdsq, u1
69 @register_operator
70 class Mult(GenericOp):
71 def __init__(self):
72 super(Mult, self).__init__(2, True, "Mult")
74 def computeNewNumber(self, (n1v, n2v), (n1sdsq, n2sdsq), (u1, u2)):
75 new_value = n1v * n2v
76 new_sdsq = n1v**2 * n2sdsq + n2v**2 * n1sdsq
77 return new_value, new_sdsq, number.units_join(u1, u2)
79 @register_operator
80 class Div(GenericOp):
81 def __init__(self):
82 super(Div, self).__init__(2, False, "Div")
84 def computeNewNumber(self, (n1v, n2v), (n1sdsq, n2sdsq), (u1, u2)):
85 new_value = n1v / n2v
86 new_sdsq = n2v**(-2) * n1sdsq + n1v**2 * n2v**(-4) * n2sdsq
87 return new_value, new_sdsq, number.units_diff(u1, u2)
90 # Numeric operators
92 # e.g. op(number) -> 2 * number
95 class Times(GenericOp):
96 def __init__(self, num):
97 super(Times, self).__init__(1, True, str(num))
98 self.num=num
100 def computeNewNumber(self, (n1v,), (n1sdsq, ), (u1,)):
101 new_value = self.num * n1v
102 new_sdsq = self.num**2 * n1sdsq
103 return new_value, new_sdsq, u1
106 # Unit Conversions
109 # TODO TODO TODO
112 # All together
115 OPERATORS_ARITHMETIC = map(lambda x: x() , OP_CLASSES)