Closed kwankyu closed 6 years ago
Replying to @tscrim:
- I am pretty sure there is a bug in the caching of
vector_space
as the key is always returnNone
, so thebase
parameter is ignored. Actually, you do not need to have a key here because you error out whenbase is not None
. Is this for compatibility with something else? Doesbase**1
do something? I feel like it should just bebase
. 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.
Branch pushed to git repo; I updated commit sha1. New commits:
12a78a0 | Move INPUT fields to the class docstrings |
Branch pushed to git repo; I updated commit sha1. New commits:
b563d67 | Fix Returns to Return |
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 returnNone
, so thebase
parameter is ignored. Actually, you do not need to have a key here because you error out whenbase is not None
. Is this for compatibility with something else? Doesbase**1
do something? I feel like it should just bebase
. 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, sinceself
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 overbase
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?
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 returnNone
, so thebase
parameter is ignored. Actually, you do not need to have a key here because you error out whenbase is not None
. Is this for compatibility with something else? Doesbase**1
do something? I feel like it should just bebase
. 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, sinceself
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 overbase
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 whyvector_space
should take an argument. Everything about that code says it should not have any arguments and you can should just replacebase
withself
. 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.
Replying to @kwankyu:
It is for consistency. Note that general function fields also have
vector_space
, for which it is reasonable to take abase
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.
Branch pushed to git repo; I updated commit sha1. New commits:
8dd2639 | Add TestSuites for each `__init__` method |
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.
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.
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 beforeParent.__init__
is called, as does the appropriate setup (e.g., constructingelement_class
). The thing to do would be to have a hook (via a attribute) that is looked at byIdealMonoid
in its__init__
which then sets itsElement
attribute, e.g.:self.Element = R._ideal_class
Ok.
Also, is there a use-case for someone to pass an
ideal_class
toideal
orideal_with_gens_over_base
? If so, then this hook I mentioned above should be removed and theideal_class
should instead be an additional construction parameter forIdealMonoid
.
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
.
Branch pushed to git repo; I updated commit sha1. New commits:
086f278 | remove unused _gens_over_base |
Replying to @tscrim:
- I don't see the point of having
_gens_over_base
. It is only called fromgens_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.
Branch pushed to git repo; I updated commit sha1. New commits:
8e24456 | make some docstrings clearer |
Replying to @tscrim:
- I don't like avoiding
self
: it makes you have strange sentences likeReturn 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.
Branch pushed to git repo; I updated commit sha1. New commits:
01be0eb | remove is_finite method |
Replying to @tscrim:
- Micro-optimization: in
mul_vecs
, you might want to moveself._mtable[i]
part out of thefor 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 aMatrix
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.
Branch pushed to git repo; I updated commit sha1. New commits:
31434b9 | Merge branch 'develop' |
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
.
Reviewer: Travis Scrimshaw
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 :-)
Sorry for adding commits after review. I worked a bit more while responding to patchbot plugin failures.
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::
.
Branch pushed to git repo; I updated commit sha1. New commits:
6c96607 | fix for docbuild failure |
Branch pushed to git repo; I updated commit sha1. New commits:
48100b4 | fix : to :: |
Thank you.
Changed branch from u/klee/25435 to 48100b4
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