## Section4.8Sage

Cyclic groups are very important, so it is no surprise that they appear in many different forms in Sage. Each is slightly different, and no one implementation is ideal for an introduction, but together they can illustrate most of the important ideas. Here is a guide to the various ways to construct, and study, a cyclic group in Sage.

### SubsectionInfinite Cyclic Groups

In Sage, the integers $$\mathbb Z$$ are constructed with ZZ. To build the infinite cyclic group such as $$3\mathbb Z$$ from Example 4.1, simply use 3*ZZ. As an infinite set, there is not a whole lot you can do with this. You can test if integers are in this set, or not. You can also recall the generator with the .gen() command.

G = 3*ZZ
-12 in G

37 in G

G.gen()


### SubsectionAdditive Cyclic Groups

The additive cyclic group $$\mathbb Z_n$$ can be built as a special case of a more general Sage construction. First we build $$\mathbb Z_{14}$$ and capture its generator. Throughout, pay close attention to the use of parentheses and square brackets for when you experiment on your own.

G = AdditiveAbelianGroup([14])
G.order()

G.list()

a = G.gen(0)
a


You can compute in this group, by using the generator, or by using new elements formed by coercing integers into the group, or by taking the result of operations on other elements. And we can compute the order of elements in this group. Notice that we can perform repeated additions with the shortcut of taking integer multiples of an element.

a + a

a + a + a + a

4*a

37*a


We can create, and then compute with, new elements of the group by coercing an integer (in a list of length $$1$$) into the group. You may get a DeprecationWarning the first time you use this syntax if you are using an old version of Sage. The mysterious warning can be safely ignored.

G([2])

b = G([2]); b

b + b

2*b == 4*a

7*b

b.order()

c = a - 6*b; c

c + c + c + c

c.order()


It is possible to create cyclic subgroups, from an element designated to be the new generator. Unfortunately, to do this requires the .submodule() method (which should be renamed in Sage).

H = G.submodule([b]); H

H.list()

H.order()

e = H.gen(0); e

3*e

e.order()


The cyclic subgroup H just created has more than one generator. We can test this by building a new subgroup and comparing the two subgroups.

f = 12*a; f

f.order()

K = G.submodule([f]); K

K.order()

K.list()

K.gen(0)

H == K


Certainly the list of elements, and the common generator of (2) lead us to belive that H and K are the same, but the comparison in the last line leaves no doubt.

Results in this section, especially Theorem 4.13 and Corollary 4.14, can be investigated by creating generators of subgroups from a generator of one additive cyclic group, creating the subgroups, and computing the orders of both elements and orders of groups.

### SubsectionAbstract Multiplicative Cyclic Groups

We can create an abstract cyclic group in the style of Theorem 4.3, Theorem 4.9, and Theorem 4.10. In the syntax below a is a name for the generator, and 14 is the order of the element. Notice that the notation is now multiplicative, so we multiply elements, and repeated products can be written as powers.

G.<a> = AbelianGroup([14])
G.order()

G.list()

a.order()


Computations in the group are similar to before, only with different notation. Now products, with repeated products written as exponentiation.

b = a^2
b.order()

b*b*b

c = a^7
c.order()

c^2

b*c

b^37*c^42


Subgroups can be formed with a .subgroup() command. But do not try to list the contents of a subgroup, it'll look strangely unfamiliar. Also, comparison of subgroups is not implemented.

H = G.subgroup([a^2])
H.order()

K = G.subgroup([a^12])
K.order()

L = G.subgroup([a^4])
H == L


One advantage of this implementation is the possibility to create all possible subgroups. Here we create the list of subgroups, extract one in particular (the third), and check its order.

allsg = G.subgroups(); allsg

sub = allsg[2]
sub.order()


### SubsectionCyclic Permutation Groups

We will learn more about permutation groups in the next chapter. But we will mention here that it is easy to create cyclic groups as permutation groups, and a variety of methods are available for working with them, even if the actual elements get a bit cumbersome to work with. As before, notice that the notation and syntax is multiplicative.

G=CyclicPermutationGroup(14)
a = G.gen(0); a

b = a^2
b = a^2; b

b.order()

a*a*b*b*b

c = a^37*b^26; c

c.order()


We can create subgroups, check their orders, and list their elements.

H = G.subgroup([a^2])
H.order()

H.gen(0)

H.list()


It could help to visualize this group, and the subgroup, as rotations of a regular $$12$$-gon with the vertices labeled with the integers $$1$$ through $$12\text{.}$$ This is not the full group of symmetries, since it does not include reflections, just the $$12$$ rotations.

### SubsectionCayley Tables

As groups, each of the examples above (groups and subgroups) have Cayley tables implemented. Since the groups are cyclic, and their subgroups are therefore cyclic, the Cayley tables should have a similar “cyclic” pattern. Note that the letters used in the default table are generic, and are not related to the letters used above for specific elements — they just match up with the group elements in the order given by .list().

G.<a> = AbelianGroup([14])
G.cayley_table()


If the real names of the elements are not too complicated, the table could be more informative using these names.

K.<b> = AbelianGroup([10])
K.cayley_table(names='elements')


### SubsectionComplex Roots of Unity

The finite cyclic subgroups of $${\mathbb T}\text{,}$$ generated by a primitive $$n$$th root of unity are implemented as a more general construction in Sage, known as a cyclotomic field. If you concentrate on just the multiplication of powers of a generator (and ignore the infinitely many other elements) then this is a finite cyclic group. Since this is not implemented directly in Sage as a group, per se, it is a bit harder to construct things like subgroups, but it is an excellent exercise to try. It is a nice example since the complex numbers are a concrete and familiar construction. Here are a few sample calculations to provide you with some exploratory tools. See the notes following the computations.

G = CyclotomicField(14)
w = G.gen(0); w

wc = CDF(w)
wc.abs()

wc.arg()/N(2*pi/14)

b = w^2
b.multiplicative_order()

bc = CDF(b); bc

bc.abs()

bc.arg()/N(2*pi/14)

sg = [b^i for i in range(7)]; sg

c = sg[3]; d = sg[5]
c*d

c = sg[3]; d = sg[6]
c*d in sg

c*d == sg[2]

sg[5]*sg[6] == sg[4]

G.multiplication_table(elements=sg)


Notes:

1. zeta14 is the name of the generator used for the cyclotomic field, it is a primitive root of unity (a $$14$$th root of unity in this case). We have captured it as w.

2. The syntax CDF(w) will convert the complex number w into the more familiar form with real and imaginary parts.

3. The method .abs() will return the modulus of a complex number, $$r$$ as described in the text. For elements of $${\mathbb C}^\ast$$ this should always equal $$1\text{.}$$

4. The method .arg() will return the argument of a complex number, $$\theta$$ as described in the text. Every element of the cyclic group in this example should have an argument that is an integer multiple of $$\frac{2\pi}{14}\text{.}$$ The N() syntax converts the symbolic value of pi to a numerical approximation.

5. sg is a list of elements that form a cyclic subgroup of order 7, composed of the first 7 powers of b = w^2. So, for example, the last comparison multiplies the fifth power of b with the sixth power of b, which would be the eleventh power of b. But since b has order 7, this reduces to the fourth power.

6. If you know a subset of an infinite group forms a subgroup, then you can produce its Cayley table by specifying the list of elements you want to use. Here we ask for a multiplication table, since that is the relevant operation.