Skip to content
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

inner_direct_product #349

Open
fieker opened this issue Mar 16, 2021 · 20 comments
Open

inner_direct_product #349

fieker opened this issue Mar 16, 2021 · 20 comments
Milestone

Comments

@fieker
Copy link
Contributor

fieker commented Mar 16, 2021

while I was (am) very happy to have found this function, I always thought an inner product combines sub-objects only? This sees to me an out product with maps (which is why I am happy)

@fingolfin
Copy link
Member

Yeah sorry, this name is simply wrong (my fault, in the end). It should just be called direct_product. Overall the code for direct products needs to be overhauled once again

@lgoettgens
Copy link
Member

Currently, both direct_product and inner_direct_product both construct an inner product. They differ in the type of group created, direct_product creates a DirectProductGroup from arbitrary GAPGroups, while inner_direct_product constructs a T from Ts (for T in PermGroup, PcGroup, FPGroup).

Just to note it somewhere, one can make the current inner_direct_product implementation fail as follows:

julia> G = symmetric_group(3)
Sym( [ 1 .. 3 ] )

julia> inner_direct_product(Union{PcGroup,FPGroup}[PcGroup(G),FPGroup(G)])
ERROR: MethodError: no method matching Union{FPGroup, PcGroup}(::GAP.GapObj)

Closest candidates are:
  (::Type{T})(::GrpGen) where T<:Oscar.GAPGroup
   @ Oscar ~/code/Oscar.jl/src/Groups/homomorphisms.jl:808
  (::Type{T})(::GrpAbFinGen) where T<:Oscar.GAPGroup
   @ Oscar ~/code/Oscar.jl/src/Groups/homomorphisms.jl:750
  (::Type{S})(::T) where {S<:Union{GrpAbFinGen, Oscar.GAPGroup}, T<:Oscar.GAPGroup}
   @ Oscar ~/code/Oscar.jl/src/Groups/homomorphisms.jl:746

Stacktrace:
 [1] inner_direct_product(L::Vector{Union{FPGroup, PcGroup}}; morphisms::Bool)
   @ Oscar ~/code/Oscar.jl/src/Groups/directproducts.jl:82
 [2] inner_direct_product(L::Vector{Union{FPGroup, PcGroup}})
   @ Oscar ~/code/Oscar.jl/src/Groups/directproducts.jl:77
 [3] top-level scope
   @ REPL[10]:1

@fingolfin fingolfin added this to the 1.0 milestone Jan 19, 2024
@fingolfin
Copy link
Member

direct_product should by default construct inner direct products and be "type preserving", i.e.: if the input consists of two perm groups the output should be a perm group (pc group, fp group). And we probably need an optional "task" argument to select whether to return the projections and embedding maps.

I.e follow the pattern here:

    direct_product(F::FreeMod{T}...; task::Symbol = :prod) where T

Given free modules $F_1\dots F_n$, say, return the direct product $\prod_{i=1}^n F_i$.

Additionally, return
- a vector containing the canonical projections  $\prod_{i=1}^n F_i\to F_i$ if `task = :prod` (default),
- a vector containing the canonical injections  $F_i\to\prod_{i=1}^n F_i$ if `task = :sum`,
- two vectors containing the canonical projections and injections, respectively, if `task = :both`,
- none of the above maps if `task = :none`.

@thofma
Copy link
Collaborator

thofma commented Jan 19, 2024

I think we decided against that in #3059 (comment).

@fingolfin
Copy link
Member

Similar for semidirect products and wreath products, I guess?

And if the groups are of different types, we can still return direct product objects

For matrix groups, we either can't get this type stable (if the factors are defined over different fields/rings (e.g. one over GF(2) and one factor over GF(3), we need to switch to the generic direct product objects), or else we reject these cases with a helpful error ("use exterior_direct_product instead ... BLA")

@fingolfin
Copy link
Member

@thofma thanks for the reminder. I'll amend my comment to "do whatever we decided to do for controlling which maps to return or not"

@fingolfin
Copy link
Member

@mjrodgers and @ThomasBreuer can you two work together on this?

@mjrodgers
Copy link
Collaborator

@fingolfin Sure, happy to work on this - just following the guidance of the linked comment?

@ThomasBreuer
Copy link
Member

Wait a moment.
I understand the issue and the "linked comment" as follows:

  • inner_direct_product (currently defined only for groups) shall disappear.
  • direct_product for groups shall take an arbitrary positive number of arguments, and return always a tuple with two entries, the direct product and the vector of projections.

