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
comment:42

Replying to @tscrim:

  • I am pretty sure there is a bug in the caching of vector_space as the key is always return None, so the base parameter is ignored. Actually, you do not need to have a key here because you error out when base is not None. Is this for compatibility with something else? Does base**1 do something? I feel like it should just be base. I guess some of this is a hold-over from the old code, so it is not a big issue.

This is not my code. But it seems not a bug to me. The intention is to force base to self (a rational function field) if given, since self is the only reasonable base field for a rational function field. If F is a rational function field,

F.vector_space()  ---> Ok. The base is F.
F.vector_space(F) ---> Ok. The base is F.
F.vector_space(G) ---> Raise an error.

For the first two cases, the cache key is None. On the other hand, base**1 creates a vector space over base of dimension 1.

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

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

12a78a0Move INPUT fields to the class docstrings
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 5ee44a2 to 12a78a0

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

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

b563d67Fix Returns to Return
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 12a78a0 to b563d67

tscrim commented 6 years ago
comment:45

Replying to @kwankyu:

Replying to @tscrim:

  • I am pretty sure there is a bug in the caching of vector_space as the key is always return None, so the base parameter is ignored. Actually, you do not need to have a key here because you error out when base is not None. Is this for compatibility with something else? Does base**1 do something? I feel like it should just be base. I guess some of this is a hold-over from the old code, so it is not a big issue.

This is not my code. But it seems not a bug to me. The intention is to force base to self (a rational function field) if given, since self is the only reasonable base field for a rational function field. If F is a rational function field,

F.vector_space()  ---> Ok. The base is F.
F.vector_space(F) ---> Ok. The base is F.
F.vector_space(G) ---> Raise an error.

For the first two cases, the cache key is None. On the other hand, base**1 creates a vector space over base of dimension 1.

Ah, right, that shorthand. It would definitely improve readability to have it be FreeModule(base, 1), but it is not important as it is just looks like a change because of the refactoring. I just do not see why vector_space should take an argument. Everything about that code says it should not have any arguments and you can should just replace base with self. Unless it is for some consistency or used in some other more general context?

kwankyu commented 6 years ago
comment:46

Replying to @tscrim:

Replying to @kwankyu:

Replying to @tscrim:

  • I am pretty sure there is a bug in the caching of vector_space as the key is always return None, so the base parameter is ignored. Actually, you do not need to have a key here because you error out when base is not None. Is this for compatibility with something else? Does base**1 do something? I feel like it should just be base. I guess some of this is a hold-over from the old code, so it is not a big issue.

This is not my code. But it seems not a bug to me. The intention is to force base to self (a rational function field) if given, since self is the only reasonable base field for a rational function field. If F is a rational function field,

F.vector_space()  ---> Ok. The base is F.
F.vector_space(F) ---> Ok. The base is F.
F.vector_space(G) ---> Raise an error.

For the first two cases, the cache key is None. On the other hand, base**1 creates a vector space over base of dimension 1.

Ah, right, that shorthand. It would definitely improve readability to have it be FreeModule(base, 1), but it is not important as it is just looks like a change because of the refactoring. I just do not see why vector_space should take an argument. Everything about that code says it should not have any arguments and you can should just replace base with self. Unless it is for some consistency or used in some other more general context?

It is for consistency. Note that general function fields also have vector_space, for which it is reasonable to take a base argument. Thus, perhaps, one can write generic code for function fields, rational or not. This is not my design.

tscrim commented 6 years ago
comment:47

Replying to @kwankyu:

It is for consistency. Note that general function fields also have vector_space, for which it is reasonable to take a base argument. Thus, perhaps, one can write generic code for function fields, rational or not. This is not my design.

Fair enough. I only really noticed it because of the refactoring.

I think the only last thing to do is to have a doctest in each of the __init__ methods that simply created the corresponding object and runs TestSuite(foo).run(). Otherwise, I think that takes care of everything. Thank you.

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

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

8dd2639Add TestSuites for each `__init__` method
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from b563d67 to 8dd2639

kwankyu commented 6 years ago
comment:49

It was instructive to add TestSuites for all parents. I could finally understand the basics of the interplay of Parents, Elements, and Categories. Thank you.

I will take care of other comments after a week long national holidays.

tscrim commented 6 years ago
comment:50

Replying to @kwankyu:

It was instructive to add TestSuites for all parents. I could finally understand the basics of the interplay of Parents, Elements, and Categories. Thank you.

I am glad to hear you were able to learn some new stuff. It looks like you were able to reduce the redundancy.

I have a few additional small comments:

Error messages should not be proper sentences (so not starting with a capital letter and ending with a period/full-stop):

-        if n != 0: raise IndexError("Only one generator.")
+        if n != 0:
+            raise IndexError("only one generator")
         return self._gen

(This is a general Python convention.) Same also for raise IndexError("Only {} generators".format(self.ngens())).

These type of changes do not seem to be correct to me:

        m = self.ideal_monoid()
        m.Element = FunctionFieldIdeal_rational

The Element attribute should be set by the corresponding parent before Parent.__init__ is called, as does the appropriate setup (e.g., constructing element_class). The thing do do would be to have a hook (via a attribute) that is looked at by IdealMonoid in its __init__ which then sets its Element attribute, e.g.:

self.Element = R._ideal_class

Also, is there a use-case for someone to pass an ideal_class to ideal or ideal_with_gens_over_base? If so, then this hook I mentioned above should be removed and the ideal_class should instead be an additional construction parameter for IdealMonoid.

Trivial formatting:

         - ``gens`` -- list of elements that are a basis for the
-              ideal over the maximal order of the base field
+          ideal over the maximal order of the base field

If you want to enforce a particular subcategory for input, you can do:

-category or IntegralDomains()
+category = IntegralDomains().or_subcategory(category)

(for None, this becomes IntegralDomains()).

I can also look into why the facade parents are not behaving well once the above is done.

I will take care of other comments after a week long national holidays.

No problem. Enjoy your holidays.

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

Changed commit from 8dd2639 to b255323

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

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

c722247fix error messages to start in lower case
950389ffix doctest errors; reorganize ideal_class
b255323use .or_subcategory
kwankyu commented 6 years ago
comment:52

Replying to @tscrim:

These type of changes do not seem to be correct to me:

        m = self.ideal_monoid()
        m.Element = FunctionFieldIdeal_rational

The Element attribute should be set by the corresponding parent before Parent.__init__ is called, as does the appropriate setup (e.g., constructing element_class). The thing to do would be to have a hook (via a attribute) that is looked at by IdealMonoid in its __init__ which then sets its Element attribute, e.g.:

self.Element = R._ideal_class

Ok.

Also, is there a use-case for someone to pass an ideal_class to ideal or ideal_with_gens_over_base? If so, then this hook I mentioned above should be removed and the ideal_class should instead be an additional construction parameter for IdealMonoid.

Perhaps not. This is a left-over from existing code. I tried to clean this up.

I can also look into why the facade parents are not behaving well once the above is done.

The function field orders are facade parents, because the parent of elements of an order is just the function field. What seems to me a bug is that some category tests intended for normal parents are still applied to facade parents. For example, _test_one, _test_zero.

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

Changed commit from b255323 to 086f278

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

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

086f278remove unused _gens_over_base
kwankyu commented 6 years ago
comment:54

Replying to @tscrim:

  • I don't see the point of having _gens_over_base. It is only called from gens_over_base and could be moved into there.

I guess _gens_over_base was introduced for efficiency when I implemented "places" and "divisors" on top of orders and ideals. As that is not needed here, I removed it. I may reintroduce it in a later ticket.

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

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

b9baf20remove custom caches
fe77aeaset basis_matrix immutable
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 086f278 to fe77aea

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

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

