Skip to content

Structural Computations

Abelian groups support a wide range of structural operations such as

  • enumeration of subgroups

  • (outer) direct products

  • tensor and hom constructions

  • free resolutions and general complexes

  • (co)-homology and tensor and hom-functors

# snfMethod.
julia
snf(A::FinGenAbGroup) -> FinGenAbGroup, FinGenAbGroupHom

Return a pair (G,f), where G is an abelian group in canonical Smith normal form isomorphic to A and an isomorphism f:GA.

source


# find_isomorphismMethod.
julia
find_isomorphism(G, op, A::GrpAb) -> Dict, Dict

Given an abelian group A and a collection G which is an abelian group with the operation op, this functions returns isomorphisms GA and AG encoded as dictionaries.

It is assumed that G and A are isomorphic.

source


Subgroups and Quotients

# torsion_subgroupMethod.
julia
torsion_subgroup(G::FinGenAbGroup) -> FinGenAbGroup, Map

Return the torsion subgroup of G.

source


# subMethod.
julia
sub(G::FinGenAbGroup, s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, FinGenAbGroupHom

Create the subgroup H of G generated by the elements in s together with the injection ι:HG.

source


# subMethod.
julia
sub(A::SMat, r::AbstractUnitRange, c::AbstractUnitRange) -> SMat

Return the submatrix of A, where the rows correspond to r and the columns correspond to c.

source

julia
sub(s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, FinGenAbGroupHom

Assuming that the non-empty array s contains elements of an abelian group G, this functions returns the subgroup H of G generated by the elements in s together with the injection ι:HG.

source


# subMethod.
julia
sub(G::FinGenAbGroup, M::ZZMatrix) -> FinGenAbGroup, FinGenAbGroupHom

Create the subgroup H of G generated by the elements corresponding to the rows of M together with the injection ι:HG.

source


# subMethod.
julia
sub(G::FinGenAbGroup, n::ZZRingElem) -> FinGenAbGroup, FinGenAbGroupHom

Create the subgroup nG of G together with the injection ι:nGG.

source


# subMethod.
julia
sub(G::FinGenAbGroup, n::Integer) -> FinGenAbGroup, Map

Create the subgroup nG of G together with the injection ι:nGG.

source


# sylow_subgroupMethod.
julia
sylow_subgroup(G::FinGenAbGroup, p::IntegerUnion) -> FinGenAbGroup, FinGenAbGroupHom

Return the Sylow psubgroup of the finitely generated abelian group G, for a prime p. This is the subgroup of p-power order in G whose index in G is coprime to p.

Examples

julia
julia> A = abelian_group(ZZRingElem[2, 6, 30])
Z/2 x Z/6 x Z/30

julia> H, j = sylow_subgroup(A, 2);

julia> H
(Z/2)^3

julia> divexact(order(A), order(H))
45

source


# has_quotientMethod.
julia
has_quotient(G::FinGenAbGroup, invariant::Vector{Int}) -> Bool

Given an abelian group G, return true if it has a quotient with given elementary divisors and false otherwise.

source


# has_complementMethod.
julia
has_complement(f::FinGenAbGroupHom) -> Bool, FinGenAbGroupHom
has_complement(U::FinGenAbGroup, G::FinGenAbGroup) -> Bool, FinGenAbGroupHom

Given a map representing a subgroup of a group G, or a subgroup U of a group G, return either true and an injection of a complement in G, or false.

See also: is_pure

source


# is_pureMethod.
julia
is_pure(U::FinGenAbGroup, G::FinGenAbGroup) -> Bool

A subgroup U of G is called pure if for all n an element in U that is in the image of the multiplication by n map of G is also a multiple of an element in U.

For finite abelian groups this is equivalent to U having a complement in G. They are also know as isolated subgroups and serving subgroups.

See also: is_neat, has_complement

EXAMPLES

julia
julia> G = abelian_group([2, 8]);

julia> U, _ = sub(G, [G[1]+2*G[2]]);

julia> is_pure(U, G)
false

julia> U, _ = sub(G, [G[1]+4*G[2]]);

julia> is_pure(U)
true

julia> has_complement(U, G)[1]
true

source


# is_neatMethod.
julia
is_neat(U::FinGenAbGroup, G::FinGenAbGroup) -> Bool

A subgroup U of G is called neat if for all primes p an element in U that is in the image of the multiplication by p map of G is also a multiple of an element in U.

See also: is_pure

EXAMPLES

julia
julia> G = abelian_group([2, 8]);

julia> U, _ = sub(G, [G[1] + 2*G[2]]);

julia> is_neat(U, G)
true

julia> is_pure(U, G)
false

source


# saturateMethod.
julia
saturate(U::FinGenAbGroup, G::FinGenAbGroup) -> FinGenAbGroup

For a subgroup U of G find a minimal overgroup that is pure, and thus has a complement.

See also: is_pure, has_complement

source


A sophisticated algorithm for the enumeration of all (or selected) subgroups of a finite abelian group is available.

# psubgroupsMethod.
julia
psubgroups(g::FinGenAbGroup, p::Integer;
           subtype = :all,
           quotype = :all,
           index = -1,
           order = -1)

Return an iterator for the subgroups of G of the specific form. Note that subtype (and quotype) is the type of the subgroup as an abelian p-group.

source


julia

julia> G = abelian_group([6, 12])
Z/6 x Z/12

julia> shapes = MSet{Vector{ZZRingElem}}()
MSet{Vector{ZZRingElem}}()

julia> for U = psubgroups(G, 2)
         push!(shapes, elementary_divisors(U[1]))
       end

julia> shapes
MSet{Vector{ZZRingElem}} with 8 elements:
  ZZRingElem[]
  ZZRingElem[4]    : 2
  ZZRingElem[2, 4]
  ZZRingElem[2]    : 3
  ZZRingElem[2, 2]

So there are 2 subgroups isomorphic to C4 (ZZRingElem[4] : 2), 1 isomorphic to C2×C4, 1 trivial and 3 C2 subgroups.

# subgroupsMethod.
julia
subgroups(g::FinGenAbGroup;
          subtype = :all ,
          quotype = :all,
          index = -1,
          order = -1)

Return an iterator for the subgroups of G of the specific form.

source


julia
julia> for U = subgroups(G, subtype = [2])
         @show U[1], map(U[2], gens(U[1]))
       end
(U[1], map(U[2], gens(U[1]))) = (Z/2, FinGenAbGroupElem[[0, 6]])
(U[1], map(U[2], gens(U[1]))) = (Z/2, FinGenAbGroupElem[[3, 6]])
(U[1], map(U[2], gens(U[1]))) = (Z/2, FinGenAbGroupElem[[3, 0]])

julia> for U = subgroups(G, quotype = [2])
         @show U[1], map(U[2], gens(U[1]))
       end
(U[1], map(U[2], gens(U[1]))) = (Finitely generated abelian group with 3 generators and 3 relations, FinGenAbGroupElem[[3, 3], [0, 4], [2, 0]])
(U[1], map(U[2], gens(U[1]))) = (Finitely generated abelian group with 3 generators and 3 relations, FinGenAbGroupElem[[0, 3], [0, 4], [2, 0]])
(U[1], map(U[2], gens(U[1]))) = (Finitely generated abelian group with 4 generators and 4 relations, FinGenAbGroupElem[[3, 6], [0, 6], [0, 4], [2, 0]])
# quoMethod.
julia
quo(G::FinGenAbGroup, s::Vector{FinGenAbGroupElem}) -> FinGenAbGroup, GrpAbfinGemMap

Create the quotient H of G by the subgroup generated by the elements in s, together with the projection p:GH.

source


# quoMethod.
julia
quo(G::FinGenAbGroup, M::ZZMatrix) -> FinGenAbGroup, FinGenAbGroupHom

Create the quotient H of G by the subgroup generated by the elements corresponding to the rows of M, together with the projection p:GH.

source


# quoMethod.
julia
quo(G::FinGenAbGroup, n::Integer}) -> FinGenAbGroup, Map
quo(G::FinGenAbGroup, n::ZZRingElem}) -> FinGenAbGroup, Map

