Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of finite Drinfeld modules #33713

Closed
kryzar opened this issue Apr 15, 2022 · 307 comments · Fixed by #35026
Closed

Implementation of finite Drinfeld modules #33713

kryzar opened this issue Apr 15, 2022 · 307 comments · Fixed by #35026

Comments

@kryzar
Copy link
Contributor

kryzar commented Apr 15, 2022

Edit (2022-09-27). A lot has changed since the original post. Here is a quick update.

What is a Drinfeld module?

Let L be a finite field extension of \Fq and fix a ring morphism \gamma: \Fq[X] \to L. Let \Ltau be the ring of Ore polynomials with coefficients in L and whose generator is the Frobenius endomorphism \tau: x \mapsto x^q. A Drinfeld module over the morphism \gamma \phi is uniquely defined by an \Fq-algebra morphism \Fq[X] \to \Ltau, P \mapsto \phi_P, verifying \phi_X = \gamma(X) + a_1\tau + \dots + a_r\tau^r and r > 0.

A morphism of Drinfeld modules u: \phi \to \psi is defined by an Ore polynomial u \in \Ltau verifying u \phi_X = \psi_X u.

Drinfeld modules and their morphisms are the object and morphisms of the category of Drinfeld modules defined over the morphism \gamma.

A Drinfeld module induces an \Fq[X]-module law on L, defined by a \star z = \phi_a(z), where a \in \Fq[X] and z \in L. This is referred to as the Drinfeld module action induced by \phi.

Overview

We created:

  • DrinfeldModule(Parent, UniqueRepresentation);
  • FiniteDrinfeldModule(DrinfeldModule);
  • DrinfeldModuleAction(Action);
  • DrinfeldModules(Category_over_base);
  • DrinfeldModuleHomset(Homset);
  • DrinfeldModuleMorphism(Morphism, UniqueRepresentation).

Here is a short demo:

sage: Fq = GF(2)
sage: FqX.<X> = Fq[]
sage: K.<i> = Fq.extension(2)
sage: phi = DrinfeldModule(FqX, [i, i, 1])
sage: phi
Drinfeld module defined by X |--> t^2 + i*t + i over base Ring morphism:
  From: Univariate Polynomial Ring in X over Finite Field of size 2 (using GF2X)
  To:   Finite Field in i of size 2^2
  Defn: X |--> i
sage: phi(X)
t^2 + i*t + i
sage: psi = DrinfeldModule(FqX, [i, i+1, 1])
sage: t = phi.ore_polring().gen()
sage: i + t in Hom(phi, psi)
True
sage: phi.velu(i + t)
Drinfeld module defined by X |--> t^2 + (i + 1)*t + i over base Ring morphism:
  From: Univariate Polynomial Ring in X over Finite Field of size 2 (using GF2X)
  To:   Finite Field in i of size 2^2
  Defn: X |--> i



I would like to propose an implementation for finite Drinfeld modules. I
opened this ticket to discuss this idea and have feedback on implementation
directions, in order to comply with Sage's guidelines. Please feel free to express any doubt or criticism, or give ideas! I very much value the collaborative aspect of the SageMath community.

Motivation

A finite Drinfeld module is defined as follows. Let Fq be a finite fields
with q elements, let L be a finite extension of Fq. Consider the
\Fqbar-linear endomorphism \tau: x \mapsto x^q, and define L\{\tau\} as
the ring of Ore polynomials in \tau with coefficients in L (see [ticket: 29629]). Also fix \omega a non zero element of
L. An \Fq-Drinfeld module defined over L is, by definition, an
\Fq-algebra morphism \phi: \Fq[X]\toL\{\tau\} such that:

  • \phi(X) as constant coefficient \omega,
  • \phi(\Fq[X]) is not contained in L.

At the moment, there exists no such implementation in Sage.

Drinfeld modules are standard arithmetic tools in the theory of function
fields. See [Goss, Basic structures of function field arithmetic, 1998],
[Rosen, Number theory in function fields, 2002]. Good resources are also
[Gekeler, On finite Drinfeld modules, 1991], [Hayes, ''A brief introduction to
Drinfeld modules*, 1991] and [Caranay, Greenberg, Scheidler, *Computing modular
polynomials and isogenies of rank two Drinfeld modules'', 2020]. The author of
this ticket got interested in Drinfeld modules with isogeny-based cryptographic
applications in mind; see https://arxiv.org/abs/2203.06970.

