Mapytex/mapytex/calculus/API/tokens/polynomial.py

134 lines
3.1 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.
"""
Tokens representing polynomials functions
"""
from ..expression import Expression
from functools import partial
from .token import Token
from ...core.MO import MO
from ...core.MO.atoms import moify
__all__ = ["Polynomial", "Quadratic", "Linear"]
class Polynomial(Token):
""" Token representing a polynomial
:examples:
>>> from ...core.MO.polynomial import MOpolynomial
>>> P = Polynomial(MOpolynomial('x', [1, 2, 3]))
>>> P
<Polynomial 3x^2 + 2x + 1>
"""
def __init__(self, a, name="", ancestor=None):
if not isinstance(a, MO):
if isinstance(a, str):
raise TypeError
else:
raise TypeError
else:
mo = a
Token.__init__(self, mo, name, ancestor)
self._mathtype = "polynome"
@classmethod
def from_mo(cls, mo, name="", ancestor=None):
return cls(mo, name, ancestor)
@classmethod
def random(cls):
raise NotImplemented
def __setitem__(self, key, item):
""" Use Polynomial like if they were a dictionnary to set coefficients """
pass
def __getitem__(self, key):
""" Use Polynomial like if they were a dictionnary to get coefficients """
pass
def __call__(self, value):
""" Call a Polynomial to evaluate itself on value
:examples:
>>> from ...core.MO.polynomial import MOpolynomial
>>> P = Polynomial(MOpolynomial('x', [1, 2, 3]))
>>> for s in P(2).explain():
... print(s)
3 * 2^2 + 2 * 2 + 1
3 * 4 + 4 + 1
12 + 5
17
"""
tree = self._mo.tree
variable = (set(tree.get_leafs(extract_variable)) - {None}).pop()
dest = moify(value)
replace_var = partial(replace, origin=variable, dest=dest)
tree = tree.map_on_leaf(replace_var)
return Expression(tree).simplify()
class Linear(Polynomial):
""" Token representing a linear """
def __init__(self, mo, name="", ancestor=None):
Polynomial.__init__(self, mo, name, ancestor)
self._mathtype = "affine"
@classmethod
def random(cls):
raise NotImplemented
class Quadratic(Polynomial):
""" Token representing a quadratic """
def __init__(self, mo, name="", ancestor=None):
Polynomial.__init__(self, mo, name, ancestor)
self._mathtype = "polynome du 2nd degré"
@classmethod
def random(cls):
raise NotImplemented
def extract_variable(leaf):
try:
return leaf.variable
except AttributeError:
return None
def replace(leaf, origin, dest):
""" Recursively replace origin to dest in leaf """
try:
leaf.tree
except AttributeError:
if leaf == origin:
return dest
return leaf
replace_var = partial(replace, origin=origin, dest=dest)
return leaf.tree.map_on_leaf(replace_var)
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del