#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2017 lafrite # # Distributed under terms of the MIT license. """ Multiply MO """ 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 .exceptions import MultiplyError from .filters import special_case multiply_doc = """ Multiply MOs :param left: left MO :param right: right MO :returns: Tree or MO """ multiply = Dispatcher("multiply", doc=multiply_doc) def multiply_filter(left, right): """ Automatic multiply on MO :param left: MO :param right: MO :returns: MO if it is a special case, nothing other wise >>> a = MOnumber(1) >>> b = MOFraction(1, 2) >>> multiply(a, b) >>> multiply(b, a) >>> a = MOnumber(0) >>> b = MOFraction(1, 2) >>> multiply(a, b) """ try: if left == 0: return left except TypeError: pass try: if right == 0: return right except TypeError: pass try: if left == 1: return right except TypeError: pass try: if right == 1: return left except TypeError: pass @multiply.register(MOnumber, MOnumber) @special_case(multiply_filter) def monumber_monumber(left, right): """ Simply multiply values >>> a = MOnumber(4) >>> b = MOnumber(6) >>> multiply(a, b) """ return MO.factory(left.value * right.value) @multiply.register(MOnumber, MOFraction) @special_case(multiply_filter) def monumber_mofraction(left, right): """ Return division Tree with on the numertor MOnumber times numerator of MOFraction >>> a = MOnumber(4) >>> b = MOFraction(6, 5) >>> print(multiply(a, b)) / > * | > 4 | > 6 > 5 >>> b = MOFraction(6, 5, True) >>> print(multiply(a, b)) / > * | > 4 | > - | | > None | | > 6 > 5 """ num = Tree("*", left, right.numerator) return Tree("/", num, right._denominator) @multiply.register(MOFraction, MOnumber) @special_case(multiply_filter) def mofraction_monumber(left, right): """ Return division Tree with on the numertor MOnumber times numerator of MOFraction >>> a = MOFraction(6, 5) >>> b = MOnumber(4) >>> print(multiply(a, b)) / > * | > 6 | > 4 > 5 """ num = Tree("*", left.numerator, right) return Tree("/", num, left._denominator) @multiply.register(MOFraction, MOFraction) @special_case(multiply_filter) def mofraction_mofraction(left, right): """ Multiply two mofractions (numertors together and denominators together) >>> a = MOFraction(1, 5) >>> b = MOFraction(4, 5) >>> print(multiply(a, b)) / > * | > 1 | > 4 > * | > 5 | > 5 """ num = Tree("*", left.numerator, right.numerator) denom = Tree("*", left.denominator, right.denominator) return Tree("/", num, denom) @multiply.register((MOnumber, MOFraction), MOstr) @special_case(multiply_filter) def moscalar_mostr(left, right): """ Multiply a scalar with a letter to create a MOMonomial >>> a = MOnumber(2) >>> b = MOstr('x') >>> multiply(a, b) >>> a = MOFraction(1, 5) >>> multiply(a, b) """ return MOMonomial(left, right) @multiply.register(MOstr, (MOnumber, MOFraction)) @special_case(multiply_filter) def mostr_moscalar(left, right): """ Multiply a scalar with a letter to create a MOMonomial >>> a = MOstr('x') >>> b = MOnumber(2) >>> multiply(a, b) >>> b = MOFraction(1, 5) >>> multiply(a, b) """ 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) # >>> print(multiply(a, b)) """ coefficient = Tree('*', left, right._coefficient) return Tree('*', coefficient, MOMonomial(1, right._variable, right._power)) # ----------------------------- # Reglages pour 'vim' # vim:set autoindent expandtab tabstop=4 shiftwidth=4: # cursor: 16 del