Beispiel #1
0
def Sequence(x,
             universe=None,
             check=True,
             immutable=False,
             cr=False,
             cr_str=None,
             use_sage_types=False):
    """
    A mutable list of elements with a common guaranteed universe,
    which can be set immutable.

    A universe is either an object that supports coercion (e.g., a
    parent), or a category.

    INPUT:

    - ``x`` - a list or tuple instance

    - ``universe`` - (default: None) the universe of elements; if None
      determined using canonical coercions and the entire list of
      elements.  If list is empty, is category Objects() of all
      objects.

    - ``check`` -- (default: True) whether to coerce the elements of x
      into the universe

    - ``immutable`` - (default: True) whether or not this sequence is
      immutable

    - ``cr`` - (default: False) if True, then print a carriage return
      after each comma when printing this sequence.

    - ``cr_str`` - (default: False) if True, then print a carriage return
      after each comma when calling ``str()`` on this sequence.

    - ``use_sage_types`` -- (default: False) if True, coerce the
       built-in Python numerical types int, float, complex to the
       corresponding Sage types (this makes functions like vector()
       more flexible)

    OUTPUT:

    - a sequence

    EXAMPLES::

        sage: v = Sequence(range(10))
        sage: v.universe()
        <type 'int'>
        sage: v
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    We can request that the built-in Python numerical types be coerced
    to Sage objects::

        sage: v = Sequence(range(10), use_sage_types=True)
        sage: v.universe()
        Integer Ring
        sage: v
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    You can also use seq for "Sequence", which is identical to using
    Sequence::

        sage: v = seq([1,2,1/1]); v
        [1, 2, 1]
        sage: v.universe()
        Rational Field

    Note that assignment coerces if possible,::

        sage: v = Sequence(range(10), ZZ)
        sage: a = QQ(5)
        sage: v[3] = a
        sage: parent(v[3])
        Integer Ring
        sage: parent(a)
        Rational Field
        sage: v[3] = 2/3
        Traceback (most recent call last):
        ...
        TypeError: no conversion of this rational to integer

    Sequences can be used absolutely anywhere lists or tuples can be used::

        sage: isinstance(v, list)
        True

    Sequence can be immutable, so entries can't be changed::

        sage: v = Sequence([1,2,3], immutable=True)
        sage: v.is_immutable()
        True
        sage: v[0] = 5
        Traceback (most recent call last):
        ...
        ValueError: object is immutable; please change a copy instead.

    Only immutable sequences are hashable (unlike Python lists),
    though the hashing is potentially slow, since it first involves
    conversion of the sequence to a tuple, and returning the hash of
    that.::

        sage: v = Sequence(range(10), ZZ, immutable=True)
        sage: hash(v) == hash(tuple(range(10)))
        True


    If you really know what you are doing, you can circumvent the type
    checking (for an efficiency gain)::

        sage: list.__setitem__(v, int(1), 2/3)        # bad circumvention
        sage: v
        [0, 2/3, 2, 3, 4, 5, 6, 7, 8, 9]
        sage: list.__setitem__(v, int(1), int(2))     # not so bad circumvention

    You can make a sequence with a new universe from an old sequence.::

        sage: w = Sequence(v, QQ)
        sage: w
        [0, 2, 2, 3, 4, 5, 6, 7, 8, 9]
        sage: w.universe()
        Rational Field
        sage: w[1] = 2/3
        sage: w
        [0, 2/3, 2, 3, 4, 5, 6, 7, 8, 9]

    The default universe for any sequence, if no compatible parent structure
    can be found, is the universe of all Sage objects.

    This example illustrates how every element of a list is taken into account
    when constructing a sequence.::

        sage: v = Sequence([1,7,6,GF(5)(3)]); v
        [1, 2, 1, 3]
        sage: v.universe()
        Finite Field of size 5

    TESTS::

        sage: Sequence(["a"], universe=ZZ)
        Traceback (most recent call last):
        ...
        TypeError: unable to convert a to an element of Integer Ring
    """
    from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal

    if isinstance(x, Sequence_generic) and universe is None:
        universe = x.universe()
        x = list(x)

    if isinstance(x, MPolynomialIdeal) and universe is None:
        universe = x.ring()
        x = x.gens()

    if universe is None:
        orig_x = x
        x = list(
            x)  # make a copy even if x is a list, we're going to change it

        if len(x) == 0:
            from sage.categories.objects import Objects
            universe = Objects()
        else:
            import sage.structure.element
            if use_sage_types:
                # convert any Python built-in numerical types to Sage objects
                x = [sage.structure.coerce.py_scalar_to_element(e) for e in x]
            # start the pairwise coercion
            for i in range(len(x) - 1):
                try:
                    x[i], x[i + 1] = sage.structure.element.canonical_coercion(
                        x[i], x[i + 1])
                except TypeError:
                    from sage.categories.objects import Objects
                    universe = Objects()
                    x = list(orig_x)
                    check = False  # no point
                    break
            if universe is None:  # no type errors raised.
                universe = sage.structure.element.parent(x[len(x) - 1])

    from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
    from sage.rings.polynomial.pbori.pbori import BooleanMonomialMonoid
    from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing
    from sage.rings.quotient_ring import is_QuotientRing

    if is_MPolynomialRing(universe) or isinstance(
            universe, BooleanMonomialMonoid) or (is_QuotientRing(universe)
                                                 and is_MPolynomialRing(
                                                     universe.cover_ring())):
        return PolynomialSequence(x,
                                  universe,
                                  immutable=immutable,
                                  cr=cr,
                                  cr_str=cr_str)
    else:
        return Sequence_generic(x, universe, check, immutable, cr, cr_str,
                                use_sage_types)
def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None):
    """
    Construct a new polynomial sequence object.

    INPUT:

    - ``arg1`` - a multivariate polynomial ring, an ideal or a matrix

    - ``arg2`` - an iterable object of parts or polynomials
      (default:``None``)

      - ``immutable`` - if ``True`` the sequence is immutable (default: ``False``)

      - ``cr`` - print a line break after each element (default: ``False``)

      - ``cr_str`` - print a line break after each element if 'str' is
        called (default: ``None``)

    EXAMPLES::

        sage: P.<a,b,c,d> = PolynomialRing(GF(127),4)
        sage: I = sage.rings.ideal.Katsura(P)

    If a list of tuples is provided, those form the parts::

        sage: F = Sequence([I.gens(),I.gens()], I.ring()); F # indirect doctest
        [a + 2*b + 2*c + 2*d - 1,
         a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
         2*a*b + 2*b*c + 2*c*d - b,
         b^2 + 2*a*c + 2*b*d - c,
         a + 2*b + 2*c + 2*d - 1,
         a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
         2*a*b + 2*b*c + 2*c*d - b,
         b^2 + 2*a*c + 2*b*d - c]
        sage: F.nparts()
        2

    If an ideal is provided, the generators are used::

        sage: Sequence(I)
        [a + 2*b + 2*c + 2*d - 1,
         a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
         2*a*b + 2*b*c + 2*c*d - b,
         b^2 + 2*a*c + 2*b*d - c]

    If a list of polynomials is provided, the system has only one
    part::

        sage: F = Sequence(I.gens(), I.ring()); F
        [a + 2*b + 2*c + 2*d - 1,
         a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
         2*a*b + 2*b*c + 2*c*d - b,
         b^2 + 2*a*c + 2*b*d - c]
         sage: F.nparts()
         1
    """

    from sage.matrix.matrix import is_Matrix

    if is_MPolynomialRing(arg1) or is_QuotientRing(arg1):
        ring = arg1
        gens = arg2

    elif is_MPolynomialRing(arg2) or is_QuotientRing(arg2):
        ring = arg2
        gens = arg1

    elif is_Matrix(arg1) and arg2 is None:
        ring = arg1.base_ring()
        gens = arg1.list()

    elif isinstance(arg1, MPolynomialIdeal) and arg2 is None:
        ring = arg1.ring()
        gens = arg1.gens()

    elif isinstance(arg1, (list,tuple,GeneratorType)) and arg2 is None:
        gens = arg1

        try:
            e = iter(gens).next()
        except StopIteration:
            raise ValueError("Cannot determine ring from provided information.")

        if is_MPolynomial(e) or isinstance(e, QuotientRingElement):
            ring = e.parent()
        else:
            ring = iter(e).next().parent()
    else:
        raise TypeError("Cannot understand input.")

    try:
        e = iter(gens).next()

        if is_MPolynomial(e) or isinstance(e, QuotientRingElement):
            gens = tuple(gens)
            parts = (gens,)
            if not all(f.parent() is ring for f in gens):
                parts = ((ring(f) for f in gens),)
        else:
            parts = []
            _gens = []
            for part in gens:
                _part = []
                for gen in part:
                    if not gen.parent() is ring:
                        ring(gen)
                    _part.append(gen)
                _gens.extend(_part)
                parts.append(tuple(_part))
            gens = _gens
    except StopIteration:
        gens = tuple()
        parts = ((),)

    k = ring.base_ring()

    try: c = k.characteristic()
    except NotImplementedError: c = -1

    if c != 2:
        return PolynomialSequence_generic(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str)
    elif k.degree() == 1:
        return PolynomialSequence_gf2(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str)
    elif k.degree() > 1:
        return PolynomialSequence_gf2e(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str)
