Mapytex/pymath/calculus/abstract_polynom.py

627 lines
22 KiB
Python
Raw Normal View History

2015-04-03 14:07:07 +00:00
#!/usr/bin/env python
# encoding: utf-8
from .explicable import Explicable
from .expression import Expression
from .operator import op
from .generic import spe_zip, expand_list, isNumber, transpose_fill, flatten_list, isPolynom, isNumerand
2016-02-13 04:04:08 +00:00
from .render import txt, tex
2015-04-03 14:07:07 +00:00
from itertools import chain
from functools import wraps
2016-02-13 04:04:08 +00:00
2015-04-03 14:07:07 +00:00
def power_cache(fun):
"""Decorator which cache calculated powers of polynoms """
2016-02-13 04:04:08 +00:00
cache = {}
2015-04-03 14:07:07 +00:00
@wraps(fun)
def cached_fun(self, power):
#print("cache -> ", cache)
if (tuple(self._coef), power) in cache.keys():
return cache[(tuple(self._coef), power)]
else:
poly_powered = fun(self, power)
cache[(tuple(self._coef), power)] = poly_powered
return poly_powered
return cached_fun
2016-02-13 04:04:08 +00:00
2015-04-03 14:07:07 +00:00
class AbstractPolynom(Explicable):
"""The mathematic definition of a polynom. It will be the parent class of Polynom (classical polynoms) and later of SquareRoot polynoms"""
2016-02-13 04:04:08 +00:00
def __init__(self, coefs=[1], letter="x", name="P"):
2015-04-03 14:07:07 +00:00
"""Initiate the polynom
:param coef: coefficients of the polynom (ascending degree sorted)
3 possibles type of coefficent:
- a : simple "number". [1,2] designate 1 + 2x
- [a,b,c]: list of coeficient for same degree. [1,[2,3],4] designate 1 + 2x + 3x + 4x^2
- a: a Expression. [1, Expression("2+3"), 4] designate 1 + (2+3)x + 4x^2
:param letter: the string describing the unknown
:param name: Name of the polynom
>>> P = AbstractPolynom([1, 2, 3])
>>> P.mainOp
'+'
>>> P.name
'P'
>>> P._letter
'x'
>>> AbstractPolynom([1]).mainOp
'*'
>>> AbstractPolynom([0, 0, 3]).mainOp
'*'
>>> AbstractPolynom([1, 2, 3])._letter
'x'
>>> AbstractPolynom([1, 2, 3], "y")._letter
'y'
>>> AbstractPolynom([1, 2, 3], name = "Q").name
'Q'
"""
super(AbstractPolynom, self).__init__()
2015-04-03 15:32:02 +00:00
try:
# Remove 0 at the end of the coefs
while coefs[-1] == 0:
coefs = coefs[:-1]
except IndexError:
pass
2015-04-07 06:55:05 +00:00
if coefs == []:
coefs = [0]
2015-04-03 14:07:07 +00:00
self.feed_coef(coefs)
self._letter = letter
self.name = name
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
if self.is_monom():
self.mainOp = op.mul
else:
self.mainOp = op.add
self._isPolynom = 1
def feed_coef(self, l_coef):
"""Feed coef of the polynom. Manage differently whether it's a number or an expression
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
:l_coef: list of coef
"""
self._coef = []
for coef in l_coef:
2016-02-13 04:04:08 +00:00
if isinstance(coef, list) and len(coef) == 1:
2015-04-03 14:07:07 +00:00
self._coef.append(coef[0])
else:
self._coef.append(coef)
@property
def degree(self):
"""Getting the degree fo the polynom
:returns: the degree of the polynom
>>> AbstractPolynom([1, 2, 3]).degree
2
>>> AbstractPolynom([1]).degree
0
"""
return len(self._coef) - 1
def is_monom(self):
"""is the polynom a monom (only one coefficent)
:returns: 1 if yes 0 otherwise
>>> AbstractPolynom([1, 2, 3]).is_monom()
0
>>> AbstractPolynom([1]).is_monom()
1
"""
2016-02-13 04:04:08 +00:00
if len([i for i in self._coef if i != 0]) == 1:
2015-04-03 14:07:07 +00:00
return 1
else:
return 0
def give_name(self, name):
self.name = name
def __str__(self):
return str(Expression(self.postfix_tokens))
def __repr__(self):
2016-02-13 04:04:08 +00:00
return "< " + str(self.__class__) + " " + str(self._coef) + ">"
2015-04-03 14:07:07 +00:00
def coef_postfix(self, a, i):
"""Return the postfix display of a coeficient
:param a: value for the coeficient (/!\ as a postfix list)
:param i: power
:returns: postfix tokens of coef
>>> p = AbstractPolynom()
>>> p.coef_postfix([3],2)
[3, 'x', 2, '^', '*']
>>> p.coef_postfix([0],1)
[]
>>> p.coef_postfix([3],0)
[3]
>>> p.coef_postfix([3],1)
[3, 'x', '*']
>>> p.coef_postfix([1],1)
['x']
>>> p.coef_postfix([1],2)
['x', 2, '^']
"""
2016-02-13 04:04:08 +00:00
ans = []
2015-04-03 14:07:07 +00:00
if a == [0]:
pass
elif i == 0:
ans = a
elif i == 1:
2016-02-13 04:04:08 +00:00
ans = a * (a != [1]) + [self._letter] + [op.mul] * (a != [1])
2015-04-03 14:07:07 +00:00
else:
2016-02-13 04:04:08 +00:00
ans = a * (a != [1]) + [self._letter, i,
op.pw] + [op.mul] * (a != [1])
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
return ans
@property
def postfix_tokens(self):
"""Return the postfix form of the polynom
:returns: the postfix list of polynom's tokens
>>> p = AbstractPolynom([1, 2])
>>> p.postfix_tokens
[2, 'x', '*', 1, '+']
>>> p = AbstractPolynom([1, -2])
>>> p.postfix_tokens
[2, 'x', '*', '-', 1, '+']
>>> p = AbstractPolynom([1,2,3])
>>> p.postfix_tokens
[3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+']
>>> p = AbstractPolynom([1])
>>> p.postfix_tokens
[1]
>>> p = AbstractPolynom([0])
>>> p.postfix_tokens
[0]
>>> p = AbstractPolynom([1,[2,3]])
>>> p.postfix_tokens
[2, 'x', '*', 3, 'x', '*', '+', 1, '+']
>>> p = AbstractPolynom([1,[2,-3]])
>>> p.postfix_tokens
[2, 'x', '*', 3, 'x', '*', '-', 1, '+']
>>> p = AbstractPolynom([1,[-2,-3]])
>>> p.postfix_tokens
[2, 'x', '*', '-', 3, 'x', '*', '-', 1, '+']
2016-01-07 16:34:23 +00:00
>>> from pymath.calculus.expression import Expression
>>> from pymath.calculus.operator import op
2015-04-03 14:07:07 +00:00
>>> e = Expression([2,3,op.add])
>>> p = AbstractPolynom([1,e])
>>> p.postfix_tokens
[2, 3, '+', 'x', '*', 1, '+']
"""
if self == 0:
return [0]
2016-02-13 04:04:08 +00:00
# TODO: Faudrait factoriser un peu tout ça..! |dim. déc. 21 16:02:34
# CET 2014
2015-04-03 14:07:07 +00:00
postfix = []
2016-02-13 04:04:08 +00:00
for (i, a) in list(enumerate(self._coef))[::-1]:
2015-04-03 14:07:07 +00:00
operator = [op.add]
operator_sub1 = []
2016-02-13 04:04:08 +00:00
if isinstance(a, Expression):
2015-04-03 14:07:07 +00:00
# case coef is an arithmetic expression
2016-02-13 04:04:08 +00:00
c = self.coef_postfix(a.postfix_tokens, i)
2015-04-03 14:07:07 +00:00
if c != []:
postfix.append(c)
if len(postfix) > 1:
postfix += operator
2016-02-13 04:04:08 +00:00
elif isinstance(a, list):
2015-04-03 14:07:07 +00:00
# case need to repeat the x^i
for b in a:
operator = [op.add]
operator_sub1 = []
if len(postfix) == 0 and isNumber(b) and b < 0:
try:
b = [(-b)[-1]]
except TypeError:
b = [-b]
operator_sub1 = [op.sub1]
elif len(postfix) > 0 and isNumber(b) and b < 0:
try:
b = [(-b)[-1]]
except TypeError:
b = [-b]
operator = [op.sub]
else:
b = [b]
2016-02-13 04:04:08 +00:00
c = self.coef_postfix(b, i)
2015-04-03 14:07:07 +00:00
if c != []:
postfix.append(c)
if len(postfix) > 1:
postfix += operator_sub1
postfix += operator
postfix += operator_sub1
elif a != 0:
if len(postfix) == 0 and a < 0:
try:
a = [(-a)[-1]]
except TypeError:
a = [-a]
operator_sub1 = [op.sub1]
elif len(postfix) > 0 and a < 0:
try:
a = [(-a)[-1]]
except TypeError:
a = [-a]
operator = [op.sub]
else:
a = [a]
2016-02-13 04:04:08 +00:00
c = self.coef_postfix(a, i)
2015-04-03 14:07:07 +00:00
if c != []:
postfix.append(c)
if len(postfix) > 1:
postfix += operator_sub1
postfix += operator
postfix += operator_sub1
return flatten_list(postfix)
def conv2poly(self, other):
"""Convert anything number into a polynom
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
>>> P = AbstractPolynom([1,2,3])
>>> P.conv2poly(1)
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [1]>
2015-04-03 14:07:07 +00:00
>>> P.conv2poly(0)
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0]>
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
"""
if isNumber(other) and not isPolynom(other):
2016-02-13 04:04:08 +00:00
return AbstractPolynom([other], letter=self._letter)
2015-04-03 14:07:07 +00:00
elif isPolynom(other):
return other
else:
2016-02-13 04:04:08 +00:00
raise ValueError(type(other) +
" can't be converted into a polynom")
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
def reduce(self):
"""Compute coefficients which have same degree
:returns: new AbstractPolynom with numbers coefficients
>>> P = AbstractPolynom([1,2,3])
>>> Q = P.reduce()
>>> Q
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [1, 2, 3]>
2015-04-03 14:07:07 +00:00
>>> Q.steps
[]
>>> P = AbstractPolynom([[1,2], [3,4,5], 6])
>>> Q = P.reduce()
>>> Q
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [3, 12, 6]>
2015-04-21 16:10:14 +00:00
>>> for i in Q.explain():
... print(i)
6 x^{ 2 } + 3 x + 4 x + 5 x + 1 + 2
2015-04-21 16:10:14 +00:00
6 x^{ 2 } + ( 3 + 4 + 5 ) x + 1 + 2
6 x^{ 2 } + ( 7 + 5 ) x + 3
6 x^{ 2 } + 12 x + 3
2015-04-03 14:07:07 +00:00
>>> Q.steps
[< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [[1, 2], [3, 4, 5], 6]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [< <class 'pymath.calculus.expression.Expression'> [1, 2, '+'] >, < <class 'pymath.calculus.expression.Expression'> [3, 4, '+', 5, '+'] >, 6]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [3, < <class 'pymath.calculus.expression.Expression'> [7, 5, '+'] >, 6]>]
2015-04-03 14:07:07 +00:00
"""
2016-02-13 03:29:26 +00:00
2016-02-13 04:04:08 +00:00
# TODO: It doesn't not compute quick enough |ven. févr. 27 18:04:01 CET
# 2015
2015-04-03 14:07:07 +00:00
# gather steps for every coefficients
2015-04-03 14:07:07 +00:00
coefs_steps = []
for coef in self._coef:
coef_steps = []
2016-02-13 04:04:08 +00:00
if isinstance(coef, list):
# Simplify each element before adding them
s = []
for c in coef:
try:
with Expression.tmp_render():
s.append(list(c.simplify().explain()))
except AttributeError:
s.append([c])
2015-04-03 14:07:07 +00:00
s = list(transpose_fill(s))
last = s[-1]
coef_steps += s
2015-04-03 14:07:07 +00:00
# Convert last element into postfix addition.
2016-02-13 04:04:08 +00:00
postfix_add = self.postfix_add([i for i in last if i != 0])
# Convert it to an expression
coef_exp = Expression(postfix_add)
2015-04-03 14:07:07 +00:00
with Expression.tmp_render():
coef_steps += list(coef_exp.simplify().explain())
2015-04-03 14:07:07 +00:00
#print('\t 1.coef_steps -> ', coef_steps)
2015-04-03 14:07:07 +00:00
else:
try:
with Expression.tmp_render():
coef_steps += coef.simplify().explain()
except AttributeError:
coef_steps = [coef]
#print('\t 3.coef_steps -> ', coef_steps)
# On ajoute toutes ces étapes
coefs_steps.append(coef_steps)
#print('\t coefs_steps -> ', coefs_steps)
# On retourne la matrice
steps = []
for coefs in transpose_fill(coefs_steps):
steps.append(AbstractPolynom(coefs, self._letter))
ans, steps = steps[-1], steps[:-1]
ans.steps = steps
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
return ans
def simplify(self):
"""Same as reduce """
return self.reduce()
@staticmethod
def postfix_add(numbers):
"""Convert a list of numbers into a postfix addition
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
:numbers: list of numbers
:returns: Postfix list of succecive attition of number
>>> AbstractPolynom.postfix_add([1])
[1]
>>> AbstractPolynom.postfix_add([1, 2])
[1, 2, '+']
>>> AbstractPolynom.postfix_add([1, 2, 3])
[1, 2, '+', 3, '+']
>>> AbstractPolynom.postfix_add(1)
[1]
>>> AbstractPolynom.postfix_add([])
[0]
"""
2016-02-13 04:04:08 +00:00
if not isinstance(numbers, list):
2015-04-03 14:07:07 +00:00
return [numbers]
elif numbers == []:
return [0]
else:
2016-02-13 04:04:08 +00:00
ans = [[a, op.add] if i != 0 else [a]
for (i, a) in enumerate(numbers)]
2015-04-03 14:07:07 +00:00
return list(chain.from_iterable(ans))
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
def __eq__(self, other):
try:
o_poly = self.conv2poly(other)
return self._coef == o_poly._coef
except TypeError:
return 0
def __add__(self, other):
2016-02-13 03:29:26 +00:00
""" Overload +
2015-04-03 14:07:07 +00:00
>>> P = AbstractPolynom([1,2,3])
>>> Q = AbstractPolynom([4,5])
>>> R = P+Q
>>> R
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [5, 7, 3]>
>>> for i in R.explain():
... print(i)
3 x^{ 2 } + 2 x + 1 + 5 x + 4
3 x^{ 2 } + 2 x + 5 x + 1 + 4
3 x^{ 2 } + ( 2 + 5 ) x + 1 + 4
3 x^{ 2 } + 7 x + 5
2015-04-03 14:07:07 +00:00
>>> R.steps
[< <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', 5, 'x', '*', 4, '+', '+'] >, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [[1, 4], [2, 5], 3]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [< <class 'pymath.calculus.expression.Expression'> [1, 4, '+'] >, < <class 'pymath.calculus.expression.Expression'> [2, 5, '+'] >, 3]>]
2015-04-03 14:07:07 +00:00
"""
o_poly = self.conv2poly(other)
n_coef = spe_zip(self._coef, o_poly._coef)
2016-02-13 04:04:08 +00:00
p = AbstractPolynom(n_coef, letter=self._letter)
2015-04-03 14:07:07 +00:00
2016-02-13 04:04:08 +00:00
ini_step = [Expression(self.postfix_tokens +
o_poly.postfix_tokens + [op.add])]
2015-04-03 14:07:07 +00:00
ans = p.simplify()
ans.steps = ini_step + ans.steps
return ans
def __radd__(self, other):
o_poly = self.conv2poly(other)
return o_poly.__add__(self)
def __neg__(self):
""" overload - (as arity 1 operator)
>>> P = AbstractPolynom([1,2,3])
>>> Q = -P
>>> Q
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [-1, -2, -3]>
2015-04-03 14:07:07 +00:00
>>> Q.steps
2016-01-07 16:34:23 +00:00
[< <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', '-'] >]
2015-04-03 14:07:07 +00:00
"""
ini_step = [Expression(self.postfix_tokens + [op.sub1])]
2016-02-13 04:04:08 +00:00
ans = AbstractPolynom([-i for i in self._coef],
letter=self._letter).simplify()
2015-04-03 14:07:07 +00:00
ans.steps = ini_step + ans.steps
return ans
def __sub__(self, other):
""" overload -
>>> P = AbstractPolynom([1,2,3])
>>> Q = AbstractPolynom([4,5,6])
>>> R = P - Q
>>> R
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [-3, -3, -3]>
2015-04-07 06:46:59 +00:00
>>> for i in R.explain():
... print(i)
3 x^{ 2 } + 2 x + 1 - ( 6 x^{ 2 } + 5 x + 4 )
3 x^{ 2 } + 2 x + 1 - 6 x^{ 2 } - 5 x - 4
3 x^{ 2 } - 6 x^{ 2 } + 2 x - 5 x + 1 - 4
2015-04-07 06:46:59 +00:00
( 3 - 6 ) x^{ 2 } + ( 2 - 5 ) x + 1 - 4
- 3 x^{ 2 } - 3 x - 3
>>> R.steps
[< <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', 6, 'x', 2, '^', '*', 5, 'x', '*', '+', 4, '+', '-'] >, < <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, 'x', '*', '+', 1, '+', 6, 'x', 2, '^', '*', '-', 5, 'x', '*', '-', 4, '-', '+'] >, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [[1, -4], [2, -5], [3, -6]]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [< <class 'pymath.calculus.expression.Expression'> [1, -4, '+'] >, < <class 'pymath.calculus.expression.Expression'> [2, -5, '+'] >, < <class 'pymath.calculus.expression.Expression'> [3, -6, '+'] >]>]
2015-04-03 14:07:07 +00:00
"""
o_poly = self.conv2poly(other)
2016-02-13 04:04:08 +00:00
ini_step = [Expression(self.postfix_tokens +
o_poly.postfix_tokens + [op.sub])]
2015-04-03 14:07:07 +00:00
o_poly = -o_poly
#ini_step += o_poly.steps
ans = self + o_poly
ans.steps = ini_step + ans.steps
return ans
def __rsub__(self, other):
o_poly = self.conv2poly(other)
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
return o_poly.__sub__(self)
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
def __mul__(self, other):
""" Overload *
>>> p = AbstractPolynom([1,2])
>>> p*3
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [3, 6]>
2015-04-03 14:07:07 +00:00
>>> (p*3).steps
2016-01-07 16:34:23 +00:00
[[< <class 'pymath.calculus.expression.Expression'> [2, 'x', '*', 1, '+', 3, '*'] >], < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [3, < <class 'pymath.calculus.expression.Expression'> [2, 3, '*'] >]>]
2015-04-03 14:07:07 +00:00
>>> q = AbstractPolynom([0,0,4])
>>> q*3
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 0, 12]>
2015-04-03 14:07:07 +00:00
>>> (q*3).steps
2016-01-07 16:34:23 +00:00
[[< <class 'pymath.calculus.expression.Expression'> [4, 'x', 2, '^', '*', 3, '*'] >], < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 0, < <class 'pymath.calculus.expression.Expression'> [4, 3, '*'] >]>]
2015-04-03 14:07:07 +00:00
>>> r = AbstractPolynom([0,1])
>>> r*3
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 3]>
2015-04-03 14:07:07 +00:00
>>> (r*3).steps
2016-01-07 16:34:23 +00:00
[[< <class 'pymath.calculus.expression.Expression'> ['x', 3, '*'] >]]
2015-04-03 14:07:07 +00:00
>>> p*q
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 0, 4, 8]>
2015-04-03 14:07:07 +00:00
>>> (p*q).steps
2016-01-07 16:34:23 +00:00
[[< <class 'pymath.calculus.expression.Expression'> [2, 'x', '*', 1, '+', 4, 'x', 2, '^', '*', '*'] >], < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 0, 4, < <class 'pymath.calculus.expression.Expression'> [2, 4, '*'] >]>]
2015-04-03 14:07:07 +00:00
>>> p*r
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 1, 2]>
2015-04-03 14:07:07 +00:00
>>> P = AbstractPolynom([1,2,3])
>>> Q = AbstractPolynom([4,5,6])
>>> P*Q
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [4, 13, 28, 27, 18]>
2015-04-03 14:07:07 +00:00
"""
o_poly = self.conv2poly(other)
2016-02-13 04:04:08 +00:00
coefs = [0] * (self.degree + o_poly.degree + 1)
for (i, a) in enumerate(self._coef):
for (j, b) in enumerate(o_poly._coef):
2015-04-03 14:07:07 +00:00
if a == 0 or b == 0:
elem = 0
2016-02-13 04:04:08 +00:00
elif a == 1:
2015-04-03 14:07:07 +00:00
elem = b
2016-02-13 04:04:08 +00:00
elif b == 1:
2015-04-03 14:07:07 +00:00
elem = a
else:
elem = Expression([a, b, op.mul])
2016-02-13 04:04:08 +00:00
if coefs[i + j] == 0:
coefs[i + j] = elem
2015-04-03 14:07:07 +00:00
elif elem != 0:
2016-02-13 04:04:08 +00:00
if isinstance(coefs[i + j], list):
coefs[i + j] += [elem]
2015-04-03 14:07:07 +00:00
else:
2016-02-13 04:04:08 +00:00
coefs[i + j] = [coefs[i + j], elem]
2015-04-03 14:07:07 +00:00
2016-02-13 04:04:08 +00:00
p = AbstractPolynom(coefs, letter=self._letter)
ini_step = [Expression(self.postfix_tokens +
o_poly.postfix_tokens + [op.mul])]
2015-04-03 14:07:07 +00:00
ans = p.simplify()
ans.steps = [ini_step] + ans.steps
return ans
def __rmul__(self, other):
o_poly = self.conv2poly(other)
return o_poly.__mul__(self)
2016-02-13 03:29:26 +00:00
2015-04-03 14:07:07 +00:00
@power_cache
def __pow__(self, power):
""" Overload **
>>> p = AbstractPolynom([0,0,3])
>>> p**2
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 0, 0, 0, 9]>
2015-04-03 14:07:07 +00:00
>>> (p**2).steps
2016-01-07 16:34:23 +00:00
[< <class 'pymath.calculus.expression.Expression'> [3, 'x', 2, '^', '*', 2, '^'] >, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 0, 0, 0, < <class 'pymath.calculus.expression.Expression'> [3, 2, '^'] >]>]
2015-04-03 14:07:07 +00:00
>>> p = AbstractPolynom([1,2])
>>> p**2
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [1, 4, 4]>
2015-04-03 14:07:07 +00:00
>>> (p**2).steps
[< <class 'pymath.calculus.expression.Expression'> [2, 'x', '*', 1, '+', 2, '^'] >, [< <class 'pymath.calculus.expression.Expression'> [2, 'x', '*', 1, '+', 2, 'x', '*', 1, '+', '*'] >], < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [1, [2, 2], < <class 'pymath.calculus.expression.Expression'> [2, 2, '*'] >]>, < <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [1, < <class 'pymath.calculus.expression.Expression'> [2, 2, '+'] >, 4]>]
2015-04-03 14:07:07 +00:00
>>> p = AbstractPolynom([0,0,1])
>>> p**3
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [0, 0, 0, 0, 0, 0, 1]>
2015-04-03 14:07:07 +00:00
>>> p = AbstractPolynom([1,2,3])
>>> p**2
2016-01-07 16:34:23 +00:00
< <class 'pymath.calculus.abstract_polynom.AbstractPolynom'> [1, 4, 10, 12, 9]>
2015-04-03 14:07:07 +00:00
"""
if not type(power):
2016-02-13 04:04:08 +00:00
raise ValueError(
"Can't raise {obj} to {pw} power".format(
obj=self.__class__, pw=str(power)))
2015-04-03 14:07:07 +00:00
ini_step = [Expression(self.postfix_tokens + [power, op.pw])]
if self.is_monom():
if self._coef[self.degree] == 1:
2016-02-13 04:04:08 +00:00
coefs = [0] * self.degree * power + [1]
p = AbstractPolynom(coefs, letter=self._letter)
2015-04-03 14:07:07 +00:00
ans = p
else:
2016-02-13 04:04:08 +00:00
coefs = [0] * self.degree * power + \
[Expression([self._coef[self.degree], power, op.pw])]
p = AbstractPolynom(coefs, letter=self._letter)
2015-04-03 14:07:07 +00:00
ans = p.simplify()
else:
if power == 2:
ans = self * self
else:
2016-02-13 04:04:08 +00:00
# TODO: faudrait changer ça c'est pas très sérieux |ven. févr.
# 27 22:08:00 CET 2015
raise AttributeError(
"__pw__ not implemented yet when power is greatter than 2")
2015-04-03 14:07:07 +00:00
ans.steps = ini_step + ans.steps
return ans
def __xor__(self, power):
return self.__pow__(power)
2015-04-21 16:10:14 +00:00
if __name__ == '__main__':
2016-02-13 04:04:08 +00:00
P = AbstractPolynom([[1, 2], [3, 4, 5], 6])
2015-04-21 16:10:14 +00:00
Q = P.reduce()
for i in Q.explain():
print(i)
#import doctest
2016-02-13 04:04:08 +00:00
# doctest.testmod()
2015-04-03 14:07:07 +00:00
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
2016-02-13 03:29:26 +00:00
# cursor: 16 del