Returns the quotient H=G/nG together with the projection p:GH.

source


# quoMethod.
julia
quo(G::FinGenAbGroup, n::Integer}) -> FinGenAbGroup, Map
quo(G::FinGenAbGroup, n::ZZRingElem}) -> FinGenAbGroup, Map

Returns the quotient H=G/nG together with the projection p:GH.

source


# quoMethod.
julia
quo(G::FinGenAbGroup, U::FinGenAbGroup) -> FinGenAbGroup, Map

Create the quotient H of G by U, together with the projection p:GH.

source


For 2 subgroups U and V of the same group G, U+V returns the smallest subgroup of G containing both. Similarly, UV computes the intersection and UV tests for inclusion. The difference between issubset = and is_subgroup is that the inclusion map is also returned in the 2nd call.

# intersectMethod.
julia
intersect(mG::FinGenAbGroupHom, mH::FinGenAbGroupHom) -> FinGenAbGroup, Map

Given two injective maps of abelian groups with the same codomain G, return the intersection of the images as a subgroup of G.

source


Direct Products

# direct_productMethod.
julia
direct_product(G::FinGenAbGroup...) -> FinGenAbGroup, Vector{FinGenAbGroupHom}

Return the direct product D of the (finitely many) abelian groups Gi, together with the projections DGi.

