Set of morphisms between two Drinfeld modules

This module provides the class sage.rings.function_field.drinfeld_module.homset.DrinfeldModuleHomset.

AUTHORS:

  • Antoine Leudière (2022-04)

  • Xavier Caruso, Yossef Musleh (2025-08): added computation of bases of homsets

class sage.rings.function_field.drinfeld_modules.homset.DrinfeldModuleHomset(X, Y, category=None, check=True)[source]

Bases: Homset

This class implements the set of morphisms between two Drinfeld \(\GF{q}[T]\)-modules.

INPUT:

  • X – the domain

  • Y – the codomain

EXAMPLES:

sage: Fq = GF(27)
sage: A.<T> = Fq[]
sage: K.<z6> = Fq.extension(2)
sage: phi = DrinfeldModule(A, [z6, z6, 2])
sage: psi = DrinfeldModule(A, [z6, 2*z6^5 + 2*z6^4 + 2*z6 + 1, 2])
sage: H = Hom(phi, psi)
sage: H
Set of Drinfeld module morphisms
 from (gen) 2*τ^2 + z6*τ + z6
   to (gen) 2*τ^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*τ + z6
>>> from sage.all import *
>>> Fq = GF(Integer(27))
>>> A = Fq['T']; (T,) = A._first_ngens(1)
>>> K = Fq.extension(Integer(2), names=('z6',)); (z6,) = K._first_ngens(1)
>>> phi = DrinfeldModule(A, [z6, z6, Integer(2)])
>>> psi = DrinfeldModule(A, [z6, Integer(2)*z6**Integer(5) + Integer(2)*z6**Integer(4) + Integer(2)*z6 + Integer(1), Integer(2)])
>>> H = Hom(phi, psi)
>>> H
Set of Drinfeld module morphisms
 from (gen) 2*τ^2 + z6*τ + z6
   to (gen) 2*τ^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*τ + z6

sage: from sage.rings.function_field.drinfeld_modules.homset import DrinfeldModuleHomset
sage: isinstance(H, DrinfeldModuleHomset)
True
[Python]
>>> from sage.all import *
>>> from sage.rings.function_field.drinfeld_modules.homset import DrinfeldModuleHomset
>>> isinstance(H, DrinfeldModuleHomset)
True

There is a simpler syntax for endomorphisms sets:

sage: E = End(phi)
sage: E
Set of Drinfeld module morphisms from (gen) 2*τ^2 + z6*τ + z6 to (gen) 2*τ^2 + z6*τ + z6
sage: E is Hom(phi, phi)
True
>>> from sage.all import *
>>> E = End(phi)
>>> E
Set of Drinfeld module morphisms from (gen) 2*τ^2 + z6*τ + z6 to (gen) 2*τ^2 + z6*τ + z6
>>> E is Hom(phi, phi)
True

The domain and codomain must have the same Drinfeld modules category:

sage: rho = DrinfeldModule(A, [T, 1])
sage: Hom(phi, rho)
Traceback (most recent call last):
...
ValueError: Drinfeld modules must be in the same category
[Python]
>>> from sage.all import *
>>> rho = DrinfeldModule(A, [T, Integer(1)])
>>> Hom(phi, rho)
Traceback (most recent call last):
...
ValueError: Drinfeld modules must be in the same category

sage: sigma = DrinfeldModule(A, [1, z6, 2])
sage: Hom(phi, sigma)
Traceback (most recent call last):
...
ValueError: Drinfeld modules must be in the same category
>>> from sage.all import *
>>> sigma = DrinfeldModule(A, [Integer(1), z6, Integer(2)])
>>> Hom(phi, sigma)
Traceback (most recent call last):
...
ValueError: Drinfeld modules must be in the same category

One can create morphism objects by calling the homset:

sage: identity_morphism = E(1)
sage: identity_morphism
Identity morphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6
[Python]
>>> from sage.all import *
>>> identity_morphism = E(Integer(1))
>>> identity_morphism
Identity morphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6

sage: tau = phi.ore_variable()
sage: frobenius_endomorphism = E(tau^6)
sage: frobenius_endomorphism
Endomorphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6
  Defn: τ^6
>>> from sage.all import *
>>> tau = phi.ore_variable()
>>> frobenius_endomorphism = E(tau**Integer(6))
>>> frobenius_endomorphism
Endomorphism of Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6
  Defn: τ^6

