{ "cells": [ { "cell_type": "markdown", "id": "f1ce2938-bc3e-47bf-8add-b538b1061acd", "metadata": {}, "source": [ "# Curriculum Bridges\n", "\n", "One of my goals is to find ways to catalyze the desire to explore higher mathematics, by creating onramps from lower math, for example high school math. \n", "\n", "Just as left and right (negative and positive) infinity might be unified in a projective geometry, so might the higher meet the lower math in the realm of philosophy and curriculum design, the latter being a practical expression, one of philosophy's fruits, at least potentially.\n", "\n", "### Branching from Graph Theory\n", "\n", "For example, Graph Theory is inherently accessible and is already making inroads in that kids get recruited into competitive programming teams, with encouraging parents hoping for scholarships or at least a stronger college admissions portfolio, not that the kids themselves don't share this agenda. \n", "\n", "So last year I found myself plowing through Dijkstra's Algorithm and myriad others, because these feature in CP (competitive programming). Academically, this material gets put in an elective called Algorithms and Data Structures. My students were 8th graders, with Python and/or C++ skills.\n", "\n", "Fano's Plane reminds me of the Konigsberg Bridge problem, which is often presented as a quasi-realistic map of Konigsberg. Examples:" ] }, { "cell_type": "markdown", "id": "1d21c7bc-2de3-4adb-9d26-47be14bc5b9d", "metadata": {}, "source": [ "![Konigberg Bridge](https://www.phymath.com/Physics%20Articles/2018/Konigsberg/figure%202.jpg)\n", "\n", "
\n", "\n", "![Slide](https://cdn.slidesharecdn.com/ss_thumbnails/koningsbergproblem-140215072342-phpapp02-thumbnail-4.jpg)" ] }, { "cell_type": "markdown", "id": "1f2814b0-3b3a-4f4d-a1e0-07c0ef17c1e5", "metadata": {}, "source": [ "### Fano's Plane" ] }, { "cell_type": "markdown", "id": "46d55cdf-ce87-469b-bddb-f1c0f284dfaf", "metadata": {}, "source": [ "However tempting it might be to present Fano's Plane as a manicured garden, with a canal boat going in a circle, with mini-Rialto bridges along inclined walkways from corners of an outer triangle to the raised central mound, with steps down to the opposite edge midpoints and a subway system around the perimeter... \n", "\n", "However tempting, that's a misreading.\n", "\n", "A Fano line is more like a set, in that we don't identify which of its three points has to be \"between the other two\".  \n", "\n", "Three points defining a line is more like three people having the same political party affiliation.  \n", "\n", "When any two people stand together, a unique common party affiliation will be evident, along with a 3rd person in the same party. \n", "\n", "Each person is in exactly three parties etc.  \n", "\n", "The Fano System here described is the simplest one, when we have 7 persons i.e. when n = 2 and persons = $n^{2} + n + 1$.  n might go higher. *Mathematica* has demos that work through n = 9. " ] }, { "cell_type": "markdown", "id": "715c6b16-6d3e-4ff4-b377-6298926bd950", "metadata": {}, "source": [ "![puzzle](https://www.mathpuzzle.com/MAA/47-Fano/Fano124.gif)" ] }, { "cell_type": "markdown", "id": "c432e84c-66bc-44fe-8013-d4bb754935a9", "metadata": {}, "source": [ "The diagram on the right, called an incidence diagram, is clearer about the overall symmetry, once we take away whether a station is one or two stops away. The incidence diagram shows what persons are \"incident to\" (members of) what party, and what parties are \"incident to\" (contain) which folks.\n", "\n", "If you're at station 3 and want to reach station 1, simply jump on the blue line and take it there, without having to go through station 7 along the way.\n", "\n", "In this sense, every station is connected to exactly six others. Every person, with three political affiliations, is connected to six others, two more in each party." ] }, { "cell_type": "code", "execution_count": 6, "id": "36786c41-4ec2-481c-a46f-9f1f4cca8766", "metadata": {}, "outputs": [], "source": [ "# use sets, not lists\n", "L1 = {5, 2, 3}\n", "L2 = {3, 7, 1}\n", "L3 = {1, 6, 5}\n", "L4 = {6, 4, 3}\n", "L5 = {2, 4, 1}\n", "L6 = {7, 4, 5}\n", "L7 = {6, 7, 2}" ] }, { "cell_type": "code", "execution_count": 4, "id": "7b3de0cd-9032-4124-adcc-92899d33dc0e", "metadata": {}, "outputs": [], "source": [ "import itertools as it" ] }, { "cell_type": "code", "execution_count": 31, "id": "df6526e7-d4d8-4f07-9fa9-94210de93386", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{1, 2, 3, 4, 5, 6, 7}" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# every intersection of two distinct lines is the set of all points\n", "set([list(a.intersection(b))[0] \n", " for a, b in it.product((L1, L2, L3, L4, L5, L6, L7), repeat=2) \n", " if a != b])" ] }, { "cell_type": "code", "execution_count": 39, "id": "a3bc0554-e7d8-48a8-9acc-1d1b0f8398a2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "3\n", "3\n", "3\n", "3\n", "3\n", "3\n" ] } ], "source": [ "# every point occurs in 3 distinct lines\n", "for i in range(1, 8):\n", " print(sum([i in line for line in (L1, L2, L3, L4, L5, L6, L7)]))" ] }, { "cell_type": "code", "execution_count": 2, "id": "a47842f9-160f-4edd-8866-2002e75d1449", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "{6, 7}.issubset( {2, 7, 6} )" ] }, { "cell_type": "code", "execution_count": 17, "id": "5b53ba2b-2245-400c-aeb3-a7aa4f157a67", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{1, 2}\n", "{1, 3}\n", "{1, 4}\n", "{1, 5}\n", "{1, 6}\n", "{1, 7}\n", "{2, 3}\n", "{2, 4}\n", "{2, 5}\n", "{2, 6}\n", "{2, 7}\n", "{3, 4}\n", "{3, 5}\n", "{3, 6}\n", "{3, 7}\n", "{4, 5}\n", "{4, 6}\n", "{4, 7}\n", "{5, 6}\n", "{5, 7}\n", "{6, 7}\n", "All good! 21 trials\n" ] } ], "source": [ "# every pair occurs only once in any block\n", "pairs = it.combinations({1, 2, 3, 4, 5, 6, 7}, 2)\n", "trials = 0\n", "for p in pairs:\n", " p = set(p)\n", " print(p)\n", " trials += 1\n", " total = sum(list(map(lambda q: p.issubset(q), (L1, L2, L3, L4, L5, L6, L7))))\n", " if total != 1:\n", " raise Exception\n", "print(f\"All good! {trials} trials\")" ] }, { "cell_type": "markdown", "id": "f667da7c-142e-423f-8d1d-5845d6aadc6b", "metadata": {}, "source": [ "* [Development of Group Theory](https://mathshistory.st-andrews.ac.uk/HistTopics/Development_group_theory/)\n", "* [Fano Plane as Steiner System](https://en.wikipedia.org/wiki/Steiner_system)\n", "* [Steiner System](https://en.wikipedia.org/wiki/Steiner_system#The_Steiner_system_S(5,_8,_24))\n", "* [Block Design](https://en.wikipedia.org/wiki/Block_design)\n", "* [Polya Theory](http://www-cs-students.stanford.edu/~blynn//polya/)\n", "* [Lecture on Sporadic Groups](https://youtu.be/B4NSw_CSErM)\n", "* [More Context on M4W](https://www.freelists.org/post/math4wisdom/Circuit-Diagrams-eg-Fanos)\n", "* [Followup YouTube](https://youtu.be/zq2IjIA-SiE)" ] }, { "cell_type": "markdown", "id": "795a8774-06eb-46ce-bf4e-73328826c2a9", "metadata": {}, "source": [ "### Isomorphism" ] }, { "cell_type": "markdown", "id": "f3596430-6f73-499d-8823-d3e03965c49b", "metadata": {}, "source": [ "The sculpture below is in some sense isomorphic to the Fano Circuit Diagram. \n", "\n", "In another sense, it highlights differences among vertices we are meant to overlook e.g. the centrality of one of them, in terms of it being but one hop from all the rest. \n", "\n", "Fano lines are better thought of as \"bags\" or \"blocks\", not subway lines, in having no \"middle points\" as distinct from \"termini\". \n", "\n", "In the simplest Fano system, represented in Steiner notation as S(2, 3, 7), every pair of persons is uniquely in one of the 3-person political parties, and we have 7 such persons in 7 such parties. Any given person will be in exactly three political parties (or blocks).\n", "\n", "This pattern may be generated in 168 ways, by swapping around party affiliation." ] }, { "cell_type": "markdown", "id": "1f52e2d7-5dd6-4298-a250-002115a79589", "metadata": {}, "source": [ "![isomorphic](https://images3.sw-cdn.net/product/picture/674x501_18401789_8312794_1491834150.jpg)" ] }, { "cell_type": "markdown", "id": "4e6eda4b-fcc7-4a02-a615-903bb49b367b", "metadata": {}, "source": [ "![](https://tony5m17h.net/heptafano.gif)" ] }, { "cell_type": "markdown", "id": "4e3b3438-d148-48de-ac68-2f0607f5a75f", "metadata": {}, "source": [ "\"Projective planes are known to exist for all orders which are prime numbers or powers of primes.\" (Block Designs, Wikipedia)" ] }, { "cell_type": "markdown", "id": "d70c525f-4952-4a6d-8393-6460ef0516be", "metadata": {}, "source": [ "### Back to Subways" ] }, { "cell_type": "code", "execution_count": 14, "id": "cf5550db-928c-4ed9-9c3f-b370850f20dd", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np" ] }, { "cell_type": "markdown", "id": "b9bf06e6-ebc7-4480-866d-b4ee09a04511", "metadata": {}, "source": [ "If we were to go ahead with the subway metaphor, and interpret the above picture quite literally, we might go with something like this:" ] }, { "cell_type": "code", "execution_count": 37, "id": "9cdbda3d-0192-4e07-a5a0-7adb7396a2b2", "metadata": {}, "outputs": [], "source": [ "# seven stations\n", "stations = {'pos_x': ( 1, 0, 0), 'pos_y': ( 0, 1, 0), 'pos_z': ( 0, 0, 1),\n", " 'neg_x': (-1, 0, 0), 'pos_z': ( 0, 0, 1), 'neg_z': ( 0, 0, -1),\n", " 'xyz_0': ( 0, 0, 0)}\n", "\n", "# seven subway routes\n", "routes = {\"V\": ('pos_x', 'pos_y', 'neg_z'),\n", " \"I\": ('pos_y', 'pos_z', 'neg_x'),\n", " \"B\": ('neg_x', 'neg_y', 'neg_z'),\n", " \"G\": ('neg_y', 'pos_z', 'pos_x'),\n", " \"Y\": ('pos_x', 'xyz_0', 'neg_x'),\n", " \"O\": ('pos_y', 'xyz_0', 'neg_y'),\n", " \"R\": ('pos_z', 'xyz_0', 'neg_z')\n", " }" ] }, { "cell_type": "code", "execution_count": 38, "id": "3f09682c-a893-46e9-a7af-c3f1fba453f1", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
Vpos_xpos_yneg_z
Ipos_ypos_zneg_x
Bneg_xneg_yneg_z
Gneg_ypos_zpos_x
Ypos_xxyz_0neg_x
Opos_yxyz_0neg_y
Rpos_zxyz_0neg_z
\n", "
" ], "text/plain": [ " 0 1 2\n", "V pos_x pos_y neg_z\n", "I pos_y pos_z neg_x\n", "B neg_x neg_y neg_z\n", "G neg_y pos_z pos_x\n", "Y pos_x xyz_0 neg_x\n", "O pos_y xyz_0 neg_y\n", "R pos_z xyz_0 neg_z" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(routes).T\n", "df" ] }, { "cell_type": "markdown", "id": "970f18d5-218f-456a-82ba-812971a1b32b", "metadata": {}, "source": [ "![boy_girl](http://work.tree-of-life.dk/Fano-Plane-Planet-Trigram-xun-down.jpg)" ] }, { "cell_type": "markdown", "id": "d3344bb1-11f9-41a1-b320-3b67abf01628", "metadata": {}, "source": [ "![girl_boy](http://work.tree-of-life.dk/Fano-Plane-Planet-Trigram-Kan-down.jpg)" ] }, { "cell_type": "markdown", "id": "dc5469ab-d67e-4246-87c8-2beb7a063ed3", "metadata": {}, "source": [ "You may be able to force yourself to see Zhen-Qian-Xun as an X axis, at 90 degrees to both the Y axis (Dui-Qian-Gen) and the Z axis (Li-Qian-Kan).\n", "\n", "Space divides into eight octants. Each octant is described by a right tetrahedron. \n", "\n", "The tetrahedron facing us is Quian-Xun-Dui-Li and does not form a closed tetrahedron. Qian reaches these other stops in one hop, but the other three stations are not directly connected. \n", "\n", "However, Qian-Gen-Zhen-Li forms a closed tetrahedron. Each is a single hop from the others.\n", "\n", "Lets categorize each octant in terms of open or closed tetrahedrons." ] }, { "cell_type": "code", "execution_count": 9, "id": "e044ebfd-d590-45b4-8d24-e99604660073", "metadata": {}, "outputs": [], "source": [ "tetrahedra = {\n", " ('Qian', 'Xun', 'Dui', 'Li') : \"OPEN\", # + + +\n", " ('Qian', 'Xun', 'Gen', 'Li') : \"OPEN\", # + - +\n", " ('Qian', 'Gen', 'Zhen', 'Li') : \"CLOSED\", # - - +\n", " ('Qian', 'Zhen', 'Dui', 'Li') : \"OPEN\", # - + +\n", " ('Qian', 'Xun', 'Dui', 'Kan'): \"OPEN\", # + + -\n", " ('Qian', 'Xun', 'Gen', 'Kan'): \"CLOSED\", # + - -\n", " ('Qian', 'Gen', 'Zhen', 'Kan'): \"CLOSED\", # - - -\n", " ('Qian', 'Zhen', 'Dui', 'Kan'): \"CLOSED\", # - + -\n", "}" ] }, { "cell_type": "markdown", "id": "a0fd98fe-d908-48d0-b5a1-2ef31e0b1499", "metadata": {}, "source": [ "We're actually free to delete the Zhen-Gen segment, or any of the segments around the inner circle, while still preserving the seven lines and their relationships. \n", "\n", "Stylistically, it's nice to make the center line a circle, but these \"lines\" are really blocks and their being connected together collineraly simply means \"in the same bag\" or \"party\"." ] }, { "cell_type": "markdown", "id": "c9717b20-e957-459c-8cd5-bb40e8332d59", "metadata": {}, "source": [ "[More use of the Subway Metaphor](https://nbviewer.org/github/4dsolutions/Python5/blob/master/S_Train.ipynb)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.12" } }, "nbformat": 4, "nbformat_minor": 5 }