Mapytex/pymath/polynom.py

204 lines
5.9 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# encoding: utf-8
2014-11-11 15:52:30 +00:00
from .expression import Expression
2014-11-11 20:00:45 +00:00
from .operator import op
2015-04-03 14:07:07 +00:00
from .generic import isNumerand
2014-12-19 16:17:25 +00:00
from .random_expression import RdExpression
2015-04-03 14:07:07 +00:00
from .abstract_polynom import AbstractPolynom
__all__ = ["Polynom"]
2015-04-03 14:07:07 +00:00
class Polynom(AbstractPolynom):
2015-04-03 14:07:07 +00:00
"""Polynom view as a function.
It can be initiate like a AbstractPolynom
# Put example
Randomly
# Put example
It can be evaluate
# Put example
And derivate
# Put example
2015-04-03 14:07:07 +00:00
"""
2014-12-19 16:17:25 +00:00
@classmethod
2015-03-08 17:51:53 +00:00
def random(self, coefs_form=[], conditions=[], letter = "x", degree = 0, name = "P"):
2014-12-19 16:17:25 +00:00
""" Create a random polynom from coefs_form and conditions
:param coefs_form: list of forms (one by coef) (ascending degree sorted)
:param conditions: condition on variables
2015-02-21 10:01:34 +00:00
:param letter: the letter for the polynom
:param degree: degree of the polynom (can't be used with coefs_form, it will be overwrite) - can't be higher than 26 (number of letters in alphabet)
2014-12-19 16:17:25 +00:00
/!\ variables need to be in brackets {}
2015-02-21 10:01:34 +00:00
>>> Polynom.random(["{b}", "{a}"]) # doctest:+ELLIPSIS
< Polynom ...
2015-02-21 10:01:34 +00:00
>>> Polynom.random(degree = 2) # doctest:+ELLIPSIS
< Polynom ...
2015-02-21 10:01:34 +00:00
>>> Polynom.random(degree = 2, conditions=["{b**2-4*a*c}>0"]) # Polynom deg 2 with positive Delta (ax^2 + bx + c)
< Polynom ...
2015-02-21 10:01:34 +00:00
>>> Polynom.random(["{c}", "{b}", "{a}"], conditions=["{b**2-4*a*c}>0"]) # Same as above
< Polynom ...
2015-02-21 10:01:34 +00:00
2014-12-19 16:17:25 +00:00
"""
2015-02-21 10:01:34 +00:00
if (degree > 0 and degree < 26):
# Générer assez de lettre pour les coefs
coefs_name = map(chr, range(97, 98+degree))
2015-02-27 21:26:53 +00:00
coefs_form = ["{" + i + "}" for i in coefs_name][::-1]
2015-02-21 10:01:34 +00:00
2014-12-19 16:17:25 +00:00
form = str(coefs_form)
2015-02-21 10:01:34 +00:00
# On créé les valeurs toutes concaténées dans un string
2014-12-19 16:17:25 +00:00
coefs = RdExpression(form, conditions)()
2015-02-21 10:01:34 +00:00
# On "parse" ce string pour créer les coefs
2014-12-19 16:29:12 +00:00
coefs = [eval(i) if type(i)==str else i for i in eval(coefs)]
2015-02-21 10:01:34 +00:00
# Création du polynom
2015-03-08 17:56:59 +00:00
return Polynom(coefs = coefs, letter = letter, name = name)
2014-12-19 16:17:25 +00:00
2015-03-08 17:56:59 +00:00
def __init__(self, coefs = [1], letter = "x", name = "P"):
"""Initiate the polynom
2014-11-11 15:52:30 +00:00
: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
2015-03-08 17:51:53 +00:00
:param name: Name of the polynom
2015-03-08 17:51:53 +00:00
>>> P = Polynom([1, 2, 3])
>>> P.mainOp
2014-11-11 20:00:45 +00:00
'+'
2015-03-08 17:51:53 +00:00
>>> P.name
'P'
>>> P._letter
'x'
2014-11-11 20:00:45 +00:00
>>> Polynom([1]).mainOp
'*'
2015-03-07 17:22:46 +00:00
>>> Polynom([0, 0, 3]).mainOp
'*'
>>> Polynom([1, 2, 3])._letter
2014-11-11 20:00:45 +00:00
'x'
>>> Polynom([1, 2, 3], "y")._letter
'y'
2015-03-08 17:51:53 +00:00
>>> Polynom([1, 2, 3], name = "Q").name
'Q'
"""
2015-04-03 14:07:07 +00:00
super(Polynom, self).__init__(coefs, letter, name)
2014-11-11 15:52:30 +00:00
def __call__(self, value):
""" Evaluate the polynom in value
:returns: Expression ready to be simplify
>>> P = Polynom([1, 2, 3])
>>> P(2)
17
>>> for i in P(2).explain():
... print(i)
3 \\times 2^{ 2 } + 2 \\times 2 + 1
3 \\times 4 + 4 + 1
12 + 4 + 1
16 + 1
17
>>> Q = P("1+h")
>>> print(Q)
3 h^{ 2 } + 8 h + 6
>>> R = P(Q)
"""
if isNumerand(value) or Expression.isExpression(value):
2015-02-27 17:04:50 +00:00
postfix_exp = [value if i==self._letter else i for i in self.postfix_tokens]
else:
2015-02-27 17:04:50 +00:00
postfix_exp = [Expression(value) if i==self._letter else i for i in self.postfix_tokens]
return Expression(postfix_exp).simplify()
2015-03-06 16:00:09 +00:00
def derivate(self):
""" Return the derivated polynom
>>> P = Polynom([1, 2, 3])
>>> Q = P.derivate()
>>> Q
< Polynom [2, 6]>
2015-03-08 17:51:53 +00:00
>>> print(Q.name)
P'
2015-03-06 16:00:09 +00:00
>>> for i in Q.explain():
... print(i)
2 \\times 3 x + 1 \\times 2
6 x + 2
"""
derv_coefs = []
for (i,c) in enumerate(self._coef):
derv_coefs += [Expression([i, c, op.mul])]
2015-03-08 17:51:53 +00:00
ans = Polynom(derv_coefs[1:]).simplify()
ans.name = self.name + "'"
return ans
2015-03-06 16:00:09 +00:00
def test(p,q):
print("---------------------")
print("---------------------")
print("p : ",p)
print("q : ",q)
print("\n Plus ------")
print(p, "+", q)
for i in (p + q):
#print(repr(i))
2015-02-27 17:04:50 +00:00
#print("\t", str(i.postfix_tokens))
print(i)
print("\n Moins ------")
for i in (p - q):
#print(repr(i))
2015-02-27 17:04:50 +00:00
#print("\t", str(i.postfix_tokens))
print(i)
print("\n Multiplier ------")
for i in (p * q):
#print(repr(i))
2015-02-27 17:04:50 +00:00
#print("\t", str(i.postfix_tokens))
print(i)
print("\n Evaluer p ------")
for i in p(3).simplify():
print(i)
print("\n Evaluer q ------")
for i in q(3).simplify():
print(i)
if __name__ == '__main__':
2014-12-22 13:20:56 +00:00
#from .fraction import Fraction
#with Expression.tmp_render(txt):
# p = Polynom([1, 2, 3])
# q = Polynom([4, 5, 6])
# for i in (p*q).explain():
# print(i)
2015-02-27 21:26:53 +00:00
# r = Polynom([0,1])
# for i in (r*3).explain():
# print(i)
# print("q = ", q)
# r = q.reduce()
# print("r = ", r)
# for i in r.explain():
# print("q = ", i)
# print(p-q)
# for i in p-q:
# print(i)
#Polynom.random(degree = 2, conditions=["{b**2-4*a*c}>0"]) # Polynom deg 2 with positive Delta (ax^2 + bx + c)
2015-02-27 17:04:50 +00:00
import doctest
2015-02-27 21:26:53 +00:00
doctest.testmod(optionflags=doctest.ELLIPSIS)
2014-11-11 20:00:45 +00:00
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del