Beispiel #3
0
    def __classcall_private__(cls, morphism_or_polys, domain=None):
        r"""
        Return the appropriate dynamical system on an affine scheme.

        TESTS::

            sage: A.<x> = AffineSpace(ZZ,1)
            sage: A1.<z> = AffineSpace(CC,1)
            sage: H = End(A1)
            sage: f2 = H([z^2+1])
            sage: f = DynamicalSystem_affine(f2, A)
            sage: f.domain() is A
            False

        ::

            sage: P1.<x,y> = ProjectiveSpace(QQ,1)
            sage: DynamicalSystem_affine([y, 2*x], domain=P1)
            Traceback (most recent call last):
            ...
            ValueError: "domain" must be an affine scheme
            sage: H = End(P1)
            sage: DynamicalSystem_affine(H([y, 2*x]))
            Traceback (most recent call last):
            ...
            ValueError: "domain" must be an affine scheme

        ::

            sage: R.<x,y,z> = QQ[]
            sage: f = DynamicalSystem_affine([x+y+z, y*z])
            Traceback (most recent call last):
            ...
            ValueError: Number of polys does not match dimension of Affine Space of dimension 3 over Rational Field

        ::
            sage: A.<x,y> = AffineSpace(QQ,2)
            sage: f = DynamicalSystem_affine([CC.0*x^2, y^2], domain=A)
            Traceback (most recent call last):
            ...
            TypeError: coefficients of polynomial not in Rational Field
        """
        if isinstance(morphism_or_polys, SchemeMorphism_polynomial):
            morphism = morphism_or_polys
            R = morphism.base_ring()
            polys = list(morphism)
            domain = morphism.domain()
            if not is_AffineSpace(domain) and not isinstance(
                    domain, AlgebraicScheme_subscheme_affine):
                raise ValueError('"domain" must be an affine scheme')
            if domain != morphism_or_polys.codomain():
                raise ValueError('domain and codomain do not agree')
            if R not in Fields():
                return typecall(cls, polys, domain)
            if is_FiniteField(R):
                return DynamicalSystem_affine_finite_field(polys, domain)
            return DynamicalSystem_affine_field(polys, domain)
        elif isinstance(morphism_or_polys, (list, tuple)):
            polys = list(morphism_or_polys)
        else:
            polys = [morphism_or_polys]

        PR = get_coercion_model().common_parent(*polys)
        fraction_field = any(is_FractionField(poly.parent()) for poly in polys)
        if fraction_field:
            K = PR.base_ring().fraction_field()
            # Replace base ring with its fraction field
            PR = PR.ring().change_ring(K).fraction_field()
            polys = [PR(poly) for poly in polys]
        else:
            quotient_ring = any(
                is_QuotientRing(poly.parent()) for poly in polys)
            # If any of the list entries lies in a quotient ring, we try
            # to lift all entries to a common polynomial ring.
            if quotient_ring:
                polys = [PR(poly).lift() for poly in polys]
            else:
                polys = [PR(poly) for poly in polys]
        if domain is None:
            if PR is SR:
                raise TypeError("Symbolic Ring cannot be the base ring")
            if fraction_field:
                PR = PR.ring()
            domain = AffineSpace(PR)
        else:
            # Check if we can coerce the given polynomials over the given domain
            PR = domain.ambient_space().coordinate_ring()
            try:
                if fraction_field:
                    PR = PR.fraction_field()
                polys = [PR(poly) for poly in polys]
            except TypeError:
                raise TypeError('coefficients of polynomial not in {}'.format(
                    domain.base_ring()))
        if len(polys) != domain.ambient_space().coordinate_ring().ngens():
            raise ValueError(
                'Number of polys does not match dimension of {}'.format(
                    domain))
        R = domain.base_ring()
        if R is SR:
            raise TypeError("Symbolic Ring cannot be the base ring")
        if not is_AffineSpace(domain) and not isinstance(
                domain, AlgebraicScheme_subscheme_affine):
            raise ValueError('"domain" must be an affine scheme')

        if R not in Fields():
            return typecall(cls, polys, domain)
        if is_FiniteField(R):
            return DynamicalSystem_affine_finite_field(polys, domain)
        return DynamicalSystem_affine_field(polys, domain)
