2018-11-12 08:41:39 +00:00
|
|
|
#! /usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vim:fenc=utf-8
|
|
|
|
#
|
|
|
|
# Copyright © 2017 lafrite <lafrite@Poivre>
|
|
|
|
#
|
|
|
|
# Distributed under terms of the MIT license.
|
|
|
|
|
2019-10-30 20:12:58 +00:00
|
|
|
from collections import OrderedDict
|
2018-11-12 08:41:39 +00:00
|
|
|
from mapytex.calculus.core.tree import Tree
|
2018-12-21 10:26:37 +00:00
|
|
|
from . import MO, MOstr
|
|
|
|
from .mo import Molecule
|
2018-11-12 08:41:39 +00:00
|
|
|
from .exceptions import MOError
|
2018-12-21 10:26:37 +00:00
|
|
|
from .monomial import MOMonomial, MOstrPower
|
2018-11-12 08:41:39 +00:00
|
|
|
|
|
|
|
__all__ = ["MOpolynomial"]
|
|
|
|
|
2019-05-14 04:55:56 +00:00
|
|
|
|
2018-12-21 10:26:37 +00:00
|
|
|
class MOpolynomial(Molecule):
|
2018-11-12 08:41:39 +00:00
|
|
|
|
2021-10-20 13:31:14 +00:00
|
|
|
""" MO polynomial: ax^n + ... + z (can't be a monomial)"""
|
2018-11-12 08:41:39 +00:00
|
|
|
|
2018-12-21 10:26:37 +00:00
|
|
|
MAINOP = "+"
|
|
|
|
|
2018-11-12 08:41:39 +00:00
|
|
|
def __init__(self, variable, coefs):
|
|
|
|
""" Initiate a MOpolynomial
|
|
|
|
|
|
|
|
:param variable: variable of the monomial (a MOstr or later a MOSqrt)
|
|
|
|
:param coefs: dictionnary {deg: coef} or a list [coef0, coef1...]
|
|
|
|
|
|
|
|
:example:
|
|
|
|
>>> MOpolynomial('x', [1, 2, 3])
|
2018-11-13 09:58:32 +00:00
|
|
|
<MOpolynomial 3x^2 + 2x + 1>
|
2018-11-12 08:41:39 +00:00
|
|
|
>>> MOpolynomial('x', [1, 0, 3])
|
2018-11-13 09:58:32 +00:00
|
|
|
<MOpolynomial 3x^2 + 1>
|
2018-11-12 08:41:39 +00:00
|
|
|
>>> MOpolynomial('x', {0: 1, 1: 2, 2: 3})
|
2018-11-13 09:58:32 +00:00
|
|
|
<MOpolynomial 3x^2 + 2x + 1>
|
2018-11-12 08:41:39 +00:00
|
|
|
>>> MOpolynomial('x', {0: 1, 3: 4})
|
2018-11-13 09:58:32 +00:00
|
|
|
<MOpolynomial 4x^3 + 1>
|
2018-11-13 10:40:21 +00:00
|
|
|
>>> MOpolynomial('x', {0: 1, 3: 1})
|
|
|
|
<MOpolynomial x^3 + 1>
|
2021-10-20 13:31:14 +00:00
|
|
|
>>> MOpolynomial('x', [0, 0, 3])
|
|
|
|
Traceback (most recent call last):
|
|
|
|
...
|
|
|
|
TypeError: A MOpolynomial can't be monomial it has to have more than one coefficient.
|
|
|
|
>>> MOpolynomial('x', {3: 1})
|
|
|
|
Traceback (most recent call last):
|
|
|
|
...
|
|
|
|
TypeError: A MOpolynomial can't be monomial it has to have more than one coefficient.
|
2018-11-12 08:41:39 +00:00
|
|
|
|
|
|
|
"""
|
|
|
|
_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 isinstance(coefs, dict):
|
2019-05-14 04:55:56 +00:00
|
|
|
_coefs = {
|
|
|
|
MO.factory(d): MO.factory(c) for (d, c) in coefs.items() if c != 0
|
|
|
|
}
|
2018-11-12 08:41:39 +00:00
|
|
|
elif isinstance(coefs, list):
|
2019-05-14 04:55:56 +00:00
|
|
|
_coefs = {
|
|
|
|
MO.factory(d): MO.factory(c) for (d, c) in enumerate(coefs) if c != 0
|
|
|
|
}
|
2018-11-12 08:41:39 +00:00
|
|
|
else:
|
|
|
|
raise TypeError("Coefs needs to be a dictionnary or a list")
|
|
|
|
self._coefs = _coefs
|
|
|
|
|
2021-10-20 13:31:14 +00:00
|
|
|
if len(self._coefs) == 1:
|
|
|
|
raise TypeError("A MOpolynomial can't be monomial it has to have more than one coefficient.")
|
|
|
|
|
2019-10-30 20:12:58 +00:00
|
|
|
monomials = OrderedDict()
|
|
|
|
for deg in sorted(self._coefs.keys()):
|
|
|
|
coef = self._coefs[deg]
|
2018-11-12 08:41:39 +00:00
|
|
|
if deg == 0:
|
2018-11-13 15:19:02 +00:00
|
|
|
monomials[deg] = coef
|
2018-12-21 10:26:37 +00:00
|
|
|
elif deg == 1 and coef == 1:
|
|
|
|
monomials[deg] = MOstr(self._variable)
|
|
|
|
elif coef == 1:
|
|
|
|
monomials[deg] = MOstrPower(self._variable, deg)
|
2018-11-13 09:58:32 +00:00
|
|
|
else:
|
2018-11-13 15:19:02 +00:00
|
|
|
monomials[deg] = MOMonomial(coef, self._variable, deg)
|
2018-11-13 09:58:32 +00:00
|
|
|
|
2018-11-13 15:19:02 +00:00
|
|
|
self._monomials = monomials
|
|
|
|
|
|
|
|
tree = Tree.from_list("+", list(self._monomials.values())[::-1])
|
2018-12-21 10:26:37 +00:00
|
|
|
Molecule.__init__(self, tree)
|
2018-11-12 08:41:39 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def variable(self):
|
|
|
|
return self._variable
|
|
|
|
|
|
|
|
@property
|
|
|
|
def degree(self):
|
2018-12-07 09:47:00 +00:00
|
|
|
"""
|
|
|
|
Maximum degree of its coefficient
|
2018-12-07 09:43:41 +00:00
|
|
|
|
|
|
|
:example:
|
|
|
|
>>> p = MOpolynomial('x', [1, 2, 3])
|
|
|
|
>>> p.degree
|
2018-12-07 14:29:34 +00:00
|
|
|
2
|
2018-12-07 09:43:41 +00:00
|
|
|
>>> p = MOpolynomial('x', {0: 1, 3: 4})
|
|
|
|
>>> p.degree
|
2018-12-07 14:29:34 +00:00
|
|
|
3
|
2018-12-07 09:43:41 +00:00
|
|
|
|
|
|
|
"""
|
2018-12-07 14:29:34 +00:00
|
|
|
return self.power.value
|
2018-11-12 08:41:39 +00:00
|
|
|
|
2018-12-07 09:47:00 +00:00
|
|
|
@property
|
|
|
|
def power(self):
|
2018-12-07 14:29:34 +00:00
|
|
|
"""
|
|
|
|
Maximum degree of its coefficient
|
|
|
|
|
|
|
|
:example:
|
|
|
|
>>> p = MOpolynomial('x', [1, 2, 3])
|
|
|
|
>>> p.power
|
|
|
|
<MOnumber 2>
|
|
|
|
>>> p = MOpolynomial('x', {0: 1, 3: 4})
|
|
|
|
>>> p.power
|
|
|
|
<MOnumber 3>
|
|
|
|
|
|
|
|
"""
|
|
|
|
return max(self._coefs.keys())
|
2018-12-07 09:47:00 +00:00
|
|
|
|
2018-11-13 13:42:40 +00:00
|
|
|
@property
|
|
|
|
def coefficients(self):
|
|
|
|
return self._coefs
|
|
|
|
|
2018-11-13 15:19:02 +00:00
|
|
|
@property
|
|
|
|
def monomials(self):
|
2018-11-23 10:53:10 +00:00
|
|
|
""" Return dictionnary with degree in keys and monomial in value
|
|
|
|
|
|
|
|
:example:
|
|
|
|
>>> p = MOpolynomial('x', [1, 2, 3])
|
|
|
|
>>> p.monomials
|
2019-10-30 20:12:58 +00:00
|
|
|
OrderedDict([(<MOnumber 0>, <MOnumber 1>), (<MOnumber 1>, <MOMonomial 2x>), (<MOnumber 2>, <MOMonomial 3x^2>)])
|
2018-11-23 10:53:10 +00:00
|
|
|
>>> p.monomials.values()
|
2019-10-30 20:12:58 +00:00
|
|
|
odict_values([<MOnumber 1>, <MOMonomial 2x>, <MOMonomial 3x^2>])
|
2018-11-23 10:53:10 +00:00
|
|
|
"""
|
2018-11-13 15:19:02 +00:00
|
|
|
return self._monomials
|
|
|
|
|
2019-07-15 15:48:59 +00:00
|
|
|
def differentiate(self):
|
|
|
|
""" Differentiate a MOMonomial and get a tree
|
|
|
|
|
|
|
|
:example:
|
|
|
|
>>> p = MOpolynomial('x', [1, 2, 3])
|
|
|
|
>>> print(p)
|
|
|
|
3x^2 + 2x + 1
|
|
|
|
>>> print(p.differentiate())
|
|
|
|
+
|
|
|
|
> 0
|
|
|
|
> +
|
|
|
|
| > 2
|
|
|
|
| > *
|
|
|
|
| | > 3
|
|
|
|
| | > *
|
|
|
|
| | | > 2
|
|
|
|
| | | > x
|
|
|
|
|
|
|
|
"""
|
|
|
|
monomials_d = [m.differentiate() for m in self.monomials.values()]
|
|
|
|
return Tree.from_list("+", monomials_d)
|
|
|
|
|
2018-11-12 08:41:39 +00:00
|
|
|
|
|
|
|
# -----------------------------
|
|
|
|
# Reglages pour 'vim'
|
|
|
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
|
|
|
# cursor: 16 del
|