Drinfeld module morphisms¶
This module provides the class
sage.rings.function_fields.drinfeld_module.morphism.DrinfeldModuleMorphism.
AUTHORS: - Antoine Leudière (2022-04)
- class sage.rings.function_field.drinfeld_modules.morphism.DrinfeldModuleMorphism(parent, ore_pol)[source]¶
- Bases: - Morphism,- UniqueRepresentation- This class represents Drinfeld \(\mathbb{F}_q[T]\)-module morphisms. - Let \(\phi\) and \(\psi\) be two Drinfeld \(\mathbb{F}_q[T]\)-modules over a field \(K\). A morphism of Drinfeld modules \(\phi \to \psi\) is an Ore polynomial \(f \in K\{\tau\}\) such that \(f \phi_a = \psi_a f\) for every \(a \in \mathbb{F}_q[T]\). In our case, this is equivalent to \(f \phi_T = \psi_T f\). An isogeny is a nonzero morphism. - To create a morphism object, the user should never explicitly instantiate - DrinfeldModuleMorphism, but rather call the parent homset with the defining Ore polynomial:- sage: Fq = GF(4) sage: A.<T> = Fq[] sage: K.<z> = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, z^2 + z, z^2 + z]) sage: t = phi.ore_polring().gen() sage: ore_pol = t + z^5 + z^3 + z + 1 sage: psi = phi.velu(ore_pol) sage: morphism = Hom(phi, psi)(ore_pol) sage: morphism Drinfeld Module morphism: From: Drinfeld module defined by T |--> (z^2 + z)*t^2 + (z^2 + z)*t + z To: Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*t^2 + (z^4 + z + 1)*t + z Defn: t + z^5 + z^3 + z + 1 - >>> from sage.all import * >>> Fq = GF(Integer(4)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(3), names=('z',)); (z,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z, z**Integer(2) + z, z**Integer(2) + z]) >>> t = phi.ore_polring().gen() >>> ore_pol = t + z**Integer(5) + z**Integer(3) + z + Integer(1) >>> psi = phi.velu(ore_pol) >>> morphism = Hom(phi, psi)(ore_pol) >>> morphism Drinfeld Module morphism: From: Drinfeld module defined by T |--> (z^2 + z)*t^2 + (z^2 + z)*t + z To: Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*t^2 + (z^4 + z + 1)*t + z Defn: t + z^5 + z^3 + z + 1 - The given Ore polynomial must indeed define a morphism: - sage: morphism = Hom(phi, psi)(1) Traceback (most recent call last): ... ValueError: Ore polynomial does not define a morphism - >>> from sage.all import * >>> morphism = Hom(phi, psi)(Integer(1)) Traceback (most recent call last): ... ValueError: Ore polynomial does not define a morphism - One can get basic data on the morphism: - sage: morphism.domain() Drinfeld module defined by T |--> (z^2 + z)*t^2 + (z^2 + z)*t + z sage: morphism.domain() is phi True sage: morphism.codomain() Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*t^2 + (z^4 + z + 1)*t + z sage: morphism.codomain() is psi True - >>> from sage.all import * >>> morphism.domain() Drinfeld module defined by T |--> (z^2 + z)*t^2 + (z^2 + z)*t + z >>> morphism.domain() is phi True >>> morphism.codomain() Drinfeld module defined by T |--> (z^5 + z^2 + z + 1)*t^2 + (z^4 + z + 1)*t + z >>> morphism.codomain() is psi True - sage: morphism.ore_polynomial() t + z^5 + z^3 + z + 1 sage: morphism.ore_polynomial() is ore_pol True - >>> from sage.all import * >>> morphism.ore_polynomial() t + z^5 + z^3 + z + 1 >>> morphism.ore_polynomial() is ore_pol True - One can check various properties: - sage: morphism.is_zero() False sage: morphism.is_isogeny() True sage: morphism.is_endomorphism() False sage: morphism.is_isomorphism() False - >>> from sage.all import * >>> morphism.is_zero() False >>> morphism.is_isogeny() True >>> morphism.is_endomorphism() False >>> morphism.is_isomorphism() False - characteristic_polynomial(var='X')[source]¶
- Return the characteristic polynomial of this endomorphism. - INPUT: - var– string (default:- X), the name of the variable of the characteristic polynomial
 - EXAMPLES: - sage: Fq = GF(5) sage: A.<T> = Fq[] sage: K.<z> = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) sage: f = phi.frobenius_endomorphism() sage: f.characteristic_polynomial() X^3 + (T + 1)*X^2 + (2*T + 3)*X + 2*T^3 + T + 1 - >>> from sage.all import * >>> Fq = GF(Integer(5)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(3), names=('z',)); (z,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z, Integer(0), Integer(1), z]) >>> f = phi.frobenius_endomorphism() >>> f.characteristic_polynomial() X^3 + (T + 1)*X^2 + (2*T + 3)*X + 2*T^3 + T + 1 - We verify, on an example, that the caracteristic polynomial of a morphism corresponding to \(\phi_a\) is \((X-a)^r\) where \(r\) is the rank: - sage: g = phi.hom(T^2 + 1) sage: chi = g.characteristic_polynomial() sage: chi.factor() (X + 4*T^2 + 4)^3 - >>> from sage.all import * >>> g = phi.hom(T**Integer(2) + Integer(1)) >>> chi = g.characteristic_polynomial() >>> chi.factor() (X + 4*T^2 + 4)^3 - An example with another variable name: - sage: f.characteristic_polynomial(var='Y') Y^3 + (T + 1)*Y^2 + (2*T + 3)*Y + 2*T^3 + T + 1 - >>> from sage.all import * >>> f.characteristic_polynomial(var='Y') Y^3 + (T + 1)*Y^2 + (2*T + 3)*Y + 2*T^3 + T + 1 
 - charpoly(var='X')[source]¶
