def postprocess(cls, options): if 'gens' in options and 'domain' in options and options['domain'].is_Composite and \ (set(options['domain'].symbols) & set(options['gens'])): raise GeneratorsError( "ground domain and generators interfere together") elif ('gens' not in options or not options['gens']) and \ 'domain' in options and options['domain'] == sympy.polys.domains.EX: raise GeneratorsError("you have to provide generators because EX domain was requested")
def postprocess(cls, options): if ("gens" in options and "domain" in options and options["domain"].is_Composite and (set(options["domain"].symbols) & set(options["gens"]))): raise GeneratorsError( "ground domain and generators interfere together") elif (("gens" not in options or not options["gens"]) and "domain" in options and options["domain"] == sympy.polys.domains.EX): raise GeneratorsError( "you have to provide generators because EX domain was requested" )
def preprocess(cls, gens): if isinstance(gens, Basic): gens = (gens, ) elif len(gens) == 1 and hasattr(gens[0], '__iter__'): gens = gens[0] if gens == (None, ): gens = () elif has_dups(gens): raise GeneratorsError("duplicated generators: %s" % str(gens)) elif any(gen.is_commutative is False for gen in gens): raise GeneratorsError("non-commutative generators: %s" % str(gens)) return tuple(gens)
def _dict_reorder(rep, gens, new_gens): """Reorder levels using dict representation. """ gens = list(gens) monoms = rep.keys() coeffs = rep.values() new_monoms = [[] for _ in range(len(rep))] used_indices = set() for gen in new_gens: try: j = gens.index(gen) used_indices.add(j) for M, new_M in zip(monoms, new_monoms): new_M.append(M[j]) except ValueError: for new_M in new_monoms: new_M.append(0) for i, _ in enumerate(gens): if i not in used_indices: for monom in monoms: if monom[i]: raise GeneratorsError("unable to drop generators") return map(tuple, new_monoms), coeffs
def inject(self, *gens): """Inject generators into this domain. """ if not (set(self.gens) & set(gens)): return self.__class__(self.dom, *(self.gens + gens)) else: raise GeneratorsError("common generators in %s and %s" % (self.gens, gens))
def inject(self, *symbols): """Inject generators into this domain. """ if not (set(self.symbols) & set(symbols)): return self.__class__(self.domain, self.symbols + symbols, self.order) else: raise GeneratorsError("common generators in %s and %s" % (self.symbols, symbols))
def _parse_symbols(symbols): if not symbols: raise GeneratorsNeeded("generators weren't specified") if isinstance(symbols, basestring): return _symbols(symbols, seq=True) elif isinstance(symbols, Expr): return (symbols,) elif is_sequence(symbols): if all(isinstance(s, basestring) for s in symbols): return _symbols(symbols) elif all(isinstance(s, Expr) for s in symbols): return symbols raise GeneratorsError("expected a string, Symbol or expression or a non-empty sequence of strings, Symbols or expressions")
def preprocess(cls, gens): from sympy import Wild, Symbol from sympy.tensor.indexed import Slice, Indexed from sympy.functions.elementary.exponential import ExpBase if isinstance(gens, Basic): gens = (gens, ) elif len(gens) == 1 and hasattr( gens[0], '__iter__') and not isinstance( gens[0], (Wild, Slice, Indexed, Symbol, ExpBase)): gens = gens[0] if gens == (None, ): gens = () elif has_dups(gens): raise GeneratorsError("duplicated generators: %s" % str(gens)) # elif any(gen.is_commutative == False for gen in gens): # raise GeneratorsError("non-commutative generators: %s" % str(gens)) return tuple(gens)
def test_pickling_polys_errors(): from sympy.polys.polyerrors import ( ExactQuotientFailed, OperationNotSupported, HeuristicGCDFailed, HomomorphismFailed, IsomorphismFailed, ExtraneousFactors, EvaluationFailed, RefinementFailed, CoercionFailed, NotInvertible, NotReversible, NotAlgebraic, DomainError, PolynomialError, UnificationFailed, GeneratorsError, GeneratorsNeeded, ComputationFailed, UnivariatePolynomialError, MultivariatePolynomialError, PolificationFailed, OptionError, FlagError) x = Symbol('x') # TODO: TypeError: __init__() takes at least 3 arguments (1 given) # for c in (ExactQuotientFailed, ExactQuotientFailed(x, 3*x, ZZ)): # check(c) # TODO: TypeError: can't pickle instancemethod objects # for c in (OperationNotSupported, OperationNotSupported(Poly(x), Poly.gcd)): # check(c) for c in (HeuristicGCDFailed, HeuristicGCDFailed()): check(c) for c in (HomomorphismFailed, HomomorphismFailed()): check(c) for c in (IsomorphismFailed, IsomorphismFailed()): check(c) for c in (ExtraneousFactors, ExtraneousFactors()): check(c) for c in (EvaluationFailed, EvaluationFailed()): check(c) for c in (RefinementFailed, RefinementFailed()): check(c) for c in (CoercionFailed, CoercionFailed()): check(c) for c in (NotInvertible, NotInvertible()): check(c) for c in (NotReversible, NotReversible()): check(c) for c in (NotAlgebraic, NotAlgebraic()): check(c) for c in (DomainError, DomainError()): check(c) for c in (PolynomialError, PolynomialError()): check(c) for c in (UnificationFailed, UnificationFailed()): check(c) for c in (GeneratorsError, GeneratorsError()): check(c) for c in (GeneratorsNeeded, GeneratorsNeeded()): check(c) # TODO: PicklingError: Can't pickle <function <lambda> at 0x38578c0>: it's not found as __main__.<lambda> # for c in (ComputationFailed, ComputationFailed(lambda t: t, 3, None)): # check(c) for c in (UnivariatePolynomialError, UnivariatePolynomialError()): check(c) for c in (MultivariatePolynomialError, MultivariatePolynomialError()): check(c) # TODO: TypeError: __init__() takes at least 3 arguments (1 given) # for c in (PolificationFailed, PolificationFailed({}, x, x, False)): # check(c) for c in (OptionError, OptionError()): check(c) for c in (FlagError, FlagError()): check(c)
def minimal_polynomial(ex, x=None, compose=True, polys=False, domain=None): """ Computes the minimal polynomial of an algebraic element. Parameters ========== ex : Expr Element or expression whose minimal polynomial is to be calculated. x : Symbol, optional Independent variable of the minimal polynomial compose : boolean, optional (default=True) Method to use for computing minimal polynomial. If ``compose=True`` (default) then ``_minpoly_compose`` is used, if ``compose=False`` then groebner bases are used. polys : boolean, optional (default=False) If ``True`` returns a ``Poly`` object else an ``Expr`` object. domain : Domain, optional Ground domain Notes ===== By default ``compose=True``, the minimal polynomial of the subexpressions of ``ex`` are computed, then the arithmetic operations on them are performed using the resultant and factorization. If ``compose=False``, a bottom-up algorithm is used with ``groebner``. The default algorithm stalls less frequently. If no ground domain is given, it will be generated automatically from the expression. Examples ======== >>> from sympy import minimal_polynomial, sqrt, solve, QQ >>> from sympy.abc import x, y >>> minimal_polynomial(sqrt(2), x) x**2 - 2 >>> minimal_polynomial(sqrt(2), x, domain=QQ.algebraic_field(sqrt(2))) x - sqrt(2) >>> minimal_polynomial(sqrt(2) + sqrt(3), x) x**4 - 10*x**2 + 1 >>> minimal_polynomial(solve(x**3 + x + 3)[0], x) x**3 + x + 3 >>> minimal_polynomial(sqrt(y), x) x**2 - y """ ex = sympify(ex) if ex.is_number: # not sure if it's always needed but try it for numbers (issue 8354) ex = _mexpand(ex, recursive=True) for expr in preorder_traversal(ex): if expr.is_AlgebraicNumber: compose = False break if x is not None: x, cls = sympify(x), Poly else: x, cls = Dummy('x'), PurePoly if not domain: if ex.free_symbols: domain = FractionField(QQ, list(ex.free_symbols)) else: domain = QQ if hasattr(domain, 'symbols') and x in domain.symbols: raise GeneratorsError("the variable %s is an element of the ground " "domain %s" % (x, domain)) if compose: result = _minpoly_compose(ex, x, domain) result = result.primitive()[1] c = result.coeff(x**degree(result, x)) if c.is_negative: result = expand_mul(-result) return cls(result, x, field=True) if polys else result.collect(x) if not domain.is_QQ: raise NotImplementedError("groebner method only works for QQ") result = _minpoly_groebner(ex, x, cls) return cls(result, x, field=True) if polys else result.collect(x)
def postprocess(cls, options): if 'gens' in options and 'domain' in options and options['domain'].is_Composite and \ (set(options['domain'].gens) & set(options['gens'])): raise GeneratorsError( "ground domain and generators interferes together")
def minimal_polynomial(ex, x=None, **args): """ Computes the minimal polynomial of an algebraic element. Parameters ========== ex : algebraic element expression x : independent variable of the minimal polynomial Options ======= compose : if ``True`` ``_minpoly_compose`` is used, if ``False`` the ``groebner`` algorithm polys : if ``True`` returns a ``Poly`` object domain : ground domain Notes ===== By default ``compose=True``, the minimal polynomial of the subexpressions of ``ex`` are computed, then the arithmetic operations on them are performed using the resultant and factorization. If ``compose=False``, a bottom-up algorithm is used with ``groebner``. The default algorithm stalls less frequently. If no ground domain is given, it will be generated automatically from the expression. Examples ======== >>> from sympy import minimal_polynomial, sqrt, solve, QQ >>> from sympy.abc import x, y >>> minimal_polynomial(sqrt(2), x) x**2 - 2 >>> minimal_polynomial(sqrt(2), x, domain=QQ.algebraic_field(sqrt(2))) x - sqrt(2) >>> minimal_polynomial(sqrt(2) + sqrt(3), x) x**4 - 10*x**2 + 1 >>> minimal_polynomial(solve(x**3 + x + 3)[0], x) x**3 + x + 3 >>> minimal_polynomial(sqrt(y), x) x**2 - y """ from sympy.polys.polytools import degree from sympy.polys.domains import FractionField from sympy.core.basic import preorder_traversal compose = args.get('compose', True) polys = args.get('polys', False) dom = args.get('domain', None) ex = sympify(ex) for expr in preorder_traversal(ex): if expr.is_AlgebraicNumber: compose = False break if x is not None: x, cls = sympify(x), Poly else: x, cls = Dummy('x'), PurePoly if not dom: dom = FractionField(QQ, list( ex.free_symbols)) if ex.free_symbols else QQ if hasattr(dom, 'symbols') and x in dom.symbols: raise GeneratorsError( "the variable %s is an element of the ground domain %s" % (x, dom)) if compose: result = _minpoly_compose(ex, x, dom) result = result.primitive()[1] c = result.coeff(x**degree(result, x)) if c.is_negative: result = expand_mul(-result) return cls(result, x, field=True) if polys else result.collect(x) if not dom.is_QQ: raise NotImplementedError("groebner method only works for QQ") result = _minpoly_groebner(ex, x, cls) return cls(result, x, field=True) if polys else result.collect(x)
def drop(self, *symbols): if self.symbol in symbols: raise GeneratorsError( 'Can not drop generator from FiniteExtension') K = self.domain.drop(*symbols) return self.set_domain(K)