Beispiel #4
0
def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=None, use_sage_types=False):
    """
    A mutable list of elements with a common guaranteed universe,
    which can be set immutable.

    A universe is either an object that supports coercion (e.g., a
    parent), or a category.

    INPUT:

    - ``x`` - a list or tuple instance

    - ``universe`` - (default: None) the universe of elements; if None
      determined using canonical coercions and the entire list of
      elements.  If list is empty, is category Objects() of all
      objects.

    - ``check`` -- (default: True) whether to coerce the elements of x
      into the universe

    - ``immutable`` - (default: True) whether or not this sequence is
      immutable

    - ``cr`` - (default: False) if True, then print a carriage return
      after each comma when printing this sequence.

    - ``cr_str`` - (default: False) if True, then print a carriage return
      after each comma when calling ``str()`` on this sequence.

    - ``use_sage_types`` -- (default: False) if True, coerce the
       built-in Python numerical types int, long, float, complex to the
       corresponding Sage types (this makes functions like vector()
       more flexible)

    OUTPUT:

    - a sequence

    EXAMPLES::

        sage: v = Sequence(range(10))
        sage: v.universe()
        <type 'int'>
        sage: v
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    We can request that the built-in Python numerical types be coerced
    to Sage objects::

        sage: v = Sequence(range(10), use_sage_types=True)
        sage: v.universe()
        Integer Ring
        sage: v
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    You can also use seq for "Sequence", which is identical to using
    Sequence::

        sage: v = seq([1,2,1/1]); v
        [1, 2, 1]
        sage: v.universe()
        Rational Field
        sage: v.parent()
        Category of sequences in Rational Field
        sage: v.parent()([3,4/3])
        [3, 4/3]


    Note that assignment coerces if possible,::

        sage: v = Sequence(range(10), ZZ)
        sage: a = QQ(5)
        sage: v[3] = a
        sage: parent(v[3])
        Integer Ring
        sage: parent(a)
        Rational Field
        sage: v[3] = 2/3
        Traceback (most recent call last):
        ...
        TypeError: no conversion of this rational to integer

    Sequences can be used absolutely anywhere lists or tuples can be used::

        sage: isinstance(v, list)
        True

    Sequence can be immutable, so entries can't be changed::

        sage: v = Sequence([1,2,3], immutable=True)
        sage: v.is_immutable()
        True
        sage: v[0] = 5
        Traceback (most recent call last):
        ...
        ValueError: object is immutable; please change a copy instead.

    Only immutable sequences are hashable (unlike Python lists),
    though the hashing is potentially slow, since it first involves
    conversion of the sequence to a tuple, and returning the hash of
    that.::

        sage: v = Sequence(range(10), ZZ, immutable=True)
        sage: hash(v)
        1591723448             # 32-bit
        -4181190870548101704   # 64-bit


    If you really know what you are doing, you can circumvent the type
    checking (for an efficiency gain)::

        sage: list.__setitem__(v, int(1), 2/3)        # bad circumvention
        sage: v
        [0, 2/3, 2, 3, 4, 5, 6, 7, 8, 9]
        sage: list.__setitem__(v, int(1), int(2))     # not so bad circumvention

    You can make a sequence with a new universe from an old sequence.::

        sage: w = Sequence(v, QQ)
        sage: w
        [0, 2, 2, 3, 4, 5, 6, 7, 8, 9]
        sage: w.universe()
        Rational Field
        sage: w[1] = 2/3
        sage: w
        [0, 2/3, 2, 3, 4, 5, 6, 7, 8, 9]

    Sequences themselves live in a category, the category of all sequences
    in the given universe.::

        sage: w.category()
        Category of sequences in Rational Field

    This is also the parent of any sequence::

        sage: w.parent()
        Category of sequences in Rational Field

    The default universe for any sequence, if no compatible parent structure
    can be found, is the universe of all Sage objects.

    This example illustrates how every element of a list is taken into account
    when constructing a sequence.::

        sage: v = Sequence([1,7,6,GF(5)(3)]); v
        [1, 2, 1, 3]
        sage: v.universe()
        Finite Field of size 5
        sage: v.parent()
        Category of sequences in Finite Field of size 5
        sage: v.parent()([7,8,9])
        [2, 3, 4]
    """
    from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal


    if isinstance(x, Sequence_generic) and universe is None:
        universe = x.universe()
        x = list(x)

    if isinstance(x, MPolynomialIdeal) and universe is None:
        universe = x.ring()
        x = x.gens()

    if universe is None:
        if not isinstance(x, (list, tuple)):
            x = list(x)
            #raise TypeError("x must be a list or tuple")

        if len(x) == 0:
            import sage.categories.all
            universe = sage.categories.all.Objects()
        else:
            import sage.structure.element as coerce
            y = x
            x = list(x)   # make a copy, or we'd change the type of the elements of x, which would be bad.
            if use_sage_types:
                # convert any Python built-in numerical types to Sage objects
                from sage.rings.integer_ring import ZZ
                from sage.rings.real_double import RDF
                from sage.rings.complex_double import CDF
                for i in range(len(x)):
                    if isinstance(x[i], int) or isinstance(x[i], long):
                        x[i] = ZZ(x[i])
                    elif isinstance(x[i], float):
                        x[i] = RDF(x[i])
                    elif isinstance(x[i], complex):
                        x[i] = CDF(x[i])
            # start the pairwise coercion
            for i in range(len(x)-1):
                try:
                    x[i], x[i+1] = coerce.canonical_coercion(x[i],x[i+1])
                except TypeError:
                    import sage.categories.all
                    universe = sage.categories.all.Objects()
                    x = list(y)
                    check = False  # no point
                    break
            if universe is None:   # no type errors raised.
                universe = coerce.parent(x[len(x)-1])

    from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing
    from sage.rings.quotient_ring import is_QuotientRing
    from sage.rings.polynomial.pbori import BooleanMonomialMonoid

    if is_MPolynomialRing(universe) or \
            (is_QuotientRing(universe) and is_MPolynomialRing(universe.cover_ring())) or \
            isinstance(universe, BooleanMonomialMonoid):
        from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
        try:
            return PolynomialSequence(x, universe, immutable=immutable, cr=cr, cr_str=cr_str)
        except (TypeError,AttributeError):
            return Sequence_generic(x, universe, check, immutable, cr, cr_str, use_sage_types)
    else:
        return Sequence_generic(x, universe, check, immutable, cr, cr_str, use_sage_types)
