-
Notifications
You must be signed in to change notification settings - Fork 125
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
Streamline methods for direct_sum
and tensor_product
throughout Oscar
#3059
Comments
We (@simonbrandhorst and @StevellM) had similar discussions for lattices, where also direct sum, direct products and "both" exist. In the end, we did the (in my opinion) right thing by disentangling and using proper mathematical language (thofma/Hecke.jl#985). The summary is
P.S.: I am not a fan of |
I strongly dislike
|
I agree with @thofma, @simonbrandhorst and @StevellM in what we should get mathematically. |
But in my pr, line 98, it was still necessary to call it with For vector spaces over a field ( |
I guess since you want both the projections and injections? But that is not what I would expect and also was suggested above (and is implemented for direct_sum and direct_product, for tensor_product we only give the module, which is more along the use cases, but we could switch the default). |
So the problem is that people did not Honor the precedent. We can argue if
task is/was a good idea, but the problem is people not abiding standards...
Task was the model to follow.
…On Thu, 30 Nov 2023, 18:22 Janko Boehm, ***@***.***> wrote:
I guess since you want both the projections and injections? But that is
not what I would expect and also was suggested above (and is implemented).
—
Reply to this email directly, view it on GitHub
<#3059 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA36CV76VQ3ADMTG2KSZ5WDYHC6E3AVCNFSM6AAAAABABLNGIGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMZUGIYDQNBSGA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
The reason for this is to not duplicate code. All three options have to
exist in all cases, for generic. The easiest implementation is in one
function with it.
…On Thu, 30 Nov 2023, 18:54 Claus Fieker, ***@***.***> wrote:
So the problem is that people did not Honor the precedent. We can argue if
task is/was a good idea, but the problem is people not abiding standards...
Task was the model to follow.
On Thu, 30 Nov 2023, 18:22 Janko Boehm, ***@***.***> wrote:
> I guess since you want both the projections and injections? But that is
> not what I would expect and also was suggested above (and is implemented).
>
> —
> Reply to this email directly, view it on GitHub
> <#3059 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AA36CV76VQ3ADMTG2KSZ5WDYHC6E3AVCNFSM6AAAAABABLNGIGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMZUGIYDQNBSGA>
> .
> You are receiving this because you are subscribed to this thread.Message
> ID: ***@***.***>
>
|
I want, depending on the situation all three, that why they exist.
…On Thu, 30 Nov 2023, 18:57 Claus Fieker, ***@***.***> wrote:
The reason for this is to not duplicate code. All three options have to
exist in all cases, for generic. The easiest implementation is in one
function with it.
On Thu, 30 Nov 2023, 18:54 Claus Fieker, ***@***.***> wrote:
> So the problem is that people did not Honor the precedent. We can argue
> if task is/was a good idea, but the problem is people not abiding
> standards...
> Task was the model to follow.
>
>
> On Thu, 30 Nov 2023, 18:22 Janko Boehm, ***@***.***> wrote:
>
>> I guess since you want both the projections and injections? But that is
>> not what I would expect and also was suggested above (and is implemented).
>>
>> —
>> Reply to this email directly, view it on GitHub
>> <#3059 (comment)>,
>> or unsubscribe
>> <https://github.com/notifications/unsubscribe-auth/AA36CV76VQ3ADMTG2KSZ5WDYHC6E3AVCNFSM6AAAAABABLNGIGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMZUGIYDQNBSGA>
>> .
>> You are receiving this because you are subscribed to this thread.Message
>> ID: ***@***.***>
>>
>
|
Sorry. Then I misunderstood your point first. So in my application I should have been aiming for |
On Thu, Nov 30, 2023 at 07:39:47AM -0800, Lars Göttgens wrote:
I strongly dislike `:task` as it makes the code intrinsically type unstable. Thus, I would like a consistent way throughout Oscar.
`LieAlgebra`s do not have any sums or products yet. `LieAlgebraModule` returns only the object in both cases.
Lets do a discussion thie afternoon after the meeting. I had a long
reply typed, but refrained from sending. This is getting off topic and
in the wrong direction.
… --
Reply to this email directly or view it on GitHub:
#3059 (comment)
You are receiving this because you are subscribed to this thread.
Message ID: ***@***.***>
|
I am on a conference currently and unfortunately (with high probability) cannot attend the meeting and/or the discussion afterwards today. |
We (@fieker and @HechtiDerLachs and myself) met today and converged to the following proposed solution. We will have the following functions:
Everything without |
For modules I took some first steps in #3021 . |
This is a nice and comprehensive list of functions and return values. But what should be the input? I can find 4 currently in use:
I think that we should decide on a general way which of these should be there in general, which have to be implemented for each type, and which can be implemented generically by the other ones. All of this should be the same for all 4 functions discussed in this thread. |
Yes, 2) should be purged. I don't think 4) alone can deal with empty products. For direct products of |
The varargs version is always bad to use programmatically. It's cool for
interactive, but I find them irritating in code...
…On Wed, 20 Dec 2023, 16:39 Tommy Hofmann, ***@***.***> wrote:
Yes, 2) should be purged. I don't think 4) alone can deal with empty
products. For direct product of $K$-algebras, I had to implement
something like direct_product(K, algebras::Vector), because one needs to
know the $K$ to construct the algebra. I would guess it is the same for
LieAlgebraModule? Alternatively one could do ;init = zero_algebra(K)
resp. ;init = zero_module(A), although this look a bit odd.
—
Reply to this email directly, view it on GitHub
<#3059 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA36CV7QLNUR5XMV5WJIGQ3YKMBDBAVCNFSM6AAAAABABLNGIGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNRUG4YDCNBTHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I may have put a lot of bad varargs of type 2) when I implemented the methods for things related to lattices... I could take care of changing this to 3) if that is better (whenever I have the time). In general, I would be in favour of keeping both the varargs and vector option. |
I think we already fixed them for lattices and related constructions. |
Direct sums and direct productsTensor products haven't been discussed, but deferred to a later point. After todays meeting, a group of 6 people (@fieker, @ThomasBreuer, @thofma, @mjrodgers, @jankoboehm and me) discussed this again with some input from #349 and came to the following conclusion (not everyone was happy, but nobody objected): minimal interface
The following can then be implemented generically in terms of the above:
ToDo-List:
|
I do not think that this will be a reasonable choice (currently and in the long run): indeed by definition direct sums and products come with the maps. But then it is not clear that someone can reconstruct these maps outside the constructors, i.e. without having to remember all the process. I had to implement such functions some time ago for lattice related objects. How does this minimal interface deal with constructions for which one cannot reconstruct the EDIT: extra thought. What about |
You store the components and all choices on the product, thus the maps can
computed
Maybe on Monday or so you can show a situation where this is not possible
…On Fri, 19 Jan 2024, 17:31 Stevell Muller, ***@***.***> wrote:
I do not think that this will be a reasonable choice (currently and in the
long run): indeed by definition direct sums and products come with the
maps. But then it is not clear that someone can reconstruct these maps
outside the constructors, i.e. without having to remember all the process.
I had to implement such functions some time ago for lattice related objects.
How does this minimal interface deal with constructions for which one
cannot reconstruct the canonical_(bla) after construction ? Should we
necessarily use direct_sum_with_injections or
direct_product_with_projections ? Or should we remember all the details
of the construction ? So in the case where one cannot reconstruct the maps
afterwards, we have somehow to always store them somewhere. But what if I
do not want to keep the maps ?
—
Reply to this email directly, view it on GitHub
<#3059 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA36CV6Q3KNVWKYTAVY77CDYPKNVBAVCNFSM6AAAAABABLNGIGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMBQG4ZDOMZZGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Unfortunately I do not have yet an example where this is not possible, but I know for sure that we do not want to store components in the construction. Sorry for the strong word, but this seems to be a very bad design decision in my opinion. I will explain why I think it is. First of all, we should understand: what is wrong with returning the maps ? I do not see any explanation for this: worse, it seemed that the conversation was first converging to using the maps. So why being against returning the maps, now ? It is much more convenient, it does not remove the possibility of writing a Indeed, such design will bring inconsistency within Oscar: a lot of functions in group theory for instance return a subgroup with an associated (canonical?) map. Why would The idea of "storing the components and all choices on the product" does not seem to be optimal, and I would prefer to avoid this. In my opinion, we also use Oscar for heavy and long computations. If tomorrow one runs computations where one needs to take direct products of 10 to 100 objects which will not be used anymore, but for which one needs the maps right away, should we really store everything ? Then after 1 month of computations, running the same function thousands of times on different sets of 10 to 100 elements, one would have filled up their memory, and garbage collector will not be able to do its job (if I understood correctly how GC works). One will still have gazillions of global objects remembering several distinct old objects (components) each, "just in case". We cannot rely on this. A more flexible solution, in my opinion, would be to keep the maps in the output, and the type(s) for which one wants (or needs?) to remember the construction, then they make it part of their constructor. I do not see why we should impose a more restricted usage. This is why it seems unreasonable to me. At the end, we will replace three characters in our code, by storing more data and imposing to the user to reconstruct the maps by hand afterwards. I am not against the |
The current state of `direct_product` for groups (that are `<:GAPGroup`) is already that
- the object returned is of a special type `DirectProductGroup` that stores the maps
- the maps aren't returned by default.
So even if we return the maps by default, they are still being stored.
Also in your example of taking direct products that are only needed for a short time, the maps will be garbage collected with the objects once they are no longer in use, correct? The maps aren't saved in some global cache, they are attached to the object.
… On Jan 22, 2024, at 9:57 AM, Stevell Muller ***@***.***> wrote:
Unfortunately I do not have yet an example where this is not possible, but I know for sure that we do not want to store components in the construction. Sorry for the strong word, but this seems to be a very bad design decision in my opinion. I will explain why I think it is.
First of all, we should understand: what is wrong with returning the maps ? I do not see any explanation for this: worse, it seemed that the conversation was first converging to using the maps. So why being against returning the maps, now ? It is much more convenient, it does not remove the possibility of writing a canonical_* function and it is more consistent with other Oscar functions.
Indeed, such design will bring inconsistency within Oscar: a lot of functions in group theory for instance return a subgroup with an associated (canonical?) map. Why would direct_product behave differently ? I am not against having canonical_*: if one wants it, can implement it and is able to make a use of it, good for them. But in general it is not something we should expect the user to have to deal with. I guess if an object comes naturally, by definition, with a given set of data then this should be returned. Otherwise why don't we have polynomial_ring_with_indeterminates or subgroup_with_embedding ?
The idea of "storing the components and all choices on the product" does not seem to be optimal, and I would prefer to avoid this. In my opinion, we also use Oscar for heavy and long computations. If tomorrow one runs computations where one needs to take direct products of 10 to 100 objects which will not be used anymore, but for which one needs the maps right away, should we really store everything ? Then after 1 month of computations, running the same function thousands of times on different sets of 10 to 100 elements, one would have filled up their memory, and garbage collector will not be able to do its job (if I understood correctly how GC works). One will still have gazillions of global objects remembering several distinct old objects (components) each, "just in case". We cannot rely on this.
In general, having to remember data is not good for long and expensive computations. So I could understand the argument of "use direct_product_with_*", but this does not solve the overall issue: should this still save the components to reconstruct the map later ? and why should we make a separate method where one could only use , _ or [1] to get rid of the maps in the output ?
A more flexible solution, in my opinion, would be to keep the maps in the output, and the type(s) for which one wants (or needs?) to remember the construction, then they make it part of their constructor. I do not see why we should impose a more restricted usage.
This is why it seems unreasonable to me. At the end, we will replace three characters in our code, by storing more data and imposing to the user to reconstruct the maps by hand afterwards. I am not against the canonical_* if it is useful to some people, and I agree that direct_sum, direct_product and biproduct are not perfect names. However I do not support removing the maps from the output.
—
Reply to this email directly, view it on GitHub <#3059 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AANWIWLQNMAELHEQL4YQZY3YPYSXTAVCNFSM6AAAAABABLNGIGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMBTGUZDONZUGU>.
You are receiving this because you were mentioned.
|
How far reaching is this decision of do not return the maps, but give |
While I am personally not opposed to also allow for the liberty of storing the maps and providing getters, I do agree with this statement of @StevellM . How come make this 180 degree turnaround just one month before the release of 1.0 after more than four years of conversion towards returning the maps? At least for someone who has not participated in the last meeting this seems rather bizarre. As for the issues raised regarding garbage collection: I do agree that there can easily be memory management issues resulting from suboptimal programming. But I believe that if the programmer is aware of this, they can be resolved, e.g. by avoiding circular referencing or even using weak keys. What raises doubts about the non-returning of the maps might be that not all parts of Oscar have data structures which are designed to also store additional information. While I am often in favor of introducing new data types for every step in the history of the creation of an object (like |
My example might be a bit confusing, sorry about that. I do want to remember the new direct product for probably several weeks in my long run computation, but I do not want to remember the components. Maybe, at the creation, I need the maps for other purpose. So if the constructor stores the components to reconstruct the maps later, my new object will remember those old components, which will not be garbage collected (even if they are definitely useless in my program). |
Here is why I am no fond of
In this sense a name like That said, if the decision was to just always call this Likewise, I do not find arguments of the form " The current "standard" is the "task" argument, which is not particular elegant or nice, but at least it works. Of course it has the downside of not being type stable, but I'd like to see the real world code using them and where type stability matters (i.e. it has a "hot loop" that isn't optimized to the call to Whatever we decide, we need to decide it soon, and then implement it everywhere. And no "but my code is special so I'll do it differently" exceptions anymore. And when I say "we decide" then of course what I really mean is that unless a miracle happens and a proposal is made that makes everybody happy, then at some point (perhaps by the end of the week?), @fieker needs to hand down an edict (after hearing all voices), as I don't think it's a good idea to keep this discussion going for a longer time. |
The conclusion of the discussion on Friday was that we prefer to have groups behave exactly the same as the other objects (like modules, abelian groups, things from an abelian category), which prohibits us from using the mathematical useful notions of "direct = product = automatically with projections", "direct sum = coproduct = automatically with injections". Thus we are back to square one and have The idea to have only the object and recover the maps is essentially independent of this. I also think this is a rather large change from the status quo. Before this was never mandatory, but always optional. |
Agreed. |
After discussion with @simonbrandhorst and @paemurru, the minimal interface and complementary functions proposed previously are fine. Though, it would be convenient if we allow a keyword argument for those functions, like |
I think this is missing the point @StevellM was trying to make. If you allow methods such as If you instead return a triple containing the direct sum object, canonical injections and canonical projections, then there is no memory leak. |
I can live with this proposal (#3059 (comment)). I don't have to like it. |
I will create a list of types to be adapted and ping people who know stuff once the generic stuff is available from AbstractAlgebra |
The meeting just decided that this is not viable until next week. |
Maybe @fieker can summarize here what the decision on this was (or point to a place where it can be read) and then we put it into the description of this issue (i.e. at the top). And then we can tackle this after the Begehung. |
the summary is in #3059 (comment)
|
As discussed yesterday with @fingolfin : At the moment it is not possible to write generic code which uses functions like
direct_sum
,tensor_product
, or evenhom
. The reason is that, depending on the type of the objects considered,direct_sum
will sometimes just return the object and in other cases a triple(S, inj, pr)
consisting of the objectS
, the injections of the summandsinj
, and the projectionspr
. Currently we find fordirect_sum
:ModuleFP
-> only the objectFPModule
-> object and mapsSimilar things happen for
tensor_product
which is supposed to return a pair(P, mult_map)
consisting of the object and a multiplication map. Here we findModuleFP
-> only the objectFPModule
-> only the objectI came across this again in the work on hyper complexes #3021 and @fingolfin criticized my workarounds for not being too sustainable and no issue being raised from my side. Hence here comes the issue to keep track of such developments.
The text was updated successfully, but these errors were encountered: