formal multiplication done, need to simplify keys

This commit is contained in:
lafrite 2014-01-18 17:08:04 +01:00 committed by Lafrite
parent c5300991d5
commit 9b104f020f
2 changed files with 72 additions and 31 deletions

View File

@ -2,7 +2,7 @@
# encoding: utf-8 # encoding: utf-8
from .fraction import Fraction from .fraction import Fraction
from .generic import add_in_dict, remove_in_dict from .generic import add_in_dict, remove_in_dict, convolution_dict
import re import re
class FormalExp(object): class FormalExp(object):
@ -51,20 +51,39 @@ class FormalExp(object):
m_power = max(power) m_power = max(power)
return power[m_power] return power[m_power]
def __add__(self, other): def check_calculous(self, other):
"""Check if other is a constant and then transform it into a dictionary compatible with FormalExp
:param other: The thing to compute with the expression
:returns: dictionary of this thing
"""
if type(other) in [int, Fraction]: if type(other) in [int, Fraction]:
d = {"":other} return {"":other}
elif type(other) == FormalExp: elif type(other) == FormalExp:
d = other._coef return other._coef.copy()
else: else:
raise ValueError("Can't add {type} with FormalExp".format(type=type(other))) raise ValueError("Can't add {type} with FormalExp".format(type=type(other)))
def const_or_formal(self, d):
"""Return a constant if there is nothing else, FormalExp otherwise
:param d: dictionary descripting the expression
:returns: a constant or a FormalExp
"""
if list(d.keys()) == ['']:
return d['']
else:
return FormalExp(d)
def __add__(self, other):
d = self.check_calculous(other)
d = add_in_dict(self._coef, d) d = add_in_dict(self._coef, d)
d = remove_in_dict(d) d = remove_in_dict(d)
if list(d.keys()) == ['']:
return [d['']] return [self.const_or_formal(d)]
else:
return [FormalExp(d)]
def __radd__(self, other): def __radd__(self, other):
return self + other return self + other
@ -80,15 +99,35 @@ class FormalExp(object):
return FormalExp(d) return FormalExp(d)
def __mul__(self, other): def __mul__(self, other):
pass d = self.check_calculous(other)
d = convolution_dict(self._coef, d, op_key = self.op_key)
d = remove_in_dict(d)
return [self.const_or_formal(d)]
def op_key(self, x,y):
"""Operation on keys for convolution_dict"""
if x == "" or y == "":
return x+y
else:
return x + "*" + y
def __rmul__(self, other): def __rmul__(self, other):
pass d = self.check_calculous(other)
d = convolution_dict(d, self._coef, op_key = self.op_key)
d = remove_in_dict(d)
return [self.const_or_formal(d)]
def __div__(self, other): def __div__(self, other):
# Will never be done :D
pass pass
def __pow__(self, other): def __pow__(self, other):
# Will never be done :D quoique
pass pass
def __len__(self): def __len__(self):
@ -98,26 +137,24 @@ class FormalExp(object):
return " + ".join([str(v) + str(k) for k,v in self._coef.items()]) return " + ".join([str(v) + str(k) for k,v in self._coef.items()])
if __name__ == '__main__': if __name__ == '__main__':
#fe1 = FormalExp({"x": 1, "":2}) fe1 = FormalExp({"x": 1, "":2})
#print(fe1) print(fe1)
#fe2 = FormalExp({"x**12": 5, "":2}) fe2 = FormalExp({"x**12": 5, "":2})
#print(fe2) print(fe2)
#fe3 = fe1 + fe2 fe3 = fe1 * fe2
#for s in fe3: for s in fe3:
# print(s) print(s)
#fe4 = fe1 + 2 fe4 = fe1 * 2
#for s in fe4: for s in fe4:
# print(s) print(s)
#print(fe1.master_coef())
#print(fe2.master_coef())
#print(fe3[0].master_coef())
#print(fe4[0].master_coef())
fe = FormalExp(letter = "a") fe = FormalExp(letter = "a")
fe_ = -2 + fe fe_ = -2 * fe
print(fe_[0]) print(fe_[0])
fe = FormalExp(letter = "a")
fe_ = fe * (-2)
print(fe_[0])

View File

@ -144,6 +144,7 @@ def remove_in_dict(d, value = 0):
return new_dict return new_dict
def convolution_dict(D1, D2, op = lambda x,y:x*y,\ def convolution_dict(D1, D2, op = lambda x,y:x*y,\
op_key = lambda x,y: x + y, \
commutative = True, op_twice = lambda x,y: x + y): commutative = True, op_twice = lambda x,y: x + y):
"""Convolution of two dictionaries """Convolution of two dictionaries
@ -170,14 +171,17 @@ def convolution_dict(D1, D2, op = lambda x,y:x*y,\
for k1 in sorted(D1.keys()): for k1 in sorted(D1.keys()):
for k2 in sorted(D2.keys()): for k2 in sorted(D2.keys()):
if k1+k2 in new_dict.keys(): if op_key(k1,k2) in new_dict.keys():
new_dict[k1+k2] = op_twice(new_dict[k1+k2], op(D1[k1],D2[k2])) key = op_key(k1,k2)
new_dict[key] = op_twice(new_dict[key], op(D1[k1],D2[k2]))
elif k2+k1 in new_dict.keys() and commutative: elif op_key(k2,k1) in new_dict.keys() and commutative:
new_dict[k2+k1] = op_twice(new_dict[k2+k1], op(D1[k1],D2[k2])) key = op_key(k2,k1)
new_dict[key] = op_twice(new_dict[key], op(D1[k1],D2[k2]))
else: else:
new_dict[k1+k2] = op(D1[k1],D2[k2]) key = op_key(k1,k2)
new_dict[key] = op(D1[k1],D2[k2])
return new_dict return new_dict