def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None):
    """
    Construct a new polynomial sequence object.

    INPUT:

    - ``arg1`` - a multivariate polynomial ring, an ideal or a matrix

    - ``arg2`` - an iterable object of parts or polynomials
      (default:``None``)

      - ``immutable`` - if ``True`` the sequence is immutable (default: ``False``)

      - ``cr`` - print a line break after each element (default: ``False``)

      - ``cr_str`` - print a line break after each element if 'str' is
        called (default: ``None``)

    EXAMPLES::

        sage: P.<a,b,c,d> = PolynomialRing(GF(127),4)
        sage: I = sage.rings.ideal.Katsura(P)

    If a list of tuples is provided, those form the parts::

        sage: F = Sequence([I.gens(),I.gens()], I.ring()); F # indirect doctest
        [a + 2*b + 2*c + 2*d - 1,
         a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
         2*a*b + 2*b*c + 2*c*d - b,
         b^2 + 2*a*c + 2*b*d - c,
         a + 2*b + 2*c + 2*d - 1,
         a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
         2*a*b + 2*b*c + 2*c*d - b,
         b^2 + 2*a*c + 2*b*d - c]
        sage: F.nparts()
        2

    If an ideal is provided, the generators are used::

        sage: Sequence(I)
        [a + 2*b + 2*c + 2*d - 1,
         a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
         2*a*b + 2*b*c + 2*c*d - b,
         b^2 + 2*a*c + 2*b*d - c]

    If a list of polynomials is provided, the system has only one
    part::

        sage: F = Sequence(I.gens(), I.ring()); F
        [a + 2*b + 2*c + 2*d - 1,
         a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
         2*a*b + 2*b*c + 2*c*d - b,
         b^2 + 2*a*c + 2*b*d - c]
         sage: F.nparts()
         1
    """

    from sage.matrix.matrix import is_Matrix

    if is_MPolynomialRing(arg1) or is_QuotientRing(arg1):
        ring = arg1
        gens = arg2

    elif is_MPolynomialRing(arg2) or is_QuotientRing(arg2):
        ring = arg2
        gens = arg1

    elif is_Matrix(arg1) and arg2 is None:
        ring = arg1.base_ring()
        gens = arg1.list()

    elif isinstance(arg1, MPolynomialIdeal) and arg2 is None:
        ring = arg1.ring()
        gens = arg1.gens()

    elif isinstance(arg1, (list,tuple,GeneratorType)) and arg2 is None:
        gens = arg1

        try:
            e = iter(gens).next()
        except StopIteration:
            raise ValueError("Cannot determine ring from provided information.")

        if is_MPolynomial(e) or isinstance(e, QuotientRingElement):
            ring = e.parent()
        else:
            ring = iter(e).next().parent()
    else:
        raise TypeError("Cannot understand input.")

    try:
        e = iter(gens).next()

        if is_MPolynomial(e) or isinstance(e, QuotientRingElement):
            gens = tuple(gens)
            parts = (gens,)
            if not all(f.parent() is ring for f in gens):
                parts = ((ring(f) for f in gens),)
        else:
            parts = []
            _gens = []
            for part in gens:
                _part = []
                for gen in part:
                    if not gen.parent() is ring:
                        ring(gen)
                    _part.append(gen)
                _gens.extend(_part)
                parts.append(tuple(_part))
            gens = _gens
    except StopIteration:
        gens = tuple()
        parts = ((),)

    k = ring.base_ring()

    try: c = k.characteristic()
    except NotImplementedError: c = -1

    if c != 2:
        return PolynomialSequence_generic(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str)
    elif k.degree() == 1:
        return PolynomialSequence_gf2(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str)
    elif k.degree() > 1:
        return PolynomialSequence_gf2e(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str)
Beispiel #6
0
    def __classcall_private__(cls, morphism_or_polys, domain=None):
        r"""
        Return the appropriate dynamical system on an affine scheme.

        TESTS::

            sage: A.<x> = AffineSpace(ZZ,1)
            sage: A1.<z> = AffineSpace(CC,1)
            sage: H = End(A1)
            sage: f2 = H([z^2+1])
            sage: f = DynamicalSystem_affine(f2, A)
            sage: f.domain() is A
            False

        ::

            sage: P1.<x,y> = ProjectiveSpace(QQ,1)
            sage: DynamicalSystem_affine([y, 2*x], domain=P1)
            Traceback (most recent call last):
            ...
            ValueError: "domain" must be an affine scheme
            sage: H = End(P1)
            sage: DynamicalSystem_affine(H([y, 2*x]))
            Traceback (most recent call last):
            ...
            ValueError: "domain" must be an affine scheme
        """
        if isinstance(morphism_or_polys, SchemeMorphism_polynomial):
            morphism = morphism_or_polys
            R = morphism.base_ring()
            polys = list(morphism)
            domain = morphism.domain()
            if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine):
                raise ValueError('"domain" must be an affine scheme')
            if domain != morphism_or_polys.codomain():
                raise ValueError('domain and codomain do not agree')
            if R not in Fields():
                return typecall(cls, polys, domain)
            if is_FiniteField(R):
                return DynamicalSystem_affine_finite_field(polys, domain)
            return DynamicalSystem_affine_field(polys, domain)
        elif isinstance(morphism_or_polys,(list, tuple)):
            polys = list(morphism_or_polys)
        else:
            polys = [morphism_or_polys]

        # We now arrange for all of our list entries to lie in the same ring
        # Fraction field case first
        fraction_field = False
        for poly in polys:
            P = poly.parent()
            if is_FractionField(P):
                fraction_field = True
                break
        if fraction_field:
            K = P.base_ring().fraction_field()
            # Replace base ring with its fraction field
            P = P.ring().change_ring(K).fraction_field()
            polys = [P(poly) for poly in polys]
        else:
            # If any of the list entries lies in a quotient ring, we try
            # to lift all entries to a common polynomial ring.
            quotient_ring = False
            for poly in polys:
                P = poly.parent()
                if is_QuotientRing(P):
                    quotient_ring = True
                    break
            if quotient_ring:
                polys = [P(poly).lift() for poly in polys]
            else:
                poly_ring = False
                for poly in polys:
                    P = poly.parent()
                    if is_PolynomialRing(P) or is_MPolynomialRing(P):
                        poly_ring = True
                        break
                if poly_ring:
                    polys = [P(poly) for poly in polys]

        if domain is None:
            f = polys[0]
            CR = f.parent()
            if CR is SR:
                raise TypeError("Symbolic Ring cannot be the base ring")
            if fraction_field:
                CR = CR.ring()
            domain = AffineSpace(CR)

        R = domain.base_ring()
        if R is SR:
            raise TypeError("Symbolic Ring cannot be the base ring")
        if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine):
            raise ValueError('"domain" must be an affine scheme')

        if R not in Fields():
            return typecall(cls, polys, domain)
        if is_FiniteField(R):
                return DynamicalSystem_affine_finite_field(polys, domain)
        return DynamicalSystem_affine_field(polys, domain)
