Ejemplo n.º 1
0
def enum_affine_number_field(X, B):
    """
    Enumerates affine points on scheme ``X`` defined over a number field. Simply checks all of the
    points of absolute height up to ``B`` and adds those that are on the scheme to the list.

    INPUT:

    - ``X`` - a scheme defined over a number field.

    - ``B`` - a real number.

    OUTPUT:

     - a list containing the affine points of ``X`` of absolute height up to ``B``,
       sorted.

    EXAMPLES::

        sage: from sage.schemes.affine.affine_rational_point import enum_affine_number_field
        sage: u = QQ['u'].0
        sage: K = NumberField(u^2 + 2, 'v')
        sage: A.<x,y,z> = AffineSpace(K, 3)
        sage: X = A.subscheme([y^2 - x])
        sage: enum_affine_number_field(X(K), 4)
        [(0, 0, -1), (0, 0, -v), (0, 0, -1/2*v), (0, 0, 0), (0, 0, 1/2*v), (0, 0, v), (0, 0, 1),
        (1, -1, -1), (1, -1, -v), (1, -1, -1/2*v), (1, -1, 0), (1, -1, 1/2*v), (1, -1, v), (1, -1, 1),
        (1, 1, -1), (1, 1, -v), (1, 1, -1/2*v), (1, 1, 0), (1, 1, 1/2*v), (1, 1, v), (1, 1, 1)]

    ::

        sage: u = QQ['u'].0
        sage: K = NumberField(u^2 + 3, 'v')
        sage: A.<x,y> = AffineSpace(K, 2)
        sage: X=A.subscheme(x-y)
        sage: from sage.schemes.affine.affine_rational_point import enum_affine_number_field
        sage: enum_affine_number_field(X, 3)
        [(-1, -1), (-1/2*v - 1/2, -1/2*v - 1/2), (1/2*v - 1/2, 1/2*v - 1/2), (0, 0), (-1/2*v + 1/2, -1/2*v + 1/2),
        (1/2*v + 1/2, 1/2*v + 1/2), (1, 1)]
    """
    from sage.schemes.affine.affine_space import is_AffineSpace
    if (is_Scheme(X)):
        if (not is_AffineSpace(X.ambient_space())):
            raise TypeError(
                "ambient space must be affine space over a number field")
        X = X(X.base_ring())
    else:
        if (not is_AffineSpace(X.codomain().ambient_space())):
            raise TypeError(
                "codomain must be affine space over a number field")

    R = X.codomain().ambient_space()

    pts = []
    for P in R.points_of_bounded_height(B):
        try:
            pts.append(X(P))
        except TypeError:
            pass
    pts.sort()
    return pts
Ejemplo n.º 2
0
def enum_affine_number_field(X, B):
    """
    Enumerates affine points on scheme ``X`` defined over a number field. Simply checks all of the
    points of absolute height up to ``B`` and adds those that are on the scheme to the list.

    INPUT:

    - ``X`` - a scheme defined over a number field.

    - ``B`` - a real number.

    OUTPUT:

     - a list containing the affine points of ``X`` of absolute height up to ``B``,
       sorted.

    EXAMPLES::

        sage: from sage.schemes.affine.affine_rational_point import enum_affine_number_field
        sage: u = QQ['u'].0
        sage: K = NumberField(u^2 + 2, 'v')
        sage: A.<x,y,z> = AffineSpace(K, 3)
        sage: X = A.subscheme([y^2 - x])
        sage: enum_affine_number_field(X(K), 4)
        [(0, 0, -1), (0, 0, -v), (0, 0, -1/2*v), (0, 0, 0), (0, 0, 1/2*v), (0, 0, v), (0, 0, 1),
        (1, -1, -1), (1, -1, -v), (1, -1, -1/2*v), (1, -1, 0), (1, -1, 1/2*v), (1, -1, v), (1, -1, 1),
        (1, 1, -1), (1, 1, -v), (1, 1, -1/2*v), (1, 1, 0), (1, 1, 1/2*v), (1, 1, v), (1, 1, 1)]

    ::

        sage: u = QQ['u'].0
        sage: K = NumberField(u^2 + 3, 'v')
        sage: A.<x,y> = AffineSpace(K, 2)
        sage: X=A.subscheme(x-y)
        sage: from sage.schemes.affine.affine_rational_point import enum_affine_number_field
        sage: enum_affine_number_field(X, 3)
        [(-1, -1), (-1/2*v - 1/2, -1/2*v - 1/2), (1/2*v - 1/2, 1/2*v - 1/2), (0, 0), (-1/2*v + 1/2, -1/2*v + 1/2),
        (1/2*v + 1/2, 1/2*v + 1/2), (1, 1)]
    """
    from sage.schemes.affine.affine_space import is_AffineSpace
    if(is_Scheme(X)):
        if (not is_AffineSpace(X.ambient_space())):
            raise TypeError("ambient space must be affine space over a number field")
        X = X(X.base_ring())
    else:
        if (not is_AffineSpace(X.codomain().ambient_space())):
            raise TypeError("codomain must be affine space over a number field")

    R = X.codomain().ambient_space()

    pts = []
    for P in R.points_of_bounded_height(B):
        try:
            pts.append(X(P))
        except TypeError:
            pass
    pts.sort()
    return pts
Ejemplo n.º 3
0
    def __init__(self, A, X):
        r"""
        Initialization function.

        EXAMPLES::

            sage: R.<v> = QQ[]
            sage: K.<u> = NumberField(v^2 + 3)
            sage: A.<x,y,z> = AffineSpace(K, 3)
            sage: C = Curve([z - u*x^2, y^2], A); C
            Affine Curve over Number Field in u with defining polynomial v^2 + 3
            defined by (-u)*x^2 + z, y^2

        ::

            sage: A.<x,y,z> = AffineSpace(GF(7), 3)
            sage: C = Curve([x^2 - z, z - 8*x], A); C
            Affine Curve over Finite Field of size 7 defined by x^2 - z, -x + z
        """
        if not is_AffineSpace(A):
            raise TypeError("A (=%s) must be an affine space" % A)
        Curve_generic.__init__(self, A, X)
        d = self.dimension()
        if d != 1:
            raise ValueError(
                "defining equations (=%s) define a scheme of dimension %s != 1"
                % (X, d))
Ejemplo n.º 4
0
    def multiplicity(self):
        r"""
        Return the multiplicity of this point on its codomain.

        Uses the subscheme multiplicity implementation. This point must be a point on an
        affine subscheme.

        OUTPUT: an integer.

        EXAMPLES::

            sage: A.<x,y,z> = AffineSpace(QQ, 3)
            sage: X = A.subscheme([y^2 - x^7*z])
            sage: Q1 = X([1,1,1])
            sage: Q1.multiplicity()
            1
            sage: Q2 = X([0,0,2])
            sage: Q2.multiplicity()
            2
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.codomain()):
            raise TypeError(
                "this point must be a point on an affine subscheme")
        return self.codomain().multiplicity(self)
Ejemplo n.º 5
0
 def __init__(self, A, X):
     if not is_AffineSpace(A):
         raise TypeError("A (=%s) must be an affine space"%A)
     Curve_generic.__init__(self, A, X)
     d = self.dimension()
     if d != 1:
         raise ValueError("defining equations (=%s) define a scheme of dimension %s != 1"%(X,d))
Ejemplo n.º 6
0
    def __classcall_private__(cls, morphism_or_polys, domain=None, names=None):
        r"""
        Return the appropriate dynamical system on a scheme.

        EXAMPLES::

            sage: R.<t> = QQ[]
            sage: DynamicalSystem(t^2 - 3)
            Dynamical System of Projective Space of dimension 1 over Rational Field
              Defn: Defined on coordinates by sending (X : Y) to
                    (X^2 - 3*Y^2 : Y^2)
        """
        if isinstance(morphism_or_polys, SchemeMorphism_polynomial):
            domain = morphism_or_polys.domain()
        if domain is not None:
            if is_AffineSpace(domain) or isinstance(
                    domain, AlgebraicScheme_subscheme_affine):
                from sage.dynamics.arithmetic_dynamics.affine_ds import DynamicalSystem_affine
                return DynamicalSystem_affine(morphism_or_polys, domain)
            if is_Berkovich_Cp(domain):
                from sage.dynamics.arithmetic_dynamics.berkovich_ds import DynamicalSystem_Berkovich
                return DynamicalSystem_Berkovich(morphism_or_polys, domain)

        from sage.dynamics.arithmetic_dynamics.projective_ds import DynamicalSystem_projective
        return DynamicalSystem_projective(morphism_or_polys, domain, names)
Ejemplo n.º 7
0
 def __init__(self, A, X):
     if not is_AffineSpace(A):
         raise TypeError("A (=%s) must be an affine space"%A)
     Curve_generic.__init__(self, A, X)
     d = self.dimension()
     if d != 1:
         raise ValueError("defining equations (=%s) define a scheme of dimension %s != 1"%(X,d))
Ejemplo n.º 8
0
    def cyclegraph(self):
        r"""
        Returns digraph of all orbits of this morphism mod `p`.

        For subschemes, only points on the subscheme whose
        image are also on the subscheme are in the digraph.

        OUTPUT: A digraph.

        EXAMPLES::

            sage: P.<x,y> = AffineSpace(GF(5), 2)
            sage: H = Hom(P, P)
            sage: f = H([x^2-y, x*y+1])
            sage: f.cyclegraph()
            Looped digraph on 25 vertices

        ::

            sage: P.<x> = AffineSpace(GF(3^3, 't'), 1)
            sage: H = Hom(P, P)
            sage: f = H([x^2-1])
            sage: f.cyclegraph()
            Looped digraph on 27 vertices

        ::

            sage: P.<x,y> = AffineSpace(GF(7), 2)
            sage: X = P.subscheme(x-y)
            sage: H = Hom(X, X)
            sage: f = H([x^2, y^2])
            sage: f.cyclegraph()
            Looped digraph on 7 vertices
        """
        if self.domain() != self.codomain():
            raise NotImplementedError("domain and codomain must be equal")
        V = []
        E = []
        from sage.schemes.affine.affine_space import is_AffineSpace

        if is_AffineSpace(self.domain()) == True:
            for P in self.domain():
                V.append(str(P))
                Q = self(P)
                E.append([str(Q)])
        else:
            X = self.domain()
            for P in X.ambient_space():
                try:
                    XP = X.point(P)
                    V.append(str(XP))
                    Q = self(XP)
                    E.append([str(Q)])
                except TypeError:  # not on the scheme
                    pass
        from sage.graphs.digraph import DiGraph

        g = DiGraph(dict(zip(V, E)), loops=True)
        return g
Ejemplo n.º 9
0
    def cyclegraph(self):
        r"""
        Returns digraph of all orbits of this morphism mod `p`.

        For subschemes, only points on the subscheme whose
        image are also on the subscheme are in the digraph.

        OUTPUT: A digraph.

        EXAMPLES::

            sage: P.<x,y> = AffineSpace(GF(5), 2)
            sage: H = Hom(P, P)
            sage: f = H([x^2-y, x*y+1])
            sage: f.cyclegraph()
            Looped digraph on 25 vertices

        ::

            sage: P.<x> = AffineSpace(GF(3^3, 't'), 1)
            sage: H = Hom(P, P)
            sage: f = H([x^2-1])
            sage: f.cyclegraph()
            Looped digraph on 27 vertices

        ::

            sage: P.<x,y> = AffineSpace(GF(7), 2)
            sage: X = P.subscheme(x-y)
            sage: H = Hom(X, X)
            sage: f = H([x^2, y^2])
            sage: f.cyclegraph()
            Looped digraph on 7 vertices
        """
        if self.domain() != self.codomain():
            raise NotImplementedError("domain and codomain must be equal")
        V = []
        E = []
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.domain()) == True:
            for P in self.domain():
                V.append(str(P))
                Q = self(P)
                E.append([str(Q)])
        else:
            X = self.domain()
            for P in X.ambient_space():
                try:
                    XP = X.point(P)
                    V.append(str(XP))
                    Q = self(XP)
                    E.append([str(Q)])
                except TypeError:  # not on the scheme
                    pass
        from sage.graphs.digraph import DiGraph
        g = DiGraph(dict(zip(V, E)), loops=True)
        return g
Ejemplo n.º 10
0
    def cyclegraph(self):
        r"""
        Return the digraph of all orbits of this morphism mod `p`.

        For subschemes, only points on the subscheme whose
        image are also on the subscheme are in the digraph.

        OUTPUT: a digraph

        EXAMPLES::

            sage: P.<x,y> = AffineSpace(GF(5), 2)
            sage: f = DynamicalSystem_affine([x^2-y, x*y+1])
            sage: f.cyclegraph()
            Looped digraph on 25 vertices

        ::

            sage: P.<x> = AffineSpace(GF(3^3, 't'), 1)
            sage: f = DynamicalSystem_affine([x^2-1])
            sage: f.cyclegraph()
            Looped digraph on 27 vertices

        ::

            sage: P.<x,y> = AffineSpace(GF(7), 2)
            sage: X = P.subscheme(x-y)
            sage: f = DynamicalSystem_affine([x^2, y^2], domain=X)
            sage: f.cyclegraph()
            Looped digraph on 7 vertices
        """
        V = []
        E = []
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.domain()):
            for P in self.domain():
                V.append(str(P))
                Q = self(P)
                E.append([str(Q)])
        else:
            X = self.domain()
            for P in X.ambient_space():
                try:
                    XP = X.point(P)
                    V.append(str(XP))
                    Q = self(XP)
                    E.append([str(Q)])
                except TypeError:  # not on the scheme
                    pass
        from sage.graphs.digraph import DiGraph
        return DiGraph(dict(zip(V, E)), loops=True)
Ejemplo n.º 11
0
    def __init__(self, base, ideal=None):
        """
        The Python constructor.

        EXAMPLES::

            sage: Berkovich_Cp_Affine(3)
            Affine Berkovich line over Cp(3) of precision 20
        """
        if base in ZZ:
            if base.is_prime():
                base = Qp(base)  # change to Qpbar
            else:
                raise ValueError("non-prime passed into Berkovich space")
        if is_AffineSpace(base):
            base = base.base_ring()
        if base in NumberFields():
            if ideal is None:
                raise ValueError('passed a number field but not an ideal')
            if base is not QQ:
                if not isinstance(ideal, NumberFieldFractionalIdeal):
                    raise ValueError(
                        'ideal was not an ideal of a number field')
                if ideal.number_field() != base:
                    raise ValueError('passed number field ' + \
                        '%s but ideal was an ideal of %s' %(base, ideal.number_field()))
                prime = ideal.smallest_integer()
            else:
                if ideal not in QQ:
                    raise ValueError('ideal was not an element of QQ')
                prime = ideal
            if not ideal.is_prime():
                raise ValueError('passed non prime ideal')
            self._base_type = 'number field'
        elif isinstance(base,
                        sage.rings.abc.pAdicField):  # change base to Qpbar
            prime = base.prime()
            ideal = None
            self._base_type = 'padic field'
        else:
            raise ValueError("base of Berkovich Space must be a padic field " + \
                "or a number field")
        self._ideal = ideal
        self._p = prime
        Parent.__init__(self, base=base, category=TopologicalSpaces())
Ejemplo n.º 12
0
    def __init__(self, A, f):
        r"""
        Initialization function.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: C = Curve([x^3 - y^2], A); C
            Affine Plane Curve over Rational Field defined by x^3 - y^2

        ::

            sage: A.<x,y> = AffineSpace(CC, 2)
            sage: C = Curve([y^2 + x^2], A); C
            Affine Plane Curve over Complex Field with 53 bits of precision defined
            by x^2 + y^2
        """
        if not (is_AffineSpace(A) and A.dimension != 2):
            raise TypeError("Argument A (= %s) must be an affine plane." % A)
        Curve_generic.__init__(self, A, [f])
Ejemplo n.º 13
0
    def __classcall_private__(cls, morphism_or_polys, domain=None, names=None):
        r"""
        Return the appropriate dynamical system on a scheme.

        EXAMPLES::

            sage: R.<t> = QQ[]
            sage: DynamicalSystem(t^2 - 3)
            Dynamical System of Projective Space of dimension 1 over Rational Field
              Defn: Defined on coordinates by sending (X : Y) to
                    (X^2 - 3*Y^2 : Y^2)
        """
        if isinstance(morphism_or_polys, SchemeMorphism_polynomial):
            domain = morphism_or_polys.domain()
        if not domain is None:
            if is_AffineSpace(domain) or isinstance(domain, AlgebraicScheme_subscheme_affine):
                from sage.dynamics.arithmetic_dynamics.affine_ds import DynamicalSystem_affine
                return DynamicalSystem_affine(morphism_or_polys, domain)

        from sage.dynamics.arithmetic_dynamics.projective_ds import DynamicalSystem_projective
        return DynamicalSystem_projective(morphism_or_polys, domain, names)
Ejemplo n.º 14
0
    def intersection_multiplicity(self, X):
        r"""
        Return the intersection multiplicity of the codomain of this point and ``X`` at this point.

        This uses the intersection_multiplicity implementations for projective/affine subschemes. This
        point must be a point on an affine subscheme.

        INPUT:

        - ``X`` -- a subscheme in the same ambient space as that of the codomain of this point.

        OUTPUT: Integer.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(GF(17), 2)
            sage: X = A.subscheme([y^2 - x^3 + 2*x^2 - x])
            sage: Y = A.subscheme([y - 2*x + 2])
            sage: Q1 = Y([1,0])
            sage: Q1.intersection_multiplicity(X)
            2
            sage: Q2 = X([4,6])
            sage: Q2.intersection_multiplicity(Y)
            1

        ::

            sage: A.<x,y,z,w> = AffineSpace(QQ, 4)
            sage: X = A.subscheme([x^2 - y*z^2, z - 2*w^2])
            sage: Q = A([2,1,2,-1])
            sage: Q.intersection_multiplicity(X)
            Traceback (most recent call last):
            ...
            TypeError: this point must be a point on an affine subscheme
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.codomain()):
            raise TypeError(
                "this point must be a point on an affine subscheme")
        return self.codomain().intersection_multiplicity(X, self)
Ejemplo n.º 15
0
def CurvePointToIdeal(C,P):
    r"""
    Return the vanishing ideal of a point on a curve.

    EXAMPLES::

        sage: x,y = AffineSpace(2, QQ, names='xy').gens()
        sage: C = Curve(y^2 - x^9 - x)
        sage: from sage.schemes.generic.divisor import CurvePointToIdeal
        sage: CurvePointToIdeal(C, (0,0))
        Ideal (x, y) of Multivariate Polynomial Ring in x, y over Rational Field
    """
    A = C.ambient_space()
    R = A.coordinate_ring()
    n = A.ngens()
    x = A.gens()
    polys = [ ]
    m = n-1
    while m > 0 and P[m] == 0:
        m += -1
    if is_ProjectiveSpace(A):
        a_m = P[m]
        x_m = x[m]
        for i in range(m):
            ai = P[i]
            if ai == 0:
                polys.append(x[i])
            else:
                polys.append(a_m*x[i]-ai*x_m)
    elif is_AffineSpace(A):
        for i in range(m+1):
            ai = P[i]
            if ai == 0:
                polys.append(x[i])
            else:
                polys.append(x[i]-ai)
    for i in range(m+1,n):
        polys.append(x[i])
    return R.ideal(polys)
Ejemplo n.º 16
0
def CurvePointToIdeal(C, P):
    r"""
    Return the vanishing ideal of a point on a curve.

    EXAMPLES::

        sage: x,y = AffineSpace(2, QQ, names='xy').gens()
        sage: C = Curve(y^2 - x^9 - x)
        sage: from sage.schemes.generic.divisor import CurvePointToIdeal
        sage: CurvePointToIdeal(C, (0,0))
        Ideal (x, y) of Multivariate Polynomial Ring in x, y over Rational Field
    """
    A = C.ambient_space()
    R = A.coordinate_ring()
    n = A.ngens()
    x = A.gens()
    polys = []
    m = n - 1
    while m > 0 and P[m] == 0:
        m += -1
    if is_ProjectiveSpace(A):
        a_m = P[m]
        x_m = x[m]
        for i in range(m):
            ai = P[i]
            if ai == 0:
                polys.append(x[i])
            else:
                polys.append(a_m * x[i] - ai * x_m)
    elif is_AffineSpace(A):
        for i in range(m + 1):
            ai = P[i]
            if ai == 0:
                polys.append(x[i])
            else:
                polys.append(x[i] - ai)
    for i in range(m + 1, n):
        polys.append(x[i])
    return R.ideal(polys)
Ejemplo n.º 17
0
    def intersection_multiplicity(self, X):
        r"""
        Return the intersection multiplicity of the codomain of this point and ``X`` at this point.

        This uses the intersection_multiplicity implementations for projective/affine subschemes. This
        point must be a point on an affine subscheme.

        INPUT:

        - ``X`` -- a subscheme in the same ambient space as that of the codomain of this point.

        OUTPUT: Integer.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(GF(17), 2)
            sage: X = A.subscheme([y^2 - x^3 + 2*x^2 - x])
            sage: Y = A.subscheme([y - 2*x + 2])
            sage: Q1 = Y([1,0])
            sage: Q1.intersection_multiplicity(X)
            2
            sage: Q2 = X([4,6])
            sage: Q2.intersection_multiplicity(Y)
            1

        ::

            sage: A.<x,y,z,w> = AffineSpace(QQ, 4)
            sage: X = A.subscheme([x^2 - y*z^2, z - 2*w^2])
            sage: Q = A([2,1,2,-1])
            sage: Q.intersection_multiplicity(X)
            Traceback (most recent call last):
            ...
            TypeError: this point must be a point on an affine subscheme
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.codomain()):
            raise TypeError("this point must be a point on an affine subscheme")
        return self.codomain().intersection_multiplicity(X, self)
Ejemplo n.º 18
0
    def __classcall_private__(cls, dynamical_system, domain=None):
        """
        Return the appropriate dynamical system on affine Berkovich space over ``Cp``.

        EXAMPLES::

            sage: A.<x> = AffineSpace(Qp(3), 1)
            sage: from sage.dynamics.arithmetic_dynamics.berkovich_ds import DynamicalSystem_Berkovich_affine
            sage: DynamicalSystem_Berkovich_affine(DynamicalSystem_affine(x^2))
            Dynamical system of Affine Berkovich line over Cp(3) of precision 20 induced by the map
              Defn: Defined on coordinates by sending (x) to
                    (x^2)
        """
        if not isinstance(dynamical_system, DynamicalSystem):
            if not isinstance(dynamical_system, DynamicalSystem_affine):
                dynamical_system = DynamicalSystem_projective(dynamical_system)
            else:
                raise TypeError(
                    'projective dynamical system passed to affine constructor')
        R = dynamical_system.base_ring()
        morphism_domain = dynamical_system.domain()
        if not is_AffineSpace(morphism_domain):
            raise TypeError(
                'the domain of dynamical_system must be affine space, not %s' %
                morphism_domain)
        if morphism_domain.dimension_relative() != 1:
            raise ValueError('domain not relative dimension 1')
        if not isinstance(R, pAdicBaseGeneric):
            if domain is None:
                raise TypeError('dynamical system defined over %s, not padic, ' %morphism_domain.base_ring() + \
                    'and domain was not specified')
            if not isinstance(domain, Berkovich_Cp_Affine):
                raise TypeError(
                    'domain was %s, not an affine Berkovich space over Cp' %
                    domain)
        else:
            domain = Berkovich_Cp_Affine(morphism_domain.base_ring())
        return typecall(cls, dynamical_system, domain)
Ejemplo n.º 19
0
    def multiplicity(self):
        r"""
        Return the multiplicity of this point on its codomain.

        Uses the subscheme multiplicity implementation. This point must be a point on an
        affine subscheme.

        OUTPUT: an integer.

        EXAMPLES::

            sage: A.<x,y,z> = AffineSpace(QQ, 3)
            sage: X = A.subscheme([y^2 - x^7*z])
            sage: Q1 = X([1,1,1])
            sage: Q1.multiplicity()
            1
            sage: Q2 = X([0,0,2])
            sage: Q2.multiplicity()
            2
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.codomain()):
            raise TypeError("this point must be a point on an affine subscheme")
        return self.codomain().multiplicity(self)
Ejemplo n.º 20
0
def enum_affine_rational_field(X, B):
    """
    Enumerates affine rational points on scheme ``X`` up to bound ``B``.

    INPUT:

    - ``X`` -  a scheme or set of abstract rational points of a scheme.
    - ``B`` -  a positive integer bound.

    OUTPUT:

    - a list containing the affine points of ``X`` of height up to ``B``,
      sorted.

    EXAMPLES::

        sage: A.<x,y,z> = AffineSpace(3, QQ)
        sage: from sage.schemes.affine.affine_rational_point import enum_affine_rational_field
        sage: enum_affine_rational_field(A(QQ), 1)
        [(-1, -1, -1), (-1, -1, 0), (-1, -1, 1), (-1, 0, -1), (-1, 0, 0), (-1, 0, 1),
        (-1, 1, -1), (-1, 1, 0), (-1, 1, 1), (0, -1, -1), (0, -1, 0), (0, -1, 1),
        (0, 0, -1), (0, 0, 0), (0, 0, 1), (0, 1, -1), (0, 1, 0), (0, 1, 1), (1, -1, -1),
        (1, -1, 0), (1, -1, 1), (1, 0, -1), (1, 0, 0), (1, 0, 1), (1, 1, -1), (1, 1, 0),
        (1, 1, 1)]

    ::

        sage: A.<w,x,y,z> = AffineSpace(4, QQ)
        sage: S = A.subscheme([x^2-y*z+1, w^3+z+y^2])
        sage: enum_affine_rational_field(S(QQ), 1)
        [(0, 0, -1, -1)]
        sage: enum_affine_rational_field(S(QQ), 2)
        [(0, 0, -1, -1), (1, -1, -1, -2), (1, 1, -1, -2)]

    ::

        sage: A.<x,y> = AffineSpace(2, QQ)
        sage: C = Curve(x^2+y-x)
        sage: enum_affine_rational_field(C, 10) # long time (3 s)
        [(-2, -6), (-1, -2), (-2/3, -10/9), (-1/2, -3/4), (-1/3, -4/9),
        (0, 0), (1/3, 2/9), (1/2, 1/4), (2/3, 2/9), (1, 0),
        (4/3, -4/9), (3/2, -3/4), (5/3, -10/9), (2, -2), (3, -6)]

    AUTHORS:

    - David R. Kohel <*****@*****.**>: original version.

    - Charlie Turner (06-2010): small adjustments.

    - Raman Raghukul 2018: updated.
    """
    from sage.schemes.affine.affine_space import is_AffineSpace
    if is_Scheme(X):
        if not is_AffineSpace(X.ambient_space()):
            raise TypeError(
                "ambient space must be affine space over the rational field")
        X = X(X.base_ring())
    elif not is_AffineSpace(X.codomain().ambient_space()):
        raise TypeError(
            "codomain must be affine space over the rational field")

    n = X.codomain().ambient_space().ngens()
    VR = X.value_ring()
    if VR is ZZ:
        R = [0] + [s * k for k in range(1, B + 1) for s in [1, -1]]
        iters = [iter(R) for _ in range(n)]
    else:  # rational field
        iters = [QQ.range_by_height(B + 1) for _ in range(n)]
    pts = []
    P = [0] * n
    try:
        pts.append(X(P))
    except TypeError:
        pass

    for it in iters:
        next(it)
    i = 0
    while i < n:
        try:
            a = VR(next(iters[i]))
        except StopIteration:
            if VR is ZZ:
                iters[i] = iter(R)
            else:  # rational field
                iters[i] = QQ.range_by_height(B + 1)
            P[i] = next(iters[i])  # reset P[i] to 0 and increment
            i += 1
            continue
        P[i] = a
        try:
            pts.append(X(P))
        except TypeError:
            pass
        i = 0
    pts.sort()
    return pts
