Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
"""Useful utilities for higher level polynomial classes. """
from __future__ import print_function, division
from sympy.polys.polyerrors import PolynomialError, GeneratorsNeeded, GeneratorsError from sympy.polys.polyoptions import build_options
from sympy.core.exprtools import decompose_power, decompose_power_rat
from sympy.core import S, Add, Mul, Pow, expand_mul, expand_multinomial
from sympy.core.compatibility import range
import re
_gens_order = { 'a': 301, 'b': 302, 'c': 303, 'd': 304, 'e': 305, 'f': 306, 'g': 307, 'h': 308, 'i': 309, 'j': 310, 'k': 311, 'l': 312, 'm': 313, 'n': 314, 'o': 315, 'p': 216, 'q': 217, 'r': 218, 's': 219, 't': 220, 'u': 221, 'v': 222, 'w': 223, 'x': 124, 'y': 125, 'z': 126, }
_max_order = 1000 _re_gen = re.compile(r"^(.+?)(\d*)$")
def _nsort(roots, separated=False): """Sort the numerical roots putting the real roots first, then sorting according to real and imaginary parts. If ``separated`` is True, then the real and imaginary roots will be returned in two lists, respectively.
This routine tries to avoid issue 6137 by separating the roots into real and imaginary parts before evaluation. In addition, the sorting will raise an error if any computation cannot be done with precision. """ raise NotImplementedError # see issue 6137: # get the real part of the evaluated real and imaginary parts of each root # make sure the parts were computed with precision raise NotImplementedError("could not compute root with precision") # insert a key to indicate if the root has an imaginary part # return the real and imaginary roots separately if desired i.append(v) else: _, roots = zip(*key) return list(roots)
def _sort_gens(gens, **args): """Sort generators in a reasonably intelligent way. """
gens_order[gen] = i + 1
try: return (-len(wrt) + wrt.index(gen), gen, 0) except ValueError: pass
else:
except TypeError: # pragma: no cover pass
def _unify_gens(f_gens, g_gens): """Unify generators in a reasonably intelligent way. """
common.append(gen)
g_gens[i], k = common[k], k + 1
i = f_gens.index(gen)
gens.extend(f_gens[:i]) f_gens = f_gens[i + 1:]
i = g_gens.index(gen)
gens.extend(g_gens[:i]) g_gens = g_gens[i + 1:]
gens.append(gen)
def _analyze_gens(gens): """Support for passing generators as `*gens` and `[gens]`. """ if len(gens) == 1 and hasattr(gens[0], '__iter__'): return tuple(gens[0]) else: return tuple(gens)
def _sort_factors(factors, **args): """Sort low-level factors in increasing 'complexity' order. """
else:
def _not_a_coeff(expr): """Do not treat NaN and infinities as valid polynomial coefficients. """
def _parallel_dict_from_expr_if_gens(exprs, opt): """Transform expressions into a multinomial form given generators. """
expr = expr.lhs - expr.rhs
else:
exp, base = -exp, Pow(base, -S.One) else: base, exp = decompose_power_rat(factor)
else:
else:
def _parallel_dict_from_expr_no_gens(exprs, opt): """Transform expressions into a multinomial form and figure out generators. """ def _is_coeff(factor): return factor.is_algebraic else:
expr = expr.lhs - expr.rhs
else:
else: base, exp = decompose_power_rat(factor)
arg = exprs[0] else:
poly[monom] += Mul(*coeff) else:
def _dict_from_expr_if_gens(expr, opt): """Transform an expression into a multinomial form given generators. """
def _dict_from_expr_no_gens(expr, opt): """Transform an expression into a multinomial form and figure out generators. """
def parallel_dict_from_expr(exprs, **args): """Transform expressions into a multinomial form. """
def _parallel_dict_from_expr(exprs, opt): """Transform expressions into a multinomial form. """
raise PolynomialError('non-commutative expressions are not supported')
else:
def dict_from_expr(expr, **args): """Transform an expression into a multinomial form. """
def _dict_from_expr(expr, opt): """Transform an expression into a multinomial form. """ raise PolynomialError('non-commutative expressions are not supported')
and expr.base.is_Add)
except AttributeError: raise PolynomialError('expression must support expand method') # TODO: Integrate this into expand() itself any(_is_expandable_pow(j) for j in i.args) for i in Add.make_args(expr)):
expr = expand_multinomial(expr) expr = expand_mul(expr)
else:
def expr_from_dict(rep, *gens): """Convert a multinomial form into an expression. """
parallel_dict_from_basic = parallel_dict_from_expr dict_from_basic = dict_from_expr basic_from_dict = expr_from_dict
def _dict_reorder(rep, gens, new_gens): """Reorder levels using dict representation. """
for monom in monoms: if monom[i]: raise GeneratorsError("unable to drop generators")
class PicklableWithSlots(object): """ Mixin class that allows to pickle objects with ``__slots__``.
Examples ========
First define a class that mixes :class:`PicklableWithSlots` in::
>>> from sympy.polys.polyutils import PicklableWithSlots >>> class Some(PicklableWithSlots): ... __slots__ = ['foo', 'bar'] ... ... def __init__(self, foo, bar): ... self.foo = foo ... self.bar = bar
To make :mod:`pickle` happy in doctest we have to use this hack::
>>> from sympy.core.compatibility import builtins >>> builtins.Some = Some
Next lets see if we can create an instance, pickle it and unpickle::
>>> some = Some('abc', 10) >>> some.foo, some.bar ('abc', 10)
>>> from pickle import dumps, loads >>> some2 = loads(dumps(some))
>>> some2.foo, some2.bar ('abc', 10)
"""
__slots__ = []
def __getstate__(self, cls=None): if cls is None: # This is the case for the instance that gets pickled cls = self.__class__
d = {}
# Get all data that should be stored from super classes for c in cls.__bases__: if hasattr(c, "__getstate__"): d.update(c.__getstate__(self, c))
# Get all information that should be stored from cls and return the dict for name in cls.__slots__: if hasattr(self, name): d[name] = getattr(self, name)
return d
def __setstate__(self, d): # All values that were pickled are now assigned to a fresh instance for name, value in d.items(): try: setattr(self, name, value) except AttributeError: # This is needed in cases like Rational :> Half pass |