sagemath / sage

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

Global function fields: orders and ideals #25435

Closed kwankyu closed 6 years ago

kwankyu commented 6 years ago

This is part of the meta-ticket #22982.

The goal of the present ticket is to add code for computing finite and infinite maximal orders and ideals thereof.

The central engine for computing maximal orders is the Leonard-Pellikaan-Singh-Swanson algorithm implemented in Singular. Most algorithms for computing with ideals are from Cohen's book A Course in Computational Algebraic Number Theory.

Component: algebra

Author: Kwankyu Lee

Branch/Commit: 48100b4

Reviewer: Travis Scrimshaw

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

kwankyu commented 6 years ago

Branch: u/klee/25435

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

Commit: 14d325a

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

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

14d325aAdd orders and ideals
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

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

1649c10Remove is_Ideal
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 14d325a to 1649c10

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

Changed commit from 1649c10 to 36aae07

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

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

36aae07Trim some comments
tscrim commented 6 years ago
comment:6

There are some doctest failures according to the patchbot. Some of them come the file name change, which technically you should deprecate the old file name (see #19879 for an example how to do this) if you think people could be importing directly from the file.

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

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

77a64daFix a doctest failure due to a changed name
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 36aae07 to 77a64da

kwankyu commented 6 years ago
comment:8

Replying to @tscrim:

There are some doctest failures according to the patchbot. Some of them come the file name change, which technically you should deprecate the old file name (see #19879 for an example how to do this) if you think people could be importing directly from the file.

I regard it as an internal change. So there is no need to deprecate.

kwankyu commented 6 years ago
comment:9

The startup modules plugin complains that

New:
    _md5
    _sha
    _sha256
    _sha512
    sage.rings.function_field.element
    sage.rings.function_field.ideal
    sage.rings.function_field.order
Removed:
    _hashlib
    _ssl
    sage.rings.function_field.function_field_element
    ssl

I don't really understand what is happening and how to deal with it. I suspect that this is somehow related with __hash__ method in the ideal or order modules...

Travis, would you give me some tips?

tscrim commented 6 years ago
comment:10

So the last three extra imports are from this change to function_field.py:

+from .order import (
+    FunctionFieldOrder_basis,
+    FunctionFieldOrderInfinite_basis,
+    FunctionFieldMaximalOrder_rational,
+    FunctionFieldMaximalOrder_global,
+    FunctionFieldMaximalOrderInfinite_rational,
+    FunctionFieldMaximalOrderInfinite_global)

However, you seem to basically be doing these imports locally anyways. I would run pyflakes on the file to see what is being duplicated in terms of imports, and you should decide if they need to be at the module level.

I probably wouldn't worry about the others as they seem to be unrelated.

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

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

f362751Merge branch 'develop' into function_fields_1
21d4b5bRemove imports from .order at module level
895c379Remove some more imports from module level
2811ce3Remove CAT from module level in function_field
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 77a64da to 2811ce3

kwankyu commented 6 years ago
comment:12

Replying to @tscrim:

So the last three extra imports are from this change to function_field.py:

+from .order import (
+    FunctionFieldOrder_basis,
+    FunctionFieldOrderInfinite_basis,
+    FunctionFieldMaximalOrder_rational,
+    FunctionFieldMaximalOrder_global,
+    FunctionFieldMaximalOrderInfinite_rational,
+    FunctionFieldMaximalOrderInfinite_global)

However, you seem to basically be doing these imports locally anyways. I would run pyflakes on the file to see what is being duplicated in terms of imports, and you should decide if they need to be at the module level.

I probably wouldn't worry about the others as they seem to be unrelated.

Ok. Let's see what would happen with new commits, though still I don't understand where

   _md5
    _sha
    _sha256
    _sha512

come from...

tscrim commented 6 years ago
comment:13

Replying to @kwankyu:

Ok. Let's see what would happen with new commits, though still I don't understand where

   _md5
    _sha
    _sha256
    _sha512

come from...

I don't know either. I suspect it is an artifact or bug in the plugin.

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

Changed commit from 2811ce3 to cf4b92b

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

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

cf4b92bRestore erroneously deleted valuation method
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from cf4b92b to e34194f

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

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

e34194fRestore ideal_with_gens_over_base method for rational function field
kwankyu commented 6 years ago

Description changed:

--- 
+++ 
@@ -1,3 +1,5 @@
 This is part of the meta-ticket #22982. 

-The goal of the present ticket is to add code for computing finite and infinite maximal orders and ideals thereof. The central engine for computing maximal orders is the Leonard-Pellikaan-Singh-Swanson algorithm implemented in Singular. Most algorithms for computing with ideals are from Cohen's book  A Course in Computational Algebraic Number Theory.
+The goal of the present ticket is to add code for computing finite and infinite maximal orders and ideals thereof. 
+
+The central engine for computing maximal orders is the Leonard-Pellikaan-Singh-Swanson algorithm implemented in Singular. Most algorithms for computing with ideals are from Cohen's book  A Course in Computational Algebraic Number Theory.
dimpase commented 6 years ago
comment:18

Why do you copy Singular's library code here? The latter is available in SAGE_LOCAL/share/singular/LIB/

E.g. normal.lib with normalP is there.

kwankyu commented 6 years ago
comment:19

Replying to @dimpase:

Why do you copy Singular's library code here? The latter is available in SAGE_LOCAL/share/singular/LIB/

E.g. normal.lib with normalP is there.

The code of this patch was written more than two years ago. It might be the case that the normal.lib was then an experimental package. But I don't remember well.

Another reason that may still be relevant now is that the normalP in the singular library does more computations than necessary for my case. For example, it also computes delta invariants of the given ideal. So I decided to make a stripped-down light version of normalP just for the code in this ticket.

dimpase commented 6 years ago
comment:20

If it's a different version than the one in Singular, this should be made clear in the file header. The functions and .lib files also should be named differently, to prevent name clashes with the ones from the Singular lib.

dimpase commented 6 years ago
comment:21

Anyway, unless Singular's own version is significantly slower, you should rather use it.

kwankyu commented 6 years ago
comment:22

Replying to @dimpase:

Anyway, unless Singular's own version is significantly slower, you should rather use it.

I am trying this approach. During computation, the Singular's version spits out many comments, each line starting with //, causing doctest failures. Do you know how to deal with this?

Failed example:
    O = F.maximal_order()
Expected nothing
Got:
    <BLANKLINE>
    // ** WARNING: result is correct if ideal is prime (not checked) **
    // disable option "isPrim" to decompose ideal into prime components
    <BLANKLINE>
    <BLANKLINE>
    // 'normalP' computed a list, say nor, of two lists:
    // To see the result, type
         nor;
    <BLANKLINE>
    // * nor[1] is a list of 1 ideal(s), where each ideal nor[1][i] consists
    // of elements g1..gk of the basering R such that gj/gk generate the integral
    // closure of R/P_i (where P_i is a min. associated prime of the input ideal)
    // as R-module in the quotient field of R/P_i;
    <BLANKLINE>
    // * nor[2] shows the delta-invariant of each component and of the input ideal
    // (-1 means infinite, and 0 that R/P_i is normal).
kwankyu commented 6 years ago
comment:23

A small timing for you.

With my version:

sage:  K.<x> = FunctionField(GF(2));
sage: R.<t> = PolynomialRing(K);
sage: F.<y> = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18)
sage: time F.maximal_order()
CPU times: user 178 ms, sys: 27.3 ms, total: 205 ms
Wall time: 201 ms

With Singular's version:

sage:  K.<x> = FunctionField(GF(2));
sage: R.<t> = PolynomialRing(K);
sage: F.<y> = K.extension(t^4 + x^12*t^2 + x^18*t + x^21 + x^18)
sage: time F.maximal_order()
//...
...
//...
CPU times: user 222 ms, sys: 31.3 ms, total: 254 ms
Wall time: 249 ms
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

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

74b2e50Rename normalP in core.lib to core_normalize
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from e34194f to 74b2e50

kwankyu commented 6 years ago
comment:25

As using Singular's version has some technical problems noted above, I switched to the alternative path to renaming the procedure in core.lib

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

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

aa79205Add orders and ideals
b42ad6bRename files
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 74b2e50 to b42ad6b

kwankyu commented 6 years ago
comment:29

I force-pushed two commits. The first commit contains all changes, and the second commit contains only filename changes.

Hopefully, a reviewer could see the changes against the devel branch more easily from the first commit.

tscrim commented 6 years ago
comment:30

Can you do a rebase? If so, I will do the review for this in the next few days (now that I have freed up a bit of time).

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

Changed commit from b42ad6b to 5a67ee5

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

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

3cc6ecfAdd orders and ideals
5a67ee5Rename files
kwankyu commented 6 years ago
comment:32

Replying to @tscrim:

I will do the review for this in the next few days (now that I have freed up a bit of time).

Thank you, Travis. I thought of splitting this big patch into pieces, but it seemed difficult. If you find reviewing the patch annoying because of its size, let me know. Then I will try once again.

tscrim commented 6 years ago
comment:33

I have been able to make it through the code. I cannot vouch so much for the mathematical correctness, but it does work as documented. Here are my comments about the code:

kwankyu commented 6 years ago
comment:34

Replying to @tscrim:

  • For order_infinite_with_basis, did you want *basis instead of basis as an input (in which case, you will have to have check be part of a **kwds)? Or do you expect people to pass a list with a single list of basis elements inside?

The code seems to be intended to support these three cases:

L.order_infinite_with_basis([1/x,1/x*y, 1/x^2*y^2])

L.order_infinite_with_basis([1/x])

L.order_infinite_with_basis(1/x)

But this is not described in the docstring. Also this is not consistent with order_with_basis. Hence I will remove the responsible code from order_infinite_with_basis. Happily, there is no doctest failure because of this.

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

Changed commit from 5a67ee5 to 9a1bbb2

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

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

9a1bbb2Remove unnecessary code from order_infinite_with_basis
kwankyu commented 6 years ago
comment:36

Replying to @tscrim:

  • Can you construct FunctionFieldMaximalOrder(Infinite)_global with having a different basis?

No.

It feels like these classes should just take one input, FunctionField(_global), which then has a hook to construct the corresponding basis (or maybe do this computation on-demand in the class itself). This would allow FunctionFieldOrder to inherit from UniqueRepresentation and maximal_order_infinite() to not be cached. I don't see how FunctionFieldOrder and subclasses are compared/hashed by default (the default Parent.__hash__ using the string representation is a horrible hash too).

I followed your suggestion partially. Now FunctionFieldMaximalOrder class inherits UniqueRepresentation. So for maximal_order() and maximal_order_infinite() are not cached.

Orders created with a basis do have unique representation behavior. They could have cached representation behavior. But I don't see a reason to force this.

Equation orders can have unique representation behavior. But I leave them just to be cached. I don't see a compelling reason to avoid using @cached_method for these. Do you have?

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

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

d4c8e8bInherit UniqueRepresentation to MaximalOrder class
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 9a1bbb2 to d4c8e8b

tscrim commented 6 years ago
comment:38

Replying to @kwankyu:

Replying to @tscrim:

  • Can you construct FunctionFieldMaximalOrder(Infinite)_global with having a different basis?

No.

It feels like these classes should just take one input, FunctionField(_global), which then has a hook to construct the corresponding basis (or maybe do this computation on-demand in the class itself). This would allow FunctionFieldOrder to inherit from UniqueRepresentation and maximal_order_infinite() to not be cached. I don't see how FunctionFieldOrder and subclasses are compared/hashed by default (the default Parent.__hash__ using the string representation is a horrible hash too).

I followed your suggestion partially. Now FunctionFieldMaximalOrder class inherits UniqueRepresentation. So for maximal_order() and maximal_order_infinite() are not cached.

Orders created with a basis do have unique representation behavior. They could have cached representation behavior. But I don't see a reason to force this.

Thank you.

Equation orders can have unique representation behavior. But I leave them just to be cached. I don't see a compelling reason to avoid using @cached_method for these. Do you have?

They are subclasses of Parent, correct? Things work faster/better in regard to, say, coercion and equality with UniqueRepresentation. It is also faster to compare for equality and hash (just use the id in both cases). Speaking of which, because of the MRO, it is better to have UniqueRepresentation as the first class.

It also means the cache is tied with the object itself rather than a creation method. Say, someone else creates a (maybe completely separate) class that wants to use the basis classes. They would also have to implement a cache, which would either create two copies of the same object or have to make the two caches interact; both of which I think are bad.

FYI - if you do really only want cached behavior, there is a CachedRepresentation class you could use. However, I don't see a reason why not to upgrade to the UniqueRepresentation here.

kwankyu commented 6 years ago
comment:39

Replying to @tscrim:

Orders created with a basis do have unique representation behavior. They could have cached representation behavior. But I don't see a reason to force this.

Thank you.

There was a typo here. I meant:

Order_basis class does not have unique representation behavior. It could have cached representation behavior. But I don't see a reason to force this.

Equation orders can have unique representation behavior. But I leave them just to be cached. I don't see a compelling reason to avoid using @cached_method for these. Do you have?

They are subclasses of Parent, correct? Things work faster/better in regard to, say, coercion and equality with UniqueRepresentation. It is also faster to compare for equality and hash (just use the id in both cases). Speaking of which, because of the MRO, it is better to have UniqueRepresentation as the first class.

Ok. I will make this fix.

It also means the cache is tied with the object itself rather than a creation method. Say, someone else creates a (maybe completely separate) class that wants to use the basis classes. They would also have to implement a cache, which would either create two copies of the same object or have to make the two caches interact; both of which I think are bad.

I agree. But EquationOrder(Infinite) class is something that I do not expect to be subclassed. Anyway now it occurs to me that I can just get rid of this class, and use the superclassOrder_basis.

tscrim commented 6 years ago
comment:40

Replying to @kwankyu:

Replying to @tscrim:

Orders created with a basis do have unique representation behavior. They could have cached representation behavior. But I don't see a reason to force this.

Thank you.

There was a typo here. I meant:

Order_basis class does not have unique representation behavior. It could have cached representation behavior. But I don't see a reason to force this.

If you expect to create elements of this class and implement coercions between them, then it makes the mechanisms in the coercion framework work a lot better and faster. In addition to the reasons given below. However, this is only a suggestion, and I don't have a strong preference (or a stake in the outcome). If you prefer it this way, then that is fine with me.

It also means the cache is tied with the object itself rather than a creation method. Say, someone else creates a (maybe completely separate) class that wants to use the basis classes. They would also have to implement a cache, which would either create two copies of the same object or have to make the two caches interact; both of which I think are bad.

I agree. But EquationOrder(Infinite) class is something that I do not expect to be subclassed. Anyway now it occurs to me that I can just get rid of this class, and use the superclassOrder_basis.

Okay, but someone might have a completely different class that would call it. For example, someone implements a 3rd party library for function fields that we tie into Sage, but you still would want to have a method, say, equation_order from that new implementation. This would give the situation I am describing above. Granted, this is not so likely, but it is better to future-proof when there is little cost to complexity IMO.

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

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

5ee44a2Inherit CachedRepresentation to Order_basis class
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from d4c8e8b to 5ee44a2