{ "cells": [ { "cell_type": "markdown", "id": "c8e376d8-df34-4b30-adf1-8511dfe60980", "metadata": {}, "source": [ "We explore some capabilities of GAP in SageMath." ] }, { "cell_type": "markdown", "id": "68a93d66-c400-4a19-8f08-1c4c1849b9cf", "metadata": {}, "source": [ "Via the `gap magics` we can directly type GAP commands in code cells of the Jupyter notebook with a SageMath kernel." ] }, { "cell_type": "markdown", "id": "2094d7e6-9460-409b-8d21-27fee57926bb", "metadata": {}, "source": [ "# 1. Combinatorics and List Manipulations" ] }, { "cell_type": "markdown", "id": "b032423d-350f-44b6-8f0d-2d459adfaa7e", "metadata": {}, "source": [ "To compute all tuples of 3 elements out of the set $\\{0,1,2\\}$:" ] }, { "cell_type": "code", "execution_count": 1, "id": "e0da241f-efa3-439f-a817-cde9513695a9", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 0, 0, 0 ], [ 0, 0, 1 ], [ 0, 0, 2 ], [ 0, 1, 0 ], [ 0, 1, 1 ], \n", " [ 0, 1, 2 ], [ 0, 2, 0 ], [ 0, 2, 1 ], [ 0, 2, 2 ], [ 1, 0, 0 ], \n", " [ 1, 0, 1 ], [ 1, 0, 2 ], [ 1, 1, 0 ], [ 1, 1, 1 ], [ 1, 1, 2 ], \n", " [ 1, 2, 0 ], [ 1, 2, 1 ], [ 1, 2, 2 ], [ 2, 0, 0 ], [ 2, 0, 1 ], \n", " [ 2, 0, 2 ], [ 2, 1, 0 ], [ 2, 1, 1 ], [ 2, 1, 2 ], [ 2, 2, 0 ], \n", " [ 2, 2, 1 ], [ 2, 2, 2 ] ]\n" ] } ], "source": [ "%%gap\n", "L := Tuples([0..2], 3)" ] }, { "cell_type": "code", "execution_count": 2, "id": "1f8fcc58-46b0-4b3d-9bff-fa183c392cb0", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "27\n" ] } ], "source": [ "%%gap\n", "Length(L)" ] }, { "cell_type": "markdown", "id": "b4fe9dc3-c9f2-4ae8-868d-c54549b0a5c7", "metadata": {}, "source": [ "We can compute the number without listing all elements." ] }, { "cell_type": "code", "execution_count": 3, "id": "673286d7-d6a8-4a7f-8df6-62146fd18ccb", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "27\n" ] } ], "source": [ "%%gap\n", "NrTuples([0..2], 3)" ] }, { "cell_type": "markdown", "id": "95f2847f-15a5-4f49-8821-d49f4d1b101f", "metadata": {}, "source": [ "Let us filter those elements of the list `L` that sum to two." ] }, { "cell_type": "code", "execution_count": 4, "id": "78ff164f-2483-4f08-a48b-6a7c68457282", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 0, 0, 2 ], [ 0, 1, 1 ], [ 0, 2, 0 ], [ 1, 0, 1 ], [ 1, 1, 0 ], \n", " [ 2, 0, 0 ] ]\n" ] } ], "source": [ "%%gap\n", "F := Filtered(L,n->Sum(n) = 2)" ] }, { "cell_type": "markdown", "id": "45859584-72a8-4ccc-9a67-8390b2542036", "metadata": {}, "source": [ "# 2. Integer Matrices and Normal Forms" ] }, { "cell_type": "markdown", "id": "459c369c-6747-40e4-82d3-2ce02213606f", "metadata": {}, "source": [ "Defining a matrix is straightforward." ] }, { "cell_type": "code", "execution_count": 5, "id": "c27a7dae-bce5-45a2-91b7-3b01bc9fc115", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]\n" ] } ], "source": [ "%%gap\n", "M := [[1,2,3],[4,5,6],[7,8,9]]" ] }, { "cell_type": "code", "execution_count": 6, "id": "2df45238-624f-4e30-a239-21751fbac453", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n" ] } ], "source": [ "%%gap\n", "Determinant(M)" ] }, { "cell_type": "markdown", "id": "3d9729cd-fe81-4396-be35-0d2bc32a77aa", "metadata": {}, "source": [ "A singular matrix has a nonempty null space." ] }, { "cell_type": "code", "execution_count": 7, "id": "4bdc0cc2-8d63-4e01-82c2-9cbfd0fdf03c", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, -2, 1 ] ]\n" ] } ], "source": [ "%%gap\n", "v := NullspaceIntMat(M)" ] }, { "cell_type": "markdown", "id": "8aee46f7-0f3b-42a7-a593-48b48e71b75e", "metadata": {}, "source": [ "Let us verify that `M` times `v` equals the zero vector." ] }, { "cell_type": "code", "execution_count": 8, "id": "f29d6c88-4eac-46ff-a601-5230101b90eb", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "true\n" ] } ], "source": [ "%%gap\n", "IsRowVector(v[1])" ] }, { "cell_type": "code", "execution_count": 9, "id": "cb715a7c-1300-4d37-afee-0a0a1328b4a7", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1 ], [ -2 ], [ 1 ] ]\n" ] } ], "source": [ "%%gap\n", "w := TransposedMat(v)" ] }, { "cell_type": "code", "execution_count": 10, "id": "398369f3-7d2c-4cbf-92a9-650778da2315", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 0 ], [ 0 ], [ 0 ] ]\n" ] } ], "source": [ "%%gap\n", "M*w" ] }, { "cell_type": "markdown", "id": "de4db433-0f2f-4bff-a306-24dd3a15fbf7", "metadata": {}, "source": [ "The Hermite normal form of an integer matrix $A$ is\n", "an upper triangular matrix $H$ obtained from $A$\n", "via multiplication with a unimodular matrix $Q$: $Q A = H$." ] }, { "cell_type": "markdown", "id": "4f7f7f30-8a99-417e-bdad-015de87eb975", "metadata": {}, "source": [ "Let us illustrate on a random 3-by-3 matrix, with integer numbers in the range -5..+5" ] }, { "cell_type": "code", "execution_count": 11, "id": "84f45128-05d9-4993-837e-f550d27406a8", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ -5, 2, -1 ], [ 0, 2, -3 ], [ -4, -5, -3 ] ]\n" ] } ], "source": [ "%%gap\n", "A := RandomMat(3,3,[-5..5]) " ] }, { "cell_type": "code", "execution_count": 12, "id": "88a66a41-aaf2-4c34-94d5-1938a3517bfd", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, 0, 48 ], [ 0, 1, 59 ], [ 0, 0, 121 ] ]\n" ] } ], "source": [ "%%gap\n", "H := HermiteNormalFormIntegerMat(A)" ] }, { "cell_type": "markdown", "id": "626617c4-a888-4fe9-a9f0-5c1b1de6947f", "metadata": {}, "source": [ "The method `TriangulizeIntegerMat`($A$)\n", "changes $A$ to its Hermite normal form." ] }, { "cell_type": "code", "execution_count": 13, "id": "4f6cdcdf-0fd8-4464-8de8-5c385d61e259", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "rec( normal := [ [ 1, 0, 48 ], [ 0, 1, 59 ], [ 0, 0, 121 ] ], rank := 3, \n", " rowC := [ [ 1, 0, 0 ], [ 0, 1, 1 ], [ 0, 0, 1 ] ], \n", " rowQ := [ [ 3, -13, 9 ], [ 4, -16, 11 ], [ 8, -33, 23 ] ], \n", " rowtrans := [ [ 3, -13, -4 ], [ 4, -16, -5 ], [ 8, -33, -10 ] ], \n", " signdet := 1 )\n" ] } ], "source": [ "%%gap \n", "N := HermiteNormalFormIntegerMatTransform(A)" ] }, { "cell_type": "code", "execution_count": 14, "id": "215d037b-ac9e-4f2a-a395-ee453d2ee7c9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, 0, 48 ], [ 0, 1, 59 ], [ 0, 0, 121 ] ]\n" ] } ], "source": [ "%%gap\n", "N.rowtrans*A" ] }, { "cell_type": "code", "execution_count": 15, "id": "07a7d3c4-fd8a-4135-b6f2-856dde49bd8f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "true\n" ] } ], "source": [ "%%gap\n", "N.rowtrans*A = N.normal" ] }, { "cell_type": "code", "execution_count": 16, "id": "71f1de91-4632-475f-9b49-ab883b3c8513", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "%%gap\n", "Determinant(N.rowtrans)" ] }, { "cell_type": "markdown", "id": "9bab8bbf-7fa7-481a-81a7-239cef61cd59", "metadata": {}, "source": [ "The Smith normal form of an integer matrix $A$\n", "is a diagonal matrix $S$ obtained via multiplications of $A$\n", "with two unimodular matrices $P$, $Q$ so that $P A Q = S$." ] }, { "cell_type": "code", "execution_count": 17, "id": "494abd62-5764-4b72-a004-ec137df6be19", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 121 ] ]\n" ] } ], "source": [ "%%gap\n", "S := SmithNormalFormIntegerMat(A)" ] }, { "cell_type": "markdown", "id": "367eedc1-55e8-4aa9-bc0d-5f6b52a2ec32", "metadata": {}, "source": [ "The method `DiagonalizeIntegerMat`($A$)\n", "changes $A$ to its Smith normal form." ] }, { "cell_type": "code", "execution_count": 18, "id": "61be7d2e-8420-411e-a33b-f600b5d83c37", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "rec( colC := [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ], \n", " colQ := [ [ 1, 0, -48 ], [ 0, 1, -59 ], [ 0, 0, 1 ] ], \n", " coltrans := [ [ 1, 0, -48 ], [ 0, 1, -59 ], [ 0, 0, 1 ] ], \n", " normal := [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 121 ] ], rank := 3, \n", " rowC := [ [ 1, 0, 0 ], [ 0, 1, 1 ], [ 0, 0, 1 ] ], \n", " rowQ := [ [ 3, -13, 9 ], [ 4, -16, 11 ], [ 8, -33, 23 ] ], \n", " rowtrans := [ [ 3, -13, -4 ], [ 4, -16, -5 ], [ 8, -33, -10 ] ], \n", " signdet := 1 )\n" ] } ], "source": [ "%%gap \n", "SNF := SmithNormalFormIntegerMatTransforms(A);" ] }, { "cell_type": "code", "execution_count": 19, "id": "712c3829-9065-4fa3-b081-4cd5cf34a377", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 121 ] ]\n" ] } ], "source": [ "%%gap\n", "SNF.rowtrans*A*SNF.coltrans" ] }, { "cell_type": "code", "execution_count": 20, "id": "37c6511a-e144-4338-9417-b053f6f72be0", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "true\n" ] } ], "source": [ "%%gap\n", "SNF.rowtrans*A*SNF.coltrans = SNF.normal;" ] }, { "cell_type": "markdown", "id": "a08f220c-cfff-4d23-8d5c-f2ebc0afc576", "metadata": {}, "source": [ "# 3. Computing with Groups" ] }, { "cell_type": "markdown", "id": "3e385c06-6199-4bbc-857e-0d34878eb4e3", "metadata": {}, "source": [ "## 3.1 Permutation Groups" ] }, { "cell_type": "markdown", "id": "0f5f9417-26a4-4679-aa2b-bc5293c90def", "metadata": {}, "source": [ "The full permutation group on $n$ elements has size $n!$\n", "so holding the entire group in memory should be avoided." ] }, { "cell_type": "code", "execution_count": 21, "id": "152ea1bc-1061-4f16-81c1-b2561435ffb1", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1,2)\n" ] } ], "source": [ "%%gap\n", "a := (1,2)" ] }, { "cell_type": "code", "execution_count": 22, "id": "82ae7290-1222-4150-b503-f02bb833e5ad", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1,2)\n" ] } ], "source": [ "%%gap \n", "Inverse(a)" ] }, { "cell_type": "code", "execution_count": 23, "id": "765c2432-b984-4a89-97b3-d9def260e666", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1,3)\n" ] } ], "source": [ "%%gap\n", "b := (1,3)" ] }, { "cell_type": "code", "execution_count": 24, "id": "6bc28325-39a4-4831-99ff-5eef5abf7aaa", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1,2,3)\n" ] } ], "source": [ "%%gap\n", "c := a*b" ] }, { "cell_type": "code", "execution_count": 25, "id": "45696009-599b-4df4-97ed-9381a929aee4", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Group([ (1,2), (1,3) ])\n" ] } ], "source": [ "%%gap \n", "g := Group(a,b)" ] }, { "cell_type": "code", "execution_count": 26, "id": "b7b87a80-a275-4e38-aac4-e31991762835", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6\n" ] } ], "source": [ "%%gap\n", "Size(g);" ] }, { "cell_type": "markdown", "id": "98075120-179d-42b0-9d8f-05763abf46b0", "metadata": {}, "source": [ "We can use an enumerator of the group." ] }, { "cell_type": "code", "execution_count": 27, "id": "f1aec440-bfec-42d6-afca-46ffb84c67d8", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "e := Enumerator(g)" ] }, { "cell_type": "code", "execution_count": 28, "id": "d116d11e-722c-4f1e-8827-5fa7f6a6b3a7", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "()\n" ] } ], "source": [ "%%gap\n", "e[1]" ] }, { "cell_type": "code", "execution_count": 29, "id": "5508a408-499f-4a5f-8cb5-9b6ff5ee758c", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1,3)\n" ] } ], "source": [ "%%gap\n", "e[6]" ] }, { "cell_type": "code", "execution_count": 30, "id": "d3c978d1-f485-43cd-a64c-3eeb7f8244b4", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ (), (1,2,3), (1,3,2), (2,3), (1,2), (1,3) ]\n" ] } ], "source": [ "%%gap\n", "G := List([1..Size(g)], i -> e[i])" ] }, { "cell_type": "markdown", "id": "2f4606c4-40b4-4fa6-912e-0d9d37091f33", "metadata": {}, "source": [ "We see all elements of the full permutation group on three elements." ] }, { "cell_type": "markdown", "id": "bd9bbe48-cd8d-4fff-b370-da02264f1581", "metadata": {}, "source": [ "For a finite group, we can ask for its *multiplication table* which contains the outcomes of any two elements of the group." ] }, { "cell_type": "code", "execution_count": 31, "id": "62d96ce3-a1c6-411b-98e1-a42b08788f18", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ (), (1,2,3), (1,3,2), (2,3), (1,2), (1,3) ]\n" ] } ], "source": [ "%%gap \n", "G" ] }, { "cell_type": "code", "execution_count": 32, "id": "52962e23-d5ba-435f-99f8-b08710ad022b", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, 2, 3, 4, 5, 6 ], [ 2, 3, 1, 6, 4, 5 ], [ 3, 1, 2, 5, 6, 4 ], \n", " [ 4, 5, 6, 1, 2, 3 ], [ 5, 6, 4, 3, 1, 2 ], [ 6, 4, 5, 2, 3, 1 ] ]\n" ] } ], "source": [ "%%gap \n", "MultiplicationTable(G)" ] }, { "cell_type": "markdown", "id": "0a93d270-c056-4735-b9c0-52b867ca381a", "metadata": {}, "source": [ "The multiplication table shows that $G, \\star$ is a group:\n", "\n", "1. $\\forall a, b \\in G$: $a \\star b \\in G$,\n", "\n", "2. $\\forall a, b, c \\in G$: $(a \\star b) \\star c = a \\star (b \\star c)$,\n", "\n", "3. $\\exists 1 \\in G$, $\\forall a \\in G$: $1 \\star a = a$,\n", "\n", "4. $\\forall a \\in G$, $\\exists b \\in G$: $a \\star b = 1$." ] }, { "cell_type": "markdown", "id": "9e1e734d-0205-4f2b-b938-fb6eabeba4bb", "metadata": {}, "source": [ "The orbit of a group on an item is\n", "the result of all group actions on that item." ] }, { "cell_type": "code", "execution_count": 33, "id": "d2ffdb17-e95a-4262-a11e-62f600334e61", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ (), (1,2,3), (1,3,2), (2,3), (1,2), (1,3) ]\n" ] } ], "source": [ "%%gap\n", "G" ] }, { "cell_type": "code", "execution_count": 34, "id": "3106cba2-0de8-47a5-a9cc-470347eb6035", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, 2, 3 ], [ 2, 1, 3 ], [ 3, 2, 1 ], [ 2, 3, 1 ], [ 3, 1, 2 ], \n", " [ 1, 3, 2 ] ]\n" ] } ], "source": [ "%%gap\n", "Orbit(g,[1,2,3],OnTuples)" ] }, { "cell_type": "markdown", "id": "7e199c22-150a-4457-9b18-70c2a1d476b0", "metadata": {}, "source": [ "Observe the cycle notation, e.g.: `(1,3,2)`denotes\n", "that 1 is mapped to 3, 3 to 2, and 2 to 1." ] }, { "cell_type": "markdown", "id": "9e54f6fe-3964-4582-a6ab-3966f950d84d", "metadata": {}, "source": [ "## 3.2 group libraries" ] }, { "cell_type": "markdown", "id": "683098c5-0876-4d52-bf32-3243d815100e", "metadata": {}, "source": [ "GAP knows several groups, available in libraries." ] }, { "cell_type": "markdown", "id": "07222390-1c85-4ec3-b505-f9d847f132e7", "metadata": {}, "source": [ "Cyclic groups are\n", "generated by one single element, for example:" ] }, { "cell_type": "code", "execution_count": 35, "id": "35d0523b-3c07-4a6a-8294-47a6c9359548", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "c5 := CyclicGroup(5);" ] }, { "cell_type": "code", "execution_count": 36, "id": "92cab674-2e2e-4349-a8f8-266ac495a535", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ f1 ]\n" ] } ], "source": [ "%%gap\n", "g := GeneratorsOfGroup(c5);" ] }, { "cell_type": "code", "execution_count": 37, "id": "bd2ef3e3-d996-4938-8ac5-67174013ee75", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ f1 ], f1^2, [ f1^3 ], f1^4, [ of ... ] ]\n" ] } ], "source": [ "%%gap\n", "G := List([1..5],i->g^i);" ] }, { "cell_type": "markdown", "id": "834df032-3b9e-4a5b-b779-c048b5483735", "metadata": {}, "source": [ "`pc` stands for polycyclic." ] }, { "cell_type": "markdown", "id": "b41e11db-5a24-4751-9f3d-42a8da48f658", "metadata": {}, "source": [ "We can use `CyclicGroup` to make groups\n", "with a prescribed number of elements:" ] }, { "cell_type": "code", "execution_count": 38, "id": "812f8330-47ef-4bed-9985-cf45ed2c2d7a", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "c4 := CyclicGroup(4)" ] }, { "cell_type": "code", "execution_count": 39, "id": "8490c228-6aa4-4e57-9c23-4d140bcf84bf", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ f1, f2 ]\n" ] } ], "source": [ "%%gap\n", "g := GeneratorsOfGroup(c4)" ] }, { "cell_type": "code", "execution_count": 40, "id": "a82d0b97-7900-4590-b8ad-183bc2ecefcf", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "f1\n", "f2\n" ] } ], "source": [ "%%gap\n", "a := g[1]; b := g[2];" ] }, { "cell_type": "code", "execution_count": 41, "id": "7e11c0bf-aea2-41eb-b7b4-1b071659561b", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1, f1, f2, f1*f2 ]\n" ] } ], "source": [ "%%gap\n", "L := [ 1, a, b, a*b ]" ] }, { "cell_type": "code", "execution_count": 42, "id": "46f164be-b0a9-428d-9d88-0d7add626e04", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " of ...\n" ] } ], "source": [ "%%gap\n", "a*b*a" ] }, { "cell_type": "code", "execution_count": 43, "id": "60edd838-97a4-456c-b212-a7eff8b4742b", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " of ...\n" ] } ], "source": [ "%%gap\n", "b*b" ] }, { "cell_type": "code", "execution_count": 44, "id": "2f3da5ec-2fbb-4767-9624-dbbb51747bf6", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "f2\n" ] } ], "source": [ "%%gap \n", "(a*b)*(a*b)" ] }, { "cell_type": "markdown", "id": "886f4d63-d779-467d-81c8-2fbb521d74a3", "metadata": {}, "source": [ "The command CyclicGroup() in GAP generates `pc`\n", "or polycyclic groups which may have more than one generator.\n", "\n", "To make a group with one generator, one can work in GAP as follows:" ] }, { "cell_type": "code", "execution_count": 45, "id": "0713a791-b888-438f-b6ec-37c4c633519b", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap \n", "f := FreeGroup(\"x\")" ] }, { "cell_type": "code", "execution_count": 46, "id": "605f54da-7759-4265-8503-a07b2c6a6460", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ x ]\n" ] } ], "source": [ "%%gap\n", "g := GeneratorsOfGroup(f)" ] }, { "cell_type": "code", "execution_count": 47, "id": "4e3e13bb-cb13-46e2-80df-e2f0f290475b", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x\n" ] } ], "source": [ "%%gap\n", "x := g[1]" ] }, { "cell_type": "code", "execution_count": 48, "id": "efc72a10-8f50-4547-aaf5-7e55bbfda094", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ x^4 ]\n" ] } ], "source": [ "%%gap \n", "relation := [ x^4 ]" ] }, { "cell_type": "code", "execution_count": 49, "id": "8019682a-2ddd-418c-80dc-6f5b804c70f4", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "G := f/relation" ] }, { "cell_type": "code", "execution_count": 50, "id": "036b9495-1726-4d0c-b255-fc363ce66a38", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n" ] } ], "source": [ "%%gap\n", "Size(G)" ] }, { "cell_type": "code", "execution_count": 51, "id": "65f294db-43d3-4984-a2ea-c97c0213d387", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ (), (1,2,3), (1,3,2), (2,3) ]\n" ] } ], "source": [ "%%gap \n", "L := List([1..Size(G)], i->e[i])" ] }, { "cell_type": "markdown", "id": "a61f25cb-df41-47be-bae4-d2e86cfd0901", "metadata": {}, "source": [ "The dihedral group of order $2n$ consists of the\n", "isometries of a regular $n$-gon: \n", " \n", "1. the $n$ rotations through angles $2 \\pi k/n$; and\n", "\n", "2. $n$ reflections about lines through the center and either through a vertex\n", "or bisecting an edge." ] }, { "cell_type": "code", "execution_count": 52, "id": "40e3677f-84b2-4f8d-9013-58b66f6c2930", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "d := DihedralGroup(10)" ] }, { "cell_type": "code", "execution_count": 53, "id": "0f27491e-74a9-4c76-94f9-924efa079789", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap \n", "e := Enumerator(d)" ] }, { "cell_type": "code", "execution_count": 54, "id": "e454d9c8-b67c-4c2f-82b5-d855a85403fa", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n" ] } ], "source": [ "%%gap \n", "Size(d)" ] }, { "cell_type": "code", "execution_count": 55, "id": "9dcd638e-c035-4093-b517-a2f0e2070cb1", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ of ..., f2, f2^2, f2^3, f2^4, f1, f1*f2, f1*f2^2, f1*f2^3, \n", " f1*f2^4 ]\n" ] } ], "source": [ "%%gap\n", "L := List([1..Size(d)],i->e[i])" ] }, { "cell_type": "code", "execution_count": 56, "id": "566f9f55-415b-4719-9795-ff396f81c365", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ f1, f2 ]\n" ] } ], "source": [ "%%gap\n", "GeneratorsOfGroup(d)" ] }, { "cell_type": "markdown", "id": "8ec542bc-6b75-4e8d-a56e-dbf4f1b5d84d", "metadata": {}, "source": [ "A subset of the generators of a group~$G$\n", "generates a subgroup of $G$:" ] }, { "cell_type": "code", "execution_count": 57, "id": "ca14d3d1-23fc-40b7-91b8-cb967d1bf601", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "d := DihedralGroup(10)" ] }, { "cell_type": "code", "execution_count": 58, "id": "f3564cde-d38e-4c1d-8275-8153033ce25b", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ f1, f2 ]\n" ] } ], "source": [ "%%gap\n", "g := GeneratorsOfGroup(d)" ] }, { "cell_type": "code", "execution_count": 59, "id": "66710a0e-a1d4-4413-89e7-1955fb771077", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "s := Group(g[1])" ] }, { "cell_type": "code", "execution_count": 60, "id": "e2885bc5-5efb-41e4-9860-dde3a88c30c2", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "true\n" ] } ], "source": [ "%%gap\n", "IsSubgroup(d,s)" ] }, { "cell_type": "markdown", "id": "583a839f-a88b-45f1-8ebf-a33f24a7f9cf", "metadata": {}, "source": [ "## 3.3 Algebraic Numbers" ] }, { "cell_type": "markdown", "id": "56c513ed-b035-4a08-82fb-c09e1f3ed236", "metadata": {}, "source": [ "We consider an irreducible polynomial $f$ with rational coefficients." ] }, { "cell_type": "code", "execution_count": 61, "id": "1ea15986-de0c-4d72-ba11-700fa39cd208", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x\n" ] } ], "source": [ "%%gap\n", "x := Indeterminate(Rationals,\"x\");" ] }, { "cell_type": "code", "execution_count": 62, "id": "5ef5758d-0dc3-4859-9e99-3f8dbed810a1", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x^3+2*x^2+1\n" ] } ], "source": [ "%%gap \n", "f := x^3 + 2*x^2 + 1;" ] }, { "cell_type": "code", "execution_count": 63, "id": "93a48ed4-c1c1-4a46-9233-a8b14bcd31a2", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "true\n" ] } ], "source": [ "%%gap\n", "IsIrreducible(f);" ] }, { "cell_type": "code", "execution_count": 64, "id": "80a59a53-3e47-4111-b691-a4db8db0c9de", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "F := AlgebraicExtension(Rationals,f);" ] }, { "cell_type": "code", "execution_count": 65, "id": "a98b5815-74a5-46f1-8bbd-40d6db161a19", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a\n" ] } ], "source": [ "%%gap\n", "a := RootOfDefiningPolynomial(F);" ] }, { "cell_type": "code", "execution_count": 66, "id": "b3d33e25-32ee-4797-a674-3407301faa0f", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-2*a^2-1\n" ] } ], "source": [ "%%gap\n", "a^3" ] }, { "cell_type": "markdown", "id": "f0eb0e54-093a-4ed1-9446-ede9f6bf43ae", "metadata": {}, "source": [ "The extension of the field of rational numbers $\\mathbb Q$ with\n", "a root $a$ of $f$ is denoted by ${\\mathbb Q}(a)$.\n", "Because $a$ is a root of $f = x^3 + 2 x^2 + 1$,\n", "we have $a^2 = -2 a^2 - 1$ and ${\\mathbb Q}(a)$ consists of elements\n", "of the form $q_0 + q_1 a + q_2 a^2$, for $q_0,q_1,q_2 \\in {\\mathbb Q}$." ] }, { "cell_type": "markdown", "id": "b5f5ac18-6e6b-4833-8524-da1b91118c75", "metadata": {}, "source": [ "We started with $f = x^3 + 2 x^2 + 1 \\in {\\mathbb Q}[x]$\n", "and added to $\\mathbb Q$ a root $a$ of $f$ to define ${\\mathbb Q}(a)$.\n", "The polynomial $f$ is now reducible over ${\\mathbb Q}(a)$:" ] }, { "cell_type": "code", "execution_count": 67, "id": "66e9df42-460a-42a8-b787-4a696e2fa9ca", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "y\n" ] } ], "source": [ "%%gap \n", "y := Indeterminate(F,\"y\")" ] }, { "cell_type": "code", "execution_count": 68, "id": "44925353-5850-4488-90eb-0b4af150d2b2", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "y^3+!2*y^2+!1\n" ] } ], "source": [ "%%gap\n", "g := y^3 + 2*y^2 + 1" ] }, { "cell_type": "code", "execution_count": 69, "id": "60a413da-9c6c-4ad8-a97c-857d718022e7", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ y+(-a), y^2+(a+2)*y+(a^2+2*a) ]\n" ] } ], "source": [ "%%gap \n", "Factors(g)" ] }, { "cell_type": "markdown", "id": "3a428b47-de66-48fc-a8af-86253fc10835", "metadata": {}, "source": [ "We defined $g = y^3 + 2 y^2 + 1 \\in {\\mathbb Q}(a)[y]$.\n", "Over ${\\mathbb Q}(a)$: $g = (y-a)(y^2 + (a+2)y + (a^2+2a))$." ] }, { "cell_type": "markdown", "id": "3d474108-15c6-46d5-8ee5-7c51bb142535", "metadata": {}, "source": [ "# 4. Rubik's Magic Cube" ] }, { "cell_type": "markdown", "id": "85701781-7fc7-49d3-8350-747d1c8411a8", "metadata": {}, "source": [ "The state of the cube is describe by a permutation on 48 numbers.\n", "\n", "Turning the front face is described by the permutation\n", "\n", "$(17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11)$\n", "\n", "which consist of 5 cycles, with meaning\n", "\n", "$$\n", "\\begin{array}{rcl}\n", "(17,19,24,22) & : & 17 \\mapsto 19 \\mapsto 24 \\mapsto 22 \\mapsto 17, \\\\\n", "(18,21,23,20) & : & 18 \\mapsto 21 \\mapsto 23 \\mapsto 20 \\mapsto 18, \\\\\n", "(6,25,43,16) & : & 6 \\mapsto 25 \\mapsto 43 \\mapsto 16 \\mapsto 6, \\\\\n", "(7,28,42,13) & : & 7 \\mapsto 28 \\mapsto 42 \\mapsto 13 \\mapsto 7, \\\\\n", "(8,30,41,11) & : & 8 \\mapsto 30 \\mapsto 41 \\mapsto 11 \\mapsto 8.\n", "\\end{array}\n", "$$\n", "\n", "Turning top, left, right, rear, and bottom are defined by\n", "\n", "\n", "$( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19)$,\n", "\n", "$( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35)$,\n", "\n", "$(25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24)$,\n", "\n", "$(33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27)$, and\n", "\n", "$(41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40)$." ] }, { "cell_type": "markdown", "id": "e92d3c82-adc2-4fd6-b445-9a3d57eb58bc", "metadata": {}, "source": [ "Following the example by Martin Sch\\\"{o}nert at\n", "\n", "`http://www.gap-system.org/Doc/Examples/rubik.html`:" ] }, { "cell_type": "code", "execution_count": 70, "id": "c25d5243-a840-46f0-b840-44e1a50944a9", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap\n", "cube := Group(\n", " ( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)\n", " (10,34,26,18)(11,35,27,19),\n", " ( 9,11,16,14)(10,13,15,12)( 1,17,41,40)\n", " ( 4,20,44,37)( 6,22,46,35),\n", " (17,19,24,22)(18,21,23,20)( 6,25,43,16)\n", " ( 7,28,42,13)( 8,30,41,11),\n", " (25,27,32,30)(26,29,31,28)( 3,38,43,19)\n", " ( 5,36,45,21)( 8,33,48,24),\n", " (33,35,40,38)(34,37,39,36)( 3, 9,46,32)\n", " ( 2,12,47,29)( 1,14,48,27),\n", " (41,43,48,46)(42,45,47,44)(14,22,30,38)\n", " (15,23,31,39)(16,24,32,40) )" ] }, { "cell_type": "markdown", "id": "d5a9e013-9e5e-496a-a75a-d23f983a0b73", "metadata": {}, "source": [ "To get the size of the group:" ] }, { "cell_type": "code", "execution_count": 71, "id": "e7159bd8-0797-48fb-bd1d-0c8e1772d4b8", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "43252003274489856000\n" ] } ], "source": [ "%%gap\n", "Size(cube)" ] }, { "cell_type": "code", "execution_count": 72, "id": "75257e65-e1f4-4fbb-9362-c7ae11c55b25", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 2, 27 ], [ 3, 14 ], [ 5, 3 ], [ 7, 2 ], [ 11, 1 ] ]\n" ] } ], "source": [ "%%gap\n", "Collected(Factors(last))" ] }, { "cell_type": "markdown", "id": "54646368-0ff9-4222-8303-258870baa7ec", "metadata": {}, "source": [ "The last result tells us that the size is $2^{27} 3^{14} 5^3 7^2 11$." ] }, { "cell_type": "markdown", "id": "2f3cf268-f914-4a58-b308-a629e3afb199", "metadata": {}, "source": [ "Let us look at the orbits." ] }, { "cell_type": "code", "execution_count": 73, "id": "f753dc43-3e14-4753-acd2-b0db7d1807e6", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ [ 1, 3, 17, 14, 8, 38, 9, 41, 19, 48, 22, 6, 30, 33, 43, 11, 46, 40, 24, \n", " 27, 25, 35, 16, 32 ], \n", " [ 2, 5, 12, 7, 36, 10, 47, 4, 28, 45, 34, 13, 29, 44, 20, 42, 26, 21, 37, \n", " 15, 31, 18, 23, 39 ] ]\n" ] } ], "source": [ "%%gap\n", "orbits := Orbits(cube, [1..48])" ] }, { "cell_type": "markdown", "id": "ab9503ee-9f90-4639-8723-8a104991e7a7", "metadata": {}, "source": [ "The first orbit contains the corner points,\n", "the second orbit contains the points at the edges." ] }, { "cell_type": "markdown", "id": "a557d309-a74c-4488-b93f-fb2836cdf8be", "metadata": {}, "source": [ "Clearly, the group cannot move a corner point onto a point at an edge." ] }, { "cell_type": "markdown", "id": "7c7b88aa-38f7-4eef-97e3-eece95cf55be", "metadata": {}, "source": [ "A homomorphism of the free group into the cube group is defined below." ] }, { "cell_type": "code", "execution_count": 74, "id": "4def76ee-186d-4a8d-b1b1-f693c09c83fa", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%gap \n", "G := FreeGroup(\"top\",\"left\",\"front\",\"right\", \"rear\",\"bottom\")" ] }, { "cell_type": "code", "execution_count": 75, "id": "d919f41d-e139-4306-b901-264de8addfc6", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ top, left, front, right, rear, bottom ] -> \n", "[ (1,3,8,6)(2,5,7,4)(9,33,25,17)(10,34,26,18)(11,35,27,19), \n", " (1,17,41,40)(4,20,44,37)(6,22,46,35)(9,11,16,14)(10,13,15,12), \n", " (6,25,43,16)(7,28,42,13)(8,30,41,11)(17,19,24,22)(18,21,23,20), \n", " (3,38,43,19)(5,36,45,21)(8,33,48,24)(25,27,32,30)(26,29,31,28), \n", " (1,14,48,27)(2,12,47,29)(3,9,46,32)(33,35,40,38)(34,37,39,36), \n", " (14,22,30,38)(15,23,31,39)(16,24,32,40)(41,43,48,46)(42,45,47,44) ]\n" ] } ], "source": [ "%%gap\n", "hom := GroupHomomorphismByImages( G, cube,\n", " GeneratorsOfGroup(G), GeneratorsOfGroup(cube) )" ] }, { "cell_type": "markdown", "id": "d52e6130-9141-4ed9-a56b-cf6d1c094252", "metadata": {}, "source": [ "We decompose a random element." ] }, { "cell_type": "code", "execution_count": 76, "id": "a9668171-51d7-4d0e-947c-5232c239d464", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1,43,17,41,46,33,19,32)(2,44,13,37,23,36,39,26,31,34,15,20,12,42,29,47,5,\n", "45)(3,25,48,35,30,6,22,14)(4,28,10,21)(8,38,9,24,11,16,40,27)\n" ] } ], "source": [ "%%gap \n", "r := Random(cube)" ] }, { "cell_type": "code", "execution_count": 77, "id": "67a21aa1-a126-4504-b802-9c33461b62fa", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "rear^-1*top^-1*right*top*rear^-1*right^2*rear*front^2*top^2*bottom^-1*rear^-1*bottom*(front^-1*top)^2*front*bottom*front*bottom^-1*top*front^-1*left*front*top^-1*left*top*left^-1*top^2*left^-1*front^-1*left^-1*front*left*top^-1*front*top^-1*front^-1*top*left^-1*top*left*top*front*top^-1*front^-1*top^-1*left*front*top*front^-1*top^-1*left^-1*top*left^-1*top^-1*rear*left^-1*rear^-1*left*top*left^2*front*top*front^-1*left^-1*top^-1*left^-1*top*rear*left*rear^-1*top^-2*front*top*front^-1*top*left*front*top*front^-1*top^-1*left^-1*front*right*top^-1*right^-1*front^-1*left^-1*top*left\n" ] } ], "source": [ "%%gap\n", "p := PreImagesRepresentative(hom, r)" ] }, { "cell_type": "code", "execution_count": 78, "id": "e682fdff-6858-479d-b0bf-9162d2c4b007", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "97\n" ] } ], "source": [ "%%gap\n", "Length( last )" ] }, { "cell_type": "markdown", "id": "9e6421da-5971-4a6b-a838-167295306ad2", "metadata": {}, "source": [ "Now, verifying that the decomposition is correct..." ] }, { "cell_type": "code", "execution_count": 79, "id": "b4c1ce7e-dd60-4a60-a0b2-4e45c2fff4c4", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1,43,17,41,46,33,19,32)(2,44,13,37,23,36,39,26,31,34,15,20,12,42,29,47,5,\n", "45)(3,25,48,35,30,6,22,14)(4,28,10,21)(8,38,9,24,11,16,40,27)\n" ] } ], "source": [ "%%gap\n", "Image( hom, p)" ] }, { "cell_type": "code", "execution_count": 80, "id": "ce688daa-2f37-4b8f-845b-4ebab5412dec", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1,43,17,41,46,33,19,32)(2,44,13,37,23,36,39,26,31,34,15,20,12,42,29,47,5,\n", "45)(3,25,48,35,30,6,22,14)(4,28,10,21)(8,38,9,24,11,16,40,27)\n" ] } ], "source": [ "%%gap\n", "r" ] }, { "cell_type": "code", "execution_count": 81, "id": "6473b13e-b9b7-48bf-9ccd-bc8ac65ff95e", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "true\n" ] } ], "source": [ "%%gap\n", "last = r" ] } ], "metadata": { "kernelspec": { "display_name": "SageMath 9.5", "language": "sage", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 5 }