{"id":1207,"date":"2021-06-25T23:30:31","date_gmt":"2021-06-26T03:30:31","guid":{"rendered":"http:\/\/aristotle2digital.blogwyrm.com\/?p=1207"},"modified":"2021-11-25T21:54:24","modified_gmt":"2021-11-26T02:54:24","slug":"category-theory-6-coding-up-mappings","status":"publish","type":"post","link":"https:\/\/aristotle2digital.blogwyrm.com\/?p=1207","title":{"rendered":"Category Theory 6 &#8211; Coding Up Mappings"},"content":{"rendered":"\n<p>This month\u2019s article is a bit of a departure from the previous installments on category theory in that it deals with the computational side of things rather than the theoretical side of things.&nbsp; But, as the recent columns have shown, it is typically the case that working with specific examples facilitates a basic understanding of the general.<\/p>\n\n\n\n<p>As a case in point, consider the set of all possible mappings between the sets $A$, $B$, and $C$, an example of which is shown below<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"796\" height=\"857\" src=\"http:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2021\/06\/A_to_B_to_C.png\" alt=\"\" class=\"wp-image-1222\" srcset=\"https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2021\/06\/A_to_B_to_C.png 796w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2021\/06\/A_to_B_to_C-279x300.png 279w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2021\/06\/A_to_B_to_C-768x827.png 768w\" sizes=\"auto, (max-width: 796px) 100vw, 796px\" \/><\/figure>\n\n\n\n<p>where $A$ has three elements $\\left\\{ a_1, a_2, a_3\\right\\}$, $B$ has two elements $\\left\\{ b_1, b_2 \\right\\}$, and $C$ has three elements $\\left\\{ c_1, c_2, c_3\\right\\}$.&nbsp; Although we\u2019ve focused on automorphisms wherein we identified $A$ and $C$ as the same set, the general case will be what we tackle here.&nbsp;<\/p>\n\n\n\n<p>Even though these sets are small, the combinatorics associated with all possible mappings quickly daunts the use of paper and pencil.&nbsp; There are 8 distinct mappings $f:A \\rightarrow B$ and 9 distinct mappings from $g:B \\rightarrow C$ leaving 72 mappings in total for the composition.&nbsp; Obviously this situation calls for some basic computing.<\/p>\n\n\n\n<p>Despite the simplicity of the discussion up to date in Lawvere and Schanuel, one thing they didn\u2019t do is actually adopt terminology well-suited to writing computer code.\u00a0 The word \u2018set\u2019, of course, is perfect for describing the collection, so that\u2019s okay, but what to call the contents of each set.\u00a0 The typical mathematical terminology would be members or elements but the former has an object-oriented connotation that would tend to obscure things while the latter is simply too generic.\u00a0 In addition, both of those are rather long to type and really don\u2019t speak to what the diagram looks like.\u00a0 For the purposes here, things like $a_3$ or $b_1$ will be called dots since they are represented as such in the diagrams.\u00a0 At this point, their terminology fails and the thing that connects two dots doesn\u2019t even have a name in their bestiary.\u00a0 Since it is drawn as an arrow in the diagrams, that is the name that will be used in the code.\u00a0 The end of the arrow without the point will be called the outgoing side; the end with the point is the incoming side.<\/p>\n\n\n\n<p>Using this terminology, we then say that:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>each set is made up of dots,<\/li><li>each dot supports one outgoing arrow<\/li><li>each dot can receive any number of incoming arrows, including zero<\/li><li>a mapping is a collection of arrows<\/li><\/ul>\n\n\n\n<p>The python programming language is an excellent choice and everything that follows is done in version 3.x within the Jupyter notebook framework.&nbsp; The sets discussed above are represented as python lists:<\/p>\n\n\n\n<div class = \"myQuoteDiv\">\n  <ul>\n     <li><pre> Aset = ['a1','a2','a3']<\/pre>\n     <li><pre> Bset = ['b1','b2']<\/pre>\n     <li><pre> Cset = ['c1','c2','c3']<\/pre>\n  <\/ul>\n<\/div>\n\n\n\n<p>The first function<\/p>\n\n\n\n<div class=\"myQuoteDiv\">\n<pre>def generate_arrows(set1,set2):\n    arrows = []\n    for dot1 in set1:\n        for dot2 in set2:\n            arrows.append(dot1+'-&gt;'+dot2)\n    return arrows\n<\/pre>\n<\/div>\n\n\n\n<p>returns a list of all possible ways to draw arrows from set1 to set2.\u00a0 Applying this function to sets $A$ and $B$ gives:<\/p>\n\n\n\n<div class=\"myQuoteDiv\">\n  <pre>generate_arrows(Aset,Bset)<\/pre>\n  \n  <pre>['a1-&gt;b1', 'a1-&gt;b2', 'a2-&gt;b1', 'a2-&gt;b2', 'a3-&gt;b1', 'a3-&gt;b2']<\/pre>\n<\/div>\n\n\n\n<p>This helper function is used by the larger function<\/p>\n\n\n\n<div class=\"myQuoteDiv\">\n<pre>def generate_mappings(set1,set2):\n    import itertools as it\n    \n    arrows      = generate_arrows(set1,set2)\n    mapping_gen = it.combinations(arrows,len(set1))\n    mappings    = []\n    for candidate in mapping_gen:\n        count = []\n        for i,dot1 in zip(range(len(set1)),set1):\n            count.append(0)\n            for arrow in candidate:\n                if dot1 in arrow:\n                    count[i] += 1\n        if min(count) != 0:\n            mappings.append(candidate)\n    return mappings\n<\/pre>\n<\/div>\n\n\n\n<p>The function generate_mappings depends on the itertools module in python to determine all the possible combinations to make a mapping.\u00a0 When applied to $A$ and $B$, the output of<\/p>\n\n\n\n<div class=\"myQuoteDiv\">\n<pre>A_to_B = generate_mappings(Aset,Bset) \n\n[('a1-&gt;b1', 'a2-&gt;b1', 'a3-&gt;b1'),\n ('a1-&gt;b1', 'a2-&gt;b1', 'a3-&gt;b2'),\n ('a1-&gt;b1', 'a2-&gt;b2', 'a3-&gt;b1'),\n ('a1-&gt;b1', 'a2-&gt;b2', 'a3-&gt;b2'),\n ('a1-&gt;b2', 'a2-&gt;b1', 'a3-&gt;b1'),\n ('a1-&gt;b2', 'a2-&gt;b1', 'a3-&gt;b2'),\n ('a1-&gt;b2', 'a2-&gt;b2', 'a3-&gt;b1'),\n ('a1-&gt;b2', 'a2-&gt;b2', 'a3-&gt;b2')]\n<\/pre>\n<\/div>\n\n\n\n<p>is a list 8 elements in length as expected.\u00a0 Each line is one possible mapping between the two sets.\u00a0 Likewise, the total listing of all mappings from $B$ to $C$\n\n\n\n<div class=\"myQuoteDiv\">\n<pre>[('b1-&gt;c1', 'b2-&gt;c1'),\n ('b1-&gt;c1', 'b2-&gt;c2'),\n ('b1-&gt;c1', 'b2-&gt;c3'),\n ('b1-&gt;c2', 'b2-&gt;c1'),\n ('b1-&gt;c2', 'b2-&gt;c2'),\n ('b1-&gt;c2', 'b2-&gt;c3'),\n ('b1-&gt;c3', 'b2-&gt;c1'),\n ('b1-&gt;c3', 'b2-&gt;c2'),\n ('b1-&gt;c3', 'b2-&gt;c3')]\n<\/pre>\n<\/div>\n\n\n\n<p>has 9 possibilities, also as expected.<\/p>\n\n\n\n<p>In order to compose functions, we need a way of combining expressions like &#8216;a1-&gt;b1&#8217; and &#8216;b1-&gt;c3&#8217; to get \u2018a1-&gt;c3\u2019.&nbsp; This is provided by<\/p>\n\n\n\n<div class=\"myQuoteDiv\">\n<pre>def compose_arrows(arrow1,arrow2):\n    head1,targ1 = arrow1.split('-&gt;')\n    head2,targ2 = arrow2.split('-&gt;')\n    if targ1 == head2:\n        return head1+'-&gt;'+targ2\n    else:\n        return False\n<\/pre>\n<\/div>\n\n\n\n<p>Note that if the middle term is not the same the function returns a False.<\/p>\n\n\n\n<p>The functionality is rounded out with the<\/p>\n\n\n\n<div class=\"myQuoteDiv\">\n<pre>def compose_mappings(mappings1,mappings2):\n    mappings = []\n    for f in mappings1:\n        for g in mappings2:\n            compositions = []\n            for f_arrow in f:\n                for g_arrow in g:\n                     compositions.append(compose_arrows(f_arrow,g_arrow))\n            while(False in compositions):\n                compositions.remove(False)\n            mappings.append(tuple(compositions))\n    return mappings\n<\/pre>\n<\/div>\n\n\n\n<p>which composes two lists of mappings. \u00a0Plugging in the previous two lists of mappings (mappings = compose_mappings(A_to_B,B_to_C)) gives a list with 72 elements.\u00a0 Of course, given the sizes of $A$ and $C$ there can be, at most, only 27 unique ones.\u00a0 The repetitions are trivially removed by casting the list to a set and then casting it back to a list.\u00a0 Doing this gives the following list of unique mappings:<\/p>\n\n\n\n<div class=\"myQuoteDiv\">\n<pre>[('a1-&gt;c1', 'a2-&gt;c2', 'a3-&gt;c1'),\n ('a1-&gt;c2', 'a2-&gt;c3', 'a3-&gt;c2'),\n ('a1-&gt;c3', 'a2-&gt;c2', 'a3-&gt;c3'),\n ('a1-&gt;c2', 'a2-&gt;c1', 'a3-&gt;c2'),\n ('a1-&gt;c1', 'a2-&gt;c3', 'a3-&gt;c1'),\n ('a1-&gt;c3', 'a2-&gt;c3', 'a3-&gt;c1'),\n ('a1-&gt;c2', 'a2-&gt;c2', 'a3-&gt;c3'),\n ('a1-&gt;c1', 'a2-&gt;c1', 'a3-&gt;c1'),\n ('a1-&gt;c3', 'a2-&gt;c1', 'a3-&gt;c1'),\n ('a1-&gt;c3', 'a2-&gt;c2', 'a3-&gt;c2'),\n ('a1-&gt;c3', 'a2-&gt;c1', 'a3-&gt;c3'),\n ('a1-&gt;c1', 'a2-&gt;c1', 'a3-&gt;c3'),\n ('a1-&gt;c3', 'a2-&gt;c3', 'a3-&gt;c3'),\n ('a1-&gt;c1', 'a2-&gt;c3', 'a3-&gt;c3'),\n ('a1-&gt;c2', 'a2-&gt;c1', 'a3-&gt;c1'),\n ('a1-&gt;c1', 'a2-&gt;c1', 'a3-&gt;c2'),\n ('a1-&gt;c2', 'a2-&gt;c2', 'a3-&gt;c1'),\n ('a1-&gt;c3', 'a2-&gt;c3', 'a3-&gt;c2'),\n ('a1-&gt;c2', 'a2-&gt;c3', 'a3-&gt;c3'),\n ('a1-&gt;c2', 'a2-&gt;c2', 'a3-&gt;c2'),\n ('a1-&gt;c1', 'a2-&gt;c2', 'a3-&gt;c2')]\n<\/pre>\n<\/div>\n\n\n\n<p>There are 21 in all, 6 less than the 27 possible mappings between $A$ and $C$.&nbsp; The missing ones correspond to the one-to-one mappings between $A$ and $C$ (i.e., $a_1 \\rightarrow c_1$, $a_2 \\rightarrow c_2$, $a_3 \\rightarrow c_3$ and permutations).&nbsp; Of course, these results drive home the point that, since the size of $B$ is smaller than $A$ and $C$, there is simply no way to support a one-to-one mapping.<\/p>\n\n\n\n<p>One can experiment with replacing $B$ with a 4-element set $D$.&nbsp; Doing so gives the expected 27 unique mappings $f: A \\rightarrow C$ (at the expense of calculating 5184 possible combinations of going from $A$ to $C$ with a layover at $D$.&nbsp; Obviously nobody should want to do this by hand.<\/p>\n\n\n\n<p>So there you have it:&nbsp; while not theoretically glamorous, functionality like this really allows for an exploration that couldn\u2019t be done by hand.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This month\u2019s article is a bit of a departure from the previous installments on category theory in that it deals with the computational side of things rather than the theoretical&#8230; <a class=\"read-more-button\" href=\"https:\/\/aristotle2digital.blogwyrm.com\/?p=1207\">Read more &gt;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1207","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/posts\/1207","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1207"}],"version-history":[{"count":0,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/posts\/1207\/revisions"}],"wp:attachment":[{"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1207"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1207"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1207"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}