{"id":8242,"date":"2022-01-15T17:28:01","date_gmt":"2022-01-15T22:28:01","guid":{"rendered":"https:\/\/blogs.mathworks.com\/cleve\/?p=8242"},"modified":"2022-01-15T17:28:01","modified_gmt":"2022-01-15T22:28:01","slug":"the-menger-sponge-complement-and-associate","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/cleve\/2022\/01\/15\/the-menger-sponge-complement-and-associate\/","title":{"rendered":"The Menger Sponge, Complement and Associate"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>A few months ago, I had never heard of Karl Menger or the cube-like fractal that he invented.  Now I have this long blog post about the sponge, and an extension that I am calling its \"associate\".<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#0cce3684-7a71-4d72-8bdb-b88d9dc6385e\">Complements and associates<\/a><\/li><li><a href=\"#e548fb2e-0e21-479f-957a-c280ea1d7ab2\">Code comes first<\/a><\/li><li><a href=\"#618fc14b-3ade-4c05-93c0-58ea341ab1eb\">Level 0<\/a><\/li><li><a href=\"#3e6342e1-2774-4643-8736-648ed87b1685\">Level 1<\/a><\/li><li><a href=\"#dbd9ac3f-037e-49f2-8b0c-c71a485e3479\">Level 2<\/a><\/li><li><a href=\"#4754f5d6-0eb6-4f94-ae08-bb7965c5fe45\">Level 3<\/a><\/li><li><a href=\"#eaaca13a-2399-460e-88be-430bb916d612\">Ten levels<\/a><\/li><li><a href=\"#0c8c7d29-c5e7-401d-915d-0d2a5954eacd\">Associate<\/a><\/li><li><a href=\"#a6dc3dcb-8b20-42ca-86d2-34cfaa56f06f\">Level 2<\/a><\/li><li><a href=\"#b3c849fb-a5ac-417d-9a2f-731aec1bae3b\">Level 3<\/a><\/li><li><a href=\"#0c5073de-9334-4c38-b619-8f991493ca47\">Level 4<\/a><\/li><\/ul><\/div><h4>Complements and associates<a name=\"0cce3684-7a71-4d72-8bdb-b88d9dc6385e\"><\/a><\/h4><p>The complement of the Menger sponge fractal at a given level is all the material that is cut away to reach that level. The sponge associate is something I encountered while trying to compute the sponge complement.<\/p><h4>Code comes first<a name=\"e548fb2e-0e21-479f-957a-c280ea1d7ab2\"><\/a><\/h4><p>I firmly believe that carefully written computer code is a means for people to communicate with each other, as well as control machines. Some of the images that I am about to present can be seen elsewhere on the Web, but I am most pleased with the code that produces them, so I will describe it first.<\/p><p>Here is the main routine, <tt>sponge<\/tt> .  If you have been following this blog, you will have seen <a href=\"https:\/\/blogs.mathworks.com\/cleve\/2021\/12\/06\/the-menger-sponge-fractal\">some of it before<\/a>. At the command line, <tt>sponge<\/tt> expects only two input arguments, a nonnegative integer specifying the level and a boolean variable specifying the Menger sponge or its complement.  The sponge is displayed with a dark shade of gold and the complement with a light shade. The function <tt>sponge<\/tt> is recursive and the recursive calls have more than two arguments.<\/p><p>Level zero terminates the recursion and is dealt with first. The level zero sponge is <a href=\"https:\/\/blogs.mathworks.com\/cleve\/2022\/01\/03\/anatomy-of-a-cube\">a solid cube<\/a>.  The level zero complement is empty and we just display the outline of a cube. Ultimately, all the output is produced by function calls <tt>cube(d,w,c)<\/tt>, which displays a dark or light cube with half-width <tt>w<\/tt> centered at <tt>c = [x y z]<\/tt>, so nothing but cubes of various sizes in various locations are displayed.  Ordinarily the cube is merged with whatever is in the current figure, thus displaying the union of the two sets.  A <tt>cla<\/tt> command clears the current display axis and thereby initiates a new set.<\/p><p>If the level is not zero, we reach the nested loops and the recursive calls.  The variables <tt>x<\/tt>, <tt>y<\/tt> and <tt>z<\/tt> take on all possible combinations of <tt>-2<\/tt>, <tt>0<\/tt> and <tt>+2<\/tt>, so the innermost statements are executed 27 times.  Now the key variable <tt>nz<\/tt> comes into play.  It is the number of nonzeros in <tt>[x y z]<\/tt>.  The vector <tt>[0 0 0]<\/tt> has zero nonzeros and is in the center of some small cube.  Vectors like <tt>[2 0 0]<\/tt> and <tt>[0 -2 0]<\/tt> have one nonzero and are in the center of some face of that small cube. Vectors like <tt>[2 0 -2]<\/tt> with two nonzeros are in the middle of some edge and vectors like <tt>[-2 2 -2]<\/tt> with three nonzeros are at the corners. There are seven <tt>[x y z]<\/tt>'s with <tt>nz &lt; 2<\/tt> leaving 20 with <tt>nz &gt;= 2<\/tt>. This provides the trisecting rule for generating the next level Menger sponge.<\/p><pre class=\"codeinput\">    type <span class=\"string\">sponge<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction sponge(m,s,d,w,c)\r\n    % sponge(m,s)\r\n    % m: level, 20^m cubes.\r\n    % s: sponge, dark gold or complement, light gold.\r\n    %\r\n    % Resursive usage:\r\n    % sponge(m,s,d,w,c)\r\n    % d: dark or light.\r\n    % w: half-width.\r\n    % c: center.\r\n\r\n    if nargin == 2\r\n        init_fig(5)\r\n        sponge(m,s,s,3,[0 0 0])\r\n        \r\n    elseif m == 0 &amp;&amp; s\r\n        cube(d,w,c)\r\n        \r\n    elseif m == 0\r\n        cube([],w,c)\r\n        \r\n    else\r\n        w = w\/3;\r\n        c = c\/3;\r\n        for x = [-2 0 2]\r\n            for y = [-2 0 2]\r\n                for z = [-2 0 2]\r\n                    nz = nnz([x y z]);\r\n                    if s &amp;&amp; nz &gt;= 2\r\n                        sponge(m-1,s,d,w,c+[x y z])\r\n                    elseif ~s &amp;&amp; nz &lt; 2\r\n                        sponge(m-1,~s,d,w,c+[x y z])\r\n                    end\r\n                end\r\n            end\r\n        end\r\n    end\r\nend\r\n<\/pre><h4>Level 0<a name=\"618fc14b-3ade-4c05-93c0-58ea341ab1eb\"><\/a><\/h4><p>This is the level 0 sponge, a solid cube.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(0,true)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_01.png\" alt=\"\"> <p>This is the level 0 complement.  It is empty.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(0,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_02.png\" alt=\"\"> <h4>Level 1<a name=\"3e6342e1-2774-4643-8736-648ed87b1685\"><\/a><\/h4><p>Trisect level 0 into 3x3x3 = 27 smaller cubes. Delete the center cube and the center of each face. This is the level 1 sponge with 20 smaller cubes and seven holes.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(1,true)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_03.png\" alt=\"\"> <p>This is the level 1 complement, the seven missing cubes.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(1,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_04.png\" alt=\"\"> <p>If you could somehow put the level 1 sponge and the level 1 complement together again, you would recreate a slightly used, but full, cube.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(1,true)\r\n    sponge(1,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_05.png\" alt=\"\"> <p>Level 1 is as far as I need to go <a href=\"https:\/\/blogs.mathworks.com\/cleve\/2021\/12\/27\/the-complement-of-the-menger-sponge\">late last year<\/a> in order to decorate my <a href=\"https:\/\/blogs.mathworks.com\/cleve\/2021\/12\/27\/seasons-greetings-2021\">Season's Greetings<\/a>.<\/p><h4>Level 2<a name=\"dbd9ac3f-037e-49f2-8b0c-c71a485e3479\"><\/a><\/h4><p>The level 2 sponge has <tt>20^2 = 400<\/tt> cubes.  I got this far in level 2 for <a href=\"https:\/\/blogs.mathworks.com\/cleve\/2021\/12\/06\/the-menger-sponge-fractal\">my first post<\/a> about the Menger sponge.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(2,true)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_06.png\" alt=\"\"> <p>The next figure has never appeared before in <i>Cleve's Corner<\/i>. I call it the level 2 <i>partial complement<\/i>.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(2,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_07.png\" alt=\"\"> <p>Form the union of the level 2 partial complement and the level 1 complement to give the entire level 2 complement.<\/p><pre class=\"codeinput\">    sponge(1,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_08.png\" alt=\"\"> <p>The union of the level 2 sponge and its complement is a full cube.<\/p><pre class=\"codeinput\">    sponge(2,true)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_09.png\" alt=\"\"> <h4>Level 3<a name=\"4754f5d6-0eb6-4f94-ae08-bb7965c5fe45\"><\/a><\/h4><p>The is the level 3 Menger sponge.  It is made from <tt>20^3 = 8000<\/tt> small cubes.  Its volume is less than half that of the original cube.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(3,true)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_10.png\" alt=\"\"> <p>The is the level 3 partial complement.<\/p><pre class=\"codeinput\">    cla\r\n    sponge(3,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_11.png\" alt=\"\"> <p>Combine levels 1, 2 and 3 partial complements to produce the entire level 3 complement.<\/p><pre class=\"codeinput\">    sponge(2,false)\r\n    sponge(1,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_12.png\" alt=\"\"> <p>The union of the level 3 sponge and its complement is, again, full.<\/p><pre class=\"codeinput\">    sponge(3,true)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_13.png\" alt=\"\"> <pre class=\"codeinput\">    format <span class=\"string\">compact<\/span>\r\n    format <span class=\"string\">short<\/span>\r\n<\/pre><h4>Ten levels<a name=\"eaaca13a-2399-460e-88be-430bb916d612\"><\/a><\/h4><p>I don't have enough time and my laptop doesn't have enough memory to go much beyond level 3, but if we could continue trisecting, the level 10 sponge would be made out of <tt>20^10 = 10,240,000,000,000<\/tt> very tiny cubes.<\/p><p>Level <tt>m<\/tt> would reduce the volume of the level <tt>0<\/tt> cube by a factor <tt>r.^m<\/tt> where<\/p><pre class=\"codeinput\">   r = (20\/27)\r\n<\/pre><pre class=\"codeoutput\">r =\r\n    0.7407\r\n<\/pre><p>By level 10 the volume of the sponge would be only 5 percent of the original volume, and the remaining 95 percent would be in the complement.<\/p><pre class=\"codeinput\">    m = (0:10)';\r\n    volumes = [r.^m 1-r.^m];\r\n<\/pre><pre class=\"codeinput\">    fprintf(<span class=\"string\">'\\n\\n                 volume\\n'<\/span>)\r\n    fprintf(<span class=\"string\">'      level  sponge  complement\\n'<\/span>)\r\n    fprintf(<span class=\"string\">'%10d %8.3f %8.3f\\n'<\/span>,[m volumes]')\r\n<\/pre><pre class=\"codeoutput\">\r\n\r\n                 volume\r\n      level  sponge  complement\r\n         0    1.000    0.000\r\n         1    0.741    0.259\r\n         2    0.549    0.451\r\n         3    0.406    0.594\r\n         4    0.301    0.699\r\n         5    0.223    0.777\r\n         6    0.165    0.835\r\n         7    0.122    0.878\r\n         8    0.091    0.909\r\n         9    0.067    0.933\r\n        10    0.050    0.950\r\n<\/pre><pre class=\"codeinput\">    plot(m,volumes,<span class=\"string\">'o-'<\/span>,<span class=\"string\">'linewidth'<\/span>,1.0)\r\n    xlabel(<span class=\"string\">'level'<\/span>)\r\n    ylabel(<span class=\"string\">'volume'<\/span>)\r\n    legend({<span class=\"string\">'sponge'<\/span>,<span class=\"string\">'complement'<\/span>},<span class=\"string\">'position'<\/span>,[.67 .47 .21 .08])\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_14.png\" alt=\"\"> <pre class=\"codeinput\">    close\r\n<\/pre><h4>Associate<a name=\"0c8c7d29-c5e7-401d-915d-0d2a5954eacd\"><\/a><\/h4><p>A Web dictionary says that an <i>associate<\/i> is someone with limited or subordinate membership in an organization. We are all familiar with associate professors in academic organizations. I accidentally created these sponge associates when I was learning how to compute sponge complements.  I liked the images, so I have kept them around.<\/p><p>The code that I now have for generating associates is almost the same as the code for generating sponges.  Just count the number of zeros in a coordinate vector instead of the number of nonzeros.<\/p><pre class=\"codeinput\">    dbtype <span class=\"string\">28<\/span> <span class=\"string\">sponge<\/span>\r\n    dbtype <span class=\"string\">28<\/span> <span class=\"string\">associate<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\n28                        nz = nnz([x y z]);\r\n\r\n28                        nz = 3 - nnz([x y z]);\r\n<\/pre><h4>Level 2<a name=\"a6dc3dcb-8b20-42ca-86d2-34cfaa56f06f\"><\/a><\/h4><p>At levels 0 and 1, sponges and associates construct the same objects. But at level 2 we have this fellow with 49 cubes.<\/p><pre class=\"codeinput\">    cla\r\n    associate(2,true)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_15.png\" alt=\"\"> <p>The associates have their own complements. The cube count at level <tt>m<\/tt> is <tt>7^m<\/tt> for an associate and <tt>20*7^(m-1)<\/tt> for its complement. This one at level 2 has 149 cubes.<\/p><pre class=\"codeinput\">    cla\r\n    associate(2,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_16.png\" alt=\"\"> <h4>Level 3<a name=\"b3c849fb-a5ac-417d-9a2f-731aec1bae3b\"><\/a><\/h4><p>Here is the level 3 associate.<\/p><pre class=\"codeinput\">    cla\r\n    associate(3,true)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_17.png\" alt=\"\"> <p>And the level 3 associate complement.<\/p><pre class=\"codeinput\">    cla\r\n    associate(3,false)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"http:\/\/blogs.mathworks.com\/cleve\/files\/sponge_blog_2_18.png\" alt=\"\"> <h4>Level 4<a name=\"0c5073de-9334-4c38-b619-8f991493ca47\"><\/a><\/h4><p>The level 4 images are best viewed with a larger format.  If you want to see them, click on these links.<\/p><p><a href=\"https:\/\/blogs.mathworks.com\/cleve\/files\/level_4_true.png\">https:\/\/blogs.mathworks.com\/cleve\/files\/level_4_true.png<\/a><\/p><p><a href=\"https:\/\/blogs.mathworks.com\/cleve\/files\/level_4_false.png\">https:\/\/blogs.mathworks.com\/cleve\/files\/level_4_false.png<\/a><\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_af73266d8c7b4cf1b586e16fa06d8b8e() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='af73266d8c7b4cf1b586e16fa06d8b8e ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' af73266d8c7b4cf1b586e16fa06d8b8e';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2022 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_af73266d8c7b4cf1b586e16fa06d8b8e()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2021a<br><\/p><\/div><!--\r\naf73266d8c7b4cf1b586e16fa06d8b8e ##### SOURCE BEGIN #####\r\n%% The Menger Sponge, Complement and Associate\r\n% A few months ago, I had never heard of Karl Menger or the \r\n% cube-like fractal that he invented.  Now I have this long blog post\r\n% about the sponge, and an extension that I am calling its \"associate\".\r\n\r\n%% Complements and associates\r\n% The complement of the Menger sponge fractal at a given level\r\n% is all the material that is cut away to reach that level.\r\n% The sponge associate is something I encountered while trying to\r\n% compute the sponge complement.\r\n\r\n%% Code comes first\r\n% I firmly believe that carefully written computer code is a means for\r\n% people to communicate with each other, as well as control machines.\r\n% Some of the images that I am about to present can be seen elsewhere\r\n% on the Web, but I am most pleased with the code that produces them,\r\n% so I will describe it first.\r\n% \r\n% Here is the main routine, |sponge| .  If you have been following this\r\n% blog, you will have seen \r\n% <https:\/\/blogs.mathworks.com\/cleve\/2021\/12\/06\/the-menger-sponge-fractal\r\n% some of it before>.\r\n% At the command line, |sponge| expects only two input arguments,\r\n% a nonnegative integer specifying the level and a boolean variable\r\n% specifying the Menger sponge or its complement.  The sponge is displayed\r\n% with a dark shade of gold and the complement with a light shade.\r\n% The function |sponge| is recursive and the recursive calls have more\r\n% than two arguments.\r\n%\r\n% Level zero terminates the recursion and is dealt with first.\r\n% The level zero sponge is\r\n% <https:\/\/blogs.mathworks.com\/cleve\/2022\/01\/03\/anatomy-of-a-cube\r\n% a solid cube>.  The level zero complement is empty and we just display\r\n% the outline of a cube.\r\n% Ultimately, all the output is produced by function calls\r\n% |cube(d,w,c)|, which displays a dark or light cube with half-width |w|\r\n% centered at |c = [x y z]|, so nothing but cubes of various sizes\r\n% in various locations are displayed.  Ordinarily the cube is merged with\r\n% whatever is in the current figure, thus displaying the union of the\r\n% two sets.  A |cla| command clears the current display axis and thereby\r\n% initiates a new set.\r\n%\r\n% If the level is not zero, we reach the nested loops and\r\n% the recursive calls.  The variables |x|, |y| and |z| take on\r\n% all possible combinations of |-2|, |0| and |+2|, so the innermost\r\n% statements are executed 27 times.  Now the key variable |nz| comes into\r\n% play.  It is the number of nonzeros in |[x y z]|.  The\r\n% vector |[0 0 0]| has zero nonzeros and is in the center of some small\r\n% cube.  Vectors like |[2 0 0]| and |[0 -2 0]| have one nonzero\r\n% and are in the center of some face of that small cube.\r\n% Vectors like |[2 0 -2]| with two nonzeros are in the middle of some edge\r\n% and vectors like |[-2 2 -2]| with three nonzeros are at the corners.\r\n% There are seven |[x y z]|'s with |nz < 2| leaving 20 with |nz >= 2|.\r\n% This provides the trisecting rule for generating the\r\n% next level Menger sponge.\r\n\r\n    type sponge\r\n    \r\n\r\n%% Level 0\r\n% This is the level 0 sponge, a solid cube.\r\n\r\n    cla\r\n    sponge(0,true)\r\n    \r\n%% \r\n% This is the level 0 complement.  It is empty.\r\n\r\n    cla\r\n    sponge(0,false)\r\n    \r\n%% Level 1\r\n% Trisect level 0 into 3x3x3 = 27 smaller cubes.\r\n% Delete the center cube and the center of each face.\r\n% This is the level 1 sponge with 20 smaller cubes and seven holes.\r\n\r\n    cla\r\n    sponge(1,true)   \r\n\r\n%% \r\n% This is the level 1 complement, the seven missing cubes.\r\n\r\n    cla\r\n    sponge(1,false)\r\n\r\n%% \r\n% If you could somehow put the level 1 sponge and the level 1 complement\r\n% together again, you would recreate a slightly used, but full, cube.\r\n\r\n    cla\r\n    sponge(1,true)\r\n    sponge(1,false)\r\n    \r\n%%\r\n% Level 1 is as far as I need to go\r\n% <https:\/\/blogs.mathworks.com\/cleve\/2021\/12\/27\/the-complement-of-the-menger-sponge\r\n% late last year> in order to decorate my\r\n% <https:\/\/blogs.mathworks.com\/cleve\/2021\/12\/27\/seasons-greetings-2021\r\n% Season's Greetings>.   \r\n    \r\n%% Level 2\r\n% The level 2 sponge has |20^2 = 400| cubes.  I got this far in level 2 for\r\n% <https:\/\/blogs.mathworks.com\/cleve\/2021\/12\/06\/the-menger-sponge-fractal\r\n% my first post> about the Menger sponge.\r\n\r\n    cla\r\n    sponge(2,true)\r\n\r\n%%\r\n% The next figure has never appeared before in _Cleve's Corner_.\r\n% I call it the level 2 _partial complement_.\r\n\r\n    cla\r\n    sponge(2,false)\r\n    \r\n%%\r\n% Form the union of the level 2 partial complement and the level 1 \r\n% complement to give the entire level 2 complement.\r\n%\r\n\r\n    sponge(1,false)\r\n\r\n%% \r\n% The union of the level 2 sponge and its complement is a full cube.\r\n\r\n    sponge(2,true)\r\n\r\n%% Level 3\r\n% The is the level 3 Menger sponge.  It is made from |20^3 = 8000|\r\n% small cubes.  Its volume is less than half that of the original cube.\r\n\r\n    cla\r\n    sponge(3,true)\r\n    \r\n%%\r\n% The is the level 3 partial complement.\r\n%\r\n    cla\r\n    sponge(3,false)\r\n      \r\n%% \r\n% Combine levels 1, 2 and 3 partial complements to produce \r\n% the entire level 3 complement.\r\n%\r\n    sponge(2,false)\r\n    sponge(1,false)\r\n\r\n%%\r\n% The union of the level 3 sponge and its complement is, again, full.\r\n\r\n    sponge(3,true)\r\n\r\n%%\r\n    format compact\r\n    format short\r\n    \r\n%% Ten levels\r\n% I don't have enough time and my laptop doesn't have enough memory to go\r\n% much beyond level 3, but if we could continue trisecting,\r\n% the level 10 sponge would be made out of\r\n% |20^10 = 10,240,000,000,000| very tiny cubes.\r\n%\r\n% Level |m| would reduce the volume of the level |0| cube by a factor\r\n% |r.^m| where\r\n\r\n   r = (20\/27)\r\n    \r\n%%\r\n% By level 10 the volume of the sponge would be only 5 percent of the\r\n% original volume, and the remaining 95 percent would be in the complement.\r\n\r\n    m = (0:10)';\r\n    volumes = [r.^m 1-r.^m];  \r\n    \r\n%% \r\n    fprintf('\\n\\n                 volume\\n')\r\n    fprintf('      level  sponge  complement\\n')      \r\n    fprintf('%10d %8.3f %8.3f\\n',[m volumes]')\r\n\r\n%%\r\n    plot(m,volumes,'o-','linewidth',1.0)\r\n    xlabel('level')\r\n    ylabel('volume')\r\n    legend({'sponge','complement'},'position',[.67 .47 .21 .08])\r\n    \r\n%%\r\n    close\r\n    \r\n%% Associate\r\n% A Web dictionary says that an _associate_ is someone\r\n% with limited or subordinate membership in an organization.\r\n% We are all familiar with associate professors in academic organizations.\r\n% I accidentally created these sponge associates when I was learning how\r\n% to compute sponge complements.  I liked the images, so I have kept \r\n% them around.\r\n%\r\n% The code that I now have for generating associates is almost the same as\r\n% the code for generating sponges.  Just count the number of zeros in a\r\n% coordinate vector instead of the number of nonzeros.\r\n\r\n    dbtype 28 sponge\r\n    dbtype 28 associate\r\n    \r\n%% Level 2\r\n% At levels 0 and 1, sponges and associates construct the same objects.\r\n% But at level 2 we have this fellow with 49 cubes.\r\n\r\n    cla\r\n    associate(2,true)\r\n    \r\n%%\r\n% The associates have their own complements.\r\n% The cube count at level |m| is |7^m| for an associate and |20*7^(m-1)|\r\n% for its complement. This one at level 2 has 149 cubes.\r\n\r\n    cla\r\n    associate(2,false)\r\n    \r\n%% Level 3\r\n% Here is the level 3 associate.\r\n\r\n    cla\r\n    associate(3,true)\r\n    \r\n%%\r\n% And the level 3 associate complement.\r\n\r\n    cla\r\n    associate(3,false) \r\n    \r\n%% Level 4\r\n% The level 4 images are best viewed with a larger format.  If you want\r\n% to see them, click on these links.\r\n%\r\n% <https:\/\/blogs.mathworks.com\/cleve\/files\/level_4_true.png>\r\n%\r\n% <https:\/\/blogs.mathworks.com\/cleve\/files\/level_4_false.png>\r\n\r\n\r\n    \r\n    \r\n##### SOURCE END ##### af73266d8c7b4cf1b586e16fa06d8b8e\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/cleve\/files\/sponge.gif\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><!--introduction--><p>A few months ago, I had never heard of Karl Menger or the cube-like fractal that he invented.  Now I have this long blog post about the sponge, and an extension that I am calling its \"associate\".... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/cleve\/2022\/01\/15\/the-menger-sponge-complement-and-associate\/\">read more >><\/a><\/p>","protected":false},"author":78,"featured_media":8302,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[18,5,23,37],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/8242"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/users\/78"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/comments?post=8242"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/8242\/revisions"}],"predecessor-version":[{"id":8245,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/posts\/8242\/revisions\/8245"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media\/8302"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/media?parent=8242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/categories?post=8242"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/cleve\/wp-json\/wp\/v2\/tags?post=8242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}