I am a first-year PhD student working with
P.-J. Spaenlehauer and
E. Thomé.

Implementation details

I propose three classes: FiniteDrinfeldModule, FiniteDrinfeldModulesRankSet
and FiniteDrinfeldModulesSet.

The FiniteDrinfeldModule class

This is the class for representing finite Drinfeld modules. It must be
instantiated with a polynomial ring and an Ore polynomial ring:

sage: Fq = GF(2)
sage: L = Fq.extension(2)
sage: FqX.<X> = Fq[]
sage: Ltau.<t> = OrePolynomialRing(L, L.frobenius_endomorphism())
sage: omega = L.gen()
sage: phi_X = omega + t + t^2
sage: phi = FiniteDrinfeldModule(FqX, Ltau, phi_X)  # phi is only defined by the image of X

Here are the methods that I wish to add in the first version:

sage: phi.generator()  # phi_X
t^2 + t + z2
sage: phi(X^2)  # Magic method __call__
t^4 + t^2 + t + z2 + 1
sage: phi.polynomial_ring  # Property, reference to FqX
Univariate Polynomial Ring in X over Finite Field of size 2 (using GF2X)
sage: phi.ore_polynomial_ring  # Property, reference to Ltau
Ore Polynomial Ring in t over Finite Field in z2 of size 2^2 twisted by z2 |--> z2^2
sage: phi.rank  # Property, rank of phi
2
sage: phi.frobenius  # Property, returns t
t
sage: phi.omega  # Property, returns omega
z2
sage: phi.Fq  # Property, reference to Fq
Finite Field of size 2
sage: phi.definition_field  # Property, reference to L
Finite Field in z2 of size 2^2
sage: phi.j_invariant  # Only if rank is 2, returns j-invariant
1