For finite abelian groups, finite direct sums and finite direct products agree and they are therefore called biproducts. If one wants to obtain D as a direct sum together with the injections DGi, one should call direct_sum(G...). If one wants to obtain D as a biproduct together with the projections and the injections, one should call biproduct(G...).

Otherwise, one could also call canonical_injections(D) or canonical_projections(D) later on.

source


# canonical_injectionMethod.
julia
canonical_injection(G::FinGenAbGroup, i::Int) -> FinGenAbGroupHom

Given a group G that was created as a direct product, return the injection from the ith component.

source


# canonical_projectionMethod.
julia
canonical_projection(G::FinGenAbGroup, i::Int) -> FinGenAbGroupHom

Given a group G that was created as a direct product, return the projection onto the ith component.

source


# flatMethod.
julia
flat(G::FinGenAbGroup) -> FinGenAbGroupHom

Given a group G that is created using (iterated) direct products, or (iterated) tensor products, return a group isomorphism into a flat product: for G:=(AB)C, it returns the isomorphism GABC (resp. ).

source


Tensor Producs

# tensor_productMethod.
julia
tensor_product(G::FinGenAbGroup...; task::Symbol = :map) -> FinGenAbGroup, Map

Given groups Gi, compute the tensor product G1Gn. If task is set to ":map", a map ϕ is returned that maps tuples in G1××Gn to pure tensors g1gn. The map admits a preimage as well.

source


# homMethod.
julia
hom(G::FinGenAbGroup, H::FinGenAbGroup, A::Vector{ <: Map{FinGenAbGroup, FinGenAbGroup}}) -> Map

Given groups G=G1Gn and H=H1Hn as well as maps ϕi:GiHi, compute the tensor product of the maps.

source


Hom-Group

# homMethod.
julia
hom(G::FinGenAbGroup, H::FinGenAbGroup; task::Symbol = :map) -> FinGenAbGroup, Map

Computes the group of all homomorpisms from G to H as an abstract group. If task is ":map", then a map ϕ is computed that can be used to obtain actual homomorphisms. This map also allows preimages. Set task to ":none" to not compute the map.

source