8e24456make some docstrings clearer
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from fe77aea to 8e24456

kwankyu commented 6 years ago
comment:57

Replying to @tscrim:

  • I don't like avoiding self: it makes you have strange sentences like Return the ideal below the ideal., which I might even argue is close to ill-defined (which ideal is the ideal?).

I like to avoid self, at least to be consistent, and follow the developer manual. Anyway, I tried to remove the ambiguities you mentioned.

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

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

01be0ebremove is_finite method
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 8e24456 to 01be0eb

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

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

504c9e4remove @cached_method from ideal_monoid
3329dc0Travis' various optimizations
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 01be0eb to 3329dc0

kwankyu commented 6 years ago
comment:60

Replying to @tscrim:

  • Micro-optimization: in mul_vecs, you might want to move self._mtable[i] part out of the for j in range(n): loop to avoid the extra lookups.

The benefit seems negligible. I left this as it is, for readability.

  • Is there a clear benefit to having mtable a list of vectors, as opposed to a list of lists or a Matrix object?

It is a list of a list of vectors.

Perhaps there would be a benefit from cythonizing mul_vec considering how frequently it is used.

Locating parts to be cythonized is a general issue that I should tackle some day, after learning more cython.

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

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

31434b9Merge branch 'develop'
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 3329dc0 to 31434b9

tscrim commented 6 years ago
comment:62

Thank you for all of your changes. LGTM.

I don't think it is exactly fair to quote the developers manual when you were the one who rewrote that part of the developers manual on self.

tscrim commented 6 years ago

Reviewer: Travis Scrimshaw

kwankyu commented 6 years ago
comment:64

Replying to @tscrim:

Thank you for all of your changes. LGTM.

I don't think it is exactly fair to quote the developers manual when you were the one who rewrote that part of the developers manual on self.

I feel sorry about that. I read the part again. It implicitly states self should be used if confusion incurs from not using it. So your recommendation above is quite legitimate, and so is my response :-)

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

Changed commit from 31434b9 to c04dd8b

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

Branch pushed to git repo; I updated commit sha1 and set ticket back to needs_review. New commits:

54ae894make TestSuite(O) run better for order O
c04dd8bremove Order and Ideal classes from startup modules
kwankyu commented 6 years ago
comment:66

Sorry for adding commits after review. I worked a bit more while responding to patchbot plugin failures.

tscrim commented 6 years ago
comment:67

That is fine. One little thing with this change:

@@ -817,12 +821,9 @@ class FunctionFieldMaximalOrder_rational(FunctionFieldMaximalOrder):

         TESTS:

-        This class defines a facade parent. Thus it does not behave well with
-        respect to elements.
-
             sage: K.<t> = FunctionField(QQ)
             sage: O = K.maximal_order()
-            sage: TestSuite(O).run(skip=['_test_euclidean_degree', '_test_gcd_vs_xgcd', '_test_one', '_test_zero'])
+            sage: TestSuite(O).run(skip='_test_gcd_vs_xgcd')
         """
         FunctionFieldMaximalOrder.__init__(self, field, ideal_class=FunctionFieldIdeal_rational,
                                            category=EuclideanDomains())

Should become TESTS::.

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

Changed commit from c04dd8b to 6c96607

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

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

6c96607fix for docbuild failure
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

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

48100b4fix : to ::
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 6 years ago

Changed commit from 6c96607 to 48100b4

tscrim commented 6 years ago
comment:70

Thank you.

kwankyu commented 6 years ago
comment:71

Replying to @tscrim:

Thank you.

Thank you for helping me step forward!

tscrim commented 6 years ago
comment:72

Replying to @kwankyu:

Replying to @tscrim:

Thank you.

Thank you for helping me step forward!

No problem. Sorry it took so long for me to get to this.

vbraun commented 6 years ago

Changed branch from u/klee/25435 to 48100b4