# Finitely generated abelian groups with GAP.¶

This module provides a python wrapper for abelian groups in GAP.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: AbelianGroupGap([3,5])
Abelian group with gap, generator orders (3, 5)


For infinite abelian groups we use the GAP package Polycyclic:

sage: AbelianGroupGap([3,0])   # optional - gap_packages
Abelian group with gap, generator orders (3, 0)


AUTHORS:

• Simon Brandhorst (2018-01-17): initial version

class sage.groups.abelian_gps.abelian_group_gap.AbelianGroupElement_gap(parent, x, check=True)

An element of an abelian group via libgap.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([3,6])
sage: G.gens()
(f1, f2)

exponents()

Return the tuple of exponents of this element.

OUTPUT:

• a tuple of integers

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([4,7,9])
sage: gens = G.gens()
sage: g = gens^2 * gens^4 * gens^8
sage: g.exponents()
(2, 4, 8)
sage: S = G.subgroup(G.gens()[:1])
sage: s = S.gens()
sage: s
f1
sage: s.exponents()
(1,)


It can handle quite large groups too:

sage: G = AbelianGroupGap([2^10, 5^10])
sage: f1, f2 = G.gens()
sage: g = f1^123*f2^789
sage: g.exponents()
(123, 789)


Warning

Crashes for very large groups.

Todo

Make exponents work for very large groups. This could be done by using Pcgs in gap.

order()

Return the order of this element.

OUTPUT:

• an integer or infinity

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap()
sage: g = G.gens()
sage: g.order()
4
sage: G = AbelianGroupGap()          # optional - gap_packages
sage: g = G.gens()                   # optional - gap_packages
sage: g.order()                         # optional - gap_packages
+Infinity

class sage.groups.abelian_gps.abelian_group_gap.AbelianGroupElement_polycyclic(parent, x, check=True)

An element of an abelian group using the GAP package Polycyclic.

exponents()

Return the tuple of exponents of self.

OUTPUT:

• a tuple of integers

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([4,7,0])          # optional - gap_packages
sage: gens = G.gens()                       # optional - gap_packages
sage: g = gens^2 * gens^4 * gens^8 # optional - gap_packages
sage: g.exponents()                         # optional - gap_packages
(2, 4, 8)


Efficiently handles very large groups:

sage: G = AbelianGroupGap([2^30,5^30,0])    # optional - gap_packages
sage: f1, f2, f3 = G.gens()                 # optional - gap_packages
sage: (f1^12345*f2^123456789).exponents()   # optional - gap_packages
(12345, 123456789, 0)

class sage.groups.abelian_gps.abelian_group_gap.AbelianGroupGap(generator_orders)

Abelian groups implemented using GAP.

INPUT:

• generator_orders – a list of nonnegative integers where $$0$$ gives a factor isomorphic to $$\ZZ$$

OUTPUT:

• an abelian group

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: AbelianGroupGap([3,6])
Abelian group with gap, generator orders (3, 6)
sage: AbelianGroupGap([3,6,5])
Abelian group with gap, generator orders (3, 6, 5)
sage: AbelianGroupGap([3,6,0])      # optional - gap_packages
Abelian group with gap, generator orders (3, 6, 0)


Warning

Needs the GAP package Polycyclic in case the group is infinite.

class sage.groups.abelian_gps.abelian_group_gap.AbelianGroupQuotient_gap(G, N)

Quotients of abelian groups by a subgroup.

Note

Do not call this directly. Instead use quotient().

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap([4,3])
sage: N = A.subgroup([A.gen(0)^2])
sage: Q1 = A.quotient(N)
sage: Q1
Quotient abelian group with generator orders (2, 3)
sage: Q2 = Q1.quotient(Q1.subgroup(Q1.gens()[:1]))
sage: Q2
Quotient abelian group with generator orders (1, 3)

cover()

Return the covering group of this quotient group.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2,3,4,5])
sage: gen = G.gens()[:2]
sage: S = G.subgroup(gen)
sage: Q = G.quotient(S)
sage: Q.cover() is G
True

lift(x)

Lift an element to the cover.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap()
sage: N = A.subgroup([A.gen(0)^2])
sage: Q = A.quotient(N)
sage: Q.lift(Q.0)
f1

natural_homomorphism()

Return the defining homomorphism into self.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap()
sage: N = A.subgroup([A.gen(0)^2])
sage: Q = A.quotient(N)
sage: Q.natural_homomorphism()
Group morphism:
From: Abelian group with gap, generator orders (4,)
To:   Quotient abelian group with generator orders (2,)

relations()

Return the relations of this quotient group.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2,3,4,5])
sage: gen = G.gens()[:2]
sage: S = G.subgroup(gen)
sage: Q = G.quotient(S)
sage: Q.relations() is S
True

class sage.groups.abelian_gps.abelian_group_gap.AbelianGroupSubgroup_gap(ambient, gens)

Subgroups of abelian groups with GAP.

INPUT:

• ambient – the ambient group

• gens – generators of the subgroup

Note

Do not construct this class directly. Instead use subgroup().

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2,3,4,5])
sage: gen = G.gens()[:2]
sage: S = G.subgroup(gen)

lift(x)

Coerce to the ambient group.

The terminology comes from the category framework and the more general notion of a subquotient.

INPUT:

