sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.23k stars 429 forks source link

Implement algebraic closures of finite fields #14990

Closed pjbruin closed 10 years ago

pjbruin commented 11 years ago

The goal of this ticket is a basic implementation of algebraic closures of finite fields. Most importantly, it provides the following:

An example using the new functionality is the following analogue of the example from #8335:

sage: Fbar = GF(3).algebraic_closure('z')
sage: Fbar
Algebraic closure of Finite Field of size 3
sage: F2, e2 = Fbar.subfield(2)
sage: F3, e3 = Fbar.subfield(3)
sage: F2
Finite Field in z2 of size 3^2

To add, we first embed into Fbar:

sage: x2 = e2(F2.gen())
sage: x3 = e3(F3.gen())
sage: x = x2 + x3
sage: x
z6^5 + 2*z6^4 + 2*z6^3 + z6^2 + 2*z6 + 1
sage: x.parent() is Fbar
True

One can also do this without explicitly invoking the embeddings; as a shortcut, Fbar has a method gen(n) returning the fixed generator of the subfield of degree n, but as an element of Fbar:

sage: x2 == Fbar.gen(2)
True
sage: x == Fbar.gen(2) + Fbar.gen(3)
True

It is conceivable that there will be different coexisting implementations (deriving from AlgebraicClosureFiniteField_generic). The current implementation uses Conway polynomials and the pseudo-Conway polynomials from #14958, as well as the functionality for finite field homomorphisms provided by #13214.

Depends on #14958 Depends on #13214

CC: @roed314 @jpflori @sagetrac-JCooley @sagetrac-dfesti @defeo @videlec @sagetrac-erousseau

Component: algebra

Keywords: finite field algebraic closure

Author: Peter Bruin

Branch: b0e1539

Reviewer: Vincent Delecroix

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

jpflori commented 11 years ago
comment:1

Another important question is to know what the AlgebraicClosure structure should cache. If its possible not to store all data that was previously cmputed when some finite fields aren't used anymore, then it can make sense to discard it (imagine working with pseudo-Conway polynomials and only going up and up, at some point you won't care about polynomials used for small finite fields). This is really arguable, but we (or I at least) had several problems before (and we still have) because pieces of Sage tend to cache too much.

pjbruin commented 10 years ago
comment:2

Replying to @jpflori:

Another important question is to know what the AlgebraicClosure structure should cache. If its possible not to store all data that was previously cmputed when some finite fields aren't used anymore, then it can make sense to discard it (imagine working with pseudo-Conway polynomials and only going up and up, at some point you won't care about polynomials used for small finite fields). This is really arguable, but we (or I at least) had several problems before (and we still have) because pieces of Sage tend to cache too much.

Yes, this is something to keep in mind. As a first step, I imagine simply storing the polynomials for all fields that we encounter. This could become problematic, especially when working with fields whose degree over the prime field is highly composite. There are at least two solutions:

pjbruin commented 10 years ago

Author: Peter Bruin

pjbruin commented 10 years ago

Description changed:

--- 
+++ 
@@ -1,14 +1,14 @@
-Algebraic closures of finite fields should be implemented.  Most importantly, we will need the following:
+The goal of this ticket is a basic implementation of algebraic closures of finite fields.  Most importantly, it provides the following:

 - class `AlgebraicClosureFiniteField`
   - method `subfield(n)` returning a tuple consisting of the subfield of order *p<sup>n</sup>* and a `RingHomomorphism_im_gens` giving the canonical embedding into the algebraic closure
 - class `AlgebraicClosureFiniteFieldElement`
-  (should mostly be a wrapper around `FiniteFieldElement`, so actually an element of a finite subfield, but having the algebraic closure as its parent and taking care of coercion into larger subfields)
+  (mostly a wrapper around `FiniteFieldElement`, so actually an element of a finite subfield, but having the algebraic closure as its parent and taking care of coercion into larger subfields)
 - method `FiniteField.algebraic_closure()`

 (Alternative names: `FiniteFieldAlgebraicClosure`, `FiniteFieldAlgebraicClosureElement`, maybe with aliases `FFpbar`, `FFpbarElement`?)