sage: isogeny = H(tau + 1)
sage: isogeny
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6
  To:   Drinfeld module defined by T |--> 2*τ^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*τ + z6
  Defn: τ + 1
[Python]
>>> from sage.all import *
>>> isogeny = H(tau + Integer(1))
>>> isogeny
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> 2*τ^2 + z6*τ + z6
  To:   Drinfeld module defined by T |--> 2*τ^2 + (2*z6^5 + 2*z6^4 + 2*z6 + 1)*τ + z6
  Defn: τ + 1

And one can test if an Ore polynomial defines a morphism using the in syntax:

sage: 1 in H
False
sage: tau^6 in H
False
sage: tau + 1 in H
True
sage: 1 in E
True
sage: tau^6 in E
True
sage: tau + 1 in E
False
>>> from sage.all import *
>>> Integer(1) in H
False
>>> tau**Integer(6) in H
False
>>> tau + Integer(1) in H
True
>>> Integer(1) in E
True
>>> tau**Integer(6) in E
True
>>> tau + Integer(1) in E
False

This also works if the candidate is a morphism object:

sage: isogeny in H
True
sage: E(0) in E
True
sage: identity_morphism in H
False
sage: frobenius_endomorphism in H
False
[Python]
>>> from sage.all import *
>>> isogeny in H
True
>>> E(Integer(0)) in E
True
>>> identity_morphism in H
False
>>> frobenius_endomorphism in H
False
Element[source]

alias of DrinfeldModuleMorphism

an_element(degree=None)[source]

Return an element in this homset.

INPUT:

  • degree (default: None) – an integer; if given, return an isogeny of this degree

EXAMPLES:

sage: Fq = GF(2)
sage: A.<T> = Fq[]
sage: K.<z> = Fq.extension(3)
sage: phi = DrinfeldModule(A, [z, z^2 + z + 1, z^2 + z])
sage: psi = DrinfeldModule(A, [z, z + 1, z^2 + z + 1])
sage: H = Hom(phi, psi)
sage: H.an_element()
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: z^2*τ^3
>>> from sage.all import *
>>> Fq = GF(Integer(2))
>>> 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 + Integer(1), z**Integer(2) + z])
>>> psi = DrinfeldModule(A, [z, z + Integer(1), z**Integer(2) + z + Integer(1)])
>>> H = Hom(phi, psi)
>>> H.an_element()
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: z^2*τ^3

We can also ask for an isogeny with a required degree:

sage: H.an_element(degree=2)
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: (z^2 + 1)*τ^2 + τ + z + 1
[Python]
>>> from sage.all import *
>>> H.an_element(degree=Integer(2))
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: (z^2 + 1)*τ^2 + τ + z + 1

If there is no isogeny with the required degree, an error is raised:

sage: H.an_element(degree=1)
Traceback (most recent call last):
...
ValueError: no isogeny of given degree
>>> from sage.all import *
>>> H.an_element(degree=Integer(1))
Traceback (most recent call last):
...
ValueError: no isogeny of given degree

Below, \(\phi\) and \(\psi\) are not isogenous, so an_element() returns the zero morphism (which is the unique element in the homset):

sage: psi = DrinfeldModule(A, [z, z^2, z^3])
sage: H = Hom(phi, psi)
sage: H.an_element()
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z + 1)*τ^2 + z^2*τ + z
  Defn: 0
[Python]
>>> from sage.all import *
>>> psi = DrinfeldModule(A, [z, z**Integer(2), z**Integer(3)])
>>> H = Hom(phi, psi)
>>> H.an_element()
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z + 1)*τ^2 + z^2*τ + z
  Defn: 0

When the base is not a finite field, computing isogenies is not implemented so far, so this method always returns the zero morphism:

sage: phi = DrinfeldModule(A, [T, 1])
sage: End(phi).an_element()
Endomorphism of Drinfeld module defined by T |--> τ + T
  Defn: 0
sage: End(phi).an_element(degree=1)
Traceback (most recent call last):
...
NotImplementedError: computing isogenies are currently only implemented over finite fields
>>> from sage.all import *
>>> phi = DrinfeldModule(A, [T, Integer(1)])
>>> End(phi).an_element()
Endomorphism of Drinfeld module defined by T |--> τ + T
  Defn: 0
>>> End(phi).an_element(degree=Integer(1))
Traceback (most recent call last):
...
NotImplementedError: computing isogenies are currently only implemented over finite fields
basis(degree=None)[source]

Return a basis of this homset.

INPUT:

  • degree – an integer or None (default: None)

