Package sage :: Package groups :: Package abelian_gps :: Module abelian_group
[hide private]
[frames] | no frames]

Module abelian_group

source code


Multiplicative Abelian Groups

AUTHOR:
    -- David Joyner (2006-03) (based on free abelian monoids by David Kohel)
    -- David Joyner (2006-05) several significant bug fixes
    -- David Joyner (2006-08) trivial changes to docs, added random,
                              fixed bug in how invariants are recorded
    -- David Joyner (2006-10) added dual_group method
    -- David Joyner (2008-02) fixed serious bug in word_problem
    -- David Joyner (2008-03) fixed bug in trivial group case

TODO:
   * additive abelian groups should also be supported


Background on elementary divisors, invariant factors and the Smith
normal form (according to section 4.1 of [C1]): An abelian group is a
group A for which there exists an exact sequence $\Z^k \rightarrow
\Z^\ell \rightarrow A \rightarrow 1$, for some positive integers
$k,\ell$ with $k\leq \ell$. For example, a finite abelian group has a
decomposition

\[
A = \langle a_1\rangle \times \dots \times  \langle a_\ell\rangle ,
\]
where $ord(a_i)=p_i^{c_i}$, for some primes $p_i$ and some
positive integers $c_i$, $i=1,...,\ell$. GAP calls the 
list (ordered by size) of the $p_i^{c_i}$ the {\it abelian invariants}.
In \sage they will be called {\it invariants}.
In this situation,
$k=\ell$ and $\phi:  \Z^\ell \rightarrow A$ is the map 
$\phi(x_1,...,x_\ell) = a_1^{x_1}...a_\ell^{x_\ell}$,
for $(x_1,...,x_\ell)\in \Z^\ell$. The matrix of relations
$M:\Z^k \rightarrow \Z^\ell$ is the matrix 
whose rows generate the kernel of $\phi$ as a $\Z$-module.
In other words, $M=(M_{ij})$ is a $\ell\times \ell$
diagonal matrix with $M_{ii}=p_i^{c_i}$. Consider now the 
subgroup $B\subset A$ generated by 
$b_1 = a_1^{f_{1,1}}...a_\ell^{f_{\ell,1}}$, ...,
$b_m = a_1^{f_{1,m}}...a_\ell^{f_{\ell,m}}$.
The kernel of the map $\phi_B:  \Z^m \rightarrow B$ defined by
$\phi_B(y_1,...,y_m) = b_1^{y_1}...b_m^{y_m}$,
for $(y_1,...,y_m)\in \Z^m$, is the kernel of the matrix

\[
F=
\left(
\begin{array}{cccc}
f_{11} & f_{12} & \dots & f_{1m}\\
f_{21} & f_{22} & \dots & f_{2m}\\
\vdots &        & \ddots & \vdots \\
f_{\ell,1} & f_{\ell,2} & \dots & f_{\ell,m}
\end{array}
\right),
\]
regarded as a map 
$Z^m\rightarrow (\Z/p_1^{c_1}\Z)\times ...\times (\Z/p_\ell^{c_\ell}\Z)$.
In particular, $B\cong \Z^m/ker(F)$. If $B=A$ then the 
Smith normal form (SNF) of a generator matrix of
$ker(F)$ and the SNF of $M$ are the same. The diagonal entries $s_i$ of the 
SNF $S = diag[s_1,s_2,s_3, ... s_r,0,0,...0]$,
are called {\it determinantal divisors} of $F$.
where $r$ is the rank. The {\it invariant factors} of  A  are:
\[
s_1, s_2/s_1, s_3/s_2, ... s_r/s_{r-1}.
\]
The {\it elementary divisors} use the highest (non-trivial) prime
powers occuring in the factorizations of the numbers $s_1, s_2,
... s_r$.


SAGE supports multiplicative abelian groups on any prescribed finite
number $n\geq 0$ of generators.  Use the \code{AbelianGroup} function
to create an abelian group, and the \code{gen} and \code{gens}
functions to obtain the corresponding generators.  You can print the
generators as arbitrary strings using the optional \code{names}
argument to the \code{AbelianGroup} function.

