import old polynom and test_polynom from polynom branch
This commit is contained in:
parent
20bc84bf6a
commit
73e6c74c72
318
pymath/polynom.py
Normal file
318
pymath/polynom.py
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
|
||||||
|
from pymath.fraction import Fraction
|
||||||
|
from pymath.expression import Expression
|
||||||
|
from pymath.generic import mix_list, sum_postfix, expand_list
|
||||||
|
|
||||||
|
__all__ = ["Polynom"]
|
||||||
|
|
||||||
|
|
||||||
|
class Polynom(object):
|
||||||
|
|
||||||
|
"""Docstring for Polynom. """
|
||||||
|
|
||||||
|
def __init__(self, coef = [1], letter = "x" ):
|
||||||
|
"""Initiate the polynom
|
||||||
|
|
||||||
|
:param coef: coefficients of the polynom (ascending degree sorted) - can be a list of list of coefficients.
|
||||||
|
3 possibles type of list:
|
||||||
|
- [a,b,..] simple list of coefficients. [1,2] designate 1 + 2x
|
||||||
|
- [a, [c,b],...] list of coefficients with x^i repeated. [1,[2,3],4) designate 1 + 2x + 3x + 4x^2
|
||||||
|
- [a, [b,c,"+"],...] list of coefficients with arithmetic expression (postfix form) in. [1, [2,3,"+"], 4] designate 1 + (2+3)x + 4x^2
|
||||||
|
:param letter: the string describing the unknown
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.feed_coef(coef)
|
||||||
|
self._letter = letter
|
||||||
|
|
||||||
|
|
||||||
|
if self.is_monom():
|
||||||
|
self.mainOp = "*"
|
||||||
|
else:
|
||||||
|
self.mainOp = "+"
|
||||||
|
|
||||||
|
def feed_coef(self, l_coef):
|
||||||
|
"""Feed coef of the polynom. Manage differently whether it's a number or an expression
|
||||||
|
|
||||||
|
:l_coef: list of coef
|
||||||
|
"""
|
||||||
|
self._coef = []
|
||||||
|
for coef in l_coef:
|
||||||
|
if type(coef) == list and len(coef)==1:
|
||||||
|
self._coef.append(coef[0])
|
||||||
|
else:
|
||||||
|
self._coef.append(coef)
|
||||||
|
|
||||||
|
def get_degree(self):
|
||||||
|
"""Getting the degree fo the polynom
|
||||||
|
|
||||||
|
:returns: the degree of the polynom
|
||||||
|
|
||||||
|
"""
|
||||||
|
return len(self._coef) - 1
|
||||||
|
|
||||||
|
def is_monom(self):
|
||||||
|
"""is the polynom a monom (only one coefficent)
|
||||||
|
:returns: 1 if yes 0 otherwise
|
||||||
|
"""
|
||||||
|
if len([i for i in self._coef if i != 0])==1:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
# TODO: Voir si on peut utiliser un render |sam. juin 14 08:56:16 CEST 2014
|
||||||
|
from .renders import txt
|
||||||
|
return txt(self.get_postfix())
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "< Polynom " + str(self._coef) + ">"
|
||||||
|
|
||||||
|
def coef_postfix(self, a, i):
|
||||||
|
"""Return the postfix display of a coeficient
|
||||||
|
|
||||||
|
:param a: value for the coeficient (/!\ as a list)
|
||||||
|
:param i: power
|
||||||
|
:returns: postfix tokens of coef
|
||||||
|
|
||||||
|
"""
|
||||||
|
ans =[]
|
||||||
|
if a == 0:
|
||||||
|
return ans
|
||||||
|
if i == 0:
|
||||||
|
ans = a
|
||||||
|
elif i == 1:
|
||||||
|
ans = a * (a!=[1]) + [self._letter] + ["*"] * (a!=[1])
|
||||||
|
else:
|
||||||
|
ans = a * (a!=[1]) + [self._letter, i, "^"] + ["*"] * (a!=[1])
|
||||||
|
|
||||||
|
return ans
|
||||||
|
|
||||||
|
def get_postfix(self):
|
||||||
|
"""Return the postfix form of the polynom
|
||||||
|
|
||||||
|
:returns: the postfix list of polynom's tokens
|
||||||
|
|
||||||
|
"""
|
||||||
|
self._postfix = []
|
||||||
|
first_elem = 1
|
||||||
|
for (i,a) in list(enumerate(self._coef))[::-1]:
|
||||||
|
if type(a) == list and str(a[-1]) in "+-*^/":
|
||||||
|
# case coef is an arithmetic expression
|
||||||
|
self._postfix += self.coef_postfix(a,i)
|
||||||
|
if not first_elem:
|
||||||
|
self._postfix.append("+")
|
||||||
|
first_elem = 0
|
||||||
|
|
||||||
|
elif type(a) == list and str(a[-1]) not in "+-*^/":
|
||||||
|
# case need to repeat the x^i
|
||||||
|
for b in a:
|
||||||
|
if type(b) == list:
|
||||||
|
self._postfix += self.coef_postfix(b,i)
|
||||||
|
else:
|
||||||
|
self._postfix += self.coef_postfix([b],i)
|
||||||
|
if not first_elem:
|
||||||
|
self._postfix.append("+")
|
||||||
|
first_elem = 0
|
||||||
|
|
||||||
|
elif a != 0:
|
||||||
|
self._postfix += self.coef_postfix([a],i)
|
||||||
|
if not first_elem:
|
||||||
|
self._postfix.append("+")
|
||||||
|
first_elem = 0
|
||||||
|
|
||||||
|
return self._postfix
|
||||||
|
|
||||||
|
def convert_into_poly(self, other):
|
||||||
|
"""Convert anything (int and fract) into a polynom """
|
||||||
|
if type(other) in [int, Fraction]:
|
||||||
|
return Polynom([other])
|
||||||
|
elif type(other) == Polynom:
|
||||||
|
return other
|
||||||
|
else:
|
||||||
|
raise ValueError(type(other) + " can't be converted into a polynom")
|
||||||
|
|
||||||
|
def reduce(self):
|
||||||
|
"""Compute coefficients which have same degree
|
||||||
|
|
||||||
|
:returns: new Polynom with numbers coefficients
|
||||||
|
"""
|
||||||
|
steps = []
|
||||||
|
for a in self._coef:
|
||||||
|
coef_steps = []
|
||||||
|
if type(a) == list and str(a[-1]) in "+-*^":
|
||||||
|
# case coef is an arithmetic expression
|
||||||
|
exp = Expression(a)
|
||||||
|
coef_steps = list(exp.simplify(render = lambda x:x))
|
||||||
|
|
||||||
|
steps.append(coef_steps)
|
||||||
|
elif type(a) == list and str(a[-1]) not in "+-*^":
|
||||||
|
# case need to repeat the x^i
|
||||||
|
if [i for i in a if type(i) == list] != []:
|
||||||
|
# first we simplify arithmetic exp
|
||||||
|
# Et hop un coup de sorcelerie!
|
||||||
|
elem = [list(Expression(i).simplify(render = lambda x:self.list_or_num(x))) if type(i) == list else i for i in a ]
|
||||||
|
|
||||||
|
elem = expand_list(elem)
|
||||||
|
coef_steps += elem
|
||||||
|
exp = elem[-1]
|
||||||
|
|
||||||
|
else:
|
||||||
|
exp = a
|
||||||
|
|
||||||
|
exp = sum_postfix(exp)
|
||||||
|
exp = Expression(exp)
|
||||||
|
|
||||||
|
coef_steps += list(exp.simplify(render = lambda x:x))
|
||||||
|
|
||||||
|
steps.append(coef_steps)
|
||||||
|
else:
|
||||||
|
steps.append(a)
|
||||||
|
|
||||||
|
steps = expand_list(steps)
|
||||||
|
|
||||||
|
return [Polynom(s) for s in steps]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def list_or_num(x):
|
||||||
|
if len(x) == 1:
|
||||||
|
return x[0]
|
||||||
|
else:
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
def simplify(self):
|
||||||
|
"""Same as reduce """
|
||||||
|
return self.reduce()
|
||||||
|
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if type(other) in [int, Fraction, Polynom] or other.isnumeric():
|
||||||
|
o_poly = self.convert_into_poly(other)
|
||||||
|
|
||||||
|
return self._coef == o_poly._coef
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
steps = []
|
||||||
|
|
||||||
|
o_poly = self.convert_into_poly(other)
|
||||||
|
|
||||||
|
n_coef = mix_list(self._coef, o_poly._coef)
|
||||||
|
p = Polynom(n_coef)
|
||||||
|
steps.append(p)
|
||||||
|
|
||||||
|
steps += p.simplify()
|
||||||
|
return steps
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
return self.__add__(other)
|
||||||
|
|
||||||
|
def __neg__(self):
|
||||||
|
return Polynom([-i for i in self._coef], letter = self._letter)
|
||||||
|
|
||||||
|
def __sub__(self, other):
|
||||||
|
o_poly = self.convert_into_poly(other)
|
||||||
|
o_poly = -o_poly
|
||||||
|
|
||||||
|
return self.__add__(o_poly)
|
||||||
|
|
||||||
|
def __rsub__(self, other):
|
||||||
|
o_poly = self.convert_into_poly(other)
|
||||||
|
|
||||||
|
return o_poly.__sub__(-self)
|
||||||
|
|
||||||
|
def __mul__(self, other):
|
||||||
|
steps = []
|
||||||
|
o_poly = self.convert_into_poly(other)
|
||||||
|
|
||||||
|
coefs = []
|
||||||
|
for (i,a) in enumerate(self._coef):
|
||||||
|
for (j,b) in enumerate(o_poly._coef):
|
||||||
|
if a == 0 or b == 0:
|
||||||
|
elem = 0
|
||||||
|
else:
|
||||||
|
elem = [a, b, "*"]
|
||||||
|
try:
|
||||||
|
if coefs[i+j]==0:
|
||||||
|
coefs[i+j] = elem
|
||||||
|
elif elem != 0:
|
||||||
|
coefs[i+j] = [coefs[i+j], elem]
|
||||||
|
except IndexError:
|
||||||
|
coefs.append(elem)
|
||||||
|
|
||||||
|
p = Polynom(coefs)
|
||||||
|
steps.append(p)
|
||||||
|
|
||||||
|
steps += p.simplify()
|
||||||
|
return steps
|
||||||
|
|
||||||
|
def __rmul__(self, other):
|
||||||
|
o_poly = self.convert_into_poly(other)
|
||||||
|
|
||||||
|
return o_poly.__mul__(self)
|
||||||
|
|
||||||
|
def __div__(self, other):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __truediv__(self, other):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test(p,q):
|
||||||
|
print("---------------------")
|
||||||
|
print("---------------------")
|
||||||
|
print("p : ",p)
|
||||||
|
print("q : ",q)
|
||||||
|
|
||||||
|
print("\n Plus ------")
|
||||||
|
for i in (p + q):
|
||||||
|
#print(repr(i))
|
||||||
|
#print("\t", str(i.get_postfix()))
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
print("\n Moins ------")
|
||||||
|
for i in (p - q):
|
||||||
|
#print(repr(i))
|
||||||
|
#print("\t", str(i.get_postfix()))
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
print("\n Multiplier ------")
|
||||||
|
for i in (p * q):
|
||||||
|
#print(repr(i))
|
||||||
|
#print("\t", str(i.get_postfix()))
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
p = Polynom([1, -2 ])
|
||||||
|
q = Polynom([4, 7])
|
||||||
|
#test(p,q)
|
||||||
|
|
||||||
|
q = Polynom([0, Fraction(1,2), 0, Fraction(-4,3)])
|
||||||
|
#test(p,q)
|
||||||
|
|
||||||
|
p = Polynom([1, 1, 1 ])
|
||||||
|
print(p)
|
||||||
|
|
||||||
|
|
||||||
|
#print("-- Poly étrange --")
|
||||||
|
#p = Polynom([1, [[2, 3, "*"],3], 4], "x")
|
||||||
|
#print(repr(p))
|
||||||
|
#for i in p.simplify():
|
||||||
|
# print(repr(i))
|
||||||
|
#print("-- Poly étrange --")
|
||||||
|
#p = Polynom([1, [[2, 3, "*"], [4,5,"*"]], 4], "x")
|
||||||
|
#print(repr(p))
|
||||||
|
#print(p)
|
||||||
|
#for i in p.simplify():
|
||||||
|
# print(repr(i))
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Reglages pour 'vim'
|
||||||
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
# cursor: 16 del
|
162
test/test_polynom.py
Normal file
162
test/test_polynom.py
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from pymath.polynom import Polynom
|
||||||
|
from pymath.fraction import Fraction
|
||||||
|
|
||||||
|
|
||||||
|
class TestPolynom(unittest.TestCase):
|
||||||
|
"""Testing functions from pymath.polynom"""
|
||||||
|
|
||||||
|
def test_init(self):
|
||||||
|
p = Polynom([1, 2, 3], "x")
|
||||||
|
|
||||||
|
def test_init_multi(self):
|
||||||
|
p = Polynom([1, [2, 3], 4], "x")
|
||||||
|
|
||||||
|
def test_init_arith(self):
|
||||||
|
p = Polynom([1, [2, 3, "+"], 4], "x")
|
||||||
|
|
||||||
|
def test_init_arith_2(self):
|
||||||
|
p = Polynom([1, [[2, 3, "*"],3], 4], "x")
|
||||||
|
|
||||||
|
def test_deg(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_eval(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#def test_print(self):
|
||||||
|
# p = Polynom([1,2,3])
|
||||||
|
# ans = "1 + 2 x + 3 x^2"
|
||||||
|
# self.assertEqual(ans, str(p))
|
||||||
|
|
||||||
|
#def test_print_monom(self):
|
||||||
|
# p = Polynom([0,2])
|
||||||
|
# ans = "2 x"
|
||||||
|
# self.assertEqual(ans, str(p))
|
||||||
|
|
||||||
|
#def test_print_0_coef(self):
|
||||||
|
# p = Polynom([0,1,3])
|
||||||
|
# ans = "x + 3 x^2"
|
||||||
|
# self.assertEqual(ans, str(p))
|
||||||
|
|
||||||
|
#def test_print_multi_coef(self):
|
||||||
|
# p = Polynom([1,[2, -2],3])
|
||||||
|
# ans = "1 + 2 x - 2 x + 3 x^2"
|
||||||
|
# self.assertEqual(ans, str(p))
|
||||||
|
|
||||||
|
def test_get_postfix(self):
|
||||||
|
p = Polynom([1,2,3])
|
||||||
|
#ans = [1, 2, "x", "*", "+", 3, "x", 2, "^", "*", "+"]
|
||||||
|
ans = [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+']
|
||||||
|
self.assertEqual(ans, p.get_postfix())
|
||||||
|
|
||||||
|
def test_get_postfix_monom(self):
|
||||||
|
p = Polynom([0,2])
|
||||||
|
ans = [2, "x", "*"]
|
||||||
|
self.assertEqual(ans, p.get_postfix())
|
||||||
|
|
||||||
|
def test_get_postfix_0_coef(self):
|
||||||
|
p = Polynom([0,2,0,4])
|
||||||
|
#ans = [2, "x", "*", 4, "x", 3, "^", "*", "+"]
|
||||||
|
ans = [4, 'x', 3, '^', '*', 2, 'x', '*', '+']
|
||||||
|
self.assertEqual(ans, p.get_postfix())
|
||||||
|
|
||||||
|
def test_get_postfix_1_coef(self):
|
||||||
|
p = Polynom([0,1,1])
|
||||||
|
#ans = ["x", "x", 2, "^", "+"]
|
||||||
|
ans = ["x", 2, "^", "x", "+"]
|
||||||
|
self.assertEqual(ans, p.get_postfix())
|
||||||
|
|
||||||
|
def test_get_postfix_neg_coef(self):
|
||||||
|
# TODO: Choix arbitraire (vis à vis des + et des -) il faudra faire en fonction de render |sam. juin 14 09:45:55 CEST 2014
|
||||||
|
p = Polynom([-1,-2,-3])
|
||||||
|
#ans = [-1, -2, "x", "*", "+", -3, "x", 2, "^", "*", "+"]
|
||||||
|
ans = [-3, 'x', 2, '^', '*', -2, 'x', '*', '+', -1, '+']
|
||||||
|
self.assertEqual(ans, p.get_postfix())
|
||||||
|
|
||||||
|
def test_get_postfix_multi_coef(self):
|
||||||
|
p = Polynom([1,[2, 3],4])
|
||||||
|
#ans = [1, 2, "x", "*", "+", 3, "x", "*", "+", 4, "x", 2, "^", "*", "+"]
|
||||||
|
ans = [4, 'x', 2, '^', '*', 2, 'x', '*', '+', 3, 'x', '*', '+', 1, '+']
|
||||||
|
self.assertEqual(ans, p.get_postfix())
|
||||||
|
|
||||||
|
def test_get_postfix_arithm_coef(self):
|
||||||
|
p = Polynom([1,[2, 3, "+"],4])
|
||||||
|
#ans = [1, 2, 3, "+", "x", "*", "+", 4, "x", 2, "^", "*", "+"]
|
||||||
|
ans = [4, 'x', 2, '^', '*', 2, 3, '+', 'x', '*', '+', 1, '+']
|
||||||
|
self.assertEqual(ans, p.get_postfix())
|
||||||
|
|
||||||
|
def test_reduce_nilpo(self):
|
||||||
|
p = Polynom([1, 2, 3])
|
||||||
|
self.assertEqual(p, p.reduce()[-1])
|
||||||
|
|
||||||
|
def test_reduce(self):
|
||||||
|
p = Polynom([1, [2, 3], 4])
|
||||||
|
reducted = Polynom([1, 5, 4])
|
||||||
|
self.assertEqual(p.reduce()[-1],reducted)
|
||||||
|
|
||||||
|
def test_add_int(self):
|
||||||
|
p = Polynom([1, 2, 3])
|
||||||
|
q = (p + 2)[-1]
|
||||||
|
self.assertEqual(q, Polynom([3, 2, 3]))
|
||||||
|
|
||||||
|
def test_add_frac(self):
|
||||||
|
p = Polynom([1, 2, 3])
|
||||||
|
f = Fraction(1, 2)
|
||||||
|
q = (p + f)[-1]
|
||||||
|
self.assertEqual(q, Polynom([Fraction(3, 2), 2, 3]))
|
||||||
|
|
||||||
|
def test_add_poly(self):
|
||||||
|
p = Polynom([1, 0, 3])
|
||||||
|
q = Polynom([0, 2, 3])
|
||||||
|
r = (p + q)[-1]
|
||||||
|
self.assertEqual(r, Polynom([1, 2, 6]))
|
||||||
|
|
||||||
|
def test_radd_int(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_radd_frac(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_radd_poly(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_mul_int(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_mul_frac(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_mul_poly(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_rmul_int(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_rmul_frac(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_rmul_poly(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Reglages pour 'vim'
|
||||||
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
# cursor: 16 del
|
||||||
|
|
Loading…
Reference in New Issue
Block a user