- Return the characteristic polynomial of this endomorphism. - INPUT: - var– string (default:- 'X'); the name of the variable of the characteristic polynomial
 - EXAMPLES: - sage: Fq = GF(5) sage: A.<T> = Fq[] sage: K.<z> = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) sage: f = phi.frobenius_endomorphism() sage: chi = f.charpoly() sage: chi X^3 + (T + 1)*X^2 + (2*T + 3)*X + 2*T^3 + T + 1 - >>> from sage.all import * >>> Fq = GF(Integer(5)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(3), names=('z',)); (z,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z, Integer(0), Integer(1), z]) >>> f = phi.frobenius_endomorphism() >>> chi = f.charpoly() >>> chi X^3 + (T + 1)*X^2 + (2*T + 3)*X + 2*T^3 + T + 1 - We check that the characteristic polynomial annihilates the morphism (Cayley-Hamilton’s theorem): - sage: chi(f) Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z Defn: 0 - >>> from sage.all import * >>> chi(f) Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z Defn: 0 - We verify, on an example, that the caracteristic polynomial of the morphism corresponding to \(\phi_a\) is \((X-a)^r\) where \(r\) is the rank: - sage: g = phi.hom(T^2 + 1) sage: g.charpoly().factor() (X + 4*T^2 + 4)^3 - >>> from sage.all import * >>> g = phi.hom(T**Integer(2) + Integer(1)) >>> g.charpoly().factor() (X + 4*T^2 + 4)^3 - An example with another variable name: - sage: f.charpoly(var='Y') Y^3 + (T + 1)*Y^2 + (2*T + 3)*Y + 2*T^3 + T + 1 - >>> from sage.all import * >>> f.charpoly(var='Y') Y^3 + (T + 1)*Y^2 + (2*T + 3)*Y + 2*T^3 + T + 1 
 - dual_isogeny()[source]¶
