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
"""Tools for constructing domains for expressions. """
from __future__ import print_function, division
from sympy.polys.polyutils import parallel_dict_from_basic from sympy.polys.polyoptions import build_options from sympy.polys.polyerrors import GeneratorsNeeded from sympy.polys.domains import ZZ, QQ, RR, EX from sympy.polys.domains.realfield import RealField from sympy.utilities import public from sympy.core import sympify
def _construct_simple(coeffs, opt): """Handle simple domains, e.g.: ZZ, QQ, RR and algebraic domains. """
else:
# XXX: add support for a + b*I coefficients if not algebraics: reals = True else: # there are both reals and algebraics -> EX return False if not reals: algebraics = True else: # there are both algebraics and reals -> EX return False else: # this is a composite domain, e.g. ZZ[X], EX
domain, result = _construct_algebraic(coeffs, opt) else: # Use the maximum precision of all coefficients for the RR's # precision max_prec = max([c._prec for c in coeffs]) domain = RealField(prec=max_prec) else: else:
def _construct_algebraic(coeffs, opt): """We know that coefficients are algebraic so construct the extension. """ from sympy.polys.numberfields import primitive_element
result, exts = [], set([])
for coeff in coeffs: if coeff.is_Rational: coeff = (None, 0, QQ.from_sympy(coeff)) else: a = coeff.as_coeff_add()[0] coeff -= a
b = coeff.as_coeff_mul()[0] coeff /= b
exts.add(coeff)
a = QQ.from_sympy(a) b = QQ.from_sympy(b)
coeff = (coeff, b, a)
result.append(coeff)
exts = list(exts)
g, span, H = primitive_element(exts, ex=True, polys=True) root = sum([ s*ext for s, ext in zip(span, exts) ])
domain, g = QQ.algebraic_field((g, root)), g.rep.rep
for i, (coeff, a, b) in enumerate(result): if coeff is not None: coeff = a*domain.dtype.from_list(H[exts.index(coeff)], g, QQ) + b else: coeff = domain.dtype.from_list([b], g, QQ)
result[i] = coeff
return domain, result
def _construct_composite(coeffs, opt): """Handle composite domains, e.g.: ZZ[X], QQ[X], ZZ(X), QQ(X). """
except GeneratorsNeeded: return None
else:
else:
fractions = True break
else:
elif coeff.is_Float: reals = True break
ground = RR else:
else:
def _construct_expression(coeffs, opt): """The last resort case, i.e. use the expression domain. """
@public def construct_domain(obj, **args): """Construct a minimal domain for the list of coefficients. """
monoms, coeffs = [], [] else: else: else: coeffs = [obj]
else: domain, coeffs = _construct_expression(coeffs, opt) else: result = None else:
else:
else: else: return domain, coeffs[0] |