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