- Return a dual isogeny to this morphism. - By definition, a dual isogeny of \(f : \phi \to \psi\) is an isogeny \(g : \psi \to \phi\) such that the composite \(g \circ f\) is the multiplication by a generator of the norm of \(f\). - EXAMPLES: - sage: Fq = GF(5) sage: A.<T> = Fq[] sage: K.<z> = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) sage: t = phi.ore_variable() sage: f = phi.hom(t + 1) sage: f Drinfeld Module morphism: From: Drinfeld module defined by T |--> z*t^3 + t^2 + z To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z Defn: t + 1 sage: g = f.dual_isogeny() sage: g Drinfeld Module morphism: From: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z To: Drinfeld module defined by T |--> z*t^3 + t^2 + z Defn: z*t^2 + (4*z + 1)*t + z + 4 - >>> from sage.all import * >>> Fq = GF(Integer(5)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(3), names=('z',)); (z,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z, Integer(0), Integer(1), z]) >>> t = phi.ore_variable() >>> f = phi.hom(t + Integer(1)) >>> f Drinfeld Module morphism: From: Drinfeld module defined by T |--> z*t^3 + t^2 + z To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z Defn: t + 1 >>> g = f.dual_isogeny() >>> g Drinfeld Module morphism: From: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z To: Drinfeld module defined by T |--> z*t^3 + t^2 + z Defn: z*t^2 + (4*z + 1)*t + z + 4 - We check that \(f \circ g\) (resp. \(g \circ f\)) is the multiplication by the norm of \(f\): - sage: a = f.norm().gen(); a T + 4 sage: g * f == phi.hom(a) True sage: psi = f.codomain() sage: f * g == psi.hom(a) True - >>> from sage.all import * >>> a = f.norm().gen(); a T + 4 >>> g * f == phi.hom(a) True >>> psi = f.codomain() >>> f * g == psi.hom(a) True 
 - inverse()[source]¶
- Return the inverse of this morphism. - Only morphisms defined by constant nonzero Ore polynomials are invertible. - EXAMPLES: - sage: Fq = GF(5) sage: A.<T> = Fq[] sage: K.<z> = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 1, z, z^2]) sage: f = phi.hom(2); f Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z Defn: 2 sage: f.inverse() Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z Defn: 3 - >>> from sage.all import * >>> Fq = GF(Integer(5)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(3), names=('z',)); (z,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z, Integer(1), z, z**Integer(2)]) >>> f = phi.hom(Integer(2)); f Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z Defn: 2 >>> f.inverse() Endomorphism of Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z Defn: 3 - Inversion of general isomorphisms between different Drinfeld modules also works: - sage: g = phi.hom(z); g Drinfeld Module morphism: From: Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z To: Drinfeld module defined by T |--> z^2*t^3 + (z^2 + 2*z + 3)*t^2 + (z^2 + 3*z)*t + z Defn: z sage: g.inverse() Drinfeld Module morphism: From: Drinfeld module defined by T |--> z^2*t^3 + (z^2 + 2*z + 3)*t^2 + (z^2 + 3*z)*t + z To: Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z Defn: 3*z^2 + 4 - >>> from sage.all import * >>> g = phi.hom(z); g Drinfeld Module morphism: From: Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z To: Drinfeld module defined by T |--> z^2*t^3 + (z^2 + 2*z + 3)*t^2 + (z^2 + 3*z)*t + z Defn: z >>> g.inverse() Drinfeld Module morphism: From: Drinfeld module defined by T |--> z^2*t^3 + (z^2 + 2*z + 3)*t^2 + (z^2 + 3*z)*t + z To: Drinfeld module defined by T |--> z^2*t^3 + z*t^2 + t + z Defn: 3*z^2 + 4 - When the morphism is not invertible, an error is raised: - sage: F = phi.frobenius_endomorphism() sage: F.inverse() Traceback (most recent call last): ... ZeroDivisionError: this morphism is not invertible - >>> from sage.all import * >>> F = phi.frobenius_endomorphism() >>> F.inverse() Traceback (most recent call last): ... ZeroDivisionError: this morphism is not invertible 
 - is_identity()[source]¶
- Return - Truewhether the morphism is the identity morphism.- EXAMPLES: - sage: Fq = GF(2) sage: A.<T> = Fq[] sage: K.<z6> = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: morphism = End(phi)(1) sage: morphism.is_identity() True - >>> from sage.all import * >>> Fq = GF(Integer(2)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(6), names=('z6',)); (z6,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z6, Integer(1), Integer(1)]) >>> morphism = End(phi)(Integer(1)) >>> morphism.is_identity() True - sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) sage: t = phi.ore_polring().gen() sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) sage: morphism.is_identity() False - >>> from sage.all import * >>> psi = DrinfeldModule(A, [z6, z6**Integer(4) + z6**Integer(2) + Integer(1), Integer(1)]) >>> t = phi.ore_polring().gen() >>> morphism = Hom(phi, psi)(t + z6**Integer(5) + z6**Integer(2) + Integer(1)) >>> morphism.is_identity() False 
 - is_isogeny()[source]¶