Beispiel #7
0
    def __classcall_private__(cls, morphism_or_polys, domain=None):
        r"""
        Return the appropriate dynamical system on an affine scheme.

        TESTS::

            sage: A.<x> = AffineSpace(ZZ,1)
            sage: A1.<z> = AffineSpace(CC,1)
            sage: H = End(A1)
            sage: f2 = H([z^2+1])
            sage: f = DynamicalSystem_affine(f2, A)
            sage: f.domain() is A
            False

        ::

            sage: P1.<x,y> = ProjectiveSpace(QQ,1)
            sage: DynamicalSystem_affine([y, 2*x], domain=P1)
            Traceback (most recent call last):
            ...
            ValueError: "domain" must be an affine scheme
            sage: H = End(P1)
            sage: DynamicalSystem_affine(H([y, 2*x]))
            Traceback (most recent call last):
            ...
            ValueError: "domain" must be an affine scheme
        """
        if isinstance(morphism_or_polys, SchemeMorphism_polynomial):
            morphism = morphism_or_polys
            R = morphism.base_ring()
            polys = list(morphism)
            domain = morphism.domain()
            if not is_AffineSpace(domain) and not isinstance(
                    domain, AlgebraicScheme_subscheme_affine):
                raise ValueError('"domain" must be an affine scheme')
            if domain != morphism_or_polys.codomain():
                raise ValueError('domain and codomain do not agree')
            if R not in Fields():
                return typecall(cls, polys, domain)
            if is_FiniteField(R):
                return DynamicalSystem_affine_finite_field(polys, domain)
            return DynamicalSystem_affine_field(polys, domain)
        elif isinstance(morphism_or_polys, (list, tuple)):
            polys = list(morphism_or_polys)
        else:
            polys = [morphism_or_polys]

        # We now arrange for all of our list entries to lie in the same ring
        # Fraction field case first
        fraction_field = False
        for poly in polys:
            P = poly.parent()
            if is_FractionField(P):
                fraction_field = True
                break
        if fraction_field:
            K = P.base_ring().fraction_field()
            # Replace base ring with its fraction field
            P = P.ring().change_ring(K).fraction_field()
            polys = [P(poly) for poly in polys]
        else:
            # If any of the list entries lies in a quotient ring, we try
            # to lift all entries to a common polynomial ring.
            quotient_ring = False
            for poly in polys:
                P = poly.parent()
                if is_QuotientRing(P):
                    quotient_ring = True
                    break
            if quotient_ring:
                polys = [P(poly).lift() for poly in polys]
            else:
                poly_ring = False
                for poly in polys:
                    P = poly.parent()
                    if is_PolynomialRing(P) or is_MPolynomialRing(P):
                        poly_ring = True
                        break
                if poly_ring:
                    polys = [P(poly) for poly in polys]

        if domain is None:
            f = polys[0]
            CR = f.parent()
            if CR is SR:
                raise TypeError("Symbolic Ring cannot be the base ring")
            if fraction_field:
                CR = CR.ring()
            domain = AffineSpace(CR)

        R = domain.base_ring()
        if R is SR:
            raise TypeError("Symbolic Ring cannot be the base ring")
        if not is_AffineSpace(domain) and not isinstance(
                domain, AlgebraicScheme_subscheme_affine):
            raise ValueError('"domain" must be an affine scheme')

        if R not in Fields():
            return typecall(cls, polys, domain)
        if is_FiniteField(R):
            return DynamicalSystem_affine_finite_field(polys, domain)
        return DynamicalSystem_affine_field(polys, domain)