If degree is None, a basis over the underlying function ring is returned. Otherwise, a \(\GF{q}\)-basis of the set of morphisms of degree at most degree is returned.

ALGORITHM:

We reformulate the problem as a linear system over \(\GF{q}\) or \(A = \GF{q}[T]\) and solve it. We refer to [Wes2022] and [Mus2023], Section 7.3 for more details.

EXAMPLES:

sage: Fq = GF(5)
sage: A.<T> = Fq[]
sage: K.<z> = Fq.extension(2)
sage: phi = DrinfeldModule(A, [z, 0, 1, z])
sage: End(phi).basis()
[Identity morphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: τ^2,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: 2*τ^4 + z*τ^3 + z]
>>> from sage.all import *
>>> Fq = GF(Integer(5))
>>> A = Fq['T']; (T,) = A._first_ngens(1)
>>> K = Fq.extension(Integer(2), names=('z',)); (z,) = K._first_ngens(1)
>>> phi = DrinfeldModule(A, [z, Integer(0), Integer(1), z])
>>> End(phi).basis()
[Identity morphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: τ^2,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: 2*τ^4 + z*τ^3 + z]

If we specify a degree, a basis over \(\GF{q}\) is computed:

sage: End(phi).basis(degree=5)
[Identity morphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: z*τ^3 + z,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: τ^2,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: z*τ^5 + z*τ^2,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: τ^4]
[Python]
>>> from sage.all import *
>>> End(phi).basis(degree=Integer(5))
[Identity morphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: z*τ^3 + z,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: τ^2,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: z*τ^5 + z*τ^2,
 Endomorphism of Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   Defn: τ^4]

Here is another example where the domain and the codomain differ:

sage: psi = DrinfeldModule(A, [z, 3*z + 1, 2*z, 4*z + 1])
sage: H = Hom(phi, psi)
sage: H.basis()
[Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
   Defn: τ + 1,
 Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
   Defn: 3*τ^3 + (z + 2)*τ^2 + 4*z*τ + z + 4,
 Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
   Defn: (z + 4)*τ^2 + 4*z*τ + z + 4]

sage: H.basis(degree=2)
[Drinfeld Module morphism:
 From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
 Defn: τ + 1,
 Drinfeld Module morphism:
 From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
 Defn: (z + 4)*τ^2 + (4*z + 1)*τ + z]
>>> from sage.all import *
>>> psi = DrinfeldModule(A, [z, Integer(3)*z + Integer(1), Integer(2)*z, Integer(4)*z + Integer(1)])
>>> H = Hom(phi, psi)
>>> H.basis()
[Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
   Defn: τ + 1,
 Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
   Defn: 3*τ^3 + (z + 2)*τ^2 + 4*z*τ + z + 4,
 Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
   Defn: (z + 4)*τ^2 + 4*z*τ + z + 4]

>>> H.basis(degree=Integer(2))
[Drinfeld Module morphism:
 From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
 Defn: τ + 1,
 Drinfeld Module morphism:
 From: Drinfeld module defined by T |--> z*τ^3 + τ^2 + z
   To:   Drinfeld module defined by T |--> (4*z + 1)*τ^3 + 2*z*τ^2 + (3*z + 1)*τ + z
 Defn: (z + 4)*τ^2 + (4*z + 1)*τ + z]

We can check that \(\phi\) and \(\psi\) are not isomorphic by checking that there is no isogeny of degree \(0\) between them:

sage: H.basis(degree=0)
[]
[Python]
>>> from sage.all import *
>>> H.basis(degree=Integer(0))
[]

When \(\phi\) and \(\psi\) are not isogenous, an empty list is returned:

sage: psi = DrinfeldModule(A, [z, 3*z, 2*z, 4*z])
sage: Hom(phi, psi).basis()
[]
>>> from sage.all import *
>>> psi = DrinfeldModule(A, [z, Integer(3)*z, Integer(2)*z, Integer(4)*z])
>>> Hom(phi, psi).basis()
[]

Currently, this method only works over finite fields:

sage: A.<T> = GF(5)[]
sage: phi = DrinfeldModule(A, [T, 1])
sage: End(phi).basis()
Traceback (most recent call last):
...
NotImplementedError: computing basis of homsets are currently only implemented over finite fields
[Python]
>>> from sage.all import *
>>> A = GF(Integer(5))['T']; (T,) = A._first_ngens(1)
>>> phi = DrinfeldModule(A, [T, Integer(1)])
>>> End(phi).basis()
Traceback (most recent call last):
...
NotImplementedError: computing basis of homsets are currently only implemented over finite fields
basis_over_frobenius()[source]