-An example using the new functionality would be the following analogue of the example from #8335:
+An example using the new functionality is the following analogue of the example from #8335:

sage: Fbar = GF(3).algebraic_closure('z') @@ -30,7 +30,7 @@ sage: x.parent() is Fbar True

-It would be nice to do this without explicitly invoking the embeddings; as a shortcut, `Fbar` should have a method `gen(n)` returning the fixed generator of the subfield of degree *n*, but as an element of `Fbar`:
+One can also do this without explicitly invoking the embeddings; as a shortcut, `Fbar` has a method `gen(n)` returning the fixed generator of the subfield of degree *n*, but as an element of `Fbar`:

sage: x2 == Fbar.gen(2) @@ -39,6 +39,6 @@ True


-(The above example assumes that an `AlgebraicClosureFiniteFieldElement` is printed in the same way as the underlying `FiniteFieldElement`; we do not necessarily have to do this.)
+(The above example shows that `AlgebraicClosureFiniteFieldElement` is printed in the same way as the underlying `FiniteFieldElement`.)

-It is conceivable that there will be different coexisting implementations (classes deriving from an abstract `AlgebraicClosureFiniteField`).  The first (and easiest) to implement should use Conway polynomials and the pseudo-Conway polynomials from #14958, probably using some of the code from #8335.
+It is conceivable that there will be different coexisting implementations (classes deriving from an abstract `AlgebraicClosureFiniteField`).  The current implementation uses Conway polynomials and the pseudo-Conway polynomials from #14958, as well as the functionality for finite field homomorphisms provided by #13214.
pjbruin commented 10 years ago
comment:3

Here is a first implementation. The examples in the ticket description work exactly as written. It doesn't have a huge amount of functionality yet; for example, it would be nice to be able to factor polynomials over an algebraic closure of Fp. But this can probably wait until another ticket.

pjbruin commented 10 years ago

Changed dependencies from #14958 to #14958, #13214

pjbruin commented 10 years ago

Description changed:

--- 
+++ 
@@ -1,12 +1,12 @@
 The goal of this ticket is a basic implementation of algebraic closures of finite fields.  Most importantly, it provides the following:

-- class `AlgebraicClosureFiniteField`
+- class `AlgebraicClosureFiniteField_generic` (abstract base class)
   - method `subfield(n)` returning a tuple consisting of the subfield of order *p<sup>n</sup>* and a `RingHomomorphism_im_gens` giving the canonical embedding into the algebraic closure
+- class `AlgebraicClosureFiniteField_pseudo_conway` (implements the specific defining polynomials of the finite subfields and the relations between the generators of these subfields)
 - class `AlgebraicClosureFiniteFieldElement`
   (mostly a wrapper around `FiniteFieldElement`, so actually an element of a finite subfield, but having the algebraic closure as its parent and taking care of coercion into larger subfields)
-- method `FiniteField.algebraic_closure()`
-
-(Alternative names: `FiniteFieldAlgebraicClosure`, `FiniteFieldAlgebraicClosureElement`, maybe with aliases `FFpbar`, `FFpbarElement`?)
+- factory class `AlgebraicClosureFiniteField` (to get unique parents)
+- method `FiniteField.algebraic_closure()` (invokes the factory class)

 An example using the new functionality is the following analogue of the example from #8335:

@@ -39,6 +39,7 @@
 True

-(The above example shows that AlgebraicClosureFiniteFieldElement is printed in the same way as the underlying FiniteFieldElement.) +It is conceivable that there will be different coexisting implementations (deriving from AlgebraicClosureFiniteField_generic). The current implementation uses Conway polynomials and the pseudo-Conway polynomials from #14958, as well as the functionality for finite field homomorphisms provided by #13214.