Beispiel #8
0
    def __classcall_private__(cls, morphism_or_polys, domain=None):
        r"""
        Return the appropriate dynamical system on an affine scheme.

        TESTS::

            sage: A.<x> = AffineSpace(ZZ,1)
            sage: A1.<z> = AffineSpace(CC,1)
            sage: H = End(A1)
            sage: f2 = H([z^2+1])
            sage: f = DynamicalSystem_affine(f2, A)
            sage: f.domain() is A
            False

        ::

            sage: P1.<x,y> = ProjectiveSpace(QQ,1)
            sage: DynamicalSystem_affine([y, 2*x], domain=P1)
            Traceback (most recent call last):
            ...
            ValueError: "domain" must be an affine scheme
            sage: H = End(P1)
            sage: DynamicalSystem_affine(H([y, 2*x]))
            Traceback (most recent call last):
            ...
            ValueError: "domain" must be an affine scheme

        ::

            sage: R.<x,y,z> = QQ[]
            sage: f = DynamicalSystem_affine([x+y+z, y*z])
            Traceback (most recent call last):
            ...
            ValueError: Number of polys does not match dimension of Affine Space of dimension 3 over Rational Field

        ::
            sage: A.<x,y> = AffineSpace(QQ,2)
            sage: f = DynamicalSystem_affine([CC.0*x^2, y^2], domain=A)
            Traceback (most recent call last):
            ...
            TypeError: coefficients of polynomial not in Rational Field
        """
        if isinstance(morphism_or_polys, SchemeMorphism_polynomial):
            morphism = morphism_or_polys
            R = morphism.base_ring()
            polys = list(morphism)
            domain = morphism.domain()
            if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine):
                raise ValueError('"domain" must be an affine scheme')
            if domain != morphism_or_polys.codomain():
                raise ValueError('domain and codomain do not agree')
            if R not in Fields():
                return typecall(cls, polys, domain)
            if is_FiniteField(R):
                return DynamicalSystem_affine_finite_field(polys, domain)
            return DynamicalSystem_affine_field(polys, domain)
        elif isinstance(morphism_or_polys,(list, tuple)):
            polys = list(morphism_or_polys)
        else:
            polys = [morphism_or_polys]

        PR = get_coercion_model().common_parent(*polys)         
        fraction_field = any(is_FractionField(poly.parent()) for poly in polys)
        if fraction_field:
            K = PR.base_ring().fraction_field()
            # Replace base ring with its fraction field
            PR = PR.ring().change_ring(K).fraction_field()
            polys = [PR(poly) for poly in polys]
        else:
            quotient_ring = any(is_QuotientRing(poly.parent()) for poly in polys)
            # If any of the list entries lies in a quotient ring, we try
            # to lift all entries to a common polynomial ring.
            if quotient_ring:
                polys = [PR(poly).lift() for poly in polys]
            else:
                polys = [PR(poly) for poly in polys]
        if domain is None:
            if PR is SR:
                raise TypeError("Symbolic Ring cannot be the base ring")
            if fraction_field:
                PR = PR.ring()
            domain = AffineSpace(PR)
        else:
            # Check if we can coerce the given polynomials over the given domain 
            PR = domain.ambient_space().coordinate_ring()
            try:
                if fraction_field:
                    PR = PR.fraction_field()
                polys = [PR(poly) for poly in polys]
            except TypeError:
                raise TypeError('coefficients of polynomial not in {}'.format(domain.base_ring()))
        if len(polys) != domain.ambient_space().coordinate_ring().ngens():
            raise ValueError('Number of polys does not match dimension of {}'.format(domain))
        R = domain.base_ring()
        if R is SR:
            raise TypeError("Symbolic Ring cannot be the base ring")
        if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine):
            raise ValueError('"domain" must be an affine scheme')

        if R not in Fields():
            return typecall(cls, polys, domain)
        if is_FiniteField(R):
                return DynamicalSystem_affine_finite_field(polys, domain)
        return DynamicalSystem_affine_field(polys, domain)
Beispiel #9
0
def ring_defining_ideal(R):
    R_ideal = R.ideal(0)
    if is_QuotientRing(R):
        R_ideal = R.defining_ideal()
    return R_ideal