# Dual groups of Finite Multiplicative Abelian Groups#

The basic idea is very simple. Let G be an abelian group and $$G^*$$ its dual (i.e., the group of homomorphisms from G to $$\CC^\times$$). Let $$g_j$$, $$j=1,..,n$$, denote generators of $$G$$ - say $$g_j$$ is of order $$m_j>1$$. There are generators $$X_j$$, $$j=1,..,n$$, of $$G^*$$ for which $$X_j(g_j)=\exp(2\pi i/m_j)$$ and $$X_i(g_j)=1$$ if $$i\not= j$$. These are used to construct $$G^*$$.

Sage supports multiplicative abelian groups on any prescribed finite number $$n > 0$$ of generators. Use AbelianGroup() function to create an abelian group, the dual_group() method to create its dual, and then the gen() and gens() methods to obtain the corresponding generators. You can print the generators as arbitrary strings using the optional names argument to the dual_group() method.

EXAMPLES:

sage: F = AbelianGroup(5, [2,5,7,8,9], names='abcde')
sage: (a, b, c, d, e) = F.gens()

sage: # needs sage.rings.number_field
sage: Fd = F.dual_group(names='ABCDE')
sage: Fd.base_ring()
Cyclotomic Field of order 2520 and degree 576
sage: A,B,C,D,E = Fd.gens()
sage: A(a)
-1
sage: A(b), A(c), A(d), A(e)
(1, 1, 1, 1)

sage: # needs sage.rings.real_mpfr
sage: Fd = F.dual_group(names='ABCDE', base_ring=CC)
sage: Fd.category()
Category of commutative groups
sage: A,B,C,D,E = Fd.gens()
sage: A(a)    # abs tol 1e-8
-1.00000000000000 + 0.00000000000000*I
sage: A(b); A(c); A(d); A(e)
1.00000000000000
1.00000000000000
1.00000000000000
1.00000000000000


AUTHORS:

• David Joyner (2006-08) (based on abelian_groups)

• David Joyner (2006-10) modifications suggested by William Stein

• Volker Braun (2012-11) port to new Parent base. Use tuples for immutables. Default to cyclotomic base ring.

class sage.groups.abelian_gps.dual_abelian_group.DualAbelianGroup_class(G, names, base_ring)#

Dual of abelian group.

EXAMPLES:

sage: F = AbelianGroup(5,[3,5,7,8,9], names="abcde")
sage: F.dual_group()                                                            # needs sage.rings.number_field
Dual of Abelian Group isomorphic to Z/3Z x Z/5Z x Z/7Z x Z/8Z x Z/9Z
over Cyclotomic Field of order 2520 and degree 576

sage: F = AbelianGroup(4,[15,7,8,9], names="abcd")
sage: F.dual_group(base_ring=CC)                                                # needs sage.rings.real_mpfr
Dual of Abelian Group isomorphic to Z/15Z x Z/7Z x Z/8Z x Z/9Z
over Complex Field with 53 bits of precision

Element#
base_ring()#

Return the scalars over which the group is dualized.

EXAMPLES:

sage: F = AbelianGroup(3,[5,64,729], names=list("abc"))
sage: Fd = F.dual_group(base_ring=CC)
sage: Fd.base_ring()
Complex Field with 53 bits of precision

gen(i=0)#

The $$i$$-th generator of the abelian group.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: F = AbelianGroup(3, [1,2,3], names='a')
sage: Fd = F.dual_group(names="A")
sage: Fd.0
1
sage: Fd.1
A1
sage: Fd.gens_orders()
(1, 2, 3)

gens()#

Return the generators for the group.

OUTPUT:

A tuple of group elements generating the group.

EXAMPLES:

sage: F = AbelianGroup([7,11]).dual_group()                                 # needs sage.rings.number_field
sage: F.gens()                                                              # needs sage.rings.number_field
(X0, X1)

gens_orders()#

The orders of the generators of the dual group.

OUTPUT:

A tuple of integers.

EXAMPLES:

sage: F = AbelianGroup([5]*1000)
sage: Fd = F.dual_group()                                                   # needs sage.rings.number_field
sage: invs = Fd.gens_orders(); len(invs)                                    # needs sage.rings.number_field
1000

group()#

Return the group that self is the dual of.

EXAMPLES:

sage: F = AbelianGroup(3,[5,64,729], names=list("abc"))
sage: Fd = F.dual_group(base_ring=CC)
sage: Fd.group() is F
True

invariants()#

The invariants of the dual group.

You should use gens_orders() instead.

EXAMPLES:

sage: F = AbelianGroup([5]*1000)
sage: Fd = F.dual_group()                                                   # needs sage.rings.number_field
sage: invs = Fd.gens_orders(); len(invs)                                    # needs sage.rings.number_field
1000

is_commutative()#

Return True since this group is commutative.

EXAMPLES:

sage: G = AbelianGroup([2,3,9])
sage: Gd = G.dual_group()                                                   # needs sage.rings.number_field
sage: Gd.is_commutative()                                                   # needs sage.rings.number_field
True
sage: Gd.is_abelian()                                                       # needs sage.rings.number_field
True

list()#

Return tuple of all elements of this group.

EXAMPLES:

sage: G = AbelianGroup([2,3], names="ab")
sage: Gd = G.dual_group(names="AB")                                         # needs sage.rings.number_field
sage: Gd.list()                                                             # needs sage.rings.number_field
(1, B, B^2, A, A*B, A*B^2)

ngens()#

The number of generators of the dual group.

EXAMPLES:

sage: F = AbelianGroup([7]*100)
sage: Fd = F.dual_group()                                                   # needs sage.rings.number_field
sage: Fd.ngens()                                                            # needs sage.rings.number_field
100

order()#

Return the order of this group.

EXAMPLES:

sage: G = AbelianGroup([2,3,9])
sage: Gd = G.dual_group()                                                   # needs sage.rings.number_field
sage: Gd.order()                                                            # needs sage.rings.number_field
54

random_element()#

Return a random element of this dual group.

EXAMPLES:

sage: G = AbelianGroup([2,3,9])
sage: Gd = G.dual_group(base_ring=CC)                                       # needs sage.rings.real_mpfr
sage: Gd.random_element().parent() is Gd                                    # needs sage.rings.real_mpfr
True

sage: # needs sage.rings.real_mpfr
sage: N = 43^2 - 1
sage: G = AbelianGroup([N], names="a")
sage: Gd = G.dual_group(names="A", base_ring=CC)
sage: a, = G.gens()
sage: A, = Gd.gens()
sage: x = a^(N/4); y = a^(N/3); z = a^(N/14)
sage: found = [False]*4
sage: while not all(found):
....:     X = A*Gd.random_element()
....:     found[len([b for b in [x,y,z] if abs(X(b)-1)>10^(-8)])] = True

sage.groups.abelian_gps.dual_abelian_group.is_DualAbelianGroup(x)#

Return True if $$x$$ is the dual group of an abelian group.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.groups.abelian_gps.dual_abelian_group import is_DualAbelianGroup
sage: F = AbelianGroup(5,[3,5,7,8,9], names=list("abcde"))
sage: Fd = F.dual_group()
sage: is_DualAbelianGroup(Fd)
True
sage: F = AbelianGroup(3,[1,2,3], names='a')
sage: Fd = F.dual_group()
sage: Fd.gens()
(1, X1, X2)
sage: F.gens()
(1, a1, a2)