-It is conceivable that there will be different coexisting implementations (classes deriving from an abstract AlgebraicClosureFiniteField). The current implementation uses Conway polynomials and the pseudo-Conway polynomials from #14958, as well as the functionality for finite field homomorphisms provided by #13214. +Apply: attachment: trac_14990-algebraic_closure_finite_field.patch +

pjbruin commented 10 years ago
comment:6

Patch updated; now also implements is_square() and sqrt(), and makes doctests pass again.

pjbruin commented 10 years ago

Attachment: trac_14990-algebraic_closure_finite_field.patch.gz

update (doctest coverage)

defeo commented 10 years ago
comment:7

Nice work. I agree this is the way to go for Fp-bar. Here's some thoughts.

  1. It'd be nice to implement a _latex_ method in the elements.

  2. There's a quote problem in the first paragraph of the docstring:

    '[\Bold{F}_n:\Bold{F}]=1`
  3. I'm perplexed about the _cmp_ function in conway_polynomials.py:

    sage: PCL3 = PseudoConwayLattice(3, use_database=False)
    sage: PCL5 = PseudoConwayLattice(5, use_database=False)
    sage: PCL3 == PCL5
    True

    Is this the intended result?

  4. F.inclusion(1, a).section() is None for any a, this makes _change_level fail.

  5. I wonder: wouldn't it be more efficient if _coerce_2 had a shortcut for when x and y are in the same level? (I really don't know, just wondering)

  6. This patch lacks some obvious coercions, for example, F._subfield(2)(F.gen(2)). Should this wait for another ticket, or should this ticket do it?

I'd like to play around with different implementations of Fp-bar. This would help understand if the abstract class AlgebraicClosureFiniteField_generic is abstract enough, or if we need to think more carefully about its interface.

I don't know what's best: make this ticket enter 5.13, then start experimenting? Or, rather, keep experimenting and wait the different implementations to have settled before giving positive review?

If you want to go for the first, I'd be happy to give positive review as soon as the minor problems mentioned above are solved. If you prefer the second option, would you mind switching to git, so to ease collaboration?

jpflori commented 10 years ago
comment:8

Replying to @defeo:

Nice work. I agree this is the way to go for Fp-bar. Here's some thoughts.

  1. It'd be nice to implement a _latex_ method in the elements.

Sure.

  1. There's a quote problem in the first paragraph of the docstring:

    '[\Bold{F}_n:\Bold{F}]=1`
  2. I'm perplexed about the _cmp_ function in conway_polynomials.py:

    sage: PCL3 = PseudoConwayLattice(3, use_database=False)
    sage: PCL5 = PseudoConwayLattice(5, use_database=False)
    sage: PCL3 == PCL5
    True

    Is this the intended result?

This looks wrong to me.

  1. F.inclusion(1, a).section() is None for any a, this makes _change_level fail.

  2. I wonder: wouldn't it be more efficient if _coerce_2 had a shortcut for when x and y are in the same level? (I really don't know, just wondering)

Stupid rant: I don' like the name _coerce_2, I don't think it really fits with our current naming scheme, nor that it really suggests what the function does (I first thought of coerce_to... of course it is two, not to).

About the shortcut, why not, but it does not seem that urgent. Maybe we should do some timings.

  1. This patch lacks some obvious coercions, for example, F._subfield(2)(F.gen(2)). Should this wait for another ticket, or should this ticket do it?

Depends on the difficulty? :)

I'd like to play around with different implementations of Fp-bar. This would help understand if the abstract class AlgebraicClosureFiniteField_generic is abstract enough, or if we need to think more carefully about its interface.

I don't know what's best: make this ticket enter 5.13, then start experimenting? Or, rather, keep experimenting and wait the different implementations to have settled before giving positive review?

