︠50fba585-acc5-4836-a3ed-f70747892be9i︠ %html
Applied Discrete Structures by Alan Doerr & Kenneth Levasseur is licensed under a Creative Commons Attribution - Noncommercial - ShareAlike 3.0 United States License.
This document describes the basic ways in which a relation can be represented with Sage. These topics are introduced in chapter 6 of Applied Discrete Structures.
Example 1. Consider the "random relation" the set of digits, 0 through 9, which each pair of digits is related with probablity 0.25. The list of digits, which we call A, is created using range. In Python, the default first number in range is 0 and the list specification is "open on the right" so that the upper limit is not included. Therefore range(10) produces the digits 0 through 9.
︡c8333ad8-dc8e-4a19-9e60-fd92cb8a0425︡{"done":true,"html":"Applied Discrete Structures by Alan Doerr & Kenneth Levasseur is licensed under a Creative Commons Attribution - Noncommercial - ShareAlike 3.0 United States License.
\nThis document describes the basic ways in which a relation can be represented with Sage. These topics are introduced in chapter 6 of Applied Discrete Structures.
\n\nExample 1. Consider the \"random relation\" the set of digits, 0 through 9, which each pair of digits is related with probablity 0.25. The list of digits, which we call A, is created using range. In Python, the default first number in range is 0 and the list specification is \"open on the right\" so that the upper limit is not included. Therefore range(10) produces the digits 0 through 9.
"} ︠40596bbe-62b1-4070-bb68-8cb248867d47s︠ ︡cea3f2c4-aa83-42ab-b809-d367e79fcdbc︡{"done":true}︡ ︠21c70175-c391-4f81-b3a0-1206b75b1659s︠ A=range(10) A ︡b79f0c92-7022-4064-bbb4-feaa13bfb7c1︡{"stdout":"[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n"}︡{"done":true}︡ ︠e8b0b208-99c6-453c-92b3-250ea5e2b9b7i︠ %htmlHere is the complete list of pairs from which we draw approximately 25% for our relation.
︡9c489c67-6444-4df6-8f9a-da86ebf4d1a4︡{"done":true,"html":"Here is the complete list of pairs from which we draw approximately 25% for our relation.
"} ︠5e58657b-5b49-4142-9846-2e8748f5a492s︠ tuples(A,2) ︡1bf86bdd-9972-4ea8-8235-a43b931cbb3f︡{"stdout":"[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9)]\n"}︡{"done":true}︡ ︠5d6c0600-79f4-4e60-bce5-5679f9d3a811i︠ %htmlThe result of the next expression is random. The output represents a fundamental way to represent any relation as a set of ordered pairs.
︡34f3ae44-3310-44bc-a982-825118488a76︡{"done":true,"html":"The result of the next expression is random. The output represents a fundamental way to represent any relation as a set of ordered pairs.
"} ︠6fbe8307-58e5-4c2a-b0be-165651066db0s︠ r=random_sublist(tuples(A,2),0.25) r ︡ac931ddc-2d46-4526-b960-2c5fc1dccab4︡{"stdout":"[(0, 0), (0, 1), (0, 4), (0, 8), (1, 5), (1, 6), (1, 7), (2, 2), (2, 6), (2, 7), (3, 1), (3, 4), (3, 6), (3, 8), (4, 5), (5, 1), (5, 2), (5, 5), (5, 6), (5, 7), (5, 9), (6, 1), (6, 3), (6, 9), (7, 5), (7, 8), (8, 3), (8, 4), (8, 7), (9, 0), (9, 3), (9, 8), (9, 9)]\n"}︡{"done":true}︡ ︠464cfea5-2d08-4475-9fb4-6bbe659e2678i︠ %htmlThere are several wasy to create a directed graph (DiGraph) in Sage. The most basic as a dictionary. The following code creates a dictionary corresponding to the relation.
︡dcf2a1bc-4bea-49ab-8303-8a89e776fd18︡{"done":true,"html":"There are several wasy to create a directed graph (DiGraph) in Sage. The most basic as a dictionary. The following code creates a dictionary corresponding to the relation.
"} ︠3b67cf22-b829-4dfd-889c-93c096ff993fs︠ rd={} for p in r: if p[0] in rd: rd[p[0]].append(p[1]) else: rd[p[0]]=[p[1]] ︡b14b5bea-40f6-4aa3-805f-d616506117be︡{"done":true}︡ ︠9cea9aca-e3cb-4c6c-b122-2701f4d82f4ci︠ %htmlTo recover the information defined within a (small) dictionary, use the
To recover the information defined within a (small) dictionary, use the
We can plot the graph. For larger relations, the information you get may not be very easy to read, but here it is clear.
︡7a39c0c0-69a8-4641-867e-490fec6d8fae︡{"done":true,"html":"We can plot the graph. For larger relations, the information you get may not be very easy to read, but here it is clear.
"} ︠e795aadb-c9d9-4f63-9103-c0601f4a4677s︠ g.plot() ︡95a7f6d1-b55b-4f99-b1ce-cf4bd3560026︡{"file":{"filename":"/home/user/.sage/temp/project-f351622c-d261-4717-abee-4c0bfa210e88/174/tmp_00D2GJ.svg","show":true,"text":null,"uuid":"63ef3164-12a3-406c-aa4e-499fda628bd1"},"once":false}︡{"done":true}︡ ︠d1586d49-8b27-4f09-85db-eb374da63990s︠ g.density() ︡1c3d43fe-99d5-4b13-9f49-997e4fdfb589︡{"stdout":"33/100\n"}︡{"done":true}︡ ︠ba06f519-acff-4957-af3d-20a5e81adf47s︠ ︡f8e182ac-41e2-4e72-b2df-3443af3e6894︡{"done":true}︡ ︠f78b3c42-c406-4267-a722-be31b2855002s︠ for k in range(10): print k, g.distance(0,k) ︡de22c5c4-f22b-4062-a9fd-07f0db876e2d︡{"stdout":"0 0\n1 1\n2 3\n3 2\n4 1\n5 2\n6 2\n7 2\n8 1\n9 3\n"}︡{"done":true}︡ ︠e6c64b45-587c-4070-93e0-c4cd11c83945s︠ g.distance(9,1) ︡d818227b-e582-4033-a2fa-7f0f6fc2ba5f︡{"stdout":"2\n"}︡{"done":true}︡ ︠8ae231bb-5335-4b6d-b163-3aa355d51efci︠ %htmlHere is the adjacency matrix of the graph. Row i column j is 1 if the edge [i,j] is part of the relation. Recall that in Python, indexing of matrices starts at 0 just as with lists; so the first row is row 0, corresponding to the digit 0. This is why we used the digits as our vertex set.
︡baf8c1be-d2a7-4d67-aa5b-6dd918da0cf4︡{"done":true,"html":"Here is the adjacency matrix of the graph. Row i column j is 1 if the edge [i,j] is part of the relation. Recall that in Python, indexing of matrices starts at 0 just as with lists; so the first row is row 0, corresponding to the digit 0. This is why we used the digits as our vertex set.
"} ︠987231d3-b804-40a4-8599-7afa5c1525f7s︠ R=g.adjacency_matrix() R ︡5b51cdb7-c678-4259-a68a-65b5db749c41︡{"stdout":"[1 1 0 0 1 0 0 0 1 0]\n[0 0 0 0 0 1 1 1 0 0]\n[0 0 1 0 0 0 1 1 0 0]\n[0 1 0 0 1 0 1 0 1 0]\n[0 0 0 0 0 1 0 0 0 0]\n[0 1 1 0 0 1 1 1 0 1]\n[0 1 0 1 0 0 0 0 0 1]\n[0 0 0 0 0 1 0 0 1 0]\n[0 0 0 1 1 0 0 1 0 0]\n[1 0 0 1 0 0 0 0 1 1]\n"}︡{"done":true}︡ ︠fd627ded-c6c3-46cd-8a68-b731aae70a96i︠ %htmlThe square of this matrix gives us information on the number of paths of length 2 between any two vertices.
︡46047ba1-ac55-4b03-b8fc-96bf6d9426da︡{"done":true,"html":"The square of this matrix gives us information on the number of paths of length 2 between any two vertices.
"} ︠546212fb-01f0-46d9-b9e7-d2d6fc73c75bs︠ ︡397904ae-0cef-4bb4-9edb-ed707a8030a4︡{"done":true}︡ ︠399832b8-e45a-4af2-986c-5a8ce92910d4s︠ R*R ︡aeef06d7-82f5-4cbc-8d0e-bdad56a5817d︡{"stdout":"[1 1 0 1 2 2 1 2 1 0]\n[0 2 1 1 0 2 1 1 1 2]\n[0 1 1 1 0 1 1 1 1 1]\n[0 1 0 2 1 2 1 2 0 1]\n[0 1 1 0 0 1 1 1 0 1]\n[1 2 2 2 0 3 3 3 2 3]\n[1 1 0 1 1 1 2 1 2 1]\n[0 1 1 1 1 1 1 2 0 1]\n[0 1 0 0 1 2 1 0 2 0]\n[2 2 0 2 3 0 1 1 3 1]\n"}︡{"done":true}︡ ︠10689a94-d72d-43f5-9688-483a3c605230i︠ %htmlThe cube gives us information on paths of length 3.
︡92b20db8-3520-4532-8677-d123bbab1067︡{"done":true,"html":"The cube gives us information on paths of length 3.
"} ︠8b1e126b-1365-40f8-bdc5-88ce0710f4c6s︠ R*R*R ︡9bc1eadd-459b-43dd-919e-2fe5034d6971︡{"stdout":"[1 5 2 2 3 7 4 4 4 3]\n[2 4 3 4 2 5 6 6 4 5]\n[1 3 2 3 2 3 4 4 3 3]\n[1 5 2 2 2 6 5 3 5 4]\n[1 2 2 2 0 3 3 3 2 3]\n[4 9 5 8 5 8 9 9 9 9]\n[2 5 1 5 4 4 3 4 4 4]\n[1 3 2 2 1 5 4 3 4 3]\n[0 3 2 3 2 4 3 5 0 3]\n[3 5 0 5 7 6 4 5 6 2]\n"}︡{"done":true}︡ ︠7964e2f8-ee72-4bb3-baaf-690b2e63b25di︠ %htmlThe matrices above are technically not adjacencly matrices since they are not 0-1 matrices. See Example 3, below, for how to remedy this situation.
︡3dca88f1-8799-43cb-b14d-12487f4482da︡{"done":true,"html":"The matrices above are technically not adjacencly matrices since they are not 0-1 matrices. See Example 3, below, for how to remedy this situation.
"} ︠048b175c-620b-4184-a2db-3fe6c229e19cs︠ g.transitive_closure().adjacency_matrix() ︡c856c4be-ed0a-4e45-82fe-d14ee1f8d286︡{"stdout":"[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n[1 1 1 1 1 1 1 1 1 1]\n"}︡{"done":true}︡ ︠e22ab453-7ae4-4f06-986d-3efcbdb9aad0i︠ %htmlWe define $r$ on the divisors of 60 by $ a r b \Leftrightarrow \frac{b}{a}$ is a prime.
︡527973fd-614f-4571-989d-6cf6e984f75b︡{"done":true,"html":"\n We define $r$ on the divisors of 60 by $ a r b \\Leftrightarrow \\frac{b}{a}$ is a prime.\n
"} ︠ae34bbda-1be2-4ea8-80d0-2f1562d9dfdes︠ D=60.divisors();D ︡6c836563-bab7-4ca3-a886-c5de5c30276c︡{"stdout":"[1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60]\n"}︡{"done":true}︡ ︠7fdec36f-61c5-44a0-aa61-dca8e3a6128ds︠ r={}; for p in tuples(D,2): if (p[1]//p[0]).is_prime(): if p[0] in r: r[p[0]]=r[p[0]]+[p[1]] else: r[p[0]]=[p[1]] r ︡b38100e8-80e1-4429-97f3-8dc3c4acb99e︡{"stdout":"{1: [2, 3, 5], 2: [4, 5, 6, 10, 15], 3: [6, 10, 15], 4: [10, 12, 15, 20, 30], 5: [10, 12, 15], 6: [12, 15, 20, 30], 10: [20, 30], 12: [30, 60], 15: [30], 20: [60], 30: [60]}\n"}︡{"done":true}︡ ︠2714b1db-a820-4579-b450-b387ce5b2299s︠ DiGraph(r).plot(tree_root=1) ︡9407ad7b-a0a1-4152-998f-c6117c6cddcc︡{"file":{"filename":"/home/user/.sage/temp/project-f351622c-d261-4717-abee-4c0bfa210e88/174/tmp_QPlZTN.svg","show":true,"text":null,"uuid":"41e8224e-0a2b-482d-b427-16548bdcafda"},"once":false}︡{"done":true}︡ ︠b8308d7c-f71a-4d4d-b234-45bc65728d03s︠ ︡68c90065-98b2-4941-bbad-ef6e06290f0d︡{"done":true}︡ ︠e403c440-97e5-4dab-90f8-6fb5d121802di︠ %htmlThis short example illustrates the transitive closure of a relation. We start by defining a relation directly as a simple dictionary. The graph is a "chain" of length 4. ︡7fcdcecf-6759-42fc-9a46-3d4b40c5be5e︡{"done":true,"html":"
\n\n
This short example illustrates the transitive closure of a relation. We start by defining a relation directly as a simple dictionary. The graph is a \"chain\" of length 4."} ︠3dd4c237-c5c6-491d-a613-db7613b53f6cs︠ s={} s[0]=[1] s[1]=[2] s[2]=[3] s[3]=[4] ︡aadd83de-7b5e-4b79-889c-467305da4a91︡{"done":true}︡ ︠e159d849-3349-4a10-a98d-87bba16fb09bs︠ DiGraph(s).plot() ︡cec8d115-075d-4bb1-939a-104c79e7fdf5︡{"file":{"filename":"/home/user/.sage/temp/project-f351622c-d261-4717-abee-4c0bfa210e88/174/tmp_0SK43s.svg","show":true,"text":null,"uuid":"54c5322b-ac76-4fa5-957d-72f13c8ad58d"},"once":false}︡{"done":true}︡ ︠c53c454b-beaa-4d3e-a75a-4db1c5739242i︠ %htmlThe transitive closure of a relation is the smallest transitive relation containing that relation.
︡6385fa75-bcc4-43f1-9875-12ab88207249︡{"done":true,"html":"The transitive closure of a relation is the smallest transitive relation containing that relation.
"} ︠2bf674e5-f4cc-4113-915d-b9481f28dae8s︠ DiGraph(s).transitive_closure().plot() ︡8ac4e064-55ce-4f61-9364-b2bf65b53b82︡{"file":{"filename":"/home/user/.sage/temp/project-f351622c-d261-4717-abee-4c0bfa210e88/174/tmp_HfRGvF.svg","show":true,"text":null,"uuid":"6e6211fb-054b-4b53-bef1-56fb15018add"},"once":false}︡{"done":true}︡ ︠af861f22-0696-446b-a637-c20c3602f1bbi︠ %htmlExample 3. This next example is of a relation that is defined in terms of a boolean function. It is based on mod 17 arithmetic, where $a\cdot b (mod 17)$ is defined to be the remainder when 17 is divided into $a\cdot b$. For example $5\cdot 10 (mod 17) = 16$ since $5\cdot 10 = 50 = 17\cdot 2 + 16$
The set of remainders when you divide by 17 is $\{0, 1, 2, \ldots , 16\}$ but since 17 is prime and we start with the positive remainders, products will never equal 0 mod 17.
︡061581d0-8c89-45c5-85df-cd0a9f820cdf︡{"done":true,"html":"Example 3. This next example is of a relation that is defined in terms of a boolean function. It is based on mod 17 arithmetic, where $a\\cdot b (mod 17)$ is defined to be the remainder when 17 is divided into $a\\cdot b$. For example $5\\cdot 10 (mod 17) = 16$ since $5\\cdot 10 = 50 = 17\\cdot 2 + 16$
\n\nThe set of remainders when you divide by 17 is $\\{0, 1, 2, \\ldots , 16\\}$ but since 17 is prime and we start with the positive remainders, products will never equal 0 mod 17.
"} ︠4401e0ce-b716-48e7-9e4d-b2c99fc55163s︠ B=range(1,17) B ︡5e3270dd-a905-47dd-b46c-1665f460083c︡{"stdout":"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]\n"}︡{"done":true}︡ ︠fa8f2c93-320b-4712-9f1b-b12f2cff58d6i︠ %htmlWe define the relation $m$ on $B$ by $(a, b)\in m$ if $3\cdot x (mod 17) = y$ or $5\cdot x (mod 17) = y$. In Sage, this translates to the following function.
︡877f4a58-9937-4c45-ac0b-f428ffa5944d︡{"done":true,"html":"We define the relation $m$ on $B$ by $(a, b)\\in m$ if $3\\cdot x (mod 17) = y$ or $5\\cdot x (mod 17) = y$. In Sage, this translates to the following function.
"} ︠14e72ce2-1e7f-4745-8973-2b6c8882b7c5s︠ def m(x,y): return (3*x).mod(17)==y or (5*x).mod(17)==y ︡1b599c55-5c46-44dc-a102-7d15f7b9bff5︡{"done":true}︡ ︠3f43bdc1-9cdd-4ade-b9ce-90eb14b9ee18i︠ %htmlChanging the number 3 and 5 in the definition above to 3 and 6 creates an interesting alternative relation. Also changing the modulus can be interesting, but if you use a non-prime modulus, you have to include 0 as a possible remainder.
Again, we build a dictionary based on the boolean function.
︡5b932007-fb21-4658-8eec-8e3c2d9d3837︡{"done":true,"html":"Changing the number 3 and 5 in the definition above to 3 and 6 creates an interesting alternative relation. Also changing the modulus can be interesting, but if you use a non-prime modulus, you have to include 0 as a possible remainder.
\nAgain, we build a dictionary based on the boolean function.
"} ︠cf0139f5-2da9-47d7-ab45-de7314adfe8fs︠ md={} for k in B: for j in B: if m(k,j): if k in md: md[k].append(j) else: md[k]=[j] ︡98593450-f2b2-4450-8d77-01b93b69037a︡{"done":true}︡ ︠b81b830b-7a28-4ed8-abb0-5b36b04fa601s︠ g=DiGraph(md) g.plot() ︡8a10ca06-4ef5-4c04-9158-d2d0dccc60bb︡{"file":{"filename":"/home/user/.sage/temp/project-f351622c-d261-4717-abee-4c0bfa210e88/174/tmp_UGsQqk.svg","show":true,"text":null,"uuid":"ca29249f-f3b7-4b27-8ed6-761f09522db4"},"once":false}︡{"done":true}︡ ︠3a0c2057-3196-4076-81b2-5c39a4576309s︠ G=g.adjacency_matrix() G ︡aeba295f-175f-478c-858b-06b551a60532︡{"stdout":"[0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0]\n[0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0]\n[0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0]\n[1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0]\n[1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1]\n[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1]\n[0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0]\n[0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0]\n[0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0]\n[0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0]\n[0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0]\n"}︡{"done":true}︡ ︠75b34bac-b849-4706-81ed-94d74b72ca7fi︠ %htmlThe square of relation m can be determined by squaring the adjacency matrix of m. Thanks to Jason Grout, who pointed out how to turn all nonzero entries in the product to a 1. By doing that you lose the information about the number of paths of length two between any pair of vertices, but the plot of the graph is much nicer.
︡357da18c-332d-4b0c-b1c7-ab09718d44c4︡{"done":true,"html":"The square of relation m can be determined by squaring the adjacency matrix of m. Thanks to Jason Grout, who pointed out how to turn all nonzero entries in the product to a 1. By doing that you lose the information about the number of paths of length two between any pair of vertices, but the plot of the graph is much nicer.
"} ︠4345655c-99ac-472b-a9ed-02f768e614afs︠ H=(G*G).apply_map(lambda x: 1 if x!=0 else 0) H ︡a680540b-1027-44a5-b5bd-1b1d753c7f86︡{"stdout":"[0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0]\n[1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1]\n[0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0]\n[0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0]\n[0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0]\n[0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0]\n[0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0]\n[1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0]\n[0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1]\n[0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0]\n[0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0]\n[0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0]\n[0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0]\n[0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0]\n[1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1]\n[0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0]\n"}︡{"done":true}︡ ︠8c50477d-50f2-4403-bfbe-be82e3eee39di︠ %htmlHere is the graph of the square of m, but with multiple edges.
︡72636e5f-f047-4166-8f0f-c9f90738a794︡{"done":true,"html":"Here is the graph of the square of m, but with multiple edges.
"} ︠91890e0f-2031-461f-a2df-a0e18ee24877s︠ DiGraph(H).plot() ︡db095c90-ac1b-402d-b1cb-73304bc407e2︡{"file":{"filename":"/home/user/.sage/temp/project-f351622c-d261-4717-abee-4c0bfa210e88/174/tmp_Sp_Fr_.svg","show":true,"text":null,"uuid":"73f67c31-c977-4347-b73a-d5780fc79ccd"},"once":false}︡{"done":true}︡ ︠3202f007-8a04-4864-b2db-d41d55b227d8s︠ s=DiGraph({0:[1],1:[3],2:[3],3:[4],4:[1]}) s.plot(layout="circular",save_pos="True").save('S65-3s.svg') ︡7bb2db8f-448b-4df8-8b33-0da9bfbe7ad8︡{"done":true}︡ ︠b6ebb469-bcf8-40a7-b500-d83d5d8824dd︠ ︡27331985-6cff-4e42-9abb-df7e3db06e0a︡ ︠a45a75d4-df08-4ee9-baba-d9ccbb8f18bds︠ s2=DiGraph((s.adjacency_matrix())^2) s2.plot(pos=s.get_pos()).save('S65-3s2.svg') ︡af5d3968-e8ca-4ff2-abf2-e0343c50e3e4︡{"done":true}︡ ︠f6de063b-c996-4e71-9a8e-7e7aaac1f734︠ ︡aa568d7d-16bd-41c0-b2a4-df00737a22fe︡{"done":true}︡ ︠5ad87031-baea-4822-9978-1a99f5f9b454s︠ s3=DiGraph((s.adjacency_matrix())^3) s3.plot(pos=s.get_pos()).save('S65-3s3.svg') ︡4b792800-2fe2-4d0c-a2f6-0a33985b00b7︡{"done":true}︡ ︠00e0e6a2-4cce-4e36-a840-3f0947dfe61bs︠ stc=(s.adjacency_matrix())+(s.adjacency_matrix())^2+(s.adjacency_matrix())^3 stc ︡7b8ab8a5-1f70-467e-b4e4-3ec50eebad5c︡{"stdout":"[0 1 0 1 1]\n[0 1 0 1 1]\n[0 1 0 1 1]\n[0 1 0 1 1]\n[0 1 0 1 1]\n"}︡{"done":true}︡ ︠8daf6de8-bfc9-4f3c-a602-b52e0254579ds︠ stc=DiGraph(Matrix([[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]])) stc.plot(pos=s.get_pos()).save('S65-3stc.svg') ︡e972f0dc-ce57-4dee-a2f6-2eeac3a827dd︡{"done":true}︡ ︠b28a9613-ec12-4149-9b54-ba4840056c52s︠ s3=DiGraph((s.adjacency_matrix())+(s.adjacency_matrix())^3+(s.adjacency_matrix())^3) s3.plot(pos=s.get_pos()).save('S65-3stc.png') ︡bb8222f8-f6ac-4d02-8fe3-8961447efdac︡{"done":true}︡ ︠123c0754-14c0-47a8-af39-274c50e0f3a7s︠ list(s.edges()) ︡8ed0ce62-ef52-415b-a3ef-30b6d7fd72d4︡{"stdout":"[(0, 1, None), (1, 3, None), (2, 3, None), (3, 4, None), (4, 1, None)]\n"}︡{"done":true}︡ ︠755d4692-9e6c-41b3-bcdf-276d8399f427︠