Mapytex/mapytex/calculus/core/compute/add.py

179 lines
3.8 KiB
Python

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2017 lafrite <lafrite@Poivre>
#
# Distributed under terms of the MIT license.
"""
Adding MO
"""
from ..tree import Tree
from ..MO.mo import MO, MOnumber
from ..MO.fraction import MOFraction
from .exceptions import AddError
from .arithmetic import lcm
from .type_filter import args_are
from multipledispatch import Dispatcher
add_doc = """ Adding MOs
:param left: left MO
:param right: right MO
:return: Tree or MO
"""
add = Dispatcher("add", doc=add_doc)
@add.register(MOnumber, MOnumber)
def monumber_monumber(left, right):
""" Simply add MO value
>>> a = MOnumber(4)
>>> b = MOnumber(6)
>>> add(a, b)
<MOnumber 10>
"""
return MO.factory(left.value + right.value)
@add.register(MOnumber, MOFraction)
def monumber_mofraction(left, right):
""" Return a tree with the MOnumber transformed into a MOFraction
>>> a = MOnumber(4)
>>> b = MOFraction(6, 5)
>>> print(add(a, b))
+
> /
| > 4
| > 1
> /
| > 6
| > 5
"""
left_fraction = MOFraction(left, MOnumber(1))
return Tree("+", left_fraction, right)
@add.register(MOFraction, MOnumber)
def mofraction_monumber(left, right):
""" Return a tree with the MOnumber transformed into a MOFraction
>>> a = MOFraction(6, 5)
>>> b = MOnumber(4)
>>> print(add(a, b))
+
> /
| > 6
| > 5
> /
| > 4
| > 1
"""
right_fraction = MOFraction(right, MOnumber(1))
return Tree("+", left, right_fraction)
@add.register(MOFraction, MOFraction)
def mofraction_mofraction(left, right):
""" 3 differents cases:
Fractions have same denomintor -> add numerator Tree
>>> a = MOFraction(1, 5)
>>> b = MOFraction(4, 5)
>>> print(add(a, b))
/
> +
| > 1
| > 4
> 5
>>> a = MOFraction(1, 5, True)
>>> b = MOFraction(4, 5)
>>> print(mofraction_mofraction(a, b))
/
> +
| > -
| | > None
| | > 1
| > 4
> 5
>>> a = MOFraction(1, 5)
>>> b = MOFraction(4, 5, True)
>>> print(mofraction_mofraction(a, b))
/
> +
| > 1
| > -
| | > None
| | > 4
> 5
A denominator is a multiple of the other
>>> a = MOFraction(1, 2)
>>> b = MOFraction(1, 4)
>>> print(mofraction_mofraction(a, b))
+
> /
| > *
| | > 1
| | > 2
| > *
| | > 2
| | > 2
> /
| > 1
| > 4
Denominators are coprime
>>> a = MOFraction(1, 2)
>>> b = MOFraction(1, 5)
>>> print(mofraction_mofraction(a, b))
+
> /
| > *
| | > 1
| | > 5
| > *
| | > 2
| | > 5
> /
| > *
| | > 1
| | > 2
| > *
| | > 5
| | > 2
"""
if left.denominator == right.denominator:
num = Tree("+", left.numerator, right.numerator)
return Tree("/", num, left.denominator)
denom_lcm = lcm(left.denominator, right.denominator)
if left.denominator == denom_lcm:
left_frac = left
else:
multiply_by = denom_lcm // left.denominator
left_num = Tree("*", left.numerator, MO.factory(multiply_by))
left_denom = Tree("*", left.denominator, MO.factory(multiply_by))
left_frac = Tree("/", left_num, left_denom)
if right.denominator == denom_lcm:
right_frac = right
else:
multiply_by = denom_lcm // right.denominator
right_num = Tree("*", right.numerator, MO.factory(multiply_by))
right_denom = Tree("*", right.denominator, MO.factory(multiply_by))
right_frac = Tree("/", right_num, right_denom)
return Tree("+", left_frac, right_frac)
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del