If you want to go for the first, I'd be happy to give positive review as soon as the minor problems mentioned above are solved. If you prefer the second option, would you mind switching to git, so to ease collaboration?

I don't really know. I'm usually for fast inclusion. But for this one I might be inclined to wait for 6.0 to give it a little more testing.

In particular, I'd like to make sure that this gets well with #715, #11521, #14711, #15303 and other coercion related stuff, though there should be no problems from what I currently see. We should also to check that when the user deletes an algebraic closure objects, everything gets garbage collected.

Maybe it needs some more thinking on the category framework integration with more general algebraic closures (not even sure it would make sense though)? I see the Factory currently sets it to Fields(). Additional question: how does it interact with the AlgebraicClosureFunctor from sage.categories.pushout? Not sure how harmful it would be to modify that after the current ticket is merged.

videlec commented 10 years ago
comment:9

Hi,

Thanks for the nice patch! I played a little bit with the patch and here are few comments (from a user point of vue).

For the FiniteFieldAlgebraicClosure

For elements

   def my_method(self):
       return self._value.my_method()

this concerns minimal_polynomial, trace, norm, multiplicative_order, ...

Vincent

pjbruin commented 10 years ago
comment:11

Thanks to you all for the comments. I haven't got a lot of time at the moment, but hope to get back to this ticket soon. In the meantime, feel free to continue suggesting improvements or implementing them yourselves. 8-)

videlec commented 10 years ago
comment:12

Replying to @pjbruin:

Thanks to you all for the comments. I haven't got a lot of time at the moment, but hope to get back to this ticket soon. In the meantime, feel free to continue suggesting improvements or implementing them yourselves. 8-)

Thanks. I am happy to work on this (I already implements the remarks I made). Is that ok if I switch to the git workflow ?

defeo commented 10 years ago
comment:13

Replying to @videlec:

Thanks. I am happy to work on this (I already implements the remarks I made). Is that ok if I switch to the git workflow ?

Even if this ticket doesn't switch to the git workflow, I'd be happy to pull from your branch and start experimenting. Do you mind sharing it in a comment?

videlec commented 10 years ago
comment:14

Replying to @defeo:

Replying to @videlec:

Thanks. I am happy to work on this (I already implements the remarks I made). Is that ok if I switch to the git workflow ?

Even if this ticket doesn't switch to the git workflow, I'd be happy to pull from your branch and start experimenting. Do you mind sharing it in a comment?

This is: u/vdelecroix/14990

pjbruin commented 10 years ago
comment:15

Replying to @videlec:

Replying to @pjbruin:

Thanks to you all for the comments. I haven't got a lot of time at the moment, but hope to get back to this ticket soon. In the meantime, feel free to continue suggesting improvements or implementing them yourselves. 8-)

Thanks. I am happy to work on this (I already implements the remarks I made). Is that ok if I switch to the git workflow ?

I haven't done any development with Sage+Git before (only uploaded an SSH key and installed Sage using Git), but I'll start trying it out. Once I get some facility in using it, I won't mind if this will become a Git ticket.

videlec commented 10 years ago
comment:16

Replying to @pjbruin:

Replying to @videlec:

Replying to @pjbruin:

Thanks to you all for the comments. I haven't got a lot of time at the moment, but hope to get back to this ticket soon. In the meantime, feel free to continue suggesting improvements or implementing them yourselves. 8-)

Thanks. I am happy to work on this (I already implements the remarks I made). Is that ok if I switch to the git workflow ?

I haven't done any development with Sage+Git before (only uploaded an SSH key and installed Sage using Git), but I'll start trying it out. Once I get some facility in using it, I won't mind if this will become a Git ticket.

Hi Peter,

I switch to git only recently and it is not easy to go from git to patches (the other way around is quite easy using the sage dev scripts). I modified several things from your patch, in particular: algebraic_closure now works without argument (the name is 'z' by default). I think that I will modify the following two problems

From the last version #15390 (roots of polynomial and eigenvalues) works nicely !