- Return - Truewhether the morphism is an isogeny.- EXAMPLES: - sage: Fq = GF(2) sage: A.<T> = Fq[] sage: K.<z6> = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) sage: t = phi.ore_polring().gen() sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) sage: morphism.is_isogeny() True - >>> from sage.all import * >>> Fq = GF(Integer(2)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(6), names=('z6',)); (z6,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z6, Integer(1), Integer(1)]) >>> psi = DrinfeldModule(A, [z6, z6**Integer(4) + z6**Integer(2) + Integer(1), Integer(1)]) >>> t = phi.ore_polring().gen() >>> morphism = Hom(phi, psi)(t + z6**Integer(5) + z6**Integer(2) + Integer(1)) >>> morphism.is_isogeny() True - sage: zero_morphism = End(phi)(0) sage: zero_morphism.is_isogeny() False - >>> from sage.all import * >>> zero_morphism = End(phi)(Integer(0)) >>> zero_morphism.is_isogeny() False - sage: identity_morphism = End(phi)(1) sage: identity_morphism.is_isogeny() True - >>> from sage.all import * >>> identity_morphism = End(phi)(Integer(1)) >>> identity_morphism.is_isogeny() True - sage: frobenius_endomorphism = phi.frobenius_endomorphism() sage: frobenius_endomorphism.is_isogeny() True - >>> from sage.all import * >>> frobenius_endomorphism = phi.frobenius_endomorphism() >>> frobenius_endomorphism.is_isogeny() True 
 - is_isomorphism()[source]¶
- Return - Truewhether the morphism is an isomorphism.- EXAMPLES: - sage: Fq = GF(2) sage: A.<T> = Fq[] sage: K.<z6> = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) sage: t = phi.ore_polring().gen() sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) sage: morphism.is_isomorphism() False - >>> from sage.all import * >>> Fq = GF(Integer(2)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(6), names=('z6',)); (z6,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z6, Integer(1), Integer(1)]) >>> psi = DrinfeldModule(A, [z6, z6**Integer(4) + z6**Integer(2) + Integer(1), Integer(1)]) >>> t = phi.ore_polring().gen() >>> morphism = Hom(phi, psi)(t + z6**Integer(5) + z6**Integer(2) + Integer(1)) >>> morphism.is_isomorphism() False - sage: zero_morphism = End(phi)(0) sage: zero_morphism.is_isomorphism() False - >>> from sage.all import * >>> zero_morphism = End(phi)(Integer(0)) >>> zero_morphism.is_isomorphism() False - sage: identity_morphism = End(phi)(1) sage: identity_morphism.is_isomorphism() True - >>> from sage.all import * >>> identity_morphism = End(phi)(Integer(1)) >>> identity_morphism.is_isomorphism() True - sage: frobenius_endomorphism = phi.frobenius_endomorphism() sage: frobenius_endomorphism.is_isomorphism() False - >>> from sage.all import * >>> frobenius_endomorphism = phi.frobenius_endomorphism() >>> frobenius_endomorphism.is_isomorphism() False 
 - is_zero()[source]¶
- Return - Truewhether the morphism is the zero morphism.- EXAMPLES: - sage: Fq = GF(2) sage: A.<T> = Fq[] sage: K.<z6> = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) sage: t = phi.ore_polring().gen() sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) sage: morphism.is_zero() False - >>> from sage.all import * >>> Fq = GF(Integer(2)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(6), names=('z6',)); (z6,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z6, Integer(1), Integer(1)]) >>> psi = DrinfeldModule(A, [z6, z6**Integer(4) + z6**Integer(2) + Integer(1), Integer(1)]) >>> t = phi.ore_polring().gen() >>> morphism = Hom(phi, psi)(t + z6**Integer(5) + z6**Integer(2) + Integer(1)) >>> morphism.is_zero() False - sage: zero_morphism = End(phi)(0) sage: zero_morphism.is_zero() True - >>> from sage.all import * >>> zero_morphism = End(phi)(Integer(0)) >>> zero_morphism.is_zero() True 
 - norm(ideal=True)[source]¶
