Feat: Polynomial are displayed in nicer order!

This commit is contained in:
Bertrand Benjamin 2019-10-30 21:12:58 +01:00
parent e596c1af60
commit d72a2be175
7 changed files with 61 additions and 33 deletions

View File

@ -84,19 +84,20 @@ x^7
>>> e = Expression.from_str("1+2x^2+3x+4+5x")
>>> e_simplified = e.simplify()
>>> e_simplified
<Quadratic 5 + 2x^2 + 8x>
<Quadratic 2x^2 + 8x + 5>
>>> for s in e_simplified.explain():
... print(s)
1 + 2x^2 + 3x + 4 + 5x
1 + 2x^2 + 3x + 4 + 5x
1 + 4 + 2x^2 + 3x + 5x
5 + 2x^2 + (3 + 5) * x
5 + 2x^2 + 8x
2x^2 + 3x + 1 + 4 + 5x
2x^2 + 3x + 5x + 1 + 4
2x^2 + (3 + 5) * x + 5
2x^2 + 8x + 5
>>> e = Expression.from_str("(2x+3)^2")
>>> e_simplified = e.simplify()
>>> e_simplified
<Quadratic 12x + 4x^2 + 9>
<Quadratic 4x^2 + 12x + 9>
>>> for s in e_simplified.explain():
... print(s)
(2x + 3)^2
@ -105,7 +106,8 @@ x^7
2 * 2 * x^(1 + 1) + 3 * 2 * x + 3 * 2 * x + 9
6x + 6x + 4x^2 + 9
(6 + 6) * x + 4x^2 + 9
12x + 4x^2 + 9
4x^2 + 12x + 9
"""

View File

@ -104,7 +104,7 @@ class Expression(object):
<Linear 2x + 1>
>>> e = Expression.from_str("2x + 1 + 5x^2")
>>> e
<Quadratic 2x + 1 + 5x^2>
<Quadratic 5x^2 + 2x + 1>
>>> e = Expression.from_str("2x + 1 + 5x")
>>> e
<Exp: 2x + 1 + 5x>
@ -468,7 +468,7 @@ class Expression(object):
>>> f("u_n")
<Exp: 3u_n^2 + 2u_n + 1>
>>> f(f)
<Polynomial 36x^2 + 16x + 6 + 36x^3 + 27x^4>
<Polynomial 27x^4 + 36x^3 + 36x^2 + 16x + 6>
"""
tree = self._tree
variable = (set(tree.get_leafs(extract_variable)) - {None}).pop()

View File

@ -104,12 +104,12 @@ class Polynomial(Token):
>>> P
<Polynomial 3x^2 + 2x + 1>
>>> P.differentiate()
<Linear 2 + 6x>
<Linear 6x + 2>
>>> for s in P.differentiate().explain():
... print(s)
0 + 2 + 3 * 2x
2 + 3 * 2 * x
2 + 6x
6x + 2
"""
return Expression(self._mo.differentiate()).simplify()
@ -212,7 +212,7 @@ class Quadratic(Polynomial):
4 - 12
- 8
>>> P.differentiate()
<Linear 2 + 6x>
<Linear 6x + 2>
>>> P.roots
[]

View File

@ -174,7 +174,7 @@ class Token(object):
>>> a = Integer(3)
>>> c = a - "x"
>>> c
<Linear 3 - x>
<Linear - x + 3>
"""
return self._operate(other, "-")

View File