Your work is really nice!

Cheers, Vincent

pjbruin commented 10 years ago
comment:17

Now experimenting with Git. I made some changes to Vincent's branch and will now try to create my own branch on Trac. You can ignore this for the moment...

pjbruin commented 10 years ago

Branch: u/pbruin/14990

videlec commented 10 years ago
comment:19

Hi,

In order to speed up a bit, you could add the following lines at the very begining of the method _to_common_subfield(self, x, y) (lines 561-580)

if x._level == y._level:
    return x._value, y._value

(when the level is the same I go from 3ms to 0.8ms)

What do you think about what I suggest in comment:15 namely, implementing .is_finite() (returning False) and do something for Zmod(3) ?


Last 10 new commits:

[dbc331b](https://github.com/sagemath/sagetrac-mirror/commit/dbc331b)rename _coerce_2 to _to_common_subfield; cosmetic changes
[ac93a01](https://github.com/sagemath/sagetrac-mirror/commit/ac93a01)remove the optional name from algebraic_closure examples
[2432102](https://github.com/sagemath/sagetrac-mirror/commit/2432102)allow no argument for .algebraic_closure()
[a197d0d](https://github.com/sagemath/sagetrac-mirror/commit/a197d0d)Merge branch 'u/vdelecroix/14990' of ssh://trac.sagemath.org:2222/sage into 14990
[f232993](https://github.com/sagemath/sagetrac-mirror/commit/f232993)fix the parent in pth_root and pth_power
[0f4b895](https://github.com/sagemath/sagetrac-mirror/commit/0f4b895)add examples to .cardinality()
[d95f57f](https://github.com/sagemath/sagetrac-mirror/commit/d95f57f)more methods to algebraic elements
[081c096](https://github.com/sagemath/sagetrac-mirror/commit/081c096)Trac 14990: implement algebraic closures of finite fields
[31045f7](https://github.com/sagemath/sagetrac-mirror/commit/31045f7)fix the parent in pth_root and pth_power
[3d88af6](https://github.com/sagemath/sagetrac-mirror/commit/3d88af6)add examples to .cardinality()
videlec commented 10 years ago

Commit: dbc331b

pjbruin commented 10 years ago
comment:20

Replying to @videlec:

In order to speed up a bit, you could add the following lines at the very begining of the method _to_common_subfield(self, x, y) (lines 561-580)

I guess I could, but would you mind doing this yourself? (First because it's your change, but also so that I can get an idea about what this causes Git to do. If this kind of thing works smoothly, I'd be happy to definitively make this a Git ticket.) Or do I have to somehow change permissions on my branch for that?

videlec commented 10 years ago
comment:21

Replying to @pjbruin:

Replying to @videlec:

In order to speed up a bit, you could add the following lines at the very begining of the method _to_common_subfield(self, x, y) (lines 561-580)

I guess I could, but would you mind doing this yourself? (First because it's your change, but also so that I can get an idea about what this causes Git to do. If this kind of thing works smoothly, I'd be happy to definitively make this a Git ticket.) Or do I have to somehow change permissions on my branch for that?

I can not have write access to your branch on trac. But nevertheless it is still possible to synchronize our works. I will do the modification inside my branch u/vdelecroix/14990 and then you can update the changes to your local branch with

$ git checkout THE_NAME_OF_MY_LOCAL_BRANCH_FOR_14990
$ git pull trac u/vdelecroix/14990
$ git reset --merge

Once it is done you can just push the changes to your branch u/pruin/14990 on trac. The second command above pull the changes but do not reset the HEAD. The third one is precisely here for that purpose: it reset the head to the current FETCH_HEAD obtained from pull.

I will tell you when I am done.

jpflori commented 10 years ago
comment:22

Hey, I'm not sure using pull/reset is the safer and best way to share your work together. What I would do, but I might be wrong, is to track the other one branch as a remote. Then go to my local branch and merge the other one latest changes.

videlec commented 10 years ago
comment:23

Hey,

Thanks Jean-Pierre for the suggestion. My method is what is described in the developer guide. Anyway, how should I do to declare u/pbruin/14990 on trac has a remote ?

Best, Vincent

videlec commented 10 years ago
comment:24

Hi,

I push my changes to u/vdelecroix/14990. For the Zmod(p) suggestion it is actually possible to obtain the algebraic closure with

sage: Zmod(3).field().algebraic_closure()
Algebraic closure of Finite Field of size 3

So I think there is nothing to change here.

V.

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 10 years ago

Changed commit from dbc331b to f8540ae

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 10 years ago

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

[f8540ae](https://github.com/sagemath/sagetrac-mirror/commit/f8540ae)fix comparison of pseudo-Conway polynomial trees
[d6cf8d6](https://github.com/sagemath/sagetrac-mirror/commit/d6cf8d6)tiny optimization for _to_common_subfield and implementation of is_finite.
jpflori commented 10 years ago
comment:26

Replying to @videlec:

Hey,

Thanks Jean-Pierre for the suggestion. My method is what is described in the developer guide. Anyway, how should I do to declare u/pbruin/14990 on trac has a remote ?

In fact, doing "pull" is the same thing as doing "fetch+merge" at once in your local branch. It's just I find it nicer to have a bunch of remotes synchronized locally to be able to have a look at them, make local branch from them for experimentation and so on, before merging them into actual working branches. Then you don't need the "reset --merge" trick (that I didn't know!).

To add a branch to an existing remote (as trac already exist and you surely want to track all branches coming from the trac server in the same remote), you can issue:

pjbruin commented 10 years ago
comment:27

Hi Vincent,

Replying to @videlec:

  • .is_finite() fails on GF(3).algebraic_closure() (raise a NotImplementedError). On the other hand it will be fixed with the new category schemes which allows Field().infinite())

Are you sure we should remove is_finite() and cardinality() after #10963 is done? Maybe a user wants to pass a custom category to __init__() (say Ring() or Fields()); then the magic wouldn't work anymore, it seems.

pjbruin commented 10 years ago

Description changed:

--- 
+++ 
@@ -41,5 +41,3 @@

 It is conceivable that there will be different coexisting implementations (deriving from `AlgebraicClosureFiniteField_generic`).  The current implementation uses Conway polynomials and the pseudo-Conway polynomials from #14958, as well as the functionality for finite field homomorphisms provided by #13214.

-Apply: [attachment: trac_14990-algebraic_closure_finite_field.patch](https://github.com/sagemath/sage-prod/files/10658221/trac_14990-algebraic_closure_finite_field.patch.gz)
-
pjbruin commented 10 years ago
comment:28

For me Git seems to work fine now; I propose we continue with this.

After a combination of Git commands and editing .git/config by hand, it looks as follows:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = git://github.com/sagemath/sage.git
[branch "master"]
        remote = origin
        merge = refs/heads/master
[remote "trac"]
        url = git://trac.sagemath.org/sage.git
        fetch = +refs/heads/master:refs/remotes/trac/master
        fetch = +refs/heads/u/pbruin/14990:refs/remotes/trac/u/pbruin/14990
        fetch = +refs/heads/u/vdelecroix/14990:refs/remotes/trac/u/vdelecroix/14990
[branch "ticket/14990"]
        remote = trac
        merge = refs/heads/u/pbruin/14990

Does this look correct to the more experienced Git users?

pjbruin commented 10 years ago
comment:29

The following problems observed by Luca in comment:7 still need to be fixed:

  1. It'd be nice to implement a _latex_ method in the elements.

  2. F.inclusion(1, a).section() is None for any a, this makes _change_level fail.

  3. This patch lacks some obvious coercions, for example, F._subfield(2)(F.gen(2)). Should this wait for another ticket, or should this ticket do it?

pjbruin commented 10 years ago

Work Issues: see comment 29

videlec commented 10 years ago
comment:30

Replying to @pjbruin:

The following problems observed by Luca in comment:7 still need to be fixed:

  1. It'd be nice to implement a _latex_ method in the elements.

  2. F.inclusion(1, a).section() is None for any a, this makes _change_level fail.

  3. This patch lacks some obvious coercions, for example, F._subfield(2)(F.gen(2)). Should this wait for another ticket, or should this ticket do it?

I implemented 1 using self._value.latex().

For 4, why is there a method _change_level, it is nowhere used ? Anyway, what do you expect as a section ? It needs to be compatible with embeddings of subfields.

For 6, it is definitely not a coercion but rather a conversion. It would be nice to have it but I am in favor of having it for a next ticket.

pjbruin commented 10 years ago
comment:31

Replying to @videlec:

Replying to @pjbruin:

The following problems observed by Luca in comment:7 still need to be fixed:

  1. It'd be nice to implement a _latex_ method in the elements.

  2. F.inclusion(1, a).section() is None for any a, this makes _change_level fail.

  3. This patch lacks some obvious coercions, for example, F._subfield(2)(F.gen(2)). Should this wait for another ticket, or should this ticket do it?

I implemented 1 using self._value.latex().

That seems like the right solution. The last doctest was wrong, at least on my system; this will be fixed in my next commit.

For 4, why is there a method _change_level, it is nowhere used ? Anyway, what do you expect as a section ? It needs to be compatible with embeddings of subfields.

The bug involving the prime subfield has been fixed. The section of the embedding between two subfields is just the map that sends an element of the larger subfield to the unique preimage in the smaller one if it exists, and raises a ValueError otherwise.

The reason for _change_level() is just that it would be nice to be able to change to a smaller internal representation of the same element, for example if one knows in advance that the result of a computation is going to be in a smaller subfield. Probably the function shouldn't have a leading underscore, though; I'm changing this.

For 6, it is definitely not a coercion but rather a conversion. It would be nice to have it but I am in favor of having it for a next ticket.

In principle we could register a conversion map from our algebraic closure to any finite subfield at the moment we construct this subfield, but this feels somewhat like a waste. Alternatively, we could create a class for embeddings of a finite field into an algebraic closure, and equip that with a section() method, or we could (less elegantly) teach the element constructors of the various finite field classes to accept elements of an algebraic closure.

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 10 years ago

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

[6325b20](https://github.com/sagemath/sagetrac-mirror/commit/6325b20)rename/fix change_level(); new doctests
[27cc628](https://github.com/sagemath/sagetrac-mirror/commit/27cc628)add a `_latex_` method to the elements
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 10 years ago

Changed commit from f8540ae to 6325b20

pjbruin commented 10 years ago
comment:33

One issue I have some doubts about is whether the name argument of FiniteField.algebraic_closure(self, name='z') should be optional. We require the user to specify a name in most cases (finite fields, number fields, polynomial rings, Hecke eigenforms, etc.), so allowing a default here seems to go against the convention.

An exception is CyclotomicField(), which generates names starting with zeta; but in this case one could argue that this naming convention is practically universal. In the case of AA and QQbar, the name a is used for the generator in as_number_field_element(), and here one cannot even specify a name; this seems to go against the convention as well.

videlec commented 10 years ago
comment:34

Replying to @pjbruin:

One issue I have some doubts about is whether the name argument of FiniteField.algebraic_closure(self, name='z') should be optional. We require the user to specify a name in most cases (finite fields, number fields, polynomial rings, Hecke eigenforms, etc.), so allowing a default here seems to go against the convention.

On the other hand, QQ.algebraic_closure() works and if you want a generic method for roots of polynomials and eigenvalues of matrices (have a look at #15390) then you do not want to guess about what kind of argument the algebraic closure needs. More precisely, you do

P.change_ring(P.base_ring().algebraic_closure()).roots()

I would not be in trouble if we have a default for the generator of finite field, polynomial ring, etc. Actually, GF(9) looks more natural to me than GF(9, 'a') as there is only one field of cardinality 9.

An exception is CyclotomicField(), which generates names starting with zeta; but in this case one could argue that this naming convention is practically universal. In the case of AA and QQbar, the name a is used for the generator in as_number_field_element(), and here one cannot even specify a name; this seems to go against the convention as well.

videlec commented 10 years ago
comment:35

For 4, why is there a method _change_level, it is nowhere used ? Anyway, what do you expect as a section ? It needs to be compatible with embeddings of subfields.

The bug involving the prime subfield has been fixed. The section of the embedding between two subfields is just the map that sends an element of the larger subfield to the unique preimage in the smaller one if it exists, and raises a ValueError otherwise.

The reason for _change_level() is just that it would be nice to be able to change to a smaller internal representation of the same element, for example if one knows in advance that the result of a computation is going to be in a smaller subfield. Probably the function shouldn't have a leading underscore, though; I'm changing this.

I see. But then, as a user, you do not want to guess what should be the level. If you have a look at .as_finite_field_element() there is a minimal option if set to True make the method returns the "optimal" level. If you compare with AA and QQbar the methods is called exactify or simplify (I do not understand the subtle difference between those two methods). The two latter do not accept arguments.

pjbruin commented 10 years ago
comment:36

Replying to @videlec:

On the other hand, QQ.algebraic_closure() works and if you want a generic method for roots of polynomials and eigenvalues of matrices (have a look at #15390) then you do not want to guess about what kind of argument the algebraic closure needs.

Fair point; as far as I am concerned, this is the main argument for allowing a default argument in FiniteField.algebraic_closure().

I would not be in trouble if we have a default for the generator of finite field, polynomial ring, etc. Actually, GF(9) looks more natural to me than GF(9, 'a') as there is only one field of cardinality 9.

That is true, but it is only unique up to non-canonical isomorphism, unlike Z/9Z, for example. To me the notation GF(9) looks too much like it is canonical, and insisting on a variable name is a good way to remind the user that a choice of a defining polynomial is being made.

For algebraic closures, I am inclined to say that the current status is not bad: keep 'z' as the default name for FiniteField.algebraic_closure(), but don't extend this to a default name for the AlgebraicClosureFiniteField constructor.

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 10 years ago

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

[5fe4189](https://github.com/sagemath/sagetrac-mirror/commit/5fe4189)matrix2.pyx: no special case for finite fields in F.algebraic_closure()
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 10 years ago

Changed commit from 6325b20 to 5fe4189

pjbruin commented 10 years ago

Description changed:

--- 
+++ 
@@ -40,4 +40,3 @@

It is conceivable that there will be different coexisting implementations (deriving from AlgebraicClosureFiniteField_generic). The current implementation uses Conway polynomials and the pseudo-Conway polynomials from #14958, as well as the functionality for finite field homomorphisms provided by #13214.

pjbruin commented 10 years ago

Changed work issues from see comment 29 to none

defeo commented 10 years ago
comment:39

Hi,

I'm still baking my own experimental version of Fp-bar on top of this ticket. I have a question: shouldn't _subfield() use check_irreducible=False in the FiniteField constructor? It looks like a waste to check twice for irreducibility.

pjbruin commented 10 years ago
comment:40

Replying to @defeo:

I'm still baking my own experimental version of Fp-bar on top of this ticket. I have a question: shouldn't _subfield() use check_irreducible=False in the FiniteField constructor? It looks like a waste to check twice for irreducibility.

Good idea, I'll rebase this ticket and then disable the check.

defeo commented 10 years ago
comment:41

Replying to @pjbruin:

Good idea, I'll rebase this ticket and then disable the check.

Why "rebase"? Maybe you meant "merge master"?