• x – an element of this subgroup

OUTPUT:

The corresponding element of the ambient group

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap()
sage: g = G.gen(0)
sage: H = G.subgroup([g^2])
sage: h = H.gen(0); h
f2
sage: h.parent()
Subgroup of Abelian group with gap, generator orders (4,) generated by (f2,)
sage: H.lift(h)
f2
sage: H.lift(h).parent()
Abelian group with gap, generator orders (4,)

retract(x)

Convert an element of the ambient group into this subgroup.

The terminology comes from the category framework and the more general notion of a subquotient.

INPUT:

• x – an element of the ambient group that actually lies in this subgroup.

OUTPUT:

The corresponding element of this subgroup

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap()
sage: g = G.gen(0)
sage: H = G.subgroup([g^2])
sage: H.retract(g^2)
f2
sage: H.retract(g^2).parent()
Subgroup of Abelian group with gap, generator orders (4,) generated by (f2,)

class sage.groups.abelian_gps.abelian_group_gap.AbelianGroup_gap(G, category, ambient=None)

Finitely generated abelian groups implemented in GAP.

Needs the gap package Polycyclic in case the group is infinite.

INPUT:

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([3, 2, 5])
sage: G
Abelian group with gap, generator orders (3, 2, 5)

Element
all_subgroups()

Return the list of all subgroups of this group.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2, 3])
sage: G.all_subgroups()
[Subgroup of Abelian group with gap, generator orders (2, 3) generated by (),
Subgroup of Abelian group with gap, generator orders (2, 3) generated by (f1,),
Subgroup of Abelian group with gap, generator orders (2, 3) generated by (f2,),
Subgroup of Abelian group with gap, generator orders (2, 3) generated by (f2, f1)]

aut()

Return the group of automorphisms of self.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2, 3])
sage: G.aut()
Full group of automorphisms of Abelian group with gap, generator orders (2, 3)

automorphism_group()

Return the group of automorphisms of self.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2, 3])
sage: G.aut()
Full group of automorphisms of Abelian group with gap, generator orders (2, 3)

elementary_divisors()

Return the elementary divisors of this group.

See sage.groups.abelian_gps.abelian_group_gap.elementary_divisors().

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2,3,4,5])
sage: G.elementary_divisors()
(2, 60)

exponent()

Return the exponent of this abelian group.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2,3,7])
sage: G
Abelian group with gap, generator orders (2, 3, 7)
sage: G = AbelianGroupGap([2,4,6])
sage: G
Abelian group with gap, generator orders (2, 4, 6)
sage: G.exponent()
12

gens_orders()

Return the orders of the generators.

Use elementary_divisors() if you are looking for an invariant of the group.

OUTPUT:

• a tuple of integers

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: Z2xZ3 = AbelianGroupGap([2,3])
sage: Z2xZ3.gens_orders()
(2, 3)
sage: Z2xZ3.elementary_divisors()
(6,)
sage: Z6 = AbelianGroupGap()
sage: Z6.gens_orders()
(6,)
sage: Z6.elementary_divisors()
(6,)
sage: Z2xZ3.is_isomorphic(Z6)
True
sage: Z2xZ3 is Z6
False

identity()

Return the identity element of this group.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([4,10])
sage: G.identity()
1

is_subgroup_of(G)

Return if self is a subgroup of G considered in the same ambient group.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2,3,4,5])
sage: gen = G.gens()[:2]
sage: S1 = G.subgroup(gen)
sage: S1.is_subgroup_of(G)
True
sage: S2 = G.subgroup(G.gens()[1:])
sage: S2.is_subgroup_of(S1)
False

is_trivial()

Return True if this group is the trivial group.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([])
sage: G
Abelian group with gap, generator orders ()
sage: G.is_trivial()
True
sage: AbelianGroupGap().is_trivial()
True
sage: AbelianGroupGap([1,1,1]).is_trivial()
True
sage: AbelianGroupGap().is_trivial()
False
sage: AbelianGroupGap([2,1]).is_trivial()
False

quotient(N)

Return the quotient of this group by the normal subgroup $$N$$.

INPUT:

• N – a subgroup

• check – bool (default: True) check if $$N$$ is normal

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap([2,3,4,5])
sage: S = A.subgroup(A.gens()[:1])
sage: A.quotient(S)
Quotient abelian group with generator orders (1, 3, 4, 5)

subgroup(gens)

Return the subgroup of this group generated by gens.

INPUT:

• gens – a list of elements coercible into this group

OUTPUT:

• a subgroup

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: G = AbelianGroupGap([2,3,4,5])
sage: gen = G.gens()[:2]
sage: S = G.subgroup(gen)
sage: S
Subgroup of Abelian group with gap, generator orders (2, 3, 4, 5)
generated by (f1, f2)
sage: g = G.an_element()
sage: s = S.an_element()
sage: g * s
f2^2*f3*f5
sage: G = AbelianGroupGap([3,4,0,2])     # optional - gap_packages
sage: gen = G.gens()[:2]                 # optional - gap_packages
sage: S = G.subgroup(gen)                # optional - gap_packages
sage: g = G.an_element()                 # optional - gap_packages
sage: s = S.an_element()                 # optional - gap_packages
sage: g * s                              # optional - gap_packages
g1^2*g2^2*g3*g4