@ -6,6 +6,7 @@
#
# Distributed under terms of the MIT license.
from collections import OrderedDict
from mapytex.calculus.core.tree import Tree
from . import MO, MOstr
from .mo import Molecule
@ -57,8 +58,9 @@ class MOpolynomial(Molecule):
raise TypeError("Coefs needs to be a dictionnary or a list")
self._coefs = _coefs
monomials = {}
for deg, coef in self._coefs.items():
monomials = OrderedDict()
for deg in sorted(self._coefs.keys()):
coef = self._coefs[deg]
if deg == 0:
monomials[deg] = coef
elif deg == 1 and coef == 1:
@ -120,9 +122,9 @@ class MOpolynomial(Molecule):
:example:
>>> p = MOpolynomial('x', [1, 2, 3])
>>> p.monomials
{<MOnumber 0>: <MOnumber 1>, <MOnumber 1>: <MOMonomial 2x>, <MOnumber 2>: <MOMonomial 3x^2>}
OrderedDict([(<MOnumber 0>, <MOnumber 1>), (<MOnumber 1>, <MOMonomial 2x>), (<MOnumber 2>, <MOMonomial 3x^2>)])
>>> p.monomials.values()
dict_values([<MOnumber 1>, <MOMonomial 2x>, <MOMonomial 3x^2>])
odict_values([<MOnumber 1>, <MOMonomial 2x>, <MOMonomial 3x^2>])
"""
return self._monomials

View File

@ -77,13 +77,22 @@ class Tree:
> *
| > 3
| > n
>>> t = Tree.from_str("2+{n}*x", random=True)
>>> t = Tree.from_str("2+{n}x", random=True)
>>> print(t)
+
> 2
> *
| > {n}
| > x
>>> t = Tree.from_str("{a}({b}x+{c})", random=True)
>>> print(t)
*
> {a}
> +
| > *
| | > {b}
| | > x
| > {c}
"""
@ -954,7 +963,22 @@ class MutableTree(Tree):
| | > 8
| | > 3
| > x
>>> t = MutableTree.from_str("{b}*x+{c}", random=True)
>>> print(t)
+
> *
| > {b}
| > x
> {c}
>>> t = MutableTree.from_str("{a}*({b}*x+{c})", random=True)
>>> print(t)
*
> {a}
> +
| > *
| | > {b}
| | > x
| > {c}
"""
if random:
str_2_mut_tree = rdstr2(cls.sink)

View File

@ -95,10 +95,10 @@ def moscalar_momonomial(left, right):
>>> a = MOnumber(2)
>>> b = MOMonomial(3, 'x', 4)
>>> add(a, b)
<MOpolynomial 2 + 3x^4>
<MOpolynomial 3x^4 + 2>
>>> a = MOFraction(1, 5)
>>> add(a, b)
<MOpolynomial 1 / 5 + 3x^4>
<MOpolynomial 3x^4 + 1 / 5>
"""
return MOpolynomial(right.variable, {right.power: right.coefficient, 0: left})
@ -126,10 +126,10 @@ def moscalar_mopolynomial(left, right):
>>> a = MOnumber(2)
>>> b = MOpolynomial('x', [0, 2, 3])
>>> add(a, b)
<MOpolynomial 2 + 3x^2 + 2x>
<MOpolynomial 3x^2 + 2x + 2>
>>> a = MOFraction(1, 5)
>>> add(a, b)
<MOpolynomial 1 / 5 + 3x^2 + 2x>
<MOpolynomial 3x^2 + 2x + 1 / 5>
"""
if 0 in right.coefficients.keys():
raise NotImplementedError(
@ -237,7 +237,7 @@ def mostr_mopolynomial(left, right):
>>> a = MOstr("x")
>>> b = MOpolynomial('x', [1, 0, 3])
>>> add(a, b)
<MOpolynomial x + 3x^2 + 1>
<MOpolynomial 3x^2 + x + 1>
"""
if 1 in right.coefficients.keys():
raise NotImplementedError("Polynomial with no constant, calculus to do")
@ -255,7 +255,7 @@ def mopolynomial_mostr(left, right):
>>> a = MOpolynomial('x', [1, 0, 3])
>>> b = MOstr("x")
>>> add(a, b)
<MOpolynomial 3x^2 + 1 + x>
<MOpolynomial 3x^2 + x + 1>
"""
if 1 in left.coefficients.keys():
raise NotImplementedError("Polynomial with no constant, calculus to do")
@ -272,7 +272,7 @@ def mostrpower_mopolynomial(left, right):
>>> a = MOstrPower("x", 2)
>>> b = MOpolynomial('x', [1, 2, 0, 4])
>>> add(a, b)
<MOpolynomial x^2 + 4x^3 + 2x + 1>
<MOpolynomial 4x^3 + x^2 + 2x + 1>
"""
if left.power in right.coefficients.keys():
raise NotImplementedError("Degree in common, need to compute")
@ -290,7 +290,7 @@ def mopolynomial_mostrpower(left, right):
>>> a = MOpolynomial('x', [1, 2, 0, 4])
>>> b = MOstrPower("x", 2)
>>> add(a, b)
<MOpolynomial 4x^3 + 2x + 1 + x^2>
<MOpolynomial 4x^3 + x^2 + 2x + 1>
"""
if right.power in left.coefficients.keys():
raise NotImplementedError("Degree in common, need to compute")
@ -307,7 +307,7 @@ def momonomial_mopolynomial(left, right):
>>> a = MOMonomial(3, "x", 2)
>>> b = MOpolynomial('x', [1, 2, 0, 4])
>>> add(a, b)
<MOpolynomial 3x^2 + 4x^3 + 2x + 1>
<MOpolynomial 4x^3 + 3x^2 + 2x + 1>
"""
if left.power in right.coefficients.keys():
raise NotImplementedError("Degree in common, need to compute")
@ -325,7 +325,7 @@ def mopolynomial_momonomial(left, right):
>>> a = MOpolynomial('x', [1, 2, 0, 4])
>>> b = MOMonomial(3, "x", 2)
>>> add(a, b)
<MOpolynomial 4x^3 + 2x + 1 + 3x^2>
<MOpolynomial 4x^3 + 3x^2 + 2x + 1>
"""
if right.power in left.coefficients.keys():
raise NotImplementedError("Degree in common, need to compute")
@ -342,9 +342,9 @@ def mopolynomial_mopolynomial(left, right):
>>> a = MOpolynomial('x', [1, 0, 3])
>>> b = MOpolynomial('x', [0, 2, 0, 4])
>>> add(a, b)
<MOpolynomial 3x^2 + 1 + 4x^3 + 2x>
<MOpolynomial 4x^3 + 3x^2 + 2x + 1>
>>> add(b, a)
<MOpolynomial 4x^3 + 2x + 3x^2 + 1>
<MOpolynomial 4x^3 + 3x^2 + 2x + 1>
"""
common_degree = set(left.monomials.keys()).intersection(right.monomials.keys())
if common_degree:
@ -361,7 +361,7 @@ def mostr_monomial(left, right):
>>> a = MOstr('x')
>>> b = MOMonomial(3, 'x', 4)
>>> add(a, b)
<MOpolynomial x + 3x^4>
<MOpolynomial 3x^4 + x>
"""
if right.power == 1:
raise NotImplementedError("Monomial is deg 1, need to compute")
@ -391,7 +391,7 @@ def mostrpower_monomial(left, right):
>>> a = MOstrPower('x', 2)
>>> b = MOMonomial(3, 'x', 4)
>>> add(a, b)
<MOpolynomial x^2 + 3x^4>
<MOpolynomial 3x^4 + x^2>
"""
if left.power == right.power:
raise NotImplementedError(