From f8e00a8638a2416e5f68ad011fe057ede90e2151 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Sun, 18 Mar 2018 10:34:46 +0300 Subject: [PATCH] Create MOstrPower and start adding it into multiply --- mapytex/calculus/core/MO/monomial.py | 170 ++++++++++++---------- mapytex/calculus/core/compute/multiply.py | 94 +++++++++++- 2 files changed, 182 insertions(+), 82 deletions(-) diff --git a/mapytex/calculus/core/MO/monomial.py b/mapytex/calculus/core/MO/monomial.py index 06322ed..1ae9126 100644 --- a/mapytex/calculus/core/MO/monomial.py +++ b/mapytex/calculus/core/MO/monomial.py @@ -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(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(4, "x", 1) + >>> x = MOstr('x') + >>> MOMonomial(4, x) - >>> MOMonomial(1, "x", 2) - - >>> MOMonomial(1, "x", 1) - - >>> 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(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' diff --git a/mapytex/calculus/core/compute/multiply.py b/mapytex/calculus/core/compute/multiply.py index 86612d9..f622695 100644 --- a/mapytex/calculus/core/compute/multiply.py +++ b/mapytex/calculus/core/compute/multiply.py @@ -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) + + >>> 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'