Why are the embeddings not returned?
The "linked comment" says that direct_sum returns an object an injections, but when one deals with direct products of groups then one is interested in both projections and injections.

@lgoettgens
Copy link
Member

Wait a moment. I understand the issue and the "linked comment" as follows:

  • inner_direct_product (currently defined only for groups) shall disappear.
  • direct_product for groups shall take an arbitrary positive number of arguments, and return always a tuple with two entries, the direct product and the vector of projections.

Why are the embeddings not returned? The "linked comment" says that direct_sum returns an object an injections, but when one deals with direct products of groups then one is interested in both projections and injections.

You get both embeddings and projections with biproduct (see #3059 (comment)). Furthermore, you can get the embeddins separately for the case of groups. (For other types it may not be possible to construct the maps at a later point in time)

@ThomasBreuer
Copy link
Member

Then I think we want to support biproduct for groups, and direct_product is just a variant that omits the creation of the embeddings. (Is the direct_sum variant for groups that returns the direct product and the embeddings of interest?)

(If I understand the comment about constructing the embeddings at a later time right then the idea is that the first embedding can be created as the inverse of the restriction of the first projection to the kernel of the second projection; I think this is not what one wants to propose in practice, since the direct product construction gives one the necessary information in an easier way.)

@lgoettgens
Copy link
Member

Then I think we want to support biproduct for groups, and direct_product is just a variant that omits the creation of the embeddings. (Is the direct_sum variant for groups that returns the direct product and the embeddings of interest?)

We should have all three out of consistentcy with other types.

(If I understand the comment about constructing the embeddings at a later time right then the idea is that the first embedding can be created as the inverse of the restriction of the first projection to the kernel of the second projection; I think this is not what one wants to propose in practice, since the direct product construction gives one the necessary information in an easier way.)

No, that's not what I meant here. For groups, there is embedding(G,i) and projection(G, i) that can construct injections/projections at a later point in time (to be renamed in #3201). For other types, this may not be so easy to implement, so the user needs to get all morphisms they will ever need need when creating the product.

@ThomasBreuer
Copy link
Member

Thanks, now I understand your comment. Calling embedding(G, i) and projection(G, i) is reasonable because the direct product object stores the relevant information.

@thofma
Copy link
Collaborator

thofma commented Jan 19, 2024

I think the problem is that there is a mismatch between names. For modules (edit: and abelian groups):

  • direct product = product (with projections)
  • direct sum = coproduct (with injections)

For groups:

  • direct product = product (with projections)
  • free product = coproduct (with injections)
  • direct sum = ??

There is no biproduct of groups (in general)

@mjrodgers
Copy link
Collaborator

mjrodgers commented Jan 19, 2024

@thofma So for now should I just remove the morphisms argument for direct_product and have it always return the DirectProductGroup and the projections only?

@ThomasBreuer
Copy link
Member

Now I am getting confused.
Currently my viewpoint is that we can take the GrpAbFinGen documentation of direct_product, direct_sum, biproduct also for GAPGroup: The product object is the same, just the returned maps differ.

@thofma
Copy link
Collaborator

thofma commented Jan 19, 2024

These three things are categorical concepts (product, coproduct and biproduct). They exist for modules and abelian gorups. But there is no mathematical biproduct for groups.

I am just wondering, whether we then want to extend this to groups then.

@ThomasBreuer
Copy link
Member

O.k., then it is "just" a question of function names, and we need names for functions that return a direct product of groups, with or without embeddings and projections.
We cannot use the same function together with an optional argument that controls the output type because then somebody would complain that this is not type stable.

Are we perhaps back to direct_product (just the object) vs. direct_product_with_injections vs. direct_product_with_projections vs. direct_product_with_injections_and_projections?

Or we can argue that the currently available groups (GrpAbFinGen and GAPGroups admit a construction of the injections/projections later on. Then we need only a function that returns the object, and we can recommend to use canonical_injections and canonical_projections.

@mjrodgers
Copy link
Collaborator

To have direct_sum/direct_product defined for arbitrary groups and only differing in whether we get the projections or the injections seems confusing (and having a method called biproduct to give both seems to lack convincing motivation).

I would argue that we should have only a direct_product command, and have it return no maps. The maps are easily accessible with no real overhead so unless I'm overlooking something, it seems there is no real programmatic advantage to having these other methods defined.

@ThomasBreuer
Copy link
Member

I agree with @mjrodgers that the easiest solution is to have just direct_product which returns the direct product object.
Then the documentation should mention how one can construct the injections/projections.

However, this direct_product is not consistent with that for GrpAbFinGen, which returns also the projections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants