.. -*- coding: utf-8 -*- .. linkall .. _prep-quickstart-abstract-algebra: Sage Quickstart for Abstract Algebra ==================================== This `Sage <http://www.sagemath.org>`_ quickstart tutorial was developed for the MAA PREP Workshop "Sage: Using Open\-Source Mathematics Software with Undergraduates" (funding provided by NSF DUE 0817071). It is licensed under the Creative Commons Attribution\-ShareAlike 3.0 license (`CC BY\-SA <http://creativecommons.org/licenses/by-sa/3.0/>`_). As computers are discrete and finite, anything with a discrete, finite set of generators is natural to implement and explore. Group Theory ------------- Many common groups are pre-defined, usually as permutation groups: that is, explicitly described as subgroups of symmetric groups. - Every group of order 15 or less is available as a permutation group. - Sometimes they are available under special names, though. :: sage: G = QuaternionGroup() sage: G Quaternion group of order 8 as a permutation group :: sage: H = AlternatingGroup(5) sage: H Alternating group of order 5!/2 as a permutation group :: sage: H.is_simple() True :: sage: D = DihedralGroup(8) sage: D Dihedral group of order 16 as a permutation group We can access a lot of information about groups, such as: - A list of subgroups up to conjugacy, - or a stabilizer, - or other things demonstrated below. :: sage: for K in D.conjugacy_classes_subgroups(): ....: print(K) Subgroup generated by [()] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(2,8)(3,7)(4,6)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,2)(3,8)(4,7)(5,6)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(2,8)(3,7)(4,6), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,2)(3,8)(4,7)(5,6), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(2,8)(3,7)(4,6), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,2,3,4,5,6,7,8), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,2)(3,8)(4,7)(5,6), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(2,8)(3,7)(4,6), (1,2,3,4,5,6,7,8), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) In the previous cell we once again did a for loop over a set of objects rather than just a list of numbers. This can be very powerful. :: sage: D.stabilizer(3) Subgroup generated by [(1,5)(2,4)(6,8)] of (Dihedral group of order 16 as a permutation group) :: sage: for K in D.normal_subgroups(): ....: print(K) Subgroup generated by [(1,2,3,4,5,6,7,8), (1,8)(2,7)(3,6)(4,5)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,2,3,4,5,6,7,8), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8), (1,8)(2,7)(3,6)(4,5)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(2,8)(3,7)(4,6), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [(1,5)(2,6)(3,7)(4,8)] of (Dihedral group of order 16 as a permutation group) Subgroup generated by [()] of (Dihedral group of order 16 as a permutation group) We can access specific subgroups if we know the generators as a permutation group. :: sage: L = D.subgroup(["(1,3,5,7)(2,4,6,8)"]) :: sage: L.is_normal(D) True :: sage: Q=D.quotient(L) sage: Q Permutation Group with generators [(1,2)(3,4), (1,3)(2,4)] :: sage: Q.is_isomorphic(KleinFourGroup()) True There are some matrix groups as well, both finite and infinite. :: sage: S = SL(2, GF(3)) sage: S Special Linear Group of degree 2 over Finite Field of size 3 We can print out *all* of the elements of this group. :: sage: for a in S: ....: print(a) [1 0] [0 1] ... [2 2] [2 1] :: sage: SS = SL(2, ZZ) Of course, you have to be careful what you try to do! :: sage: SS.list() Traceback (most recent call last): ... NotImplementedError: group must be finite :: sage: for a in SS.gens(): ....: print(a) [ 0 1] [-1 0] ... Rings ------ Sage has many pre\-defined rings to experiment with. Here is how one would access :math:`\ZZ/12\ZZ`, for instance. :: sage: twelve = Integers(12) sage: twelve Ring of integers modulo 12 :: sage: twelve.is_field() False :: sage: twelve.is_integral_domain() False Quaternions, and generalizations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We can define generalized quaternion algebras, where :math:`i^2=a`, :math:`j^2=b`, and :math:`k=i\cdot j`, all over :math:`\QQ`:: sage: quat = QuaternionAlgebra(-1, -1) sage: quat Quaternion Algebra (-1, -1) with base ring Rational Field :: sage: quat.is_field() False :: sage: quat.is_commutative() False :: sage: quat.is_division_algebra() True :: sage: quat2 = QuaternionAlgebra(5, -7) :: sage: quat2.is_division_algebra() True :: sage: quat2.is_field() False Polynomial Rings ~~~~~~~~~~~~~~~~ Polynomial arithmetic in Sage is a very important tool. The first cell brings us back to the symbolic world. This is **not the same thing** as polynomials! :: sage: reset('x') # This returns x to being a variable sage: (x^4 + 2*x).parent() Symbolic Ring Now we will turn :math:`x` into the generator of a polynomial ring. The syntax is a little unusual, but you will see it often. :: sage: R.<x> = QQ[] sage: R Univariate Polynomial Ring in x over Rational Field :: sage: R.random_element() # random -5/2*x^2 - 1/4*x - 1 :: sage: R.is_integral_domain() True :: sage: (x^4 + 2*x).parent() Univariate Polynomial Ring in x over Rational Field :: sage: (x^2+x+1).is_irreducible() True :: sage: F = GF(5) sage: P.<y> = F[] :: sage: P.random_element() # random 2*y :: sage: I = P.ideal(y^3+2*y) sage: I Principal ideal (y^3 + 2*y) of Univariate Polynomial Ring in y over Finite Field of size 5 :: sage: Q = P.quotient(I) :: sage: Q Univariate Quotient Polynomial Ring in ybar over Finite Field of size 5 with modulus y^3 + 2*y Fields ------ Sage has superb support for finite fields and extensions of the rationals. Finite Fields ~~~~~~~~~~~~~ :: sage: F.<a> = GF(3^4) sage: F Finite Field in a of size 3^4 The generator satisfies a Conway polynomial, by default, or the polynomial can be specified. :: sage: F.polynomial() a^4 + 2*a^3 + 2 :: sage: F.list() [0, a, a^2, a^3, a^3 + 1, a^3 + a + 1, a^3 + a^2 + a + 1, 2*a^3 + a^2 + a + 1, a^2 + a + 2, a^3 + a^2 + 2*a, 2*a^3 + 2*a^2 + 1, a^3 + a + 2, a^3 + a^2 + 2*a + 1, 2*a^3 + 2*a^2 + a + 1, a^3 + a^2 + a + 2, 2*a^3 + a^2 + 2*a + 1, 2*a^2 + a + 2, 2*a^3 + a^2 + 2*a, 2*a^2 + 2, 2*a^3 + 2*a, 2*a^3 + 2*a^2 + 2, a^3 + 2*a + 2, a^3 + 2*a^2 + 2*a + 1, 2*a^2 + a + 1, 2*a^3 + a^2 + a, a^2 + 2, a^3 + 2*a, a^3 + 2*a^2 + 1, a + 1, a^2 + a, a^3 + a^2, 2*a^3 + 1, 2*a^3 + a + 2, 2*a^3 + a^2 + 2*a + 2, 2*a^2 + 2*a + 2, 2*a^3 + 2*a^2 + 2*a, a^3 + 2*a^2 + 2, 2*a + 1, 2*a^2 + a, 2*a^3 + a^2, 2, 2*a, 2*a^2, 2*a^3, 2*a^3 + 2, 2*a^3 + 2*a + 2, 2*a^3 + 2*a^2 + 2*a + 2, a^3 + 2*a^2 + 2*a + 2, 2*a^2 + 2*a + 1, 2*a^3 + 2*a^2 + a, a^3 + a^2 + 2, 2*a^3 + 2*a + 1, 2*a^3 + 2*a^2 + a + 2, a^3 + a^2 + 2*a + 2, 2*a^3 + 2*a^2 + 2*a + 1, a^3 + 2*a^2 + a + 2, a^2 + 2*a + 1, a^3 + 2*a^2 + a, a^2 + 1, a^3 + a, a^3 + a^2 + 1, 2*a^3 + a + 1, 2*a^3 + a^2 + a + 2, a^2 + 2*a + 2, a^3 + 2*a^2 + 2*a, 2*a^2 + 1, 2*a^3 + a, 2*a^3 + a^2 + 2, 2*a + 2, 2*a^2 + 2*a, 2*a^3 + 2*a^2, a^3 + 2, a^3 + 2*a + 1, a^3 + 2*a^2 + a + 1, a^2 + a + 1, a^3 + a^2 + a, 2*a^3 + a^2 + 1, a + 2, a^2 + 2*a, a^3 + 2*a^2, 1] :: sage: (a^3 + 2*a^2 + 2)*(2*a^3 + 2*a + 1) 2*a^3 + a^2 + a + 1 :math:`F` should be the splitting field of the polynomial :math:`x^{81}-x`, so it is very good that we get no output from the following cell, which combines a loop and a conditional statement. :: sage: for a in F: ....: if not (a^81 - a == 0): ....: print("Oops!") Field Extensions, Number Fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Most things you will need in an undergraduate algebra classroom are already in Sage. :: sage: N = QQ[sqrt(2)] sage: N Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? :: sage: var('z') z sage: M.<a>=NumberField(z^2-2) sage: M Number Field in a with defining polynomial z^2 - 2 :: sage: M.degree() 2 :: sage: M.is_galois() True :: sage: M.is_isomorphic(N) True