def representation(self, s): """ Return the representation of `s` as a linear morphism acting on ``self`` INPUT: - `s` -- an element of the semigroup acting on ``self`` EXAMPLES:: sage: S = AperiodicMonoids().Finite().example(5); S sage: A = S.simple_module(3) sage: pi = S.monoid_generators() sage: pi Finite family {1: 11345, 2: 12245, 3: 12335, 4: 12344, -1: 22345, -4: 12355, -3: 12445, -2: 13345} sage: phi = A.representation(pi[1]) Generic endomorphism of A quotient of Free module generated by {33444, 33334, 33344, 34444} endowed with an action of The finite H-trivial monoid of order preserving maps on {1, .., 5} over Rational Field sage: phi(A.an_element()) 2*B[11144] + 2*B[11444] + 3*B[11114] sage: phi.matrix() [1 0 0 0] [0 0 0 0] [0 0 1 0] [0 1 0 1] """ from sage.categories.homset import End import functools return SetMorphism( End(self, Modules(self.base_ring()).WithBasis().FiniteDimensional()), functools.partial(self.action, s))
def nth_iterate_map(self, n): r""" For a map ``self`` this function returns the nth iterate of ``self`` as a function on ``self.domain()`` ALGORITHM: Uses a form of successive squaring to reducing computations. .. TODO:: This could be improved. INPUT: - ``n`` -- a positive integer. OUTPUT: - A map between products of projective spaces EXAMPLES:: sage: Z.<a,b,x,y,z> = ProductProjectiveSpaces([1,2],QQ) sage: H = End(Z) sage: f = H([a^3,b^3,x^2,y^2,z^2]) sage: f.nth_iterate_map(3) Scheme endomorphism of Product of projective spaces P^1 x P^2 over Rational Field Defn: Defined by sending (a : b , x : y : z) to (a^27 : b^27 , x^8 : y^8 : z^8). """ if not self.is_endomorphism(): raise TypeError("Domain and Codomain of function not equal") E = self.domain() D = int(n) if D < 0: raise TypeError("Iterate number must be a nonnegative integer") N = sum([ E.ambient_space()[i].dimension_relative() + 1 for i in range(E.ambient_space().num_components()) ]) F = list(self._polys) Coord_ring = E.coordinate_ring() if isinstance(Coord_ring, QuotientRing_generic): PHI = [Coord_ring.gen(i).lift() for i in range(N)] else: PHI = [Coord_ring.gen(i) for i in range(N)] while D: if D & 1: PHI = [PHI[j](*F) for j in range(N)] if D > 1: #avoid extra iterate F = [F[j](*F) for j in range(N)] #'square' D >>= 1 return End(E)(PHI)
def as_scheme_morphism(self): """ Return this dynamical system as :class:`SchemeMorphism_polynomial`. OUTPUT: :class:`SchemeMorphism_polynomial` EXAMPLES:: sage: P.<x,y,z> = ProjectiveSpace(ZZ, 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) sage: type(f.as_scheme_morphism()) <class 'sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space'> :: sage: P.<x,y> = ProjectiveSpace(QQ, 1) sage: f = DynamicalSystem_projective([x^2-y^2, y^2]) sage: type(f.as_scheme_morphism()) <class 'sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space_field'> :: sage: P.<x,y> = ProjectiveSpace(GF(5), 1) sage: f = DynamicalSystem_projective([x^2, y^2]) sage: type(f.as_scheme_morphism()) <class 'sage.schemes.projective.projective_morphism.SchemeMorphism_polynomial_projective_space_finite_field'> :: sage: A.<x,y> = AffineSpace(ZZ, 2) sage: f = DynamicalSystem_affine([x^2-2, y^2]) sage: type(f.as_scheme_morphism()) <class 'sage.schemes.affine.affine_morphism.SchemeMorphism_polynomial_affine_space'> :: sage: A.<x,y> = AffineSpace(QQ, 2) sage: f = DynamicalSystem_affine([x^2-2, y^2]) sage: type(f.as_scheme_morphism()) <class 'sage.schemes.affine.affine_morphism.SchemeMorphism_polynomial_affine_space_field'> :: sage: A.<x,y> = AffineSpace(GF(3), 2) sage: f = DynamicalSystem_affine([x^2-2, y^2]) sage: type(f.as_scheme_morphism()) <class 'sage.schemes.affine.affine_morphism.SchemeMorphism_polynomial_affine_space_finite_field'> """ H = End(self.domain()) return H(list(self))
def hecke_module_morphism(self): """ Return the endomorphism of Hecke modules defined by the matrix attached to this Hecke operator. EXAMPLES:: sage: M = ModularSymbols(Gamma1(13)) sage: t = M.hecke_operator(2) sage: t Hecke operator T_2 on Modular Symbols space of dimension 15 for Gamma_1(13) of weight 2 with sign 0 and over Rational Field sage: t.hecke_module_morphism() Hecke module morphism T_2 defined by the matrix [ 2 0 0 0 0 0 0 1 0 0 1 0 0 0 0] [ 0 2 0 1 0 1 0 0 -1 0 0 0 0 0 1] [ 0 1 2 0 0 0 0 0 0 0 0 -1 1 0 0] [ 1 0 0 2 0 -1 1 0 1 0 -1 1 -1 0 0] [ 0 0 1 0 2 0 -1 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0 0 0 0 1 -2 2 -1] [ 0 0 0 0 0 2 -1 0 -1 0 0 0 0 1 0] [ 0 0 0 0 1 0 0 2 0 0 0 0 0 0 -1] [ 0 0 0 0 0 1 0 0 -1 0 2 -1 0 2 -1] [ 0 0 0 0 0 1 1 0 0 -1 0 1 -1 2 0] [ 0 0 0 0 0 2 0 0 -1 -1 1 -1 0 1 0] [ 0 0 0 0 0 1 1 0 1 0 0 0 -1 1 0] [ 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0] [ 0 0 0 0 0 1 0 0 1 -1 2 0 0 0 -1] [ 0 0 0 0 0 0 0 0 0 1 0 -1 2 0 -1] Domain: Modular Symbols space of dimension 15 for Gamma_1(13) of weight ... Codomain: Modular Symbols space of dimension 15 for Gamma_1(13) of weight ... """ try: return self.__hecke_module_morphism except AttributeError: T = self.matrix() M = self.domain() H = End(M) if isinstance(self, HeckeOperator): name = "T_%s" % self.index() else: name = "" self.__hecke_module_morphism = morphism.HeckeModuleMorphism_matrix( H, T, name) return self.__hecke_module_morphism
def __init__(self, polys_or_rat_fncts, domain): r""" The Python constructor. EXAMPLES:: sage: from sage.dynamics.arithmetic_dynamics.generic_ds import DynamicalSystem sage: P.<x,y> = ProjectiveSpace(QQ,1) sage: f = DynamicalSystem_projective([x^2+y^2, y^2]) sage: isinstance(f, DynamicalSystem) True """ H = End(domain) # All consistency checks are done by the public class constructors, # so we can set check=False here. SchemeMorphism_polynomial.__init__(self, H, polys_or_rat_fncts, check=False)
def to_ambient_space_morphism(self): r""" Return the identity map on ``self``. This is present for uniformity of use; the corresponding method for abstract root and weight lattices/spaces, is not trivial. EXAMPLES:: sage: P = RootSystem(['A',2]).ambient_space() sage: f = P.to_ambient_space_morphism() sage: p = P.an_element() sage: p (2, 2, 3) sage: f(p) (2, 2, 3) sage: f(p)==p True """ return End(self).identity()
def order(self): r""" Returns the number of elements of ``self``. EXAMPLES:: sage: F.<a> = GF(4) sage: SemimonomialTransformationGroup(F, 5).order() == (4-1)**5 * factorial(5) * 2 True """ from sage.functions.other import factorial from sage.categories.homset import End n = self.degree() R = self.base_ring() if R.is_field(): multgroup_size = len(R) - 1 autgroup_size = R.degree() else: multgroup_size = R.unit_group_order() autgroup_size = len([x for x in End(R) if x.is_injective()]) return multgroup_size**n * factorial(n) * autgroup_size
def _normalize_morphism(self, category): """ Returns the normalize morphism EXAMPLES:: sage: P = JackPolynomialsP(QQ); P.rename("JackP") sage: normal = P._normalize_morphism(AlgebrasWithBasis(P.base_ring())) sage: normal.parent() Set of Homomorphisms from JackP to JackP sage: normal.category_for() Category of algebras with basis over Fraction Field of Univariate Polynomial Ring in t over Rational Field sage: t = P.t sage: a = 2/(1/2*t+1/2) sage: b = 1/(1/3+1/6*t) sage: c = 24/(4*t^2 + 12*t + 8) sage: normal( a*P[1] + b*P[2] + c*P[2,1] ) (4/(t+1))*JackP[1] + (6/(t+2))*JackP[2] + (6/(t^2+3*t+2))*JackP[2, 1] TODO: this method should not be needed once short idioms to construct morphisms will be available """ return SetMorphism(End(self, category), self._normalize)
def _element_constructor_(self, arg1, v=None, perm=None, autom=None, check=True): r""" Coerce ``arg1`` into this permutation group, if ``arg1`` is 0, then we will try to coerce ``(v, perm, autom)``. INPUT: - ``arg1`` (optional) -- either the integers 0, 1 or an element of ``self`` - ``v`` (optional) -- a vector of length ``self.degree()`` - ``perm`` (optional) -- a permutaton of degree ``self.degree()`` - ``autom`` (optional) -- an automorphism of the ring EXAMPLES:: sage: F.<a> = GF(9) sage: S = SemimonomialTransformationGroup(F, 4) sage: S(1) ((1, 1, 1, 1); (), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a) sage: g = S(v=[1,1,1,a]) sage: S(g) ((1, 1, 1, a); (), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a) sage: S(perm=Permutation('(1,2)(3,4)')) ((1, 1, 1, 1); (1,2)(3,4), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a) sage: S(autom=F.hom([a**3])) ((1, 1, 1, 1); (), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> 2*a + 1) """ from sage.categories.homset import End R = self.base_ring() if arg1 == 0: if v is None: v = [R.one()] * self.degree() if perm is None: perm = Permutation(range(1, self.degree() + 1)) if autom is None: autom = R.hom(R.gens()) if check: try: v = [R(x) for x in v] except TypeError: raise TypeError('the vector attribute %s ' % v + 'should be iterable') if len(v) != self.degree(): raise ValueError('the length of the vector is %s,' % len(v) + ' should be %s' % self.degree()) if not all(x.parent() is R and x.is_unit() for x in v): raise ValueError('there is at least one element in the ' + 'list %s not lying in %s ' % (v, R) + 'or which is not invertible') try: perm = Permutation(perm) except TypeError: raise TypeError('the permutation attribute %s ' % perm + 'could not be converted to a permutation') if len(perm) != self.degree(): raise ValueError('the permutation length is %s,' % len(perm) + ' should be %s' % self.degree()) try: if autom.parent() != End(R): autom = End(R)(autom) except TypeError: raise TypeError('%s of type %s' % (autom, type(autom)) + ' is not coerceable to an automorphism') return self.Element(self, v, perm, autom) else: try: if arg1.parent() is self: return arg1 except AttributeError: pass try: from sage.rings.integer import Integer if Integer(arg1) == 1: return self() except TypeError: pass raise TypeError('the first argument must be an integer' + ' or an element of this group')
def homogenize(self, n): r""" Return the homogenization of this map. If it's domain is a subscheme, the domain of the homogenized map is the projective embedding of the domain. The domain and codomain can be homogenized at different coordinates: ``n[0]`` for the domain and ``n[1]`` for the codomain. INPUT: - ``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:`SchemeMorphism_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) Scheme endomorphism of Projective Space of dimension 2 over Integer Ring Defn: Defined on coordinates by sending (x0 : x1 : x2) to (x0^2*x2^5 - 2*x2^7 : x0^5*x1^2 : x0^5*x2^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)) Scheme endomorphism of Projective Space of dimension 2 over Complex Field with 53 bits of precision Defn: Defined on coordinates by sending (x0 : x1 : x2) to (x0*x1*x2^2 : x0^2*x2^2 + (-2.00000000000000)*x2^4 : x0*x1^3 - x0^2*x1*x2) :: 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*x1^2 : 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)) Scheme endomorphism of Projective Space of dimension 2 over Univariate Polynomial Ring in t over Integer Ring Defn: Defined on coordinates by sending (x0 : x1 : x2) to (x1*x2^2 : x0^2*x2 + (-2)*x2^3 : x1^3 - x0*x1*x2) :: sage: A.<x> = AffineSpace(QQ, 1) sage: H = End(A) sage: f = H([x^2-1]) sage: f.homogenize((1, 0)) Scheme endomorphism of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x0 : x1) to (x1^2 : x0^2 - x1^2) :: sage: R.<a> = PolynomialRing(QQbar) sage: A.<x,y> = AffineSpace(R, 2) sage: H = End(A) sage: f = H([QQbar(sqrt(2))*x*y, a*x^2]) sage: f.homogenize(2) Scheme endomorphism of Projective Space of dimension 2 over Univariate Polynomial Ring in a over Algebraic Field Defn: Defined on coordinates by sending (x0 : x1 : x2) to (1.414213562373095?*x0*x1 : a*x0^2 : x2^2) :: sage: P.<x,y,z> = AffineSpace(QQ, 3) sage: H = End(P) sage: f = H([x^2 - 2*x*y + z*x, z^2 -y^2 , 5*z*y]) sage: f.homogenize(2).dehomogenize(2) == f True :: sage: K.<c> = FunctionField(QQ) sage: A.<x> = AffineSpace(K, 1) sage: f = Hom(A, A)([x^2 + c]) sage: f.homogenize(1) Scheme endomorphism of Projective Space of dimension 1 over Rational function field in c over Rational Field Defn: Defined on coordinates by sending (x0 : x1) to (x0^2 + c*x1^2 : x1^2) :: sage: A.<z> = AffineSpace(QQbar, 1) sage: H = End(A) sage: f = H([2*z / (z^2+2*z+3)]) sage: f.homogenize(1) Scheme endomorphism of Projective Space of dimension 1 over Algebraic Field Defn: Defined on coordinates by sending (x0 : x1) to (x0*x1 : 1/2*x0^2 + x0*x1 + 3/2*x1^2) :: sage: A.<z> = AffineSpace(QQbar, 1) sage: H = End(A) sage: f = H([2*z / (z^2 + 2*z + 3)]) sage: f.homogenize(1) Scheme endomorphism of Projective Space of dimension 1 over Algebraic Field Defn: Defined on coordinates by sending (x0 : x1) to (x0*x1 : 1/2*x0^2 + x0*x1 + 3/2*x1^2) :: sage: R.<c,d> = QQbar[] sage: A.<x> = AffineSpace(R, 1) sage: H = Hom(A, A) sage: F = H([d*x^2 + c]) sage: F.homogenize(1) Scheme endomorphism of Projective Space of dimension 1 over Multivariate Polynomial Ring in c, d over Algebraic Field Defn: Defined on coordinates by sending (x0 : x1) to (d*x0^2 + c*x1^2 : x1^2) """ #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 and codomain A = self.domain().projective_embedding(ind[0]).codomain() if self.is_endomorphism(): B = A H = End(A) else: B = self.codomain().projective_embedding(ind[1]).codomain() H = Hom(A, B) newvar = A.ambient_space().coordinate_ring().gen(ind[0]) N = A.ambient_space().dimension_relative() M = B.ambient_space().dimension_relative() #create dictionary for mapping of coordinate rings R = self.domain().ambient_space().coordinate_ring() S = A.ambient_space().coordinate_ring() Rvars = R.gens() vars = list(S.gens()) vars.remove(S.gen(ind[0])) D = dict([[Rvars[i], vars[i]] for i in range(N)]) #clear the denominators if a rational function L = [self[i].denominator() for i in range(M)] l = [prod(L[:j] + L[j + 1:M]) for j in range(M)] F = [S(R(self[i].numerator() * l[i]).subs(D)) for i in range(M)] #homogenize F.insert(ind[1], S(R(prod(L)).subs(D))) #coerce in case l is a constant try: #remove possible gcd of the polynomials g = gcd(F) F = [S(f / g) for f in F] #remove possible gcd of coefficients gc = gcd([f.content() for f in F]) F = [S(f / gc) for f in F] except (AttributeError, ValueError, NotImplementedError, TypeError, ArithmeticError): #no gcd pass d = max([F[i].degree() for i in range(M + 1)]) F = [ F[i].homogenize(str(newvar)) * newvar**(d - F[i].degree()) for i in range(M + 1) ] return (H(F))
def affine_minimal(vp, return_transformation=False, D=None, quick=False): r""" Given vp a scheme morphisms on the projective line over the rationals, this procedure determines if `\phi` is minimal. In particular, it determines if the map is affine minimal, which is enough to decide if it is minimal or not. See Proposition 2.10 in [Bruin-Molnar]. INPUT: - ``vp`` -- scheme morphism on the projective line. - ``D`` -- a list of primes, in case one only wants to check minimality at those specific primes. - ``return_transformation`` -- a boolean value, default value True. This signals a return of the ``PGL_2`` transformation to conjugate ``vp`` to the calculated minimal model. default: False - ``quick`` -- a boolean value. If true the algorithm terminates once algorithm determines F/G is not minimal, otherwise algorithm only terminates once a minimal model has been found. OUTPUT: - ``newvp`` -- scheme morphism on the projective line. - ``conj`` -- linear fractional transformation which conjugates ``vp`` to ``newvp`` EXAMPLES:: sage: PS.<X,Y> = ProjectiveSpace(QQ,1) sage: H = Hom(PS,PS) sage: vp = H([X^2+9*Y^2,X*Y]) sage: from sage.schemes.projective.endPN_minimal_model import affine_minimal sage: affine_minimal(vp,True) ( Scheme endomorphism of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (X : Y) to (X^2 + Y^2 : X*Y) , [3 0] [0 1] ) """ BR = vp.domain().base_ring() conj = matrix(BR, 2, 2, 1) flag = True d = vp.degree() vp.normalize_coordinates() Affvp = vp.dehomogenize(1) R = Affvp.coordinate_ring() if R.is_field(): #want the polynomial ring not the fraction field R = R.ring() F = R(Affvp[0].numerator()) G = R(Affvp[0].denominator()) if G.degree() == 0 or F.degree() == 0: raise TypeError( "Affine minimality is only considered for maps not of the form f or 1/f for a polynomial f." ) z = F.parent().gen(0) minF, minG = F, G #If the valuation of a prime in the resultant is small enough, we can say the #map is affine minimal at that prime without using the local minimality loop. See #Theorem 3.2.2 in [Molnar, M.Sc. thesis] if d % 2 == 0: g = d else: g = 2 * d Res = vp.resultant() #Some quantities needed for the local minimization loop, but we compute now #since the value is constant, so we do not wish to compute in every local loop. #See Theorem 3.3.3 in [Molnar, M.Sc thesis] H = F - z * minG d1 = F.degree() A = AffineSpace(BR, 1, H.parent().variable_name()) end_ring = End(A) ubRes = end_ring([H / minG]).homogenize(1).resultant() #Set the primes to check minimality at, if not already prescribed if D is None: D = ZZ(Res).prime_divisors() #Check minimality at all primes in D. If D is all primes dividing #Res(minF/minG), this is enough to show whether minF/minG is minimal or not. See #Propositions 3.2.1 and 3.3.7 in [Molnar, M.Sc. thesis]. for p in D: while True: if Res.valuation(p) < g: #The model is minimal at p min = True else: #The model may not be minimal at p. newvp, conj = Min(vp, p, ubRes, conj) if newvp == vp: min = True else: vp = newvp Affvp = vp.dehomogenize(1) min = False if min: #The model is minimal at p break elif F == Affvp[0].numerator() and G == Affvp[0].denominator(): #The model is minimal at p break else: #The model is not minimal at p flag = False if quick: break if quick and not flag: break if quick: #only return whether the model is minimal return flag if return_transformation: return vp, conj return vp
def chebyshev_polynomial(self, n, kind='first'): """ Generates an endomorphism of this affine line by a Chebyshev polynomial. Chebyshev polynomials are a sequence of recursively defined orthogonal polynomials. Chebyshev of the first kind are defined as `T_0(x) = 1`, `T_1(x) = x`, and `T_{n+1}(x) = 2xT_n(x) - T_{n-1}(x)`. Chebyshev of the second kind are defined as `U_0(x) = 1`, `U_1(x) = 2x`, and `U_{n+1}(x) = 2xU_n(x) - U_{n-1}(x)`. INPUT: - ``n`` -- a non-negative integer. - ``kind`` -- ``first`` or ``second`` specifying which kind of chebyshev the user would like to generate. Defaults to ``first``. OUTPUT: :class:`SchemeMorphism_polynomial_affine_space` EXAMPLES:: sage: A.<x> = AffineSpace(QQ, 1) sage: A.chebyshev_polynomial(5, 'first') Scheme endomorphism of Affine Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x) to (16*x^5 - 20*x^3 + 5*x) :: sage: A.<x> = AffineSpace(QQ, 1) sage: A.chebyshev_polynomial(3, 'second') Scheme endomorphism of Affine Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x) to (8*x^3 - 4*x) :: sage: A.<x> = AffineSpace(QQ, 1) sage: A.chebyshev_polynomial(3, 2) Traceback (most recent call last): ... ValueError: keyword 'kind' must have a value of either 'first' or 'second' :: sage: A.<x> = AffineSpace(QQ, 1) sage: A.chebyshev_polynomial(-4, 'second') Traceback (most recent call last): ... ValueError: first parameter 'n' must be a non-negative integer :: sage: A = AffineSpace(QQ, 2, 'x') sage: A.chebyshev_polynomial(2) Traceback (most recent call last): ... TypeError: affine space must be of dimension 1 """ if self.dimension_relative() != 1: raise TypeError("affine space must be of dimension 1") n = ZZ(n) if (n < 0): raise ValueError( "first parameter 'n' must be a non-negative integer") H = End(self) if kind == 'first': return H([chebyshev_T(n, self.gen(0))]) elif kind == 'second': return H([chebyshev_U(n, self.gen(0))]) else: raise ValueError( "keyword 'kind' must have a value of either 'first' or 'second'" )
def change_ring(self,R, check=True): r""" Returns a new :class:`SchemeMorphism_polynomial` which is ``self`` coerced to ``R``. If ``check`` is ``True``, then the initialization checks are performed. INPUT: - ``R`` -- ring - ``check`` -- Boolean OUTPUT: - A new :class: `SchemeMorphism_polynomial` which is ``self`` coerced to ``R``. EXAMPLES:: sage: P.<x,y>=ProjectiveSpace(ZZ,1) sage: H=Hom(P,P) sage: f=H([3*x^2,y^2]) sage: f.change_ring(GF(3)) Traceback (most recent call last): ... ValueError: polys (=[0, y^2]) must be of the same degree :: sage: P.<x,y,z>=ProjectiveSpace(QQ,2) sage: H=Hom(P,P) sage: f=H([5/2*x^3 + 3*x*y^2-y^3,3*z^3 + y*x^2, x^3-z^3]) sage: f.change_ring(GF(3)) Scheme endomorphism of Projective Space of dimension 2 over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y : z) to (x^3 - y^3 : x^2*y : x^3 - z^3) :: sage: P.<x,y>=ProjectiveSpace(QQ,1) sage: X=P.subscheme([5*x^2-y^2]) sage: H=Hom(X,X) sage: f=H([x,y]) sage: f.change_ring(GF(3)) Scheme endomorphism of Closed subscheme of Projective Space of dimension 1 over Finite Field of size 3 defined by: -x^2 - y^2 Defn: Defined on coordinates by sending (x : y) to (x : y) Check that :trac:'16834' is fixed:: sage: A.<x,y,z> = AffineSpace(RR,3) sage: h = Hom(A,A) sage: f = h([x^2+1.5,y^3,z^5-2.0]) sage: f.change_ring(CC) Scheme endomorphism of Affine Space of dimension 3 over Complex Field with 53 bits of precision Defn: Defined on coordinates by sending (x, y, z) to (x^2 + 1.50000000000000, y^3, z^5 - 2.00000000000000) :: sage: A.<x,y> = ProjectiveSpace(ZZ,1) sage: B.<u,v> = AffineSpace(QQ,2) sage: h = Hom(A,B) sage: f = h([x^2, y^2]) sage: f.change_ring(QQ) Scheme morphism: From: Projective Space of dimension 1 over Rational Field To: Affine Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y) to (x^2, y^2) """ T=self.domain().change_ring(R) if self.is_endomorphism(): H=End(T) else: S=self.codomain().change_ring(R) H=Hom(T,S) G=[f.change_ring(R) for f in self._polys] return(H(G,check))