Ejemplo n.º 21
0
def Curve(F, A=None):
    """
    Return the plane or space curve defined by ``F``, where ``F`` can be either
    a multivariate polynomial, a list or tuple of polynomials, or an algebraic
    scheme.

    If no ambient space is passed in for ``A``, and if ``F`` is not an
    algebraic scheme, a new ambient space is constructed.

    Also not specifying an ambient space will cause the curve to be defined in
    either affine or projective space based on properties of ``F``. In
    particular, if ``F`` contains a nonhomogenous polynomial, the curve is
    affine, and if ``F`` consists of homogenous polynomials, then the curve is
    projective.

    INPUT:

    - ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme.

    - ``A`` -- (default: None) an ambient space in which to create the curve.

    EXAMPLES: A projective plane curve.  ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3); C
        Projective Plane Curve over Rational Field defined by x^3 + y^3 + z^3
        sage: C.genus()
        1

    Affine plane curves.  ::

        sage: x,y = GF(7)['x,y'].gens()
        sage: C = Curve(y^2 + x^3 + x^10); C
        Affine Plane Curve over Finite Field of size 7 defined by x^10 + x^3 + y^2
        sage: C.genus()
        0
        sage: x, y = QQ['x,y'].gens()
        sage: Curve(x^3 + y^3 + 1)
        Affine Plane Curve over Rational Field defined by x^3 + y^3 + 1

    A projective space curve.  ::

        sage: x,y,z,w = QQ['x,y,z,w'].gens()
        sage: C = Curve([x^3 + y^3 - z^3 - w^3, x^5 - y*z^4]); C
        Projective Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4
        sage: C.genus()
        13

    An affine space curve.  ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve([y^2 + x^3 + x^10 + z^7,  x^2 + y^2]); C
        Affine Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2
        sage: C.genus()
        47

    We can also make non-reduced non-irreducible curves.  ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve((x-y)*(x+y))
        Projective Conic Curve over Rational Field defined by x^2 - y^2
        sage: Curve((x-y)^2*(x+y)^2)
        Projective Plane Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4

    A union of curves is a curve.  ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3)
        sage: D = Curve(x^4 + y^4 + z^4)
        sage: C.union(D)
        Projective Plane Curve over Rational Field defined by
        x^7 + x^4*y^3 + x^3*y^4 + y^7 + x^4*z^3 + y^4*z^3 + x^3*z^4 + y^3*z^4 + z^7

    The intersection is not a curve, though it is a scheme.  ::

        sage: X = C.intersection(D); X
        Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
         x^3 + y^3 + z^3,
         x^4 + y^4 + z^4

    Note that the intersection has dimension 0.  ::

        sage: X.dimension()
        0
        sage: I = X.defining_ideal(); I
        Ideal (x^3 + y^3 + z^3, x^4 + y^4 + z^4) of Multivariate Polynomial Ring in x, y, z over Rational Field

    If only a polynomial in three variables is given, then it must be
    homogeneous such that a projective curve is constructed.  ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve(x^2+y^2)
        Projective Conic Curve over Rational Field defined by x^2 + y^2
        sage: Curve(x^2+y^2+z)
        Traceback (most recent call last):
        ...
        TypeError: x^2 + y^2 + z is not a homogeneous polynomial

    An ambient space can be specified to construct a space curve in an affine
    or a projective space.  ::

        sage: A.<x,y,z> = AffineSpace(QQ, 3)
        sage: C = Curve([y - x^2, z - x^3], A)
        sage: C
        Affine Curve over Rational Field defined by -x^2 + y, -x^3 + z
        sage: A == C.ambient_space()
        True

    The defining polynomial must be nonzero unless the ambient space itself is
    of dimension 1. ::

        sage: P1.<x,y> = ProjectiveSpace(1,GF(5))
        sage: S = P1.coordinate_ring()
        sage: Curve(S(0), P1)
        Projective Line over Finite Field of size 5
        sage: Curve(P1)
        Projective Line over Finite Field of size 5

    ::

        sage: A1.<x> = AffineSpace(1, QQ)
        sage: R = A1.coordinate_ring()
        sage: Curve(R(0), A1)
        Affine Line over Rational Field
        sage: Curve(A1)
        Affine Line over Rational Field

    """
    if A is None:
        if is_AmbientSpace(F) and F.dimension() == 1:
            return Curve(F.coordinate_ring().zero(), F)

        if is_AlgebraicScheme(F):
            return Curve(F.defining_polynomials(), F.ambient_space())

        if isinstance(F, (list, tuple)):
            P = Sequence(F).universe()
            if not is_MPolynomialRing(P):
                raise TypeError("universe of F must be a multivariate polynomial ring")
            for f in F:
                if not f.is_homogeneous():
                    A = AffineSpace(P.ngens(), P.base_ring(), names=P.variable_names())
                    A._coordinate_ring = P
                    break
            else:
                A = ProjectiveSpace(P.ngens()-1, P.base_ring(), names=P.variable_names())
                A._coordinate_ring = P
        elif is_MPolynomial(F): # define a plane curve
            P = F.parent()
            k = F.base_ring()

            if not k.is_field():
                if k.is_integral_domain():  # upgrade to a field
                    P = P.change_ring(k.fraction_field())
                    F = P(F)
                    k = F.base_ring()
                else:
                    raise TypeError("not a multivariate polynomial over a field or an integral domain")

            if F.parent().ngens() == 2:
                if F == 0:
                    raise ValueError("defining polynomial of curve must be nonzero")
                A = AffineSpace(2, P.base_ring(), names=P.variable_names())
                A._coordinate_ring = P
            elif F.parent().ngens() == 3:
                if F == 0:
                    raise ValueError("defining polynomial of curve must be nonzero")

                # special case: construct a conic curve
                if F.total_degree() == 2 and k.is_field():
                    return Conic(k, F)

                A = ProjectiveSpace(2, P.base_ring(), names=P.variable_names())
                A._coordinate_ring = P
            elif F.parent().ngens() == 1:
                if not F.is_zero():
                    raise ValueError("defining polynomial of curve must be zero "
                                     "if the ambient space is of dimension 1")

                A = AffineSpace(1, P.base_ring(), names=P.variable_names())
                A._coordinate_ring = P
            else:
                raise TypeError("number of variables of F (={}) must be 2 or 3".format(F))
            F = [F]
        else:
            raise TypeError("F (={}) must be a multivariate polynomial".format(F))
    else:
        if not is_AmbientSpace(A):
            raise TypeError("ambient space must be either an affine or projective space")
        if not isinstance(F, (list, tuple)):
            F = [F]
        if  not all(f.parent() == A.coordinate_ring() for f in F):
            raise TypeError("need a list of polynomials of the coordinate ring of {}".format(A))

    n = A.dimension_relative()
    if n < 1:
        raise TypeError("ambient space should be an affine or projective space of positive dimension")

    k = A.base_ring()

    if is_AffineSpace(A):
        if n != 2:
            if is_FiniteField(k):
                if A.coordinate_ring().ideal(F).is_prime():
                    return IntegralAffineCurve_finite_field(A, F)
            if k in Fields():
                if k == QQ and A.coordinate_ring().ideal(F).is_prime():
                    return IntegralAffineCurve(A, F)
                return AffineCurve_field(A, F)
            return AffineCurve(A, F)

        if not (len(F) == 1 and F[0] != 0 and F[0].degree() > 0):
            raise TypeError("need a single nonconstant polynomial to define a plane curve")

        F = F[0]
        if is_FiniteField(k):
            if _is_irreducible_and_reduced(F):
                return IntegralAffinePlaneCurve_finite_field(A, F)
            return AffinePlaneCurve_finite_field(A, F)
        if k in Fields():
            if k == QQ and _is_irreducible_and_reduced(F):
                return IntegralAffinePlaneCurve(A, F)
            return AffinePlaneCurve_field(A, F)
        return AffinePlaneCurve(A, F)

    elif is_ProjectiveSpace(A):
        if n != 2:
            if not all(f.is_homogeneous() for f in F):
                raise TypeError("polynomials defining a curve in a projective space must be homogeneous")
            if is_FiniteField(k):
                if A.coordinate_ring().ideal(F).is_prime():
                    return IntegralProjectiveCurve_finite_field(A, F)
            if k in Fields():
                if k == QQ and A.coordinate_ring().ideal(F).is_prime():
                    return IntegralProjectiveCurve(A, F)
                return ProjectiveCurve_field(A, F)
            return ProjectiveCurve(A, F)

        # There is no dimension check when initializing a plane curve, so check
        # here that F consists of a single nonconstant polynomial.
        if not (len(F) == 1 and F[0] != 0 and F[0].degree() > 0):
            raise TypeError("need a single nonconstant polynomial to define a plane curve")

        F = F[0]
        if not F.is_homogeneous():
            raise TypeError("{} is not a homogeneous polynomial".format(F))

        if is_FiniteField(k):
            if _is_irreducible_and_reduced(F):
                return IntegralProjectivePlaneCurve_finite_field(A, F)
            return ProjectivePlaneCurve_finite_field(A, F)
        if k in Fields():
            if k == QQ and _is_irreducible_and_reduced(F):
                return IntegralProjectivePlaneCurve(A, F)
            return ProjectivePlaneCurve_field(A, F)
        return ProjectivePlaneCurve(A, F)

    else:
        raise TypeError('ambient space neither affine nor projective')
Ejemplo n.º 22
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)
Ejemplo n.º 23
0
def enum_affine_rational_field(X, B):
    """
    Enumerates affine rational points on scheme ``X`` up to bound ``B``.

    INPUT:

    - ``X`` -  a scheme or set of abstract rational points of a scheme.
    - ``B`` -  a positive integer bound.

    OUTPUT:

    - a list containing the affine points of ``X`` of height up to ``B``,
      sorted.

    EXAMPLES::

        sage: A.<x,y,z> = AffineSpace(3, QQ)
        sage: from sage.schemes.affine.affine_rational_point import enum_affine_rational_field
        sage: enum_affine_rational_field(A(QQ), 1)
        [(-1, -1, -1), (-1, -1, 0), (-1, -1, 1), (-1, 0, -1), (-1, 0, 0), (-1, 0, 1),
        (-1, 1, -1), (-1, 1, 0), (-1, 1, 1), (0, -1, -1), (0, -1, 0), (0, -1, 1),
        (0, 0, -1), (0, 0, 0), (0, 0, 1), (0, 1, -1), (0, 1, 0), (0, 1, 1), (1, -1, -1),
        (1, -1, 0), (1, -1, 1), (1, 0, -1), (1, 0, 0), (1, 0, 1), (1, 1, -1), (1, 1, 0),
        (1, 1, 1)]

    ::

        sage: A.<w,x,y,z> = AffineSpace(4, QQ)
        sage: S = A.subscheme([x^2-y*z+3, w^3+z+y^2])
        sage: enum_affine_rational_field(S(QQ), 2)
        []
        sage: enum_affine_rational_field(S(QQ), 3)
        [(-2, 0, -3, -1)]

    ::

        sage: A.<x,y> = AffineSpace(2, QQ)
        sage: C = Curve(x^2+y-x)
        sage: enum_affine_rational_field(C, 10)
        [(-2, -6), (-1, -2), (0, 0), (1, 0), (2, -2), (3, -6)]


    AUTHORS:

    - David R. Kohel <*****@*****.**>: original version.

    - Charlie Turner (06-2010): small adjustments.
    """
    from sage.schemes.affine.affine_space import is_AffineSpace
    if(is_Scheme(X)):
        if (not is_AffineSpace(X.ambient_space())):
            raise TypeError("ambient space must be affine space over the rational field")
        X = X(X.base_ring())
    else:
        if (not is_AffineSpace(X.codomain().ambient_space())):
            raise TypeError("codomain must be affine space over the rational field")

    n = X.codomain().ambient_space().ngens()
    if X.value_ring() is ZZ:
        Q = [ 1 ]
    else: # rational field
        Q = range(1, B + 1)
    R = [ 0 ] + [ s*k for k in range(1, B+1) for s in [1, -1] ]
    pts = []
    P = [0] * n
    m = ZZ(0)
    try:
        pts.append(X(P))
    except TypeError:
        pass
    iters = [ iter(R) for _ in range(n) ]
    for it in iters:
        next(it)
    i = 0
    while i < n:
        try:
            a = ZZ(next(iters[i]))
        except StopIteration:
            iters[i] = iter(R) # reset
            P[i] = next(iters[i]) # reset P[i] to 0 and increment
            i += 1
            continue
        m = m.gcd(a)
        P[i] = a
        for b in Q:
            if m.gcd(b) == 1:
                try:
                    pts.append(X([ num/b for num in P ]))
                except TypeError:
                    pass
        i = 0
        m = ZZ(0)
    pts.sort()
    return pts
Ejemplo n.º 24
0
    def dynatomic_polynomial(self,period):
        r"""
        For a map `f:\mathbb{A}^1 \to \mathbb{A}^1` this function computes the (affine) dynatomic polynomial.
        The dynatomic polynomial is the analog of the cyclotomic polynomial and its roots are the points
        of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f:\mathbb{P}^1 \to \mathbb{P}^1` and compute the dynatomic polynomial there.
        Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]` where `m` is the preperiod and `n` is the period

        OUTPUT:

        - If possible, a single variable polynomial in the coordinate ring of ``self``.
          Otherwise a fraction field element of the coordinate ring of ``self``

        EXAMPLES::

            sage: A.<x,y>=AffineSpace(QQ,2)
            sage: H=Hom(A,A)
            sage: f=H([x^2+y^2,y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: Does not make sense in dimension >1

            ::

            sage: A.<x>=AffineSpace(ZZ,1)
            sage: H=Hom(A,A)
            sage: f=H([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

            ::

            sage: A.<x>=AffineSpace(CC,1)
            sage: H=Hom(A,A)
            sage: f=H([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

            ::

            sage: A.<x>=AffineSpace(QQ,1)
            sage: H=Hom(A,A)
            sage: f=H([x^2-10/9])
            sage: f.dynatomic_polynomial([2,1])
            531441*x^4 - 649539*x^2 - 524880
        """
        if self.domain() != self.codomain():
            raise TypeError("Must have same domain and codomain to iterate")
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.domain())==False:
            raise NotImplementedError("Not implemented for subschemes")
        if self.domain().dimension_relative()>1:
            raise TypeError("Does not make sense in dimension >1")
        F=self.homogenize(1).dynatomic_polynomial(period)
        if F.denominator()==1:
            R=F.parent()
            Vars=list(R.variable_names())
            Vars.pop()
            S=PolynomialRing(R.base_ring(),Vars)
            phi=R.hom([S.gen(0),1],S)
            return(phi(F))
        else:
            R=F.numerator().parent()
            Vars=list(R.variable_names())
            Vars.pop()
            S=PolynomialRing(R.base_ring(),Vars)
            phi=R.hom([S.gen(0),1],S)
            return(phi(F.numerator())/phi(F.denominator()))
Ejemplo n.º 25
0
 def __init__(self, A, f):
     P = f.parent()
     if not (is_AffineSpace(A) and A.dimension != 2):
         raise TypeError("Argument A (= %s) must be an affine plane."%A)
     Curve_generic.__init__(self, A, [f])
Ejemplo n.º 26
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)
Ejemplo n.º 27
0
    def dynatomic_polynomial(self,period):
        r"""
        For a map `f:\mathbb{A}^1 \to \mathbb{A}^1` this function computes the (affine) dynatomic polynomial.
        The dynatomic polynomial is the analog of the cyclotomic polynomial and its roots are the points
        of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f:\mathbb{P}^1 \to \mathbb{P}^1` and compute the dynatomic polynomial there.
        Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]` where `m` is the preperiod and `n` is the period

        OUTPUT:

        - If possible, a single variable polynomial in the coordinate ring of ``self``.
          Otherwise a fraction field element of the coordinate ring of ``self``

        EXAMPLES::

            sage: A.<x,y>=AffineSpace(QQ,2)
            sage: H=Hom(A,A)
            sage: f=H([x^2+y^2,y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: Does not make sense in dimension >1

            ::

            sage: A.<x>=AffineSpace(ZZ,1)
            sage: H=Hom(A,A)
            sage: f=H([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

            ::

            sage: A.<x>=AffineSpace(CC,1)
            sage: H=Hom(A,A)
            sage: f=H([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

            ::

            sage: A.<x>=AffineSpace(QQ,1)
            sage: H=Hom(A,A)
            sage: f=H([x^2-10/9])
            sage: f.dynatomic_polynomial([2,1])
            531441*x^4 - 649539*x^2 - 524880
        """
        if self.domain() != self.codomain():
            raise TypeError("Must have same domain and codomain to iterate")
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.domain())==False:
            raise NotImplementedError("Not implemented for subschemes")
        if self.domain().dimension_relative()>1:
            raise TypeError("Does not make sense in dimension >1")
        F=self.homogenize(1).dynatomic_polynomial(period)
        if F.denominator()==1:
            R=F.parent()
            Vars=list(R.variable_names())
            Vars.pop()
            S=PolynomialRing(R.base_ring(),Vars)
            phi=R.hom([S.gen(0),1],S)
            return(phi(F))
        else:
            R=F.numerator().parent()
            Vars=list(R.variable_names())
            Vars.pop()
            S=PolynomialRing(R.base_ring(),Vars)
            phi=R.hom([S.gen(0),1],S)
            return(phi(F.numerator())/phi(F.denominator()))
Ejemplo n.º 28
0
    def __classcall_private__(cls, dynamical_system, domain=None, ideal=None):
        """
        Return the appropriate dynamical system on Berkovich space.

        EXAMPLES::

            sage: R.<t> = Qp(3)[]
            sage: f = DynamicalSystem_affine(t^2 - 3)
            sage: DynamicalSystem_Berkovich(f)
            Dynamical system of Affine Berkovich line over Cp(3) of precision 20 induced by the map
              Defn: Defined on coordinates by sending ((1 + O(3^20))*t) to
                    ((1 + O(3^20))*t^2 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 +
                    2*3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + 2*3^14 +
                    2*3^15 + 2*3^16 + 2*3^17 + 2*3^18 + 2*3^19 + 2*3^20 + O(3^21))
        """
        if not (is_Berkovich_Cp(domain) or domain is None):
            raise TypeError(
                'domain must be a Berkovich space over Cp, not %s' % domain)

        if isinstance(domain, Berkovich_Cp_Affine):
            if not isinstance(dynamical_system, DynamicalSystem_affine):
                try:
                    dynamical_system = DynamicalSystem_affine(dynamical_system)
                except:
                    raise TypeError('domain was affine Berkovich space, but dynamical_system did not ' + \
                        'convert to an affine dynamical system')
        if isinstance(domain, Berkovich_Cp_Projective):
            if not isinstance(dynamical_system, DynamicalSystem_projective):
                try:
                    dynamical_system = DynamicalSystem_projective(
                        dynamical_system)
                except:
                    raise TypeError('domain was projective Berkovich space, but dynamical_system did not convert ' + \
                        'to a projective dynamical system')

        if not isinstance(dynamical_system, DynamicalSystem):
            try:
                dynamical_system = DynamicalSystem(dynamical_system)
            except:
                raise TypeError(
                    'dynamical_system did not convert to a dynamical system')
        morphism_domain = dynamical_system.domain()

        if not isinstance(morphism_domain.base_ring(), pAdicBaseGeneric):
            if morphism_domain.base_ring() in NumberFields():
                if domain is None and ideal is not None:
                    if is_AffineSpace(morphism_domain):
                        domain = Berkovich_Cp_Affine(
                            morphism_domain.base_ring(), ideal)
                    else:
                        domain = Berkovich_Cp_Projective(
                            morphism_domain, ideal)
                else:
                    if ideal is not None:
                        if ideal != domain.ideal():
                            raise ValueError(
                                'conflicting inputs for ideal and domain')
            else:
                raise ValueError('base ring of domain of dynamical_system must be p-adic or a number field ' + \
                    'not %s' %morphism_domain.base_ring())

        if is_AffineSpace(morphism_domain):
            return DynamicalSystem_Berkovich_affine(dynamical_system, domain)

        return DynamicalSystem_Berkovich_projective(dynamical_system, domain)
Ejemplo n.º 29
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)
Ejemplo n.º 30
0
    def dynatomic_polynomial(self, period):
        r"""
        For a map `f:\mathbb{A}^1 \to \mathbb{A}^1` this function computes 
        the (affine) dynatomic polynomial.

        The dynatomic polynomial is the analog of the cyclotomic polynomial and its roots are the points
        of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f:\mathbb{P}^1 \to \mathbb{P}^1` and compute the dynatomic polynomial there.
        Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]`,
          where `m` is the preperiod and `n` is the period.

        OUTPUT:

        - If possible, a single variable polynomial in the coordinate ring of the polynomial. \
          Otherwise a fraction field element of the coordinate ring of the polynomial.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: H = Hom(A, A)
            sage: f = H([x^2+y^2, y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: does not make sense in dimension >1

        ::

            sage: A.<x> = AffineSpace(ZZ, 1)
            sage: H = Hom(A, A)
            sage: f = H([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: H = Hom(A, A)
            sage: f = H([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

        ::

            sage: A.<x> = AffineSpace(QQ, 1)
            sage: H = Hom(A, A)
            sage: f = H([x^2-10/9])
            sage: f.dynatomic_polynomial([2, 1])
            531441*x^4 - 649539*x^2 - 524880

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: H = Hom(A, A)
            sage: f = H([x^2+CC.0])
            sage: f.dynatomic_polynomial(2)
            x^2 + x + 1.00000000000000 + 1.00000000000000*I

        ::

            sage: K.<c> = FunctionField(QQ)
            sage: A.<x> = AffineSpace(K, 1)
            sage: f = Hom(A, A)([x^2 + c])
            sage: f.dynatomic_polynomial(4)
            x^12 + 6*c*x^10 + x^9 + (15*c^2 + 3*c)*x^8 + 4*c*x^7 + (20*c^3 + 12*c^2 + 1)*x^6
            + (6*c^2 + 2*c)*x^5 + (15*c^4 + 18*c^3 + 3*c^2 + 4*c)*x^4 + (4*c^3 + 4*c^2 + 1)*x^3
            + (6*c^5 + 12*c^4 + 6*c^3 + 5*c^2 + c)*x^2 + (c^4 + 2*c^3 + c^2 + 2*c)*x
            + c^6 + 3*c^5 + 3*c^4 + 3*c^3 + 2*c^2 + 1
        """
        if self.domain() != self.codomain():
            raise TypeError("must have same domain and codomain to iterate")
        from sage.schemes.affine.affine_space import is_AffineSpace

        if is_AffineSpace(self.domain()) == False:
            raise NotImplementedError("not implemented for subschemes")
        if self.domain().dimension_relative() > 1:
            raise TypeError("does not make sense in dimension >1")
        F = self.homogenize(1).dynatomic_polynomial(period)
        if F.denominator() == 1:
            R = F.parent()
            S = self.coordinate_ring()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F)
        else:
            R = F.numerator().parent()
            S = self.coordinate_ring()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F.numerator()) / phi(F.denominator())
Ejemplo n.º 31
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)
Ejemplo n.º 32
0
    def dynatomic_polynomial(self, period):
        r"""
        Compute the (affine) dynatomic polynomial of a dynamical system
        `f: \mathbb{A}^1 \to \mathbb{A}^1`.

        The dynatomic polynomial is the analog of the cyclotomic polynomial
        and its roots are the points of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f: \mathbb{P}^1 \to \mathbb{P}^1` and compute
        the dynatomic polynomial there. Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]`,
          where `m` is the preperiod and `n` is the period

        OUTPUT:

        If possible, a single variable polynomial in the coordinate ring
        of the polynomial. Otherwise a fraction field element of the
        coordinate ring of the polynomial.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: f = DynamicalSystem_affine([x^2+y^2, y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: does not make sense in dimension >1

        ::

            sage: A.<x> = AffineSpace(ZZ, 1)
            sage: f = DynamicalSystem_affine([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: f = DynamicalSystem_affine([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

        ::

            sage: A.<x> = AffineSpace(QQ, 1)
            sage: f = DynamicalSystem_affine([x^2-10/9])
            sage: f.dynatomic_polynomial([2, 1])
            531441*x^4 - 649539*x^2 - 524880

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: f = DynamicalSystem_affine([x^2+CC.0])
            sage: f.dynatomic_polynomial(2)
            x^2 + x + 1.00000000000000 + 1.00000000000000*I

        ::

            sage: K.<c> = FunctionField(QQ)
            sage: A.<x> = AffineSpace(K, 1)
            sage: f = DynamicalSystem_affine([x^2 + c])
            sage: f.dynatomic_polynomial(4)
            x^12 + 6*c*x^10 + x^9 + (15*c^2 + 3*c)*x^8 + 4*c*x^7 + (20*c^3 + 12*c^2 + 1)*x^6
            + (6*c^2 + 2*c)*x^5 + (15*c^4 + 18*c^3 + 3*c^2 + 4*c)*x^4 + (4*c^3 + 4*c^2 + 1)*x^3
            + (6*c^5 + 12*c^4 + 6*c^3 + 5*c^2 + c)*x^2 + (c^4 + 2*c^3 + c^2 + 2*c)*x
            + c^6 + 3*c^5 + 3*c^4 + 3*c^3 + 2*c^2 + 1

        ::

            sage: A.<z> = AffineSpace(QQ, 1)
            sage: f = DynamicalSystem_affine([z^2+3/z+1/7])
            sage: f.dynatomic_polynomial(1).parent()
            Multivariate Polynomial Ring in z over Rational Field

        ::

            sage: R.<c> = QQ[]
            sage: A.<z> = AffineSpace(R,1)
            sage: f = DynamicalSystem_affine([z^2 + c])
            sage: f.dynatomic_polynomial([1,1])
            z^2 + z + c

        ::

            sage: A.<x> = AffineSpace(CC,1)
            sage: F = DynamicalSystem_affine([1/2*x^2 + CC(sqrt(3))])
            sage: F.dynatomic_polynomial([1,1])
            (0.125000000000000*x^4 + 0.366025403784439*x^2 + 1.50000000000000)/(0.500000000000000*x^2 - x + 1.73205080756888)
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if not is_AffineSpace(self.domain()):
            raise NotImplementedError("not implemented for subschemes")
        if self.domain().dimension_relative() > 1:
            raise TypeError("does not make sense in dimension >1")
        G = self.homogenize(1)
        F = G.dynatomic_polynomial(period)
        T = G.domain().coordinate_ring()
        S = self.domain().coordinate_ring()
        if is_SymbolicExpressionRing(F.parent()):
            u = var(self.domain().coordinate_ring().variable_name())
            return F.subs({F.variables()[0]:u,F.variables()[1]:1})
        elif T(F.denominator()).degree() == 0:
            R = F.parent()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F)
        else:
            R = F.numerator().parent()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F.numerator())/phi(F.denominator())
Ejemplo n.º 33
0
def enum_affine_rational_field(X, B):
    """
    Enumerates affine rational points on scheme ``X`` up to bound ``B``.

    INPUT:

    - ``X`` -  a scheme or set of abstract rational points of a scheme.
    - ``B`` -  a positive integer bound.

    OUTPUT:

    - a list containing the affine points of ``X`` of height up to ``B``,
      sorted.

    EXAMPLES::

        sage: A.<x,y,z> = AffineSpace(3, QQ)
        sage: from sage.schemes.affine.affine_rational_point import enum_affine_rational_field
        sage: enum_affine_rational_field(A(QQ), 1)
        [(-1, -1, -1), (-1, -1, 0), (-1, -1, 1), (-1, 0, -1), (-1, 0, 0), (-1, 0, 1),
        (-1, 1, -1), (-1, 1, 0), (-1, 1, 1), (0, -1, -1), (0, -1, 0), (0, -1, 1),
        (0, 0, -1), (0, 0, 0), (0, 0, 1), (0, 1, -1), (0, 1, 0), (0, 1, 1), (1, -1, -1),
        (1, -1, 0), (1, -1, 1), (1, 0, -1), (1, 0, 0), (1, 0, 1), (1, 1, -1), (1, 1, 0),
        (1, 1, 1)]

    ::

        sage: A.<w,x,y,z> = AffineSpace(4, QQ)
        sage: S = A.subscheme([x^2-y*z+3, w^3+z+y^2])
        sage: enum_affine_rational_field(S(QQ), 2)
        []
        sage: enum_affine_rational_field(S(QQ), 3)
        [(-2, 0, -3, -1)]

    ::

        sage: A.<x,y> = AffineSpace(2, QQ)
        sage: C = Curve(x^2+y-x)
        sage: enum_affine_rational_field(C, 10)
        [(-2, -6), (-1, -2), (0, 0), (1, 0), (2, -2), (3, -6)]


    AUTHORS:

    - David R. Kohel <*****@*****.**>: original version.

    - Charlie Turner (06-2010): small adjustments.
    """
    from sage.schemes.affine.affine_space import is_AffineSpace
    if (is_Scheme(X)):
        if (not is_AffineSpace(X.ambient_space())):
            raise TypeError(
                "ambient space must be affine space over the rational field")
        X = X(X.base_ring())
    else:
        if (not is_AffineSpace(X.codomain().ambient_space())):
            raise TypeError(
                "codomain must be affine space over the rational field")

    n = X.codomain().ambient_space().ngens()
    if X.value_ring() is ZZ:
        Q = [1]
    else:  # rational field
        Q = range(1, B + 1)
    R = [0] + [s * k for k in range(1, B + 1) for s in [1, -1]]
    pts = []
    P = [0] * n
    m = ZZ(0)
    try:
        pts.append(X(P))
    except TypeError:
        pass
    iters = [iter(R) for _ in range(n)]
    for it in iters:
        next(it)
    i = 0
    while i < n:
        try:
            a = ZZ(next(iters[i]))
        except StopIteration:
            iters[i] = iter(R)  # reset
            P[i] = next(iters[i])  # reset P[i] to 0 and increment
            i += 1
            continue
        m = m.gcd(a)
        P[i] = a
        for b in Q:
            if m.gcd(b) == 1:
                try:
                    pts.append(X([num / b for num in P]))
                except TypeError:
                    pass
        i = 0
        m = ZZ(0)
    pts.sort()
    return pts
Ejemplo n.º 34
0
    def points(self, **kwds):
        r"""
        Return some or all rational points of an affine scheme.

        For dimension 0 subschemes points are determined through a groebner
        basis calculation. For schemes or subschemes with dimension greater than 1
        points are determined through enumeration up to the specified bound.

        Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound
        are returned. For a zero-dimensional subscheme, all points are returned regardless of whether the field
        is infinite or not.

        For number fields, this uses the
        Doyle-Krumm algorithm 4 (algorithm 5 for imaginary quadratic) for
        computing algebraic numbers up to a given height [Doyle-Krumm]_.

        The algorithm requires floating point arithmetic, so the user is
        allowed to specify the precision for such calculations.
        Additionally, due to floating point issues, points
        slightly larger than the bound may be returned. This can be controlled
        by lowering the tolerance.


        INPUT:

        kwds:

        - ``bound`` - real number (optional, default: 0). The bound for the
          height of the coordinates. Only used for subschemes with
          dimension at least 1.

        - ``zero_tolerance`` - positive real number (optional, default=10^(-10)).
          For numerically inexact fields, points are on the subscheme if they
          satisfy the equations to within tolerance.

        - ``tolerance`` - a rational number in (0,1] used in doyle-krumm algorithm-4
          for enumeration over number fields.

        - ``precision`` - the precision to use for computing the elements of
          bounded height of number fields.

        OUTPUT:

        - a list of rational points of a affine scheme

        .. WARNING::

           For numerically inexact fields such as ComplexField or RealField the
           list of points returned is very likely to be incomplete. It may also
           contain repeated points due to tolerance.

        EXAMPLES: The bug reported at #11526 is fixed::

            sage: A2 = AffineSpace(ZZ, 2)
            sage: F = GF(3)
            sage: A2(F).points()
            [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

        ::

            sage: A.<x,y> = ZZ[]
            sage: I = A.ideal(x^2-y^2-1)
            sage: V = AffineSpace(ZZ, 2)
            sage: X = V.subscheme(I)
            sage: M = X(ZZ)
            sage: M.points(bound=1)
            [(-1, 0), (1, 0)]

        ::

            sage: u = QQ['u'].0
            sage: K.<v> = NumberField(u^2 + 3)
            sage: A.<x,y> = AffineSpace(K, 2)
            sage: len(A(K).points(bound=2))
            1849

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: E = A.subscheme([x^2 + y^2 - 1, y^2 - x^3 + x^2 + x - 1])
            sage: E(A.base_ring()).points()
            [(-1, 0), (0, -1), (0, 1), (1, 0)]

        ::

            sage: A.<x,y> = AffineSpace(CC, 2)
            sage: E = A.subscheme([y^3 - x^3 - x^2, x*y])
            sage: E(A.base_ring()).points()
            verbose 0 (124: affine_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.
            [(-1.00000000000000, 0.000000000000000),
            (0.000000000000000, 0.000000000000000)]

        ::

            sage: A.<x1,x2> = AffineSpace(CDF, 2)
            sage: E = A.subscheme([x1^2 + x2^2 + x1*x2, x1 + x2])
            sage: E(A.base_ring()).points()
            verbose 0 (124: affine_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.
            [(0.0, 0.0)]
        """
        from sage.schemes.affine.affine_space import is_AffineSpace

        X = self.codomain()
        if not is_AffineSpace(X) and X.base_ring() in Fields():
            if hasattr(X.base_ring(), 'precision'):
                numerical = True
                verbose("Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.", level=0)
                zero_tol = RR(kwds.pop('zero_tolerance', 10**(-10)))
                if zero_tol <= 0:
                    raise ValueError("tolerance must be positive")
            else:
                numerical = False
            # Then X must be a subscheme
            dim_ideal = X.defining_ideal().dimension()
            if dim_ideal < 0: # no points
                return []
            if dim_ideal == 0: # if X zero-dimensional
                rat_points = []
                AS = X.ambient_space()
                N = AS.dimension_relative()
                BR = X.base_ring()
                #need a lexicographic ordering for elimination
                R = PolynomialRing(BR, N, AS.gens(), order='lex')
                I = R.ideal(X.defining_polynomials())
                I0 = R.ideal(0)
                #Determine the points through elimination
                #This is much faster than using the I.variety() function on each affine chart.
                G = I.groebner_basis()
                if G != [1]:
                    P = {}
                    points = [P]
                    #work backwards from solving each equation for the possible
                    #values of the next coordinate
                    for i in range(len(G) - 1, -1, -1):
                        new_points = []
                        good = 0
                        for P in points:
                            #substitute in our dictionary entry that has the values
                            #of coordinates known so far. This results in a single
                            #variable polynomial (by elimination)
                            L = G[i].substitute(P)
                            if R(L).degree() > 0:
                                if numerical:
                                    for pol in L.univariate_polynomial().roots(multiplicities=False):
                                        r = L.variables()[0]
                                        varindex = R.gens().index(r)
                                        P.update({R.gen(varindex):pol})
                                        new_points.append(copy(P))
                                        good = 1
                                else:
                                    L = L.factor()
                                #the linear factors give the possible rational values of
                                #this coordinate
                                    for pol, pow in L:
                                        if pol.degree() == 1 and len(pol.variables()) == 1:
                                            good = 1
                                            r = pol.variables()[0]
                                            varindex = R.gens().index(r)
                                            #add this coordinates information to
                                            #each dictionary entry
                                            P.update({R.gen(varindex):-pol.constant_coefficient() /
                                            pol.monomial_coefficient(r)})
                                            new_points.append(copy(P))
                            else:
                                new_points.append(P)
                                good = 1
                        if good:
                            points = new_points
                    #the dictionary entries now have values for all coordinates
                    #they are the rational solutions to the equations
                    #make them into affine points
                    for i in range(len(points)):
                        if numerical:
                            if len(points[i]) == N:
                                S = AS([points[i][R.gen(j)] for j in range(N)])
                                if all([g(list(S)) < zero_tol for g in X.defining_polynomials()]):
                                    rat_points.append(S)
                        else:
                            if len(points[i]) == N and I.subs(points[i]) == I0:
                                S = X([points[i][R.gen(j)] for j in range(N)])
                                rat_points.append(S)

                rat_points = sorted(rat_points)
                return rat_points
        R = self.value_ring()
        B = kwds.pop('bound', 0)
        tol = kwds.pop('tolerance', 1e-2)
        prec = kwds.pop('precision', 53)
        if is_RationalField(R) or R == ZZ:
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified"%B)
            from sage.schemes.affine.affine_rational_point import enum_affine_rational_field
            return enum_affine_rational_field(self,B)
        if R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified"%B)
            from sage.schemes.affine.affine_rational_point import enum_affine_number_field
            return enum_affine_number_field(self, bound=B, tolerance=tol, precision=prec)
        elif is_FiniteField(R):
            from sage.schemes.affine.affine_rational_point import enum_affine_finite_field
            return enum_affine_finite_field(self)
        else:
            raise TypeError("unable to enumerate points over %s"%R)
Ejemplo n.º 35
0
    def homogenize(self,n,newvar='h'):
        r"""
        Return the homogenization of ``self``. If ``self.domain()`` is a subscheme, the domain of
        the homogenized map is the projective embedding of ``self.domain()``

        INPUT:

        - ``newvar`` -- the name of the homogenization variable (only used when ``self.domain()`` is affine space)

        - ``n`` -- the n-th projective embedding into projective space

        OUTPUT:

        - :class:`SchemMorphism_polynomial_projective_space`

        EXAMPLES::

            sage: A.<x,y>=AffineSpace(ZZ,2)
            sage: H=Hom(A,A)
            sage: f=H([(x^2-2)/x^5,y^2])
            sage: f.homogenize(2,'z')
            Scheme endomorphism of Projective Space of dimension 2 over Integer Ring
              Defn: Defined on coordinates by sending (x : y : z) to
                    (x^2*z^5 - 2*z^7 : x^5*y^2 : x^5*z^2)

        ::

            sage: A.<x,y>=AffineSpace(CC,2)
            sage: H=Hom(A,A)
            sage: f=H([(x^2-2)/(x*y),y^2-x])
            sage: f.homogenize(0,'z')
            Scheme endomorphism of Projective Space of dimension 2 over Complex
            Field with 53 bits of precision
              Defn: Defined on coordinates by sending (x : y : z) to
                    (x*y*z^2 : x^2*z^2 + (-2.00000000000000)*z^4 : x*y^3 - x^2*y*z)

        ::

            sage: A.<x,y>=AffineSpace(ZZ,2)
            sage: X=A.subscheme([x-y^2])
            sage: H=Hom(X,X)
            sage: f=H([9*y^2,3*y])
            sage: f.homogenize(2)
            Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 over Integer Ring defined by:
              -x1^2 + x0*x2
              Defn: Defined on coordinates by sending (x0 : x1 : x2) to
                    (9*x0*x2 : 3*x1*x2 : x2^2)

        ::

            sage: R.<t>=PolynomialRing(ZZ)
            sage: A.<x,y>=AffineSpace(R,2)
            sage: H=Hom(A,A)
            sage: f=H([(x^2-2)/y,y^2-x])
            sage: f.homogenize(0,'z')
            Scheme endomorphism of Projective Space of dimension 2 over Univariate
            Polynomial Ring in t over Integer Ring
              Defn: Defined on coordinates by sending (x : y : z) to
                    (y*z^2 : x^2*z + (-2)*z^3 : y^3 - x*y*z)
        """
        A=self.domain()
        B=self.codomain()
        N=A.ambient_space().dimension_relative()
        NB=B.ambient_space().dimension_relative()
        Vars=list(A.ambient_space().variable_names())+[newvar]
        S=PolynomialRing(A.base_ring(),Vars)
        try:
            l=lcm([self[i].denominator() for i in range(N)])
        except Exception:  #no lcm
            l=prod([self[i].denominator() for i in range(N)])

        from sage.rings.polynomial.polynomial_ring import PolynomialRing_general
        from sage.rings.polynomial.multi_polynomial_ring_generic import MPolynomialRing_generic
        if self.domain().base_ring()==RealField() or self.domain().base_ring()==ComplexField():
            F=[S(((self[i]*l).numerator())._maxima_().divide(self[i].denominator())[0].sage()) for i in range(N)]
        elif isinstance(self.domain().base_ring(),(PolynomialRing_general,MPolynomialRing_generic)):
            F=[S(((self[i]*l).numerator())._maxima_().divide(self[i].denominator())[0].sage()) for i in range(N)]
        else:
            F=[S(self[i]*l) for i in range(N)]
        F.insert(n,S(l))
        d=max([F[i].degree() for i in range(N+1)])
        F=[F[i].homogenize(newvar)*S.gen(N)**(d-F[i].degree()) for i in range(N+1)]
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(A)==True:
            from sage.schemes.projective.projective_space import ProjectiveSpace
            X=ProjectiveSpace(A.base_ring(),NB,Vars)
        else:
            X=A.projective_embedding(n).codomain()
            phi=S.hom(X.ambient_space().gens(),X.ambient_space().coordinate_ring())
            F=[phi(f) for f in F]
        H=Hom(X,X)
        return(H(F))
Ejemplo n.º 36
0
    def numerical_points(self, F=None, **kwds):
        """
        Return some or all numerical approximations of rational points of an affine scheme.

        This is for dimension 0 subschemes only and the points are determined
        through a groebner calculation over the base ring and then numerically
        approximating the roots of the resulting polynomials. If the base ring
        is a number field, the embedding into ``F`` must be known.

        INPUT:

        ``F`` - numerical ring

        kwds:

        - ``zero_tolerance`` - positive real number (optional, default=10^(-10)).
          For numerically inexact fields, points are on the subscheme if they
          satisfy the equations to within tolerance.

        OUTPUT: A list of points in the ambient space.

        .. WARNING::

           For numerically inexact fields the list of points returned may contain repeated
           or be missing points due to tolerance.

        EXAMPLES::

            sage: K.<v> = QuadraticField(3)
            sage: A.<x,y> = AffineSpace(K, 2)
            sage: X = A.subscheme([x^3 - v^2*y, y - v*x^2 + 3])
            sage: L = X(K).numerical_points(F=RR); L  # abs tol 1e-14
            [(-1.18738247880014, -0.558021142104134),
             (1.57693558184861, 1.30713548084184),
             (4.80659931965815, 37.0162574656220)]
            sage: L[0].codomain()
            Affine Space of dimension 2 over Real Field with 53 bits of precision

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: X = A.subscheme([y^2 - x^2 - 3*x, x^2 - 10*y])
            sage: len(X(QQ).numerical_points(F=ComplexField(100)))
            4

        ::

            sage: A.<x1, x2> = AffineSpace(QQ, 2)
            sage: E = A.subscheme([30*x1^100 + 1000*x2^2 + 2000*x1*x2 + 1, x1 + x2])
            sage: len(E(A.base_ring()).numerical_points(F=CDF, zero_tolerance=1e-9))
            100

        TESTS::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: X = A.subscheme([y^2 - x^2 - 3*x, x^2 - 10*y])
            sage: X(QQ).numerical_points(F=QQ)
            Traceback (most recent call last):
            ...
            TypeError: F must be a numerical field

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: X = A.subscheme([y^2 - x^2 - 3*x, x^2 - 10*y])
            sage: X(QQ).numerical_points(F=CC, zero_tolerance=-1)
            Traceback (most recent call last):
            ...
            ValueError: tolerance must be positive
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if F is None:
            F = CC
        if not F in Fields() or not hasattr(F, 'precision'):
            raise TypeError('F must be a numerical field')
        X = self.codomain()
        if X.base_ring() not in NumberFields():
            raise TypeError('base ring must be a number field')

        AA = X.ambient_space().change_ring(F)
        if not is_AffineSpace(X) and X.base_ring() in Fields():
            # Then X must be a subscheme
            dim_ideal = X.defining_ideal().dimension()
            if dim_ideal != 0: # no points
                return []
        else:
            return []

        # if X zero-dimensional
        zero_tol = RR(kwds.pop('zero_tolerance', 10**(-10)))
        if zero_tol <= 0:
            raise ValueError("tolerance must be positive")
        rat_points = []
        PS = X.ambient_space()
        N = PS.dimension_relative()
        BR = X.base_ring()
        # need a lexicographic ordering for elimination
        R = PolynomialRing(BR, N, PS.gens(), order='lex')
        RF = R.change_ring(F)
        I = R.ideal(X.defining_polynomials())
        I0 = R.ideal(0)
        # Determine the points through elimination This is much faster
        # than using the I.variety() function on each affine chart.
        G = I.groebner_basis()
        G = [RF(g) for g in G]
        if G != [1]:
            P = {}
            points = [P]
            # work backwards from solving each equation for the possible
            # values of the next coordinate
            for g in reversed(G):
                new_points = []
                good = False
                for P in points:
                    # substitute in our dictionary entry that has the
                    # values of coordinates known so far. This results
                    # in a single variable polynomial (by elimination)
                    L = g.substitute(P)
                    if len(RF(L).variables()) == 1:
                        r = L.variables()[0]
                        var = RF.gen(RF.gens().index(r))

                        for pol in L.univariate_polynomial().roots(ring=F,
                                multiplicities=False):
                            P[var] = pol
                            new_points.append(copy(P))
                            good = True
                    else:
                        new_points.append(P)
                        good = True
                if good:
                    points = new_points
            # the dictionary entries now have values for all
            # coordinates they are the rational solutions to the
            # equations make them into affine points
            polys = [g.change_ring(F) for g in X.defining_polynomials()]
            for P in points:
                if len(P) == N:
                    S = AA([P[R.gen(j)] for j in range(N)])
                    if all([g(list(S)) < zero_tol for g in polys]):
                        rat_points.append(S)

        rat_points = sorted(rat_points)
        return rat_points
Ejemplo n.º 37
0
def Curve(F, A=None):
    """
    Return the plane or space curve defined by ``F``, where
    ``F`` can be either a multivariate polynomial, a list or
    tuple of polynomials, or an algebraic scheme.

    If no ambient space is passed in for ``A``, and if ``F`` is not
    an algebraic scheme, a new ambient space is constructed.

    Also not specifying an ambient space will cause the curve to be defined
    in either affine or projective space based on properties of ``F``. In
    particular, if ``F`` contains a nonhomogenous polynomial, the curve is
    affine, and if ``F`` consists of homogenous polynomials, then the curve
    is projective.

    INPUT:

    - ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme.

    - ``A`` -- (default: None) an ambient space in which to create the curve.

    EXAMPLES: A projective plane curve

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3); C
        Projective Plane Curve over Rational Field defined by x^3 + y^3 + z^3
        sage: C.genus()
        1

    EXAMPLES: Affine plane curves

    ::

        sage: x,y = GF(7)['x,y'].gens()
        sage: C = Curve(y^2 + x^3 + x^10); C
        Affine Plane Curve over Finite Field of size 7 defined by x^10 + x^3 + y^2
        sage: C.genus()
        0
        sage: x, y = QQ['x,y'].gens()
        sage: Curve(x^3 + y^3 + 1)
        Affine Plane Curve over Rational Field defined by x^3 + y^3 + 1

    EXAMPLES: A projective space curve

    ::

        sage: x,y,z,w = QQ['x,y,z,w'].gens()
        sage: C = Curve([x^3 + y^3 - z^3 - w^3, x^5 - y*z^4]); C
        Projective Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4
        sage: C.genus()
        13

    EXAMPLES: An affine space curve

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve([y^2 + x^3 + x^10 + z^7,  x^2 + y^2]); C
        Affine Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2
        sage: C.genus()
        47

    EXAMPLES: We can also make non-reduced non-irreducible curves.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve((x-y)*(x+y))
        Projective Conic Curve over Rational Field defined by x^2 - y^2
        sage: Curve((x-y)^2*(x+y)^2)
        Projective Plane Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4

    EXAMPLES: A union of curves is a curve.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3)
        sage: D = Curve(x^4 + y^4 + z^4)
        sage: C.union(D)
        Projective Plane Curve over Rational Field defined by
        x^7 + x^4*y^3 + x^3*y^4 + y^7 + x^4*z^3 + y^4*z^3 + x^3*z^4 + y^3*z^4 + z^7

    The intersection is not a curve, though it is a scheme.

    ::

        sage: X = C.intersection(D); X
        Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
         x^3 + y^3 + z^3,
         x^4 + y^4 + z^4

    Note that the intersection has dimension `0`.

    ::

        sage: X.dimension()
        0
        sage: I = X.defining_ideal(); I
        Ideal (x^3 + y^3 + z^3, x^4 + y^4 + z^4) of Multivariate Polynomial Ring in x, y, z over Rational Field

    EXAMPLES: In three variables, the defining equation must be
    homogeneous.

    If the parent polynomial ring is in three variables, then the
    defining ideal must be homogeneous.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve(x^2+y^2)
        Projective Conic Curve over Rational Field defined by x^2 + y^2
        sage: Curve(x^2+y^2+z)
        Traceback (most recent call last):
        ...
        TypeError: x^2 + y^2 + z is not a homogeneous polynomial

    The defining polynomial must always be nonzero::

        sage: P1.<x,y> = ProjectiveSpace(1,GF(5))
        sage: Curve(0*x)
        Traceback (most recent call last):
        ...
        ValueError: defining polynomial of curve must be nonzero

    ::

        sage: A.<x,y,z> = AffineSpace(QQ, 3)
        sage: C = Curve([y - x^2, z - x^3], A)
        sage: A == C.ambient_space()
        True
    """
    if not A is None:
        if not isinstance(F, (list, tuple)):
            return Curve([F], A)
        if not is_AmbientSpace(A):
            raise TypeError("A (=%s) must be either an affine or projective space"%A)
        if not all([f.parent() == A.coordinate_ring() for f in F]):
            raise TypeError("F (=%s) must be a list or tuple of polynomials of the coordinate ring of " \
            "A (=%s)"%(F, A))
        n = A.dimension_relative()
        if n < 2:
            raise TypeError("A (=%s) must be either an affine or projective space of dimension > 1"%A)
        # there is no dimension check when initializing a plane curve, so check here that F consists
        # of a single nonconstant polynomial
        if n == 2:
            if len(F) != 1 or F[0] == 0 or not is_MPolynomial(F[0]):
                raise TypeError("F (=%s) must consist of a single nonconstant polynomial to define a plane curve"%(F,))
        if is_AffineSpace(A):
            if n > 2:
                return AffineCurve(A, F)
            k = A.base_ring()
            if is_FiniteField(k):
                if k.is_prime_field():
                    return AffinePlaneCurve_prime_finite_field(A, F[0])
                return AffinePlaneCurve_finite_field(A, F[0])
            return AffinePlaneCurve(A, F[0])
        elif is_ProjectiveSpace(A):
            if not all([f.is_homogeneous() for f in F]):
                raise TypeError("polynomials defining a curve in a projective space must be homogeneous")
            if n > 2:
                return ProjectiveCurve(A, F)
            k = A.base_ring()
            if is_FiniteField(k):
                if k.is_prime_field():
                    return ProjectivePlaneCurve_prime_finite_field(A, F[0])
                return ProjectivePlaneCurve_finite_field(A, F[0])
            return ProjectivePlaneCurve(A, F[0])

    if is_AlgebraicScheme(F):
        return Curve(F.defining_polynomials(), F.ambient_space())

    if isinstance(F, (list, tuple)):
        if len(F) == 1:
            return Curve(F[0])
        F = Sequence(F)
        P = F.universe()
        if not is_MPolynomialRing(P):
            raise TypeError("universe of F must be a multivariate polynomial ring")

        for f in F:
            if not f.is_homogeneous():
                A = AffineSpace(P.ngens(), P.base_ring())
                A._coordinate_ring = P
                return AffineCurve(A, F)

        A = ProjectiveSpace(P.ngens()-1, P.base_ring())
        A._coordinate_ring = P
        return ProjectiveCurve(A, F)

    if not is_MPolynomial(F):
        raise TypeError("F (=%s) must be a multivariate polynomial"%F)

    P = F.parent()
    k = F.base_ring()
    if F.parent().ngens() == 2:
        if F == 0:
            raise ValueError("defining polynomial of curve must be nonzero")
        A2 = AffineSpace(2, P.base_ring())
        A2._coordinate_ring = P

        if is_FiniteField(k):
            if k.is_prime_field():
                return AffinePlaneCurve_prime_finite_field(A2, F)
            else:
                return AffinePlaneCurve_finite_field(A2, F)
        else:
            return AffinePlaneCurve(A2, F)

    elif F.parent().ngens() == 3:
        if F == 0:
            raise ValueError("defining polynomial of curve must be nonzero")
        P2 = ProjectiveSpace(2, P.base_ring())
        P2._coordinate_ring = P

        if F.total_degree() == 2 and k.is_field():
            return Conic(F)

        if is_FiniteField(k):
            if k.is_prime_field():
                return ProjectivePlaneCurve_prime_finite_field(P2, F)
            else:
                return ProjectivePlaneCurve_finite_field(P2, F)
        else:
            return ProjectivePlaneCurve(P2, F)


    else:

        raise TypeError("Number of variables of F (=%s) must be 2 or 3"%F)
Ejemplo n.º 38
0
    def points(self, B=0):
        r"""
        Return some or all rational points of an affine scheme.

        INPUT:

        - ``B`` -- integer (optional, default: 0). The bound for the
          height of the coordinates.

        OUTPUT:

        - If the base ring is a finite field: all points of the scheme,
          given by coordinate tuples.

        - If the base ring is `\QQ` or `\ZZ`: the subset of points whose
          coordinates have height ``B`` or less.

        EXAMPLES: The bug reported at #11526 is fixed::

            sage: A2 = AffineSpace(ZZ, 2)
            sage: F = GF(3)
            sage: A2(F).points()
            [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

            sage: R = ZZ
            sage: A.<x,y> = R[]
            sage: I = A.ideal(x^2-y^2-1)
            sage: V = AffineSpace(R, 2)
            sage: X = V.subscheme(I)
            sage: M = X(R)
            sage: M.points(1)
            [(-1, 0), (1, 0)]

        ::

            sage: u = QQ['u'].0
            sage: K.<v> = NumberField(u^2 + 3)
            sage: A.<x,y> = AffineSpace(K, 2)
            sage: len(A(K).points(9))
            361

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: E = A.subscheme([x^2 + y^2 - 1, y^2 - x^3 + x^2 + x - 1])
            sage: E(A.base_ring()).points()
            [(-1, 0), (0, -1), (0, 1), (1, 0)]
        """
        X = self.codomain()

        from sage.schemes.affine.affine_space import is_AffineSpace
        if not is_AffineSpace(X) and X.base_ring() in Fields():
            # Then X must be a subscheme
            dim_ideal = X.defining_ideal().dimension()
            if dim_ideal < 0: # no points
                return []
            if dim_ideal == 0: # if X zero-dimensional
                N = len(X.ambient_space().gens())
                S = X.defining_polynomials()[0].parent()
                R = PolynomialRing(S.base_ring(), 's', N, order='lex')
                phi = S.hom(R.gens(),R)
                J = R.ideal([phi(t) for t in X.defining_polynomials()])
                D = J.variety()
                points = []
                for d in D:
                    P = [d[t] for t in R.gens()]
                    points.append(X(P))
                points.sort()
                return points
        R = self.value_ring()
        if is_RationalField(R) or R == ZZ:
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified"%B)
            from sage.schemes.affine.affine_rational_point import enum_affine_rational_field
            return enum_affine_rational_field(self,B)
        if R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified"%B)
            from sage.schemes.affine.affine_rational_point import enum_affine_number_field
            return enum_affine_number_field(self,B)
        elif is_FiniteField(R):
            from sage.schemes.affine.affine_rational_point import enum_affine_finite_field
            return enum_affine_finite_field(self)
        else:
            raise TypeError("unable to enumerate points over %s"%R)
Ejemplo n.º 39
0
    def homogenize(self,n,newvar='h'):
        r"""
        Return the homogenization of ``self``. If ``self.domain()`` is a subscheme, the domain of
        the homogenized map is the projective embedding of ``self.domain()``. The domain and codomain
        can be homogenized at different coordinates: ``n[0]`` for the domain and ``n[1]`` for the codomain.

        INPUT:

        - ``newvar`` -- the name of the homogenization variable (only used when ``self.domain()`` is affine space)

        - ``n`` -- a tuple of nonnegative integers. If ``n`` is an integer, then the two values of
            the tuple are assumed to be the same.

        OUTPUT:

        - :class:`SchemMorphism_polynomial_projective_space`

        EXAMPLES::

            sage: A.<x,y>=AffineSpace(ZZ,2)
            sage: H=Hom(A,A)
            sage: f=H([(x^2-2)/x^5,y^2])
            sage: f.homogenize(2,'z')
            Scheme endomorphism of Projective Space of dimension 2 over Integer Ring
              Defn: Defined on coordinates by sending (x : y : z) to
                    (x^2*z^5 - 2*z^7 : x^5*y^2 : x^5*z^2)

        ::

            sage: A.<x,y>=AffineSpace(CC,2)
            sage: H=Hom(A,A)
            sage: f=H([(x^2-2)/(x*y),y^2-x])
            sage: f.homogenize((2,0),'z')
            Scheme endomorphism of Projective Space of dimension 2 over Complex
            Field with 53 bits of precision
              Defn: Defined on coordinates by sending (x : y : z) to
                    (x*y*z^2 : x^2*z^2 + (-2.00000000000000)*z^4 : x*y^3 - x^2*y*z)

        ::

            sage: A.<x,y>=AffineSpace(ZZ,2)
            sage: X=A.subscheme([x-y^2])
            sage: H=Hom(X,X)
            sage: f=H([9*y^2,3*y])
            sage: f.homogenize(2)
            Scheme endomorphism of Closed subscheme of Projective Space of dimension 2 over Integer Ring defined by:
              -x1^2 + x0*x2
              Defn: Defined on coordinates by sending (x0 : x1 : x2) to
                    (9*x0*x2 : 3*x1*x2 : x2^2)

        ::

            sage: R.<t>=PolynomialRing(ZZ)
            sage: A.<x,y>=AffineSpace(R,2)
            sage: H=Hom(A,A)
            sage: f=H([(x^2-2)/y,y^2-x])
            sage: f.homogenize((2,0),'z')
            Scheme endomorphism of Projective Space of dimension 2 over Univariate
            Polynomial Ring in t over Integer Ring
              Defn: Defined on coordinates by sending (x : y : z) to
                    (y*z^2 : x^2*z + (-2)*z^3 : y^3 - x*y*z)

        ::

            sage: A.<x>=AffineSpace(QQ,1)
            sage: H=End(A)
            sage: f=H([x^2-1])
            sage: f.homogenize((1,0),'y')
            Scheme endomorphism of Projective Space of dimension 1 over Rational
            Field
              Defn: Defined on coordinates by sending (x : y) to
                    (y^2 : x^2 - y^2)
        """
        A=self.domain()
        B=self.codomain()
        N=A.ambient_space().dimension_relative()
        NB=B.ambient_space().dimension_relative()

        #it is possible to homogenize the domain and codomain at different coordinates
        if isinstance(n,(tuple,list)):
            ind=tuple(n)
        else:
            ind=(n,n)

        #homogenize the domain
        Vars=list(A.ambient_space().variable_names())
        Vars.insert(ind[0],newvar)
        S=PolynomialRing(A.base_ring(),Vars)

        #find the denominators if a rational function
        try:
            l=lcm([self[i].denominator() for i in range(N)])
        except Exception:  #no lcm
            l=prod([self[i].denominator() for i in range(N)])

        from sage.rings.polynomial.polynomial_ring import PolynomialRing_general
        from sage.rings.polynomial.multi_polynomial_ring_generic import MPolynomialRing_generic
        if self.domain().base_ring()==RealField() or self.domain().base_ring()==ComplexField():
            F=[S(((self[i]*l).numerator())._maxima_().divide(self[i].denominator())[0].sage()) for i in range(N)]
        elif isinstance(self.domain().base_ring(),(PolynomialRing_general,MPolynomialRing_generic)):
            F=[S(((self[i]*l).numerator())._maxima_().divide(self[i].denominator())[0].sage()) for i in range(N)]
        else:
            F=[S(self[i]*l) for i in range(N)]

        #homogenize the codomain
        F.insert(ind[1],S(l))
        d=max([F[i].degree() for i in range(N+1)])
        F=[F[i].homogenize(newvar)*S.gen(N)**(d-F[i].degree()) for i in range(N+1)]
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(A)==True:
            from sage.schemes.projective.projective_space import ProjectiveSpace
            X=ProjectiveSpace(A.base_ring(),NB,Vars)
        else:
            X=A.projective_embedding(ind[1]).codomain()
            phi=S.hom(X.ambient_space().gens(),X.ambient_space().coordinate_ring())
            F=[phi(f) for f in F]
        H=Hom(X,X)
        return(H(F))
Ejemplo n.º 40
0
def enum_affine_number_field(X, **kwds):
    """
    Enumerates affine points on scheme ``X`` defined over a number field. Simply checks all of the
    points of absolute height up to ``B`` and adds those that are on the scheme to the list.

    This algorithm computes 2 lists: L containing elements x in `K` such that
    H_k(x) <= B, and a list L' containing elements x in `K` that, due to
    floating point issues,
    may be slightly larger then the bound. This can be controlled
    by lowering the tolerance.

    ALGORITHM:

    This is an implementation of the revised algorithm (Algorithm 4) in
    [Doyle-Krumm]_. Algorithm 5 is used for imaginary quadratic fields.


    INPUT:

    kwds:

    - ``bound`` - a real number

    - ``tolerance`` - a rational number in (0,1] used in doyle-krumm algorithm-4

    - ``precision`` - the precision to use for computing the elements of bounded height of number fields.

    OUTPUT:

     - a list containing the affine points of ``X`` of absolute height up to ``B``,
       sorted.

    EXAMPLES::

        sage: from sage.schemes.affine.affine_rational_point import enum_affine_number_field
        sage: u = QQ['u'].0
        sage: K = NumberField(u^2 + 2, 'v')
        sage: A.<x,y,z> = AffineSpace(K, 3)
        sage: X = A.subscheme([y^2 - x])
        sage: enum_affine_number_field(X(K), bound=2**0.5)
        [(0, 0, -1), (0, 0, -v), (0, 0, -1/2*v), (0, 0, 0), (0, 0, 1/2*v), (0, 0, v), (0, 0, 1),
        (1, -1, -1), (1, -1, -v), (1, -1, -1/2*v), (1, -1, 0), (1, -1, 1/2*v), (1, -1, v), (1, -1, 1),
        (1, 1, -1), (1, 1, -v), (1, 1, -1/2*v), (1, 1, 0), (1, 1, 1/2*v), (1, 1, v), (1, 1, 1)]

    ::

        sage: u = QQ['u'].0
        sage: K = NumberField(u^2 + 3, 'v')
        sage: A.<x,y> = AffineSpace(K, 2)
        sage: X=A.subscheme(x-y)
        sage: from sage.schemes.affine.affine_rational_point import enum_affine_number_field
        sage: enum_affine_number_field(X, bound=3**0.25)
        [(-1, -1), (-1/2*v - 1/2, -1/2*v - 1/2), (1/2*v - 1/2, 1/2*v - 1/2), (0, 0), (-1/2*v + 1/2, -1/2*v + 1/2),
        (1/2*v + 1/2, 1/2*v + 1/2), (1, 1)]
    """
    B = kwds.pop('bound')
    tol = kwds.pop('tolerance', 1e-2)
    prec = kwds.pop('precision', 53)
    from sage.schemes.affine.affine_space import is_AffineSpace
    if is_Scheme(X):
        if not is_AffineSpace(X.ambient_space()):
            raise TypeError(
                "ambient space must be affine space over a number field")
        X = X(X.base_ring())
    elif not is_AffineSpace(X.codomain().ambient_space()):
        raise TypeError("codomain must be affine space over a number field")

    R = X.codomain().ambient_space()

    pts = []
    for P in R.points_of_bounded_height(bound=B, tolerance=tol,
                                        precision=prec):
        try:
            pts.append(X(P))
        except TypeError:
            pass
    pts.sort()
    return pts
Ejemplo n.º 41
0
 def __init__(self, A, f):
     P = f.parent()
     if not (is_AffineSpace(A) and A.dimension != 2):
         raise TypeError("Argument A (= %s) must be an affine plane." % A)
     Curve_generic.__init__(self, A, [f])
Ejemplo n.º 42
0
def enum_affine_finite_field(X):
    r"""
    Enumerates affine points on scheme ``X`` defined over a finite field.

    INPUT:

    - ``X`` -  a scheme defined over a finite field or a set of abstract
      rational points of such a scheme.

    OUTPUT:

    - a list containing the affine points of ``X`` over the finite field,
      sorted.

    EXAMPLES::

        sage: F = GF(7)
        sage: A.<w,x,y,z> = AffineSpace(4, F)
        sage: C = A.subscheme([w^2+x+4, y*z*x-6, z*y+w*x])
        sage: from sage.schemes.affine.affine_rational_point import enum_affine_finite_field
        sage: enum_affine_finite_field(C(F))
        []
        sage: C = A.subscheme([w^2+x+4, y*z*x-6])
        sage: enum_affine_finite_field(C(F))
        [(0, 3, 1, 2), (0, 3, 2, 1), (0, 3, 3, 3), (0, 3, 4, 4), (0, 3, 5, 6),
        (0, 3, 6, 5), (1, 2, 1, 3), (1, 2, 2, 5), (1, 2, 3, 1), (1, 2, 4, 6),
        (1, 2, 5, 2), (1, 2, 6, 4), (2, 6, 1, 1), (2, 6, 2, 4), (2, 6, 3, 5),
        (2, 6, 4, 2), (2, 6, 5, 3), (2, 6, 6, 6), (3, 1, 1, 6), (3, 1, 2, 3),
        (3, 1, 3, 2), (3, 1, 4, 5), (3, 1, 5, 4), (3, 1, 6, 1), (4, 1, 1, 6),
        (4, 1, 2, 3), (4, 1, 3, 2), (4, 1, 4, 5), (4, 1, 5, 4), (4, 1, 6, 1),
        (5, 6, 1, 1), (5, 6, 2, 4), (5, 6, 3, 5), (5, 6, 4, 2), (5, 6, 5, 3),
        (5, 6, 6, 6), (6, 2, 1, 3), (6, 2, 2, 5), (6, 2, 3, 1), (6, 2, 4, 6),
        (6, 2, 5, 2), (6, 2, 6, 4)]

    ::

        sage: A.<x,y,z> = AffineSpace(3, GF(3))
        sage: S = A.subscheme(x+y)
        sage: enum_affine_finite_field(S)
        [(0, 0, 0), (0, 0, 1), (0, 0, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2),
        (2, 1, 0), (2, 1, 1), (2, 1, 2)]

    ALGORITHM:

    Checks all points in affine space to see if they lie on X.

    .. WARNING::

        If ``X`` is defined over an infinite field, this code will not finish!

    AUTHORS:

    - John Cremona and Charlie Turner (06-2010)
    """
    from sage.schemes.affine.affine_space import is_AffineSpace
    if is_Scheme(X):
        if not is_AffineSpace(X.ambient_space()):
            raise TypeError(
                "ambient space must be affine space over a finite field")
        X = X(X.base_ring())
    elif not is_AffineSpace(X.codomain().ambient_space()):
        raise TypeError("codomain must be affine space over a finite field")

    n = X.codomain().ambient_space().ngens()
    F = X.value_ring()
    pts = []
    for c in cartesian_product_iterator([F] * n):
        try:
            pts.append(X(c))
        except Exception:
            pass
    pts.sort()
    return pts
Ejemplo n.º 43
0
    def dynatomic_polynomial(self, period):
        r"""
        Compute the (affine) dynatomic polynomial of a dynamical system
        `f: \mathbb{A}^1 \to \mathbb{A}^1`.

        The dynatomic polynomial is the analog of the cyclotomic polynomial
        and its roots are the points of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f: \mathbb{P}^1 \to \mathbb{P}^1` and compute
        the dynatomic polynomial there. Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]`,
          where `m` is the preperiod and `n` is the period

        OUTPUT:

        If possible, a single variable polynomial in the coordinate ring
        of the polynomial. Otherwise a fraction field element of the
        coordinate ring of the polynomial.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: f = DynamicalSystem_affine([x^2+y^2, y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: does not make sense in dimension >1

        ::

            sage: A.<x> = AffineSpace(ZZ, 1)
            sage: f = DynamicalSystem_affine([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: f = DynamicalSystem_affine([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

        ::

            sage: A.<x> = AffineSpace(QQ, 1)
            sage: f = DynamicalSystem_affine([x^2-10/9])
            sage: f.dynatomic_polynomial([2, 1])
            531441*x^4 - 649539*x^2 - 524880

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: f = DynamicalSystem_affine([x^2+CC.0])
            sage: f.dynatomic_polynomial(2)
            x^2 + x + 1.00000000000000 + 1.00000000000000*I

        ::

            sage: K.<c> = FunctionField(QQ)
            sage: A.<x> = AffineSpace(K, 1)
            sage: f = DynamicalSystem_affine([x^2 + c])
            sage: f.dynatomic_polynomial(4)
            x^12 + 6*c*x^10 + x^9 + (15*c^2 + 3*c)*x^8 + 4*c*x^7 + (20*c^3 + 12*c^2 + 1)*x^6
            + (6*c^2 + 2*c)*x^5 + (15*c^4 + 18*c^3 + 3*c^2 + 4*c)*x^4 + (4*c^3 + 4*c^2 + 1)*x^3
            + (6*c^5 + 12*c^4 + 6*c^3 + 5*c^2 + c)*x^2 + (c^4 + 2*c^3 + c^2 + 2*c)*x
            + c^6 + 3*c^5 + 3*c^4 + 3*c^3 + 2*c^2 + 1

        ::

            sage: A.<z> = AffineSpace(QQ, 1)
            sage: f = DynamicalSystem_affine([z^2+3/z+1/7])
            sage: f.dynatomic_polynomial(1).parent()
            Multivariate Polynomial Ring in z over Rational Field

        ::

            sage: R.<c> = QQ[]
            sage: A.<z> = AffineSpace(R,1)
            sage: f = DynamicalSystem_affine([z^2 + c])
            sage: f.dynatomic_polynomial([1,1])
            z^2 + z + c

        ::

            sage: A.<x> = AffineSpace(CC,1)
            sage: F = DynamicalSystem_affine([1/2*x^2 + CC(sqrt(3))])
            sage: F.dynatomic_polynomial([1,1])
            (0.125000000000000*x^4 + 0.366025403784439*x^2 + 1.50000000000000)/(0.500000000000000*x^2 - x + 1.73205080756888)

        TESTS::

            sage: R.<c> = QQ[]
            sage: Pc.<x,y> = ProjectiveSpace(R, 1)
            sage: G = DynamicalSystem_projective([(1/2*c + 1/2)*x^2 + (-2*c)*x*y + 2*c*y^2 , \
                  (1/4*c + 1/2)*x^2 + (-c - 1)*x*y + (c + 1)*y^2])
            sage: G.dehomogenize(1).dynatomic_polynomial(2)
            (1/4*c + 1/4)*x^2 + (-c - 1/2)*x + c + 1
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if not is_AffineSpace(self.domain()):
            raise NotImplementedError("not implemented for subschemes")
        if self.domain().dimension_relative() > 1:
            raise TypeError("does not make sense in dimension >1")
        G = self.homogenize(1)
        F = G.dynatomic_polynomial(period)
        T = G.domain().coordinate_ring()
        S = self.domain().coordinate_ring()
        if is_SymbolicExpressionRing(F.parent()):
            u = var(self.domain().coordinate_ring().variable_name())
            return F.subs({F.variables()[0]: u, F.variables()[1]: 1})
        elif T(F.denominator()).degree() == 0:
            R = F.parent()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F)
        else:
            R = F.numerator().parent()
            phi = R.hom([S.gen(0), 1], S)
            return phi(F.numerator()) / phi(F.denominator())
Ejemplo n.º 44
0
def enum_affine_finite_field(X):
    r"""
    Enumerates affine points on scheme ``X`` defined over a finite field.

    INPUT:

    - ``X`` -  a scheme defined over a finite field or a set of abstract
      rational points of such a scheme.

    OUTPUT:

    - a list containing the affine points of ``X`` over the finite field,
      sorted.

    EXAMPLES::

        sage: F = GF(7)
        sage: A.<w,x,y,z> = AffineSpace(4, F)
        sage: C = A.subscheme([w^2+x+4, y*z*x-6, z*y+w*x])
        sage: from sage.schemes.affine.affine_rational_point import enum_affine_finite_field
        sage: enum_affine_finite_field(C(F))
        []
        sage: C = A.subscheme([w^2+x+4, y*z*x-6])
        sage: enum_affine_finite_field(C(F))
        [(0, 3, 1, 2), (0, 3, 2, 1), (0, 3, 3, 3), (0, 3, 4, 4), (0, 3, 5, 6),
        (0, 3, 6, 5), (1, 2, 1, 3), (1, 2, 2, 5), (1, 2, 3, 1), (1, 2, 4, 6),
        (1, 2, 5, 2), (1, 2, 6, 4), (2, 6, 1, 1), (2, 6, 2, 4), (2, 6, 3, 5),
        (2, 6, 4, 2), (2, 6, 5, 3), (2, 6, 6, 6), (3, 1, 1, 6), (3, 1, 2, 3),
        (3, 1, 3, 2), (3, 1, 4, 5), (3, 1, 5, 4), (3, 1, 6, 1), (4, 1, 1, 6),
        (4, 1, 2, 3), (4, 1, 3, 2), (4, 1, 4, 5), (4, 1, 5, 4), (4, 1, 6, 1),
        (5, 6, 1, 1), (5, 6, 2, 4), (5, 6, 3, 5), (5, 6, 4, 2), (5, 6, 5, 3),
        (5, 6, 6, 6), (6, 2, 1, 3), (6, 2, 2, 5), (6, 2, 3, 1), (6, 2, 4, 6),
        (6, 2, 5, 2), (6, 2, 6, 4)]

    ::

        sage: A.<x,y,z> = AffineSpace(3, GF(3))
        sage: S = A.subscheme(x+y)
        sage: enum_affine_finite_field(S)
        [(0, 0, 0), (0, 0, 1), (0, 0, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2),
        (2, 1, 0), (2, 1, 1), (2, 1, 2)]

    ALGORITHM:

    Checks all points in affine space to see if they lie on X.

    .. WARNING::

        If ``X`` is defined over an infinite field, this code will not finish!

    AUTHORS:

    - John Cremona and Charlie Turner (06-2010)
    """
    from sage.schemes.affine.affine_space import is_AffineSpace
    if(is_Scheme(X)):
        if (not is_AffineSpace(X.ambient_space())):
            raise TypeError("ambient space must be affine space over a finite field")
        X = X(X.base_ring())
    else:
        if (not is_AffineSpace(X.codomain().ambient_space())):
            raise TypeError("codomain must be affine space over a finite field")

    n = X.codomain().ambient_space().ngens()
    F = X.value_ring()
    pts = []
    for c in cartesian_product_iterator([F]*n):
        try:
            pts.append(X(c))
        except Exception:
            pass
    pts.sort()
    return pts
Ejemplo n.º 45
0
    def dynatomic_polynomial(self, period):
        r"""
        For a map `f:\mathbb{A}^1 \to \mathbb{A}^1` this function computes 
        the (affine) dynatomic polynomial.

        The dynatomic polynomial is the analog of the cyclotomic polynomial and its roots are the points
        of formal period `n`.

        ALGORITHM:

        Homogenize to a map `f:\mathbb{P}^1 \to \mathbb{P}^1` and compute the dynatomic polynomial there.
        Then, dehomogenize.

        INPUT:

        - ``period`` -- a positive integer or a list/tuple `[m,n]`,
          where `m` is the preperiod and `n` is the period.

        OUTPUT:

        - If possible, a single variable polynomial in the coordinate ring of the polynomial. \
          Otherwise a fraction field element of the coordinate ring of the polynomial.

        EXAMPLES::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: H = Hom(A, A)
            sage: f = H([x^2+y^2, y^2])
            sage: f.dynatomic_polynomial(2)
            Traceback (most recent call last):
            ...
            TypeError: does not make sense in dimension >1

        ::

            sage: A.<x> = AffineSpace(ZZ, 1)
            sage: H = Hom(A, A)
            sage: f = H([(x^2+1)/x])
            sage: f.dynatomic_polynomial(4)
            2*x^12 + 18*x^10 + 57*x^8 + 79*x^6 + 48*x^4 + 12*x^2 + 1

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: H = Hom(A, A)
            sage: f = H([(x^2+1)/(3*x)])
            sage: f.dynatomic_polynomial(3)
            13.0000000000000*x^6 + 117.000000000000*x^4 + 78.0000000000000*x^2 +
            1.00000000000000

        ::

            sage: A.<x> = AffineSpace(QQ, 1)
            sage: H = Hom(A, A)
            sage: f = H([x^2-10/9])
            sage: f.dynatomic_polynomial([2, 1])
            531441*x^4 - 649539*x^2 - 524880

        ::

            sage: A.<x> = AffineSpace(CC, 1)
            sage: H = Hom(A, A)
            sage: f = H([x^2+CC.0])
            sage: f.dynatomic_polynomial(2)
            x^2 + x + 1.00000000000000 + 1.00000000000000*I

        ::

            sage: K.<c> = FunctionField(QQ)
            sage: A.<x> = AffineSpace(K, 1)
            sage: f = Hom(A, A)([x^2 + c])
            sage: f.dynatomic_polynomial(4)
            x^12 + 6*c*x^10 + x^9 + (15*c^2 + 3*c)*x^8 + 4*c*x^7 + (20*c^3 + 12*c^2 + 1)*x^6
            + (6*c^2 + 2*c)*x^5 + (15*c^4 + 18*c^3 + 3*c^2 + 4*c)*x^4 + (4*c^3 + 4*c^2 + 1)*x^3
            + (6*c^5 + 12*c^4 + 6*c^3 + 5*c^2 + c)*x^2 + (c^4 + 2*c^3 + c^2 + 2*c)*x
            + c^6 + 3*c^5 + 3*c^4 + 3*c^3 + 2*c^2 + 1
        """
        if self.domain() != self.codomain():
            raise TypeError("must have same domain and codomain to iterate")
        from sage.schemes.affine.affine_space import is_AffineSpace
        if is_AffineSpace(self.domain()) == False:
            raise NotImplementedError("not implemented for subschemes")
        if self.domain().dimension_relative() > 1:
            raise TypeError("does not make sense in dimension >1")
        F = self.homogenize(1).dynatomic_polynomial(period)
        if F.denominator() == 1:
            R = F.parent()
            S = self.coordinate_ring()
            phi = R.hom([S.gen(0), 1], S)
            return (phi(F))
        else:
            R = F.numerator().parent()
            S = self.coordinate_ring()
            phi = R.hom([S.gen(0), 1], S)
            return (phi(F.numerator()) / phi(F.denominator()))
Ejemplo n.º 46
0
def Curve(F, A=None):
    """
    Return the plane or space curve defined by ``F``, where
    ``F`` can be either a multivariate polynomial, a list or
    tuple of polynomials, or an algebraic scheme.

    If no ambient space is passed in for ``A``, and if ``F`` is not
    an algebraic scheme, a new ambient space is constructed.

    Also not specifying an ambient space will cause the curve to be defined
    in either affine or projective space based on properties of ``F``. In
    particular, if ``F`` contains a nonhomogenous polynomial, the curve is
    affine, and if ``F`` consists of homogenous polynomials, then the curve
    is projective.

    INPUT:

    - ``F`` -- a multivariate polynomial, or a list or tuple of polynomials, or an algebraic scheme.

    - ``A`` -- (default: None) an ambient space in which to create the curve.

    EXAMPLE: A projective plane curve

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3); C
        Projective Plane Curve over Rational Field defined by x^3 + y^3 + z^3
        sage: C.genus()
        1

    EXAMPLE: Affine plane curves

    ::

        sage: x,y = GF(7)['x,y'].gens()
        sage: C = Curve(y^2 + x^3 + x^10); C
        Affine Plane Curve over Finite Field of size 7 defined by x^10 + x^3 + y^2
        sage: C.genus()
        0
        sage: x, y = QQ['x,y'].gens()
        sage: Curve(x^3 + y^3 + 1)
        Affine Plane Curve over Rational Field defined by x^3 + y^3 + 1

    EXAMPLE: A projective space curve

    ::

        sage: x,y,z,w = QQ['x,y,z,w'].gens()
        sage: C = Curve([x^3 + y^3 - z^3 - w^3, x^5 - y*z^4]); C
        Projective Curve over Rational Field defined by x^3 + y^3 - z^3 - w^3, x^5 - y*z^4
        sage: C.genus()
        13

    EXAMPLE: An affine space curve

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve([y^2 + x^3 + x^10 + z^7,  x^2 + y^2]); C
        Affine Curve over Rational Field defined by x^10 + z^7 + x^3 + y^2, x^2 + y^2
        sage: C.genus()
        47

    EXAMPLE: We can also make non-reduced non-irreducible curves.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve((x-y)*(x+y))
        Projective Conic Curve over Rational Field defined by x^2 - y^2
        sage: Curve((x-y)^2*(x+y)^2)
        Projective Plane Curve over Rational Field defined by x^4 - 2*x^2*y^2 + y^4

    EXAMPLE: A union of curves is a curve.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: C = Curve(x^3 + y^3 + z^3)
        sage: D = Curve(x^4 + y^4 + z^4)
        sage: C.union(D)
        Projective Plane Curve over Rational Field defined by
        x^7 + x^4*y^3 + x^3*y^4 + y^7 + x^4*z^3 + y^4*z^3 + x^3*z^4 + y^3*z^4 + z^7

    The intersection is not a curve, though it is a scheme.

    ::

        sage: X = C.intersection(D); X
        Closed subscheme of Projective Space of dimension 2 over Rational Field defined by:
         x^3 + y^3 + z^3,
         x^4 + y^4 + z^4

    Note that the intersection has dimension `0`.

    ::

        sage: X.dimension()
        0
        sage: I = X.defining_ideal(); I
        Ideal (x^3 + y^3 + z^3, x^4 + y^4 + z^4) of Multivariate Polynomial Ring in x, y, z over Rational Field

    EXAMPLE: In three variables, the defining equation must be
    homogeneous.

    If the parent polynomial ring is in three variables, then the
    defining ideal must be homogeneous.

    ::

        sage: x,y,z = QQ['x,y,z'].gens()
        sage: Curve(x^2+y^2)
        Projective Conic Curve over Rational Field defined by x^2 + y^2
        sage: Curve(x^2+y^2+z)
        Traceback (most recent call last):
        ...
        TypeError: x^2 + y^2 + z is not a homogeneous polynomial

    The defining polynomial must always be nonzero::

        sage: P1.<x,y> = ProjectiveSpace(1,GF(5))
        sage: Curve(0*x)
        Traceback (most recent call last):
        ...
        ValueError: defining polynomial of curve must be nonzero

    ::

        sage: A.<x,y,z> = AffineSpace(QQ, 3)
        sage: C = Curve([y - x^2, z - x^3], A)
        sage: A == C.ambient_space()
        True
    """
    if not A is None:
        if not isinstance(F, (list, tuple)):
            return Curve([F], A)
        if not is_AmbientSpace(A):
            raise TypeError(
                "A (=%s) must be either an affine or projective space" % A)
        if not all([f.parent() == A.coordinate_ring() for f in F]):
            raise TypeError("F (=%s) must be a list or tuple of polynomials of the coordinate ring of " \
            "A (=%s)"%(F, A))
        n = A.dimension_relative()
        if n < 2:
            raise TypeError(
                "A (=%s) must be either an affine or projective space of dimension > 1"
                % A)
        # there is no dimension check when initializing a plane curve, so check here that F consists
        # of a single nonconstant polynomial
        if n == 2:
            if len(F) != 1 or F[0] == 0 or not is_MPolynomial(F[0]):
                raise TypeError(
                    "F (=%s) must consist of a single nonconstant polynomial to define a plane curve"
                    % (F, ))
        if is_AffineSpace(A):
            if n > 2:
                return AffineCurve(A, F)
            k = A.base_ring()
            if is_FiniteField(k):
                if k.is_prime_field():
                    return AffinePlaneCurve_prime_finite_field(A, F[0])
                return AffinePlaneCurve_finite_field(A, F[0])
            return AffinePlaneCurve(A, F[0])
        elif is_ProjectiveSpace(A):
            if not all([f.is_homogeneous() for f in F]):
                raise TypeError(
                    "polynomials defining a curve in a projective space must be homogeneous"
                )
            if n > 2:
                return ProjectiveCurve(A, F)
            k = A.base_ring()
            if is_FiniteField(k):
                if k.is_prime_field():
                    return ProjectivePlaneCurve_prime_finite_field(A, F[0])
                return ProjectivePlaneCurve_finite_field(A, F[0])
            return ProjectivePlaneCurve(A, F[0])

    if is_AlgebraicScheme(F):
        return Curve(F.defining_polynomials(), F.ambient_space())

    if isinstance(F, (list, tuple)):
        if len(F) == 1:
            return Curve(F[0])
        F = Sequence(F)
        P = F.universe()
        if not is_MPolynomialRing(P):
            raise TypeError(
                "universe of F must be a multivariate polynomial ring")

        for f in F:
            if not f.is_homogeneous():
                A = AffineSpace(P.ngens(), P.base_ring())
                A._coordinate_ring = P
                return AffineCurve(A, F)

        A = ProjectiveSpace(P.ngens() - 1, P.base_ring())
        A._coordinate_ring = P
        return ProjectiveCurve(A, F)

    if not is_MPolynomial(F):
        raise TypeError("F (=%s) must be a multivariate polynomial" % F)

    P = F.parent()
    k = F.base_ring()
    if F.parent().ngens() == 2:
        if F == 0:
            raise ValueError("defining polynomial of curve must be nonzero")
        A2 = AffineSpace(2, P.base_ring())
        A2._coordinate_ring = P

        if is_FiniteField(k):
            if k.is_prime_field():
                return AffinePlaneCurve_prime_finite_field(A2, F)
            else:
                return AffinePlaneCurve_finite_field(A2, F)
        else:
            return AffinePlaneCurve(A2, F)

    elif F.parent().ngens() == 3:
        if F == 0:
            raise ValueError("defining polynomial of curve must be nonzero")
        P2 = ProjectiveSpace(2, P.base_ring())
        P2._coordinate_ring = P

        if F.total_degree() == 2 and k.is_field():
            return Conic(F)

        if is_FiniteField(k):
            if k.is_prime_field():
                return ProjectivePlaneCurve_prime_finite_field(P2, F)
            else:
                return ProjectivePlaneCurve_finite_field(P2, F)
        else:
            return ProjectivePlaneCurve(P2, F)

    else:

        raise TypeError("Number of variables of F (=%s) must be 2 or 3" % F)
Ejemplo n.º 47
0
    def points(self, **kwds):
        r"""
        Return some or all rational points of an affine scheme.

        Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound
        are returned. For a zero-dimensional subscheme, all points are returned regardless of whether the field
        is infinite or not.

        For number fields, this uses the
        Doyle-Krumm algorithm 4 (algorithm 5 for imaginary quadratic) for
        computing algebraic numbers up to a given height [Doyle-Krumm]_.

        The algorithm requires floating point arithmetic, so the user is
        allowed to specify the precision for such calculations.
        Additionally, due to floating point issues, points
        slightly larger than the bound may be returned. This can be controlled
        by lowering the tolerance.

        INPUT:

        - ``bound`` - a real number

        - ``tolerance`` - a rational number in (0,1] used in doyle-krumm algorithm-4

        - ``precision`` - the precision to use for computing the elements of bounded height of number fields.

        OUTPUT:

        - a list of rational points of a affine scheme

        EXAMPLES: The bug reported at #11526 is fixed::

            sage: A2 = AffineSpace(ZZ, 2)
            sage: F = GF(3)
            sage: A2(F).points()
            [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

            sage: R = ZZ
            sage: A.<x,y> = R[]
            sage: I = A.ideal(x^2-y^2-1)
            sage: V = AffineSpace(R, 2)
            sage: X = V.subscheme(I)
            sage: M = X(R)
            sage: M.points(bound=1)
            [(-1, 0), (1, 0)]

        ::

            sage: u = QQ['u'].0
            sage: K.<v> = NumberField(u^2 + 3)
            sage: A.<x,y> = AffineSpace(K, 2)
            sage: len(A(K).points(bound=2))
            1849

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: E = A.subscheme([x^2 + y^2 - 1, y^2 - x^3 + x^2 + x - 1])
            sage: E(A.base_ring()).points()
            [(-1, 0), (0, -1), (0, 1), (1, 0)]
        """
        B = kwds.pop('bound', 0)
        tol = kwds.pop('tolerance', 1e-2)
        prec = kwds.pop('precision', 53)

        X = self.codomain()

        from sage.schemes.affine.affine_space import is_AffineSpace
        if not is_AffineSpace(X) and X.base_ring() in Fields():
            # Then X must be a subscheme
            dim_ideal = X.defining_ideal().dimension()
            if dim_ideal < 0:  # no points
                return []
            if dim_ideal == 0:  # if X zero-dimensional
                N = len(X.ambient_space().gens())
                S = X.defining_polynomials()[0].parent()
                R = PolynomialRing(S.base_ring(), 's', N, order='lex')
                phi = S.hom(R.gens(), R)
                J = R.ideal([phi(t) for t in X.defining_polynomials()])
                D = J.variety()
                points = []
                for d in D:
                    P = [d[t] for t in R.gens()]
                    points.append(X(P))
                points.sort()
                return points
        R = self.value_ring()
        if is_RationalField(R) or R == ZZ:
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified" %
                                B)
            from sage.schemes.affine.affine_rational_point import enum_affine_rational_field
            return enum_affine_rational_field(self, B)
        if R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified" %
                                B)
            from sage.schemes.affine.affine_rational_point import enum_affine_number_field
            return enum_affine_number_field(self,
                                            bound=B,
                                            tolerance=tol,
                                            precision=prec)
        elif is_FiniteField(R):
            from sage.schemes.affine.affine_rational_point import enum_affine_finite_field
            return enum_affine_finite_field(self)
        else:
            raise TypeError("unable to enumerate points over %s" % R)
Ejemplo n.º 48
0
    def _coerce_map_from_(self, other):
        r"""
        Return true if ``other`` canonically coerces to ``self``.

        EXAMPLES::

            sage: R.<t> = QQ[]
            sage: P = ProjectiveSpace(QQ, 1, 'x')
            sage: P2 = ProjectiveSpace(R, 1, 'x')
            sage: P2(R)._coerce_map_from_(P(QQ))
            True
            sage: P(QQ)._coerce_map_from_(P2(R))
            False

        ::

            sage: P = ProjectiveSpace(QQ, 1, 'x')
            sage: P2 = ProjectiveSpace(CC, 1, 'y')
            sage: P2(CC)._coerce_map_from_(P(QQ))
            False

        ::

            sage: A.<x,y,z> = AffineSpace(QQ, 3)
            sage: H = A.subscheme(z)
            sage: L = A.subscheme([z, y+z])
            sage: A(QQ)._coerce_map_from_(H(QQ))
            True
            sage: H(QQ)._coerce_map_from_(L(QQ))
            True
            sage: L(QQ).has_coerce_map_from(H(QQ))
            False
            sage: A(CC)._coerce_map_from_(H(QQ))
            True
            sage: H(CC)._coerce_map_from_(L(RR))
            True

        ::

            sage: A.<x,y,z> = AffineSpace(QQ, 3)
            sage: A2.<u,v> = AffineSpace(QQ, 2)
            sage: A(QQ).has_coerce_map_from(A2(QQ))
            False

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: P.<u,v,w> = ProjectiveSpace(QQ, 2)
            sage: A(QQ).has_coerce_map_from(P(QQ))
            False

        ::

            sage: A = AffineSpace(QQ, 1)
            sage: A(QQ)._coerce_map_from_(ZZ)
            True

        ::

            sage: PS = ProjectiveSpace(ZZ, 1, 'x')
            sage: PS2 = ProjectiveSpace(Zp(7), 1, 'x')
            sage: PS(ZZ).has_coerce_map_from(PS2(Zp(7)))
            False
            sage: PS2(Zp(7)).has_coerce_map_from(PS(ZZ))
            True

        ::

            sage: PP1 = ProductProjectiveSpaces(ZZ, [2,1], 'x')
            sage: PP1(QQ)._coerce_map_from_(PP1(ZZ))
            True
            sage: PP2 = ProductProjectiveSpaces(QQ, [1,2], 'x')
            sage: PP2(QQ)._coerce_map_from_(PP1(ZZ))
            False
            sage: PP3 = ProductProjectiveSpaces(QQ, [2,1], 'y')
            sage: PP3(QQ)._coerce_map_from_(PP1(ZZ))
            False

        ::

            sage: K.<w> = QuadraticField(2)
            sage: A.<x,y,z> = AffineSpace(QQ, 3)
            sage: H = A.subscheme(z)
            sage: A(K).has_coerce_map_from(H(QQ))
            True

        TESTS::

            sage: P.<x,y> = ProjectiveSpace(QQ, 1)
            sage: X = P. subscheme ([x-y])
            sage: P(1,1) == X(1,1)
            True

        ::

            sage: A = AffineSpace(QQ, 1, 'x')
            sage: AC = AffineSpace(CC, 1, 'x')
            sage: A(3/2) == AC(3/2)
            True

        ::

            sage: A = AffineSpace(QQ, 1)
            sage: A(0) == 0
            True
        """
        target = self.codomain()
        #ring elements can be coerced to a space if we're affine dimension 1
        #and the base rings are coercible
        if isinstance(other, CommutativeRing):
            try:
                from sage.schemes.affine.affine_space import is_AffineSpace
                if is_AffineSpace(target.ambient_space())\
                  and target.ambient_space().dimension_relative() == 1:
                    return target.base_ring().has_coerce_map_from(other)
                else:
                    return False
            except AttributeError:  #no .ambient_space
                return False
        elif isinstance(other, SchemeHomset_points):
            #we are converting between scheme points
            from sage.schemes.generic.algebraic_scheme import AlgebraicScheme_subscheme
            source = other.codomain()
            if isinstance(target, AlgebraicScheme_subscheme):
                #subscheme coerce when there is containment
                if not isinstance(source, AlgebraicScheme_subscheme):
                    return False
                if target.ambient_space() == source.ambient_space():
                    if all([
                            g in source.defining_ideal()
                            for g in target.defining_polynomials()
                    ]):
                        return self.domain().coordinate_ring(
                        ).has_coerce_map_from(other.domain().coordinate_ring())
            else:
                #if the target is an ambient space, we can coerce if the base rings coerce
                #and they are the same type: affine, projective, etc and have the same
                #variable names
                from sage.schemes.projective.projective_space import is_ProjectiveSpace
                from sage.schemes.affine.affine_space import is_AffineSpace
                from sage.schemes.product_projective.space import is_ProductProjectiveSpaces
                try:
                    ta = target.ambient_space()
                    sa = source.ambient_space()
                except AttributeError:  #no .ambient_space
                    return False
                #for projective and affine varieties, we check dimension
                #and matching variable names
                if (is_ProjectiveSpace(ta) and is_ProjectiveSpace(sa))\
                  or (is_AffineSpace(ta) and is_AffineSpace(sa)):
                    if (ta.variable_names() == sa.variable_names()):
                        return self.domain().coordinate_ring(
                        ).has_coerce_map_from(other.domain().coordinate_ring())
                    else:
                        return False
                #for products of projective spaces, we check dimension of
                #components and matching variable names
                elif (is_ProductProjectiveSpaces(ta)
                      and is_ProductProjectiveSpaces(sa)):
                    if (ta.dimension_relative_components() == sa.dimension_relative_components()) \
                      and (ta.variable_names() == sa.variable_names()):
                        return self.domain().coordinate_ring(
                        ).has_coerce_map_from(other.domain().coordinate_ring())
                    else:
                        return False