Return a basis of this homser over \(\GF{q}[\tau^n]\) where \(n = [K:\GF{q}]\) (and thus \(\tau^n\) is to the Frobenius endomorphism).

ALGORITHM:

We return the basis of the kernel of a matrix derived from the constraint that \(\iota \phi_T = \psi_T \iota\) for any morphism \(iota: \phi \to \psi\). We refer to [Mus2023], Section 7.3 for more details.

EXAMPLES:

sage: Fq = GF(2)
sage: A.<T> = Fq[]
sage: K.<z> = Fq.extension(3)
sage: phi = DrinfeldModule(A, [z, z^2 + z + 1, z^2 + z])
sage: psi = DrinfeldModule(A, [z, z + 1, z^2 + z + 1])
sage: H = Hom(phi, psi)
sage: H.basis_over_frobenius()
[Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
   To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
   Defn: (z^2 + 1)*τ^2 + τ + z + 1,
 Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
   To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
   Defn: (z^2 + 1)*τ^5 + (z + 1)*τ^4 + z*τ^3 + τ^2 + (z^2 + z)*τ + z,
 Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
   To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
   Defn: z^2]
>>> from sage.all import *
>>> Fq = GF(Integer(2))
>>> 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 + Integer(1), z**Integer(2) + z])
>>> psi = DrinfeldModule(A, [z, z + Integer(1), z**Integer(2) + z + Integer(1)])
>>> H = Hom(phi, psi)
>>> H.basis_over_frobenius()
[Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
   To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
   Defn: (z^2 + 1)*τ^2 + τ + z + 1,
 Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
   To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
   Defn: (z^2 + 1)*τ^5 + (z + 1)*τ^4 + z*τ^3 + τ^2 + (z^2 + z)*τ + z,
 Drinfeld Module morphism:
   From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
   To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
   Defn: z^2]

sage: Fq = GF(5)
sage: A.<T> = Fq[]
sage: K.<z> = Fq.extension(3)
sage: phi = DrinfeldModule(A, [z, 3*z, 4*z])
sage: chi = DrinfeldModule(A, [z, 2*z^2 + 3, 4*z^2 + 4*z])
sage: H = Hom(phi, chi)
sage: H.basis_over_frobenius()
[]
[Python]
>>> 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(3)*z, Integer(4)*z])
>>> chi = DrinfeldModule(A, [z, Integer(2)*z**Integer(2) + Integer(3), Integer(4)*z**Integer(2) + Integer(4)*z])
>>> H = Hom(phi, chi)
>>> H.basis_over_frobenius()
[]
random_element(degree=None)[source]

Return a random morphism in this homset.

INPUT:

  • degree (default: None) – the maximum degree of the morphism

EXAMPLES:

sage: Fq = GF(2)
sage: A.<T> = Fq[]
sage: K.<z> = Fq.extension(3)
sage: psi = DrinfeldModule(A, [z, z + 1, z^2 + z + 1])
sage: phi = DrinfeldModule(A, [z, z^2 + z + 1, z^2 + z])
sage: H = Hom(phi, psi)
sage: H.random_element()  # random
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: z*τ^7 + (z^2 + 1)*τ^6 + τ^5 + z^2*τ^4 + (z^2 + z + 1)*τ^3 + τ^2 + (z^2 + z)*τ + z
>>> from sage.all import *
>>> Fq = GF(Integer(2))
>>> A = Fq['T']; (T,) = A._first_ngens(1)
>>> K = Fq.extension(Integer(3), names=('z',)); (z,) = K._first_ngens(1)
>>> psi = DrinfeldModule(A, [z, z + Integer(1), z**Integer(2) + z + Integer(1)])
>>> phi = DrinfeldModule(A, [z, z**Integer(2) + z + Integer(1), z**Integer(2) + z])
>>> H = Hom(phi, psi)
>>> H.random_element()  # random
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: z*τ^7 + (z^2 + 1)*τ^6 + τ^5 + z^2*τ^4 + (z^2 + z + 1)*τ^3 + τ^2 + (z^2 + z)*τ + z

When degree is given, a uniformly distributed random isogeny of degree at most the given value is outputted:

sage: H.random_element(3)  # random
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: (z^2 + 1)*τ^2 + τ + z + 1
[Python]
>>> from sage.all import *
>>> H.random_element(Integer(3))  # random
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: (z^2 + 1)*τ^2 + τ + z + 1

For producing a random isogeny with accurate degree, we can proceed as follows:

sage: H.an_element(3) + H.random_element(2)  # random
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: z^2*τ^3 + (z^2 + 1)*τ^2 + τ + z^2 + z + 1
>>> from sage.all import *
>>> H.an_element(Integer(3)) + H.random_element(Integer(2))  # random
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: z^2*τ^3 + (z^2 + 1)*τ^2 + τ + z^2 + z + 1

Currently, this method only works over finite fields:

sage: phi = DrinfeldModule(A, [T, 1])
sage: End(phi).random_element()
Traceback (most recent call last):
...
NotImplementedError: computing isogenies are currently only implemented over finite fields
[Python]
>>> from sage.all import *
>>> phi = DrinfeldModule(A, [T, Integer(1)])
>>> End(phi).random_element()
Traceback (most recent call last):
...
NotImplementedError: computing isogenies are currently only implemented over finite fields
zero()[source]

Return the zero morphism is this homset.

EXAMPLES:

sage: Fq = GF(5)
sage: A.<T> = Fq[]
sage: K.<z> = Fq.extension(3)
sage: phi = DrinfeldModule(A, [z, z^2 + z + 1, z^2 + z])
sage: psi = DrinfeldModule(A, [z, z + 1, z^2 + z + 1])
sage: H = Hom(phi, psi)
sage: H.zero()
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: 0
>>> 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, z**Integer(2) + z + Integer(1), z**Integer(2) + z])
>>> psi = DrinfeldModule(A, [z, z + Integer(1), z**Integer(2) + z + Integer(1)])
>>> H = Hom(phi, psi)
>>> H.zero()
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> (z^2 + z)*τ^2 + (z^2 + z + 1)*τ + z
  To:   Drinfeld module defined by T |--> (z^2 + z + 1)*τ^2 + (z + 1)*τ + z
  Defn: 0
class sage.rings.function_field.drinfeld_modules.homset.DrinfeldModuleMorphismAction(A, H, is_left, op)[source]

Bases: Action

Action of the function ring on the homset of a Drinfeld module.

EXAMPLES:

sage: Fq = GF(5)
sage: A.<T> = Fq[]
sage: K.<z> = Fq.extension(3)
sage: phi = DrinfeldModule(A, [z, 1, z])
sage: psi = DrinfeldModule(A, [z, z^2 + 4*z + 3, 2*z^2 + 4*z + 4])
sage: H = Hom(phi, psi)
sage: tau = phi.ore_variable()
sage: f = H(tau + 2)
>>> 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])
>>> psi = DrinfeldModule(A, [z, z**Integer(2) + Integer(4)*z + Integer(3), Integer(2)*z**Integer(2) + Integer(4)*z + Integer(4)])
>>> H = Hom(phi, psi)
>>> tau = phi.ore_variable()
>>> f = H(tau + Integer(2))

Left action:

sage: (T + 1) * f
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> z*τ^2 + τ + z
  To:   Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^2 + (z^2 + 4*z + 3)*τ + z
  Defn: (2*z^2 + 4*z + 4)*τ^3 + (2*z + 1)*τ^2 + (2*z^2 + 4*z + 2)*τ + 2*z + 2
[Python]
>>> from sage.all import *
>>> (T + Integer(1)) * f
Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> z*τ^2 + τ + z
  To:   Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^2 + (z^2 + 4*z + 3)*τ + z
  Defn: (2*z^2 + 4*z + 4)*τ^3 + (2*z + 1)*τ^2 + (2*z^2 + 4*z + 2)*τ + 2*z + 2

Right action currently does not work (it is a known bug, due to an incompatibility between multiplication of morphisms and the coercion system):

sage: f * (T + 1)
Traceback (most recent call last):
...
TypeError: right (=T + 1) must be a map to multiply it by Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> z*τ^2 + τ + z
  To:   Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^2 + (z^2 + 4*z + 3)*τ + z
  Defn: τ + 2
>>> from sage.all import *
>>> f * (T + Integer(1))
Traceback (most recent call last):
...
TypeError: right (=T + 1) must be a map to multiply it by Drinfeld Module morphism:
  From: Drinfeld module defined by T |--> z*τ^2 + τ + z
  To:   Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*τ^2 + (z^2 + 4*z + 3)*τ + z
  Defn: τ + 2