Пример #1
0
 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")
Пример #2
0
 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"
         )
Пример #3
0
    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)
Пример #4
0
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
Пример #5
0
 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))
Пример #6
0
 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))
Пример #7
0
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")
Пример #8
0
    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)
Пример #9
0
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)
Пример #10
0
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)
Пример #11
0
 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")
Пример #12
0
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)
Пример #13
0
 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)