EXAMPLE 1:
We create an abelian group in zero or more variables; the syntax T(1)
creates the identity element even in the rank zero case.

    sage: T = AbelianGroup(0,[])
    sage: T
    Trivial Abelian Group
    sage: T.gens()
    ()
    sage: T(1)
    1
 
EXAMPLE 2:
An abelian group uses a multiplicative representation of elements, but
the underlying representation is lists of integer exponents.

    sage: F = AbelianGroup(5,[3,4,5,5,7],names = list("abcde"))
    sage: F
    Multiplicative Abelian Group isomorphic to C3 x C4 x C5 x C5 x C7
    sage: (a,b,c,d,e) = F.gens()
    sage: a*b^2*e*d
    a*b^2*d*e
    sage: x = b^2*e*d*a^7
    sage: x
    a*b^2*d*e
    sage: x.list()
    [1, 2, 0, 1, 1]

REFERENCES:
    [C1] H. Cohen {\bf Advanced topics in computational number theory}, Springer, 2000.
    [C2] ------, {\bf A course in computational algebraic number theory}, Springer, 1996.
    [R]  J. Rotman, {\bf An introduction to the theory of groups}, 4th ed, Springer, 1995.

 WARNINGS: Many basic properties for infinite abelian groups are not implemented.



Classes [hide private]
  AbelianGroup_class
Abelian group on $n$ generators.
  AbelianGroup_subgroup
Subgroup subclass of AbelianGroup_class, so instance methods are inherited.
Functions [hide private]
 
word_problem(words, g, verbose=False)
G and H are abelian, g in G, H is a subgroup of G generated by a list (words) of elements of G.
source code
 
