algorithm-in-python/dataStructure/polynomial.py

201 lines
5.3 KiB
Python
Raw Normal View History

2018-07-08 23:28:29 +08:00
''' mbinary
#########################################################################
# File : polynomial.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
2019-01-31 12:09:46 +08:00
# Blog: https://mbinary.xyz
2018-07-08 23:28:29 +08:00
# Github: https://github.com/mbinary
# Created Time: 2018-05-19 23:07
# Description:
#########################################################################
'''
2018-07-08 16:41:55 +08:00
#!/bin/python3
2020-04-15 12:28:20 +08:00
# notice that creating a class's initialization won't conflict with __call__ method
2018-07-08 16:41:55 +08:00
# because the former call class ,and the latter call instance
# to be implemented
2020-04-15 12:28:20 +08:00
2018-07-08 16:41:55 +08:00
class polynomial:
2020-04-15 12:28:20 +08:00
pls = []
2018-07-08 16:41:55 +08:00
n = 0
2020-04-15 12:28:20 +08:00
2018-07-08 16:41:55 +08:00
def dictize(pl):
2020-04-15 12:28:20 +08:00
if isinstance(pl, int) or isinstance(pl, float):
pl = {0: pl}
if isinstance(pl, polynomial):
2018-07-08 16:41:55 +08:00
pl = pl.polynomial.copy()
return pl
2020-04-15 12:28:20 +08:00
2018-07-08 16:41:55 +08:00
def isZero(n):
2020-04-15 12:28:20 +08:00
return abs(n) < 0.000001
def __init__(self, s='0 0'):
2018-07-08 16:41:55 +08:00
polynomial.pls.append(self)
2020-04-15 12:28:20 +08:00
polynomial.n += 1
if isinstance(s, polynomial):
self.polynomial = s.polynomial.copy()
# don't write like this .**self.polynomial = s.polynomial**,it's ref
2018-07-08 16:41:55 +08:00
return
2020-04-15 12:28:20 +08:00
elif isinstance(s, dict):
2018-07-08 16:41:55 +08:00
self.polynomial = s.copy()
return
2020-04-15 12:28:20 +08:00
s = s.replace(',', ' ')
s = s.replace('x', ' ')
s = s.replace('x^', ' ')
s = s.replace(':', ' ')
s = s.replace('\n', ' ')
2018-07-08 16:41:55 +08:00
s = s.split(' ')
num = len(s)
i = 0
print(s)
self.polynomial = dict()
li = [float(i) for i in s]
2020-04-15 12:28:20 +08:00
while i < num:
2018-07-08 16:41:55 +08:00
if not polynomial.isZero(li[i]):
index = li[i+1]
if index in self.polynomial.keys():
self.polynomial[index] += li[i]
2020-04-15 12:28:20 +08:00
else:
self.polynomial[index] = li[i]
i += 2
2018-07-08 16:41:55 +08:00
if not self.polynomial:
2020-04-15 12:28:20 +08:00
self.polynomial = {0: 0}
2018-07-08 16:41:55 +08:00
def __iter__(self):
return iter(list(self.polynomial.keys()))
2020-04-15 12:28:20 +08:00
def __getitem__(self, key):
2018-07-08 16:41:55 +08:00
return self.polynomial[key]
2020-04-15 12:28:20 +08:00
def __setitem__(self, key, val):
2018-07-08 16:41:55 +08:00
self.polynomial[key] = val
2020-04-15 12:28:20 +08:00
def __delitem__(self, k):
2018-07-08 16:41:55 +08:00
del self.polynomial[k]
2020-04-15 12:28:20 +08:00
def __add__(self, pl):
2018-07-08 16:41:55 +08:00
pl = polynomial.dictize(pl)
rst = self.polynomial.copy()
for i in pl:
if i not in rst:
rst[i] = pl[i]
else:
rst[i] += pl[i]
if polynomial.isZero(rst[i]):
del rst[i]
return polynomial(rst)
2020-04-15 12:28:20 +08:00
def __iadd__(self, pl):
2018-07-08 16:41:55 +08:00
pl = polynomial.dictize(pl)
for i in pl:
if i not in self:
self[i] = pl[i]
else:
self[i] += pl[i]
if polynomial.isZero(self[i]):
del self[i]
return self
2020-04-15 12:28:20 +08:00
def __sub__(self, pl):
2018-07-08 16:41:55 +08:00
pl = polynomial.dictize(pl)
2020-04-15 12:28:20 +08:00
tmp = {i: -j for i, j in pl.items()}
2018-07-08 16:41:55 +08:00
return self + tmp
2020-04-15 12:28:20 +08:00
def __mul__(self, pl):
2018-07-08 16:41:55 +08:00
pl = polynomial.dictize(pl)
dic = dict()
for i in pl:
for j in self:
2020-04-15 12:28:20 +08:00
index = i+j
2018-07-08 16:41:55 +08:00
if index in dic:
dic[index] += pl[i]*self[j]
2020-04-15 12:28:20 +08:00
else:
dic[index] = pl[i]*self[j]
return polynomial({i: j for i, j in dic.items() if not polynomial.isZero(j)})
def __imul__(self, pl):
2018-07-08 16:41:55 +08:00
self = self*pl
return self
2020-04-15 12:28:20 +08:00
def __pow__(self, n):
rst = polynomial({0: 1})
2018-07-08 16:41:55 +08:00
for i in range(n):
2020-04-15 12:28:20 +08:00
rst *= self.polynomial
2018-07-08 16:41:55 +08:00
return rst
2020-04-15 12:28:20 +08:00
2018-07-08 16:41:55 +08:00
def __repr__(self):
return self.__str__()
2020-04-15 12:28:20 +08:00
2018-07-08 16:41:55 +08:00
def __str__(self):
output = ''
if self.polynomial:
2020-04-15 12:28:20 +08:00
key = sorted(self.polynomial.keys(), reverse=True)
2018-07-08 16:41:55 +08:00
num = len(key)
2020-04-15 12:28:20 +08:00
for j, i in enumerate(key):
2018-07-08 16:41:55 +08:00
if polynomial.isZero(i):
2020-04-15 12:28:20 +08:00
output += '%+g' % self[i]
2018-07-08 16:41:55 +08:00
continue
if not polynomial.isZero(self[i]-1):
if not polynomial.isZero(self[i]+1):
2020-04-15 12:28:20 +08:00
output += "%+g" % self[i]
else:
output += '-'
else:
output += '+'
if not polynomial.isZero(i):
output += 'x'
if not polynomial.isZero(i-1):
output += '^%g' % i
2018-07-08 16:41:55 +08:00
if output[0] == '+':
return output[1:]
return output
2020-04-15 12:28:20 +08:00
def iterPolynomial(self, s):
rst = polynomial({0: 0})
2018-07-08 16:41:55 +08:00
for i in self:
rst += s**int(i)*self[i]
return rst
2020-04-15 12:28:20 +08:00
def __call__(self, s):
if isinstance(s, polynomial):
return self.iterPolynomial(s)
2018-07-08 16:41:55 +08:00
sum = 0
for i in self:
sum += self[i] * s**i
return sum
2020-04-15 12:28:20 +08:00
def __xor__(self, n):
2018-07-08 16:41:55 +08:00
tmp = polynomial(self)
for i in range(n):
self = self.iterPolynomial(tmp)
return self
2020-04-15 12:28:20 +08:00
2018-07-08 16:41:55 +08:00
def save(self):
polynomial.pls.append(self)
2020-04-15 12:28:20 +08:00
polynomial.n += 1
def delPlynomial(self, n):
2018-07-08 16:41:55 +08:00
return polynomial.pls.pop(n-1)
2020-04-15 12:28:20 +08:00
2018-07-08 16:41:55 +08:00
def menu():
print('polynomial operations')
print('1.create')
print('2.add')
print('3.sub')
print('4.iadd')
print('5.mul')
print('6.del')
print('7.display')
print('8.cal val')
print('9.polynomial iter')
print('10.menu')
print('11.exit')
2020-04-15 12:28:20 +08:00
2018-07-08 16:41:55 +08:00
if __name__ == '__main__':
2020-05-13 10:45:51 +08:00
menu()