From def48b8d263217ce47c4b1c78c8508af3f545ea2 Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Tue, 17 Jan 2017 09:09:45 +0000 Subject: [PATCH 1/7] Fix IPYNB_DST --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c02b5bc..d9a876b 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ RMD_DST = $(patsubst _episodes_rmd/%.Rmd,_episodes/%.md,$(RMD_SRC)) # RMarkdown files IPYNB_SRC = $(wildcard _episodes_ipynb/??-*.ipynb) -IPYNB_DST = $(patsubst _episodes_ipynb/%.ipynb,_episodes/%.ipynb,$(RMD_SRC)) +IPYNB_DST = $(patsubst _episodes_ipynb/%.ipynb,_episodes/%.ipynb,$(IPYNB_SRC)) # Lesson source files in the order they appear in the navigation menu. MARKDOWN_SRC = \ From 20f972e9166adf1604e460eb6c2cc94b9470a9ff Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Tue, 17 Jan 2017 09:10:14 +0000 Subject: [PATCH 2/7] Add IPYNB_SRC and IPYNB_DST on debug list --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index d9a876b..cd8ea31 100644 --- a/Makefile +++ b/Makefile @@ -112,6 +112,8 @@ unittest : lesson-files : @echo 'RMD_SRC:' ${RMD_SRC} @echo 'RMD_DST:' ${RMD_DST} + @echo 'IPYNB_SRC:' ${IPYNB_SRC} + @echo 'IPYNB_DST:' ${IPYNB_DST} @echo 'MARKDOWN_SRC:' ${MARKDOWN_SRC} @echo 'HTML_DST:' ${HTML_DST} From a499bde0c73195638756abb50a2c8bc05d5006f8 Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Tue, 17 Jan 2017 09:10:46 +0000 Subject: [PATCH 3/7] Make lesson-ipynb an dependence of serve --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cd8ea31..31fa847 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ commands : @grep -h -E '^##' ${MAKEFILES} | sed -e 's/## //g' ## serve : run a local server. -serve : lesson-rmd +serve : lesson-rmd lesson-ipynb ${JEKYLL} serve ## site : build files but do not run a server. From 178a7dce6d78a3a7c5cbe10be07f0c7c786fb2ba Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Tue, 17 Jan 2017 09:11:05 +0000 Subject: [PATCH 4/7] Fix documentation text --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 31fa847..23ce5e0 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ HTML_DST = \ lesson-rmd: $(RMD_SRC) @bin/knit_lessons.sh $(RMD_SRC) -## lesson-ipynb : convert IPython Notebook files to markdown +## lesson-ipynb : convert IPython Notebook files to markdown lesson-ipynb: $(IPYNB_SRC) ${SAGE} -sh -c "jupyter nbconvert -y --execute --allow-errors --to markdown --output-dir=_episodes --template=_layouts/ipynb2md.tpl $(IPYNB_SRC)" From c87b2e8cbac637d1ced066e2b9d15597cff01702 Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Wed, 18 Jan 2017 23:31:06 +0000 Subject: [PATCH 5/7] Document work around for challenges and examples --- _config.yml | 3 + _episodes/02-objects.md | 64 +++++++++------ _episodes/02-objects_files/02-objects_5_0.png | Bin 26406 -> 26811 bytes _episodes_ipynb/02-objects.ipynb | 74 +++++++++++++----- _layouts/ipynb2md.tpl | 8 +- 5 files changed, 104 insertions(+), 45 deletions(-) diff --git a/_config.yml b/_config.yml index d09e731..b4c8e4b 100644 --- a/_config.yml +++ b/_config.yml @@ -67,3 +67,6 @@ exclude: # Turn off built-in syntax highlighting. highlighter: false + +kramdown: + parse_block_html: true diff --git a/_episodes/02-objects.md b/_episodes/02-objects.md index f15aeb2..d478fd0 100644 --- a/_episodes/02-objects.md +++ b/_episodes/02-objects.md @@ -19,8 +19,10 @@ include chunk for codes, just like you'd normally do. - - 2 +~~~ +2 +~~~ +{: .output} Output with error message: @@ -50,27 +52,43 @@ plot(sin, (0,10)) - ![png](../02-objects_files/02-objects_5_0.png) -For the challenges and their solutions, you need to pay attention to where the -`>` go and where to leave blank lines. You can include code chunks in both the -instructions and solutions. For instance this: - -> ## Challenge: Can you do it? -> -> What is the output of this command? -> -> ~~~ -> "a" + "b" -> ~~~ -> {: .source} -> -> > ## Solution -> > -> > ~~~ -> > ab -> > ~~~ -> {: .solution} -{: .challenge} +For the challenges +you need to pay attention to include `
` +before it and `<\blockquote>` after it. +And for the solutions +you need to pay attention to include `
` +before it and `<\blockquote>` after it. +**This hacks is necessary for allow include Jupyter cells on challenges and solutions.** +
+## Challenge: Can you do it? + +What is the output of this command? + +~~~ +"a" + "b" +~~~ +{: .source} + +
+ +## Solution + + +~~~ +"a" + "b" +~~~ +{: .source .python} + + + +~~~ +'ab' +~~~ +{: .output} + + +
+
diff --git a/_episodes/02-objects_files/02-objects_5_0.png b/_episodes/02-objects_files/02-objects_5_0.png index a764cf7f0caa97a2a86af669421ad2befd3e45ce..ff203a3c0a4f0800169e5cb581dfa034f02d600c 100644 GIT binary patch literal 26811 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 diff --git a/_episodes_ipynb/02-objects.ipynb b/_episodes_ipynb/02-objects.ipynb index 7efa61f..5ad9033 100644 --- a/_episodes_ipynb/02-objects.ipynb +++ b/_episodes_ipynb/02-objects.ipynb @@ -104,26 +104,62 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "For the challenges and their solutions, you need to pay attention to where the\n", - "`>` go and where to leave blank lines. You can include code chunks in both the\n", - "instructions and solutions. For instance this:\n", + "For the challenges\n", + "you need to pay attention to include `
`\n", + "before it and `<\\blockquote>` after it.\n", + "And for the solutions\n", + "you need to pay attention to include `
`\n", + "before it and `<\\blockquote>` after it.\n", + "**This hacks is necessary for allow include Jupyter cells on challenges and solutions.**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "## Challenge: Can you do it?\n", + "\n", + "What is the output of this command?\n", + "\n", + "~~~\n", + "\"a\" + \"b\"\n", + "~~~\n", + "{: .source}\n", + "\n", + "
\n", "\n", - "> ## Challenge: Can you do it?\n", - ">\n", - "> What is the output of this command?\n", - ">\n", - "> ~~~\n", - "> \"a\" + \"b\"\n", - "> ~~~\n", - "> {: .source}\n", - ">\n", - "> > ## Solution\n", - "> >\n", - "> > ~~~\n", - "> > ab\n", - "> > ~~~\n", - "> {: .solution}\n", - "{: .challenge}" + "## Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'ab'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"a\" + \"b\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
" ] } ], diff --git a/_layouts/ipynb2md.tpl b/_layouts/ipynb2md.tpl index 5822b4d..805dc2b 100644 --- a/_layouts/ipynb2md.tpl +++ b/_layouts/ipynb2md.tpl @@ -26,7 +26,6 @@ {% endblock traceback_line %} {% block execute_result %} - {% block data_priority scoped %} {{ super() }} {% endblock %} @@ -34,7 +33,7 @@ {% block stream %} ~~~ -{{ output.text | indent }} +{{ output.text }} ~~~ {: .output} {% endblock stream %} @@ -64,7 +63,10 @@ {% endblock data_markdown %} {% block data_text scoped %} -{{ output.data['text/plain'] | indent }} +~~~ +{{ output.data['text/plain'] }} +~~~ +{: .output} {% endblock data_text %} {%- block markdowncell scoped -%} From 0708456053cb6c22de22670f5302a34baf5359c5 Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Thu, 19 Jan 2017 12:41:07 +0000 Subject: [PATCH 6/7] Add some IPython notebook files --- ...02-objects.ipynb => 01-introduction.ipynb} | 28 +- .../02-multiply-matrix-and-vector.ipynb | 292 ++++++ _episodes_ipynb/03-matrix-group.ipynb | 253 +++++ _episodes_ipynb/04-more-matrix-groups.ipynb | 945 ++++++++++++++++++ _episodes_ipynb/06-rotational-subgroup.ipynb | 111 ++ _episodes_ipynb/07-orbits.ipynb | 121 +++ _episodes_ipynb/08-polytopes.ipynb | 96 ++ _episodes_ipynb/09-idd.ipynb | 64 ++ _episodes_ipynb/10-conjugacy-classes.ipynb | 59 ++ ...sions-of-irreducible-representations.ipynb | 40 + _episodes_ipynb/12-pymol-visualisation.ipynb | 79 ++ _episodes_ipynb/13-cartan-matrix.ipynb | 180 ++++ 12 files changed, 2265 insertions(+), 3 deletions(-) rename _episodes_ipynb/{02-objects.ipynb => 01-introduction.ipynb} (98%) create mode 100644 _episodes_ipynb/02-multiply-matrix-and-vector.ipynb create mode 100644 _episodes_ipynb/03-matrix-group.ipynb create mode 100644 _episodes_ipynb/04-more-matrix-groups.ipynb create mode 100644 _episodes_ipynb/06-rotational-subgroup.ipynb create mode 100644 _episodes_ipynb/07-orbits.ipynb create mode 100644 _episodes_ipynb/08-polytopes.ipynb create mode 100644 _episodes_ipynb/09-idd.ipynb create mode 100644 _episodes_ipynb/10-conjugacy-classes.ipynb create mode 100644 _episodes_ipynb/11-number-and-dimensions-of-irreducible-representations.ipynb create mode 100644 _episodes_ipynb/12-pymol-visualisation.ipynb create mode 100644 _episodes_ipynb/13-cartan-matrix.ipynb diff --git a/_episodes_ipynb/02-objects.ipynb b/_episodes_ipynb/01-introduction.ipynb similarity index 98% rename from _episodes_ipynb/02-objects.ipynb rename to _episodes_ipynb/01-introduction.ipynb index 5ad9033..f5f1402 100644 --- a/_episodes_ipynb/02-objects.ipynb +++ b/_episodes_ipynb/01-introduction.ipynb @@ -5,7 +5,7 @@ "metadata": {}, "source": [ "---\n", - "title: Objects\n", + "title: First session with SageMath\n", "teaching: 30\n", "exercises: 0\n", "questions:\n", @@ -14,8 +14,7 @@ "- \"...\"\n", "---\n", "\n", - "The rest of the lesson should be written as a normal RMarkdown file. You can\n", - "include chunk for codes, just like you'd normally do." + "Lesson text\n" ] }, { @@ -40,6 +39,29 @@ "1 + 1" ] }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[ -2 1]\n", + "[ 3/2 -1/2]" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matrix([[1,2], [3,4]])^(-1)" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/_episodes_ipynb/02-multiply-matrix-and-vector.ipynb b/_episodes_ipynb/02-multiply-matrix-and-vector.ipynb new file mode 100644 index 0000000..4a3ef3d --- /dev/null +++ b/_episodes_ipynb/02-multiply-matrix-and-vector.ipynb @@ -0,0 +1,292 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Multiply a matrix and a vector\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us define the 3 x 3 minus-identity matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A = matrix([[-1,0,0], [0,-1,0], [0,0,-1]])\n", + "A" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Or simply" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A = -identity_matrix(3)\n", + "A" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define vector `v` to be the vector with coordinates `x`, `y`, `z`" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'y' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvector\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mz\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'y' is not defined" + ] + } + ], + "source": [ + "v = vector([x, y, z])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Didn't work... We need to define `y` (and `z`) as symbolic variables. Only `x` is defined by default when you launch Sage!" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x, y, z = SR.var(\"x y z\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(x, y, z)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v = vector([x, y, z])\n", + "v" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Multiply matrix and vector using `*`" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(-x, -y, -z)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A * v" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, 0, 3)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v.subs(x=1, y=0, z=3)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(-1, 0, -3)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A * v.subs(x=1, y=0, z=3)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(-x, -y, -z)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "A * v" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(-1, 0, -3)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "_.subs(x=1, y=0, z=3)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/03-matrix-group.ipynb b/_episodes_ipynb/03-matrix-group.ipynb new file mode 100644 index 0000000..9b54306 --- /dev/null +++ b/_episodes_ipynb/03-matrix-group.ipynb @@ -0,0 +1,253 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Matrix Group Closure\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---\n", + "\n", + "Multiply together till you achieve closure (of the group)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "([1 0 0]\n", + "[0 1 0]\n", + "[0 0 1], 2)\n", + "(0, 2)\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "(1, 1)\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n" + ] + } + ], + "source": [ + "count = 1\n", + "\n", + "g = [A]\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + " \n", + "# don't do this till later\n", + "I3 = identity_matrix(3) \n", + "tmp = identity_matrix(3)\n", + "for i in range(count):\n", + " for j in range(10):\n", + " tmp = tmp * g[i]\n", + " if (tmp - I3).norm().abs() < 0.01:\n", + " print(i,j+1)\n", + " print(g[i]^(j+1)) # comment out or assert \n", + " break\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Find the inverses to the group elements" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1]\n", + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n" + ] + } + ], + "source": [ + "I3 = identity_matrix(3)\n", + "\n", + "g_inverse = []\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " if (I3-g[i]*g[j])<0.01:\n", + " g_inverse.append(g[j])\n", + "\n", + "for i in range(count):\n", + " print (g[i])\n", + " print (g_inverse[i])\n", + " print (g[i]*g_inverse[i])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## From reflection formula find matrix?\n", + "\n", + "for x'=x-2x_parallel=x-2(x.n)n/(n.n), resolve for components x=(x1, x2, x3) and n=(n1, n2, n3) find 3x3 matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# TODO: n-dimensional case\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def reflection_matrix(v, normalize=True):\n", + " \"\"\"\n", + " Return the reflection matrix to the plane with normal vector v\n", + " \n", + " INPUT:\n", + " \n", + " - ``v`` -- vector or any iterable that can be turned into a vector\n", + " - ``normalize`` -- boolean (default: True)\n", + " \n", + " If ``normalize`` is ``False``, assume the vector is a unit vector and avoid normalizing.\n", + "\n", + " EXAMPLE:\n", + " \n", + " sage: a, b, c = SR.var(\"a b c\")\n", + " sage: A = reflection_matrix((a, b, c))\n", + " sage: A\n", + " [-a^2 + b^2 + c^2 -2*a*b -2*a*c]\n", + " [ -2*a*b a^2 - b^2 + c^2 -2*b*c]\n", + " [ -2*a*c -2*b*c a^2 + b^2 - c^2]\n", + " \"\"\"\n", + " v = vector(v)\n", + " m = matrix(v)\n", + " n = len(v)\n", + " R = v.base_ring()\n", + " if normalize:\n", + " return (identity_matrix(n) - 2/v.dot_product(v) * m.transpose() * m)\n", + " return (v.dot_product(v) * identity_matrix(n) - 2 * m.transpose() * m)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[-2*n1^2/(n1^2 + n2^2 + n3^2) + 1 -2*n1*n2/(n1^2 + n2^2 + n3^2) -2*n1*n3/(n1^2 + n2^2 + n3^2)]\n", + "[ -2*n1*n2/(n1^2 + n2^2 + n3^2) -2*n2^2/(n1^2 + n2^2 + n3^2) + 1 -2*n2*n3/(n1^2 + n2^2 + n3^2)]\n", + "[ -2*n1*n3/(n1^2 + n2^2 + n3^2) -2*n2*n3/(n1^2 + n2^2 + n3^2) -2*n3^2/(n1^2 + n2^2 + n3^2) + 1]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n1, n2, n3 = SR.var(\"n1 n2 n3\")\n", + "\n", + "A=reflection_matrix([n1, n2, n3])\n", + "\n", + "A" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "r = reflection_matrix\n", + "a, b, c = r((1, 0, 0)), r((-1/4*(1+sqrt(5)), -1/2, -1/4*(1-sqrt(5)))), r((0, 0, 1))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/04-more-matrix-groups.ipynb b/_episodes_ipynb/04-more-matrix-groups.ipynb new file mode 100644 index 0000000..eecf597 --- /dev/null +++ b/_episodes_ipynb/04-more-matrix-groups.ipynb @@ -0,0 +1,945 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Matrix Groups\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---\n", + "\n", + "Matrix groups involves $A1^3$, $A3$, $H3$.\n", + "\n", + "with Episode 5 - order of group, order of elements, inverses, traces, determinants" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A1^3 here: sub in simple roots into the general reflection formula above, then generate the group\n", + "\n", + "$A_1^3$: $\\alpha_1=(1,0,0)^T, \\alpha_2=(0,1,0)^T, \\alpha_3=(0,0,1)^T$\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "([1 0 0]\n", + "[0 1 0]\n", + "[0 0 1], 4)\n", + "([-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1], 5)\n", + "([-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1], 6)\n", + "([ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1], 7)\n", + "([-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1], 8)\n", + "(-1, 1, 1)\n", + "(-1, 1, 1)\n", + "(-1, 1, 1)\n", + "(1, 3, 0)\n", + "(1, -1, 1)\n", + "(1, -1, 1)\n", + "(1, -1, 1)\n", + "(-1, -3, 1)\n" + ] + } + ], + "source": [ + "g=[]\n", + "count=3\n", + "g.append(reflection_matrix([1, 0, 0]))\n", + "g.append(reflection_matrix([0, 1, 0]))\n", + "g.append(reflection_matrix([0, 0, 1]))\n", + "\n", + "g\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "\n", + "I3 = identity_matrix(3)\n", + "\n", + "g_inverse = []\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " if (I3-g[i]*g[j])<0.01:\n", + " g_inverse.append(g[j])\n", + "\n", + "I3 = identity_matrix(3) \n", + "tmp = identity_matrix(3)\n", + "for i in range(count):\n", + " for j in range(10):\n", + " tmp = tmp * g[i]\n", + " if (tmp - I3).norm().abs() < 0.01:\n", + " break\n", + " print(g[i].determinant(), g[i].trace(), j)\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('coset', 0, 0)\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 1]\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 1]\n", + "('coset', 0, 1)\n", + "[ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1]\n", + "[ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1]\n", + "('coset', 0, 2)\n", + "[ 1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "[ 1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "('coset', 0, 3)\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "('coset', 1, 0)\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 1]\n", + "('coset', 1, 1)\n", + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1]\n", + "[ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1]\n", + "('coset', 1, 2)\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "[ 1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "('coset', 1, 3)\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "('coset', 2, 0)\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 1]\n", + "('coset', 2, 1)\n", + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1]\n", + "[ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1]\n", + "('coset', 2, 2)\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "[ 1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "('coset', 2, 3)\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "('coset', 3, 0)\n", + "[ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1]\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 1]\n", + "('coset', 3, 1)\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "[ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1]\n", + "('coset', 3, 2)\n", + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1]\n", + "[ 1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "('coset', 3, 3)\n", + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n" + ] + } + ], + "source": [ + "# bit of conjugacy classes if you fancy - tidy up and do set of sets here?\n", + "\n", + "for i in range(4):\n", + " for j in range(4):\n", + " print(\"coset\", i, j)\n", + " print(g[i] * g[j] * g_inverse[i])\n", + " print(g[j])\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Do A3 next: sub in simple roots into the general reflection formula above, then generate the group\n", + "\n", + "$A_3$: $\\alpha_1=\\frac{1}{\\sqrt{2}}(-1,1,0)^T, \\alpha_2=\\frac{1}{\\sqrt{2}}(0,-1,1)^T, \\alpha_3=\\frac{1}{\\sqrt{2}}(1,1,0)^T$" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "([1 0 0]\n", + "[0 1 0]\n", + "[0 0 1], 4)\n", + "([0 0 1]\n", + "[1 0 0]\n", + "[0 1 0], 5)\n", + "([-1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 1], 6)\n", + "([0 1 0]\n", + "[0 0 1]\n", + "[1 0 0], 7)\n", + "([ 0 -1 0]\n", + "[ 0 0 1]\n", + "[-1 0 0], 8)\n", + "([0 0 1]\n", + "[0 1 0]\n", + "[1 0 0], 9)\n", + "([-1 0 0]\n", + "[ 0 0 1]\n", + "[ 0 -1 0], 10)\n", + "([ 0 0 -1]\n", + "[-1 0 0]\n", + "[ 0 1 0], 11)\n", + "([-1 0 0]\n", + "[ 0 0 -1]\n", + "[ 0 1 0], 12)\n", + "([ 0 0 -1]\n", + "[ 0 -1 0]\n", + "[ 1 0 0], 13)\n", + "([ 0 0 -1]\n", + "[ 0 1 0]\n", + "[-1 0 0], 14)\n", + "([ 0 -1 0]\n", + "[ 0 0 -1]\n", + "[ 1 0 0], 15)\n", + "([ 0 0 -1]\n", + "[ 1 0 0]\n", + "[ 0 -1 0], 16)\n", + "([ 0 0 1]\n", + "[ 0 -1 0]\n", + "[-1 0 0], 17)\n", + "([ 0 0 1]\n", + "[-1 0 0]\n", + "[ 0 -1 0], 18)\n", + "([ 0 1 0]\n", + "[ 0 0 -1]\n", + "[-1 0 0], 19)\n", + "([ 1 0 0]\n", + "[ 0 0 -1]\n", + "[ 0 -1 0], 20)\n", + "([-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1], 21)\n", + "([ 0 -1 0]\n", + "[ 1 0 0]\n", + "[ 0 0 -1], 22)\n", + "([ 0 1 0]\n", + "[-1 0 0]\n", + "[ 0 0 -1], 23)\n", + "([ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1], 24)\n", + "(0, -1, 1, 1)\n", + "(1, -1, 1, 1)\n", + "(2, -1, 1, 1)\n", + "(3, 1, 3, 0)\n", + "(4, 1, 0, 2)\n", + "(5, 1, -1, 1)\n", + "(6, 1, 0, 2)\n", + "(7, 1, 0, 2)\n", + "(8, -1, 1, 1)\n", + "(9, -1, -1, 3)\n", + "(10, 1, 0, 2)\n", + "(11, -1, -1, 3)\n", + "(12, -1, -1, 3)\n", + "(13, -1, 1, 1)\n", + "(14, 1, 0, 2)\n", + "(15, 1, 0, 2)\n", + "(16, -1, -1, 3)\n", + "(17, 1, 0, 2)\n", + "(18, 1, 0, 2)\n", + "(19, -1, 1, 1)\n", + "(20, 1, -1, 1)\n", + "(21, -1, -1, 3)\n", + "(22, -1, -1, 3)\n", + "(23, 1, -1, 1)\n" + ] + } + ], + "source": [ + "K. = NumberField(x^2 - 2, embedding=1.4)\n", + "g=[]\n", + "count=3\n", + "g.append(reflection_matrix([-1/r, 1/r, 0]))\n", + "g.append(reflection_matrix([0, -1/r, 1/r]))\n", + "g.append(reflection_matrix([1/r, 1/r, 0]))\n", + "\n", + "g\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "\n", + "I3 = identity_matrix(3)\n", + "\n", + "g_inverse = []\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " if (I3-g[i]*g[j])<0.01:\n", + " g_inverse.append(g[j])\n", + "\n", + "I3 = identity_matrix(3) \n", + "tmp = identity_matrix(3)\n", + "for i in range(count):\n", + " for j in range(10):\n", + " tmp = tmp * g[i]\n", + " if (tmp - I3).norm().abs() < 0.01:\n", + " break\n", + " print(i, g[i].determinant(), g[i].trace(), j)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('coset', 0, 0)\n", + "[0 1 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "[0 1 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "('coset', 0, 1)\n", + "[0 0 1]\n", + "[0 1 0]\n", + "[1 0 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "[0 1 0]\n", + "('coset', 0, 2)\n", + "[ 0 -1 0]\n", + "[-1 0 0]\n", + "[ 0 0 1]\n", + "[ 0 -1 0]\n", + "[-1 0 0]\n", + "[ 0 0 1]\n", + "('coset', 0, 3)\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "('coset', 1, 0)\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[0 1 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "('coset', 1, 1)\n", + "[0 0 1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "[0 1 0]\n", + "('coset', 1, 2)\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "[ 0 -1 0]\n", + "[-1 0 0]\n", + "[ 0 0 1]\n", + "('coset', 1, 3)\n", + "[0 0 1]\n", + "[0 1 0]\n", + "[1 0 0]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "('coset', 2, 0)\n", + "[ 0 0 1]\n", + "[-1 0 0]\n", + "[ 0 -1 0]\n", + "[0 1 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "('coset', 2, 1)\n", + "[0 1 0]\n", + "[0 0 1]\n", + "[1 0 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "[0 1 0]\n", + "('coset', 2, 2)\n", + "[ 0 0 -1]\n", + "[ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 -1 0]\n", + "[-1 0 0]\n", + "[ 0 0 1]\n", + "('coset', 2, 3)\n", + "[-1 0 0]\n", + "[ 0 0 1]\n", + "[ 0 -1 0]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n", + "('coset', 3, 0)\n", + "[ 1 0 0]\n", + "[ 0 -1 0]\n", + "[ 0 0 -1]\n", + "[0 1 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "('coset', 3, 1)\n", + "[ 0 -1 0]\n", + "[ 0 0 -1]\n", + "[ 1 0 0]\n", + "[1 0 0]\n", + "[0 0 1]\n", + "[0 1 0]\n", + "('coset', 3, 2)\n", + "[-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1]\n", + "[ 0 -1 0]\n", + "[-1 0 0]\n", + "[ 0 0 1]\n", + "('coset', 3, 3)\n", + "[ 0 -1 0]\n", + "[ 1 0 0]\n", + "[ 0 0 -1]\n", + "[1 0 0]\n", + "[0 1 0]\n", + "[0 0 1]\n" + ] + } + ], + "source": [ + "# bit of conjugacy classes if you fancy\n", + "\n", + "for i in range(4):\n", + " for j in range(4):\n", + " print(\"coset\", i, j)\n", + " print(g[i] * g[j] * g_inverse[i])\n", + " print(g[j])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Do H3 next: sub in simple roots into the general reflection formula above, then generate the group\n", + "\n", + "$H_3$: $\\alpha_1=(0,1,0)^T, \\alpha_2=-\\frac{1}{2}(\\tau,1,(\\tau-1))^T, \\alpha_3=(0,0,1)^T$\n", + "\n", + "$\\tau$ is the golden ratio $\\tau = \\frac{1}{2}(1+\\sqrt{5})\\sim 1.618$ and satisfies the relation $\\tau^2=\\tau+1$.\n", + "\n", + "\n", + "You will need to modify the two earlier examples to either deal with $\\tau$ numerically (i.e. to within a certain error) or via the recursion relation. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false, + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "([1 0 0]\n", + "[0 1 0]\n", + "[0 0 1], 4)\n", + "([ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 -1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 1/4*sqrt(5) - 1/4]\n", + "[ 1/2 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4], 5)\n", + "([-1 0 0]\n", + "[ 0 1 0]\n", + "[ 0 0 -1], 6)\n", + "([ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 1/4*sqrt(5) - 1/4]\n", + "[ -1/2 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4], 7)\n", + "([-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 -1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4], 8)\n", + "([ 1/4*sqrt(5) + 1/4 -1/2 1/4*sqrt(5) - 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 1/2], 9)\n", + "([ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 -1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4], 10)\n", + "([-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 1/4*sqrt(5) - 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4], 11)\n", + "([ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 -1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 1/4*sqrt(5) - 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4], 12)\n", + "([ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 1/4*sqrt(5) - 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4], 13)\n", + "([-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 -1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4], 14)\n", + "([ 1/4*sqrt(5) + 1/4 -1/2 1/4*sqrt(5) - 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 -1/2], 15)\n", + "([ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 -1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4], 16)\n", + "([-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 -1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 1/4*sqrt(5) - 1/4]\n", + "[ -1/2 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4], 17)\n", + "([ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4], 18)\n", + "([-1/4*sqrt(5) - 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 1/2], 19)\n", + "([-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4], 20)\n", + "([-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 -1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 1/4*sqrt(5) - 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4], 21)\n", + "([ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4], 22)\n", + "([-1/4*sqrt(5) - 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 -1/2], 23)\n", + "([-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4], 24)\n", + "([ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 -1/2]\n", + "[-1/4*sqrt(5) - 1/4 -1/2 -1/4*sqrt(5) + 1/4], 25)\n", + "([ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 -1/2]\n", + "[-1/4*sqrt(5) - 1/4 -1/2 1/4*sqrt(5) - 1/4]\n", + "[ -1/2 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4], 26)\n", + "([ -1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 -1/2]\n", + "[ 1/4*sqrt(5) + 1/4 -1/2 -1/4*sqrt(5) + 1/4], 27)\n", + "([ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 1/2]\n", + "[-1/4*sqrt(5) - 1/4 -1/2 1/4*sqrt(5) - 1/4], 28)\n", + "([ 0 0 -1]\n", + "[-1 0 0]\n", + "[ 0 -1 0], 29)\n", + "([ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 -1/2 1/4*sqrt(5) - 1/4], 30)\n", + "([-1/4*sqrt(5) - 1/4 -1/2 1/4*sqrt(5) - 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 1/2], 31)\n", + "([ 1/4*sqrt(5) + 1/4 -1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 -1/2], 32)\n", + "([ 1/4*sqrt(5) + 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 1/2], 33)\n", + "([-1/4*sqrt(5) - 1/4 -1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 -1/2], 34)\n", + "([-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 -1/2]\n", + "[ 1/4*sqrt(5) + 1/4 -1/2 1/4*sqrt(5) - 1/4]\n", + "[ 1/2 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4], 35)\n", + "([ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[-1/4*sqrt(5) - 1/4 -1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4], 36)\n", + "([ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[-1/4*sqrt(5) - 1/4 -1/2 -1/4*sqrt(5) + 1/4], 37)\n", + "([-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 -1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4], 38)\n", + "([ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 -1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 1/4*sqrt(5) - 1/4], 39)\n", + "([ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 -1/2]\n", + "[-1/4*sqrt(5) - 1/4 -1/2 1/4*sqrt(5) - 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4], 40)\n", + "([ -1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 -1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 1/4*sqrt(5) - 1/4], 41)\n", + "([ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[-1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 -1/4*sqrt(5) + 1/4], 42)\n", + "([ 0 0 -1]\n", + "[-1 0 0]\n", + "[ 0 1 0], 43)\n", + "([ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 1/4*sqrt(5) + 1/4 1/2]\n", + "[-1/4*sqrt(5) - 1/4 1/2 -1/4*sqrt(5) + 1/4], 44)\n", + "([-1/4*sqrt(5) - 1/4 -1/2 1/4*sqrt(5) - 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 -1/2], 45)\n", + "([ 1/4*sqrt(5) + 1/4 -1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 1/2], 46)\n", + "([ 1/4*sqrt(5) + 1/4 1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 -1/2], 47)\n", + "([-1/4*sqrt(5) - 1/4 -1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 1/2], 48)\n", + "([-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 -1/2]\n", + "[ 1/4*sqrt(5) + 1/4 -1/2 1/4*sqrt(5) - 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 1/4*sqrt(5) + 1/4], 49)\n", + "([ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[-1/4*sqrt(5) - 1/4 -1/2 -1/4*sqrt(5) + 1/4]\n", + "[ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4], 50)\n", + "([ 1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4]\n", + "[ 1/4*sqrt(5) - 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 1/2 1/4*sqrt(5) - 1/4], 51)\n", + "([-1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4 1/2]\n", + "[ 1/4*sqrt(5) + 1/4 -1/2 -1/4*sqrt(5) + 1/4]\n", + "[ -1/2 -1/4*sqrt(5) + 1/4 -1/4*sqrt(5) - 1/4], 52)\n" + ] + } + ], + "source": [ + "\n", + "g = []\n", + "count = 3\n", + "\n", + "g.append(reflection_matrix([1, 0, 0]))\n", + "g.append(reflection_matrix([-1/4*(1+sqrt(5)), -1/2, -1/4*(1-sqrt(5))]))\n", + "g.append(reflection_matrix([0, 0, 1]))\n", + "\n", + "# Build g\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = (g[i] * g[j]).apply_map(expand)\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = (g[i] * g[j]).apply_map(expand)\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "\n", + "I3 = identity_matrix(3)\n", + "\n", + "g_inverse = []\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " if (I3-g[i]*g[j])<0.01:\n", + " g_inverse.append(g[j])\n", + "\n", + "I3 = identity_matrix(3) \n", + "tmp = identity_matrix(3)\n", + "for i in range(count):\n", + " for j in range(10):\n", + " tmp = tmp * g[i]\n", + " if (tmp - I3).norm().abs() < 0.01:\n", + " break\n", + " print(i, g[i].determinant(), g[i].trace(), j)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "K5. = NumberField(x^2 - x - 1, embedding=1.6)\n", + "\n", + "g=[]\n", + "count=3\n", + "g.append(reflection_matrix((1, 0, 0)))\n", + "g.append(reflection_matrix((-1/2*a, -1/2, -1/2*(1-a)))\n", + "g.append(reflection_matrix((0, 0, 1)))\n", + "\n", + "g\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "\n", + "I3 = identity_matrix(3)\n", + "\n", + "g_inverse = []\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " if (I3-g[i]*g[j])<0.01:\n", + " g_inverse.append(g[j])\n", + "\n", + "I3 = identity_matrix(3) \n", + "tmp = identity_matrix(3)\n", + "for i in range(count):\n", + " for j in range(10):\n", + " tmp = tmp * g[i]\n", + " if (tmp - I3).norm().abs() < 0.01:\n", + " break\n", + " print(i, g[i].determinant(), g[i].trace(), j+1)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "K. = NumberField(x^2-5)\n", + "\n", + "g=[]\n", + "count=3\n", + "g.append(reflection_matrix((1, 0, 0))\n", + "g.append(reflection_matrix((-1/4*(1+a), -1/2, -1/4*(1-a)))\n", + "g.append(reflection_matrix((0, 0, 1))\n", + "\n", + "g\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " new = True\n", + " tmp = g[i] * g[j]\n", + " for k in range(count):\n", + " if (tmp - g[k]).norm().abs() < 0.01:\n", + " new = False\n", + " if new:\n", + " count += 1\n", + " g.append(tmp)\n", + " print(g[-1], count)\n", + "\n", + "\n", + "I3 = identity_matrix(3)\n", + "\n", + "g_inverse = []\n", + "\n", + "for i in range(count):\n", + " for j in range(count):\n", + " if (I3-g[i]*g[j])<0.01:\n", + " g_inverse.append(g[j])\n", + "\n", + "I3 = identity_matrix(3) \n", + "tmp = identity_matrix(3)\n", + "for i in range(count):\n", + " for j in range(10):\n", + " tmp = tmp * g[i]\n", + " if (tmp - I3).norm().abs() < 0.01:\n", + " break\n", + " print(i, g[i].determinant(), g[i].trace(), j+1)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/06-rotational-subgroup.ipynb b/_episodes_ipynb/06-rotational-subgroup.ipynb new file mode 100644 index 0000000..0bf0ad8 --- /dev/null +++ b/_episodes_ipynb/06-rotational-subgroup.ipynb @@ -0,0 +1,111 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Rotational Subgroup\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "g" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [], + "source": [ + "counteven=0\n", + "g_even = []\n", + "for i in range(count):\n", + " if (((g[i]).determinant()-1).abs() < 0.01):\n", + " counteven += 1\n", + " g_even.append(g[i])\n", + " print(g_even[-1], counteven) #\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "closed = false\n", + "\n", + "for i in range(counteven):\n", + " for j in range(counteven):\n", + "\n", + " tmp = g_even[i] * g_even[j]\n", + " new = true\n", + "\n", + " #create a function that compares to group elements and returns label k if it is contained in the group?\n", + " for k in range(counteven):\n", + " if (tmp - g_even[k]).norm().abs() < 0.01:\n", + " new = false\n", + " break\n", + " \n", + " if new: \n", + " print(\"not closed\")\n", + " closed = false\n", + " break\n", + "\n", + "if closed: \n", + " print (\"closed\")\n", + "\n", + "g_even_inverse = []\n", + "\n", + "#create a function that makes inverses\n", + "for i in range(counteven):\n", + " for j in range(counteven):\n", + " if (I3-g_even[i] * g_even[j])<0.01:\n", + " g_even_inverse.append(g[j])\n", + " print(g_even_inverse[-1]) #\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/07-orbits.ipynb b/_episodes_ipynb/07-orbits.ipynb new file mode 100644 index 0000000..381f43f --- /dev/null +++ b/_episodes_ipynb/07-orbits.ipynb @@ -0,0 +1,121 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Orbits\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---\n", + "\n", + "Make an icosahedron by picking a seed vector on a 5-fold axis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "icosahedron_dupl = []\n", + "T5 = vector([0,1,1.618]) \n", + "seed = T5\n", + "for i in range(counteven):\n", + " icosahedron_dupl.append(g_even[i] * seed)\n", + "\n", + "\n", + "\n", + "# now delete duplicates - do ito golden ratio, or round or convert to set etc\n", + "\n", + "icosahedron_dupl\n", + "\n", + "icosahedron = []\n", + "\n", + "\n", + "# define function take orbit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Make a dodecahedron by picking a seed vector on a 3-fold axis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "dodecahedron = []\n", + "T3 = vector([1,1,1]) \n", + "seed = T3\n", + "for i in range(counteven):\n", + " dodecahedron.append(g_even[i] * seed)\n", + "\n", + "\n", + "\n", + "# now delete duplicates - do ito golden ratio, or round or convert to set etc\n", + "# define function take orbit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Make a icosidodecahedron by picking a seed vector on a 2-fold axis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "icosidodecahedron = []\n", + "T2 = vector([1,0,0]) \n", + "seed = T2\n", + "for i in range(counteven):\n", + " icosidodecahedron.append(g_even[i] * seed)\n", + "\n", + "# plot\n", + "# now delete duplicates - do ito golden ratio, or round or convert to set etc\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/08-polytopes.ipynb b/_episodes_ipynb/08-polytopes.ipynb new file mode 100644 index 0000000..5d5f68c --- /dev/null +++ b/_episodes_ipynb/08-polytopes.ipynb @@ -0,0 +1,96 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Display polytopes\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "point3d(icosahedron, size=100)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "icosahedron=[v.change_ring(RDF) for v in icosahedron]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "P=Polyhedron(icosahedron)\n", + "plot(P)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "point3d(dodecahedron, size=100)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "point3d(icosidodecahedron, size=100)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/09-idd.ipynb b/_episodes_ipynb/09-idd.ipynb new file mode 100644 index 0000000..6496d2f --- /dev/null +++ b/_episodes_ipynb/09-idd.ipynb @@ -0,0 +1,64 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: IDD\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---\n", + "\n", + "Show IDD is a root system." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "IDD=icosidodecahedron\n", + "\n", + "for points in IDD:\n", + " if not (-points in IDD):\n", + " print(\"first axiom violated\")\n", + "\n", + "for points in IDD:\n", + " for refl in IDD:\n", + " tmp = reflection_matrix(refl[1], n2=refl[2], n3=refl[3]) * points\n", + " if not (tmp in IDD):\n", + " print(\"second axiom violated\", tmp)\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/10-conjugacy-classes.ipynb b/_episodes_ipynb/10-conjugacy-classes.ipynb new file mode 100644 index 0000000..f05d35d --- /dev/null +++ b/_episodes_ipynb/10-conjugacy-classes.ipynb @@ -0,0 +1,59 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Conjugacy Classes\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "cc = []\n", + "\n", + "\n", + "\n", + "for i in range(4):\n", + " for j in range(4):\n", + " print(\"coset\", i, j)\n", + " print(g[i] * g[j] * g_inverse[i])\n", + " print(g[j])\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/11-number-and-dimensions-of-irreducible-representations.ipynb b/_episodes_ipynb/11-number-and-dimensions-of-irreducible-representations.ipynb new file mode 100644 index 0000000..63cbbe9 --- /dev/null +++ b/_episodes_ipynb/11-number-and-dimensions-of-irreducible-representations.ipynb @@ -0,0 +1,40 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Number and Dimensions of Irreducible Representations\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/12-pymol-visualisation.ipynb b/_episodes_ipynb/12-pymol-visualisation.ipynb new file mode 100644 index 0000000..1ca7d6c --- /dev/null +++ b/_episodes_ipynb/12-pymol-visualisation.ipynb @@ -0,0 +1,79 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: More advanced Caspar-Klug orbits and pymol visualisation\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[[0.904721509025590, 0.0879675935421300, 0.416822136685000],\n", + " [0.979660168810660, 0.0952540054366200, 0.176614348770000],\n", + " [0.894764055651420, 0.317512115546100, 0.313979842320000],\n", + " [0.986175314321600, 0.165705309322800, 0]]" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "seeds = [[ 0.904721509025590, 0.0879675935421300, 0.416822136685000], \n", + "[0.979660168810660, 0.0952540054366200, 0.176614348770000], \n", + "[0.894764055651420, 0.317512115546100, 0.313979842320000],\n", + "[0.986175314321600, 0.165705309322800, 0]]\n", + "seeds\n", + "\n", + "T4capsid = []\n", + "\n", + "for seed in seeds:\n", + " for i in range(count_even):\n", + " T4capsid.append(g_even[i] * seed)\n", + " \n", + "point3d(T4capsid, size=100)\n", + " \n", + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/_episodes_ipynb/13-cartan-matrix.ipynb b/_episodes_ipynb/13-cartan-matrix.ipynb new file mode 100644 index 0000000..316bc52 --- /dev/null +++ b/_episodes_ipynb/13-cartan-matrix.ipynb @@ -0,0 +1,180 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Cartan matrix and Perron-Frobenius eigenvector\n", + "teaching: 30\n", + "exercises: 0\n", + "questions:\n", + "- \"...\"\n", + "objectives:\n", + "- \"...\"\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# define Cartan matrix - function of arbitrary number of vectors?\n", + "\n", + "# find eigenvalues using SAGE routine\n", + "\n", + "# find the Perron-Frobenius eigenvalue\n", + "\n", + "def Cartan_matrix(Delta, symbolic=False):\n", + " \"\"\"\n", + " Return the Cartan matrix for a simple system\n", + " \n", + " INPUT:\n", + " \n", + " - ``Delta`` -- list of vectors or any iterable that can be turned into a vector\n", + " - \n", + "\n", + " EXAMPLES::\n", + "\n", + " sage: Delta = ((1, 0, 0)), ((0, 1, 0)), ((0, 0, 1))\n", + " sage: C = Cartan_matrix(Delta)\n", + " sage: C\n", + " [2 0 0]\n", + " [0 2 0]\n", + " [0 0 2]\n", + " \"\"\"\n", + " Delta=[vector(v) for v in Delta]\n", + "\n", + " M = matrix([[2 / w.dot_product(w) * v.dot_product(w) for w in Delta] for v in Delta])\n", + " \n", + " if symbolic:\n", + " M = M.apply_map(expand)\n", + " \n", + " return M" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[ 2 -1 0]\n", + "[ -1 2 -1/2*sqrt(5) - 1/2]\n", + "[ 0 -1/2*sqrt(5) - 1/2 2]" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Delta = ((0, 1, 0)), ((-1/4*(1+sqrt(5)), -1/2, 1/4*(1-sqrt(5)))), ((1, 0, 0))\n", + "\n", + "Delta\n", + "\n", + "C = Cartan_matrix(Delta, symbolic=True)\n", + "C" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(-1/2*sqrt(2*sqrt(5) + 10) + 2,\n", + " [(1, 1/2*sqrt(2*sqrt(5) + 10), 1/2*sqrt(5) + 1/2)],\n", + " 1),\n", + " (1/2*sqrt(2*sqrt(5) + 10) + 2,\n", + " [(1, -1/2*sqrt(2*sqrt(5) + 10), 1/2*sqrt(5) + 1/2)],\n", + " 1),\n", + " (2, [(1, 0, -1/2*sqrt(5) + 1/2)], 1)]" + ] + }, + "execution_count": 132, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "E = C.eigenvectors_right()\n", + "E\n", + "\n", + " \n", + "A=QQbar(E[1][1][0][2])\n", + "A\n", + "E" + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 1/2*sqrt(2*sqrt(5) + 10), 1/2*sqrt(5) + 1/2)\n" + ] + } + ], + "source": [ + "# find PF eigenvector i.e. all coefficients of the same sign\n", + "for i in range(3):\n", + " tmp = E[i][1][0]\n", + " if all (x * tmp[0] > 0 for x in tmp):\n", + " print(tmp)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# find duals to roots (weights), construct two vectors from two-colouring of the graph and the PF evec just found; orthonormalise and project root system into this plane\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 7.4", + "language": "", + "name": "sagemath" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} From 5c04bb4fd86c3bce8999ce43c6e4980277aa54c2 Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Thu, 19 Jan 2017 12:43:14 +0000 Subject: [PATCH 7/7] Add compiled files --- _episodes/01-first-session.md | 36 -- .../{02-objects.md => 01-introduction.md} | 26 +- .../01-introduction_5_0.png | Bin 0 -> 26539 bytes .../01-introduction_6_0.png | Bin 0 -> 26619 bytes _episodes/02-multiply-matrix-and-vector.md | 163 +++++++ _episodes/02-objects_files/02-objects_5_0.png | Bin 26811 -> 0 bytes _episodes/03-matrix-group.md | 164 +++++++ _episodes/04-more-matrix-groups.md | 447 ++++++++++++++++++ _episodes/06-rotational-subgroup.md | 90 ++++ _episodes/07-orbits.md | 106 +++++ _episodes/08-polytopes.md | 136 ++++++ _episodes/09-idd.md | 43 ++ _episodes/10-conjugacy-classes.md | 43 ++ ...mensions-of-irreducible-representations.md | 9 + _episodes/12-pymol-visualisation.md | 43 ++ _episodes/13-cartan-matrix.md | 119 +++++ 16 files changed, 1384 insertions(+), 41 deletions(-) delete mode 100644 _episodes/01-first-session.md rename _episodes/{02-objects.md => 01-introduction.md} (81%) create mode 100644 _episodes/01-introduction_files/01-introduction_5_0.png create mode 100644 _episodes/01-introduction_files/01-introduction_6_0.png create mode 100644 _episodes/02-multiply-matrix-and-vector.md delete mode 100644 _episodes/02-objects_files/02-objects_5_0.png create mode 100644 _episodes/03-matrix-group.md create mode 100644 _episodes/04-more-matrix-groups.md create mode 100644 _episodes/06-rotational-subgroup.md create mode 100644 _episodes/07-orbits.md create mode 100644 _episodes/08-polytopes.md create mode 100644 _episodes/09-idd.md create mode 100644 _episodes/10-conjugacy-classes.md create mode 100644 _episodes/11-number-and-dimensions-of-irreducible-representations.md create mode 100644 _episodes/12-pymol-visualisation.md create mode 100644 _episodes/13-cartan-matrix.md diff --git a/_episodes/01-first-session.md b/_episodes/01-first-session.md deleted file mode 100644 index 467ccc5..0000000 --- a/_episodes/01-first-session.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: First session with SageMath -teaching: 30 -exercises: 0 -questions: -- "..." -objectives: -- "..." ---- -> ## Learning Objectives -> -> * ... -{: .objectives} - -Lesson text - -~~~ {.python} -matrix([[1,2], [3,4]])^(-1) -~~~ - -~~~ {.output} -[ -2 1] -[ 3/2 -1/2] -~~~ - -> ## Some question -> -> Also, some other question -{: .callout} - -> ## Set up some challenge -> -> * Task 1 -> -> * Task 2 -{: .challenge} diff --git a/_episodes/02-objects.md b/_episodes/01-introduction.md similarity index 81% rename from _episodes/02-objects.md rename to _episodes/01-introduction.md index d478fd0..be291a2 100644 --- a/_episodes/02-objects.md +++ b/_episodes/01-introduction.md @@ -1,5 +1,5 @@ --- -title: Objects +title: First session with SageMath teaching: 30 exercises: 0 questions: @@ -8,8 +8,8 @@ objectives: - "..." --- -The rest of the lesson should be written as a normal RMarkdown file. You can -include chunk for codes, just like you'd normally do. +Lesson text + ~~~ @@ -25,6 +25,22 @@ include chunk for codes, just like you'd normally do. {: .output} + + +~~~ +matrix([[1,2], [3,4]])^(-1) +~~~ +{: .source .python} + + + +~~~ +[ -2 1] +[ 3/2 -1/2] +~~~ +{: .output} + + Output with error message: @@ -36,7 +52,7 @@ x[10] ~~~ --------------------------------------------------------------------------- TypeError Traceback (most recent call last) - in () + in () ----> 1 x[Integer(10)] TypeError: 'sage.symbolic.expression.Expression' object does not support indexing @@ -52,7 +68,7 @@ plot(sin, (0,10)) -![png](../02-objects_files/02-objects_5_0.png) +![png](../01-introduction_files/01-introduction_6_0.png) For the challenges diff --git a/_episodes/01-introduction_files/01-introduction_5_0.png b/_episodes/01-introduction_files/01-introduction_5_0.png new file mode 100644 index 0000000000000000000000000000000000000000..acd43728b61ca03a6e3792e25c53e5a71b0ba9b8 GIT binary patch literal 26539 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 Q5BaD1QOzTdR8C#}Kk0s|QUCw| literal 0 HcmV?d00001 diff --git a/_episodes/02-multiply-matrix-and-vector.md b/_episodes/02-multiply-matrix-and-vector.md new file mode 100644 index 0000000..7153a61 --- /dev/null +++ b/_episodes/02-multiply-matrix-and-vector.md @@ -0,0 +1,163 @@ +--- +title: Multiply a matrix and a vector +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- +Let us define the 3 x 3 minus-identity matrix + + +~~~ +A = matrix([[-1,0,0], [0,-1,0], [0,0,-1]]) +A +~~~ +{: .source .python} + + + +~~~ +[-1 0 0] +[ 0 -1 0] +[ 0 0 -1] +~~~ +{: .output} + + +Or simply + + +~~~ +A = -identity_matrix(3) +A +~~~ +{: .source .python} + + + +~~~ +[-1 0 0] +[ 0 -1 0] +[ 0 0 -1] +~~~ +{: .output} + + +Define vector `v` to be the vector with coordinates `x`, `y`, `z` + + +~~~ +v = vector([x, y, z]) +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () +----> 1 v = vector([x, y, z]) + +NameError: name 'y' is not defined +~~~ +{: .error} +Didn't work... We need to define `y` (and `z`) as symbolic variables. Only `x` is defined by default when you launch Sage! + + +~~~ +x, y, z = SR.var("x y z") +~~~ +{: .source .python} + + +~~~ +v = vector([x, y, z]) +v +~~~ +{: .source .python} + + + +~~~ +(x, y, z) +~~~ +{: .output} + + +Multiply matrix and vector using `*` + + +~~~ +A * v +~~~ +{: .source .python} + + + +~~~ +(-x, -y, -z) +~~~ +{: .output} + + + + +~~~ +v.subs(x=1, y=0, z=3) +~~~ +{: .source .python} + + + +~~~ +(1, 0, 3) +~~~ +{: .output} + + + + +~~~ +A * v.subs(x=1, y=0, z=3) +~~~ +{: .source .python} + + + +~~~ +(-1, 0, -3) +~~~ +{: .output} + + + + +~~~ +A * v +~~~ +{: .source .python} + + + +~~~ +(-x, -y, -z) +~~~ +{: .output} + + + + +~~~ +_.subs(x=1, y=0, z=3) +~~~ +{: .source .python} + + + +~~~ +(-1, 0, -3) +~~~ +{: .output} + + diff --git a/_episodes/02-objects_files/02-objects_5_0.png b/_episodes/02-objects_files/02-objects_5_0.png deleted file mode 100644 index ff203a3c0a4f0800169e5cb581dfa034f02d600c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26811 zcma&ObySpH)Hggx2?{76C?zTg2#CrMf|Q8NfONMg9fHywDk+Ghf`oK;H-aEY$k3gF zba%abyr1V=-@DfL$9J!FuUQV~y3RSf&fdS@KI1PhD@j63LySNmNYJP!iUOwtKM_-Q{JK2m zjjoj=>cTsbXnhI%LB836H;p1fKu*hm6udYWn*x-aY+r^#=ND4fZ=nIu{!3 zr?Oun4t$8d|60s)qdZYz;VoJ6fL>H2XPEH8lf!K#(=&HAP8qXa)Z(zp;!uxprG13i zmeP5|dA}U3lnR@a6zLSpk>r(;6rHN%!<`j|!Ga{)&WHA7boWFvRessMNO%`l#U;px78+Va&K7MW5Mp=bQO;#8CU0b7bwFi@JJy;?g z@Fbb=dhxlLDYb6QyFYLd$3`)~k zYN9A^qmm@0PmZLooamJpf85?3!L)zDB%@WIY%j5lx#Zb4;1dOsAw)|oM_Es%sZ}|W z(?*2W_v)fLMJ5;m=)0yG?a#gn^a(S#$_pG>EX27aU*MX>p{Z^i`q`(FrE2=8Eh02o zCWhCvFH>c>(k?5IKi!8@Yx#SBRavofNzMb;D4~Ee+D+A+-Dq*=9{p{BDz3@`uONYPWeaSJ3+K+uNxROv|dfrVovr( zPHb1Twd}46sxJ0OM)PsqIJ+hq!Oun$$*GmfAmp5`mZuAvIPCuDo*XCSvbb8cW`CJb zMPAi@*8k_`pVFpEqafRzK1DOLom!(DO-#B1CX^X-flFP)BwiR3>!5i92jNNmBncyO z#un>dxxL+k$#ZAU(c{u_$tjsqm6Qs|$(Ou|`T9^*{v!RIG25_WE4^nkxIE+mhm#5K z!1fId4ARrn{dSprORdUke;sV4Eair+R>`&f^gCIi6SmMhTCK`){ES2k?DP)Sks=Tg zJ3pvZ>8ke=x5w6or4Ia6DKnFfr$$%Gq%B7@Ut{w0mh}kJ@05-vC`R5bQBAg6T1Nkz zIAe(S7As8S5IL(Tw*JPsXTNq=XiwW!_X5I`LZe1=vG3QgkFH~bD($qwJyhwYb&m|D zEuz%RdHwl9LCf@(rl^WMa`N5j4p)^)?3;if1$qJG{k)O7Ivu2BP~nx}iPQc_9~=ZK zy!ug$MQ?cl$@*2kyD*@lD2VH9d@tEN_tUE?nLC^^?dG^GkGnmIPY${;5o%Hsr=>#r z4-aOWYTcjuY%dpK&Q9WUghw53QOh7iUp(3g4-dO#Xf#Z_Z@)r*beNHW5hp`?9K~!$ z)uCouqdcR>((u}b-J&ccG~%k`sM#cbk30I!r2hWNZkZ~_@iaAN&3!)TOZR~GEuph& zq-C^D)2}vdmU9TaZtgCWnhx_x*V!Py3Kv}^uhEBCf24V&?Zyv#e!378!#KU1d>?6-@KUKrDI z-q#E{P=GTELAOsQ56+muLcb!nV=pk zrDoyzA*eg+P>iOyq~JN)y_&I;J>~+aHZISG67qtzGEXN|9vv z1P7?Vj`9GcMt8%*2N!KjGi0PQm0Ii)o667J7g$6JuI%a7Xs3BifSvfqSVf*5$hmCM z6?b%987i7b6>JZiw<>YqAcFThtdgtNBB{7!bNRY_$woY^P7X0KR>Q=2@;b-+OkP*m zlfi*jD_AOs30iNXA8m&qT}rn{ZLk6-x7;$SIy?C**{TB3G=9yCFk9Vu6Fp!$=}@a_ zdiCL(WV3bw!2M5FqStP6rpvBI%;)gsmjk?3k(~m+cKMHY%l=LNEkU%cv$W{K z8ylUp*YiDcDV?z^lRbnC*6^%E_oe49yC~y0ww)FBnsx6b=^$&^NwV0jzoZ zrHT74e~pXegk)x@XSYRUIQ8$JUn#3&I%!_l3({`XV-+%eAtny7kR}qLSyK3R0)c4Q zt;g*T-WsS=yobWb@D06fqJ5R$ZnzsJYRbGoprk_a>5$O3?V+!VR z=fE^M#HA-9rv2ClPvM)YW70stBIQk*hz42H*4Shr(i!<-#? z@S>$M}_CxPdX&c(&xb`4~#xo z`sr4wW@-(9^NMC`yH_Zy|CDl($gS0E`&G1d*(yt3BO8g=etdw*${SvYqP*DRFyV%g zypH}TG$%lWU{qDj&X3sDI|=aqcC+p}2rut%o3Cp6nsdh;;+L5Itt-JbVrn)lWvECeZ6hAe`&7BI zT3Oys9M7{4*K7>T7$wB}ju+K1HG9JWN3ASXvbbC?Q*Iz&{?*zMJ8}>3@szyUPzKlE zcH{_A6;7SDJK{3O>%NL7hxYEc@|RUg`h1=SVP&P!xr zQ*VA@n8Bjy`~o;+1pC8wPSrOyIhVA`f*ZXM^}lkf6{GpOQcsgpD`hDz4(J&7;E5dn zuDt4*RDhXOVpkn(o)=tAc~^Tt?V- zCa7Py$nb)a`}7T(2|s>7unyGTZNAJPct?U2)B;{o&}GbM@eo4+9t zPta=GH%d&V1Z474QljEWU-rj;s%xm)@WWaaBdm z&duFnVUY}Dk+Y}&;Scu4!cjIlEr5PgzN?8nqrUlSv)~{osfJs-%Esp4`=1>pgyC>j zgYb!YA0MIW-0h16V{9nqn`v{@kN)0bXG9=g&CU+a88_>*bdEWUEOxeBmky$ZJrB5+ zU_#m>xuU4JB43p^*oDr%IoZK<#(s#yMMPmm?IcmTaGTiY$zcOoHqYTkiw=tywLEga z2~y#eVRVvYm29YXr+_pK?=$ChF%Su(lhAgE&_eCXo7Wn1KI26o)mTCkCo&5ID7mWgJ%Ld|V98Zlmzf`dDFi6nrai=Dm5a7dcV zusxH##C+sVS2DVE5f_2_V4{4uq_;99<4c;`!<4s_7d6+ee{5EmWU^lFea>{|X`1x~z+3xHx2Zc)%XD0;x)e zw|YrRs^pD1VA3fV>F$Rizli%m|w<2f<5B{E_x6Pzj{eosHR%Gto%AZ3z#@=At@qc9!KXA^GFXa|r-Nco3dHY~%7rk-H_9=5iX7 z*P#;7&?t2xL&yt(w83(+R@Ogm+tPkKYNF`B@AVuU%oCK!rnF2Xoudhsmzi7HCcCa% z)(HWAJ-+Y(J5BS)C>kWBh$=f{Yf`klsJyyW0itOz7F-DSsZaAcmgJ~)Sq%;HA6-E7 z6^?IO-RgbS7 zlXBleg7jhqRECRM>}Z<8@&bHDN45XV&YEn_w&o@^wWrEps-3_Mw zxh8DdLhAhR1Wxoy+fUAWrCYoR1k3JrPk&@FBvaqsE+NzXx4O#EQU?d{DqV=dmyq4* z^bNxH9Qbc1-aodVVV{UUhu|+@i7(#OCMGzmnkLT3mxq(aj=brD#9MK8Rn&D?MjiVv zOH6+6tvs~gjQ^v7NdG`4QXDDkp^uOa}*jo;mUSbEJgwlVI z;R>R@Kq6^(ZgV=&w2LGZ6320;7U4^eC`p3bW7(lNm!T82)^^TVvHC2~hgEGZlqow) zFgE(~tz@GPb<6X20th7IoSrTYDhRASf?1_mVhyNeG{X^-`*Cjl!#2L8AoPOpXft|B zrPM+6#CfU!0>a(3C|%d?xcqxj0*-g9ot{Goth3=u1K9&x|O`diSSul(I0yhcwP3|pGIzTb0@%5w~px%6UhD||2h zmcV|u84ijeGK6(gQP*(A#gjvDYDX0MQ}f5Nuv)U~_OS#7Pr5^%>$$Vl?9yai6x&;| zk~SZZVpqd@%J}QQA&|i2Jop_)t6fn6M=0hPtK3Ld8uI0Xc}pAlSK#n|Y1teZPBvPW z2*l^1A^>TZ8;HHL9IO_KdrTCFX##xkVvwz*Hs(VZSd-GqaA~X6roqTIAtK*=ddPT$ z(3_pI&^L*z)+9^%JOPXzF8smk*&Q8D2ZzMSa@lh)2#J&9aYC5wh3p4RfkYJ9%!1^v zL86blLqwI*q;?k3)H<^QMC9M}L>79LOcl-{(9!qBhs!?hjvBn~d|H*q)0G`($-CI{D^h|6$qKviXxX^aea|!8(59=5zSJ12-Z4SBN z^z8HVm{Z~lI*_3_)b2ly<_Rpi7TWQS$o_7hc^(KbX_=|wbVSm~3Bp1_1`Jb;sxoVySl6%hbSVjW~ z{EYP3Q;>A~m(t4&r%$^>5KH|-H}oiOm&=}`hIkSXknDX9n~`kP?tj-ra#b|J5qVGF z8v^Eb8#@HdR8YGFbS9y!`jKx4mUtoKj+< zFhQ3P%b!`)&QcZ3(54lx>#iZ-_#4VIRJLhPa>Lsc)f{aWFZPOx(rbrVc@Vl~9UlbC^4`>-99~cjoC8DwKKwBPeVSp5eKxUpxk1;hYHH}-;4*4F zi@8m5^|=+zr_nbymW)5=lxYTB*^kjP^oF_(#{lzp4I*(dcj-eS~*uyW%az9g++f8_FfJ6JJd+PI5>wgByN zH`u;g!rrLm!!=N&04vS(?0f2EZ30r;#_mpGErAo;g_J1Bkv;dFc2sB&>)&$I<*2Zm zPKqx4poTDE2U=;pz=gW?bTEz}L7UYei=-z_Iwb|0y10V$b{3gqogp7tkA6L~+@3gA z1<$A`Ae$Qca{xAcq~A~wM9Z==%EqY)o`h%`uXR(@Wl##Uws_exTwANA2N6sKkPbqw zT2@H>6&YzvVV4A_Y$@>%q2C^`{>k^$$=Muiw;G|`P>>3+ zoqAuIcZ0?*mH_d>d>EOb#RoVkn1l)-x@NtnC$Q@~tTZnyj_en92AsZo2f%{d_P-UI zMPM~5NJxs}HpWE1!+yOoX3p}YQ3OUWr$hxmLK6hfdtXRy4*HUa$Ed!!WjT6B0{6}v zNY*rryAx;mC`s<`P6yggPoY^L!Qf(_*!qr7AsX`Nth%=(tA-8l&VyH9V+Z6Frv-@a z1Sa0_v0n+D>nzd3n|#t795L>uHk=Qo86v#`P#hV?m5THaAVRmEYA0B6A*|tVgqp>! zyDa2t>u;wTR}i8Q`SBX6o$RND$U5b(ja7|2WXLW*B9sun2=OJT$D*ehz!9;x1giY< zNW^*XD80zxvZzj>0qnP|2KaN*T(1W+^gy9MPfvJb4if{xp5i~yoBLK z4#YeID*~^!t9-J<1#cT=PrMUvJl)({xffIL65Ju)bxBKcWf)>6HXq;N)Vu4pNfd^w zz;kjqq@M=M!IcpIP<>q3n-bVtQ3Oj5OO>%az5^$yJFi=1Z?ZqqF(3PFIHhU()uV%{ ze5JJ{6F)D2p6}6WhRM@|S@h=URACKr@r$qyjnJ^FtXJmG)=z-`^yh-LusrU*gqv4) z*KGqo2b~^wfvfoYR)iXMeC9|oTC*m)pGmnZUmwb%6@M=vJDci1T*I`oNY^-njzr9Q znhymal21y4727QhBl#0D7YCvWi*jD#jz8^|7ym9lSUIXFv-i)-k%)_0fEWJ8+%}U#a*JrCrazZKL z;gmp|Ndwa|wmgKD;~%$;_r=yXU_)QJlUBN_ zAC*0nFZfJJ(goqmeLLy;LKMI|jJYOHsq%Hxw&`SFh2_nzB**|DQ!_r|=Wwk&mz_OOj*DK-G9)~^gP^kAs5?7ZlaiM1nfWLJucjb=-&^fuQ)1Hnm{YS@ervAdqeED(^-}V0S zjrWcEoSBn;bwVz?>EgbmfUL&et^9kl=Ir!{Cn(ff&|#R(r}*{_syA`zg=zBmUju)=Gl_*P zh`bq@C9sF@d_dTJ9LKTkh0^Ow?NE-3U3&MpbQlt?l`yY85Q)iz-4h_T|LXb(8;8woA1^8TKH-D0w8j%EgMpKYzJ3bL}nx8>rr zSC)BRPkKTFdLOmlk(|CPkxEdRuOr+j46N$ARe|m|%L)R4D;zcr+4l`tcf_vZu zI+|3W0wc9Ub@heGS`tKLG2eYTw)o|dPGy5(acT~ zigZ7AbOV#9T*|E~e%V5b?IS2M?mF$d+V@f9RK3Lfx)aFNeqq==uWxr{q%Rpwv9s7G z9Z1EA`6BF8OcOL5Q%OXj9x1ULbnTXoLo9u?Ed~u|T)jt(@K~-&i5X;L3D>xv0zGf~ ziz>s-Wx&+BSRT1}!Ws4B$B(w3Kjjq^KCujkMRJuH7Cp2{{w9v4*jypYS8zTwT?k+Y z2-Gugq`W(Iw0fI-M)k6bghXk;PK$^X-#7s5!Bk}nXffWGKENO$O+sMHiTyb#!fqxI zsbrj-6k`Px`2jodX1yg|IeAVqyxK4E8;wzW$kU)uMI|sYd02HvG&8*b_KD-&oa3$7osYADFd0X!rbNRF`bf3n;$`nMa>^`CIORN5s;w3@Th zWSTTzTsYp!nJ4v&lK&Z3Y%PF9a5??CLd)YmYzkxlg8QC5L;Ei=u}XH!<5xLI+swnM z+jNz?`Dtg(5v2Qw=V_wze+t?>n;_cP9!fdSkU$|FocN8HnAqawotm$xcbh>zdDU>5 zB2WOcvi%;#{d8W)WqAKJ2n4oAytxSqobJsrzeTdOiG}@KJi9@j&pjb6Ctzcf9JZYz zp(Ke=R=o`nN{}W#x#6~nY4=S*dK!dw+pjPmGUHKxa^r0i!DrTE0stc^AeD!K4&7bZ zesiz z8+NQ_N%r#;6U5|WSVn0MG{JzzG=gXhCB%`70O%!|@WTmh`GzD(bqWK^5L`oPmBEaR zU!a?!{fj*b@q3^|3u$T=L&Hm7uB6i*Ww7psd z)A4;^;9MDD>4=%f%1&OHspeE*rDEOZ)2)^2#AEP+P-+Qrd|kJ`!=FV(P>v-Rb%x45 z{P7flD_SjabN6QY4|2NF?+9L=5Lh{K`#q;l454cl?OEfGIm-NCtO&qO5v&t$Cg6`{5Sd3 zh9Pw-Yyz>(WJUNqiRSsGDaLwrlINDBl+7H9kPNHqbX^x28i8r7mSUdL}a7)Dd-jNiuvJAO-zh3)+(CFAD-h z>l2lBVVWh=-b9ST#228V3m|Y*3Z%j~%@^b~K#BbFGmrG*z(<9w^;E2Qt9Jq9MR=R^ zb7Z`fT-fdb1qEC7vbxl}>_aZu`aW@rR!VAF6!OPOLs;=z4U6U2A}E?szxU4Z^QQBH z1z$UU`%84MlLS&}h_FcDR&%gROQF9>5Q$pkXuMRyWuuuioR4MUF@2Fmf}#uXv4Z){ z`kz71m>v1#J{)jV0s#bw0_Y%-c?R)!0PQ)GrSgj*4tQxQiAKKmI8Ku5ujF3iaM3=* zXf8-eLF~CinO9?E+|Zi`1+09*RAY|NLLiqm3!0&tN4PDR9(pW_Z#P_j`XMABFeil+ zVP@9FVA^mFc0e{XR7%JKI0TcEJd%!CWa6~F(>?|_{X?7(oP5|ygmBS6e}h*&)@ql)`4dd`%dW6naFa;j9y1A! zyjthzI+yNmx0KuwV=Ciacagy&X19XyHi1NA9UMW127_0n>$#wj!>R9sF1|cPkrCQ% z5ei-~A!XeI$LFhF{$emcd_9$~Tm@CNXy1pc`Z4=h%m~j@uVyzIY2b&&Pl|7^E~*=s*s1nOiMO8!Ls$c~g;wJtmI1f#;D6%tVh z%|wX0pIsskp5d$)O*LBP%V5vfhKOE?#yBC~k*IzqJTcWs@Kfm20|z=zC{_-5vh0OB z>2T{Qs>)&Hyjzo`A~gx*2Nrq(1b7VzVx=!s<*}rRh~2He3D##3bX8wu!q6}`3{OsxiiDYYH~c*d$N9u;4y?l**@NyKRosPh z(C1S@_Q(5~D*rPQ$N`RtY!2*uFZix>p_(j75#z>7Y5 zOJ)#)fbk;FP#SnLkSBlXv1^7Z=kE56&x^eU@som^bh-|xDvSD*)JtyNS_8OS}^N$ zhs1NmzV_*@tpVvA_hzw>T>D;2fY1Xa@|fP-Sp~rBlHMQ7O261-b{b-0$M4>=A+emC z>WnKBSQIbsXIB}K`SODJZ$sme@O&~6+gK+4&`guT^6sY{-O=w1U@$%Z^Oy!if~(wh zvd)l;z!EDef@)Ke@4)+(7uxWt;rwdS8^~2$>W3(F@BRDIw2z56tqHGRX2@M%^(qKg zmJmPqT(NBn!r#B}ez^k&l!~$^d$jcoT5aLWCg8VUR1`xLe2$7voLbj6?WBWLPP?!u zMI{Sbfx&_&6_I9P2I_{Q4_ey_ORKN2YqJpfBxAc!!vX@zpWm!_*SKrUG|fwhDC^G& z6F&5FVGNa?s8vjQTFm-G3PVY9aA1GP{BkbjnPzcFrNg{85mVK%D;rOQkQ?f5Mn>t4 zXx_0wnEanY!_A;~1P_(HsnOS+4nC^g+7(4W5{jjF;M;5tEafZYqRp~Vm&{5N5SStn zIN0Sm8y?HKGI%3L7bK3LmXb=Yu&E%t`OwgCXssTLqwnh}QewTj)9LPK)KgqSshy>w zM;Dl~egvk}xL`+u7G*BZFsR$06_8*;X|cEeGx_PhES6Xg;UgMP0~L8jtWy6%?HJv>=5sY&qh6{P}% z3~@qL{#U!LMyIa3+c+K3Xd#z3WZ4-o=->cS1T>b5KUYpcJY+^o+u%7%?vJ7u7_1d$ z{DKvLxCW%qr&sx&qXp)Ldpmtb&zd9!M-KEJU0h z!QvZz6zkkyU&P;k5=h1S=Dvttms>=jS12AxEO`~! z&F^oDW&oag@`ZP020sPkyJYprPl(lIeAJG-p7y&wt%&=20_=x!Fi{_n~5`$Ep>Z00Z%FaKpKb$?d^imT&6D&yOVV!%UN_)*-zEP9k!QjIahv%Esq@QY z#~r*<6IQ)Qh~MjWQ~C7!%2-U()6xG)_H&dpAnNOp*6Nz2&#;*{`5BQxcfMN{B;Fjq z&b5$}j>N??OJg%4GG=C=3`cRjUK07Pc$PVBfmz3kQjz?5Iro5jYz|SKE=dNh@S5SC z36P62T!gIpEJvIW621yTRmtapJ~o}7G)v)7T#tiun({vNGse%v!~oBx#0i1us@dq~ z7}V*#*lDhE6Mj|a=cw6@`Cx&`a{&Zz4QgV@jL|wYpkhG56{-&ue#EH{kzgb0WWci0~wtZrZKg<*@<+d6H}@9|;-K zUw|J@FMUqbpAh~Bn4eRY;J3IHFp%dEizg~${q(Xtm_V^ZUa@1re*>q2__7sey@`~^ zLvHXUe*U9TKLJe(LL}JbEsg7#4TrltH^fgh@q3ajS!J#UR(obLD8D!nf8q9|!zVxG zwBQ{R-1M)YQ`Yl)^=(AYy5-e>etwuB0QRq{6P$FSC&NkBdr+rM6qvhG2!*7U1A!i_Dj@X)gHlX zzHO4Qc(`4_%MA6Xhi0Yna7|1iPI_>UY?y%UB!l`jFIE~*myL0Tr51LjXqgg)AKLeD zJnpcD(C|e%?_iB69#X>n*UB9CByh7XitfB`P5Y$wutloG=6Z=}qH4c~LhB-#%1^V=5rF01=nIK-=;O>dbZ;xF9 z^|bA8D=pOQl@p#TxMva)n<*QJ**K^Kg(o}jB%hvOr_8g|qSa}~r&#yhwEw;-^A(Yq zCx&ZUk687(vfof%OqgSsRiKZ!uZ0=j zuR_t~ca6N?9k-0I0%xKrN%V4Iyd*f4A9PzWEPCb=#IOrc zs47L;vhLN-Y}j>&d@+@iz-f{-N<|t62O$Y2Wj^^?4qN<&wl_xg@A{C9nszY^psQP= ztSSNnvL`sWp?qX?1S>YI{+E9R|5?``$p%L5lFL;7Nie7SBpC62p~+_vy*r$Lyos8` zq0{u_5HcIx659;ReghHQOD@J=Z^XVK-m8DPVTfHUy#OjL7RZ`Qk9HP^SYO`#?8$e9 za?q#)8l_oqyjdt;9Pe+yD_J>;&%~jWLwi04^_lKYV%yDJm6%=-R$|-9h%PG50qaK@r@)fwDVj7Q*DTSzf=5r&m_X_OMS> z7zu9`y0>4x>L_WHy4|M+6@G4*vTU`7J*;|pyaS&?r3JtIuuYPdWoeT`L@+&9{cPD{ zkkN9iP3Yb=>#>bsU_E_EPKu^wyRE~aoWerth)~HQBi`vjE-+;P>n)Y$LT-Rrw%+1V z5jZ=Zb+g`;0oef(6_`rxxPnGF9XFa!#8CW!1J?VCpGKeV(YRyKK&^;w+e`|_#wGtj zrLLzznR{zByC)lp3|xjAH}l*)$YWXPB6U4kV-7r{nTY8eI$Ts-rT)5_6I$|K!2a&x#5a;@lg4qEr<)RFCDRH5T1n9RR3>z zICJS@ZeuCS;qs19li7^VQJe4w%8^Hql2zHGPmZ#N_v#rvJj~jpHJCQPq7t`?&5d&^ z0U(bTepU1pC9{cy+kW3DzS3L^cuL_QYXACm!Gi}6$amgguM5g1q^F}GVY_k~`;LmF zPsfz??p@W9Qp*w`)hJF0ar|mTj>QhQ;!`-as*Cc@qo|;XsxJe3w+Kx54fbN54=sQm zDXB6#Y5rtgIY?!-17ZooOh!aOnPWlhhl6HX`}&)nO@noMW|$|Hd%AGVK_?9-vT`5!lDBP}J8}GX=VD5U!nUp<9EMB61ngcM^8<84k*T8v zU|S*%s`&e3=tf#t#=?@JS_k_Z22Z;Y35syCEoum#yC!-J_+*uXx9Us8YbsLdrGb(0 zS_6syMr0&E(JY5dgz@3>Ff*r?kt2>4r9fun$`=`RghxiEz8b4E z{Sk1b?@-fbei*&HY<#}9u<*f{(|oMJN^uW%L@>SJ;y~SL$&xz1R8MMYUDu9~_0;$G zSS~Au*D^dbG!dA(S5i{*xL5bTOa>^^JM^V+I;5-nxU~w=uSN@ zS$VKeQuvy=^+N~Swegz8@tP_I*Y$>%!Kj+G+M{h4@b{A>Lw6{%bZ>$fF3ELaZC_IQ z%nftyH&@V8TU{bRw{jLgZ#YLn1D%a@6NdwJ$?SRI_N(F1d=9aB2l5}gF7p8o# z_Y3WfCczEIzaKr0la|!i^95JS#j)Jf@xj*1%^d-U(*9&$hJeVvL%S>XeNlUWv#?wqr@ zZf$MtY*6?ju-2IUjT!S@XP(0WPdV3}J~ixBSDIcW4f5pbGG}beC!g}6ef9hE{g+6K z!FvM=lN8*>oys5%9$?%`EQS<;%k6#nQAjl>Z>L)lQ)#zsjH1FNxG1l$|E)hyj|;6? zViqy(I71Rd!_)Tq0i9(%0@||Ia?7p8t2IW-tkmWdsDrn+ZFg2iu=2{>7)Ub_os>vY z7<==JlLol3PJtzkf!D4paABdSb8{7+TQ&9Bm&6EmwMDRAJ9>QKLerkxLdWZki=!1q zn_F8uCu<&hd=sukaZYnz?s(*Ue{4=fCx9dcWjl<%_Pzb=a{_nQBPF}VUWGi}8rxr- zWvqOB19nKd6n8h%-;8VHxMfxox$>;ZARzaZEl#b{ULXw3kKvZbK0AWJ;bdoE>11zW zfYz#dNfROHQICur5VS&sbXO-4dYn2b)dHBD{}k|t2Le1(6Kr* z#X6P0y`(pS6ssG(nb`gJ{+@_3+?+UH4C_$Ht3Aw|>xfC~&(W$1rZ_*9-;pt1+-euP zuU_j~A$+vVjpaHsGBTuOWct9QcA%R;0tE1htkkRF6Fih99d%dlNIUAT&UUxtb(Mvs zCrOgdX`kp`)t%U%teu_a-L2VHv|AZgiGnW5S2a7Ts)9nSbfsGXR9yD4vvnnAeNx>f z%7XUG`@{1NtD^^cS!8`;-JbQ88_l#lZiluVv4UzVS4GIVfrjYIyfUiMH)XA!rIy#< z7Qqe=-vNV`s&U!t2dU)3rQ;v7rX=2`ll5MQlW)mtcPrpRxF}G_d6)sGH6iF0-Q{Kq zb358S87N_f&;&9LCZBSI`vf$6yGDT+Y%2zqF<(!owT1Xk#ig5#gG;#qF9kjXAk8^l zVtZg+tYuZBf=fu+TeCNwwK3CTzA^p7dAXpamiKbngPWH}EFM}v|LXnSruoCQq>1A> zKC_Y1oJ#wZ%q#4wf92pl9+um#2==i`SAjbK?e22tdfsXLZ!f^v+8O!Tq08QCpAQM` zY0+X0m^D@|aQ9jT4k885fYNxH>1BUsS=BV0ltgy2 zf>@q2MDMfn5<`-E|~8|CXBpbAlgF(NdQRPNpjVDyEh-wOn_a?1z+qh5#-fk zE6X}mlY1J!E#11WwL1I;1hzvgv?&2LWeIGF>g|67=A@ONJt|ABCmL_RHRJ}M60JRn zPvFEK7O)MG732iaPqaGRDwShGo2dSXh9~rJS0>IS;r~Lpa+47IWd>hWNSZXEV7;S- zMO8#q-ZiRjM@3f3l6zno#Sy-Mz`zLbj>N>9{~8o=Ct15hxS)5^EjI1zv;fJZNOyY9 zFtp8`EXYBtM0x=H_5uM}>4{s7OO-5z9$cS9ObS7#W3x;uD^6e0>m&#+%f^V~bSu3K z{l;1K*J-dXXj?#!Rk5^yvV1{VN~G7Y$Wo@1Ov%KULHR!k78u09LKT@_$g$J%fRIG( z00Kyb&eSEQ4Q!^<4Cy#D_npAiX`JJf;$B__42VXJp97nN9;E*7D1cQLd-e5j$qeloT{BA;B5cVVaO3BrcCY;~b*z3h~f2cCk9_O8orW zp9x;8Ook$}UIeuH9cm;ZIJtoz+rQQ@B&Y6%hw$6b4P<>2L~&0bg!v?d1Tz-aV< z+w#`-_xD&hsMI{F*y77cC*r)%H}RDlqVglQV5m*c<~tQ*cpG%%@LyoT5oD`70V97j zZ^?<9Sk1o;!+Xc^@ORiQTw({T-Lw#kp(C0U4{HAriEx=2aY+flAhU>Kn>4^?93s|? z5tlfo^2g4`-3IJJ{~Pc}Xjn`q4&Q7s=_CBa!C)8M&#(6aK(s*{YXO&(a5f3ohC)G+lK2HaA5_0a^%hp!4YQxG6pOZ z84OgNe-@UNLu`acFmvjdrPUGQgO197wuJ&WNyUkEYad*~Wc&-+2?UocG&JC5R_rMQ zC4`UZM7S8GQ8dZfb*^uxnO2oQKOX0N?e5A-?;c~x0@mUJ!^5BN+Mer+i03LXV~%yh zb|I7BU}sm~6NM7DqM`z_yYAW6Fda!8c_M({3k@;Uda(O)HTmat6yE^K!w#1oE^Za} zW~2;qKHE?Ee}2dUTMOmRAkvfJ*H8c&f^KSQF6g4QHlCNo{{F~9S_*qE#9`5!lvmI! zu}nhy3D}!WJ-uJ^RA~_V(j%pqFUADsPE_f^-ya`w(*a2>It};P-Hr(6|A{fTurNDn z5|KQC4+6;a*LR34}qgJ`fJ|7Aul>+-5=;!;Oi65#EFATIxgNXu!{Yz?4)Z-H1 z%>WQ7>0S$WnErK|BFH&;RA>Z{SN}639o5L#01Yg99pZ?Ok4X^2UY`Tn1(Zd_8M?dt zIyTt|Yi=-3S(}4X13OS1Zuo4?bw}ed6=ie$51z;)4tBB%cPMH2fMRSl2JB}|msbq8 zb@>DLa{JA?3Fs++x8!Il8X4Vl7Jv@cuBd1}=#~Po+>`xVNDeQc+oH?{##%1et42(s z)0C8hUa#0jExnQ>BbaN>YGo9+*zdkXkl$qgMOyYn5MmMI{n}$i&C(Ai7ZDaELX@G{ zi%^+Be~CW+>YQnNxKPY`!wD`rHoOAMislJ(-d=YIBnL};*V?(ehfk3n;C(JbntCBz z38Ka%{+}b7Hu$xS32zW#M zxT@^mT7je?_?Lxv?z6Fm5L^s_-}nHTL}9sppbAIk1<-x)n?$JeWeZc_FtHZkxzEa0 z(ET04=sr-bDQ^jLtk-F=%kE422$wEAqKv&LGzy>GxeFYx=b5Uog5|CShz4snkD;l& z(Wf8}r{RAHtz~FGLF5s=wF3rHv*aNGxDQPU0;I?i3W^G=0V%|x1NcLQB9UL6V zOg4&F5w3bt0T4x@uWN;gN8A)~=}l{^(W*-a%?R4_&~7vNn%oN!T+b}D6qX#EFvCs3 z5&ijp3cJ!ks=Btl4T(ykB&1Y^&}hgQr%(P@(|E(j&dOY>ZlUAtU14KmV{B?FR^8{Kyqb3DLY>fH)v%%) zUSb&WP=^14SuXk!!b(%vXstjypt4Wa$VEO38Jc*B!Ln}s-cX)^No zqdiH7ndDDYnkspPL3Q$wiAH*V`scYcS)y2M>x<-c4SQM_((Lj*B0YYU3=yJRMD%qu z+xO8uS-4_{oXPB%`cV5`>_cazPg`D#oiYa@Po+kz7K&7zdF2^-?j9~1{=KUFM66xF zsFcKBuQ1qgiZ15{07JiqeWKt^^1plmXA!^QmCL-m35Jzh)XBZr7b=+ag4ma2Y(gTJFWfCu3c}QT)VMW?%BcsL# z`QQ!FyWlY&&(hBhS<2M0Ro&=%_1@to)s2Uuh&B_W$eA(N?JjCz7)Ij;ManS!nlGp8 z?YFx};0!h~)hxge&Q6@4y1|28Je`r5Kwrb&uE%U~!uoDoeq38#47Q+3SkC0qccI*e zbk9gBtgq`W%zeyy=-zECT%PBz^cjut6KPCsaTD%CU#SR{Fy1YUw|90rF8v;6Kkn3F zGqT}18Z!F7O9b{svvFm~*35*2H1=!-Zb6T^MoK_-&t?q+0U}Mn=xC@w76>Sm+gI3B`_rKqg8t z@Vd&L@rEa}$CfcS_cGX)H+O4S|GCDH4a$cD5qMiKB_qkjv-kIo7iQLX6&>XE_jsZuh;Qw- z$JiLw!FoawSP&u~TJ{@hUVCJ7jUmErh6aOX9XnYLN)B93O-;oCkprac=xFV! zE0RuUg>#uvuVw$kfE*PaUYwe;f_XU*IqBX!AX z#HH>MQr*GJ*QIyG)ou3CBM07lRN^O9U*1cuz|u*6Ih1N(a&$L(-fr+5bon4TH19oP zN1SSLDx;Ql+bpdUB}J=pL`gfJ; zV|Z;&Ba{zczY|*WIX$gEX<#)|O&03)86vpdSjRT&kxzx9CNq2KUpf1k%S3bqaYlVC ziqqC%sNBI5bEUf8Wy;%(c_MTogdg=ks{NhakpEOc^wrnz+3a9! z9Jts)UKJU!g+$_BLz1;sP=Q8w?MQIkum&jIOxDL~EV+DbaKB zUdpE$rMMt!lo$|pR&9v+CXp4)#dm;&-d|hEmp6YoI5=48(nLB84~6Xe|e7SPyNl#db(nFL*2n3FqIL!_wsKG}7i2n@Du$_QZLH$1p-qN@E? zji@-ecV_E_c5(_y?zGs@`Tb*#Y-6(GQ8HQ9nx*?~dd}p0%y=qu0L@3W&!k#kTRQ~& zk#}Fc(hwCFKQ~0roc;ZFx7_8apNW~v*OW?2H;TGslm6Ilv|k0SikSCdHa{MP|MOD3rsuH!U=O0)FSGi|OV(p0#W5q26IR-j<0B z-F8(~r1vKg0Axwa$i&3OnMEzJ5}P6-wwx>%emWio5eq>J2nvb4mm#jSypx;muKE`5 z{EzOla#9$ywEi^Td0kg`4it>TosaWHa;vH=lH^@JUgc6f#u%OZU}k0C_smy7+0!w` zstjPynVCP!X&Hg65_{j@+Kz5iWzMR!G|H2U?=6Jc3B8YbG49_}2IXA4%ipP#G~21G zOuSRSgc87`i@$7qk-El%3NXX`f`WpgYTNqoEr}}Lzdu#`BWv^6lW{yII{NI(AkK#7 zX48NE$v|i4zXHoC8{X9a84TTIUA3)cPuT zEm=;b!w*BdMVLp8HKbup(h>C zvz&7q32PCVqe@W!M{hiN%6mFW2G^g3uTidP8avbR*hceg>i3nb%mMFI@}}UT@?sZo z-qc1BJ`B3(cAFJa-i`BiIE>4W8%4I|aOZR8JPj4hTw1Ui|FV*Brk52dQYF^$J^gz{l-Qs&PIm_> zHLH-DGP|D<{bJnQwnx0)r{gtX@+ML6_Ue<1b7PX@W{;*ZYc?>L$|`8zy3v`*FY#b(&$%~l}6P#t=|=0 zSZyhw(vA~0C*{Xk`ycQ6>>`DITb$sG6OtH$|)dp&i8*SjFu!I(X3a&H;Fh95_gVgHf|0FF`cD zbz2k6e3}CcYidM_(>`@GW4L+ph=g%Wpg|l1B;Ur9Wzc*XC7$^q-$^{6_2i=0i(D$m zG03~#Kdqd&y4f{^rx5NNe8KKtOhoxUJhWwOrqMy&?^#6|Q#qQYaZsaO2Rd6L1cygO zRQZIG&#}MKqVS=k#5NQ88cf`k3wP>QjO$6LS|%!g^5ju4F^q7ZeI#oW2ydZ(6FDLe zw{`ET=9ITLcnTdyEZkH^oyuSqh!JvrirWq+-mL7s+=4rsX2$7XUKdCc6kY70t#=sD~#&GNW*PF#%QUs7c$6> z=EXTInS`Wd#47cMZYjNj4(E} zC8ffX{QFL6qlV_e^fK3}sV=Z74D$W&-(3Jo=u^!thqwlICddpPlsDxk(wxa#T<|Dw zH$2MlKmhg**x0}OLq;v$hK9Bp_EV1dXH$W>QIVw)K;uyatr9yFcrAIOOggYPrBTAh z4R4WfH$OwrW)Xa?SwHd&Feq*C#HFy_eRwv)eI(g^X@R_P?(dED0MPwnlx6C~Ic6W& z-k2!bSnaoQGT5idYji@`5e3JYwghg`(G$g# zyaL%e1~V~?ut?bPkB_bT1cX5o?l60nc}b&cte^|2a#e7ggbTiY)e_g!8m)p8e&yQ_ zLo}T4az`Yif!8$!bjG>*B+{8()HOTC2NO&((S8nhXB568yOio3S=(C)-fA8Vo&u~d zu?!a;wmn3!PxK3sFKgGfeF(wwqE8pqpif)7ap)NQI?6&iZdC?3@4h$9@z~Vit|S-j z_wVU9xXEQGgYO%dx%YIVZAXh*Sqkf<=$h~>efi7$h1I+tI`(@x#RJD)H#G;%KN_+(&i zugp1YQ@aYWERH`Y`d=G+TL=X$ocD<=iJB1`^yGWB^>V)KpQV3V&meZ#KaDv znD~2cp>%*43#U+q>92jX7e1aSZB5%}c?rzVhDz>QAva6Nw|ZkD#Yq_S`KXq37M}`m zACAVnLIF;VUbljUV1-Ul+6DI?SMt(JltEb1)&`o9EM0P~i%Fq+n&ccA8I@^fh0soJ zayZ}U$SpKOLz^xNW-<{XsHuRK7#uMSk(|Pi6==h3(l#8ZMI;6KZV(&}dj1e}4!6AA z%TlZ5rHg@ z>I)=;5ydWKJ2pL+^uW!1o(ac)FxNd#_&b+UNP!WAD{ zHvSzk*6F$oz+3JtC3C(bPLbK-X2KBW2d9$D^v39B$hjEp{Y)>$bm}2ir+=D4%nd zIl9#CRvHy}+rG82VYNJkh2~o*$*HKQ*wEN$yy@y|;$Y+Vs7-#y&*e&nPuBYoFj$3JDH2G&fH`tiVtpUbI!X8C81H>mv~Vcj^r|mDnb{DE7#2 zds@i=6Fqt0&~zcOZ+n3+l-&6^rM8lpX(+)iBSQq5q_7M#cR2Neb%-wNroQ*e=}8CV zzlPo)CM}*t?L{7;I^33**L9YDZAMU8+IsPANedd#v=kMwsl+qn-H69y z?WgG=+#`Ldi*?Vh(oeV~+?+sSD4U7!5kyrwEtZWdRxdSLbw1oMadyx7^a`fgl9vA{ z2d*GrLIU zkg4GC7m(zcS&@05_zmPD_tjxP+ag=U_b-+sKqsx4?1;zDc-b={6Z%UU)&!AF%Art3 z2H65!J(ptcO=;RcSFn!T8aLJ?kTYH$XC?^f3YxT2YJDLMi@*6wIG%XBkB@BTGAww zQ*rhQuL&QiI+|Ay-Fx|VRCM0J=j%+_Vm(j-$!cV zPXs3}a#<2P>Hn1M%+dR@(dC(hQ?KJL_j`Cq<=AOK;!4eEoZr&rlF!o%(@xnB(6Lc6 zdtqsTPGf>CCmce^aismKCcOOZcI|ar6h7;^f8mk)?~I9THPW2taALVxssChvWmy6z z0uT)hS@exJly9PSt>_T9F%p>HpOoV6_SFEWM=){ zteps?gzJx&?UPy9UG2EbcO_rlZ5{CUH}G6zBDzD7t7i|m$%j18o@{of9!U_|DI1P0 zOk^9uJD*WhB|QYnNpeBAtl{1QbY}u%iQxkK_6$7_pRDA|Y)D01AopXxwaUa+t)^e9so&smsBxXhiHkFuxw79?WAOJ z-4bV_uxlRDcB$GD6CJP9S7kfpXg_#l=o;VlRYboi%q;r@ptRMNI+C*h7G%gy+5zTZ zrxxWmv8|+&AjVc>x;0lQl!hj`X})!QU~IKfHtew|7w++h>u7=9dUe|YE)SHphWSp5 z#l*+-YZZ0ZKDgg(}P)pqiEXqJ9ls=wu> zDRVNh2wi)QW0SbKxHy_AaWn%QPu26UJrfhV9=-W_8tgl>ABxEBW!1@G5X71h@VpK| z#IJ9P1hY$Iq@#FVs`~YepN=I@_IOKA?9f-+*t}>^46OO zEwO9b6a+#${6>P`f+HyH16RP1Z_LsawEw0(^hMLnx^s$Ax|V9?3w}kh`<6R*nr{Vc znS3CbpHwh7cm+(F=H7okb0Hi5^Niv}1A#r1OH01FIraOql_3l$0TCM|RV|N~92)+p ztF0Gnc}Ze|ug0lUWO8U*ih^~>TP}YjhFFN?=i2ti;G-EGJ<2O6n9s&3@B{oL54l;0 zjl0EalMQ5@lVQJr9`=;0+a2x?Peu~i~ss5?(x&JQM%!25k)@=QJ|E0x5S^G$z zZZ=lJ#G$ReD!{6ka=h|mfl7g;P}O%vw|$uJ!iSz-@ehK^tJsLOAuTr8p-Xv@Apie zsOf2kq1Z()y|4J&y;BzE47IBgfnqy-M)mj4FX>116MpYK6C$y?s|w$#)v#57SLG6AIwbj zOIr!oj~_sbXB!Kb%Bf9*1TPB>R+g6(AZ`0Le`zkgqN{pwXtLBSEf zYPIog^HEQ}I_g4sKrmqV@D9$2L!|2_zaoMXFzQIn23+FG}6tFGkSCNFOWyY`%ei`eD1 zSjBJES#H=_)-tc;LAsk#>kzht88BK8I5Q(dgM)(uzgQxLlLEhU zqi(Lae+W!IZ2>IH-G98>vW%ID0po}q-mhQ3(CAdc&4J5mOpbN1KRx>%z{mIM$fW+B z@qs-xLI0ba$FQ;Bd9sb%`1$ZfBagi}=Ln+xWkf#tw> in () + 1 count = Integer(1) + 2 +----> 3 g = [A] + 4 + 5 for i in range(count): + +NameError: name 'A' is not defined +~~~ +{: .error} +Find the inverses to the group elements + + +~~~ +I3 = identity_matrix(3) + +g_inverse = [] + +for i in range(count): + for j in range(count): + if (I3-g[i]*g[j])<0.01: + g_inverse.append(g[j]) + +for i in range(count): + print (g[i]) + print (g_inverse[i]) + print (g[i]*g_inverse[i]) + + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 5 for i in range(count): + 6 for j in range(count): +----> 7 if (I3-g[i]*g[j]) in () + 1 g=[] + 2 count=Integer(3) +----> 3 g.append(reflection_matrix([Integer(1), Integer(0), Integer(0)])) + 4 g.append(reflection_matrix([Integer(0), Integer(1), Integer(0)])) + 5 g.append(reflection_matrix([Integer(0), Integer(0), Integer(1)])) + +NameError: name 'reflection_matrix' is not defined +~~~ +{: .error} + + +~~~ +# bit of conjugacy classes if you fancy - tidy up and do set of sets here? + +for i in range(4): + for j in range(4): + print("coset", i, j) + print(g[i] * g[j] * g_inverse[i]) + print(g[j]) + + +~~~ +{: .source .python} + +~~~ +('coset', 0, 0) + +~~~ +{: .output} + +~~~ +--------------------------------------------------------------------------- +IndexErrorTraceback (most recent call last) + in () + 4 for j in range(Integer(4)): + 5 print("coset", i, j) +----> 6 print(g[i] * g[j] * g_inverse[i]) + 7 print(g[j]) + 8 + +IndexError: list index out of range +~~~ +{: .error} +Do A3 next: sub in simple roots into the general reflection formula above, then generate the group + +$A_3$: $\alpha_1=\frac{1}{\sqrt{2}}(-1,1,0)^T, \alpha_2=\frac{1}{\sqrt{2}}(0,-1,1)^T, \alpha_3=\frac{1}{\sqrt{2}}(1,1,0)^T$ + + +~~~ +K. = NumberField(x^2 - 2, embedding=1.4) +g=[] +count=3 +g.append(reflection_matrix([-1/r, 1/r, 0])) +g.append(reflection_matrix([0, -1/r, 1/r])) +g.append(reflection_matrix([1/r, 1/r, 0])) + +g + +for i in range(count): + for j in range(count): + new = True + tmp = g[i] * g[j] + for k in range(count): + if (tmp - g[k]).norm().abs() < 0.01: + new = False + if new: + count += 1 + g.append(tmp) + print(g[-1], count) + +for i in range(count): + for j in range(count): + new = True + tmp = g[i] * g[j] + for k in range(count): + if (tmp - g[k]).norm().abs() < 0.01: + new = False + if new: + count += 1 + g.append(tmp) + print(g[-1], count) + + +I3 = identity_matrix(3) + +g_inverse = [] + +for i in range(count): + for j in range(count): + if (I3-g[i]*g[j])<0.01: + g_inverse.append(g[j]) + +I3 = identity_matrix(3) +tmp = identity_matrix(3) +for i in range(count): + for j in range(10): + tmp = tmp * g[i] + if (tmp - I3).norm().abs() < 0.01: + break + print(i, g[i].determinant(), g[i].trace(), j) + + + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 2 g=[] + 3 count=Integer(3) +----> 4 g.append(reflection_matrix([-Integer(1)/r, Integer(1)/r, Integer(0)])) + 5 g.append(reflection_matrix([Integer(0), -Integer(1)/r, Integer(1)/r])) + 6 g.append(reflection_matrix([Integer(1)/r, Integer(1)/r, Integer(0)])) + +NameError: name 'reflection_matrix' is not defined +~~~ +{: .error} + + +~~~ +# bit of conjugacy classes if you fancy + +for i in range(4): + for j in range(4): + print("coset", i, j) + print(g[i] * g[j] * g_inverse[i]) + print(g[j]) + +~~~ +{: .source .python} + +~~~ +('coset', 0, 0) + +~~~ +{: .output} + +~~~ +--------------------------------------------------------------------------- +IndexErrorTraceback (most recent call last) + in () + 4 for j in range(Integer(4)): + 5 print("coset", i, j) +----> 6 print(g[i] * g[j] * g_inverse[i]) + 7 print(g[j]) + +IndexError: list index out of range +~~~ +{: .error} +Do H3 next: sub in simple roots into the general reflection formula above, then generate the group + +$H_3$: $\alpha_1=(0,1,0)^T, \alpha_2=-\frac{1}{2}(\tau,1,(\tau-1))^T, \alpha_3=(0,0,1)^T$ + +$\tau$ is the golden ratio $\tau = \frac{1}{2}(1+\sqrt{5})\sim 1.618$ and satisfies the relation $\tau^2=\tau+1$. + + +You will need to modify the two earlier examples to either deal with $\tau$ numerically (i.e. to within a certain error) or via the recursion relation. + + +~~~ + +g = [] +count = 3 + +g.append(reflection_matrix([1, 0, 0])) +g.append(reflection_matrix([-1/4*(1+sqrt(5)), -1/2, -1/4*(1-sqrt(5))])) +g.append(reflection_matrix([0, 0, 1])) + +# Build g + +for i in range(count): + for j in range(count): + new = True + tmp = (g[i] * g[j]).apply_map(expand) + for k in range(count): + if (tmp - g[k]).norm().abs() < 0.01: + new = False + if new: + count += 1 + g.append(tmp) + print(g[-1], count) + + +for i in range(count): + for j in range(count): + new = True + tmp = (g[i] * g[j]).apply_map(expand) + for k in range(count): + if (tmp - g[k]).norm().abs() < 0.01: + new = False + if new: + count += 1 + g.append(tmp) + print(g[-1], count) + + +I3 = identity_matrix(3) + +g_inverse = [] + +for i in range(count): + for j in range(count): + if (I3-g[i]*g[j])<0.01: + g_inverse.append(g[j]) + +I3 = identity_matrix(3) +tmp = identity_matrix(3) +for i in range(count): + for j in range(10): + tmp = tmp * g[i] + if (tmp - I3).norm().abs() < 0.01: + break + print(i, g[i].determinant(), g[i].trace(), j) + + + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 3 count = Integer(3) + 4 +----> 5 g.append(reflection_matrix([Integer(1), Integer(0), Integer(0)])) + 6 g.append(reflection_matrix([-Integer(1)/Integer(4)*(Integer(1)+sqrt(Integer(5))), -Integer(1)/Integer(2), -Integer(1)/Integer(4)*(Integer(1)-sqrt(Integer(5)))])) + 7 g.append(reflection_matrix([Integer(0), Integer(0), Integer(1)])) + +NameError: name 'reflection_matrix' is not defined +~~~ +{: .error} + + +~~~ +K5. = NumberField(x^2 - x - 1, embedding=1.6) + +g=[] +count=3 +g.append(reflection_matrix((1, 0, 0))) +g.append(reflection_matrix((-1/2*a, -1/2, -1/2*(1-a))) +g.append(reflection_matrix((0, 0, 1))) + +g + +for i in range(count): + for j in range(count): + new = True + tmp = g[i] * g[j] + for k in range(count): + if (tmp - g[k]).norm().abs() < 0.01: + new = False + if new: + count += 1 + g.append(tmp) + print(g[-1], count) + +for i in range(count): + for j in range(count): + new = True + tmp = g[i] * g[j] + for k in range(count): + if (tmp - g[k]).norm().abs() < 0.01: + new = False + if new: + count += 1 + g.append(tmp) + print(g[-1], count) + + +I3 = identity_matrix(3) + +g_inverse = [] + +for i in range(count): + for j in range(count): + if (I3-g[i]*g[j])<0.01: + g_inverse.append(g[j]) + +I3 = identity_matrix(3) +tmp = identity_matrix(3) +for i in range(count): + for j in range(10): + tmp = tmp * g[i] + if (tmp - I3).norm().abs() < 0.01: + break + print(i, g[i].determinant(), g[i].trace(), j+1) + +~~~ +{: .source .python} + +~~~ + File "", line 7 +g.append(reflection_matrix((Integer(0), Integer(0), Integer(1)))) +^ +SyntaxError: invalid syntax +~~~ +{: .error} + + +~~~ +K. = NumberField(x^2-5) + +g=[] +count=3 +g.append(reflection_matrix((1, 0, 0)) +g.append(reflection_matrix((-1/4*(1+a), -1/2, -1/4*(1-a))) +g.append(reflection_matrix((0, 0, 1)) + +g + +for i in range(count): + for j in range(count): + new = True + tmp = g[i] * g[j] + for k in range(count): + if (tmp - g[k]).norm().abs() < 0.01: + new = False + if new: + count += 1 + g.append(tmp) + print(g[-1], count) + +for i in range(count): + for j in range(count): + new = True + tmp = g[i] * g[j] + for k in range(count): + if (tmp - g[k]).norm().abs() < 0.01: + new = False + if new: + count += 1 + g.append(tmp) + print(g[-1], count) + + +I3 = identity_matrix(3) + +g_inverse = [] + +for i in range(count): + for j in range(count): + if (I3-g[i]*g[j])<0.01: + g_inverse.append(g[j]) + +I3 = identity_matrix(3) +tmp = identity_matrix(3) +for i in range(count): + for j in range(10): + tmp = tmp * g[i] + if (tmp - I3).norm().abs() < 0.01: + break + print(i, g[i].determinant(), g[i].trace(), j+1) + +~~~ +{: .source .python} + +~~~ + File "", line 6 +g.append(reflection_matrix((-Integer(1)/Integer(4)*(Integer(1)+a), -Integer(1)/Integer(2), -Integer(1)/Integer(4)*(Integer(1)-a))) +^ +SyntaxError: invalid syntax +~~~ +{: .error} diff --git a/_episodes/06-rotational-subgroup.md b/_episodes/06-rotational-subgroup.md new file mode 100644 index 0000000..92bcec0 --- /dev/null +++ b/_episodes/06-rotational-subgroup.md @@ -0,0 +1,90 @@ +--- +title: Rotational Subgroup +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- + + +~~~ +g +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () +----> 1 g + +NameError: name 'g' is not defined +~~~ +{: .error} + + +~~~ +counteven=0 +g_even = [] +for i in range(count): + if (((g[i]).determinant()-1).abs() < 0.01): + counteven += 1 + g_even.append(g[i]) + print(g_even[-1], counteven) # + + + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 1 counteven=Integer(0) + 2 g_even = [] +----> 3 for i in range(count): + 4 if (((g[i]).determinant()-Integer(1)).abs() < RealNumber('0.01')): + 5 counteven += Integer(1) + +NameError: name 'count' is not defined +~~~ +{: .error} + + +~~~ +closed = false + +for i in range(counteven): + for j in range(counteven): + + tmp = g_even[i] * g_even[j] + new = true + + #create a function that compares to group elements and returns label k if it is contained in the group? + for k in range(counteven): + if (tmp - g_even[k]).norm().abs() < 0.01: + new = false + break + + if new: + print("not closed") + closed = false + break + +if closed: + print ("closed") + +g_even_inverse = [] + +#create a function that makes inverses +for i in range(counteven): + for j in range(counteven): + if (I3-g_even[i] * g_even[j])<0.01: + g_even_inverse.append(g[j]) + print(g_even_inverse[-1]) # + +~~~ +{: .source .python} diff --git a/_episodes/07-orbits.md b/_episodes/07-orbits.md new file mode 100644 index 0000000..90ac53b --- /dev/null +++ b/_episodes/07-orbits.md @@ -0,0 +1,106 @@ +--- +title: Orbits +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- + +Make an icosahedron by picking a seed vector on a 5-fold axis + + +~~~ +icosahedron_dupl = [] +T5 = vector([0,1,1.618]) +seed = T5 +for i in range(counteven): + icosahedron_dupl.append(g_even[i] * seed) + + + +# now delete duplicates - do ito golden ratio, or round or convert to set etc + +icosahedron_dupl + +icosahedron = [] + + +# define function take orbit +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 2 T5 = vector([Integer(0),Integer(1),RealNumber('1.618')]) + 3 seed = T5 +----> 4 for i in range(counteven): + 5 icosahedron_dupl.append(g_even[i] * seed) + 6 + +NameError: name 'counteven' is not defined +~~~ +{: .error} +Make a dodecahedron by picking a seed vector on a 3-fold axis + + +~~~ +dodecahedron = [] +T3 = vector([1,1,1]) +seed = T3 +for i in range(counteven): + dodecahedron.append(g_even[i] * seed) + + + +# now delete duplicates - do ito golden ratio, or round or convert to set etc +# define function take orbit +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 2 T3 = vector([Integer(1),Integer(1),Integer(1)]) + 3 seed = T3 +----> 4 for i in range(counteven): + 5 dodecahedron.append(g_even[i] * seed) + 6 + +NameError: name 'counteven' is not defined +~~~ +{: .error} +Make a icosidodecahedron by picking a seed vector on a 2-fold axis + + +~~~ +icosidodecahedron = [] +T2 = vector([1,0,0]) +seed = T2 +for i in range(counteven): + icosidodecahedron.append(g_even[i] * seed) + +# plot +# now delete duplicates - do ito golden ratio, or round or convert to set etc + + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 2 T2 = vector([Integer(1),Integer(0),Integer(0)]) + 3 seed = T2 +----> 4 for i in range(counteven): + 5 icosidodecahedron.append(g_even[i] * seed) + 6 + +NameError: name 'counteven' is not defined +~~~ +{: .error} diff --git a/_episodes/08-polytopes.md b/_episodes/08-polytopes.md new file mode 100644 index 0000000..c94fca1 --- /dev/null +++ b/_episodes/08-polytopes.md @@ -0,0 +1,136 @@ +--- +title: Display polytopes +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- + + +~~~ +point3d(icosahedron, size=100) + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +TypeError Traceback (most recent call last) + in () +----> 1 point3d(icosahedron, size=Integer(100)) + +/home/raniere/src/sagemath/local/lib/python2.7/site-packages/sage/plot/plot3d/shapes2.pyc in point3d(v, size, **kwds) + 1126 except TypeError: + 1127 # argument is an iterator +-> 1128 v = list(v) + 1129 l = len(v) + 1130 + +TypeError: 'function' object is not iterable +~~~ +{: .error} + + +~~~ +icosahedron=[v.change_ring(RDF) for v in icosahedron] +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +TypeError Traceback (most recent call last) + in () +----> 1 icosahedron=[v.change_ring(RDF) for v in icosahedron] + +TypeError: 'function' object is not iterable +~~~ +{: .error} + + +~~~ +P=Polyhedron(icosahedron) +plot(P) + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +TypeError Traceback (most recent call last) + in () +----> 1 P=Polyhedron(icosahedron) + 2 plot(P) + +/home/raniere/src/sagemath/src/sage/misc/lazy_import.pyx in sage.misc.lazy_import.LazyImport.__call__ (/home/raniere/src/sagemath/src/build/cythonized/sage/misc/lazy_import.c:3646)() +387 True +388 """ +--> 389 return self._get_object()(*args, **kwds) +390 +391 def __repr__(self): + +/home/raniere/src/sagemath/local/lib/python2.7/site-packages/sage/misc/decorators.pyc in wrapper(*args, **kwds) +710 kwds[new_name] = kwds[old_name] +711 del kwds[old_name] +--> 712 return func(*args, **kwds) +713 +714 return wrapper + +/home/raniere/src/sagemath/local/lib/python2.7/site-packages/sage/geometry/polyhedron/constructor.pyc in Polyhedron(vertices, rays, lines, ieqs, eqns, ambient_dim, base_ring, minimize, verbose, backend) +366 """ +367 # Clean up the arguments +--> 368 vertices = _make_listlist(vertices) +369 rays = _make_listlist(rays) +370 lines= _make_listlist(lines) + +/home/raniere/src/sagemath/local/lib/python2.7/site-packages/sage/geometry/polyhedron/misc.pyc in _make_listlist(x) + 88 """ + 89 if x is None: return [] +---> 90 return [list(y) for y in x] + 91 + 92 + +TypeError: 'function' object is not iterable +~~~ +{: .error} + + +~~~ +point3d(dodecahedron, size=100) + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +TypeError Traceback (most recent call last) + in () +----> 1 point3d(dodecahedron, size=Integer(100)) + +/home/raniere/src/sagemath/local/lib/python2.7/site-packages/sage/plot/plot3d/shapes2.pyc in point3d(v, size, **kwds) + 1126 except TypeError: + 1127 # argument is an iterator +-> 1128 v = list(v) + 1129 l = len(v) + 1130 + +TypeError: 'function' object is not iterable +~~~ +{: .error} + + +~~~ +point3d(icosidodecahedron, size=100) +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () +----> 1 point3d(icosidodecahedron, size=Integer(100)) + +NameError: name 'icosidodecahedron' is not defined +~~~ +{: .error} diff --git a/_episodes/09-idd.md b/_episodes/09-idd.md new file mode 100644 index 0000000..f0a5e4d --- /dev/null +++ b/_episodes/09-idd.md @@ -0,0 +1,43 @@ +--- +title: IDD +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- + +Show IDD is a root system. + + +~~~ +IDD=icosidodecahedron + +for points in IDD: + if not (-points in IDD): + print("first axiom violated") + +for points in IDD: + for refl in IDD: + tmp = reflection_matrix(refl[1], n2=refl[2], n3=refl[3]) * points + if not (tmp in IDD): + print("second axiom violated", tmp) + + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () +----> 1 IDD=icosidodecahedron + 2 + 3 for points in IDD: + 4 if not (-points in IDD): + 5 print("first axiom violated") + +NameError: name 'icosidodecahedron' is not defined +~~~ +{: .error} diff --git a/_episodes/10-conjugacy-classes.md b/_episodes/10-conjugacy-classes.md new file mode 100644 index 0000000..f8a2a4c --- /dev/null +++ b/_episodes/10-conjugacy-classes.md @@ -0,0 +1,43 @@ +--- +title: Conjugacy Classes +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- + + +~~~ +cc = [] + + + +for i in range(4): + for j in range(4): + print("coset", i, j) + print(g[i] * g[j] * g_inverse[i]) + print(g[j]) + +~~~ +{: .source .python} + +~~~ +('coset', 0, 0) + +~~~ +{: .output} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 6 for j in range(Integer(4)): + 7 print("coset", i, j) +----> 8 print(g[i] * g[j] * g_inverse[i]) + 9 print(g[j]) + +NameError: name 'g' is not defined +~~~ +{: .error} diff --git a/_episodes/11-number-and-dimensions-of-irreducible-representations.md b/_episodes/11-number-and-dimensions-of-irreducible-representations.md new file mode 100644 index 0000000..19925ba --- /dev/null +++ b/_episodes/11-number-and-dimensions-of-irreducible-representations.md @@ -0,0 +1,9 @@ +--- +title: Number and Dimensions of Irreducible Representations +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- diff --git a/_episodes/12-pymol-visualisation.md b/_episodes/12-pymol-visualisation.md new file mode 100644 index 0000000..1830c89 --- /dev/null +++ b/_episodes/12-pymol-visualisation.md @@ -0,0 +1,43 @@ +--- +title: More advanced Caspar-Klug orbits and pymol visualisation +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- + + +~~~ +seeds = [[ 0.904721509025590, 0.0879675935421300, 0.416822136685000], +[0.979660168810660, 0.0952540054366200, 0.176614348770000], +[0.894764055651420, 0.317512115546100, 0.313979842320000], +[0.986175314321600, 0.165705309322800, 0]] +seeds + +T4capsid = [] + +for seed in seeds: + for i in range(count_even): + T4capsid.append(g_even[i] * seed) + +point3d(T4capsid, size=100) + + +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () + 8 + 9 for seed in seeds: +---> 10 for i in range(count_even): + 11 T4capsid.append(g_even[i] * seed) + 12 + +NameError: name 'count_even' is not defined +~~~ +{: .error} diff --git a/_episodes/13-cartan-matrix.md b/_episodes/13-cartan-matrix.md new file mode 100644 index 0000000..c88dbae --- /dev/null +++ b/_episodes/13-cartan-matrix.md @@ -0,0 +1,119 @@ +--- +title: Cartan matrix and Perron-Frobenius eigenvector +teaching: 30 +exercises: 0 +questions: +- "..." +objectives: +- "..." +--- + + +~~~ +# define Cartan matrix - function of arbitrary number of vectors? + +# find eigenvalues using SAGE routine + +# find the Perron-Frobenius eigenvalue + +def Cartan_matrix(Delta, symbolic=False): + """ + Return the Cartan matrix for a simple system + + INPUT: + + - ``Delta`` -- list of vectors or any iterable that can be turned into a vector + - + + EXAMPLES:: + + sage: Delta = ((1, 0, 0)), ((0, 1, 0)), ((0, 0, 1)) + sage: C = Cartan_matrix(Delta) + sage: C + [2 0 0] + [0 2 0] + [0 0 2] + """ + Delta=[vector(v) for v in Delta] + + M = matrix([[2 / w.dot_product(w) * v.dot_product(w) for w in Delta] for v in Delta]) + + if symbolic: + M = M.apply_map(expand) + + return M +~~~ +{: .source .python} + + +~~~ +Delta = ((0, 1, 0)), ((-1/4*(1+sqrt(5)), -1/2, 1/4*(1-sqrt(5)))), ((1, 0, 0)) + +Delta + +C = Cartan_matrix(Delta, symbolic=True) +C +~~~ +{: .source .python} + + + +~~~ +[ 2 -1 0] +[ -1 2 -1/2*sqrt(5) - 1/2] +[ 0 -1/2*sqrt(5) - 1/2 2] +~~~ +{: .output} + + + + +~~~ +E = C.eigenvectors_right() +E + + +A=QQbar(E[1][1][0][2]) +A +E +~~~ +{: .source .python} + + + +~~~ +[(-1/2*sqrt(2*sqrt(5) + 10) + 2, + [(1, 1/2*sqrt(2*sqrt(5) + 10), 1/2*sqrt(5) + 1/2)], + 1), + (1/2*sqrt(2*sqrt(5) + 10) + 2, + [(1, -1/2*sqrt(2*sqrt(5) + 10), 1/2*sqrt(5) + 1/2)], + 1), + (2, [(1, 0, -1/2*sqrt(5) + 1/2)], 1)] +~~~ +{: .output} + + + + +~~~ +# find PF eigenvector i.e. all coefficients of the same sign +for i in range(3): + tmp = E[i][1][0] + if all (x * tmp[0] > 0 for x in tmp): + print(tmp) + +~~~ +{: .source .python} + +~~~ +(1, 1/2*sqrt(2*sqrt(5) + 10), 1/2*sqrt(5) + 1/2) + +~~~ +{: .output} + + +~~~ +# find duals to roots (weights), construct two vectors from two-colouring of the graph and the PF evec just found; orthonormalise and project root system into this plane + +~~~ +{: .source .python}