- Return the norm of this isogeny. - INPUT: - ideal– boolean (default:- True); if- True, return the norm as an ideal in the function ring of the Drinfeld modules; if- False, return the norm as an element in this function ring (only relevant for endomorphisms)
 - EXAMPLES: - sage: Fq = GF(5) sage: A.<T> = Fq[] sage: K.<z> = Fq.extension(3) sage: phi = DrinfeldModule(A, [z, 0, 1, z]) sage: t = phi.ore_variable() sage: f = phi.hom(t + 1) sage: f.norm() Principal ideal (T + 4) of Univariate Polynomial Ring in T over Finite Field of size 5 - >>> from sage.all import * >>> Fq = GF(Integer(5)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(3), names=('z',)); (z,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z, Integer(0), Integer(1), z]) >>> t = phi.ore_variable() >>> f = phi.hom(t + Integer(1)) >>> f.norm() Principal ideal (T + 4) of Univariate Polynomial Ring in T over Finite Field of size 5 - The norm of the Frobenius endomorphism is equal to the characteristic: - sage: F = phi.frobenius_endomorphism() sage: F.norm() Principal ideal (T^3 + 3*T + 3) of Univariate Polynomial Ring in T over Finite Field of size 5 sage: phi.characteristic() T^3 + 3*T + 3 - >>> from sage.all import * >>> F = phi.frobenius_endomorphism() >>> F.norm() Principal ideal (T^3 + 3*T + 3) of Univariate Polynomial Ring in T over Finite Field of size 5 >>> phi.characteristic() T^3 + 3*T + 3 - For \(a\) in the underlying function ring, the norm of the endomorphism given by \(\phi_a\) is \(a^r\) where \(r\) is the rank: - sage: g = phi.hom(T) sage: g.norm() Principal ideal (T^3) of Univariate Polynomial Ring in T over Finite Field of size 5 sage: h = phi.hom(T+1) sage: h.norm() Principal ideal (T^3 + 3*T^2 + 3*T + 1) of Univariate Polynomial Ring in T over Finite Field of size 5 - >>> from sage.all import * >>> g = phi.hom(T) >>> g.norm() Principal ideal (T^3) of Univariate Polynomial Ring in T over Finite Field of size 5 >>> h = phi.hom(T+Integer(1)) >>> h.norm() Principal ideal (T^3 + 3*T^2 + 3*T + 1) of Univariate Polynomial Ring in T over Finite Field of size 5 - For endomorphisms, the norm is not an ideal of \(A\) but it makes sense as an actual element of \(A\). We can get this element by passing in the argument - ideal=False:- sage: phi.hom(2*T).norm(ideal=False) 3*T^3 sage: f.norm(ideal=False) Traceback (most recent call last): ... ValueError: norm is defined as an actual element only for endomorphisms - >>> from sage.all import * >>> phi.hom(Integer(2)*T).norm(ideal=False) 3*T^3 >>> f.norm(ideal=False) Traceback (most recent call last): ... ValueError: norm is defined as an actual element only for endomorphisms 
 - ore_polynomial()[source]¶
- Return the Ore polynomial that defines the morphism. - EXAMPLES: - sage: Fq = GF(2) sage: A.<T> = Fq[] sage: K.<z6> = Fq.extension(6) sage: phi = DrinfeldModule(A, [z6, 1, 1]) sage: psi = DrinfeldModule(A, [z6, z6^4 + z6^2 + 1, 1]) sage: t = phi.ore_polring().gen() sage: morphism = Hom(phi, psi)(t + z6^5 + z6^2 + 1) sage: ore_pol = morphism.ore_polynomial() sage: ore_pol t + z6^5 + z6^2 + 1 - >>> from sage.all import * >>> Fq = GF(Integer(2)) >>> A = Fq['T']; (T,) = A._first_ngens(1) >>> K = Fq.extension(Integer(6), names=('z6',)); (z6,) = K._first_ngens(1) >>> phi = DrinfeldModule(A, [z6, Integer(1), Integer(1)]) >>> psi = DrinfeldModule(A, [z6, z6**Integer(4) + z6**Integer(2) + Integer(1), Integer(1)]) >>> t = phi.ore_polring().gen() >>> morphism = Hom(phi, psi)(t + z6**Integer(5) + z6**Integer(2) + Integer(1)) >>> ore_pol = morphism.ore_polynomial() >>> ore_pol t + z6^5 + z6^2 + 1 - sage: ore_pol * phi(T) == psi(T) * ore_pol True - >>> from sage.all import * >>> ore_pol * phi(T) == psi(T) * ore_pol True