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
– a 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
– a 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
True
whether 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
True
whether 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
True
whether 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
True
whether 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
– a boolean (default:True
); ifTrue
, return the norm as an ideal in the function ring of the Drinfeld modules; ifFalse
, 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