AbelianGroup(n, invfac=['4ti2-20061025', 'R-2.6.0', 'atlas-3.7.37', 'atlas-3.8.1', 'a..., names='f')
Create the multiplicative abelian group in $n$ generators with given invariants (which need not be prime powers).
source code
 
is_AbelianGroup(x)
Return True if $x$ is an abelian group.
source code
Function Details [hide private]

word_problem(words, g, verbose=False)

source code 

G and H are abelian, g in G, H is a subgroup of G generated by a
list (words) of elements of G. If g is in H, return the expression
for g as a word in the elements of (words).

The 'word problem' for a finite abelian group G boils down to the following
matrix-vector analog of the Chinese remainder theorem.

Problem: Fix integers $1<n_1\leq n_2\leq ...\leq n_k$ (indeed, 
these $n_i$ will all be prime powers), fix a generating set 
$g_i=(a_{i1},...,a_{ik})$ (with $a_{ij}\in \Z/n_j\Z$),
for $1\leq i\leq \ell$, for the group $G$, and let 
$d = (d_1,...,d_k)$ be an element of the direct product
$\Z/n_1\Z \times ...\times \Z/n_k\Z$. Find, if they exist,
integers $c_1,...,c_\ell$ such that 
$c_1g_1+...+c_\ell g_\ell = d$. In other words, solve the
equation $cA=d$ for $c\in \Z^\ell$, where $A$ is the matrix whose 
rows are the $g_i$'s. Of course, it suffices to restrict the $c_i$'s
to the range $0\leq c_i\leq N-1$, where $N$ denotes the least common
multiple of the integers $n_1,...,n_k$.

This function does not solve this directly, as perhaps it should. Rather 
(for both speed and as a model for a similar function valid for more 
general groups), it pushes it over to GAP, which has optimized algorithms for
the word problem. Essentially, this function is a wrapper for the GAP
function 'Factorization'. 

EXAMPLE:
    sage: G.<a,b,c> = AbelianGroup(3,[2,3,4]); G
    Multiplicative Abelian Group isomorphic to C2 x C3 x C4
    sage: word_problem([a*b,a*c], b*c)
    [[a*b, 1], [a*c, 1]]
    sage: word_problem([a*c,c],a)
    [[a*c, 1], [c, -1]]
    sage: word_problem([a*c,c],a,verbose=True)
    a = (a*c)^1*(c)^-1
    [[a*c, 1], [c, -1]]

    sage: A.<a,b,c,d,e> = AbelianGroup(5,[4, 5, 5, 7, 8])
    sage: b1 = a^3*b*c*d^2*e^5
    sage: b2 = a^2*b*c^2*d^3*e^3
    sage: b3 = a^7*b^3*c^5*d^4*e^4
    sage: b4 = a^3*b^2*c^2*d^3*e^5
    sage: b5 = a^2*b^4*c^2*d^4*e^5
    sage: word_problem([b1,b2,b3,b4,b5],e)
    [[a^3*b*c*d^2*e^5, 1],
     [a^2*b*c^2*d^3*e^3, 1],
     [a^3*b^3*d^4*e^4, 3],
     [a^2*b^4*c^2*d^4*e^5, 1]]
    sage: word_problem([a,b,c,d,e],e)
    [[e, 1]]
    sage: word_problem([a,b,c,d,e],b)
    [[b, 1]]

    
WARNINGS: (1) Might have unpleasant effect when the word problem
             cannot be solved.

         (2) Uses permutation groups, so may be slow when group is
             large. The instance method word_problem of the class
             AbelianGroupElement is implemented differently
             (wrapping GAP's"EpimorphismFromFreeGroup" and 
             "PreImagesRepresentative") and may be faster.

AbelianGroup(n, invfac=['4ti2-20061025', 'R-2.6.0', 'atlas-3.7.37', 'atlas-3.8.1', 'a..., names='f')

source code 

Create the multiplicative abelian group in $n$ generators with
given invariants (which need not be prime powers).

INPUT:
    n -- integer
    invfac -- (the"invariant factors") a list of non-negative integers
              in the form [a0, a1,...,a(n-1)], typically written in
              increasing order.  This list is padded with zeros if
              it has length less than n.  
    names -- (optional) names of generators

Alternatively, you can also give input in the following form:
    
    \code{AbelianGroup(invfac, names="f")},

where names must be explicitly named.
    
OUTPUT:
    Abelian group with generators and invariant type. The default name
    for generator A.i is fi, as in GAP.

EXAMPLES:
    sage: F = AbelianGroup(5, [5,5,7,8,9], names='abcde')
    sage: F(1)
    1
    sage: (a, b, c, d, e) = F.gens()
    sage: mul([ a, b, a, c, b, d, c, d ], F(1))
    a^2*b^2*c^2*d^2
    sage: d * b**2 * c**3 
    b^2*c^3*d
    sage: F = AbelianGroup(3,[2]*3); F
    Multiplicative Abelian Group isomorphic to C2 x C2 x C2
    sage: H = AbelianGroup([2,3], names="xy"); H
    Multiplicative Abelian Group isomorphic to C2 x C3
    sage: AbelianGroup(5)
    Multiplicative Abelian Group isomorphic to Z x Z x Z x Z x Z
    sage: AbelianGroup(5).order()
    +Infinity

Notice how $0$'s are padded on.
    sage: AbelianGroup(5, [2,3,4])
    Multiplicative Abelian Group isomorphic to Z x Z x C2 x C3 x C4

The invariant list can't be longer than the number of generators.
    sage: AbelianGroup(2, [2,3,4])
    Traceback (most recent call last):
    ...
    ValueError: invfac (=[2, 3, 4]) must have length n (=2)

is_AbelianGroup(x)

source code 

Return True if $x$ is an abelian group.

EXAMPLES:
    sage: F = AbelianGroup(5,[5,5,7,8,9],names = list("abcde")); F
    Multiplicative Abelian Group isomorphic to C5 x C5 x C7 x C8 x C9
    sage: is_AbelianGroup(F)
    True
    sage: is_AbelianGroup(AbelianGroup(7, [3]*7))
    True