Create MOstrPower and start adding it into multiply

This commit is contained in:
Bertrand Benjamin 2018-03-18 10:34:46 +03:00
parent 3b59e0ffb0
commit f8e00a8638
2 changed files with 182 additions and 82 deletions

View File

@ -13,42 +13,83 @@ from ..renders import tree2txt, tree2tex
__all__ = ["MOMonomial"]
class MOstrPower(MO):
""" Power of a MOstr """
def __init__(self, variable, power):
""" Initiate a MOstrPower
:param variable: variable of the monomial (a MOstr or later a MOSqrt)
:param power: non negative interger (MOnumber type)
>>> MOstrPower("x", 2)
<MOstrPower x^2>
>>> MOstrPower(3, 1)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The variable of a monomial should be convertible into MOstr
>>> MOstrPower("x", 0)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The power of a MOstrPower should be greater than 1
>>> MOstrPower("x", 1)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The power of a MOstrPower should be greater than 1
>>> MOstrPower("x", -2)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The power of a MOstrPower should be greater than 1
>>> MOstrPower("x", 2.4)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The power of a monomial should be a integer
"""
_variable = MO.factory(variable)
if not isinstance(_variable, MOstr):
raise MOError("The variable of a monomial should be convertible into MOstr")
self._variable = _variable
_power = MO.factory(power)
if power <= 1:
raise MOError("The power of a MOstrPower should be greater than 1")
elif not isinstance(_power.value, int):
raise MOError("The power of a monomial should be a integer")
self._power = _power
value = Tree("^",
self._variable,
self._power
)
MO.__init__(self, value)
@property
def variable(self):
return self._variable
@property
def power(self):
return self._power
class MOMonomial(MO):
""" Monomial math object"""
def __init__(self, coefficient, variable, power = 1):
def __init__(self, coefficient, variable):
""" Initiate the MOMonomial
:param coefficient: coefficient of the monomial (a non zero constant)
:param variable: varaible of the monomial (a MOstr or later a MOSqrt)
:param power: non negative interger (MOnumber type)
:param variable: variable of the monomial (a MOstr or later a MOSqrt)
>>> MOMonomial(4, "x", 2)
<MOMonomial 4x^2>
>>> MOMonomial(4, "x", 1)
>>> x = MOstr('x')
>>> MOMonomial(4, x)
<MOMonomial 4x>
>>> MOMonomial(1, "x", 2)
<MOMonomial x^2>
>>> MOMonomial(1, "x", 1)
<MOMonomial x>
>>> MOMonomial(4, 3, 1)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The variable of a monomial should be convertible into MOstr
>>> MOMonomial(4, "x", 0)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The power of a monomial should be greater than 0
>>> MOMonomial(4, "x", -2)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The power of a monomial should be greater than 0
>>> MOMonomial(4, "x", 2.4)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The power of a monomial should be a integer
>>> MOMonomial(0, "x", 1)
>>> x = MOstrPower('x', 2)
>>> MOMonomial(4, x)
<MOMonomial 4x^2>
>>> MOMonomial(0, x)
Traceback (most recent call last):
...
mapytex.calculus.core.MO.exceptions.MOError: The coefficient of a monomial should not be 0
@ -58,64 +99,39 @@ class MOMonomial(MO):
raise MOError("The coefficient of a monomial should not be 0")
self._coefficient = _coefficient
_variable = MO.factory(variable)
if not isinstance(_variable, MOstr):
raise MOError("The variable of a monomial should be convertible into MOstr")
self._variable = _variable
if not isinstance(variable, (MOstr, MOstrPower)):
raise
self._variable = variable
_power = MO.factory(power)
if power <= 0:
raise MOError("The power of a monomial should be greater than 0")
elif not isinstance(_power.value, int):
raise MOError("The power of a monomial should be a integer")
self._power = _power
value = Tree("*",
self._coefficient,
self._variable
if self._power > 1:
self.value = Tree("*",
self._coefficient,
Tree("^",
self._variable,
self._power
)
)
else:
self.value = Tree("*",
self._coefficient,
self._variable,
)
@property
def __txt__(self):
try:
if self._coefficient == 1:
try:
return tree2txt(self.value.right_value)
except AttributeError:
return str(self.value.right_value)
except TypeError:
pass
try:
return tree2txt(self.value)
except AttributeError:
return str(self.value)
MO.__init__(self, value)
@property
def __tex__(self):
try:
if self._coefficient == 1:
try:
return tree2tex(self.value.right_value)
except AttributeError:
return str(self.value.right_value)
except TypeError:
pass
def coefficient(self):
return self._coefficient
try:
return tree2tex(self.value)
except AttributeError:
return str(self.value)
@property
def strpower(self):
if isinstance(self._variable, MOstr):
return self._variable
return self._variable
@property
def variable(self):
if isinstance(self._variable, MOstr):
return self._variable
return self._variable.variable
@property
def power(self):
if isinstance(self._variable, MOstr):
return 1
return self._variable.power
# -----------------------------
# Reglages pour 'vim'

View File

@ -14,7 +14,7 @@ from multipledispatch import Dispatcher
from ..tree import Tree
from ..MO.mo import MO, MOnumber, MOstr
from ..MO.fraction import MOFraction
from ..MO.monomial import MOMonomial
from ..MO.monomial import MOstrPower, MOMonomial
from .exceptions import MultiplyError
from .filters import special_case
@ -175,18 +175,102 @@ def mostr_moscalar(left, right):
"""
return MOMonomial(right, left)
@multiply.register((MOnumber, MOFraction), MOstrPower)
@special_case(multiply_filter)
def moscalar_mostrpower(left, right):
""" Multiply a scalar with a MOstrPower
>>> a = MOnumber(4)
>>> x = MOstrPower('x', 4)
>>> print(multiply(a, x))
*
> 4
> ^
| > x
| > 4
"""
return MOMonomial(left, right)
@multiply.register(MOstrPower, (MOnumber, MOFraction))
@special_case(multiply_filter)
def mostrpower_moscalar(left, right):
""" Multiply a MOstrPower with a scalar
>>> a = MOnumber(4)
>>> x = MOstrPower('x', 4)
>>> print(multiply(x, a))
*
> 4
> ^
| > x
| > 4
"""
return MOMonomial(right, left)
@multiply.register((MOnumber, MOFraction), MOMonomial)
@special_case(multiply_filter)
def moscalar_monomonial(left, right):
""" Multiply a scalar with a monomial
>>> a = MOnumber(4)
>>> b = MOMonomial(5, 'x', 3)
>>> x = MOstrPower('x', 4)
>>> b = MOMonomial(5, x)
>>> print(multiply(a, b))
*
> *
| > 4
| > 5
> ^
| > x
| > 4
# >>> print(multiply(a, b))
"""
coefficient = Tree('*', left, right._coefficient)
return Tree('*', coefficient, MOMonomial(1, right._variable, right._power))
coefficient = Tree('*', left, right.coefficient)
return Tree('*', coefficient, right.strpower)
@multiply.register(MOMonomial, (MOnumber, MOFraction))
@special_case(multiply_filter)
def monomonial_moscalar(left, right):
""" Multiply a momonial with a scalar
>>> x = MOstrPower('x', 4)
>>> a = MOMonomial(5, x)
>>> b = MOnumber(4)
>>> print(multiply(a, b))
*
> *
| > 4
| > 5
> ^
| > x
| > 4
"""
coefficient = Tree('*', right, left.coefficient)
return Tree('*', coefficient, left.strpower)
@multiply.register(MOstr, MOstrPower)
@special_case(multiply_filter)
def mostr_mostrpower(left, right):
""" Multiply a MOstr and a MOstrPower
>>> a = MOstr('x')
>>> b = MOstrPower('x', 4)
>>> multiply(a, b)
<MOstrPower x^5>
>>> a = MOstr('x')
>>> b = MOstrPower('y', 4)
>>> multiply(a, b)
Traceback (most recent call last):
...
mapytex.calculus.core.compute.exceptions.MultiplyError: Can't multiply MOstr and MOstrPower if they don'thave same variable (got x and y)
"""
if left.variable != right.variable:
raise MultiplyError("Can't multiply MOstr and MOstrPower if they don't"
f"have same variable (got {left.variable} and {right.variable})")
return MOstrPower(left.variable, right.power+1)
# -----------------------------
# Reglages pour 'vim'