A crucial feature of finite Drinfeld module is that they endow the algebraic
closure \Fqbar with a structure of left-\Fq[X]-module. I think the most
appropriate mechanism is to have a method algebraic_closure_action return a
LeftModuleAction (see
https://doc.sagemath.org/html/en/reference/coercion/sage/structure/coerce_actions.html#sage.structure.coerce_actions.LeftModuleAction).
I am not yet sure if it is the best way to do it.

On top of this, the first version should be well doctested and include Sage's
own magic method (_repr_, _latex, etc).

In further versions, I wish to include:

  • methods in isogenies of Drinfeld modules (esp. Vélu's formula for Drinfeld modules);
  • methods on the torsion of Drinfeld modules (module law and vector space law);
  • class methods (instanciate a random Drinfeld module, or from a j-invariant);
  • methods on the well-definition of a Drinfeld module on some sub-field of L.

Naturally, any input (especially negative) is more than welcome!

The FiniteDrinfeldModulesRankSet and FiniteDrinfeldModulesSet classes

To comply with the coercion model (see
https://doc.sagemath.org/html/en/developer/coding_in_python.html#the-sage-coercion-model,
https://doc.sagemath.org/html/en/reference/coercion/index.html), any instance
of FiniteDrinfeldModule must have a parent. I was thinking about creating a
class FiniteDrinfeldModulesRankSet, representing the set of all finite
Drinfeld modules (with FqX, Ltau and omega fixed) with a prescribed rank.
The class FiniteDrinfeldModulesSet is the same, except the rank can be
arbitrary.

The details are not clear to me at this point.

Development environment

It is not clear to me yet in which environment I should work: tox virtual
environment, Docker ?.. Any advice is more than welcome.

Depends on #34692

CC: @xcaruso @mbombar @zimmermann6 @DavidAyotte @spaenlehauer

Component: number theory

Keywords: Drinfeld modules, Ore polynomials, Function fields

Author: Antoine Leudière

Branch/Commit: public/drinfeld_module @ 6982ae0

Issue created by migration from https://trac.sagemath.org/ticket/33713

@kryzar kryzar added this to the sage-9.6 milestone Apr 15, 2022
@kryzar

This comment has been minimized.

@xcaruso
Copy link
Contributor

xcaruso commented Apr 16, 2022

comment:2

Some quick comments:

  • I'm not completely sure that Drinfeld modules should be elements of some parent; maybe, actually, they could parents themselves (e.g. elliptic curves are parents) but it is also not that nice because it breaks the construction phi(X^2); I do not know if having something outside this hierarchy is relevant here.
  • usually in Sage, we do not expose properties but methods, e.g. phi.polynomial_ring() is more appropriate than phi.polynomial_ring, etc.
  • for the development environment, to start with, I think you can simply create a new git branch on your local repository, work on it and push it here on trac when you're ready.

@mkoeppe mkoeppe modified the milestones: sage-9.6, sage-9.7 Apr 17, 2022
@kryzar
Copy link
Contributor Author

kryzar commented Apr 19, 2022

comment:4

Hi Xavier, thank you for your input. Ok for the methods instead of properties. For the parent/coercion, the paragraph Parents and Elements states
Most things in Sage are either parents or have a parent.

I think it is quite nice, when in doubt about something, to be able to call parent(phi) and have the set of Drinfeld modules in which phi was defined. Of course, this is a bit redundant with _repr_.

Anyway, the most important thing is FiniteDrinfeldModule, and this is where I start.

@kryzar
Copy link
Contributor Author

kryzar commented Apr 19, 2022

@kryzar
Copy link
Contributor Author

kryzar commented Apr 19, 2022

Commit: 439907f

@kryzar

This comment has been minimized.

@fchapoton
Copy link
Contributor

comment:6
  • la case Author (ici plus haut) doit contenir le nom complet, c'est tout

  • il suffit de donner le nom de la branche, pas besoin de remplir la case commit

@fchapoton
Copy link
Contributor

Changed author from Antoine Leudière (antoine-leudiere) to Antoine Leudière

@fchapoton
Copy link
Contributor

comment:7

Il existe une hiérarchie : catégorie > parent > élément.

Moralement, chaque parent est un ensemble.

Par exemple, la catégorie "Groups", dans laquelle se placent les parents qui sont des groupes, ces parents ayant eux mêmes des éléments. Pour un parent donné, on peut demander sa catégorie par la méthode .category() et aussi .categories().

Peut-être qu'il n'est pas nécessaire de créer la catégorie "DrinfeldModules" maintenant.

@kryzar
Copy link
Contributor Author

kryzar commented Apr 20, 2022

comment:8

Replying to @fchapoton:

Il existe une hiérarchie : catégorie > parent > élément.

Moralement, chaque parent est un ensemble.

Par exemple, la catégorie "Groups", dans laquelle se placent les parents qui sont des groupes, ces parents ayant eux mêmes des éléments. Pour un parent donné, on peut demander sa catégorie par la méthode .category() et aussi .categories().

Peut-être qu'il n'est pas nécessaire de créer la catégorie "DrinfeldModules" maintenant.

Merci Frédéric ; c'est entendu, nous verrons plus tard.

@xcaruso
Copy link
Contributor

xcaruso commented Apr 23, 2022

comment:9

Ah tiens, on parle français maintenant ici ?
I switch to english because I think that other people might be interested.

The difficulty, I think, with Drinfeld modules is that they exhibit as the same time aspects of elements and parents.
By definition, they are ring homomorphisms from Fq[X] to some Ore polynomial ring. In this sense, they should be considered as elements of some hom space. However, in practice, my understanding is that we often view them as spaces (in general Fqbar) endowed with a semi-linear action of the algebra Fq[X]. As such, it makes sense to consider the category of Drinfeld modules and define methods which are usually related to parents (e.g. rank, definition_field, etc.).

IMO, the situation is quite similar to what we have for group representations, which can be viewed either as group morphisms G -> GLn(K) or as K-vector spaces endowed with a linear action of G. In sage, the latter point of view is privilegied but I'm not sure we should follow the same pattern here because the most standard definition of Drinfeld modules are in terms of ring homomorphisms.

@kryzar
Copy link
Contributor Author

kryzar commented Apr 25, 2022

comment:10

This is a good synthethis of the problem. It is true that most interesting
properties of Drinfeld modules come from the Fq[X]-algebra structure on Fqbar.
However, the structure of ring homomorphism is richer and we should not forget
it. For exemple, it is with it that we can easily define the rank or the
characteristic polynomial. But in the meantime, talking about Drinfeld module
as only ring homomorphisms kinda misses the point of those objects, as we are
primilarly interested in their action on Fqbar.

That's why my initial idea was to make drinfeld modules children of some
DrinfeldModuleSet or DrinfeldModuleCategory (not too familiar with
conventions here). I believe with this I can still make the class
FiniteDrinfeldModule inherit RingHomomorphism.

I plan on soon pushing a first draft of FiniteDrinfeldModule that inherits
RingHomomorphism.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 26, 2022

Changed commit from 439907f to df3598c

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 26, 2022

Branch pushed to git repo; I updated commit sha1. New commits:

df3598cCreate a draft of FiniteDrinfeldModule

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 26, 2022

Changed commit from df3598c to 84c7b5b

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 26, 2022

Branch pushed to git repo; I updated commit sha1. New commits:

84c7b5bCreate draft for finite Drinfeld module doctest

@kryzar
Copy link
Contributor Author

kryzar commented Apr 26, 2022

comment:13

Hi guys.

I commited and pushed an elementary draft for FiniteDrinfeldModule (the
class representing Drinfeld modules) and FiniteDrinfeldModuleAction (the
class representing the \Fq[X]-action given by a Drinfeld module).

You can try them now. The (incomplete and rudimentary) doctest gives you usage
examples.

Any feedback would be greatly appreciated, so that I do not go in the wrong
direction.

Summary:

  • FiniteDrinfeldModule inherits sage.rings.morphism.RingHomomorphism_im_gens.
  • FiniteDrinfeldModuleAction inherits sage.categories.action.Action.
  • I tried to systematically check the validity of the user inputs. I still have
    corner cases to cover though.
  • The computation of the action is done in
    FiniteDrinfeldModuleAction._act_, but I really do not know if this is the
    right place. The documentation was not clear to me so I chose this option via
    trial and error and by looking at the code of Action.
  • Similarly, the method of FiniteDrinfeldModule used to get the associated
    action is _get_action_, which seems wrong considering the _ prefix.
  • I put those two classes in a single file, located in
    $SAGE_ROOT/src/sage/modules. As discussed below, this may be misleading
    considering that, technically a Drinfeld module is not a module but a
    morphism. Furthermore, may be the two classes should be in separate files.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 27, 2022

Branch pushed to git repo; I updated commit sha1. New commits:

2723f99Fix FiniteDrinfeldModule action in all.py

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 27, 2022

Changed commit from 84c7b5b to 2723f99

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented May 12, 2022

Changed commit from 2723f99 to 7c96d1f

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented May 12, 2022

Branch pushed to git repo; I updated commit sha1. Last 10 new commits:

8bef6baRefactor `_latex_` method in FiniteDrinfeldModule
f0a9f63Refactor FiniteDrinfeldModuleAction
86348ffAdd various getters for FiniteDrinfeldModule
2c24562Add methods to deal with complex multiplication in FiniteDrinfeldModule
0499221Add methods to deal with isogenies in FiniteDrinfeldModule
3609c91Move FiniteDrinfeldModule to sage.rings.function_field
e3fc37fFix method is_morphism in FiniteDrinfeldModule
0515d9bAdd blank line before FiniteDrinfeldModuleAction (PEP8)
8c848d9Refactor doctest in FiniteDrinfeldModule
7c96d1fAlphabetically order methods in sage.rings.function_field.finite_drinfeld_module.py

@fchapoton
Copy link
Contributor

comment:16

le linter (qui vérifie certains détails dans le code) est pas content:

sage/rings/function_field/finite_drinfeld_module.py:295:12: E713 test for membership should be 'not in'
16
sage/rings/function_field/finite_drinfeld_module.py:389:12: E713 test for membership should be 'not in'
17
sage/rings/function_field/finite_drinfeld_module.py:411:12: E713 test for membership should be 'not in'
18
sage/rings/function_field/finite_drinfeld_module.py:420:12: E713 test for membership should be 'not in'
19
sage/rings/function_field/finite_drinfeld_module.py:453:12: E713 test for membership should be 'not in'

@kryzar
Copy link
Contributor Author

kryzar commented May 13, 2022

comment:17

Thank you Frédéric for the reminder. I'll be sure to check that out.

Replying to @fchapoton:

le linter (qui vérifie certains détails dans le code) est pas content:

sage/rings/function_field/finite_drinfeld_module.py:295:12: E713 test for membership should be 'not in'
16
sage/rings/function_field/finite_drinfeld_module.py:389:12: E713 test for membership should be 'not in'
17
sage/rings/function_field/finite_drinfeld_module.py:411:12: E713 test for membership should be 'not in'
18
sage/rings/function_field/finite_drinfeld_module.py:420:12: E713 test for membership should be 'not in'
19
sage/rings/function_field/finite_drinfeld_module.py:453:12: E713 test for membership should be 'not in'

@DavidAyotte
Copy link
Member

comment:19

Hello Antoine,
thank you for this new feature, it looks very well done! Is there a reason why you only consider Drinfeld modules over finite fields? Some times ago I did a basic implementation of Drinfeld modules over A = Fq[T] (see https://github.com/DavidAyotte/drinfeld_modules) (still unfinished, my end goal is to work with Drinfeld modular forms). Also, do you plan to implement a constructor for your Drinfeld module class? For example, given a finite list of element in a finite field [a_0, a_1,... , a_r], the constructor could create a Drinfeld module of rank r defined by

T |---> a_0 + a_1*tau + ... + a_r*tau^r (tau = frobenius endomorphism).

I think that this would improve the usage of this implementation for the end-user. Anyhow, I will be looking forward to this ticket and I will be glad to help you if you have any questions!

@DavidAyotte
Copy link
Member

comment:265

Hi, after a good night of sleep, I was thinking about the last example I brought up in my last comment and I think that I was a bit confused. In fact, it should be possible to consider such Drinfeld module even if the characteristic of the chosen A-field is finite. The conditions to be a Drinfeld module are imposed only on the constant coefficient. Sorry for this confusion!

Also, if a Drinfeld module defined over Fq(X) have its coefficients in Fq, should we call it finite?

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 11, 2022

Changed commit from 7d8e358 to 78c99e0

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 11, 2022

Branch pushed to git repo; I updated commit sha1. New commits:

26fe426(fix) Adress typos from comment 264
bee20a0Add details on the base definition in DrinfeldModule doc
78c99e0Enhance "base ring comment"

@kryzar
Copy link
Contributor Author

kryzar commented Oct 11, 2022

comment:267

Replying to Matthias Köppe:

Replying to Antoine Leudière:

It comes as no surprise that TestSuite(drinfeld_module).run() fails.

You can skip specific tests by passing skip=['...', '...'] to run

Thanks for the tip; this looks like the way to go.

Replying to David Ayotte:

  • About this comment:
        # FIXME
        # The parent method `base_ring` is defined not here, as it
        # should be, but in `DrinfeldModule`.
        #
        # This is because calling `phi.base_ring()` calls the
        # `base_ring` method of `CategoryObject` and not the one defined
        # here.
        #
        # This works, but any better solution would be welcome.
Here, you are not using `CategoryObject` anymore, so I think that you can remove this comment. Also, you have an other mention of `CategoryObject` in the `base_ring` method of `DrinfeldModule`:
    def base_ring(self):
        r"""
        Raise exception ``AttributeError``.

        The base of a Drinfeld module is a ring morphism, not a ring.

        This method is implemented in ``CategoryObject``, of which Parent
        inherits. It returns the base of the category. I overloaded it
        to avoid confusion.
In fact, I think you don't need this method anymore, since you now use `Category_over_base`.

Apologies for not making things clearer.

The problem is the following. In this implementation, the base of a Drinfeld
module category is a morphism \gamma: A \to K rather than just the field
K. Therefore, the method base_ring is misleading (to me at least), and I
don't want it implemented (this is debatable, as a change_ring method would
be nice).

However, the class DrinfeldModule inherits Parent, which inherits
CategoryObject. The class CategoryObject implements the method base_ring,
only to return self._base (see
$SAGE_ROOT/src/sage/structure/category_object.pyx, line 610). Consequently,
it is always possible to call phi.base_ring(). My goal is then to have this
method raise an exception when called, to emphasize that here, Drinfeld modules
do not have base rings. The first thing I tried was to implement base_ring in
the class ParentMethods: part of DrinfeldModules. However, this does not
work, and the solution I found was to define the method in DrinfeldModule.

The definition of base_ring should in the parent methods of
DrinfeldModules, as it is a method that depends on the sole category.

I tried to make the comment clearer, hope that's better.

Replying to David Ayotte:

  • On the same topic of base ring, I think that this is a bug:
sage: A = GF(5)['T']; K = Frac(A)
sage: phi = DrinfeldModule(A, [K(2), K.one()]); phi
Drinfeld module defined by T |--> t + 2 over base Ring morphism:
  From: Univariate Polynomial Ring in T over Finite Field of size 5
  To:   Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 5
  Defn: T |--> 2
sage: phi.is_finite()
False
Also, this should not be possible:
sage: A = GF(5)['T']; K = Frac(A)
sage: DrinfeldModule(A, [K(2), K.gen()])
Drinfeld module defined by T |--> T*t + 2 over base Ring morphism:
  From: Univariate Polynomial Ring in T over Finite Field of size 5
  To:   Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 5
  Defn: T |--> 2
Indeed, the coefficients of a Drinfeld module should be elements of the image of the base (and `T` is not in the image in the example above). One fix for this would be to try to convert the constant coefficient of the Drinfeld module into an element of a finite field. For example, this works:
sage: phi.function_ring().base_ring()(phi.constant_coefficient())
2
even though `phi.constant_coefficient()` is an element of `Frac(A)`. However, there might be a better way of doing this.

Replying to David Ayotte:

Hi, after a good night of sleep, I was thinking about the last example I brought up in my last comment and I think that I was a bit confused. In fact, it should be possible to consider such Drinfeld module even if the characteristic of the chosen A-field is finite. The conditions to be a Drinfeld module are imposed only on the constant coefficient. Sorry for this confusion!

Also, if a Drinfeld module defined over Fq(X) have its coefficients in Fq, should we call it finite?

I think you are raising a crucial question. It shows that there is ambiguity in
the documentation that must be addressed.

In my view, the ideal solution would be to instantiate a Drinfeld module phi
by giving a morphism A \to K\{\tau\} as the input. We can deduce the
base ring morphism from here as the morphism \Fq[X] \to K defined by
D \circ \phi, where D is the "constant-coefficient function".

As we saw in the early days of this ticket, this requires numerous lines of
code, and we chose a lighter solution: DrinfeldModule is defined with the
sole generator; the base morphism is implicitly defined as the ring morphism
A \to K that maps a to the constant coefficient of \phi_a, and where K
is the compositum of all the parents of the coefficients.

This means that a Drinfeld module whose coefficients lie in a finite field
(e.g. \Fq) but whose parent is a function field (e.g. \Fq(X)) would not be
considered finite.

I amended the documentation to make it clearer. What do you think?

@DavidAyotte
Copy link
Member

comment:268

Replying to Antoine Leudière:

The problem is the following. In this implementation, the base of a Drinfeld module category is a morphism \gamma: A \to K rather than just the field K. Therefore, the method base_ring is misleading (to me at least), and I don't want it implemented (this is debatable, as a change_ring method would be nice).

May I ask what are the advantages of considering a A-field (A = Fq[X]) as a morphism? Mathematically, a A-field is just a field F which is a A-algebra F via a morphism Fq[X] ---> F. Thus, I think that there are two valid points of view for a A-field (as a field or as a morphism) in a similar way that there are two valid points of view for a representation (as a module or a group morphism). So, to rephrase my question, what made you choose to consider the morphism point of view?

In my view, the ideal solution would be to instantiate a Drinfeld module phi
by giving a morphism A \to K\{\tau\} as the input. We can deduce the
base ring morphism from here as the morphism \Fq[X] \to K defined by
D \circ \phi, where D is the "constant-coefficient function".

As we saw in the early days of this ticket, this requires numerous lines of
code, and we chose a lighter solution: DrinfeldModule is defined with the
sole generator; the base morphism is implicitly defined as the ring morphism
A \to K that maps a to the constant coefficient of \phi_a, and where K
is the compositum of all the parents of the coefficients.

This means that a Drinfeld module whose coefficients lie in a finite field
(e.g. \Fq) but whose parent is a function field (e.g. \Fq(X)) would not be
considered finite.

Unless that I'm confused again, I think that by giving a morphism A --> K{\tau} as the input, the same problem could be possible to recreate: we could consider a morphism A --> \Fq(X){\tau} sending X to a \tau-polynomial with coefficient in \Fq which are coerced in \Fq(X).

Do you think that the Drinfeld module constructor could parse the coefficients a little bit further by checking if they can be converted into an element of a finite field? For example:

sage: A.<X> = GF(5)[]
sage: K.<X> = Frac(A)
sage: a = K(2)
sage: a.parent()
Fraction Field of Univariate Polynomial Ring in X over Finite Field of size 5
sage: b = K.base_ring()(a); b
2
sage: b.parent()
Finite Field of size 5
sage: K.base_ring()(X)
Traceback (most recent call last):
...
ValueError: not constant

@xcaruso
Copy link
Contributor

xcaruso commented Oct 13, 2022

comment:269

Replying to David Ayotte:

May I ask what are the advantages of considering a A-field (A = Fq[X]) as a morphism? Mathematically, a A-field is just a field F which is a A-algebra F via a morphism Fq[X] ---> F. Thus, I think that there are two valid points of view for a A-field (as a field or as a morphism) in a similar way that there are two valid points of view for a representation (as a module or a group morphism). So, to rephrase my question, what made you choose to consider the morphism point of view?

I propose to return F.over(phi.category().base()) which exactly returns what you wants, i.e. A considered as an algebra over Fq[X] through defining morphism.

Or, maybe even better, let phi.category().base() return also the ring extension.

@kryzar
Copy link
Contributor Author

kryzar commented Oct 17, 2022

comment:270

Replying to David Ayotte:

Replying to Antoine Leudière:

The problem is the following. In this implementation, the base of a Drinfeld module category is a morphism \gamma: A \to K rather than just the field K. Therefore, the method base_ring is misleading (to me at least), and I don't want it implemented (this is debatable, as a change_ring method would be nice).

May I ask what are the advantages of considering a A-field (A = Fq[X]) as a morphism? Mathematically, a A-field is just a field F which is a A-algebra F via a morphism Fq[X] ---> F. Thus, I think that there are two valid points of view for a A-field (as a field or as a morphism) in a similar way that there are two valid points of view for a representation (as a module or a group morphism). So, to rephrase my question, what made you choose to consider the morphism point of view?

I think both points of view are very good, and I did not know about
K.over(gamma), which is why I went for the morphism! Thanks Xavier for the
tip. Despite the morphism point of view working and being quite natural, I am
happy to change for the A-field point of view! I will refactor the code.

In my view, the ideal solution would be to instantiate a Drinfeld module phi
by giving a morphism A \to K\{\tau\} as the input. We can deduce the
base ring morphism from here as the morphism \Fq[X] \to K defined by
D \circ \phi, where D is the "constant-coefficient function".

As we saw in the early days of this ticket, this requires numerous lines of
code, and we chose a lighter solution: DrinfeldModule is defined with the
sole generator; the base morphism is implicitly defined as the ring morphism
A \to K that maps a to the constant coefficient of \phi_a, and where K
is the compositum of all the parents of the coefficients.

This means that a Drinfeld module whose coefficients lie in a finite field
(e.g. \Fq) but whose parent is a function field (e.g. \Fq(X)) would not be
considered finite.

Unless that I'm confused again, I think that by giving a morphism A --> K{\tau} as the input, the same problem could be possible to recreate: we could consider a morphism A --> \Fq(X){\tau} sending X to a \tau-polynomial with coefficient in \Fq which are coerced in \Fq(X).

Do you think that the Drinfeld module constructor could parse the coefficients a little bit further by checking if they can be converted into an element of a finite field? For example:

sage: A.<X> = GF(5)[]
sage: K.<X> = Frac(A)
sage: a = K(2)
sage: a.parent()
Fraction Field of Univariate Polynomial Ring in X over Finite Field of size 5
sage: b = K.base_ring()(a); b
2
sage: b.parent()
Finite Field of size 5
sage: K.base_ring()(X)
Traceback (most recent call last):
...
ValueError: not constant

Please let me know if I misunderstood something.

I think coefficients of the Drinfeld module generator should always be seen as
element of the codomain of the morphism gamma: A \to K that defines the
category. Even if the coefficients could be seen in a smaller, finite field.
This makes a clear convention; users can themselves specify the field they
want.

For example, if the Drinfeld module is defined using [Frac(FqX)(1), Frac(FqX)(1)],
I don't consider it finite, because K is Frac(FqX) and it
is infinite. However, this Drinfeld module canonically corresponds to a finite
Drinfeld module defined over \Fq. I suggest that the constructor stays the
same and doesn't try any conversion. We may however create a method that casts
the Drinfeld module to a new one with a smaller field, whenever possible.

@DavidAyotte
Copy link
Member

comment:271

Please let me know if I misunderstood something.

No I don't think that you misunderstood something. In fact, I think you've made some good points. I was seeing this as a problem, but, looking back, I find that it is really just a matter of definition/convention. Therefore, I'm totally fine to leave it as it is.

@kryzar
Copy link
Contributor Author

kryzar commented Oct 17, 2022

comment:272

Replying to David Ayotte:

Please let me know if I misunderstood something.

No I don't think that you misunderstood something. In fact, I think you've made some good points. I was seeing this as a problem, but, looking back, I find that it is really just a matter of definition/convention. Therefore, I'm totally fine to leave it as it is.

Understood. Thank you for this discussion!

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 15, 2022

Changed commit from 78c99e0 to 6982ae0

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 15, 2022

Branch pushed to git repo; I updated commit sha1. New commits:

31e8cf5Merge branch 'develop' into public/drinfeld_module
501a254Implement `characteristic` method for rings extensions
bcffa0cFix imprecision in documentation
675e249Add tests for characteristic method
ab2c211Fix doctest
6982ae0Merge branch 'public/ring-extension-characteristic' into public/drinfeld_module

@kryzar
Copy link
Contributor Author

kryzar commented Nov 15, 2022

Dependencies: #34692

@kryzar

This comment has been minimized.

@kryzar
Copy link
Contributor Author

kryzar commented Dec 9, 2022

comment:276

After discussing this with Xavier Caruso, we suggest to remove the class DrinfeldModuleAction in order to replace it by a new class, representing the module associated to a Drinfeld module. See ticket #34833, which will be worked on later.

Best,

Antoine

@roed314
Copy link
Contributor

roed314 commented Feb 8, 2023

comment:108
I only had a chance to take a brief look at the code, but I agree with Travis that this should be Parent/Element. Nothing much to add to what he explains in comment:103, except to emphasize that Category in Sage is a technical framework for managing dynamic Parent and Element classes. CategoryObject is just a low-level technical class - an object that has the notion of a distinguished category and delegates attribute look ups (as in method calls) to that category. Sage is not prepared for Category to take on the role of general mathematical categories.

I just saw @kryzar give a talk on this at Sage Days 117, and I think it makes a lot more sense to have Drinfeld modules be a CategoryObject and not a Parent. The original intention of that distinction was exactly for this purpose: to support categories without a forgetful functor to sets. That being said, I know that a lot of work has been done on this ticket since the decision to use Parent was made, and I think it's fine to choose to stick with that decision for convenience. But if there are future projects making this choice, I would advocate for using CategoryObject for this role and solving the problems that arise in doing so.

@mkoeppe
Copy link
Contributor

mkoeppe commented Feb 8, 2023

I think it's much better to just create a Parent that is not in the category Sets. It just requires removing one sentence in the documentation that says "parents model sets". There's nothing else that makes them sets.

@roed314
Copy link
Contributor

roed314 commented Feb 8, 2023

There's lots more that makes them sets. If you look at the majority of the code in sage/structure/parent.pyx, more than half of the code is focused on handling elements. And I can tell you that from a historical point of view (since I was at Sage Days 15 where this framework was laid out) that the distinction between Parent and CategoryObject is precisely whether it contains elements.

I haven't read all of the long discussion on this ticket, but it looks like you already had an argument with Travis about this. From the point of view of convenience, I think it's reasonable to abuse Parents in this way. But I don't think we should change the documentation, and I don't think we should discourage others from using CategoryObject in this way in the future if they think it's the right choice for their project.

@mkoeppe
Copy link
Contributor

mkoeppe commented Feb 8, 2023

I haven't read all of the long discussion on this ticket, but it looks like you already had an argument with Travis about this.

Yes, and I won ;)

@roed314
Copy link
Contributor

roed314 commented Feb 8, 2023

I have other projects to work on this week besides arguing about this, but I don't agree.

@mkoeppe
Copy link
Contributor

mkoeppe commented Feb 8, 2023

I don't agree.

Yes, that's the default before reading my argument.

@tscrim
Copy link
Collaborator

tscrim commented Feb 9, 2023

comment:108
I only had a chance to take a brief look at the code, but I agree with Travis that this should be Parent/Element. Nothing much to add to what he explains in comment:103, except to emphasize that Category in Sage is a technical framework for managing dynamic Parent and Element classes. CategoryObject is just a low-level technical class - an object that has the notion of a distinguished category and delegates attribute look ups (as in method calls) to that category. Sage is not prepared for Category to take on the role of general mathematical categories.

I just saw @kryzar give a talk on this at Sage Days 117, and I think it makes a lot more sense to have Drinfeld modules be a CategoryObject and not a Parent. The original intention of that distinction was exactly for this purpose: to support categories without a forgetful functor to sets. That being said, I know that a lot of work has been done on this ticket since the decision to use Parent was made, and I think it's fine to choose to stick with that decision for convenience. But if there are future projects making this choice, I would advocate for using CategoryObject for this role and solving the problems that arise in doing so.

I still believe that the Category is really a Parent and the Parent (CategoryObject) is really an Element, similar to ideals. This is how the code quacks, but there are some technical limitations with Map preventing this from working smoothly. It won't change the interface, but it would make it fit the paradigms within Sage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants