<?xml version="1.0" encoding="UTF-8"?>
<feed
  xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0"
  xml:lang="en"
   >
  <title type="text">Sébastien Labbé</title>
  <subtitle type="text">Sébastien Labbé</subtitle>

  <updated>2026-05-07T01:54:30Z</updated>
  <generator uri="http://blogofile.com/">Blogofile</generator>

  <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue" />
  <id>http://www.slabbe.org/blogue/feed/atom/</id>
  <link rel="self" type="application/atom+xml" href="http://www.slabbe.org/blogue/feed/atom/index.xml" />
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[On the bifurcation diagram proposed by Jang and Robinson]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2025/05/on-the-bifurcation-diagram-proposed-by-jang-and-robinson" />
    <id>http://www.slabbe.org/blogue/2025/05/on-the-bifurcation-diagram-proposed-by-jang-and-robinson</id>
    <updated>2025-05-06T14:37:00Z</updated>
    <published>2025-05-06T14:37:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <summary type="html"><![CDATA[On the bifurcation diagram proposed by Jang and Robinson]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2025/05/on-the-bifurcation-diagram-proposed-by-jang-and-robinson"><![CDATA[<div class="document">
<p>In this blog post, we present a few remarks on the &quot;bifurcation
diagram&quot; proposed by Jang and Robinson in [1] to describe the tilings
associated to a set of 24 Wang tiles encoding Penrose tilings.</p>
<p>[1] Hyeeun Jang, E. Arthur Robinson Jr, Directional Expansiveness for
Rd-Actions and for Penrose Tilings,
<a class="reference external" href="https://arxiv.org/abs/2504.10838">arxiv:2504.10838</a></p>
<p>In particular, I believe that something is wrong in what the authors call the
&quot;bifurcation diagram&quot; shown in Figure 10. But, as we illustrate below, it can
be fixed easily by permuting some of the labels of the partition.</p>
<p>I saw Jang and Robinsion's bifurcation diagram for the first time during
the talk &quot;Remembering Shunji Ito&quot; made by Robinson during the <a class="reference external" href="https://www.irif.fr/~numeration/Archive">online
conference</a> dedicated to the
memory of Shunji Ito on December 14, 2021. At that time, I was working
on the family of metallic mean Wang tiles. This is why the bifurcation
diagram shown by Robinson and extracted from Jang's PhD thesis got my
attention right away, because it was looking very much like the Markov
partition associated to the Ammann set of 16 Wang tiles, the first
member of the family of metallic mean Wang tiles. As we illustrate
below, Jang and Robinson's bifurcation diagram is a refinement of the
Markov partition associated the Ammann set of 16 Wang tiles. This means
that the 16 tiles Ammann Wang shift is a factor of the 24 tiles Penrose
Wang shift. Also most probably the bifurcation diagram is a Markov
Partition for the same associated toral <span class="formula">ℤ<sup>2</sup></span>-action. But
this needs a proof.</p>
<p>The content of this blog post is also available as a Jupyter notebook that can
be <a class="reference external" href="https://nbviewer.jupyter.org/url/www.slabbe.org/Files/2025/jang_robinson.ipynb">viewed and downloaded from the nbviewer</a>.</p>
<div class="section" id="dependencies">
<h1>Dependencies</h1>
<p>The computations made here depend on the modules <tt class="docutils literal">WangTileSet</tt>,
<tt class="docutils literal">WangTiling</tt>, <tt class="docutils literal">PolyhedronPartition</tt>,
<tt class="docutils literal">PolyhedronExchangeTransformation</tt>, <tt class="docutils literal">PETsCoding</tt> implemented in the
SageMath optional package <a class="reference external" href="https://pypi.org/project/slabbe/">slabbe</a>
over the last years in order to describe and study the Jeandel-Rao
aperiodic tilings and the family of metallic mean Wang tiles.</p>
<p>Note that the package <tt class="docutils literal">slabbe</tt> can be installed by running
<tt class="docutils literal">!pip install slabbe</tt> directly in SageMath:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="c1"># !pip install slabbe             # uncomment and execute this line to install slabbe package</span>
</pre></div>



<p>Here are the version of the packages used in this post:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">import</span> <span class="nn">importlib</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">importlib</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">version</span><span class="p">(</span><span class="s2">&quot;slabbe&quot;</span><span class="p">)</span>
<span class="s1">&#39;0.8.0&#39;</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">version</span><span class="p">()</span>
<span class="s1">&#39;SageMath version 10.5.beta6, Release Date: 2024-09-29&#39;</span>
</pre></div>



</div>
<div class="section" id="jang-robinson-encoding-of-the-penrose-24-wang-tiles">
<h1>Jang-Robinson encoding of the Penrose 24 Wang tiles</h1>
<p>We encode the 24 Wang tiles proposed by Jang and Robinson (Figure 9 of [1])
using alphabet <span class="formula">{<i>A</i>, <i>B</i>, <i>C</i>, <i>D</i>, <i>E</i>, <i>F</i>, <i>G</i>, <i>H</i>, <i>I</i>, <i>J</i>}</span> for the shapes:</p>
<img alt="/Files/2025/Figure9.png" src="/Files/2025/Figure9.png" />
<p>We define the 24 Wang tiles in SageMath:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe</span> <span class="kn">import</span> <span class="n">WangTileSet</span><span class="p">,</span> <span class="n">WangTiling</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tiles</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;AADD&quot;</span><span class="p">,</span> <span class="s2">&quot;CCBB&quot;</span><span class="p">,</span> <span class="s2">&quot;EEII&quot;</span><span class="p">,</span> <span class="s2">&quot;JJFF&quot;</span><span class="p">,</span>
<span class="o">....</span><span class="p">:</span>          <span class="s2">&quot;CCHH&quot;</span><span class="p">,</span> <span class="s2">&quot;GGDD&quot;</span><span class="p">,</span> <span class="s2">&quot;HHAA&quot;</span><span class="p">,</span> <span class="s2">&quot;BBGG&quot;</span><span class="p">,</span>
<span class="o">....</span><span class="p">:</span>          <span class="s2">&quot;FGEC&quot;</span><span class="p">,</span> <span class="s2">&quot;FDEH&quot;</span><span class="p">,</span> <span class="s2">&quot;GFCE&quot;</span><span class="p">,</span> <span class="s2">&quot;DFHE&quot;</span><span class="p">,</span>
<span class="o">....</span><span class="p">:</span>          <span class="s2">&quot;BICF&quot;</span><span class="p">,</span> <span class="s2">&quot;DEAJ&quot;</span><span class="p">,</span> <span class="s2">&quot;IBFC&quot;</span><span class="p">,</span> <span class="s2">&quot;EDJA&quot;</span><span class="p">,</span>
<span class="o">....</span><span class="p">:</span>          <span class="s2">&quot;HCBA&quot;</span><span class="p">,</span> <span class="s2">&quot;CHAB&quot;</span><span class="p">,</span> <span class="s2">&quot;BADG&quot;</span><span class="p">,</span> <span class="s2">&quot;ABGD&quot;</span><span class="p">,</span>
<span class="o">....</span><span class="p">:</span>          <span class="s2">&quot;DFBJ&quot;</span><span class="p">,</span> <span class="s2">&quot;AICE&quot;</span><span class="p">,</span> <span class="s2">&quot;FDJB&quot;</span><span class="p">,</span> <span class="s2">&quot;IAEC&quot;</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T0</span> <span class="o">=</span> <span class="n">WangTileSet</span><span class="p">([</span><span class="nb">tuple</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">tile</span><span class="p">)</span> <span class="k">for</span> <span class="n">tile</span> <span class="ow">in</span> <span class="n">tiles</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T0</span>
<span class="n">Wang</span> <span class="n">tile</span> <span class="nb">set</span> <span class="n">of</span> <span class="n">cardinality</span> <span class="mi">24</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T0</span><span class="o">.</span><span class="n">tikz</span><span class="p">(</span><span class="n">ncolumns</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</pre></div>



<img alt="/Files/2025/output_9_0.png" src="/Files/2025/output_9_0.png" />
</div>
<div class="section" id="constructing-jang-robinson-bifurcation-diagram-as-a-polygonal-partition">
<h1>Constructing Jang-Robinson Bifurcation diagram as a polygonal partition</h1>
<p>Below is a reproduction of Jang-Robinson bifurcation diagram shown in
Figure 10 from <a class="reference external" href="https://arxiv.org/abs/2504.10838">arxiv:2504.10838</a></p>
<img alt="/Files/2025/Figure10.png" src="/Files/2025/Figure10.png" style="width: 40em;" />
<p>In this section, we construct this bifurcation diagram in SageMath as
a polygonal partition.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe</span> <span class="kn">import</span> <span class="n">PolyhedronPartition</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">z</span> <span class="o">=</span> <span class="n">polygen</span><span class="p">(</span><span class="n">QQ</span><span class="p">,</span> <span class="s1">&#39;z&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">K</span> <span class="o">=</span> <span class="n">NumberField</span><span class="p">(</span><span class="n">z</span><span class="o">**</span><span class="mi">2</span><span class="o">-</span><span class="n">z</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;phi&#39;</span><span class="p">,</span> <span class="n">embedding</span><span class="o">=</span><span class="n">RR</span><span class="p">(</span><span class="mf">1.6</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">phi</span> <span class="o">=</span> <span class="n">K</span><span class="o">.</span><span class="n">gen</span><span class="p">()</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">square</span> <span class="o">=</span> <span class="n">polytopes</span><span class="o">.</span><span class="n">hypercube</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="n">intervals</span> <span class="o">=</span> <span class="s1">&#39;zero_one&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">PolyhedronPartition</span><span class="p">([</span><span class="n">square</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="o">^</span><span class="mi">3</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span> <span class="o">+</span> <span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span> <span class="o">+</span> <span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="o">^</span><span class="mi">3</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="o">^</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">refine_by_hyperplane</span><span class="p">([</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="o">-</span><span class="n">P</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">translate</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="c1">#P.plot()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">rename_keys</span><span class="p">({</span><span class="mi">0</span><span class="p">:</span><span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">:</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">:</span><span class="mi">18</span><span class="p">,</span> <span class="mi">3</span><span class="p">:</span><span class="mi">19</span><span class="p">,</span> <span class="mi">4</span><span class="p">:</span><span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">:</span><span class="mi">6</span><span class="p">,</span> <span class="mi">6</span><span class="p">:</span><span class="mi">16</span><span class="p">,</span> <span class="mi">7</span><span class="p">:</span><span class="mi">17</span><span class="p">,</span> <span class="mi">8</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span> <span class="mi">9</span><span class="p">:</span><span class="mi">4</span><span class="p">,</span> <span class="mi">10</span><span class="p">:</span><span class="mi">15</span><span class="p">,</span><span class="mi">11</span><span class="p">:</span><span class="mi">9</span><span class="p">,</span>
<span class="n">sage</span><span class="p">:</span>                    <span class="mi">12</span><span class="p">:</span><span class="mi">22</span><span class="p">,</span><span class="mi">13</span><span class="p">:</span><span class="mi">23</span><span class="p">,</span><span class="mi">14</span><span class="p">:</span><span class="mi">8</span><span class="p">,</span> <span class="mi">15</span><span class="p">:</span><span class="mi">14</span><span class="p">,</span><span class="mi">16</span><span class="p">:</span><span class="mi">13</span><span class="p">,</span><span class="mi">17</span><span class="p">:</span><span class="mi">11</span><span class="p">,</span><span class="mi">18</span><span class="p">:</span><span class="mi">20</span><span class="p">,</span><span class="mi">19</span><span class="p">:</span><span class="mi">21</span><span class="p">,</span><span class="mi">20</span><span class="p">:</span><span class="mi">10</span><span class="p">,</span> <span class="mi">21</span><span class="p">:</span><span class="mi">12</span><span class="p">,</span> <span class="mi">22</span><span class="p">:</span><span class="mi">3</span><span class="p">,</span>
<span class="n">sage</span><span class="p">:</span>                    <span class="mi">23</span><span class="p">:</span><span class="mi">2</span><span class="p">})</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_14_0.png" src="/Files/2025/output_14_0.png" />
</div>
<div class="section" id="our-claim">
<h1>Our claim</h1>
<p>We claim that the above bifurcation diagram from Jang-Robinson preprint
is slightly wrong according to the choice of indices of the 24 Wang
tiles made by Jang and Robinson and shown above. The following changes
should be made in order to fix the partition:</p>
<blockquote>
<ul class="simple">
<li>indices 9 and 22 should be swapped,</li>
<li>indices 8 and 23 should be swapped,</li>
<li>indices 11 and 20 should be swapped and</li>
<li>indices 10 and 21 should be swapped.</li>
</ul>
</blockquote>
</div>
<div class="section" id="defining-the-toral-translations-in-the-internal-space-as-pets">
<h1>Defining the toral translations in the internal space as PETs</h1>
<p>We define the toral translations associated to the partition chosen by
Jang-Robinson. The internal space is the 2-dimensional torus
<span class="formula">ℝ<sup>2</sup> ⁄ ℤ<sup>2</sup></span>. It is represented as the unit square
<span class="formula">[0, 1)<sup>2</sup></span>. On this fundamental domain, a toral translation is a
polygon exchange transformation.</p>
<p>Note that according to their choice,</p>
<blockquote>
<ul class="simple">
<li>a unit horizontal translation in the physical space corresponds to a vertical
translation by <span class="formula">(0, <i>φ</i>)</span> in the internal space,</li>
<li>a unit vertical translation in the physical space corresponds to a horizontal
translation by <span class="formula">(<i>φ</i>, 0)</span> in the internal space,</li>
</ul>
</blockquote>
<p>where <span class="formula"><i>φ</i></span> is the golden mean.</p>
<p>Below, we follow their convention.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe</span> <span class="kn">import</span> <span class="n">PolyhedronExchangeTransformation</span> <span class="k">as</span> <span class="n">PET</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">base</span> <span class="o">=</span> <span class="n">diagonal_matrix</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">R0e1</span> <span class="o">=</span> <span class="n">PET</span><span class="o">.</span><span class="n">toral_translation</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">vector</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span><span class="n">phi</span><span class="p">)))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">R0e2</span> <span class="o">=</span> <span class="n">PET</span><span class="o">.</span><span class="n">toral_translation</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">vector</span><span class="p">((</span><span class="n">phi</span><span class="p">,</span><span class="mi">0</span><span class="p">)))</span>
</pre></div>



<p>We compute a <span class="formula">10×10</span> pattern obtained by coding the orbit of
some starting point under the <span class="formula">ℤ<sup>2</sup></span>-action <span class="formula"><i>R</i><sub>0</sub></span>.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.coding_of_PETs</span> <span class="kn">import</span> <span class="n">PETsCoding</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">coding_R0_P</span> <span class="o">=</span> <span class="n">PETsCoding</span><span class="p">((</span><span class="n">R0e1</span><span class="p">,</span><span class="n">R0e2</span><span class="p">),</span> <span class="n">P</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">coding_R0_P</span><span class="o">.</span><span class="n">pattern</span><span class="p">((</span><span class="o">.</span><span class="mi">3</span><span class="p">,</span><span class="o">.</span><span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">WangTiling</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">T0</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span><span class="o">.</span><span class="n">tikz</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_21_0.png" src="/Files/2025/output_21_0.png" />
<p>We observe that this pattern is <strong>not</strong> valid !!!</p>
</div>
<div class="section" id="let-s-fix-the-partition">
<h1>Let's fix the partition</h1>
<p>We claim that the above pattern is wrong because something is wrong in
the labelling of the atoms in the partition proposed by Jang and
Robinson for the 24 Wang tiles encoding Penrose tilings.</p>
<p>Below, we fix the partition by swapping labels 8 and 23, 9 and 22, 11
and 20, 10 and 21:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">d</span> <span class="o">=</span> <span class="p">{</span><span class="n">i</span><span class="p">:</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">24</span><span class="p">)}</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">d</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="mi">8</span><span class="p">:</span><span class="mi">23</span><span class="p">,</span> <span class="mi">23</span><span class="p">:</span><span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">:</span><span class="mi">22</span><span class="p">,</span> <span class="mi">22</span><span class="p">:</span><span class="mi">9</span><span class="p">,</span> <span class="mi">11</span><span class="p">:</span><span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">:</span><span class="mi">11</span><span class="p">,</span> <span class="mi">10</span><span class="p">:</span><span class="mi">21</span><span class="p">,</span> <span class="mi">21</span><span class="p">:</span><span class="mi">10</span><span class="p">})</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P1</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">rename_keys</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P1</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_24_0.png" src="/Files/2025/output_24_0.png" />
<p>We compute a <span class="formula">10×10</span> pattern out of this updated partition
<span class="formula"><i>P</i><sub>1</sub></span>:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">coding_R0_P1</span> <span class="o">=</span> <span class="n">PETsCoding</span><span class="p">((</span><span class="n">R0e1</span><span class="p">,</span><span class="n">R0e2</span><span class="p">),</span> <span class="n">P1</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">coding_R0_P1</span><span class="o">.</span><span class="n">pattern</span><span class="p">((</span><span class="o">.</span><span class="mi">3</span><span class="p">,</span><span class="o">.</span><span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">WangTiling</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">T0</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span><span class="o">.</span><span class="n">tikz</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_26_0.png" src="/Files/2025/output_26_0.png" />
<p>We observe that this pattern <strong>is valid</strong> !!!</p>
</div>
<div class="section" id="understanding-the-issue-using-edge-label-partitions">
<h1>Understanding the issue using edge label partitions</h1>
<p>Let us try to understand the fix in terms of the Wang tiles east, north,
west and south edge labels partitions induced by the original partition.</p>
<p>Indeed, since each atom of the partition corresponds to a Wang tile, we
can deduce a partition of the unit square for the east labels (and
respectively for the north, west and south labels) by merging two atoms
in the partition if their east edge label is the same.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="k">def</span> <span class="nf">edge_label_partitions</span><span class="p">(</span><span class="n">partition</span><span class="p">,</span> <span class="n">tiles</span><span class="p">):</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">EAST</span> <span class="o">=</span> <span class="n">partition</span><span class="o">.</span><span class="n">merge_atoms</span><span class="p">({</span><span class="n">i</span><span class="p">:</span><span class="n">tiles</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">24</span><span class="p">)})</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">NORTH</span> <span class="o">=</span> <span class="n">partition</span><span class="o">.</span><span class="n">merge_atoms</span><span class="p">({</span><span class="n">i</span><span class="p">:</span><span class="n">tiles</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">24</span><span class="p">)})</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">WEST</span> <span class="o">=</span> <span class="n">partition</span><span class="o">.</span><span class="n">merge_atoms</span><span class="p">({</span><span class="n">i</span><span class="p">:</span><span class="n">tiles</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">24</span><span class="p">)})</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">SOUTH</span> <span class="o">=</span> <span class="n">partition</span><span class="o">.</span><span class="n">merge_atoms</span><span class="p">({</span><span class="n">i</span><span class="p">:</span><span class="n">tiles</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">3</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">24</span><span class="p">)})</span>
<span class="o">....</span><span class="p">:</span>     <span class="k">return</span> <span class="n">EAST</span><span class="p">,</span> <span class="n">NORTH</span><span class="p">,</span> <span class="n">WEST</span><span class="p">,</span> <span class="n">SOUTH</span>
<span class="n">sage</span><span class="p">:</span> <span class="k">def</span> <span class="nf">draw_edge_label_partitions</span><span class="p">(</span><span class="n">partition</span><span class="p">,</span> <span class="n">tiles</span><span class="p">):</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">EAST</span><span class="p">,</span> <span class="n">NORTH</span><span class="p">,</span> <span class="n">WEST</span><span class="p">,</span> <span class="n">SOUTH</span> <span class="o">=</span> <span class="n">edge_label_partitions</span><span class="p">(</span><span class="n">partition</span><span class="p">,</span> <span class="n">tiles</span><span class="p">)</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">L</span> <span class="o">=</span> <span class="p">[</span><span class="n">EAST</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span> <span class="o">+</span> <span class="n">text</span><span class="p">(</span><span class="s1">&#39;EAST&#39;</span><span class="p">,</span> <span class="p">(</span><span class="o">.</span><span class="mi">5</span><span class="p">,</span><span class="mf">1.05</span><span class="p">)),</span>
<span class="o">....</span><span class="p">:</span>          <span class="n">NORTH</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span> <span class="o">+</span> <span class="n">text</span><span class="p">(</span><span class="s1">&#39;NORTH&#39;</span><span class="p">,</span> <span class="p">(</span><span class="o">.</span><span class="mi">5</span><span class="p">,</span><span class="mf">1.05</span><span class="p">)),</span>
<span class="o">....</span><span class="p">:</span>          <span class="n">WEST</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span> <span class="o">+</span> <span class="n">text</span><span class="p">(</span><span class="s1">&#39;WEST&#39;</span><span class="p">,</span> <span class="p">(</span><span class="o">.</span><span class="mi">5</span><span class="p">,</span><span class="mf">1.05</span><span class="p">)),</span>
<span class="o">....</span><span class="p">:</span>          <span class="n">SOUTH</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span> <span class="o">+</span> <span class="n">text</span><span class="p">(</span><span class="s1">&#39;SOUTH&#39;</span><span class="p">,</span> <span class="p">(</span><span class="o">.</span><span class="mi">5</span><span class="p">,</span><span class="mf">1.05</span><span class="p">))]</span>
<span class="o">....</span><span class="p">:</span>     <span class="k">return</span> <span class="n">graphics_array</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">nrows</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
</pre></div>



<p>This is what we get using the partition proposed by Jang and Robinson
for the 24 Wang tiles encoding Penrose tilings:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">draw_edge_label_partitions</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">T0</span><span class="p">)</span>
</pre></div>



<img alt="/Files/2025/output_31_0.png" src="/Files/2025/output_31_0.png" />
<p>Here are some observations which are normal:</p>
<blockquote>
<ul class="simple">
<li>partitions NORTH and EAST are symmetric under a reflexion by the positive
diagonal (remember that the tile set is symmetric under the positive
diagonal)</li>
<li>partitions WEST and SOUTH are symmetric under a reflexion by the positive
diagonal (remember that the tile set is symmetric under the positive
diagonal)</li>
</ul>
</blockquote>
<p>Here are some observations which are <strong>not</strong> normal:</p>
<blockquote>
<ul class="simple">
<li>partitions WEST and EAST do not give the same area to the same index (in a
Wang tiling, the frequency of a EAST label should be equal to the frequency
of the same WEST label)</li>
<li>partitions SOUTH and NORTH do not give the same area to the same index (in a
Wang tiling, the frequency of a NORTH label should be equal to the frequency
of the same SOUTH label)</li>
<li>partitions EAST and WEST are not a translate of one another (idealy a
horizontal translate)</li>
<li>partitions SOUTH and NORTH are not a translate of one another (idealy a
vertical translate)</li>
</ul>
</blockquote>
<p>Another indication that something may be wrong is:</p>
<blockquote>
<ul class="simple">
<li>atoms B, H, E, J, A, G are not convex in the torus</li>
</ul>
</blockquote>
<p>This is not a necessity. Atoms are not convex in the Markov partition
associated to Jeandel-Rao tilings [2]. But they are convex for the
Ammann set of 16 Wang tiles and their generalization to metallic mean
numbers made in [3,4]. Since Penrose tilings are closely related to
Ammann A2 tilings, we may also expect to have simple convex atoms in
each of the four edge label partitions.</p>
<div class="line-block">
<div class="line">[2]&nbsp;Markov partitions for toral <span class="formula">ℤ<sup>2</sup></span>-rotations
featuring Jeandel-Rao Wang shift and model sets, Annales Henri
Lebesgue 4 (2021) 283-324. <a class="reference external" href="https://doi.org/10.5802/ahl.73">doi:10.5802/ahl.73</a></div>
<div class="line">[3]&nbsp;Metallic mean Wang tiles I: self-similarity, aperiodicity and
minimality, <a class="reference external" href="https://arxiv.org/abs/2312.03652">arxiv:2312.03652</a></div>
<div class="line">[4] Metallic mean Wang tiles II: the dynamics of an aperiodic computer
chip, <a class="reference external" href="https://arxiv.org/abs/2403.03197">arxiv:2403.03197</a></div>
</div>
<p>Here is the area of each atom in each of the four partitions. We observe
that only atoms C and D have the same area in each of the four
partitions.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="k">def</span> <span class="nf">table_of_area_of_atom_in_east_north_west_south_partitions</span><span class="p">(</span><span class="n">partition</span><span class="p">,</span> <span class="n">tiles</span><span class="p">):</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">columns</span> <span class="o">=</span> <span class="p">[]</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">labels</span> <span class="o">=</span> <span class="s1">&#39;ABCDEFGHIJ&#39;</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">EAST</span><span class="p">,</span> <span class="n">NORTH</span><span class="p">,</span> <span class="n">WEST</span><span class="p">,</span> <span class="n">SOUTH</span> <span class="o">=</span> <span class="n">edge_label_partitions</span><span class="p">(</span><span class="n">partition</span><span class="p">,</span> <span class="n">tiles</span><span class="p">)</span>
<span class="o">....</span><span class="p">:</span>     <span class="k">for</span> <span class="n">partition</span> <span class="ow">in</span> <span class="p">[</span><span class="n">EAST</span><span class="p">,</span> <span class="n">NORTH</span><span class="p">,</span> <span class="n">WEST</span><span class="p">,</span> <span class="n">SOUTH</span><span class="p">]:</span>
<span class="o">....</span><span class="p">:</span>         <span class="n">d</span> <span class="o">=</span> <span class="n">partition</span><span class="o">.</span><span class="n">volume_dict</span><span class="p">()</span>
<span class="o">....</span><span class="p">:</span>         <span class="n">column</span> <span class="o">=</span> <span class="p">[</span><span class="n">d</span><span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">labels</span><span class="p">]</span>
<span class="o">....</span><span class="p">:</span>         <span class="n">columns</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">column</span><span class="p">)</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">header_row</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;EAST&#39;</span><span class="p">,</span> <span class="s1">&#39;NORTH&#39;</span><span class="p">,</span> <span class="s1">&#39;WEST&#39;</span><span class="p">,</span> <span class="s1">&#39;SOUTH&#39;</span><span class="p">]</span>
<span class="o">....</span><span class="p">:</span>     <span class="k">return</span> <span class="n">table</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="n">columns</span><span class="p">,</span> <span class="n">header_row</span><span class="o">=</span><span class="n">header_row</span><span class="p">,</span> <span class="n">header_column</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;&#39;</span><span class="p">]</span><span class="o">+</span><span class="nb">list</span><span class="p">(</span><span class="n">labels</span><span class="p">))</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">table_of_area_of_atom_in_east_north_west_south_partitions</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">T0</span><span class="p">)</span>
    <span class="err">│</span> <span class="n">EAST</span>             <span class="n">NORTH</span>            <span class="n">WEST</span>             <span class="n">SOUTH</span>
<span class="err">├───┼────────────────┼────────────────┼────────────────┼────────────────┤</span>
  <span class="n">A</span> <span class="err">│</span> <span class="mi">15</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">-</span> <span class="mi">12</span>    <span class="mi">15</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">-</span> <span class="mi">12</span>    <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">B</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="mi">15</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">-</span> <span class="mi">12</span>    <span class="mi">15</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">-</span> <span class="mi">12</span>
  <span class="n">C</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">D</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">E</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="o">-</span><span class="mi">11</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">9</span>    <span class="o">-</span><span class="mi">11</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">9</span>
  <span class="n">F</span> <span class="err">│</span> <span class="o">-</span><span class="mi">11</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">9</span>    <span class="o">-</span><span class="mi">11</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">9</span>    <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">G</span> <span class="err">│</span> <span class="o">-</span><span class="mi">8</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">13</span>      <span class="o">-</span><span class="mi">8</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">13</span>      <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">H</span> <span class="err">│</span> <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">8</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">13</span>      <span class="o">-</span><span class="mi">8</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">13</span>
  <span class="n">I</span> <span class="err">│</span> <span class="mi">5</span><span class="o">*</span><span class="n">phi</span> <span class="o">-</span> <span class="mi">8</span>        <span class="mi">5</span><span class="o">*</span><span class="n">phi</span> <span class="o">-</span> <span class="mi">8</span>        <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">J</span> <span class="err">│</span> <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="mi">5</span><span class="o">*</span><span class="n">phi</span> <span class="o">-</span> <span class="mi">8</span>        <span class="mi">5</span><span class="o">*</span><span class="n">phi</span> <span class="o">-</span> <span class="mi">8</span>
</pre></div>



<p>But, we observe that we can fix the partitions if we assume that the
atoms C and D in the four partitions are correct. There is a unique
translation sending atoms C,D in the partition WEST to the atoms C and D
in the partition EAST. That translation should send the partition WEST
exactly on EAST. Similarly for SOUTH and NORTH. This suggest a way to
fix atoms B, H, E, J, A, G in the partition.</p>
</div>
<div class="section" id="fixed-edge-labels-partitions">
<h1>Fixed Edge labels partitions</h1>
<p>Using the fixed partition, here is what we get.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">P1</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_39_0.png" src="/Files/2025/output_39_0.png" />


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">draw_edge_label_partitions</span><span class="p">(</span><span class="n">P1</span><span class="p">,</span> <span class="n">T0</span><span class="p">)</span>
</pre></div>



<img alt="/Files/2025/output_40_0.png" src="/Files/2025/output_40_0.png" />
<p>Now it looks good! As for the partitions associated to the metallic mean
Wang tiles, the four partitions are isometric copies of the other ones
(under toral translation or reflection).</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">table_of_area_of_atom_in_east_north_west_south_partitions</span><span class="p">(</span><span class="n">P1</span><span class="p">,</span> <span class="n">T0</span><span class="p">)</span>
    <span class="err">│</span> <span class="n">EAST</span>             <span class="n">NORTH</span>            <span class="n">WEST</span>             <span class="n">SOUTH</span>
<span class="err">├───┼────────────────┼────────────────┼────────────────┼────────────────┤</span>
  <span class="n">A</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">B</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">C</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">D</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">E</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">F</span> <span class="err">│</span> <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>        <span class="n">phi</span> <span class="o">-</span> <span class="mi">3</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">G</span> <span class="err">│</span> <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">H</span> <span class="err">│</span> <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">I</span> <span class="err">│</span> <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>
  <span class="n">J</span> <span class="err">│</span> <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>   <span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="p">(</span><span class="n">phi</span><span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">n</span><span class="p">(),</span> <span class="p">(</span><span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">n</span><span class="p">()</span>
<span class="p">(</span><span class="mf">0.118033988749895</span><span class="p">,</span> <span class="mf">0.0729490168751576</span><span class="p">)</span>
</pre></div>



<p>Labels A, B, C, D, E and F all have the same frequency of
<span class="formula"><i>ϕ</i> − <span class="fraction"><span class="ignored">(</span><span class="numerator">3</span><span class="ignored">)/(</span><span class="denominator">2</span><span class="ignored">)</span></span> ≈ 0.118</span>.</p>
<p>Labels G, H, I and J all have the same frequency of
<span class="formula"> − <span class="fraction"><span class="ignored">(</span><span class="numerator">3</span><span class="ignored">)/(</span><span class="denominator">2</span><span class="ignored">)</span></span><i>ϕ</i> + <span class="fraction"><span class="ignored">(</span><span class="numerator">5</span><span class="ignored">)/(</span><span class="denominator">2</span><span class="ignored">)</span></span> ≈ 0.0729</span>.</p>
<p>We check that frequencies sum to 1:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="mi">6</span> <span class="o">*</span> <span class="p">(</span><span class="n">phi</span><span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">*</span> <span class="p">(</span><span class="o">-</span><span class="mi">3</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">5</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>
<span class="mi">1</span>
</pre></div>



</div>
<div class="section" id="proposed-partition-for-the-encoding-of-the-penrose-tilings-into-24-wang-tiles">
<h1>Proposed partition for the encoding of the Penrose tilings into 24 Wang tiles</h1>
<p>As done with the Markov partition associated to Jeandel-Rao aperiodic
tilings, and for the Markov partition associated to the family of
metallic mean Wang tiles, I think it is more natural to associate
horizontal (vertical) translations in the internal space with horizontal
(vertical) translations in the physical space. This way, the brain is
less mixed up and the projections in the physical space <span class="formula"><i>π</i></span> and
in the internal space <span class="formula"><i>π</i><sub><span class="textrm">int</span></sub></span> of the cut and project
scheme are defined more naturally. This way the internal space and
physical space can even be identified: this is the root of the
do-it-yourself tutorial allowing the construction of Jeandel-Rao tilings
[5]. See also my <em>Habilitation à diriger des recherches</em> written in
English during Spring 2025 for more information [6].</p>
<div class="line-block">
<div class="line">[5] <a class="reference external" href="/blogue/2024/04/a-do-it-yourself-polygonal-partition-to-construct-jeandel-rao-tilings/">A do-it-yourself polygonal partition to construct Jeandel-Rao
tilings</a>, April 2024,</div>
<div class="line">[6]&nbsp;Sébastien Labbé, <a class="reference external" href="/HDR/">Aperiodic order: from combinatorics to geometry
via symbolic dynamics, number theory and algorithms</a>, Mémoire
d’habilitation à diriger des recherches,</div>
</div>
<p>First, we flip the partition <span class="formula"><i>P</i><sub>1</sub></span> by the positive diagonal. This
exchanges the role of x and y axis.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">P2</span> <span class="o">=</span> <span class="n">P1</span><span class="o">.</span><span class="n">apply_linear_map</span><span class="p">(</span><span class="n">matrix</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">]))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P2</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_50_0.png" src="/Files/2025/output_50_0.png" />
<p>This allows to define the <span class="formula">ℤ<sup>2</sup></span>-action <span class="formula"><i>R</i><sub>1</sub></span> on the
torus with horizontal and vertical translations for <span class="formula"><i>e</i><sub>1</sub></span> and
<span class="formula"><i>e</i><sub>2</sub></span> respectively:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">base</span> <span class="o">=</span> <span class="n">diagonal_matrix</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">R1e1</span> <span class="o">=</span> <span class="n">PET</span><span class="o">.</span><span class="n">toral_translation</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">vector</span><span class="p">((</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">,</span><span class="mi">0</span><span class="p">)))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">R1e2</span> <span class="o">=</span> <span class="n">PET</span><span class="o">.</span><span class="n">toral_translation</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">vector</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="o">/</span><span class="n">phi</span><span class="p">)))</span>
</pre></div>



<p>Then, we rotate the partition. This changes the origin of the partition.
This change may be optional, but it makes the partition look closer to
the partitions already studied in [2,3,4]. It simplifies the explanation
of any relation between them (and there is one, see below!).</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">P3</span> <span class="o">=</span> <span class="n">R1e1</span><span class="p">(</span><span class="n">P2</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P3</span> <span class="o">=</span> <span class="n">R1e2</span><span class="p">(</span><span class="n">P3</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P3</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_54_0.png" src="/Files/2025/output_54_0.png" />
<p>We observe that the partition <span class="formula"><i>P</i><sub>3</sub></span> associated to the 24 Wang
tiles encoding Penrose tiling is a refinement of the partition
associated to the 16 Ammann tiles (see Figure 15 in [4] as the 16 Ammann
tiles are equivalent to the <span class="formula"><i>n</i></span>-th metallic mean Wang tiles when
<span class="formula"><i>n</i> = 1</span>).</p>
<p>We compute a <span class="formula">10×10</span> pattern obtained by coding the orbit of
some starting point under the <span class="formula">ℤ<sup>2</sup></span>-action <span class="formula"><i>R</i><sub>1</sub></span>
using partition <span class="formula"><i>P</i><sub>3</sub></span>.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.coding_of_PETs</span> <span class="kn">import</span> <span class="n">PETsCoding</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">coding_R1_P3</span> <span class="o">=</span> <span class="n">PETsCoding</span><span class="p">((</span><span class="n">R1e1</span><span class="p">,</span><span class="n">R1e2</span><span class="p">),</span> <span class="n">P3</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">coding_R1_P3</span><span class="o">.</span><span class="n">pattern</span><span class="p">((</span><span class="o">.</span><span class="mi">3</span><span class="p">,</span><span class="o">.</span><span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span> <span class="o">=</span> <span class="n">WangTiling</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">T0</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pattern</span><span class="o">.</span><span class="n">tikz</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_58_0.png" src="/Files/2025/output_58_0.png" />
<p>We are happy to see that the pattern is still valid after all the
changes we have made!</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">draw_edge_label_partitions</span><span class="p">(</span><span class="n">P3</span><span class="p">,</span> <span class="n">T0</span><span class="p">)</span>
</pre></div>



<img alt="/Files/2025/output_60_0.png" src="/Files/2025/output_60_0.png" />
<p>We observe that the EAST, NORTH, WEST and SOUTH partitions are a
refinement of the EAST, NORTH, WEST and SOUTH partitions associated to
the Ammann tiles partition (see Figure 15 in [4]).</p>
<p>The difference between the Ammann EAST and 24 Wang tiles Penrose EAST
partition is the addition of two closed geodesics of slope -1 on the
2-torus passing through the origin and through the vertex
<span class="formula">(0, <i>φ</i><sup> − 1</sup>)</span>.</p>
<p>It is possible that there is a clever way of including this information
into the labels of the Wang tiles as we have done it for the family of metallic
mean Wang tiles. Possibly, we need to use 4-dimension vectors for the tile
labels instead of 3-dimensional integer vectors. This remains an open question.</p>
</div>
<div class="section" id="wang-tiles-deduced-from-the-partition-and-mathbb-z-2-action">
<h1>Wang tiles deduced from the partition and <span class="formula">ℤ<sup>2</sup></span>-action</h1>
<p>We check that the Wang tiles computed from the partition <span class="formula"><i>P</i><sub>3</sub></span> and
<span class="formula">ℤ<sup>2</sup></span>-action <span class="formula"><i>R</i><sub>1</sub></span> is the original set of 24 Wang
tiles defined by Jang and Robinson.</p>
<p>See Proposition 8.1 in [2].</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span> <span class="o">=</span> <span class="n">coding_R1_P3</span><span class="o">.</span><span class="n">to_wang_tiles</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T</span><span class="o">.</span><span class="n">tikz</span><span class="p">()</span>
</pre></div>



<img alt="/Files/2025/output_64_0.png" src="/Files/2025/output_64_0.png" />


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span><span class="o">.</span><span class="n">is_equivalent</span><span class="p">(</span><span class="n">T0</span><span class="p">,</span> <span class="n">certificate</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="p">(</span><span class="kc">True</span><span class="p">,</span>
 <span class="p">{</span><span class="s1">&#39;3&#39;</span><span class="p">:</span> <span class="s1">&#39;D&#39;</span><span class="p">,</span>
  <span class="s1">&#39;0&#39;</span><span class="p">:</span> <span class="s1">&#39;A&#39;</span><span class="p">,</span>
  <span class="s1">&#39;6&#39;</span><span class="p">:</span> <span class="s1">&#39;G&#39;</span><span class="p">,</span>
  <span class="s1">&#39;1&#39;</span><span class="p">:</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span>
  <span class="s1">&#39;7&#39;</span><span class="p">:</span> <span class="s1">&#39;H&#39;</span><span class="p">,</span>
  <span class="s1">&#39;2&#39;</span><span class="p">:</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span>
  <span class="s1">&#39;8&#39;</span><span class="p">:</span> <span class="s1">&#39;I&#39;</span><span class="p">,</span>
  <span class="s1">&#39;4&#39;</span><span class="p">:</span> <span class="s1">&#39;E&#39;</span><span class="p">,</span>
  <span class="s1">&#39;5&#39;</span><span class="p">:</span> <span class="s1">&#39;F&#39;</span><span class="p">,</span>
  <span class="s1">&#39;9&#39;</span><span class="p">:</span> <span class="s1">&#39;J&#39;</span><span class="p">},</span>
 <span class="p">{</span><span class="s1">&#39;3&#39;</span><span class="p">:</span> <span class="s1">&#39;D&#39;</span><span class="p">,</span>
  <span class="s1">&#39;0&#39;</span><span class="p">:</span> <span class="s1">&#39;A&#39;</span><span class="p">,</span>
  <span class="s1">&#39;6&#39;</span><span class="p">:</span> <span class="s1">&#39;G&#39;</span><span class="p">,</span>
  <span class="s1">&#39;1&#39;</span><span class="p">:</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span>
  <span class="s1">&#39;7&#39;</span><span class="p">:</span> <span class="s1">&#39;H&#39;</span><span class="p">,</span>
  <span class="s1">&#39;2&#39;</span><span class="p">:</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span>
  <span class="s1">&#39;8&#39;</span><span class="p">:</span> <span class="s1">&#39;I&#39;</span><span class="p">,</span>
  <span class="s1">&#39;4&#39;</span><span class="p">:</span> <span class="s1">&#39;E&#39;</span><span class="p">,</span>
  <span class="s1">&#39;5&#39;</span><span class="p">:</span> <span class="s1">&#39;F&#39;</span><span class="p">,</span>
  <span class="s1">&#39;9&#39;</span><span class="p">:</span> <span class="s1">&#39;J&#39;</span><span class="p">},</span>
 <span class="n">Substitution</span> <span class="mi">2</span><span class="n">d</span><span class="p">:</span> <span class="p">{</span><span class="mi">0</span><span class="p">:</span> <span class="p">[[</span><span class="mi">0</span><span class="p">]],</span> <span class="mi">1</span><span class="p">:</span> <span class="p">[[</span><span class="mi">1</span><span class="p">]],</span> <span class="mi">2</span><span class="p">:</span> <span class="p">[[</span><span class="mi">2</span><span class="p">]],</span> <span class="mi">3</span><span class="p">:</span> <span class="p">[[</span><span class="mi">3</span><span class="p">]],</span> <span class="mi">4</span><span class="p">:</span> <span class="p">[[</span><span class="mi">4</span><span class="p">]],</span> <span class="mi">5</span><span class="p">:</span>
 <span class="p">[[</span><span class="mi">5</span><span class="p">]],</span> <span class="mi">6</span><span class="p">:</span> <span class="p">[[</span><span class="mi">6</span><span class="p">]],</span> <span class="mi">7</span><span class="p">:</span> <span class="p">[[</span><span class="mi">7</span><span class="p">]],</span> <span class="mi">8</span><span class="p">:</span> <span class="p">[[</span><span class="mi">8</span><span class="p">]],</span> <span class="mi">9</span><span class="p">:</span> <span class="p">[[</span><span class="mi">9</span><span class="p">]],</span> <span class="mi">10</span><span class="p">:</span> <span class="p">[[</span><span class="mi">10</span><span class="p">]],</span> <span class="mi">11</span><span class="p">:</span> <span class="p">[[</span><span class="mi">11</span><span class="p">]],</span> <span class="mi">12</span><span class="p">:</span>
 <span class="p">[[</span><span class="mi">12</span><span class="p">]],</span> <span class="mi">13</span><span class="p">:</span> <span class="p">[[</span><span class="mi">13</span><span class="p">]],</span> <span class="mi">14</span><span class="p">:</span> <span class="p">[[</span><span class="mi">14</span><span class="p">]],</span> <span class="mi">15</span><span class="p">:</span> <span class="p">[[</span><span class="mi">15</span><span class="p">]],</span> <span class="mi">16</span><span class="p">:</span> <span class="p">[[</span><span class="mi">16</span><span class="p">]],</span> <span class="mi">17</span><span class="p">:</span> <span class="p">[[</span><span class="mi">17</span><span class="p">]],</span> <span class="mi">18</span><span class="p">:</span> <span class="p">[[</span><span class="mi">18</span><span class="p">]],</span>
 <span class="mi">19</span><span class="p">:</span> <span class="p">[[</span><span class="mi">19</span><span class="p">]],</span> <span class="mi">20</span><span class="p">:</span> <span class="p">[[</span><span class="mi">20</span><span class="p">]],</span> <span class="mi">21</span><span class="p">:</span> <span class="p">[[</span><span class="mi">21</span><span class="p">]],</span> <span class="mi">22</span><span class="p">:</span> <span class="p">[[</span><span class="mi">22</span><span class="p">]],</span> <span class="mi">23</span><span class="p">:</span> <span class="p">[[</span><span class="mi">23</span><span class="p">]]})</span>
</pre></div>



</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Introduction to Python/SageMath]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2023/06/introduction-to-python-sagemath" />
    <id>http://www.slabbe.org/blogue/2023/06/introduction-to-python-sagemath</id>
    <updated>2023-06-27T16:57:00Z</updated>
    <published>2023-06-27T16:57:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <summary type="html"><![CDATA[Introduction to Python/SageMath]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2023/06/introduction-to-python-sagemath"><![CDATA[<div class="document">
<p>On Wednesday June 28th, 2023, I give short a Introduction to Python/SageMath as
an online course organized by <a class="reference external" href="https://lmv.math.cnrs.fr/laboratoire/annuaire/membres-du-laboratoire/pierre-guy-plamondon/">Pierre-Guy Plamondon</a> in <a class="reference external" href="https://mathinparis2023.imo.universite-paris-saclay.fr/">Mathematical Summer
in Paris (MSP23)</a> on WorkAdventure. Below is the material that will be
presented or suggested.</p>
<p><strong>Exercises</strong>:</p>
<blockquote>
<ol class="arabic simple">
<li>Install and open a Jupyter notebook and do the User Interface Tour in the
help menu.</li>
<li>Programming with Python. Here is a list of Jupyter notebooks to learn
programming in Python: <a class="reference external" href="/Files/2023/ProgrammingExercises.zip">ProgrammingExercises.zip</a> or
<a class="reference external" href="/Files/2023/ProgrammingExercises.tar.xz">ProgrammingExercises.tar.xz</a></li>
<li>Reproduce the computations made by <a class="reference external" href="https://www.buzzfeednews.com/">BuzzFeedNews</a> in a <a class="reference external" href="https://github.com/BuzzFeedNews/everything">github repository of
your choice</a>, for instance about the <a class="reference external" href="https://github.com/BuzzFeedNews/2018-05-fentanyl-and-cocaine-overdose-deaths">fentanyl and cocaine overdose
deaths</a> (2018) or about <a class="reference external" href="https://github.com/BuzzFeedNews/2016-01-tennis-betting-analysis">The Tennis Racket</a> (2016).</li>
<li>Solve some problems from the <a class="reference external" href="https://projecteuler.net/">Project Euler</a>. Project Euler contains more
than 500 exercises that have to be solved with a computer</li>
<li>Reproduce one or more images from the <a class="reference external" href="https://matplotlib.org/stable/gallery/index.html">matplotlib library</a>.</li>
<li>Download the book <a class="reference external" href="https://www.sagemath.org/sagebook/english.html">Mathematical Computation with Sage</a> by Paul Zimmermann
et al. about the <a class="reference external" href="https://www.sagemath.org/">SageMath</a> open source software. Reproduce the
computations made in a section of your choice in the book.</li>
<li>Visit <a class="reference external" href="https://ask.sagemath.org/questions/">https://ask.sagemath.org/questions/</a> and try to reproduce some of the
<em>best</em> answers to questions of interest for you.</li>
<li>Choose a section of your choice in the <a class="reference external" href="https://doc.sagemath.org/html/en/reference/index.html">SageMath very large Reference
Manual</a> and reproduce the computations made in it.</li>
</ol>
</blockquote>
<p>When working on the above, two principles applies:</p>
<blockquote>
<ul class="simple">
<li><em>Once you finished solving a notebook or a problem on Project Euler on
your own you need to explain your solution to at least one other person
(who has already solved the same notebook or problem).</em></li>
<li><em>Once you reproduced the computation made by BuzzFeedNews, matplotlib
image or some computation, you need to present and explain it to at least
one other person.</em></li>
</ul>
</blockquote>
<p><strong>Supplementary material</strong>:</p>
<blockquote>
<ol class="arabic simple" start="9">
<li>Experimenting with Dynamical systems in SageMath: <a class="reference external" href="/Files/2023/DynamicalSystemExercices.zip">DynamicalSystemExercices.zip</a></li>
<li>Some more notebooks and exercices from <a class="reference external" href="https://github.com/videlec/aims-python-rwanda-2016">this course given by Vincent Delecroix at AIMS in Rwanda (2016)</a>.</li>
</ol>
</blockquote>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Découpe laser du chapeau, tuile apériodique découverte récemment]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2023/05/decoupe-laser-du-chapeau-tuile-aperiodique-decouverte-recemment" />
    <id>http://www.slabbe.org/blogue/2023/05/decoupe-laser-du-chapeau-tuile-aperiodique-decouverte-recemment</id>
    <updated>2023-05-25T11:57:00Z</updated>
    <published>2023-05-25T11:57:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="slabbe spkg" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <category scheme="http://www.slabbe.org/blogue" term="découpe laser" />
    <summary type="html"><![CDATA[Découpe laser du chapeau, tuile apériodique découverte récemment]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2023/05/decoupe-laser-du-chapeau-tuile-aperiodique-decouverte-recemment"><![CDATA[<div class="document">
<p>Le chapeau est une <a class="reference external" href="https://cs.uwaterloo.ca/~csk/hat/">tuile apériodique</a> découverte par David Smith, Joseph
Samuel Myers, Craig S. Kaplan, et Chaim Goodman-Strauss le <a class="reference external" href="https://arxiv.org/abs/2303.10798">20 mars 2023</a>.
Suite à un <a class="reference external" href="https://www.youtube.com/watch?v=FkZPMf73qYc">exposé</a> donné le 26 mars au <a class="reference external" href="https://momath.org/">National Museum of Mathematics</a>, la
nouvelle s'est vite répandue. En effet, cette découverte a été mentionnée les
jours <a class="reference external" href="https://cp4space.hatsya.com/2023/03/21/aperiodic-monotile/">suivants</a> <a class="reference external" href="https://www.sineofthetimes.org/hats-off-to-this-aperiodic-tiling/">dans</a> <a class="reference external" href="https://gilkalai.wordpress.com/2023/03/25/an-aperiodic-monotile/">des</a> <a class="reference external" href="https://mathenchant.wordpress.com/2023/04/20/seekers-of-the-one-stone/">blogues</a> puis dans <a class="reference external" href="https://www.nytimes.com/2023/03/28/science/mathematics-tiling-einstein.html">Le New York Times</a> le 28
mars, <a class="reference external" href="https://www.lemonde.fr/sciences/article/2023/03/29/mathematiques-la-pose-du-carrelage-une-drole-d-equation_6167457_1650684.html">Le Monde</a> le 29 mars, puis <a class="reference external" href="https://www.theguardian.com/science/2023/apr/03/new-einstein-shape-aperiodic-monotile">The Guardian</a> et <a class="reference external" href="https://www.quantamagazine.org/hobbyist-finds-maths-elusive-einstein-tile-20230404/">QuantaMagazine</a> le 4
avril. Un <a class="reference external" href="https://www.youtube.com/watch?v=z_qLZdBM4C8">vidéo</a> de 20 minutes, réalisé par Passe-Science et publié début
le 3 mai, explique le résultat et son contexte.</p>
<p>Déjà des articles proposant des résultats plus approfondis sur la tuile par
des experts du domaine <a class="reference external" href="http://arxiv.org/abs/2305.01174">sont</a> <a class="reference external" href="http://arxiv.org/abs/2305.05639">parus</a> sur arXiv en mai 2023. Ils interprêtent
les pavages comme des coupes et projection de réseaux de dimension supérieure.
Le deuxième propose même une partition de la fenêtre de l'espace
interne, un peu <a class="reference external" href="https://doi.org/10.5802/ahl.73">comme</a> pour les pavages de Jeandel-Rao, à la différence qu'ici
la partition a des bords fractales ce qui est pour moi une grande surprise.</p>
<p>Comme je faisais une intervention dans l'école de mon garçon à Bègles le 3 mai
et au Lycée Kastler de Talence le 4 mai, j'ai réalisé un projet de découpe
laser sur la tuile apériodique afin de partager cette récente découverte.</p>
<p>La première question était de construire un pavage d'un rectangle assez grand
avec la pièce apériodique. Pour ce faire, j'ai ajouté un <a class="reference external" href="https://gitlab.com/seblabbe/slabbe/-/blob/develop/slabbe/aperiodic_monotile.py">nouveau module</a>
dans mon package optionel au logiciel SageMath.</p>
<p>Le module réalise une réduction à une instance du problème de la couverture
universelle, qui peut être résolu dans SageMath en utilisant l'algorithme des
liens dansants de Donald Knuth, les solveurs SAT ou les programmes
d'optimisation linéaire (solveur MILP).  Le code utilise le système de
coordonnées défini dans le fichier <tt class="docutils literal">validate/kitegrid.pdf</tt> qui se trouve dans
le <a class="reference external" href="https://cs.uwaterloo.ca/~csk/hat/validate.tar.gz">code source</a> associé à l'article.</p>
<p>Voici un exemple de construction d'un pavage avec la tuile apériodique. Le
calcul est fait dans le logiciel <a class="reference external" href="https://www.sagemath.org/">SageMath</a> muni de la version de développement
de mon package optionnel <a class="reference external" href="https://pypi.org/project/slabbe/">slabbe</a> qui peut être installé avec la commande <tt class="docutils literal">sage
<span class="pre">-pip</span> install slabbe</tt>. Ici, j'utilise le solveur SAT <a class="reference external" href="https://www.labri.fr/perso/lsimon/research/glucose/">Glucose</a>, développé au
<a class="reference external" href="https://www.labri.fr/">LaBRI</a>.  On peut installer glucose dans SageMath avec la commande <tt class="docutils literal">sage <span class="pre">-i</span>
glucose</tt>.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.aperiodic_monotile</span> <span class="kn">import</span> <span class="n">MonotileSolver</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">s</span> <span class="o">=</span> <span class="n">MonotileSolver</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">draw_one_solution</span><span class="p">(</span><span class="n">solver</span><span class="o">=</span><span class="s1">&#39;glucose&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s1">&#39;solution_16x17.png&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2023/solution_16x17.png"><img alt="/Files/2023/solution_16x17.png" src="/Files/2023/solution_16x17.png" style="width: 40em;" /></a>
<p>Dans la manière de résoudre la question ci-haut,
le problème est représenté par un <a class="reference external" href="https://fr.wikipedia.org/wiki/Probl%C3%A8me_de_la_couverture_exacte">problème de couverture exacte</a> qui
consiste à recouvrir exactement les entiers de 1 à n avec des sous-ensembles
choisis dans une liste de sous-ensembles déterminés. Ici, on représente
l'espace à recouvrir de manière discrète en comptant 6 points du plan par
hexagone (un point pour chaque <em>kite</em> contenu dans un hexagone).
Rappelons que la pièce Chapeau qui nous intéresse est formée d'une union
d'exactement 8 de ces kites.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">s</span><span class="o">.</span><span class="n">plot_domain</span><span class="p">()</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2023/domain.png"><img alt="/Files/2023/domain.png" src="/Files/2023/domain.png" style="width: 40em;" /></a>
<p>Ensuite, on construit une matrice de 0 et de 1 avec autant de colonnes que de
points ci-haut (16 * 17 * 2 * 6 = 3264) et autant de lignes qu'il y a de copies
isométriques de la pièce intersectant le domaine. Pour chaque copie de la
pièce, une ligne dans la matrice contient des 1 exactement dans les colonnes
associées aux kites occupés par la pièce.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">s</span><span class="o">.</span><span class="n">the_dlx_solver</span><span class="p">()</span>
<span class="n">Dancing</span> <span class="n">links</span> <span class="n">solver</span> <span class="k">for</span> <span class="mi">3264</span> <span class="n">columns</span> <span class="ow">and</span> <span class="mi">7116</span> <span class="n">rows</span>
</pre></div>



<p>Le calcul ci-haut qui a construit la matrice (sparse) indique qu'il y a 7116
copies isométriques de la pièce qui intersectent (complètement ou
partiellement) le domaine. Quand on voudra dessiner une solution, on ignorera
les pièces incomplètes.</p>
<p>On peut maintenant résoudre le problème.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">s</span> <span class="o">=</span> <span class="n">MonotileSolver</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="mi">8</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">L</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">one_solution</span><span class="p">()</span>   <span class="c1"># l&#39;algo des liens dansants de Knuth est utilisé par défaut</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">798</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">32.2</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">830</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">1</span><span class="nb">min</span> <span class="mi">20</span><span class="n">s</span>
</pre></div>



<p>Le contenu d'une solution est une liste de nombres indiquant les lignes de la
matrice de 0/1 à considérer pour former une solution. C'est-à-dire que la sous-matrice
restreinte aux lignes données comporte exactement un 1 dans chaque colonne:</p>


<div class="pygments_manni"><pre><span></span>sage: L
[81,
 85,
 125,
 128,
 ...
 1772,
 1783,
 1794,
 1815]
</pre></div>



<p>Ici, il se trouve que les solveurs SAT sont plus efficaces que l'algo des liens
dansants pour trouver une solution:</p>


<div class="pygments_manni"><pre><span></span>sage: %time L = s.one_solution(solver=&#39;glucose&#39;)
CPU times: user 326 ms, sys: 16.1 ms, total: 342 ms
Wall time: 526 ms
sage: %time L = s.one_solution(solver=&#39;kissat&#39;)
CPU times: user 335 ms, sys: 3.64 ms, total: 339 ms
Wall time: 461 ms
</pre></div>



<p>En effet, Glucose <a class="reference external" href="/blogue/2018/12/comparison-of-wang-tiling-solvers/">se comporte plutôt bien</a> pour résoudre des problèmes de
pavages du plan lorsqu'il existe une solution. Mais lorsqu'il n'y a pas de
solution, l'algo des liens dansants de Knuth est parfois <a class="reference external" href="/blogue/2018/12/comparison-of-wang-tiling-solvers/">mieux</a>. Aussi, l'algo des
liens dansants de Knuth est très efficace pour énumérer toutes les solutions.</p>
<p>Le solveur <a class="reference external" href="https://fmv.jku.at/kissat/">Kissat</a> a été <a class="reference external" href="https://doc.sagemath.org/html/en/reference/spkg/kissat.html">ajouté dans SageMath</a> par moi-même comme package
optionnel <a class="reference external" href="https://github.com/sagemath/sage/issues/34909">cette année</a> suite à une discussion avec <a class="reference external" href="https://www.labri.fr/perso/lsimon/fr/">Laurent Simon</a> au café
du LaBRI. On peut installer le solveur kissat dans SageMath avec la commande
<tt class="docutils literal">sage <span class="pre">-i</span> kissat</tt>.</p>
<p>Ici on extrait le contour des pièces d'une solution (tel que chaque arête est dessinée une
seule fois afin d'éviter que la découpeuse laser passe deux fois par chaque
arête ce qui peut endommager ou brûler le bord des pièces en bois) et on crée
un fichier pdf ou svg. Je choisis une taille de 16 double-hexagones
horizontalement et 17 verticalement, car cela crée un fichier qui correspond à
une taille de 1m x 60cm. C'est la taille de la découpeuse laser à notre
disposition:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">s</span> <span class="o">=</span> <span class="n">MonotileSolver</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tikz</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">one_solution_tikz</span><span class="p">(</span><span class="n">solver</span><span class="o">=</span><span class="s1">&#39;glucose&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tikz</span><span class="o">.</span><span class="n">pdf</span><span class="p">(</span><span class="s1">&#39;solution_16x17.pdf&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tikz</span><span class="o">.</span><span class="n">svg</span><span class="p">(</span><span class="s1">&#39;solution_16x17.svg&#39;</span><span class="p">)</span>     <span class="c1"># or</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2023/solution_16x17.svg"><object data="/Files/2023/solution_16x17.svg" style="width: 40em;" type="image/svg+xml">/Files/2023/solution_16x17.svg</object></a>
<p>Avec l'aide de <a class="reference external" href="https://www.labri.fr/perso/renault/working/index.php">David Renault</a>, mon collègue du LaBRI qui enseigne à
l'ENSEIRB et qui m'a <a class="reference external" href="/blogue/2018/09/wooden-laser-cut-jeandel-rao-tiles/">déjà</a> accompagné dans la réalisation de projets
de découpe laser, nous avons découpé le fichier ci-haut le jeudi 27 avril au
<a class="reference external" href="https://www.eirlab.net/">EirLab</a>, l'atelier de fabrication numérique (FabLab) de l'ENSEIRB-MATMECA:</p>
<a class="reference external image-reference" href="/Files/2023/DSC_0293.JPG"><img alt="/Files/2023/DSC_0293.JPG" src="/Files/2023/DSC_0293.JPG" style="width: 40em;" /></a>
<a class="reference external image-reference" href="/Files/2023/DSC_0292.JPG"><img alt="/Files/2023/DSC_0292.JPG" src="/Files/2023/DSC_0292.JPG" style="width: 40em;" /></a>
<p>Comme toujours, il faut quelque peu modifier le fichier svg dans Inkscape avant
de lancer la découpe laser. Voici le <a class="reference external" href="/Files/2023/solution_16x17-edited.svg">fichier modifié</a> juste avant la découpe.</p>
<p>Maintenant, on peut s'amuser avec les pièces:</p>
<a class="reference external image-reference" href="/Files/2023/DSC_0309.JPG"><img alt="/Files/2023/DSC_0309.JPG" src="/Files/2023/DSC_0309.JPG" style="width: 40em;" /></a>
<p>Avec mes garçons, nous avons trouvé une forme intéressante qui recouvre le plan
périodiquement à l'exception d'un trou hexagonal. Il se trouve que la même
forme peut-être créée de deux façons différentes: sur l'image ci-bas la forme à
droite est la globalement la même, mais elle n'est pas obtenue de la même façon
que celle en haut à gauche. Pourtant, toutes deux ont le même contour extérieur
et le même trou hexagonal.</p>
<a class="reference external image-reference" href="/Files/2023/DSC_0310.JPG"><img alt="/Files/2023/DSC_0310.JPG" src="/Files/2023/DSC_0310.JPG" style="width: 40em;" /></a>
<p>Cette observation, déjà faite par d'autres, a mené au recouvrement d'une sphère
avec la pièce et un trou pentagonal:</p>
<a class="reference external image-reference" href="https://twitter.com/jon/status/1651539380786413569"><img alt="/Files/2023/FuvWc5MWYAEJWcu.jpeg" src="/Files/2023/FuvWc5MWYAEJWcu.jpeg" style="width: 40em;" /></a>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Factor complexity of words generated by multidimensional continued fraction algorithms]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2022/11/factor-complexity-of-words-generated-by-multidimensional-continued-fraction-algorithms" />
    <id>http://www.slabbe.org/blogue/2022/11/factor-complexity-of-words-generated-by-multidimensional-continued-fraction-algorithms</id>
    <updated>2022-11-03T11:11:00Z</updated>
    <published>2022-11-03T11:11:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <summary type="html"><![CDATA[Factor complexity of words generated by multidimensional continued fraction algorithms]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2022/11/factor-complexity-of-words-generated-by-multidimensional-continued-fraction-algorithms"><![CDATA[<div class="document">
<p>I was asked by email how to compute with <a class="reference external" href="https://www.sagemath.org/">SageMath</a> the factor complexity of
words generated by multidimensional continued fraction algorithms. I'm copying
my answer here so that I can more easily share it.</p>
<p><strong>A) How to calculate the factor complexity of a word</strong></p>
<p>To compute the complexity in factors, we need a finite word and <em>not</em> an
infinite infinite word. In the example below, I take a prefix of the Fibonacci
word and I compute the number of factors of size 100 and of size 0 to 19:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">w</span> <span class="o">=</span> <span class="n">words</span><span class="o">.</span><span class="n">FibonacciWord</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">w</span>
<span class="n">word</span><span class="p">:</span> <span class="mf">0100101001001010010100100101001001010010.</span><span class="o">..</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">prefix</span> <span class="o">=</span> <span class="n">w</span><span class="p">[:</span><span class="mi">100000</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">prefix</span><span class="o">.</span><span class="n">number_of_factors</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="mi">101</span>
<span class="n">sage</span><span class="p">:</span> <span class="p">[</span><span class="n">prefix</span><span class="o">.</span><span class="n">number_of_factors</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">)]</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">20</span><span class="p">]</span>
</pre></div>



<p>The documentation for the <a class="reference external" href="https://doc.sagemath.org/html/en/reference/combinat/sage/combinat/words/finite_word.html#sage.combinat.words.finite_word.FiniteWord_class.number_of_factors">number_of_factors</a> method contains more examples, etc.</p>
<p><strong>B) How to construct an S-adic word in SageMath</strong></p>
<p>The method <a class="reference external" href="https://doc.sagemath.org/html/en/reference/combinat/sage/combinat/words/word_generators.html#sage.combinat.words.word_generators.WordGenerator.s_adic">words.s_adic</a> in SageMath allows to construct an S-adic sequence
from a directive sequence, a set of substitutions and a sequence of first
letters.</p>
<p>For example, we may use Kolakoski word as a directive sequence:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">directive_sequence</span> <span class="o">=</span> <span class="n">words</span><span class="o">.</span><span class="n">KolakoskiWord</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">directive_sequence</span>
<span class="n">word</span><span class="p">:</span> <span class="mf">1221121221221121122121121221121121221221.</span><span class="o">..</span>
</pre></div>



<p>Then, I define the Thue-Morse and Fibonacci substitutions:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">tm</span> <span class="o">=</span> <span class="n">WordMorphism</span><span class="p">(</span><span class="s1">&#39;a-&gt;ab,b-&gt;ba&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">fib</span> <span class="o">=</span> <span class="n">WordMorphism</span><span class="p">(</span><span class="s1">&#39;a-&gt;ab,b-&gt;a&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tm</span>
<span class="n">WordMorphism</span><span class="p">:</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">ab</span><span class="p">,</span> <span class="n">b</span><span class="o">-&gt;</span><span class="n">ba</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">fib</span>
<span class="n">WordMorphism</span><span class="p">:</span> <span class="n">a</span><span class="o">-&gt;</span><span class="n">ab</span><span class="p">,</span> <span class="n">b</span><span class="o">-&gt;</span><span class="n">a</span>
</pre></div>



<p>Then, to define an S-adic sequence, I also need to define the sequence of first
letters. Here, it is always the constant sequence a,a,a,a,...:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">repeat</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">letters</span> <span class="o">=</span> <span class="n">repeat</span><span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">)</span>
</pre></div>



<p>I associate the letter 1 in the Kolakoski sequence to the Thue-Morse morphism
and 2 to the Fibonacci morphism, this allows to construct an S-adic sequence:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">w</span> <span class="o">=</span> <span class="n">words</span><span class="o">.</span><span class="n">s_adic</span><span class="p">(</span><span class="n">directive_sequence</span><span class="p">,</span> <span class="n">letters</span><span class="p">,</span> <span class="p">{</span><span class="mi">1</span><span class="p">:</span><span class="n">tm</span><span class="p">,</span> <span class="mi">2</span><span class="p">:</span><span class="n">fib</span><span class="p">})</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">w</span>
<span class="n">word</span><span class="p">:</span> <span class="n">abbaababbaabbaabbaababbaabbaababbaababba</span><span class="o">...</span>
</pre></div>



<p>Then, as above, I can take a prefix and compute its factor complexity:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">prefix</span> <span class="o">=</span> <span class="n">w</span><span class="p">[:</span><span class="mi">100000</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="p">[</span><span class="n">prefix</span><span class="o">.</span><span class="n">number_of_factors</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">)]</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">22</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">26</span><span class="p">,</span> <span class="mi">28</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">38</span><span class="p">]</span>
</pre></div>



<p><strong>C) Creating an S-adic sequence from Brun algorithm</strong></p>
<p>With the package <a class="reference external" href="https://pypi.org/project/slabbe/">slabbe</a>, you can construct an S-adic sequence from some of the
known Multidimensional Continued Fraction Algorithm.</p>
<p>One can install it by running <tt class="docutils literal">sage <span class="pre">-pip</span> install slabbe</tt> in a terminal where
sage command exists. Sometimes this <a class="reference external" href="https://ask.sagemath.org/question/52666/error-when-installing-slabbe-package-in-sage-91/">does not work</a>.</p>
<p>Then, one may do:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.mult_cont_frac</span> <span class="kn">import</span> <span class="n">Brun</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">algo</span> <span class="o">=</span> <span class="n">Brun</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">algo</span>
<span class="n">Brun</span> <span class="mi">3</span><span class="o">-</span><span class="n">dimensional</span> <span class="n">continued</span> <span class="n">fraction</span> <span class="n">algorithm</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">D</span> <span class="o">=</span> <span class="n">algo</span><span class="o">.</span><span class="n">substitutions</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">D</span>
<span class="p">{</span><span class="mi">312</span><span class="p">:</span> <span class="n">WordMorphism</span><span class="p">:</span> <span class="mi">1</span><span class="o">-&gt;</span><span class="mi">12</span><span class="p">,</span> <span class="mi">2</span><span class="o">-&gt;</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">-&gt;</span><span class="mi">3</span><span class="p">,</span>
 <span class="mi">321</span><span class="p">:</span> <span class="n">WordMorphism</span><span class="p">:</span> <span class="mi">1</span><span class="o">-&gt;</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="o">-&gt;</span><span class="mi">21</span><span class="p">,</span> <span class="mi">3</span><span class="o">-&gt;</span><span class="mi">3</span><span class="p">,</span>
 <span class="mi">213</span><span class="p">:</span> <span class="n">WordMorphism</span><span class="p">:</span> <span class="mi">1</span><span class="o">-&gt;</span><span class="mi">13</span><span class="p">,</span> <span class="mi">2</span><span class="o">-&gt;</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">-&gt;</span><span class="mi">3</span><span class="p">,</span>
 <span class="mi">231</span><span class="p">:</span> <span class="n">WordMorphism</span><span class="p">:</span> <span class="mi">1</span><span class="o">-&gt;</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="o">-&gt;</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">-&gt;</span><span class="mi">31</span><span class="p">,</span>
 <span class="mi">123</span><span class="p">:</span> <span class="n">WordMorphism</span><span class="p">:</span> <span class="mi">1</span><span class="o">-&gt;</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="o">-&gt;</span><span class="mi">23</span><span class="p">,</span> <span class="mi">3</span><span class="o">-&gt;</span><span class="mi">3</span><span class="p">,</span>
 <span class="mi">132</span><span class="p">:</span> <span class="n">WordMorphism</span><span class="p">:</span> <span class="mi">1</span><span class="o">-&gt;</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="o">-&gt;</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="o">-&gt;</span><span class="mi">32</span><span class="p">}</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">directive_sequence</span> <span class="o">=</span> <span class="n">algo</span><span class="o">.</span><span class="n">coding_iterator</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="n">e</span><span class="p">,</span><span class="n">pi</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="p">[</span><span class="nb">next</span><span class="p">(</span><span class="n">directive_sequence</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>
<span class="p">[</span><span class="mi">123</span><span class="p">,</span> <span class="mi">312</span><span class="p">,</span> <span class="mi">312</span><span class="p">,</span> <span class="mi">321</span><span class="p">,</span> <span class="mi">132</span><span class="p">,</span> <span class="mi">123</span><span class="p">,</span> <span class="mi">312</span><span class="p">,</span> <span class="mi">231</span><span class="p">,</span> <span class="mi">231</span><span class="p">,</span> <span class="mi">213</span><span class="p">]</span>
</pre></div>



<p>Construction of the s-adic word from the substitutions and the directive sequence:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">repeat</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">D</span> <span class="o">=</span> <span class="n">algo</span><span class="o">.</span><span class="n">substitutions</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">directive_sequence</span> <span class="o">=</span> <span class="n">algo</span><span class="o">.</span><span class="n">coding_iterator</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="n">e</span><span class="p">,</span><span class="n">pi</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">words</span><span class="o">.</span><span class="n">s_adic</span><span class="p">(</span><span class="n">directive_sequence</span><span class="p">,</span> <span class="n">repeat</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">D</span><span class="p">)</span>
<span class="n">word</span><span class="p">:</span> <span class="mf">1232323123233231232332312323123232312323.</span><span class="o">..</span>
</pre></div>



<p>Shortcut:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">algo</span><span class="o">.</span><span class="n">s_adic_word</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span><span class="n">e</span><span class="p">,</span><span class="n">pi</span><span class="p">))</span>
<span class="n">word</span><span class="p">:</span> <span class="mf">1232323123233231232332312323123232312323.</span><span class="o">..</span>
</pre></div>



<p>There are some more <a class="reference external" href="https://www.labri.fr/perso/slabbe/docs/0.6.3/mult_cont_frac.html">examples</a> in the documentation.</p>
<p>This code was used in the creation of the <a class="reference external" href="https://arxiv.org/abs/1511.08399">3-dimensional Continued Fraction
Algorithms Cheat Sheets</a> 7 years ago during my postdoc at Université de
Liège, Belgium.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Using Glucose SAT solver to find a tiling of a rectangle by polyominoes]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2021/05/using-glucose-sat-solver-to-find-a-tiling-of-a-rectangle-by-polyominoes" />
    <id>http://www.slabbe.org/blogue/2021/05/using-glucose-sat-solver-to-find-a-tiling-of-a-rectangle-by-polyominoes</id>
    <updated>2022-06-20T09:41:00Z</updated>
    <published>2021-05-27T17:04:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <summary type="html"><![CDATA[Using Glucose SAT solver to find a tiling of a rectangle by polyominoes]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2021/05/using-glucose-sat-solver-to-find-a-tiling-of-a-rectangle-by-polyominoes"><![CDATA[<div class="document">
<p>In his <a class="reference external" href="https://arxiv.org/abs/cs/0011047">Dancing links</a> article, Donald Knuth considered the problem of
packing 45 Y pentaminoes into a 15 x 15 square. We can <a class="reference external" href="https://doc.sagemath.org/html/en/reference/combinat/sage/combinat/tiling.html#donald-knuth-example-the-y-pentamino">redo this computation
in SageMath</a> using some implementation of his dancing links algorithm.</p>
<p>Dancing links takes 1.24 seconds to find a solution:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">sage.combinat.tiling</span> <span class="kn">import</span> <span class="n">Polyomino</span><span class="p">,</span> <span class="n">TilingSolver</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">y</span> <span class="o">=</span> <span class="n">Polyomino</span><span class="p">([(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">),(</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">),(</span><span class="mi">2</span><span class="p">,</span><span class="mi">0</span><span class="p">),(</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">),(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">)])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T</span> <span class="o">=</span> <span class="n">TilingSolver</span><span class="p">([</span><span class="n">y</span><span class="p">],</span> <span class="n">box</span><span class="o">=</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="mi">15</span><span class="p">),</span> <span class="n">reusable</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">reflection</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">solution</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">T</span><span class="o">.</span><span class="n">solve</span><span class="p">())</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mf">1.23</span> <span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">11.9</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">1.24</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">1.24</span> <span class="n">s</span>
</pre></div>



<p>The first solution found is:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="nb">sum</span><span class="p">(</span><span class="n">T</span><span class="o">.</span><span class="n">row_to_polyomino</span><span class="p">(</span><span class="n">row_number</span><span class="p">)</span><span class="o">.</span><span class="n">show2d</span><span class="p">()</span> <span class="k">for</span> <span class="n">row_number</span> <span class="ow">in</span> <span class="n">solution</span><span class="p">)</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2021/y_polymino_15_by_15.png"><img alt="/Files/2021/y_polymino_15_by_15.png" src="/Files/2021/y_polymino_15_by_15.png" style="width: 30em;" /></a>
<p>What is nice about dancing links algorithm is that it can list all solutions to
a problem.  For example, it takes less than 3 minutes to find all solutions of
tiling a 15 x 15 rectangle with the Y polyomino:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">T</span><span class="o">.</span><span class="n">number_of_solutions</span><span class="p">()</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">2</span><span class="nb">min</span> <span class="mi">46</span><span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">3.46</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">2</span><span class="nb">min</span> <span class="mi">46</span><span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">2</span><span class="nb">min</span> <span class="mi">46</span><span class="n">s</span>
<span class="mi">1696</span>
</pre></div>



<p>It takes more time (38s) to find a first solution of a larger 20 x 20 rectangle:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span> <span class="o">=</span> <span class="n">TilingSolver</span><span class="p">([</span><span class="n">y</span><span class="p">],</span> <span class="n">box</span><span class="o">=</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span><span class="mi">20</span><span class="p">),</span> <span class="n">reusable</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">reflection</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">solution</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">T</span><span class="o">.</span><span class="n">solve</span><span class="p">())</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mf">38.2</span> <span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">7.88</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">38.2</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">38.2</span> <span class="n">s</span>
</pre></div>



<p>The polyomino tiling problem is reduced to an instance of the universal cover
problem which is represented by a sparse matrix of 0 and 1:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">dlx</span> <span class="o">=</span> <span class="n">T</span><span class="o">.</span><span class="n">dlx_solver</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">dlx</span>
<span class="n">Dancing</span> <span class="n">links</span> <span class="n">solver</span> <span class="k">for</span> <span class="mi">400</span> <span class="n">columns</span> <span class="ow">and</span> <span class="mi">2584</span> <span class="n">rows</span>
</pre></div>



<p>We observe that finding a solution to this problem takes the same amount of
time. This is normal since it is exactly what is used behind the scene when
calling <tt class="docutils literal"><span class="pre">next(T.solve())</span></tt> above:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">sol</span> <span class="o">=</span> <span class="n">dlx</span><span class="o">.</span><span class="n">one_solution</span><span class="p">(</span><span class="n">ncpus</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mf">38.6</span> <span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">48</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">38.6</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">38.5</span> <span class="n">s</span>
</pre></div>



<p>One way to improve the time it takes it to split the problem into parts and use
many processors to work on each subproblems. Here a random column is used to
split the problem which may affect the time it takes. Sometimes a good column
is chosen and it works great as below, but sometimes it does not:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">sol</span> <span class="o">=</span> <span class="n">dlx</span><span class="o">.</span><span class="n">one_solution</span><span class="p">(</span><span class="n">ncpus</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">941</span> <span class="n">µs</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">32</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">32.9</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">1.41</span> <span class="n">s</span>
</pre></div>



<p>The reduction from dancing links instance to SAT instance <a class="reference external" href="https://trac.sagemath.org/ticket/29338">#29338</a> and to
MILP instance <a class="reference external" href="https://trac.sagemath.org/ticket/29955">#29955</a> was merged into SageMath 9.2 during the last year.  A
discussion with Franco Saliola motivated me to implement these translations
since he was also searching for faster way to solve dancing links problems.
Indeed some problems are solved faster with other kind of solver, so it is good
to make some comparisons between solvers.</p>
<p>Therefore, with a recent enough version of SageMath, we can now try to find a
tiling with other kinds of solvers.  Following my <a class="reference external" href="/blogue/2018/12/comparison-of-wang-tiling-solvers/">experience with tilings by
Wang tiles</a>, I know that <a class="reference external" href="https://www.labri.fr/perso/lsimon/glucose/">Glucose SAT solver</a> is quite efficient to solve
tilings of the plane. This is why I test this one below. Glucose is now an
optional package to SageMath which can be installed with:</p>


<div class="pygments_manni"><pre><span></span>sage -i glucose
</pre></div>



<p>Update (June 20th, 2022): It seems <tt class="docutils literal">sage <span class="pre">-i</span> glucose</tt> no longer works. The new
procedure is to use <tt class="docutils literal">./configure <span class="pre">--enable-glucose</span></tt> when installation is made
from source. See the question <a class="reference external" href="https://ask.sagemath.org/question/62870/unable-to-install-glucose-sat-solver-with-sage/">Unable to install glucose SAT solver with
Sage</a> on ask.sagemath.org for more information.</p>
<p>Glucose finds the solution of a 20 x 20 rectangle in 1.5 seconds:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">sol</span> <span class="o">=</span> <span class="n">dlx</span><span class="o">.</span><span class="n">one_solution_using_sat_solver</span><span class="p">(</span><span class="s1">&#39;glucose&#39;</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">306</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">12.1</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">319</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">1.51</span> <span class="n">s</span>
</pre></div>



<p>The rows of the solution found by Glucose are:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">sol</span>
<span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">38</span><span class="p">,</span> <span class="mi">74</span><span class="p">,</span> <span class="mi">245</span><span class="p">,</span> <span class="mi">270</span><span class="p">,</span> <span class="mi">310</span><span class="p">,</span> <span class="mi">320</span><span class="p">,</span> <span class="mi">327</span><span class="p">,</span> <span class="mi">332</span><span class="p">,</span> <span class="mi">366</span><span class="p">,</span> <span class="mi">419</span><span class="p">,</span> <span class="mi">557</span><span class="p">,</span> <span class="mi">582</span><span class="p">,</span> <span class="mi">613</span><span class="p">,</span> <span class="mi">660</span><span class="p">,</span>
 <span class="mi">665</span><span class="p">,</span> <span class="mi">686</span><span class="p">,</span> <span class="mi">699</span><span class="p">,</span> <span class="mi">707</span><span class="p">,</span> <span class="mi">760</span><span class="p">,</span> <span class="mi">772</span><span class="p">,</span> <span class="mi">774</span><span class="p">,</span> <span class="mi">781</span><span class="p">,</span> <span class="mi">802</span><span class="p">,</span> <span class="mi">814</span><span class="p">,</span> <span class="mi">816</span><span class="p">,</span> <span class="mi">847</span><span class="p">,</span> <span class="mi">855</span><span class="p">,</span> <span class="mi">876</span><span class="p">,</span> <span class="mi">905</span><span class="p">,</span>
 <span class="mi">1025</span><span class="p">,</span> <span class="mi">1070</span><span class="p">,</span> <span class="mi">1081</span><span class="p">,</span> <span class="mi">1092</span><span class="p">,</span> <span class="mi">1148</span><span class="p">,</span> <span class="mi">1165</span><span class="p">,</span> <span class="mi">1249</span><span class="p">,</span> <span class="mi">1273</span><span class="p">,</span> <span class="mi">1283</span><span class="p">,</span> <span class="mi">1299</span><span class="p">,</span> <span class="mi">1354</span><span class="p">,</span> <span class="mi">1516</span><span class="p">,</span> <span class="mi">1549</span><span class="p">,</span>
 <span class="mi">1599</span><span class="p">,</span> <span class="mi">1609</span><span class="p">,</span> <span class="mi">1627</span><span class="p">,</span> <span class="mi">1633</span><span class="p">,</span> <span class="mi">1650</span><span class="p">,</span> <span class="mi">1717</span><span class="p">,</span> <span class="mi">1728</span><span class="p">,</span> <span class="mi">1739</span><span class="p">,</span> <span class="mi">1773</span><span class="p">,</span> <span class="mi">1795</span><span class="p">,</span> <span class="mi">1891</span><span class="p">,</span> <span class="mi">1908</span><span class="p">,</span> <span class="mi">1918</span><span class="p">,</span>
 <span class="mi">1995</span><span class="p">,</span> <span class="mi">2004</span><span class="p">,</span> <span class="mi">2016</span><span class="p">,</span> <span class="mi">2029</span><span class="p">,</span> <span class="mi">2037</span><span class="p">,</span> <span class="mi">2090</span><span class="p">,</span> <span class="mi">2102</span><span class="p">,</span> <span class="mi">2104</span><span class="p">,</span> <span class="mi">2111</span><span class="p">,</span> <span class="mi">2132</span><span class="p">,</span> <span class="mi">2144</span><span class="p">,</span> <span class="mi">2146</span><span class="p">,</span> <span class="mi">2185</span><span class="p">,</span>
 <span class="mi">2235</span><span class="p">,</span> <span class="mi">2301</span><span class="p">,</span> <span class="mi">2460</span><span class="p">,</span> <span class="mi">2472</span><span class="p">,</span> <span class="mi">2498</span><span class="p">,</span> <span class="mi">2538</span><span class="p">,</span> <span class="mi">2548</span><span class="p">,</span> <span class="mi">2573</span><span class="p">,</span> <span class="mi">2583</span><span class="p">]</span>
</pre></div>



<p>Each row correspond to a Y polyomino embedded in the plane in a certain position:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="nb">sum</span><span class="p">(</span><span class="n">T</span><span class="o">.</span><span class="n">row_to_polyomino</span><span class="p">(</span><span class="n">row_number</span><span class="p">)</span><span class="o">.</span><span class="n">show2d</span><span class="p">()</span> <span class="k">for</span> <span class="n">row_number</span> <span class="ow">in</span> <span class="n">sol</span><span class="p">)</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2021/tiling_20_by_20_with_y_polyomino_glucose.png"><img alt="/Files/2021/tiling_20_by_20_with_y_polyomino_glucose.png" src="/Files/2021/tiling_20_by_20_with_y_polyomino_glucose.png" style="width: 30em;" /></a>
<p>Glucose-Syrup (a parallelized version of Glucose) takes about the same time (1
second) to find a tiling of a 20 x 20 rectangle:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span> <span class="o">=</span> <span class="n">TilingSolver</span><span class="p">([</span><span class="n">y</span><span class="p">],</span> <span class="n">box</span><span class="o">=</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">),</span> <span class="n">reusable</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">reflection</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">dlx</span> <span class="o">=</span> <span class="n">T</span><span class="o">.</span><span class="n">dlx_solver</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">dlx</span>
<span class="n">Dancing</span> <span class="n">links</span> <span class="n">solver</span> <span class="k">for</span> <span class="mi">400</span> <span class="n">columns</span> <span class="ow">and</span> <span class="mi">2584</span> <span class="n">rows</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">sol</span> <span class="o">=</span> <span class="n">dlx</span><span class="o">.</span><span class="n">one_solution_using_sat_solver</span><span class="p">(</span><span class="s1">&#39;glucose-syrup&#39;</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">285</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">20</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">305</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">1.09</span> <span class="n">s</span>
</pre></div>



<p>Searching for a tiling of a 30 x 30 rectangle, Glucose takes 40s and
Glucose-Syrup takes 16s while dancing links algorithm takes much longer
(<tt class="docutils literal"><span class="pre">next(T.solve())</span></tt> which is using dancing links algorithm does not halt in
less than 5 minutes):</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span> <span class="o">=</span> <span class="n">TilingSolver</span><span class="p">([</span><span class="n">y</span><span class="p">],</span> <span class="n">box</span><span class="o">=</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="mi">30</span><span class="p">),</span> <span class="n">reusable</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">reflection</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">dlx</span> <span class="o">=</span> <span class="n">T</span><span class="o">.</span><span class="n">dlx_solver</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">dlx</span>
<span class="n">Dancing</span> <span class="n">links</span> <span class="n">solver</span> <span class="k">for</span> <span class="mi">900</span> <span class="n">columns</span> <span class="ow">and</span> <span class="mi">6264</span> <span class="n">rows</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">sol</span> <span class="o">=</span> <span class="n">dlx</span><span class="o">.</span><span class="n">one_solution_using_sat_solver</span><span class="p">(</span><span class="s1">&#39;glucose&#39;</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">708</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">36</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">744</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">40.5</span> <span class="n">s</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">sol</span> <span class="o">=</span> <span class="n">dlx</span><span class="o">.</span><span class="n">one_solution_using_sat_solver</span><span class="p">(</span><span class="s1">&#39;glucose-syrup&#39;</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">754</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">39.1</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">793</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">16.1</span> <span class="n">s</span>
</pre></div>



<p>Searching for a tiling of a 35 x 35 rectangle, Glucose takes 2min 5s and
Glucose-Syrup takes 1min 16s:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span> <span class="o">=</span> <span class="n">TilingSolver</span><span class="p">([</span><span class="n">y</span><span class="p">],</span> <span class="n">box</span><span class="o">=</span><span class="p">(</span><span class="mi">35</span><span class="p">,</span> <span class="mi">35</span><span class="p">),</span> <span class="n">reusable</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">reflection</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">dlx</span> <span class="o">=</span> <span class="n">T</span><span class="o">.</span><span class="n">dlx_solver</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">dlx</span>
<span class="n">Dancing</span> <span class="n">links</span> <span class="n">solver</span> <span class="k">for</span> <span class="mi">1225</span> <span class="n">columns</span> <span class="ow">and</span> <span class="mi">8704</span> <span class="n">rows</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">sol</span> <span class="o">=</span> <span class="n">dlx</span><span class="o">.</span><span class="n">one_solution_using_sat_solver</span><span class="p">(</span><span class="s1">&#39;glucose&#39;</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mf">1.07</span> <span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">47.9</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">1.12</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">2</span><span class="nb">min</span> <span class="mi">5</span><span class="n">s</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">sol</span> <span class="o">=</span> <span class="n">dlx</span><span class="o">.</span><span class="n">one_solution_using_sat_solver</span><span class="p">(</span><span class="s1">&#39;glucose-syrup&#39;</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mf">1.06</span> <span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">24</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">1.09</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">1</span><span class="nb">min</span> <span class="mi">16</span><span class="n">s</span>
</pre></div>



<p>Here are the info of the computer used for the above timings (a 4 years old
laptop runing Ubuntu 20.04):</p>


<div class="pygments_manni"><pre><span></span>$ lscpu
Architecture :                          x86_64
Mode(s) opératoire(s) des processeurs : 32-bit, 64-bit
Boutisme :                              Little Endian
Address size :                          39 bits physical, 48 bits virtual
Processeur(s) :                         8
Liste de processeur(s) en ligne :       0-7
Thread(s) par coeur :                   2
Coeur(s) par socket :                   4
Socket(s) :                             1
Noeud(s) NUMA :                         1
Identifiant constructeur :              GenuineIntel
Famille de processeur :                 6
Modèle :                                158
Nom de modèle :                         Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
Révision :                              9
Vitesse du processeur en MHz :          3549.025
Vitesse maximale du processeur en MHz : 3900,0000
Vitesse minimale du processeur en MHz : 800,0000
BogoMIPS :                              5799.77
Virtualisation :                        VT-x
Cache L1d :                             128 KiB
Cache L1i :                             128 KiB
Cache L2 :                              1 MiB
Cache L3 :                              8 MiB
Noeud NUMA 0 de processeur(s) :         0-7
</pre></div>



<p>To finish, I should mention that the implementation of dancing links made in
SageMath is not the best one. Indeed, according to what Franco Saliola told me,
the dancing links code written by Donald Knuth himself and available on his
website (<a class="reference external" href="https://github.com/saliola/dlx1/">franco added some makefile to compile it more easily</a>) is faster.
It would be interesting to confirm this and if possible improves the
implementation made in SageMath.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Installation de Python, Jupyter et JupyterLab]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2021/02/installation-de-python-jupyter-et-jupyterlab" />
    <id>http://www.slabbe.org/blogue/2021/02/installation-de-python-jupyter-et-jupyterlab</id>
    <updated>2021-02-23T11:15:00Z</updated>
    <published>2021-02-23T11:15:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <summary type="html"><![CDATA[Installation de Python, Jupyter et JupyterLab]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2021/02/installation-de-python-jupyter-et-jupyterlab"><![CDATA[<div class="document">
<p>L'<a class="reference external" href="https://ed-mi.u-bordeaux.fr/">École doctorale de mathématiques et informatique (EDMI)</a> de l'Université de
Bordeaux offre <a class="reference external" href="https://ed-mi.u-bordeaux.fr/content/download/30259/310777/version/2/file/AFFICHE%20formation%20EDMI%202020_2021_MAJ_07012021.pdf">des cours</a> chaque année.  Dans ce cadre, cette année, je
donnerai le cours <em>Calcul et programmation avec Python ou SageMath et
meilleures pratiques</em> qui aura lieu les 25 février, 4 mars, 11 mars, 18 mars
2021 de 9h à 12h.</p>
<p>Le créneau du jeudi matin correspond au créneau des <a class="reference external" href="https://cea.labri.fr/pmwiki.php/Groupe/Sage">Jeudis Sage au LaBRI</a>
où un groupe d'utilisateurs de Python se rencontrent toutes les semaines pour
faire du développement tout en posant des questions aux autres utilisateurs
présents.</p>
<p>Le cours aura lieu sur le logiciel BigBlueButton auquel les participantEs
inscritEs se connecteront par leur navigateur web (<strong>Mozilla Firefox</strong> ou
<strong>Google Chrome</strong>). Selon les <a class="reference external" href="https://docs.bigbluebutton.org/support/faq.html#what-are-the-minimum-requirements-for-the-bigbluebutton-client">exigences minimales du client BigBlueButton</a>,
il faut éviter Safari ou IE, sinon certaines fonctionnalités ne marchent pas.
Vous pouvez vous familiariser avec l'interface BigBlueButton en écoutant ce
<a class="reference external" href="https://www.youtube.com/watch?v=uYYnryIM0Uw">tutoriel BigBlueButton</a> (sur youtube, 5 minutes). Consultez les pages de
support suivantes en cas de <a class="reference external" href="https://docs.bigbluebutton.org/support/faq.html#some-users-are-experiencing-audio-problems">soucis audio</a> ou <a class="reference external" href="https://docs.bigbluebutton.org/support/faq.html#is-wired-connection-better-than-wireless">internet</a>.</p>
<p>Pour la première séance, nous présenterons les bases de Python et les
différentes interfaces. Nous ne pourrons pas passer trop de temps à faire
l'installation des différents logiciels. Il serait donc préférable si les
installations ont déjà été faites avant le cours par chacun des participantEs.
Cela vous permettra de reproduire les commandes montrées et faire des exercices.</p>
<p>Les logiciels à installer avant le cours sont:</p>
<blockquote>
<ul class="simple">
<li>Python3</li>
<li>SageMath (facultatif)</li>
<li>IPython</li>
<li>Jupyter notebook classique</li>
<li>JupyterLab</li>
</ul>
</blockquote>
<p><strong>Python 3</strong>: Normalement, Python est déjà installé sur votre ordinateur. Vous
pouvez le confirmer en tapant <tt class="docutils literal">python</tt> ou <tt class="docutils literal">python3</tt> dans un terminal
(Linux/Mac) ou dans l'invité de commande (Windows). Vous devriez obtenir
quelque chose qui ressemble à ceci:</p>


<div class="pygments_manni"><pre><span></span>Python 3.8.5 (default, Jul 28 2020, 12:59:40)
[GCC 9.3.0] on linux
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&gt;&gt;&gt;
</pre></div>



<p><strong>SageMath</strong> (facultatif): <a class="reference external" href="https://www.sagemath.org/">SageMath</a> est un logiciel libre de mathématiques
basé sur Python et regroupant des centaines de packages et librairies.  Il y a
<a class="reference external" href="https://doc.sagemath.org/html/en/installation/index.html">plusieurs manières d'installer SageMath</a>, et je vous recommande de lire
cette documentation pour déterminer la manière de l'installer qui vous convient
le mieux. Sinon, vous pouvez <a class="reference external" href="https://www.sagemath.org/download.html">télécharger directement les binaires ici</a>.</p>
<p>Vous devriez obtenir quelque chose qui ressemble à ceci:</p>


<div class="pygments_manni"><pre><span></span>┌────────────────────────────────────────────────────────────────────┐
│ SageMath version 9.2, Release Date: 2020-10-24                     │
│ Using Python 3.8.5. Type &quot;help()&quot; for help.                        │
└────────────────────────────────────────────────────────────────────┘
sage:
</pre></div>



<p><strong>IPython</strong>:</p>
<p>Si vous avez déjà installé SageMath, c'est bon, car ipython en fait partie. La
commande <tt class="docutils literal">sage <span class="pre">-ipython</span></tt> vous permettra de l'ouvrir.</p>
<p>Si vous n'avez pas SageMath, vous pouvez l'installer via <tt class="docutils literal">pip install
ipython</tt> ou sinon en suivant <a class="reference external" href="https://ipython.readthedocs.io/en/latest/install/install.html">ces instructions</a> du site ipython. Ensuite, la
commande <tt class="docutils literal">ipython</tt> dans le terminal (Linux, OS X) ou dans l'invité de
commande (Windows) vous permettra de l'ouvrir.</p>
<p>Vous devriez obtenir quelque chose qui ressemble à ceci:</p>


<div class="pygments_manni"><pre><span></span>Python 3.8.5 (default, Jul 28 2020, 12:59:40)
Type &#39;copyright&#39;, &#39;credits&#39; or &#39;license&#39; for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type &#39;?&#39; for help.

In [1]:
</pre></div>



<p><strong>Jupyter</strong>:</p>
<p>Si vous avez déjà installé SageMath, c'est bon, car Jupyter en fait partie. La
commande <tt class="docutils literal">sage <span class="pre">-n</span> jupyter</tt> vous permettra de l'ouvrir.</p>
<p>Si vous n'avez pas SageMath, vous pouvez suivre <a class="reference external" href="https://jupyter.org/install">ces instructions</a> du site
jupyter.org. Ensuite, la commande <tt class="docutils literal">jupyter notebook</tt> dans le terminal (Linux,
OS X) ou dans l'invité de commande (Windows) vous permettra de l'ouvrir.</p>
<p>Vous devriez obtenir quelque chose qui ressemble à ceci dans votre navigateur:</p>
<a class="reference external image-reference" href="/Files/2021/jupyter.png"><img alt="/Files/2021/jupyter.png" src="/Files/2021/jupyter.png" style="width: 30em;" /></a>
<p><strong>JupyterLab</strong>:</p>
<p>Si vous avez déjà installé SageMath, vous pouvez installer JupyterLab en
faisant <tt class="docutils literal">sage <span class="pre">-i</span> jupyterlab</tt> et l'ouvrir en faisant <tt class="docutils literal">sage <span class="pre">-n</span> jupyterlab</tt>.
Sur Windows, c'est un tout petit peut différent, il faut plutôt faire
<tt class="docutils literal">pip install jupyterlab</tt> dans la console SageMath selon cette récente réponse
sur <a class="reference external" href="https://ask.sagemath.org/question/55680/installing-and-running-jupyterlab-for-sagemath-in-windows/">ask.sagemath.org</a>.</p>
<p>Si vous n'avez pas SageMath, vous pouvez suivre <a class="reference external" href="https://jupyter.org/install">les instructions</a> du même
site que ci-haut. Ensuite, la commande <tt class="docutils literal"><span class="pre">jupyter-lab</span></tt> ou <tt class="docutils literal">jupyter lab</tt> dans
le terminal (Linux, OS X) ou dans l'invité de commande (Windows) vous permettra
de l'ouvrir.</p>
<p>Vous devriez obtenir quelque chose qui ressemble à ceci dans votre navigateur:</p>
<a class="reference external image-reference" href="/Files/2021/jupyterlab.png"><img alt="/Files/2021/jupyterlab.png" src="/Files/2021/jupyterlab.png" style="width: 30em;" /></a>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Tiling a polyomino with polyominoes in SageMath]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2020/12/tiling-a-polyomino-with-polyominoes-in-sagemath" />
    <id>http://www.slabbe.org/blogue/2020/12/tiling-a-polyomino-with-polyominoes-in-sagemath</id>
    <updated>2020-12-03T13:48:00Z</updated>
    <published>2020-12-03T13:48:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <summary type="html"><![CDATA[Tiling a polyomino with polyominoes in SageMath]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2020/12/tiling-a-polyomino-with-polyominoes-in-sagemath"><![CDATA[<div class="document">
<p>Suppose that you 3D print many copies of the following 3D hexo-mino at home:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">sage.combinat.tiling</span> <span class="kn">import</span> <span class="n">Polyomino</span><span class="p">,</span> <span class="n">TilingSolver</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">p</span> <span class="o">=</span> <span class="n">Polyomino</span><span class="p">([(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)],</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;blue&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">p</span><span class="o">.</span><span class="n">show3d</span><span class="p">()</span>
<span class="n">Launched</span> <span class="n">html</span> <span class="n">viewer</span> <span class="k">for</span> <span class="n">Graphics3d</span> <span class="n">Object</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2020/polyomino.png"><img alt="/Files/2020/polyomino.png" src="/Files/2020/polyomino.png" style="width: 20em;" /></a>
<p>You would like to know if you can tile a larger polyomino or in particular a
rectangular box with many copies of it. The <a class="reference external" href="https://doc.sagemath.org/html/en/reference/combinat/sage/combinat/tiling.html">TilingSolver</a> module in SageMath
is made for that. See also <a class="reference external" href="https://ask.sagemath.org/question/54513/drawing-polyominoes/">this recent question on ask.sagemath.org</a>.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span> <span class="o">=</span> <span class="n">TilingSolver</span><span class="p">([</span><span class="n">p</span><span class="p">],</span> <span class="p">(</span><span class="mi">7</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span> <span class="n">rotation</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">reflection</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">reusable</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T</span>
<span class="n">Tiling</span> <span class="n">solver</span> <span class="n">of</span> <span class="mi">1</span> <span class="n">pieces</span> <span class="n">into</span> <span class="n">a</span> <span class="n">box</span> <span class="n">of</span> <span class="n">size</span> <span class="mi">24</span>
<span class="n">Rotation</span> <span class="n">allowed</span><span class="p">:</span> <span class="kc">True</span>
<span class="n">Reflection</span> <span class="n">allowed</span><span class="p">:</span> <span class="kc">False</span>
<span class="n">Reusing</span> <span class="n">pieces</span> <span class="n">allowed</span><span class="p">:</span> <span class="kc">True</span>
</pre></div>



<p>There is no solution when tiling a box of shape 7x5x3 with this polyomino:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span><span class="o">.</span><span class="n">number_of_solutions</span><span class="p">()</span>
<span class="mi">0</span>
</pre></div>



<p>But there are 4 solutions when tiling a box of shape 4x3x2 with this polyomino:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">T</span> <span class="o">=</span> <span class="n">TilingSolver</span><span class="p">([</span><span class="n">p</span><span class="p">],</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span> <span class="n">rotation</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">reflection</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">reusable</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T</span><span class="o">.</span><span class="n">number_of_solutions</span><span class="p">()</span>
<span class="mi">4</span>
</pre></div>



<p>We construct the list of solutions:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">solutions</span> <span class="o">=</span> <span class="p">[</span><span class="n">sol</span> <span class="k">for</span> <span class="n">sol</span> <span class="ow">in</span> <span class="n">T</span><span class="o">.</span><span class="n">solve</span><span class="p">()]</span>
</pre></div>



<p>Each solution contains the isometric copies of the polyominoes tiling the box:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">solutions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="p">[</span><span class="n">Polyomino</span><span class="p">:</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> <span class="n">Color</span><span class="p">:</span> <span class="c1">#ff0000,</span>
 <span class="n">Polyomino</span><span class="p">:</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)],</span> <span class="n">Color</span><span class="p">:</span> <span class="c1">#ff0000,</span>
 <span class="n">Polyomino</span><span class="p">:</span> <span class="p">[(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> <span class="n">Color</span><span class="p">:</span> <span class="c1">#ff0000,</span>
 <span class="n">Polyomino</span><span class="p">:</span> <span class="p">[(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)],</span> <span class="n">Color</span><span class="p">:</span> <span class="c1">#ff0000]</span>
</pre></div>



<p>It may be easier to visualize the solutions, so we define the following
function allowing to draw the solutions with different colors for each piece:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="k">def</span> <span class="nf">draw_solution</span><span class="p">(</span><span class="n">solution</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mf">0.9</span><span class="p">):</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">colors</span> <span class="o">=</span> <span class="n">rainbow</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">solution</span><span class="p">))</span>
<span class="o">....</span><span class="p">:</span>     <span class="k">for</span> <span class="n">piece</span><span class="p">,</span><span class="n">col</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">solution</span><span class="p">,</span> <span class="n">colors</span><span class="p">):</span>
<span class="o">....</span><span class="p">:</span>         <span class="n">piece</span><span class="o">.</span><span class="n">color</span><span class="p">(</span><span class="n">col</span><span class="p">)</span>
<span class="o">....</span><span class="p">:</span>     <span class="k">return</span> <span class="nb">sum</span><span class="p">((</span><span class="n">piece</span><span class="o">.</span><span class="n">show3d</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="n">size</span><span class="p">)</span> <span class="k">for</span> <span class="n">piece</span> <span class="ow">in</span> <span class="n">solution</span><span class="p">),</span> <span class="n">Graphics</span><span class="p">())</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">G</span> <span class="o">=</span> <span class="p">[</span><span class="n">draw_solution</span><span class="p">(</span><span class="n">sol</span><span class="p">)</span> <span class="k">for</span> <span class="n">sol</span> <span class="ow">in</span> <span class="n">solutions</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span>
<span class="p">[</span><span class="n">Graphics3d</span> <span class="n">Object</span><span class="p">,</span> <span class="n">Graphics3d</span> <span class="n">Object</span><span class="p">,</span> <span class="n">Graphics3d</span> <span class="n">Object</span><span class="p">,</span> <span class="n">Graphics3d</span> <span class="n">Object</span><span class="p">]</span>
</pre></div>





<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>   <span class="c1"># in Sage, this will open a 3d viewer automatically</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2020/solution0.png"><img alt="/Files/2020/solution0.png" src="/Files/2020/solution0.png" style="width: 20em;" /></a>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2020/solution1.png"><img alt="/Files/2020/solution1.png" src="/Files/2020/solution1.png" style="width: 20em;" /></a>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2020/solution2.png"><img alt="/Files/2020/solution2.png" src="/Files/2020/solution2.png" style="width: 20em;" /></a>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2020/solution3.png"><img alt="/Files/2020/solution3.png" src="/Files/2020/solution3.png" style="width: 20em;" /></a>
<p>We may save the solutions to a file:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s1">&#39;solution0.png&#39;</span><span class="p">,</span> <span class="n">aspect_ratio</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">zoom</span><span class="o">=</span><span class="mf">1.2</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s1">&#39;solution1.png&#39;</span><span class="p">,</span> <span class="n">aspect_ratio</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">zoom</span><span class="o">=</span><span class="mf">1.2</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s1">&#39;solution2.png&#39;</span><span class="p">,</span> <span class="n">aspect_ratio</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">zoom</span><span class="o">=</span><span class="mf">1.2</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s1">&#39;solution3.png&#39;</span><span class="p">,</span> <span class="n">aspect_ratio</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">zoom</span><span class="o">=</span><span class="mf">1.2</span><span class="p">)</span>
</pre></div>



<p>Question: are all of the 4 solutions isometric to each other?</p>
<p>The tiling problem is solved due to a reduction to the <a class="reference external" href="https://en.wikipedia.org/wiki/Exact_cover">exact cover problem</a>
for which <a class="reference external" href="https://arxiv.org/abs/cs/0011047">dancing links Knuth's algorithm</a> provides all the solutions. One
can see the rows of the dancing links matrix as follows:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">d</span> <span class="o">=</span> <span class="n">T</span><span class="o">.</span><span class="n">dlx_solver</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">d</span>
<span class="n">Dancing</span> <span class="n">links</span> <span class="n">solver</span> <span class="k">for</span> <span class="mi">24</span> <span class="n">columns</span> <span class="ow">and</span> <span class="mi">56</span> <span class="n">rows</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">d</span><span class="o">.</span><span class="n">rows</span><span class="p">()</span>
<span class="p">[[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">11</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">17</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">12</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">23</span><span class="p">],</span>
 <span class="o">...</span>
 <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">16</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">21</span><span class="p">,</span> <span class="mi">22</span><span class="p">,</span> <span class="mi">23</span><span class="p">]]</span>
</pre></div>



<p>The solutions to the dlx solver can be obtained as follows:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">it</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">solutions_iterator</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
<span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">36</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">52</span><span class="p">]</span>
</pre></div>



<p>These are the indices of the rows each corresponding to an isometric copy of
the polyomino within the box.</p>
<p>Since <a class="reference external" href="https://www.sagemath.org/changelogs/sage-9.2.txt">SageMath-9.2</a>, the possibility to reduce the problem to a MILP problem or a SAT
instance was added to SageMath (see #29338 and #29955):</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">d</span><span class="o">.</span><span class="n">to_milp</span><span class="p">()</span>
<span class="p">(</span><span class="n">Boolean</span> <span class="n">Program</span> <span class="p">(</span><span class="n">no</span> <span class="n">objective</span><span class="p">,</span> <span class="mi">56</span> <span class="n">variables</span><span class="p">,</span> <span class="mi">24</span> <span class="n">constraints</span><span class="p">),</span>
 <span class="n">MIPVariable</span> <span class="n">of</span> <span class="n">dimension</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">d</span><span class="o">.</span><span class="n">to_sat_solver</span><span class="p">()</span>
<span class="n">CryptoMiniSat</span> <span class="n">solver</span><span class="p">:</span> <span class="mi">56</span> <span class="n">variables</span><span class="p">,</span> <span class="mi">2348</span> <span class="n">clauses</span><span class="o">.</span>
</pre></div>



</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Computer experiments for the Lyapunov exponent for MCF algorithms when dimension is larger than 3]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2020/03/computer-experiments-for-the-lyapunov-exponent-for-mcf-algorithms-when-dimension-is-larger-than-3" />
    <id>http://www.slabbe.org/blogue/2020/03/computer-experiments-for-the-lyapunov-exponent-for-mcf-algorithms-when-dimension-is-larger-than-3</id>
    <updated>2020-03-27T13:00:00Z</updated>
    <published>2020-03-27T13:00:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="slabbe spkg" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <summary type="html"><![CDATA[Computer experiments for the Lyapunov exponent for MCF algorithms when dimension is larger than 3]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2020/03/computer-experiments-for-the-lyapunov-exponent-for-mcf-algorithms-when-dimension-is-larger-than-3"><![CDATA[<div class="document">
<p>In November 2015, I wanted to share intuitions I developped on the behavior of
various distinct Multidimensional Continued Fractions algorithms obtained from
various kind of experiments performed with them often involving combinatorics
and digitial geometry but also including the computation of their first two
Lyapunov exponents.</p>
<p>As continued fractions are deeply related to the combinatorics of Sturmian
sequences which can be seen as the digitalization of a straight line in the
grid \(\mathbb{Z}^2\), the multidimensional continued fractions algorithm
are related to the digitalization of a straight line and hyperplanes in
\(\mathbb{Z}^d\).</p>
<p>This is why I shared those experiments in what I called <a class="reference external" href="http://arxiv.org/abs/1511.08399">3-dimensional
Continued Fraction Algorithms Cheat Sheets</a> because of its format inspired
from typical cheat sheets found on the web.  All of the experiments can be
reproduced using the optional SageMath package <a class="reference external" href="https://pypi.org/project/slabbe/">slabbe</a> where I share my
research code. People asked me whether I was going to try to publish those
Cheat Sheets, but I was afraid the format would change the organization of the
information and data in each page, so, in the end, I never submitted those
Cheat Sheets anywhere.</p>
<p>Here I should say that \(d\) stands for the dimension of the vector space on
which the involved matrices act and \(d-1\) is the dimension of the
projective space on which the algorithm acts.</p>
<p>One of the consequence of the Cheat Sheets is that it made us realize that
the algorithm proposed by Julien Cassaigne had the same first two Lyapunov
exponents as the Selmer algorithm (first 3 significant digits were the same).
Julien then discovered the explanation as its algorithm is conjugated to some
semi-sorted version of the Selmer algorihm. This result was <a class="reference external" href="https://doi.org/10.1007/978-3-319-66396-8_14">shared</a> during
WORDS 2017 conference. Julien Leroy, Julien Cassaigne and I are still working
on the extended version of the paper. It is taking longer mainly because of my
fault because I have been working hard on aperiodic Wang tilings in the
previous 2 years.</p>
<p>During July 2019, Wolfgang, Valérie and Jörg asked me to perform computations
of the first two Lyapunov exponents for \(d\)-dimensional Multidimensional
Continued Fraction algorithms for \(d\) larger than 3. The main question of
interest is whether the second Lyapunov exponent keeps being negative as the
dimension increases. This property is related to the notion of strong
convergence almost everywhere of the simultaneous diopantine approximations
provided by the algorithm of a fixed vector of real numbers. It did not take me
too long to update my package since I had started to generalize my code to
larger dimensions during Fall 2017. It turns out that, as the dimension
increases, all known MCF algorithms have their second Lyapunov exponent become
positive. My computations were thus confirming what they eventually published
in their <a class="reference external" href="https://arxiv.org/abs/1910.09386">preprint</a> in November 2019.</p>
<p>My motivation for sharing the results is the conference
<a class="reference external" href="https://www.lorentzcenter.nl/multidimensional-continued-fractions-and-euclidean-dynamics.html">Multidimensional Continued Fractions and Euclidean Dynamics</a>
held this week (supposed to be held in Lorentz Center, March 23-27 2020, it got
cancelled because of the corona virus) where some discussions during video
meetings are related to this subject.</p>
<p>The computations performed below can be summarized in one graphics showing the
values of \(1-\theta_2/\theta_1\) with respect to \(d\) for various
\(d\)-dimensional MCF algorithms. It seems that \(\theta_2\) is negative
up to dimension 10 for Brun, up to dimension 4 for Selmer and up to dimension 5
for ARP.</p>
<a class="reference external image-reference" href="/Files/2020/lyapunov_exponent_comparison.png"><img alt="/Files/2020/lyapunov_exponent_comparison.png" src="/Files/2020/lyapunov_exponent_comparison.png" style="width: 40em;" /></a>
<p>I have to say that I was disapointed by the results because the algorithm
Arnoux-Rauzy-Poincaré (ARP) that Valérie and I <a class="reference external" href="http://dx.doi.org/10.1016/j.aam.2014.11.001">introduced</a> was not performing so
well as its second Lyapunov exponent seems to become positive for dimension
\(d\geq 6\). I had good expectations for ARP because it reaches the highest
value for \(1-\theta_2/\theta_1\) in the computations performed in the Cheat
Sheets, thus better than Brun, better than Selmer when \(d=3\).</p>
<p>The algorithm for the computation of the first two Lyapunov exponents was
provided to me by Vincent Delecroix. It applies the algorithm
\((v,w)\mapsto(M^{-1}v,M^T w)\) millions of times.  The evolution of the
size of the vector \(v\) gives the first Lyapunov exponent.  The evolution
of the size of the vector \(w\) gives the second Lyapunov exponent.  Since
the computation is performed on 64-bits <tt class="docutils literal">double</tt> floating point number, their
are numerical issues to deal with. This is why some Gramm Shimdts operation is
performed on the vector \(w\) at each time the vectors are renormalized to
keep the vector \(w\) orthogonal to \(v\).  Otherwise, the numerical errors
cumulate and the computed value for the \(\theta_2\) becomes the same as
\(\theta_1\). You can look at the algorithm online starting at <a class="reference external" href="https://github.com/seblabbe/slabbe/blob/develop/slabbe/mult_cont_frac_pyx.pyx#L1723">line 1723</a>
of the file <tt class="docutils literal">mult_cont_frac_pyx.pyx</tt> from my optional package.</p>
<p>I do not know from where Vincent took that algorithm. So, I do not know how
exact it is and whether there exits any proof of lower bounds and upper bounds on
the computations being performed. What I can say is that it is quite reliable in
the sense that is returns the same values over and over again (by that I mean
<cite>3 common most significant digits</cite>) with any fixed inputs (number of
iterations).</p>
<p>Below, I show the code illustrating how to reproduce the results.</p>
<p>The version <cite>0.6</cite> (November 2019) of my package <tt class="docutils literal">slabbe</tt> includes the
necessary code to deal with some \(d\)-dimensional Multidimensional Continued
Fraction (MCF) algorithms. Its <a class="reference external" href="https://www.labri.fr/perso/slabbe/docs/">documentation</a> is available online. It is a PIP
package, so it can be installed like this:</p>


<div class="pygments_manni"><pre><span></span>sage -pip install slabbe
</pre></div>



<p>Recall that the dimension \(d\) below is the linear one and \(d-1\) is the
dimension of the space for the corresponding projective algorithm.</p>
<p>Import the Brun, Selmer and Arnoux-Rauzy-Poincaré MCF algorithms from the optional package:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.mult_cont_frac</span> <span class="kn">import</span> <span class="n">Brun</span><span class="p">,</span> <span class="n">Selmer</span><span class="p">,</span> <span class="n">ARP</span>
</pre></div>



<p>The computation of the first two Lyapunov exponents performed on one single orbit:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">Brun</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">lyapunov_exponents</span><span class="p">(</span><span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">)</span>
<span class="p">(</span><span class="mf">0.30473782969922547</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.11220958022368056</span><span class="p">,</span> <span class="mf">1.3682167728713919</span><span class="p">)</span>
</pre></div>



<p>The starting point is taken randomly, but the results of the form of a 3-tuple
\((\theta_1,\theta_2,1-\theta_2/\theta_1)\) are about the same:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">Brun</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">lyapunov_exponents</span><span class="p">(</span><span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">)</span>
<span class="p">(</span><span class="mf">0.30345018206132324</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.11171509867725296</span><span class="p">,</span> <span class="mf">1.3681497170915415</span><span class="p">)</span>
</pre></div>



<p>Increasing the dimension \(d\) yields:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">Brun</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span><span class="o">.</span><span class="n">lyapunov_exponents</span><span class="p">(</span><span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">)</span>
<span class="p">(</span><span class="mf">0.32639514522732005</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.07191456560115839</span><span class="p">,</span> <span class="mf">1.2203297648654456</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">Brun</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">lyapunov_exponents</span><span class="p">(</span><span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">)</span>
<span class="p">(</span><span class="mf">0.30918877340506756</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.0463930802132972</span><span class="p">,</span> <span class="mf">1.1500477514185734</span><span class="p">)</span>
</pre></div>



<p>It performs an orbit of length \(10^7\) in about .5 seconds, of length
\(10^8\) in about 5 seconds and of length \(10^9\) in about 50 seconds:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">Brun</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">lyapunov_exponents</span><span class="p">(</span><span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">540</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">540</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">539</span> <span class="n">ms</span>
<span class="p">(</span><span class="mf">0.30488799356325225</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.11234354880132114</span><span class="p">,</span> <span class="mf">1.3684748208296182</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">Brun</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">lyapunov_exponents</span><span class="p">(</span><span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">8</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mf">5.09</span> <span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">5.09</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">5.08</span> <span class="n">s</span>
<span class="p">(</span><span class="mf">0.30455473631148755</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.11217550411862384</span><span class="p">,</span> <span class="mf">1.3683262505689446</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">Brun</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span><span class="o">.</span><span class="n">lyapunov_exponents</span><span class="p">(</span><span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">9</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mf">51.2</span> <span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">51.2</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">51.2</span> <span class="n">s</span>
<span class="p">(</span><span class="mf">0.30438755982577026</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.11211562816821799</span><span class="p">,</span> <span class="mf">1.368331834035505</span><span class="p">)</span>
</pre></div>



<p>Here, in what follows, I must admit that I needed to do a small fix to my
package, so the code below will not work in version <cite>0.6</cite> of my package, I will
update my package in the next days in order that the computations below can be
reproduced:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.lyapunov</span> <span class="kn">import</span> <span class="n">lyapunov_comparison_table</span>
</pre></div>



<p>For each \(3\leq d\leq 20\), I compute 30 orbits and I show the most
significant digits and the standard deviation of the 30 values computed.</p>
<p>For Brun algorithm:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">algos</span> <span class="o">=</span> <span class="p">[</span><span class="n">Brun</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">21</span><span class="p">)]</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">lyapunov_comparison_table</span><span class="p">(</span><span class="n">algos</span><span class="p">,</span> <span class="n">n_orbits</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">,</span> <span class="n">ncpus</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">190</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">2.8</span> <span class="n">s</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">2.99</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">6</span><span class="nb">min</span> <span class="mi">31</span><span class="n">s</span>
  <span class="n">Algorithm</span>     \<span class="c1">#Orbits   $\theta_1$ (std)     $\theta_2$ (std)      $1-\theta_2/\theta_1$ (std)</span>
<span class="o">+-------------+----------+--------------------+---------------------+-----------------------------+</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.3045</span> <span class="p">(</span><span class="mf">0.00040</span><span class="p">)</span>     <span class="o">-</span><span class="mf">0.1122</span> <span class="p">(</span><span class="mf">0.00017</span><span class="p">)</span>     <span class="mf">1.3683</span> <span class="p">(</span><span class="mf">0.00022</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.32632</span> <span class="p">(</span><span class="mf">0.000055</span><span class="p">)</span>   <span class="o">-</span><span class="mf">0.07188</span> <span class="p">(</span><span class="mf">0.000051</span><span class="p">)</span>   <span class="mf">1.2203</span> <span class="p">(</span><span class="mf">0.00014</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.30919</span> <span class="p">(</span><span class="mf">0.000032</span><span class="p">)</span>   <span class="o">-</span><span class="mf">0.04647</span> <span class="p">(</span><span class="mf">0.000041</span><span class="p">)</span>   <span class="mf">1.1503</span> <span class="p">(</span><span class="mf">0.00013</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">6</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.28626</span> <span class="p">(</span><span class="mf">0.000027</span><span class="p">)</span>   <span class="o">-</span><span class="mf">0.03043</span> <span class="p">(</span><span class="mf">0.000035</span><span class="p">)</span>   <span class="mf">1.1063</span> <span class="p">(</span><span class="mf">0.00012</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">7</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.26441</span> <span class="p">(</span><span class="mf">0.000024</span><span class="p">)</span>   <span class="o">-</span><span class="mf">0.01966</span> <span class="p">(</span><span class="mf">0.000027</span><span class="p">)</span>   <span class="mf">1.0743</span> <span class="p">(</span><span class="mf">0.00010</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.24504</span> <span class="p">(</span><span class="mf">0.000027</span><span class="p">)</span>   <span class="o">-</span><span class="mf">0.01207</span> <span class="p">(</span><span class="mf">0.000024</span><span class="p">)</span>   <span class="mf">1.04926</span> <span class="p">(</span><span class="mf">0.000096</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">9</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.22824</span> <span class="p">(</span><span class="mf">0.000021</span><span class="p">)</span>   <span class="o">-</span><span class="mf">0.00649</span> <span class="p">(</span><span class="mf">0.000026</span><span class="p">)</span>   <span class="mf">1.0284</span> <span class="p">(</span><span class="mf">0.00012</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.2138</span> <span class="p">(</span><span class="mf">0.00098</span><span class="p">)</span>     <span class="o">-</span><span class="mf">0.0022</span> <span class="p">(</span><span class="mf">0.00015</span><span class="p">)</span>     <span class="mf">1.0104</span> <span class="p">(</span><span class="mf">0.00074</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">11</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.20085</span> <span class="p">(</span><span class="mf">0.000015</span><span class="p">)</span>   <span class="mf">0.00106</span> <span class="p">(</span><span class="mf">0.000022</span><span class="p">)</span>    <span class="mf">0.9947</span> <span class="p">(</span><span class="mf">0.00011</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">12</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.18962</span> <span class="p">(</span><span class="mf">0.000017</span><span class="p">)</span>   <span class="mf">0.00368</span> <span class="p">(</span><span class="mf">0.000021</span><span class="p">)</span>    <span class="mf">0.9806</span> <span class="p">(</span><span class="mf">0.00011</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">13</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.17967</span> <span class="p">(</span><span class="mf">0.000011</span><span class="p">)</span>   <span class="mf">0.00580</span> <span class="p">(</span><span class="mf">0.000020</span><span class="p">)</span>    <span class="mf">0.9677</span> <span class="p">(</span><span class="mf">0.00011</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">14</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.17077</span> <span class="p">(</span><span class="mf">0.000011</span><span class="p">)</span>   <span class="mf">0.00755</span> <span class="p">(</span><span class="mf">0.000021</span><span class="p">)</span>    <span class="mf">0.9558</span> <span class="p">(</span><span class="mf">0.00012</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">15</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.16278</span> <span class="p">(</span><span class="mf">0.000012</span><span class="p">)</span>   <span class="mf">0.00900</span> <span class="p">(</span><span class="mf">0.000017</span><span class="p">)</span>    <span class="mf">0.9447</span> <span class="p">(</span><span class="mf">0.00010</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.15556</span> <span class="p">(</span><span class="mf">0.000011</span><span class="p">)</span>   <span class="mf">0.01022</span> <span class="p">(</span><span class="mf">0.000013</span><span class="p">)</span>    <span class="mf">0.93433</span> <span class="p">(</span><span class="mf">0.000086</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">17</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.149002</span> <span class="p">(</span><span class="mf">9.5e-6</span><span class="p">)</span>    <span class="mf">0.01124</span> <span class="p">(</span><span class="mf">0.000015</span><span class="p">)</span>    <span class="mf">0.9246</span> <span class="p">(</span><span class="mf">0.00010</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">18</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.14303</span> <span class="p">(</span><span class="mf">0.000010</span><span class="p">)</span>   <span class="mf">0.01211</span> <span class="p">(</span><span class="mf">0.000019</span><span class="p">)</span>    <span class="mf">0.9153</span> <span class="p">(</span><span class="mf">0.00014</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">19</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.13755</span> <span class="p">(</span><span class="mf">0.000012</span><span class="p">)</span>   <span class="mf">0.01285</span> <span class="p">(</span><span class="mf">0.000018</span><span class="p">)</span>    <span class="mf">0.9065</span> <span class="p">(</span><span class="mf">0.00013</span><span class="p">)</span>
  <span class="n">Brun</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.13251</span> <span class="p">(</span><span class="mf">0.000011</span><span class="p">)</span>   <span class="mf">0.01349</span> <span class="p">(</span><span class="mf">0.000019</span><span class="p">)</span>    <span class="mf">0.8982</span> <span class="p">(</span><span class="mf">0.00014</span><span class="p">)</span>
</pre></div>



<p>For Selmer algorithm:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">algos</span> <span class="o">=</span> <span class="p">[</span><span class="n">Selmer</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">21</span><span class="p">)]</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">lyapunov_comparison_table</span><span class="p">(</span><span class="n">algos</span><span class="p">,</span> <span class="n">n_orbits</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">,</span> <span class="n">ncpus</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">203</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">2.78</span> <span class="n">s</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">2.98</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">6</span><span class="nb">min</span> <span class="mi">27</span><span class="n">s</span>
  <span class="n">Algorithm</span>       \<span class="c1">#Orbits   $\theta_1$ (std)     $\theta_2$ (std)      $1-\theta_2/\theta_1$ (std)</span>
<span class="o">+---------------+----------+--------------------+---------------------+-----------------------------+</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.1827</span> <span class="p">(</span><span class="mf">0.00041</span><span class="p">)</span>     <span class="o">-</span><span class="mf">0.0707</span> <span class="p">(</span><span class="mf">0.00017</span><span class="p">)</span>     <span class="mf">1.3871</span> <span class="p">(</span><span class="mf">0.00029</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.15808</span> <span class="p">(</span><span class="mf">0.000058</span><span class="p">)</span>   <span class="o">-</span><span class="mf">0.02282</span> <span class="p">(</span><span class="mf">0.000036</span><span class="p">)</span>   <span class="mf">1.1444</span> <span class="p">(</span><span class="mf">0.00023</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.13199</span> <span class="p">(</span><span class="mf">0.000033</span><span class="p">)</span>   <span class="mf">0.00176</span> <span class="p">(</span><span class="mf">0.000034</span><span class="p">)</span>    <span class="mf">0.9866</span> <span class="p">(</span><span class="mf">0.00026</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">6</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.11205</span> <span class="p">(</span><span class="mf">0.000017</span><span class="p">)</span>   <span class="mf">0.01595</span> <span class="p">(</span><span class="mf">0.000036</span><span class="p">)</span>    <span class="mf">0.8577</span> <span class="p">(</span><span class="mf">0.00031</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">7</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.09697</span> <span class="p">(</span><span class="mf">0.000012</span><span class="p">)</span>   <span class="mf">0.02481</span> <span class="p">(</span><span class="mf">0.000030</span><span class="p">)</span>    <span class="mf">0.7442</span> <span class="p">(</span><span class="mf">0.00032</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.085340</span> <span class="p">(</span><span class="mf">8.5e-6</span><span class="p">)</span>    <span class="mf">0.03041</span> <span class="p">(</span><span class="mf">0.000032</span><span class="p">)</span>    <span class="mf">0.6437</span> <span class="p">(</span><span class="mf">0.00036</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">9</span><span class="p">)</span>    <span class="mi">30</span>         <span class="mf">0.076136</span> <span class="p">(</span><span class="mf">5.9e-6</span><span class="p">)</span>    <span class="mf">0.03379</span> <span class="p">(</span><span class="mf">0.000032</span><span class="p">)</span>    <span class="mf">0.5561</span> <span class="p">(</span><span class="mf">0.00041</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.068690</span> <span class="p">(</span><span class="mf">5.5e-6</span><span class="p">)</span>    <span class="mf">0.03565</span> <span class="p">(</span><span class="mf">0.000023</span><span class="p">)</span>    <span class="mf">0.4810</span> <span class="p">(</span><span class="mf">0.00032</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">11</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.062557</span> <span class="p">(</span><span class="mf">4.4e-6</span><span class="p">)</span>    <span class="mf">0.03646</span> <span class="p">(</span><span class="mf">0.000021</span><span class="p">)</span>    <span class="mf">0.4172</span> <span class="p">(</span><span class="mf">0.00031</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">12</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.057417</span> <span class="p">(</span><span class="mf">3.6e-6</span><span class="p">)</span>    <span class="mf">0.03654</span> <span class="p">(</span><span class="mf">0.000017</span><span class="p">)</span>    <span class="mf">0.3636</span> <span class="p">(</span><span class="mf">0.00028</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">13</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.05305</span> <span class="p">(</span><span class="mf">0.000011</span><span class="p">)</span>   <span class="mf">0.03615</span> <span class="p">(</span><span class="mf">0.000018</span><span class="p">)</span>    <span class="mf">0.3186</span> <span class="p">(</span><span class="mf">0.00032</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">14</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.04928</span> <span class="p">(</span><span class="mf">0.000060</span><span class="p">)</span>   <span class="mf">0.03546</span> <span class="p">(</span><span class="mf">0.000051</span><span class="p">)</span>    <span class="mf">0.2804</span> <span class="p">(</span><span class="mf">0.00040</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">15</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.046040</span> <span class="p">(</span><span class="mf">2.0e-6</span><span class="p">)</span>    <span class="mf">0.03462</span> <span class="p">(</span><span class="mf">0.000013</span><span class="p">)</span>    <span class="mf">0.2482</span> <span class="p">(</span><span class="mf">0.00027</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.04318</span> <span class="p">(</span><span class="mf">0.000011</span><span class="p">)</span>   <span class="mf">0.03365</span> <span class="p">(</span><span class="mf">0.000014</span><span class="p">)</span>    <span class="mf">0.2208</span> <span class="p">(</span><span class="mf">0.00028</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">17</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.040658</span> <span class="p">(</span><span class="mf">3.3e-6</span><span class="p">)</span>    <span class="mf">0.03263</span> <span class="p">(</span><span class="mf">0.000013</span><span class="p">)</span>    <span class="mf">0.1974</span> <span class="p">(</span><span class="mf">0.00030</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">18</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.038411</span> <span class="p">(</span><span class="mf">2.7e-6</span><span class="p">)</span>    <span class="mf">0.031596</span> <span class="p">(</span><span class="mf">9.8e-6</span><span class="p">)</span>     <span class="mf">0.1774</span> <span class="p">(</span><span class="mf">0.00022</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">19</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.036399</span> <span class="p">(</span><span class="mf">2.2e-6</span><span class="p">)</span>    <span class="mf">0.030571</span> <span class="p">(</span><span class="mf">8.0e-6</span><span class="p">)</span>     <span class="mf">0.1601</span> <span class="p">(</span><span class="mf">0.00019</span><span class="p">)</span>
  <span class="n">Selmer</span> <span class="p">(</span><span class="n">d</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>   <span class="mi">30</span>         <span class="mf">0.0346</span> <span class="p">(</span><span class="mf">0.00011</span><span class="p">)</span>     <span class="mf">0.02955</span> <span class="p">(</span><span class="mf">0.000093</span><span class="p">)</span>    <span class="mf">0.1452</span> <span class="p">(</span><span class="mf">0.00019</span><span class="p">)</span>
</pre></div>



<p>For Arnoux-Rauzy-Poincaré algorithm:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">algos</span> <span class="o">=</span> <span class="p">[</span><span class="n">ARP</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">21</span><span class="p">)]</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">lyapunov_comparison_table</span><span class="p">(</span><span class="n">algos</span><span class="p">,</span> <span class="n">n_orbits</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">,</span> <span class="n">ncpus</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">226</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">2.76</span> <span class="n">s</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">2.99</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">13</span><span class="nb">min</span> <span class="mi">20</span><span class="n">s</span>
  <span class="n">Algorithm</span>                        \<span class="c1">#Orbits   $\theta_1$ (std)     $\theta_2$ (std)      $1-\theta_2/\theta_1$ (std)</span>
<span class="o">+--------------------------------+----------+--------------------+---------------------+-----------------------------+</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=3)    30         0.4428 (0.00056)     -0.1722 (0.00025)     1.3888 (0.00016)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=4)    30         0.6811 (0.00020)     -0.16480 (0.000085)   1.24198 (0.000093)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=5)    30         0.7982 (0.00012)     -0.0776 (0.00010)     1.0972 (0.00013)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=6)    30         0.83563 (0.000091)   0.0475 (0.00010)      0.9432 (0.00012)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=7)    30         0.8363 (0.00011)     0.1802 (0.00016)      0.7845 (0.00020)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=8)    30         0.8213 (0.00013)     0.3074 (0.00023)      0.6257 (0.00028)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=9)    30         0.8030 (0.00012)     0.4205 (0.00017)      0.4763 (0.00022)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=10)   30         0.7899 (0.00011)     0.5160 (0.00016)      0.3467 (0.00020)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=11)   30         0.7856 (0.00014)     0.5924 (0.00020)      0.2459 (0.00022)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=12)   30         0.7883 (0.00010)     0.6497 (0.00012)      0.1759 (0.00014)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=13)   30         0.7930 (0.00010)     0.6892 (0.00014)      0.1309 (0.00014)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=14)   30         0.7962 (0.00012)     0.7147 (0.00015)      0.10239 (0.000077)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=15)   30         0.7974 (0.00012)     0.7309 (0.00014)      0.08340 (0.000074)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=16)   30         0.7969 (0.00015)     0.7411 (0.00014)      0.07010 (0.000048)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=17)   30         0.7960 (0.00014)     0.7482 (0.00014)      0.06005 (0.000050)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=18)   30         0.7952 (0.00013)     0.7537 (0.00014)      0.05218 (0.000046)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=19)   30         0.7949 (0.00012)     0.7584 (0.00013)      0.04582 (0.000035)</span>
  <span class="n">Arnoux</span><span class="o">-</span><span class="n">Rauzy</span><span class="o">-</span><span class="n">Poincar</span>\<span class="s1">&#39;e (d=20)   30         0.7948 (0.00014)     0.7626 (0.00013)      0.04058 (0.000025)</span>
</pre></div>



<p>The computation of the figure shown above is done with the code below:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">brun_list</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1.3683</span><span class="p">,</span> <span class="mf">1.2203</span><span class="p">,</span> <span class="mf">1.1503</span><span class="p">,</span> <span class="mf">1.1063</span><span class="p">,</span> <span class="mf">1.0743</span><span class="p">,</span> <span class="mf">1.04926</span><span class="p">,</span> <span class="mf">1.0284</span><span class="p">,</span> <span class="mf">1.0104</span><span class="p">,</span> <span class="mf">0.9947</span><span class="p">,</span> <span class="mf">0.9806</span><span class="p">,</span> <span class="mf">0.9677</span><span class="p">,</span> <span class="mf">0.9558</span><span class="p">,</span> <span class="mf">0.9447</span><span class="p">,</span> <span class="mf">0.93433</span><span class="p">,</span> <span class="mf">0.9246</span><span class="p">,</span> <span class="mf">0.9153</span><span class="p">,</span> <span class="mf">0.9065</span><span class="p">,</span> <span class="mf">0.8982</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">selmer_list</span> <span class="o">=</span> <span class="p">[</span> <span class="mf">1.3871</span><span class="p">,</span> <span class="mf">1.1444</span><span class="p">,</span> <span class="mf">0.9866</span><span class="p">,</span> <span class="mf">0.8577</span><span class="p">,</span> <span class="mf">0.7442</span><span class="p">,</span> <span class="mf">0.6437</span><span class="p">,</span> <span class="mf">0.5561</span><span class="p">,</span> <span class="mf">0.4810</span><span class="p">,</span> <span class="mf">0.4172</span><span class="p">,</span> <span class="mf">0.3636</span><span class="p">,</span> <span class="mf">0.3186</span><span class="p">,</span> <span class="mf">0.2804</span><span class="p">,</span> <span class="mf">0.2482</span><span class="p">,</span> <span class="mf">0.2208</span><span class="p">,</span> <span class="mf">0.1974</span><span class="p">,</span> <span class="mf">0.1774</span><span class="p">,</span> <span class="mf">0.1601</span><span class="p">,</span> <span class="mf">0.1452</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">arp_list</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1.3888</span><span class="p">,</span> <span class="mf">1.24198</span><span class="p">,</span> <span class="mf">1.0972</span><span class="p">,</span> <span class="mf">0.9432</span><span class="p">,</span> <span class="mf">0.7845</span><span class="p">,</span> <span class="mf">0.6257</span><span class="p">,</span> <span class="mf">0.4763</span><span class="p">,</span> <span class="mf">0.3467</span><span class="p">,</span> <span class="mf">0.2459</span><span class="p">,</span> <span class="mf">0.1759</span><span class="p">,</span> <span class="mf">0.1309</span><span class="p">,</span> <span class="mf">0.10239</span><span class="p">,</span> <span class="mf">0.08340</span><span class="p">,</span> <span class="mf">0.07010</span><span class="p">,</span> <span class="mf">0.06005</span><span class="p">,</span> <span class="mf">0.05218</span><span class="p">,</span> <span class="mf">0.04582</span><span class="p">,</span> <span class="mf">0.04058</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">brun_points</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">enumerate</span><span class="p">(</span><span class="n">brun_list</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">3</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">selmer_points</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">enumerate</span><span class="p">(</span><span class="n">selmer_list</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">3</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">arp_points</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">enumerate</span><span class="p">(</span><span class="n">arp_list</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">3</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span> <span class="o">=</span> <span class="n">Graphics</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span> <span class="o">+=</span> <span class="n">plot</span><span class="p">(</span><span class="mi">1</span><span class="o">+</span><span class="mi">1</span><span class="o">/</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">1</span><span class="p">),</span> <span class="n">x</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="n">legend_label</span><span class="o">=</span><span class="s1">&#39;Optimal algo:$1+1/(d-1)$&#39;</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="s1">&#39;dashed&#39;</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;blue&#39;</span><span class="p">,</span> <span class="n">thickness</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span> <span class="o">+=</span> <span class="n">line</span><span class="p">([(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">20</span><span class="p">,</span><span class="mi">1</span><span class="p">)],</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;black&#39;</span><span class="p">,</span> <span class="n">legend_label</span><span class="o">=</span><span class="s1">&#39;Strong convergence threshold&#39;</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="s1">&#39;dotted&#39;</span><span class="p">,</span> <span class="n">thickness</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span> <span class="o">+=</span> <span class="n">line</span><span class="p">(</span><span class="n">brun_points</span><span class="p">,</span> <span class="n">legend_label</span><span class="o">=</span><span class="s1">&#39;Brun&#39;</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;cyan&#39;</span><span class="p">,</span> <span class="n">thickness</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span> <span class="o">+=</span> <span class="n">line</span><span class="p">(</span><span class="n">selmer_points</span><span class="p">,</span> <span class="n">legend_label</span><span class="o">=</span><span class="s1">&#39;Selmer&#39;</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;green&#39;</span><span class="p">,</span> <span class="n">thickness</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span> <span class="o">+=</span> <span class="n">line</span><span class="p">(</span><span class="n">arp_points</span><span class="p">,</span> <span class="n">legend_label</span><span class="o">=</span><span class="s1">&#39;ARP&#39;</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;red&#39;</span><span class="p">,</span> <span class="n">thickness</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="o">.</span><span class="n">ymin</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="o">.</span><span class="n">axes_labels</span><span class="p">([</span><span class="s1">&#39;$d$&#39;</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">G</span><span class="o">.</span><span class="n">show</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s1">&#39;Computation of first 2 Lyapunov Exponents: comparison of the value $1-</span><span class="se">\\</span><span class="s1">theta_2/</span><span class="se">\\</span><span class="s1">theta_1$</span><span class="se">\n</span><span class="s1"> for $d$-dimensional MCF algorithms Brun, Selmer and ARP for $3</span><span class="se">\\</span><span class="s1">leq d</span><span class="se">\\</span><span class="s1">leq 20$&#39;</span><span class="p">)</span>
</pre></div>



</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Comment installer et utiliser RISE, une extension du notebook Jupyter pour faire des présentations]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2019/01/comment-installer-et-utiliser-rise-une-extension-du-notebook-jupyter-pour-faire-des-presentations" />
    <id>http://www.slabbe.org/blogue/2019/01/comment-installer-et-utiliser-rise-une-extension-du-notebook-jupyter-pour-faire-des-presentations</id>
    <updated>2019-01-24T10:37:00Z</updated>
    <published>2019-01-24T10:37:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <summary type="html"><![CDATA[Comment installer et utiliser RISE, une extension du notebook Jupyter pour faire des présentations]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2019/01/comment-installer-et-utiliser-rise-une-extension-du-notebook-jupyter-pour-faire-des-presentations"><![CDATA[<div class="document">
<p>La semaine dernière, Jeroen Demeyer a fait une présentation lors de l'<a class="reference external" href="https://pari.math.u-bordeaux.fr/Events/PARI2019/">Atelier
PARI/GP 2019</a> au sujet de <a class="reference external" href="https://pypi.org/project/cypari2/">cypari2</a>.</p>
<p>La présentation de Jeroen consistait en des diapositives HTML où les calculs
sont faits en direct (avec Jupyter) et où on peut les modifier en direct dans
les diapositives. Impressionant! Tout cela grâce au package Python <a class="reference external" href="https://pypi.org/project/rise/">RISE</a>.</p>
<p>Pour installer et utiliser RISE, une extension du Jupyter Notebook pour faire
des présentations éditables, il ne suffit pas de l'installer il faut aussi
recopier les css au bon endroit. Pour l'installer dans Sage, il suffit de
faire:</p>


<div class="pygments_manni"><pre><span></span>sage -pip install rise
sage -sh
jupyter-nbextension install rise --py --sys-prefix
</pre></div>



<p>Après on peut consulter ce <a class="reference external" href="https://youtu.be/sXyFa_r1nxA">démo</a> sur youtube et la <a class="reference external" href="https://rise.readthedocs.io/en/docs_hot_fixes/index.html">documentation de RISE est ici</a>.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Comparison of Wang tiling solvers]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2018/12/comparison-of-wang-tiling-solvers" />
    <id>http://www.slabbe.org/blogue/2018/12/comparison-of-wang-tiling-solvers</id>
    <updated>2018-12-12T15:24:00Z</updated>
    <published>2018-12-12T15:24:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="slabbe spkg" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <summary type="html"><![CDATA[Comparison of Wang tiling solvers]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2018/12/comparison-of-wang-tiling-solvers"><![CDATA[<div class="document">
<p>During the last year, I have written a <a class="reference external" href="https://github.com/seblabbe/slabbe/blob/develop/slabbe/wang_tiles.py">Python module</a> to deal with Wang
tiles containing about 4K lines of code including doctests and documentation.</p>
<p>It can be installed like this:</p>


<div class="pygments_manni"><pre><span></span>sage -pip install slabbe
</pre></div>



<p>It can be used like this:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe</span> <span class="kn">import</span> <span class="n">WangTileSet</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tiles</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span>
<span class="o">....</span><span class="p">:</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T0</span> <span class="o">=</span> <span class="n">WangTileSet</span><span class="p">([</span><span class="nb">tuple</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">t</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">tiles</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T0</span><span class="o">.</span><span class="n">tikz</span><span class="p">(</span><span class="n">ncolumns</span><span class="o">=</span><span class="mi">11</span><span class="p">)</span><span class="o">.</span><span class="n">pdf</span><span class="p">()</span>
</pre></div>



<object data="/Files/2018/T0_tiles.svg" style="width: 40em;" type="image/svg+xml">/Files/2018/T0_tiles.svg</object>
<p>The module on wang tiles contains a class <tt class="docutils literal">WangTileSolver</tt> which contains
three reductions of the Wang tiling problem the first using <a class="reference external" href="http://doc.sagemath.org/html/en/reference/numerical/sage/numerical/mip.html">MILP solvers</a>,
the second using <a class="reference external" href="http://doc.sagemath.org/html/en/reference/sat/index.html">SAT solvers</a> and the third using <a class="reference external" href="http://doc.sagemath.org/html/en/reference/combinat/sage/combinat/matrices/dancing_links.html">Knuth's dancing links</a>.</p>
<p>Here is one example of a tiling found using the dancing links reduction:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">tiling</span> <span class="o">=</span> <span class="n">T0</span><span class="o">.</span><span class="n">solver</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">)</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">solver</span><span class="o">=</span><span class="s1">&#39;dancing_links&#39;</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">36</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">12</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mi">48</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">65.5</span> <span class="n">ms</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tiling</span><span class="o">.</span><span class="n">tikz</span><span class="p">()</span><span class="o">.</span><span class="n">pdf</span><span class="p">()</span>
</pre></div>



<object data="/Files/2018/T0_10x10tiling.svg" style="width: 40em;" type="image/svg+xml">/Files/2018/T0_10x10tiling.svg</object>
<p>All these reductions now allow me to compare the efficiency of various types of
solvers restricted to the Wang tiling type of problems. Here is the list of
solvers that I often use.</p>
<table border="1" class="docutils">
<caption>List of solvers</caption>
<colgroup>
<col width="50%" />
<col width="50%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Solver</th>
<th class="head">Description</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal">'Gurobi'</tt></td>
<td>MILP solver</td>
</tr>
<tr><td><tt class="docutils literal">'GLPK'</tt></td>
<td>MILP solver</td>
</tr>
<tr><td><tt class="docutils literal">'PPL'</tt></td>
<td>MILP solver</td>
</tr>
<tr><td><tt class="docutils literal">'LP'</tt></td>
<td>a SAT solver using a reduction to LP</td>
</tr>
<tr><td><tt class="docutils literal">'cryptominisat'</tt></td>
<td>SAT solver</td>
</tr>
<tr><td><tt class="docutils literal">'picosat'</tt></td>
<td>SAT solver</td>
</tr>
<tr><td><tt class="docutils literal">'glucose'</tt></td>
<td>SAT solver</td>
</tr>
<tr><td><tt class="docutils literal">'dancing_links'</tt></td>
<td>Knuth's algorihm</td>
</tr>
</tbody>
</table>
<p>In this <a class="reference external" href="https://arxiv.org/abs/1808.07768">recent work</a> on the substitutive structure of Jeandel-Rao tilings, I
introduced various Wang tile sets \(T_i\) for \(i\in\{0,1,\dots,12\}\).
In this blog post, we will concentrate on the 11 Wang tile set \(T_0\)
introduced by <a class="reference external" href="https://arxiv.org/abs/1506.06492">Jeandel and Rao</a> as well as \(T_2\) containing 20 tiles and
\(T_3\) containing 24 tiles.</p>
<p><strong>Tiling a n x n square</strong></p>
<p>The most natural question to ask is to find valid Wang tilings of \(n\times
n\) square with given Wang tiles. Below is the time spent by each mentionned
solvers to find a valid tiling of a \(n\times n\) square in less than 10
seconds for each of the three wang tile sets \(T_0\), \(T_2\) and
\(T_3\).</p>
<object data="/Files/2018/T0_square_tilings.svg" style="width: 50em;" type="image/svg+xml">/Files/2018/T0_square_tilings.svg</object>
<object data="/Files/2018/T2_square_tilings.svg" style="width: 50em;" type="image/svg+xml">/Files/2018/T2_square_tilings.svg</object>
<object data="/Files/2018/T3_square_tilings.svg" style="width: 50em;" type="image/svg+xml">/Files/2018/T3_square_tilings.svg</object>
<p>We remark that MILP solvers are slower. Dancing links can solve 20x20 squares
with Jeandel Rao tiles \(T_0\) and SAT solvers are performing very well with
Glucose being the best as it can find a 55x55 tiling with Jeandel-Rao tiles
\(T_0\) in less than 10 seconds.</p>
<p><strong>Finding all dominoes allowing a surrounding of given radius</strong></p>
<p>One thing that is often needed in my research is to enumerate all horizontal
and vertical dominoes that allow a given surrounding radius. This is a
difficult question in general as deciding if a given tile set admits a tiling
of the infinite plane is undecidable. But in some cases, the information we get
from the dominoes admitting a surrounding of radius 1, 2, 3 or 4 is enough to
conclude that the tiling can be desubstituted for instance. This is why we need
to answer this question as fast as possible.</p>
<p>Below is the comparison in the time taken by each solver to compute all
vertical and horizontal dominoes allowing a surrounding of radius 1, 2 and 3
(in less than 1000 seconds for each execution).</p>
<object data="/Files/2018/T0_dominoes_surrounding.svg" style="width: 50em;" type="image/svg+xml">/Files/2018/T0_dominoes_surrounding.svg</object>
<object data="/Files/2018/T2_dominoes_surrounding.svg" style="width: 50em;" type="image/svg+xml">/Files/2018/T2_dominoes_surrounding.svg</object>
<object data="/Files/2018/T3_dominoes_surrounding.svg" style="width: 50em;" type="image/svg+xml">/Files/2018/T3_dominoes_surrounding.svg</object>
<p>What is surprising at first is that the solvers that performed well in the
first \(n\times n\) square experience are not the best in the second
experiment computing valid dominoes. Dancing links and the MILP solver Gurobi
are now the best algorithms to compute all dominoes. They are followed by
picosat and cryptominisat and then glucose.</p>
<p><strong>The source code of the above comparisons</strong></p>
<p>The source code of the above comparison can be found in this <a class="reference external" href="https://nbviewer.jupyter.org/url/www.slabbe.org/Files/2018/Comparison-of-Wang-tile-solvers.ipynb">Jupyter
notebook</a>. Note that it depends on the <a class="reference external" href="https://trac.sagemath.org/ticket/26361">use of Glucose as a Sage optional
package (#26361)</a> and on the most recent development version of <a class="reference external" href="https://pypi.python.org/pypi/slabbe">slabbe</a>
optional Sage Package.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Wooden laser-cut Jeandel-Rao tiles]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2018/09/wooden-laser-cut-jeandel-rao-tiles" />
    <id>http://www.slabbe.org/blogue/2018/09/wooden-laser-cut-jeandel-rao-tiles</id>
    <updated>2018-09-07T09:16:00Z</updated>
    <published>2018-09-07T09:16:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="slabbe spkg" />
    <category scheme="http://www.slabbe.org/blogue" term="math" />
    <category scheme="http://www.slabbe.org/blogue" term="découpe laser" />
    <summary type="html"><![CDATA[Wooden laser-cut Jeandel-Rao tiles]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2018/09/wooden-laser-cut-jeandel-rao-tiles"><![CDATA[<div class="document">
<p>I have been working on Jeandel-Rao tiles <a class="reference external" href="https://arxiv.org/abs/1808.07768">lately</a>.</p>
<a class="reference external image-reference" href="/Files/2018/article2_T0_tiles.svg"><object data="/Files/2018/article2_T0_tiles.svg" style="width: 40em;" type="image/svg+xml">/Files/2018/article2_T0_tiles.svg</object></a>
<p>Before the conference <a class="reference external" href="https://sites.google.com/view/modelsets/home">Model Sets and Aperiodic Order</a> held in Durham UK (Sep
3-7 2018), I thought it would be a good idea to bring some real tiles at the
conference. So I first decided of some conventions to represent the above tiles
as topologically closed disk basically using the representation of integers in
base 1:</p>
<a class="reference external image-reference" href="/Files/2018/T0_shapes.svg"><object data="/Files/2018/T0_shapes.svg" style="width: 40em;" type="image/svg+xml">/Files/2018/T0_shapes.svg</object></a>
<p>With these shapes, I created a 33 x 19 patch. With 3cm on each side, the patch
takes 99cm x 57cm just within the capacity of the laser cut machine (1m x 60
cm):</p>
<a class="reference external image-reference" href="/Files/2018/33x19_A_scale3.svg"><object data="/Files/2018/33x19_A_scale3.svg" style="width: 40em;" type="image/svg+xml">/Files/2018/33x19_A_scale3.svg</object></a>
<p>With the help of David Renault from LaBRI, we went at <a class="reference external" href="https://www.iut.u-bordeaux.fr/cohabit/">Coh&#64;bit</a>, the FabLab
of Bordeaux University and we laser cut two 3mm thick plywood for a total of
1282 Wang tiles. This is the result:</p>
<a class="reference external image-reference" href="/Files/2018/laser_cut_8x8.jpg"><img alt="/Files/2018/laser_cut_8x8.jpg" src="/Files/2018/laser_cut_8x8.jpg" style="width: 30em;" /></a>
<p>One may recreate the 33 x 19 tiling as follows (note that I am using
Cartesian-like coordinates, so the first list <tt class="docutils literal">data[0]</tt> actually is the first
column from bottom to top):</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
<span class="o">....</span><span class="p">:</span>  <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">]]</span>
</pre></div>



<p>The above patch have been chosen among 1000 other randomly generated as the
closest to the asymptotic frequencies of the tiles in Jeandel-Rao tilings (or
at least in the minimal subshift that I describe in the preprint):</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">c</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">flatten</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tile_count</span> <span class="o">=</span> <span class="p">[</span><span class="n">c</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">11</span><span class="p">)]</span>
</pre></div>



<p>The asymptotic frequencies:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">phi</span> <span class="o">=</span> <span class="n">golden_ratio</span><span class="o">.</span><span class="n">n</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">Linv</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">18</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">8</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span>
<span class="o">....</span><span class="p">:</span>      <span class="mi">5</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">12</span><span class="o">/</span><span class="mi">5</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">14</span><span class="o">/</span><span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span>
<span class="o">....</span><span class="p">:</span>      <span class="mi">2</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">8</span><span class="o">*</span><span class="n">phi</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">perfect_proportions</span> <span class="o">=</span> <span class="n">vector</span><span class="p">([</span><span class="mi">1</span><span class="o">/</span><span class="n">a</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">Linv</span><span class="p">])</span>
</pre></div>



<p>Comparison of the number of tiles of each type with the expected frequency:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">header_row</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;tile id&#39;</span><span class="p">,</span> <span class="s1">&#39;Asymptotic frequency&#39;</span><span class="p">,</span> <span class="s1">&#39;Expected nb of copies&#39;</span><span class="p">,</span>
<span class="o">....</span><span class="p">:</span>               <span class="s1">&#39;Nb copies in the 33x19 patch&#39;</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">columns</span> <span class="o">=</span> <span class="p">[</span><span class="nb">range</span><span class="p">(</span><span class="mi">11</span><span class="p">),</span> <span class="n">perfect_proportions</span><span class="p">,</span> <span class="n">vector</span><span class="p">(</span><span class="n">perfect_proportions</span><span class="p">)</span><span class="o">*</span><span class="mi">33</span><span class="o">*</span><span class="mi">19</span><span class="p">,</span> <span class="n">tile_count</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">table</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="n">columns</span><span class="p">,</span> <span class="n">header_row</span><span class="o">=</span><span class="n">header_row</span><span class="p">)</span>
  <span class="n">tile</span> <span class="nb">id</span>   <span class="n">Asymptotic</span> <span class="n">frequency</span>   <span class="n">Expected</span> <span class="n">nb</span> <span class="n">of</span> <span class="n">copies</span>   <span class="n">Nb</span> <span class="n">copies</span> <span class="ow">in</span> <span class="n">the</span> <span class="mi">33</span><span class="n">x19</span> <span class="n">patch</span>
<span class="o">+---------+----------------------+-----------------------+------------------------------+</span>
  <span class="mi">0</span>         <span class="mf">0.108271182329550</span>      <span class="mf">67.8860313206280</span>        <span class="mi">67</span>
  <span class="mi">1</span>         <span class="mf">0.108271182329550</span>      <span class="mf">67.8860313206280</span>        <span class="mi">65</span>
  <span class="mi">2</span>         <span class="mf">0.0255593590340479</span>     <span class="mf">16.0257181143480</span>        <span class="mi">16</span>
  <span class="mi">3</span>         <span class="mf">0.108271182329550</span>      <span class="mf">67.8860313206280</span>        <span class="mi">71</span>
  <span class="mi">4</span>         <span class="mf">0.0669152706817991</span>     <span class="mf">41.9558747174880</span>        <span class="mi">42</span>
  <span class="mi">5</span>         <span class="mf">0.0827118232955023</span>     <span class="mf">51.8603132062800</span>        <span class="mi">51</span>
  <span class="mi">6</span>         <span class="mf">0.108271182329550</span>      <span class="mf">67.8860313206280</span>        <span class="mi">65</span>
  <span class="mi">7</span>         <span class="mf">0.149627093977301</span>      <span class="mf">93.8161879237680</span>        <span class="mi">95</span>
  <span class="mi">8</span>         <span class="mf">0.0669152706817991</span>     <span class="mf">41.9558747174880</span>        <span class="mi">44</span>
  <span class="mi">9</span>         <span class="mf">0.108271182329550</span>      <span class="mf">67.8860313206280</span>        <span class="mi">67</span>
  <span class="mi">10</span>        <span class="mf">0.0669152706817991</span>     <span class="mf">41.9558747174880</span>        <span class="mi">44</span>
</pre></div>



<p>I brought the \(33\times19=641\) tiles at the conference and offered to the
first 7 persons to find a \(7\times 7\) tiling the opportunity to keep the
49 tiles they used. 49 is a good number since the frequency of the lowest tile
(with id 2) is about 2% which allows to have at least one copy of each tile in
a subset of 49 tiles allowing a solution.</p>
<p>A natural question to ask is how many such \(7\times 7\) tilings does there
exist?  With ticket <a class="reference external" href="https://trac.sagemath.org/ticket/25125">#25125</a> that was merged in Sage 8.3 this Spring, it is
possible to enumerate and count solutions in parallel with Knuth dancing links
algorithm. After the installation of the Sage Optional package <a class="reference external" href="https://pypi.python.org/pypi/slabbe/">slabbe</a> (<tt class="docutils literal">sage
<span class="pre">-pip</span> install slabbe</tt>), one may compute that there are 152244 solutions.</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe</span> <span class="kn">import</span> <span class="n">WangTileSet</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">tiles</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span>
<span class="o">....</span><span class="p">:</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T0</span> <span class="o">=</span> <span class="n">WangTileSet</span><span class="p">(</span><span class="n">tiles</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">T0_solver</span> <span class="o">=</span> <span class="n">T0</span><span class="o">.</span><span class="n">solver</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span><span class="mi">7</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">T0_solver</span><span class="o">.</span><span class="n">number_of_solutions</span><span class="p">(</span><span class="n">ncpus</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mi">16</span> <span class="n">ms</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mf">82.3</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">98.3</span> <span class="n">ms</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mi">388</span> <span class="n">ms</span>
<span class="mi">152244</span>
</pre></div>



<p>One may also get the list of all solutions and print one of them:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="o">%</span><span class="n">time</span> <span class="n">L</span> <span class="o">=</span> <span class="n">T0_solver</span><span class="o">.</span><span class="n">all_solutions</span><span class="p">();</span> <span class="nb">print</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">L</span><span class="p">))</span>
<span class="mi">152244</span>
<span class="n">CPU</span> <span class="n">times</span><span class="p">:</span> <span class="n">user</span> <span class="mf">6.46</span> <span class="n">s</span><span class="p">,</span> <span class="n">sys</span><span class="p">:</span> <span class="mi">344</span> <span class="n">ms</span><span class="p">,</span> <span class="n">total</span><span class="p">:</span> <span class="mf">6.8</span> <span class="n">s</span>
<span class="n">Wall</span> <span class="n">time</span><span class="p">:</span> <span class="mf">6.82</span> <span class="n">s</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">L</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">A</span> <span class="n">wang</span> <span class="n">tiling</span> <span class="n">of</span> <span class="n">a</span> <span class="mi">7</span> <span class="n">x</span> <span class="mi">7</span> <span class="n">rectangle</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">L</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">table</span><span class="p">()</span>  <span class="c1"># warning: the output is in Cartesian-like coordinates</span>
<span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span>
 <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">]]</span>
</pre></div>



<p>This is the number of distinct sets of 49 tiles which admits a 7x7 solution:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
<span class="n">sage</span><span class="p">:</span> <span class="k">def</span> <span class="nf">count_tiles</span><span class="p">(</span><span class="n">tiling</span><span class="p">):</span>
<span class="o">....</span><span class="p">:</span>     <span class="n">C</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">flatten</span><span class="p">(</span><span class="n">tiling</span><span class="o">.</span><span class="n">table</span><span class="p">()))</span>
<span class="o">....</span><span class="p">:</span>     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">C</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">11</span><span class="p">))</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">Lfreq</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">count_tiles</span><span class="p">,</span> <span class="n">L</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">Lfreq_count</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span><span class="n">Lfreq</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="nb">len</span><span class="p">(</span><span class="n">Lfreq_count</span><span class="p">)</span>
<span class="mi">83258</span>
</pre></div>



<p>Number of other solutions with the same set of 49 tiles:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">Counter</span><span class="p">(</span><span class="n">Lfreq_count</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
<span class="n">Counter</span><span class="p">({</span><span class="mi">1</span><span class="p">:</span> <span class="mi">49076</span><span class="p">,</span> <span class="mi">2</span><span class="p">:</span> <span class="mi">19849</span><span class="p">,</span> <span class="mi">3</span><span class="p">:</span> <span class="mi">6313</span><span class="p">,</span> <span class="mi">4</span><span class="p">:</span> <span class="mi">3664</span><span class="p">,</span> <span class="mi">6</span><span class="p">:</span> <span class="mi">1410</span><span class="p">,</span> <span class="mi">5</span><span class="p">:</span> <span class="mi">1341</span><span class="p">,</span> <span class="mi">7</span><span class="p">:</span> <span class="mi">705</span><span class="p">,</span> <span class="mi">8</span><span class="p">:</span>
<span class="mi">293</span><span class="p">,</span> <span class="mi">9</span><span class="p">:</span> <span class="mi">159</span><span class="p">,</span> <span class="mi">14</span><span class="p">:</span> <span class="mi">116</span><span class="p">,</span> <span class="mi">10</span><span class="p">:</span> <span class="mi">104</span><span class="p">,</span> <span class="mi">12</span><span class="p">:</span> <span class="mi">97</span><span class="p">,</span> <span class="mi">18</span><span class="p">:</span> <span class="mi">44</span><span class="p">,</span> <span class="mi">11</span><span class="p">:</span> <span class="mi">26</span><span class="p">,</span> <span class="mi">15</span><span class="p">:</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">13</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">17</span><span class="p">:</span> <span class="mi">8</span><span class="p">,</span>
<span class="mi">22</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">32</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">16</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">28</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">19</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">21</span><span class="p">:</span> <span class="mi">1</span><span class="p">})</span>
</pre></div>



<p>How the number of \(k\times k\)-solutions grows for <cite>k</cite> from 0 to 9:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="p">[</span><span class="n">T0</span><span class="o">.</span><span class="n">solver</span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="n">k</span><span class="p">)</span><span class="o">.</span><span class="n">number_of_solutions</span><span class="p">()</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>
<span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">85</span><span class="p">,</span> <span class="mi">444</span><span class="p">,</span> <span class="mi">1723</span><span class="p">,</span> <span class="mi">9172</span><span class="p">,</span> <span class="mi">50638</span><span class="p">,</span> <span class="mi">152244</span><span class="p">,</span> <span class="mi">262019</span><span class="p">,</span> <span class="mi">1641695</span><span class="p">]</span>
</pre></div>



<p>Unfortunately, most of those \(k\times k\)-solutions are not extendable to a
tiling of the whole plane. Indeed the number of \(k\times k\) patches in
the language of the minimal aperiodic subshift that I am able to describe and
which is a proper subset of Jeandel-Rao tilings seems, according to some
heuristic, to be something like:</p>


<div class="pygments_manni"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">49</span><span class="p">,</span> <span class="mi">108</span><span class="p">,</span> <span class="mi">184</span><span class="p">,</span> <span class="mi">268</span><span class="p">,</span> <span class="mi">367</span><span class="p">,</span> <span class="mi">483</span><span class="p">]</span>
</pre></div>



<p>I do not share my (ugly) code for this computation yet, as I will rather share
clean code soon when times come. So among the 152244 about only 483 (0.32%) of
them are prolongable into a uniformly recurrent tiling of the plane.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[A time evolution picture of packages built in parallel by Sage]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2016/12/a-time-evolution-picture-of-packages-built-in-parallel-by-sage" />
    <id>http://www.slabbe.org/blogue/2016/12/a-time-evolution-picture-of-packages-built-in-parallel-by-sage</id>
    <updated>2016-12-16T16:13:00Z</updated>
    <published>2016-12-16T16:13:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <summary type="html"><![CDATA[A time evolution picture of packages built in parallel by Sage]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2016/12/a-time-evolution-picture-of-packages-built-in-parallel-by-sage"><![CDATA[<div class="document">
<p>Compiling sage takes a while and does a lot of stuff. Each time I am wondering
which components takes so much time and which are fast. I wrote a module in my
<a class="reference external" href="https://github.com/seblabbe/slabbe">slabbe</a> version <tt class="docutils literal">0.3b2</tt> package available on <a class="reference external" href="http://pypi.python.org/pypi/slabbe">PyPI</a> to figure this out.</p>
<p>This is after compiling 7.5.beta6 after an upgrade from 7.5.beta4:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.analyze_sage_build</span> <span class="kn">import</span> <span class="n">draw_sage_build</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">draw_sage_build</span><span class="p">()</span><span class="o">.</span><span class="n">pdf</span><span class="p">()</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2016/sage_build.png"><img alt="/Files/2016/sage_build.png" src="/Files/2016/sage_build.png" style="width: 40em;" /></a>
<p>From scratch from a fresh git clone of 7.5.beta6, after running <tt class="docutils literal"><span class="pre">MAKE='make</span>
<span class="pre">-j4'</span> make ptestlong</tt>, I get:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.analyze_sage_build</span> <span class="kn">import</span> <span class="n">draw_sage_build</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">draw_sage_build</span><span class="p">()</span><span class="o">.</span><span class="n">pdf</span><span class="p">()</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2016/sage_build_from_scratch.png"><img alt="/Files/2016/sage_build_from_scratch.png" src="/Files/2016/sage_build_from_scratch.png" style="width: 40em;" /></a>
<p>The picture does not include the start and ptestlong because there was an error
compiling the documentation.</p>
<p>By default, <tt class="docutils literal">draw_sage_build</tt> considers all of the logs files in
<tt class="docutils literal">logs/pkgs</tt> but options are available to consider only log files created in a
given interval of time. See <tt class="docutils literal">draw_sage_build?</tt> for more info.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[unsupported operand parent for *, Matrix over number field, vector over symbolic ring]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2016/02/unsupported-operand-parent-for-matrix-over-number-field-vector-over-symbolic-ring" />
    <id>http://www.slabbe.org/blogue/2016/02/unsupported-operand-parent-for-matrix-over-number-field-vector-over-symbolic-ring</id>
    <updated>2016-02-18T10:17:00Z</updated>
    <published>2016-02-18T10:17:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <summary type="html"><![CDATA[unsupported operand parent for *, Matrix over number field, vector over symbolic ring]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2016/02/unsupported-operand-parent-for-matrix-over-number-field-vector-over-symbolic-ring"><![CDATA[<div class="document">
<p>Yesterday I received this email (in french):</p>


<div class="pygments_manni"><pre><span></span>Salut,
avec Thomas on a une question bête:

K.&lt;x&gt;=NumberField(x*x-x-1)

J&#39;aimerais multiplier une matrice avec des coefficients en x par un vecteur
contenant des variables a et b.  Il dit &quot;unsupported operand parent for *,
Matrix over number field, vector over symbolic ring&quot;

Est ce grave ?
</pre></div>



<p>Here is my answer. Indeed, in Sage, symbolic variables can't multiply with
elements in an Number Field in x:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">x</span> <span class="o">=</span> <span class="n">var</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">K</span><span class="o">.&lt;</span><span class="n">x</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">NumberField</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="o">-</span><span class="n">x</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">a</span> <span class="o">=</span> <span class="n">var</span><span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">a</span><span class="o">*</span><span class="n">x</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">)</span>
<span class="o">...</span>
<span class="ne">TypeError</span><span class="p">:</span> <span class="n">unsupported</span> <span class="n">operand</span> <span class="n">parent</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">for</span> <span class="s1">&#39;*&#39;</span><span class="p">:</span> <span class="s1">&#39;Symbolic Ring&#39;</span> <span class="ow">and</span>
<span class="s1">&#39;Number Field in x with defining polynomial x^2 - x - 1&#39;</span>
</pre></div>



<p>But, we can define a polynomial ring with variables in a,b and coefficients in
the NumberField. Then, we are able to multiply <tt class="docutils literal">a</tt> with <tt class="docutils literal">x</tt>:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">x</span> <span class="o">=</span> <span class="n">var</span><span class="p">(</span><span class="s1">&#39;x&#39;</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">K</span><span class="o">.&lt;</span><span class="n">x</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">NumberField</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="o">-</span><span class="n">x</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">K</span>
<span class="n">Number</span> <span class="n">Field</span> <span class="ow">in</span> <span class="n">x</span> <span class="k">with</span> <span class="n">defining</span> <span class="n">polynomial</span> <span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">-</span> <span class="n">x</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">R</span><span class="o">.&lt;</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">K</span><span class="p">[</span><span class="s1">&#39;a&#39;</span><span class="p">,</span><span class="s1">&#39;b&#39;</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">R</span>
<span class="n">Multivariate</span> <span class="n">Polynomial</span> <span class="n">Ring</span> <span class="ow">in</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="n">over</span> <span class="n">Number</span> <span class="n">Field</span> <span class="ow">in</span> <span class="n">x</span> <span class="k">with</span>
<span class="n">defining</span> <span class="n">polynomial</span> <span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">-</span> <span class="n">x</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">a</span><span class="o">*</span><span class="n">x</span>
<span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="n">a</span>
</pre></div>



<p>With two square brackets, we obtain powers series:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">R</span><span class="o">.&lt;</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">K</span><span class="p">[[</span><span class="s1">&#39;a&#39;</span><span class="p">,</span><span class="s1">&#39;b&#39;</span><span class="p">]]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">R</span>
<span class="n">Multivariate</span> <span class="n">Power</span> <span class="n">Series</span> <span class="n">Ring</span> <span class="ow">in</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="n">over</span> <span class="n">Number</span> <span class="n">Field</span> <span class="ow">in</span> <span class="n">x</span> <span class="k">with</span>
<span class="n">defining</span> <span class="n">polynomial</span> <span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">-</span> <span class="n">x</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">a</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">b</span>
<span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="n">a</span><span class="o">*</span><span class="n">b</span>
</pre></div>



<p>It works with matrices:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">MS</span> <span class="o">=</span> <span class="n">MatrixSpace</span><span class="p">(</span><span class="n">R</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">MS</span>
<span class="n">Full</span> <span class="n">MatrixSpace</span> <span class="n">of</span> <span class="mi">2</span> <span class="n">by</span> <span class="mi">2</span> <span class="n">dense</span> <span class="n">matrices</span> <span class="n">over</span> <span class="n">Multivariate</span> <span class="n">Power</span>
<span class="n">Series</span> <span class="n">Ring</span> <span class="ow">in</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="n">over</span> <span class="n">Number</span> <span class="n">Field</span> <span class="ow">in</span> <span class="n">x</span> <span class="k">with</span> <span class="n">defining</span> <span class="n">polynomial</span>
<span class="n">x</span><span class="o">^</span><span class="mi">2</span> <span class="o">-</span> <span class="n">x</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">MS</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">,</span><span class="n">x</span><span class="p">])</span>
<span class="p">[</span>  <span class="mi">0</span>   <span class="n">a</span><span class="p">]</span>
<span class="p">[</span>  <span class="n">b</span> <span class="p">(</span><span class="n">x</span><span class="p">)]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">m1</span> <span class="o">=</span> <span class="n">MS</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">,</span><span class="n">x</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">m2</span> <span class="o">=</span> <span class="n">MS</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span><span class="n">a</span><span class="o">+</span><span class="n">x</span><span class="p">,</span><span class="n">b</span><span class="o">*</span><span class="n">b</span><span class="o">+</span><span class="n">x</span><span class="p">,</span><span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="p">])</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">m1</span> <span class="o">+</span> <span class="n">m2</span> <span class="o">*</span> <span class="n">m1</span>
<span class="p">[</span>              <span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="n">b</span> <span class="o">+</span> <span class="n">a</span><span class="o">*</span><span class="n">b</span>       <span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">a</span><span class="p">]</span>
<span class="p">[</span>                <span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span><span class="o">*</span><span class="n">b</span> <span class="p">(</span><span class="mi">3</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="n">a</span> <span class="o">+</span> <span class="n">a</span><span class="o">*</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="p">]</span>
</pre></div>



</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[slabbe-0.2.spkg released]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2015/11/slabbe-0.2.spkg-released" />
    <id>http://www.slabbe.org/blogue/2015/11/slabbe-0.2.spkg-released</id>
    <updated>2015-11-30T11:53:00Z</updated>
    <published>2015-11-30T11:53:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="slabbe spkg" />
    <summary type="html"><![CDATA[slabbe-0.2.spkg released]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2015/11/slabbe-0.2.spkg-released"><![CDATA[<div class="document">
<p>These is a summary of the functionalities present in <a class="reference external" href="/Sage">slabbe-0.2.spkg</a> optional
Sage package. It works on version 6.8 of Sage but will work best with sage-6.10
(it is using the new code for <tt class="docutils literal">cartesian_product</tt> merged the the betas of
sage-6.10). It contains 7 new modules:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal">finite_word.py</tt></li>
<li><tt class="docutils literal">language.py</tt></li>
<li><tt class="docutils literal">lyapunov.py</tt></li>
<li><tt class="docutils literal">matrix_cocycle.py</tt></li>
<li><tt class="docutils literal">mult_cont_frac.pyx</tt></li>
<li><tt class="docutils literal">ranking_scale.py</tt></li>
<li><tt class="docutils literal">tikz_picture.py</tt></li>
</ul>
</blockquote>
<p><strong>Cheat Sheets</strong></p>
<p>The best way to have a quick look at what can be computed with the optional
Sage package <tt class="docutils literal"><span class="pre">slabbe-0.2.spkg</span></tt> is to look at the <a class="reference external" href="http://arxiv.org/abs/1511.08399">3-dimensional Continued
Fraction Algorithms Cheat Sheets</a> available on the arXiv since today. It
gathers a handful of informations on different 3-dimensional Continued Fraction
Algorithms including well-known and old ones (Poincaré, Brun, Selmer, Fully
Subtractive) and new ones (Arnoux-Rauzy-Poincaré, Reverse, Cassaigne).</p>
<a class="reference external image-reference" href="http://arxiv.org/abs/1511.08399"><img alt="/Files/2015/arp_cheat_sheet.png" src="/Files/2015/arp_cheat_sheet.png" style="width: 40em;" /></a>
<p><strong>Installation</strong></p>


<div class="pygments_manni"><pre><span></span>sage -i http://www.slabbe.org/Sage/slabbe-0.2.spkg    # on sage 6.8
sage -p http://www.slabbe.org/Sage/slabbe-0.2.spkg    # on sage 6.9 or beyond
</pre></div>



<p><strong>Examples</strong></p>
<p>Computing the orbit of Brun algorithm on some input in \(\mathbb{R}^3_+\)
including dual coordinates:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.mult_cont_frac</span> <span class="kn">import</span> <span class="n">Brun</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">algo</span> <span class="o">=</span> <span class="n">Brun</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">algo</span><span class="o">.</span><span class="n">cone_orbit_list</span><span class="p">((</span><span class="mi">100</span><span class="p">,</span> <span class="mi">87</span><span class="p">,</span> <span class="mi">15</span><span class="p">),</span> <span class="mi">4</span><span class="p">)</span>
<span class="p">[(</span><span class="mf">13.0</span><span class="p">,</span> <span class="mf">87.0</span><span class="p">,</span> <span class="mf">15.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mi">321</span><span class="p">),</span>
 <span class="p">(</span><span class="mf">13.0</span><span class="p">,</span> <span class="mf">72.0</span><span class="p">,</span> <span class="mf">15.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">,</span> <span class="mf">3.0</span><span class="p">,</span> <span class="mi">132</span><span class="p">),</span>
 <span class="p">(</span><span class="mf">13.0</span><span class="p">,</span> <span class="mf">57.0</span><span class="p">,</span> <span class="mf">15.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">,</span> <span class="mf">5.0</span><span class="p">,</span> <span class="mi">132</span><span class="p">),</span>
 <span class="p">(</span><span class="mf">13.0</span><span class="p">,</span> <span class="mf">42.0</span><span class="p">,</span> <span class="mf">15.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">,</span> <span class="mf">7.0</span><span class="p">,</span> <span class="mi">132</span><span class="p">)]</span>
</pre></div>



<p>Computing the invariant measure:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">fig</span> <span class="o">=</span> <span class="n">algo</span><span class="o">.</span><span class="n">invariant_measure_wireframe_plot</span><span class="p">(</span><span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">6</span><span class="p">,</span> <span class="n">ndivs</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">fig</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s1">&#39;a.png&#39;</span><span class="p">)</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2015/brun_invm_wireframe_plot.png"><img alt="/Files/2015/brun_invm_wireframe_plot.png" src="/Files/2015/brun_invm_wireframe_plot.png" style="width: 25em;" /></a>
<p>Drawing the cylinders:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">cocycle</span> <span class="o">=</span> <span class="n">algo</span><span class="o">.</span><span class="n">matrix_cocycle</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">t</span> <span class="o">=</span> <span class="n">cocycle</span><span class="o">.</span><span class="n">tikz_n_cylinders</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">png</span><span class="p">()</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2015/brun_cylinders_3.png"><img alt="/Files/2015/brun_cylinders_3.png" src="/Files/2015/brun_cylinders_3.png" style="width: 25em;" /></a>
<p>Computing the Lyapunov exponents of the 3-dimensional Brun algorithm:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe.lyapunov</span> <span class="kn">import</span> <span class="n">lyapunov_table</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">lyapunov_table</span><span class="p">(</span><span class="n">algo</span><span class="p">,</span> <span class="n">n_orbits</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">n_iterations</span><span class="o">=</span><span class="mi">10</span><span class="o">^</span><span class="mi">7</span><span class="p">)</span>
  <span class="mi">30</span> <span class="n">succesful</span> <span class="n">orbits</span>     <span class="nb">min</span>       <span class="n">mean</span>      <span class="nb">max</span>       <span class="n">std</span>
<span class="o">+-----------------------+---------+---------+---------+---------+</span>
  <span class="err">$</span>\<span class="n">theta_1</span><span class="err">$</span>              <span class="mf">0.3026</span>    <span class="mf">0.3045</span>    <span class="mf">0.3051</span>    <span class="mf">0.00046</span>
  <span class="err">$</span>\<span class="n">theta_2</span><span class="err">$</span>              <span class="o">-</span><span class="mf">0.1125</span>   <span class="o">-</span><span class="mf">0.1122</span>   <span class="o">-</span><span class="mf">0.1115</span>   <span class="mf">0.00020</span>
  <span class="err">$</span><span class="mi">1</span><span class="o">-</span>\<span class="n">theta_2</span><span class="o">/</span>\<span class="n">theta_1</span><span class="err">$</span>   <span class="mf">1.3680</span>    <span class="mf">1.3684</span>    <span class="mf">1.3689</span>    <span class="mf">0.00024</span>
</pre></div>



<p><strong>Dealing with tikzpictures</strong></p>
<p>Since I create lots of tikzpictures in my code and also because I was unhappy
at how the <tt class="docutils literal">view</tt> command of Sage handles them (a tikzpicture is not a math
expression to put inside dollar signs), I decided to create a class for
tikzpictures. I think this module could be useful in Sage so I will propose
its inclusion soon.</p>
<p>I am using the standalone document class which allows some configurations like
the border:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">slabbe</span> <span class="kn">import</span> <span class="n">TikzPicture</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">g</span> <span class="o">=</span> <span class="n">graphs</span><span class="o">.</span><span class="n">PetersenGraph</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">s</span> <span class="o">=</span> <span class="n">latex</span><span class="p">(</span><span class="n">g</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">t</span> <span class="o">=</span> <span class="n">TikzPicture</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">standalone_configs</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;border=4mm&quot;</span><span class="p">],</span> <span class="n">packages</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;tkz-graph&#39;</span><span class="p">])</span>
</pre></div>



<p>The <tt class="docutils literal">repr</tt> method does not print all of the string since it is often very
long. Though it shows how many lines are not printed:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">t</span>
\<span class="n">documentclass</span><span class="p">[</span><span class="n">tikz</span><span class="p">]{</span><span class="n">standalone</span><span class="p">}</span>
\<span class="n">standaloneconfig</span><span class="p">{</span><span class="n">border</span><span class="o">=</span><span class="mi">4</span><span class="n">mm</span><span class="p">}</span>
\<span class="n">usepackage</span><span class="p">{</span><span class="n">tkz</span><span class="o">-</span><span class="n">graph</span><span class="p">}</span>
\<span class="n">begin</span><span class="p">{</span><span class="n">document</span><span class="p">}</span>
\<span class="n">begin</span><span class="p">{</span><span class="n">tikzpicture</span><span class="p">}</span>
<span class="o">%</span>
\<span class="n">useasboundingbox</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span> <span class="n">rectangle</span> <span class="p">(</span><span class="mf">5.0</span><span class="n">cm</span><span class="p">,</span><span class="mf">5.0</span><span class="n">cm</span><span class="p">);</span>
<span class="o">%</span>
\<span class="n">definecolor</span><span class="p">{</span><span class="n">cv0</span><span class="p">}{</span><span class="n">rgb</span><span class="p">}{</span><span class="mf">0.0</span><span class="p">,</span><span class="mf">0.0</span><span class="p">,</span><span class="mf">0.0</span><span class="p">}</span>
<span class="o">...</span>
<span class="o">...</span> <span class="mi">68</span> <span class="n">lines</span> <span class="ow">not</span> <span class="n">printed</span> <span class="p">(</span><span class="mi">3748</span> <span class="n">characters</span> <span class="ow">in</span> <span class="n">total</span><span class="p">)</span> <span class="o">...</span>
<span class="o">...</span>
\<span class="n">Edge</span><span class="p">[</span><span class="n">lw</span><span class="o">=</span><span class="mf">0.1</span><span class="n">cm</span><span class="p">,</span><span class="n">style</span><span class="o">=</span><span class="p">{</span><span class="n">color</span><span class="o">=</span><span class="n">cv6v8</span><span class="p">,},](</span><span class="n">v6</span><span class="p">)(</span><span class="n">v8</span><span class="p">)</span>
\<span class="n">Edge</span><span class="p">[</span><span class="n">lw</span><span class="o">=</span><span class="mf">0.1</span><span class="n">cm</span><span class="p">,</span><span class="n">style</span><span class="o">=</span><span class="p">{</span><span class="n">color</span><span class="o">=</span><span class="n">cv6v9</span><span class="p">,},](</span><span class="n">v6</span><span class="p">)(</span><span class="n">v9</span><span class="p">)</span>
\<span class="n">Edge</span><span class="p">[</span><span class="n">lw</span><span class="o">=</span><span class="mf">0.1</span><span class="n">cm</span><span class="p">,</span><span class="n">style</span><span class="o">=</span><span class="p">{</span><span class="n">color</span><span class="o">=</span><span class="n">cv7v9</span><span class="p">,},](</span><span class="n">v7</span><span class="p">)(</span><span class="n">v9</span><span class="p">)</span>
<span class="o">%</span>
\<span class="n">end</span><span class="p">{</span><span class="n">tikzpicture</span><span class="p">}</span>
\<span class="n">end</span><span class="p">{</span><span class="n">document</span><span class="p">}</span>
</pre></div>



<p>There is a method to generates a pdf and another for generating a png. Both
opens the file in a viewer by default unless <tt class="docutils literal">view=False</tt>:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">pathtofile</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">png</span><span class="p">(</span><span class="n">density</span><span class="o">=</span><span class="mi">60</span><span class="p">,</span> <span class="n">view</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">pathtofile</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">pdf</span><span class="p">()</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2015/petersen_graph.png"><img alt="/Files/2015/petersen_graph.png" src="/Files/2015/petersen_graph.png" style="width: 25em;" /></a>
<p>Compare this with the output of <tt class="docutils literal">view(s, tightpage=True)</tt> which does not
allow to control the border and also creates a second empty page on some
operating system (osx, only one page on ubuntu):</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">view</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">tightpage</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2015/petersen_graph_view.png"><img alt="/Files/2015/petersen_graph_view.png" src="/Files/2015/petersen_graph_view.png" style="width: 25em;" /></a>
<p>One can also provide the filename where to save the file in which case the file
is not open in a viewer:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">_</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">pdf</span><span class="p">(</span><span class="s1">&#39;petersen_graph.pdf&#39;</span><span class="p">)</span>
</pre></div>



<p>Another example with polyhedron code taken from this Sage thematic tutorial
<a class="reference external" href="http://doc.sagemath.org/html/en/thematic_tutorials/polytope_tikz.html">Draw polytopes in LateX using TikZ</a>:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">V</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">],[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">],[</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">],[</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">],[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">],[</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">],[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">],[</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">],[</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">]]</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">P</span> <span class="o">=</span> <span class="n">Polyhedron</span><span class="p">(</span><span class="n">vertices</span><span class="o">=</span><span class="n">V</span><span class="p">)</span><span class="o">.</span><span class="n">polar</span><span class="p">()</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">s</span> <span class="o">=</span> <span class="n">P</span><span class="o">.</span><span class="n">projection</span><span class="p">()</span><span class="o">.</span><span class="n">tikz</span><span class="p">([</span><span class="mi">674</span><span class="p">,</span><span class="mi">108</span><span class="p">,</span><span class="o">-</span><span class="mi">731</span><span class="p">],</span><span class="mi">112</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">t</span> <span class="o">=</span> <span class="n">TikzPicture</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">t</span>
\<span class="n">documentclass</span><span class="p">[</span><span class="n">tikz</span><span class="p">]{</span><span class="n">standalone</span><span class="p">}</span>
\<span class="n">begin</span><span class="p">{</span><span class="n">document</span><span class="p">}</span>
\<span class="n">begin</span><span class="p">{</span><span class="n">tikzpicture</span><span class="p">}</span><span class="o">%</span>
        <span class="p">[</span><span class="n">x</span><span class="o">=</span><span class="p">{(</span><span class="mf">0.249656</span><span class="n">cm</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.577639</span><span class="n">cm</span><span class="p">)},</span>
        <span class="n">y</span><span class="o">=</span><span class="p">{(</span><span class="mf">0.777700</span><span class="n">cm</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.358578</span><span class="n">cm</span><span class="p">)},</span>
        <span class="n">z</span><span class="o">=</span><span class="p">{(</span><span class="o">-</span><span class="mf">0.576936</span><span class="n">cm</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.733318</span><span class="n">cm</span><span class="p">)},</span>
        <span class="n">scale</span><span class="o">=</span><span class="mf">2.000000</span><span class="p">,</span>
<span class="o">...</span>
<span class="o">...</span> <span class="mi">80</span> <span class="n">lines</span> <span class="ow">not</span> <span class="n">printed</span> <span class="p">(</span><span class="mi">4889</span> <span class="n">characters</span> <span class="ow">in</span> <span class="n">total</span><span class="p">)</span> <span class="o">...</span>
<span class="o">...</span>
\<span class="n">node</span><span class="p">[</span><span class="n">vertex</span><span class="p">]</span> <span class="n">at</span> <span class="p">(</span><span class="mf">1.00000</span><span class="p">,</span> <span class="mf">1.00000</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.00000</span><span class="p">)</span>     <span class="p">{};</span>
\<span class="n">node</span><span class="p">[</span><span class="n">vertex</span><span class="p">]</span> <span class="n">at</span> <span class="p">(</span><span class="mf">1.00000</span><span class="p">,</span> <span class="mf">1.00000</span><span class="p">,</span> <span class="mf">1.00000</span><span class="p">)</span>     <span class="p">{};</span>
<span class="o">%%</span>
<span class="o">%%</span>
\<span class="n">end</span><span class="p">{</span><span class="n">tikzpicture</span><span class="p">}</span>
\<span class="n">end</span><span class="p">{</span><span class="n">document</span><span class="p">}</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">_</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">pdf</span><span class="p">()</span>
</pre></div>



<a class="reference external image-reference" href="/Files/2015/polyhedron.png"><img alt="/Files/2015/polyhedron.png" src="/Files/2015/polyhedron.png" style="width: 20em;" /></a>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[There are 13.366.431.646 solutions to the Quantumino game]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2015/09/there-are-13.366.431.646-solutions-to-the-quantumino-game" />
    <id>http://www.slabbe.org/blogue/2015/09/there-are-13.366.431.646-solutions-to-the-quantumino-game</id>
    <updated>2015-09-21T14:55:00Z</updated>
    <published>2015-09-21T14:55:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <summary type="html"><![CDATA[There are 13.366.431.646 solutions to the Quantumino game]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2015/09/there-are-13.366.431.646-solutions-to-the-quantumino-game"><![CDATA[<div class="document">
<p>Some years ago, I wrote <a class="reference external" href="http://doc.sagemath.org/html/en/reference/games/sage/games/quantumino.html">code</a> in Sage to solve the Quantumino puzzle. I also
used it to make a one-minute <a class="reference external" href="http://vimeo.com/35348052">video</a> illustrating the Dancing links algorithm
which I am proud to say it is now part of the <a class="reference external" href="http://en.wikipedia.org/wiki/Dancing_Links">Dancing links</a> wikipedia page.</p>
<a class="reference external image-reference" href="http://www.familygamesamerica.com/mainsite/consumers/productview.php?pro_id=274"><img alt="/Files/2015/Quantumino.png" src="/Files/2015/Quantumino.png" style="width: 20em;" /></a>
<p>Let me recall that the goal of the Quantumino puzzle is to fill a \(2\times
5\times 8\) box with 16 out of 17 three-dimensional pentaminos. After writing
the sage code to solve the puzzle, one question was left: how many solutions
are there? Is the <a class="reference external" href="http://familygamesamerica.com/mainsite/consumers/productview.php?pro_id=274">official website</a> realist or very prudent when they say
that <em>there are over 10.000 potential solutions</em>? Can it be computed in hours?
days? months? years? The only thing I knew was that the following computation
(letting the 0-th pentamino aside) never finished on my machine:</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">sage.games.quantumino</span> <span class="kn">import</span> <span class="n">QuantuminoSolver</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">QuantuminoSolver</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">number_of_solutions</span><span class="p">()</span>   <span class="c1"># long time :)</span>
</pre></div>



<p>Since I spent already too much time on this side-project, I decided in 2012 to
stop investing any more time on it and to really focus on finishing writing my
thesis.</p>
<p>So before I finish writing my thesis, I knew that the computation was not going
to take a light-year, since I was able to finish the computation of the number
of solutions when the 0-th pentamino is put aside and when one pentamino is
pre-positioned somewhere in the box. That computation completed in 4 hours on
my old laptop and gave about 5 millions solutions. There are 17 choices of
pentatminos to put aside, there are 360 distinct positions of that pentamino in
the box, so I estimated the number of solution to be something like
\(17\times 360\times 5000000 = 30 \times 10^9\). Most importantly, I
estimated the computation to take \(17\times 360\times 4= 24480\) hours or
1020 days. Therefore, I knew I could not do it on my laptop.</p>
<p>But last year, I received an email from the designer of the Quantumino puzzle:</p>


<div class="pygments_manni"><pre><span></span>-------- Message transféré --------
Sujet : quantumino
Date : Tue, 09 Dec 2014 13:22:30 +0100
De : Nicolaas Neuwahl
Pour : Sebastien Labbe

hi sébastien labbé,

i&#39;m the designer of the quantumino puzzle.
i&#39;m not a mathematician, i&#39;m an architect. i like mathematics.
i&#39;m quite impressed to see the sage work on quantumino, also i have not the
knowledge for full understanding.

i have a question for you - can you tell me HOW MANY different quantumino-
solutions exist?

ty and bye

nicolaas neuwahl
</pre></div>



<p>This summer was a good timing to launch the computation on my beautiful Intel®
Core™ i5-4590 CPU &#64; 3.30GHz × 4 at Université de Liège. First, I improved the
Sage code to allow a parallel computation of number of solutions in the dancing
links code (<a class="reference external" href="http://trac.sagemath.org/ticket/18987">#18987</a>, merged in a Sage 6.9.beta6). Secondly, we may remark
that each tiling of the \(2\times 5\times 8\) box can be rotated in order
to find 3 other solutions. It is possible to gain a factor 4 by avoiding to
count 4 times the same solution up to rotations (<a class="reference external" href="http://trac.sagemath.org/ticket/19107">#19107</a>, still needs work
from myself). Thanks to Vincent Delecroix for doing the review on both ticket.
Dividing the estimated 1024 days of computation needed by a factor \(4\times
4=16\) gives an approximation of 64 days to complete the computation. Two
months, just enough to be tractable!</p>
<p>With those two tickets (some previous version to be honest) on top of sage-6.8,
I started the computation on August 4th and the computation finished last week
on September 18th for a total of 45 days. The computation was stopped only once
on September 8th (I forgot to close firefox and thunderbird that night...).</p>
<p>The number of solutions and computation time for each pentamino put aside
together with the first solution found is shown in the table below.  We remark
that some values are equal when the aside pentaminoes are miror images
(why!?:).</p>
<table border="1" class="docutils">
<colgroup>
<col width="50%" />
<col width="50%" />
</colgroup>
<tbody valign="top">
<tr><td><img alt="/Files/2015/b0.png" class="first last" src="/Files/2015/b0.png" />
</td>
<td><img alt="/Files/2015/b1.png" class="first last" src="/Files/2015/b1.png" />
</td>
</tr>
<tr><td>634 900 493  solutions</td>
<td>634 900 493  solutions</td>
</tr>
<tr><td>2 days, 6:22:44.883358</td>
<td>2 days, 6:19:08.945691</td>
</tr>
<tr><td><img alt="/Files/2015/b2.png" class="first last" src="/Files/2015/b2.png" />
</td>
<td><img alt="/Files/2015/b3.png" class="first last" src="/Files/2015/b3.png" />
</td>
</tr>
<tr><td>509 560 697  solutions</td>
<td>509 560 697  solutions</td>
</tr>
<tr><td>2 days, 0:01:36.844612</td>
<td>2 days, 0:41:59.447773</td>
</tr>
<tr><td><img alt="/Files/2015/b4.png" class="first last" src="/Files/2015/b4.png" />
</td>
<td><img alt="/Files/2015/b5.png" class="first last" src="/Files/2015/b5.png" />
</td>
</tr>
<tr><td>628 384 422  solutions</td>
<td>628 384 422  solutions</td>
</tr>
<tr><td>2 days, 7:52:31.459247</td>
<td>2 days, 8:44:49.465672</td>
</tr>
<tr><td><img alt="/Files/2015/b6.png" class="first last" src="/Files/2015/b6.png" />
</td>
<td><img alt="/Files/2015/b7.png" class="first last" src="/Files/2015/b7.png" />
</td>
</tr>
<tr><td>1 212 362 145  solutions</td>
<td>1 212 362 145  solutions</td>
</tr>
<tr><td>3 days, 17:25:00.346627</td>
<td>3 days, 19:10:02.353063</td>
</tr>
<tr><td><img alt="/Files/2015/b8.png" class="first last" src="/Files/2015/b8.png" />
</td>
<td><img alt="/Files/2015/b9.png" class="first last" src="/Files/2015/b9.png" />
</td>
</tr>
<tr><td>197 325 298  solutions</td>
<td>556 534 800  solutions</td>
</tr>
<tr><td>22:51:54.439932</td>
<td>1 day, 19:05:23.908326</td>
</tr>
<tr><td><img alt="/Files/2015/b10.png" class="first last" src="/Files/2015/b10.png" />
</td>
<td><img alt="/Files/2015/b11.png" class="first last" src="/Files/2015/b11.png" />
</td>
</tr>
<tr><td>664 820 756  solutions</td>
<td>468 206 736  solutions</td>
</tr>
<tr><td>2 days, 8:48:54.767662</td>
<td>1 day, 20:14:56.014557</td>
</tr>
<tr><td><img alt="/Files/2015/b12.png" class="first last" src="/Files/2015/b12.png" />
</td>
<td><img alt="/Files/2015/b13.png" class="first last" src="/Files/2015/b13.png" />
</td>
</tr>
<tr><td>1 385 955 043  solutions</td>
<td>1 385 955 043  solutions</td>
</tr>
<tr><td>4 days, 1:40:30.270929</td>
<td>4 days, 4:44:05.399367</td>
</tr>
<tr><td><img alt="/Files/2015/b14.png" class="first last" src="/Files/2015/b14.png" />
</td>
<td><img alt="/Files/2015/b15.png" class="first last" src="/Files/2015/b15.png" />
</td>
</tr>
<tr><td>694 998 374  solutions</td>
<td>694 998 374  solutions</td>
</tr>
<tr><td>2 days, 11:44:29.631</td>
<td>2 days, 6:01:57.946708</td>
</tr>
<tr><td><img alt="/Files/2015/b16.png" class="first last" src="/Files/2015/b16.png" />
</td>
<td>&nbsp;</td>
</tr>
<tr><td>1 347 221 708  solutions</td>
<td>&nbsp;</td>
</tr>
<tr><td>3 days, 21:51:29.043459</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
<p>Therefore the total number of solutions up to rotations is 13 366 431 646 which
is indeed more than 10000:)</p>


<div class="pygments_manni"><pre><span></span><span class="n">sage</span><span class="p">:</span> <span class="n">L</span> <span class="o">=</span> <span class="p">[</span><span class="mi">634900493</span><span class="p">,</span> <span class="mi">634900493</span><span class="p">,</span> <span class="mi">509560697</span><span class="p">,</span> <span class="mi">509560697</span><span class="p">,</span> <span class="mi">628384422</span><span class="p">,</span>
<span class="mi">628384422</span><span class="p">,</span> <span class="mi">1212362145</span><span class="p">,</span> <span class="mi">1212362145</span><span class="p">,</span> <span class="mi">197325298</span><span class="p">,</span> <span class="mi">556534800</span><span class="p">,</span> <span class="mi">664820756</span><span class="p">,</span>
<span class="mi">468206736</span><span class="p">,</span> <span class="mi">1385955043</span><span class="p">,</span> <span class="mi">1385955043</span><span class="p">,</span> <span class="mi">694998374</span><span class="p">,</span> <span class="mi">694998374</span><span class="p">,</span> <span class="mi">1347221708</span><span class="p">]</span>
<span class="n">sage</span><span class="p">:</span> <span class="nb">sum</span><span class="p">(</span><span class="n">L</span><span class="p">)</span>
<span class="mi">13366431646</span>
<span class="n">sage</span><span class="p">:</span> <span class="n">factor</span><span class="p">(</span><span class="n">_</span><span class="p">)</span>
<span class="mi">2</span> <span class="o">*</span> <span class="mi">23</span> <span class="o">*</span> <span class="mi">271</span> <span class="o">*</span> <span class="mi">1072231</span>
</pre></div>



<table border="1" class="docutils">
<caption>Summary</caption>
<colgroup>
<col width="50%" />
<col width="50%" />
</colgroup>
<tbody valign="top">
<tr><td>The machine (4 cores)</td>
<td>Intel® Core™ i5-4590 CPU &#64; 3.30GHz × 4 (Université de Liège)</td>
</tr>
<tr><td>Computation Time</td>
<td>45 days, (Aug 4th -- Sep 18th, 2015)</td>
</tr>
<tr><td>Number of solutions (up to rotations)</td>
<td>13 366 431 646</td>
</tr>
<tr><td>Number of solutions / cpu / second</td>
<td>859</td>
</tr>
</tbody>
</table>
<p>My code will be available on github.</p>
<p><strong>About the video on wikipedia.</strong></p>
<p>I must say that the video is not perfect. On wikipedia, the <a class="reference external" href="http://en.wikipedia.org/wiki/File_talk:Dancing_links_Quantumino_puzzle.ogv">file talk page</a>
of the video says that the <em>Jerky camera movement is distracting</em>. That is
because <a class="reference external" href="/blogue/2012/01/faire-une-animation-en-3d-avec-sage/">I managed to make the video</a> out of images created by
<tt class="docutils literal"><span class="pre">.show(viewer='tachyon')</span></tt> which changes the coordinate system, hardcodes a
lot of parameters, zoom properly, simplifies stuff to make sure the user don't
see just a blank image. But, for making a movie, we need access to more
parameters especially the placement of the camera (to avoid the jerky
movement). I know that Tachyon allows all of that. It is still a project that I
have to create a more versatile <tt class="docutils literal">Graphics3D <span class="pre">-&gt;</span> Tachyon</tt> conversion allowing
to construct nice videos of evolving mathematical objects. That's another
story.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Arnoux-Rauzy-Poincaré sequences]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2015/02/arnoux-rauzy-poincare-sequences" />
    <id>http://www.slabbe.org/blogue/2015/02/arnoux-rauzy-poincare-sequences</id>
    <updated>2015-02-26T16:22:00Z</updated>
    <published>2015-02-26T16:22:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <summary type="html"><![CDATA[Arnoux-Rauzy-Poincaré sequences]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2015/02/arnoux-rauzy-poincare-sequences"><![CDATA[<div class="document">
<p>In a recent article with Valérie Berthé <a class="citation-reference" href="#bl15" id="citation-reference-1">[BL15]</a>, we provided a multidimensional
continued fraction algorithm called Arnoux-Rauzy-Poincaré (ARP) to construct,
given any vector \(v\in\mathbb{R}_+^3\), an infinite word
\(w\in\{1,2,3\}^\mathbb{N}\) over a three-letter alphabet such that the
frequencies of letters in \(w\) exists and are equal to \(v\) and such that
the number of factors (i.e.  finite block of consecutive letters) of length
\(n\) appearing in \(w\) is linear and less than \(\frac{5}{2}n+1\). We
also conjecture that for almost all \(v\) the contructed word describes a
discrete path in the positive octant staying at a bounded distance from the
euclidean line of direction \(v\).</p>
<p>In Sage, you can construct this word using the next version of my package
slabbe-0.2 (not released yet, email me to press me to finish it). The one with
frequencies of letters proportionnal to \((1, e, \pi)\) is:</p>


<div class="pygments_manni"><pre><span></span>sage: from slabbe.mcf import algo
sage: D = algo.arp.substitutions()
sage: it = algo.arp.coding_iterator((1,e,pi))
sage: w = words.s_adic(it, repeat(1), D)
word: 1232323123233231232332312323123232312323...
</pre></div>



<p>The factor complexity is close to 2n+1 and the balance is often less or equal
to three:</p>


<div class="pygments_manni"><pre><span></span>sage: w[:10000].number_of_factors(100)
202
sage: w[:100000].number_of_factors(1000)
2002
sage: w[:1000].balance()
3
sage: w[:2000].balance()
3
</pre></div>



<p>Note that bounded distance from the euclidean line almost surely was proven in
<a class="citation-reference" href="#dhs2013" id="citation-reference-2">[DHS2013]</a> for Brun algorithm, another MCF algorithm.</p>
<p><strong>Other approaches: Standard model and billiard sequences</strong></p>
<p>Other approaches have been proposed to construct such discrete lines.</p>
<p>One of them is the standard model of Eric Andres <a class="citation-reference" href="#a03" id="citation-reference-3">[A03]</a>. It is also equivalent
to billiard sequences in the cube. It is well known that the factor complexity
of billiard sequences is quadratic \(p(n)=n^2+n+1\) <a class="citation-reference" href="#amst94" id="citation-reference-4">[AMST94]</a>.
Experimentally, we can verify this. We first create a billiard word of some
given direction:</p>


<div class="pygments_manni"><pre><span></span>sage: from slabbe import BilliardCube
sage: v = vector(RR, (1, e, pi))
sage: b = BilliardCube(v)
sage: b
Cubic billiard of direction (1.00000000000000, 2.71828182845905, 3.14159265358979)
sage: w = b.to_word()
sage: w
word: 3231232323123233213232321323231233232132...
</pre></div>



<p>We create some prefixes of \(w\) that we represent internally as <tt class="docutils literal">char*</tt>.
The creation is slow because the implementation of billiard words in my
optional package is in Python and is not that efficient:</p>


<div class="pygments_manni"><pre><span></span>sage: p3 = Word(w[:10^3], alphabet=[1,2,3], datatype=&#39;char&#39;)
sage: p4 = Word(w[:10^4], alphabet=[1,2,3], datatype=&#39;char&#39;) # takes 3s
sage: p5 = Word(w[:10^5], alphabet=[1,2,3], datatype=&#39;char&#39;) # takes 32s
sage: p6 = Word(w[:10^6], alphabet=[1,2,3], datatype=&#39;char&#39;) # takes 5min 20s
</pre></div>



<p>We see below that exactly \(n^2+n+1\) factors of length \(n&lt;20\) appears in
the prefix of length 1000000 of \(w\):</p>


<div class="pygments_manni"><pre><span></span>sage: A = [&#39;n&#39;] + range(30)
sage: c3 = [&#39;p_(w[:10^3])(n)&#39;] + map(p3.number_of_factors, range(30))
sage: c4 = [&#39;p_(w[:10^4])(n)&#39;] + map(p4.number_of_factors, range(30))
sage: c5 = [&#39;p_(w[:10^5])(n)&#39;] + map(p5.number_of_factors, range(30)) # takes 4s
sage: c6 = [&#39;p_(w[:10^6])(n)&#39;] + map(p6.number_of_factors, range(30)) # takes 49s
sage: ref = [&#39;n^2+n+1&#39;] + [n^2+n+1 for n in range(30)]
sage: T = table(columns=[A,c3,c4,c5,c6,ref])
sage: T
  n    p_(w[:10^3])(n)   p_(w[:10^4])(n)   p_(w[:10^5])(n)   p_(w[:10^6])(n)   n^2+n+1
+----+-----------------+-----------------+-----------------+-----------------+---------+
  0    1                 1                 1                 1                 1
  1    3                 3                 3                 3                 3
  2    7                 7                 7                 7                 7
  3    13                13                13                13                13
  4    21                21                21                21                21
  5    31                31                31                31                31
  6    43                43                43                43                43
  7    52                55                56                57                57
  8    63                69                71                73                73
  9    74                85                88                91                91
  10   87                103               107               111               111
  11   100               123               128               133               133
  12   115               145               151               157               157
  13   130               169               176               183               183
  14   144               195               203               211               211
  15   160               223               232               241               241
  16   176               253               263               273               273
  17   192               285               296               307               307
  18   208               319               331               343               343
  19   224               355               368               381               381
  20   239               392               407               421               421
  21   254               430               448               463               463
  22   268               470               491               507               507
  23   282               510               536               553               553
  24   296               552               583               601               601
  25   310               596               632               651               651
  26   324               642               683               703               703
  27   335               687               734               757               757
  28   345               734               787               813               813
  29   355               783               842               871               871
</pre></div>



<p>Billiard sequences generate paths that are at a bounded distance from an
euclidean line. This is equivalent to say that the balance is finite. The
balance is defined as the supremum value of difference of the number of
apparition of a letter in two factors of the same length. For billiard
sequences, the balance is 2:</p>


<div class="pygments_manni"><pre><span></span>sage: p3.balance()
2
sage: p4.balance() # takes 2min 37s
2
</pre></div>



<p><strong>Other approaches: Melançon and Reutenauer</strong></p>
<p>Melançon and Reutenauer <a class="citation-reference" href="#mr13" id="citation-reference-5">[MR13]</a> also suggested a method that generalizes
Christoffel words in higher dimension. The construction is based on the
application of two substitutions generalizing the construction of sturmian
sequences. Below we compute the factor complexity and the balance of some of
their words over a three-letter alphabet.</p>
<p>On a three-letter alphabet, the two morphisms are:</p>


<div class="pygments_manni"><pre><span></span>sage: L = WordMorphism(&#39;1-&gt;1,2-&gt;13,3-&gt;2&#39;)
sage: R = WordMorphism(&#39;1-&gt;13,2-&gt;2,3-&gt;3&#39;)
sage: L
WordMorphism: 1-&gt;1, 2-&gt;13, 3-&gt;2
sage: R
WordMorphism: 1-&gt;13, 2-&gt;2, 3-&gt;3
</pre></div>



<p>Example 1: periodic case \(LRLRLRLRLR\dots\). In this example, the factor
complexity seems to be around \(p(n)=2.76n\) and the balance is at least 28:</p>


<div class="pygments_manni"><pre><span></span>sage: from itertools import repeat, cycle
sage: W = words.s_adic(cycle((L,R)),repeat(&#39;1&#39;))
sage: W
word: 1213122121313121312212212131221213131213...
sage: map(W[:10000].number_of_factors, [10,20,40,80])
[27, 54, 110, 221]
sage: [27/10., 54/20., 110/40., 221/80.]
[2.70000000000000, 2.70000000000000, 2.75000000000000, 2.76250000000000]
sage: W[:1000].balance()  # takes 1.6s
21
sage: W[:2000].balance()  # takes 6.4s
28
</pre></div>



<p>Example 2: \(RLR^2LR^4LR^8LR^{16}LR^{32}LR^{64}LR^{128}\dots\) taken from
the conclusion of their article. In this example, the factor complexity seems
to be \(p(n)=3n\) and balance at least as high (=bad) as \(122\):</p>


<div class="pygments_manni"><pre><span></span>sage: W = words.s_adic([R,L,R,R,L,R,R,R,R,L]+[R]*8+[L]+[R]*16+[L]+[R]*32+[L]+[R]*64+[L]+[R]*128,&#39;1&#39;)
sage: W.length()
330312
sage: map(W.number_of_factors, [10, 20, 100, 200, 300, 1000])
[29, 57, 295, 595, 895, 2981]
sage: [29/10., 57/20., 295/100., 595/200., 895/300., 2981/1000.]
[2.90000000000000,
 2.85000000000000,
 2.95000000000000,
 2.97500000000000,
 2.98333333333333,
 2.98100000000000]
sage: W[:1000].balance()  # takes 1.6s
122
sage: W[:2000].balance()  # takes 6s
122
</pre></div>



<p>Example 3: some random ones. The complexity \(p(n)/n\) occillates between 2
and 3 for factors of length \(n=1000\) in prefixes of length 100000:</p>


<div class="pygments_manni"><pre><span></span>sage: for _ in range(10):
....:     W = words.s_adic([choice((L,R)) for _ in range(50)],&#39;1&#39;)
....:     print W[:100000].number_of_factors(1000)/1000.
2.02700000000000
2.23600000000000
2.74000000000000
2.21500000000000
2.78700000000000
2.52700000000000
2.85700000000000
2.33300000000000
2.65500000000000
2.51800000000000
</pre></div>



<p>For ten randomly generated words, the balance goes from 6 to 27 which is much
more than what is obtained for billiard words or by our approach:</p>


<div class="pygments_manni"><pre><span></span>sage: for _ in range(10):
....:     W = words.s_adic([choice((L,R)) for _ in range(50)],&#39;1&#39;)
....:     print W[:1000].balance(), W[:2000].balance()
12 15
8 24
14 14
5 11
17 17
14 14
6 6
19 27
9 16
12 12
</pre></div>



<div class="section" id="references">
<h1>References</h1>
<table class="docutils citation" frame="void" id="bl15" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-1">[BL15]</a></td><td>V. Berthé, S. Labbé,
Factor Complexity of S-adic words generated by the Arnoux-Rauzy-Poincaré Algorithm,
<em>Advances in Applied Mathematics</em> 63 (2015) 90-130.
<a class="reference external" href="http://dx.doi.org/10.1016/j.aam.2014.11.001">http://dx.doi.org/10.1016/j.aam.2014.11.001</a></td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="dhs2013" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-2">[DHS2013]</a></td><td>Delecroix, Vincent, Tomás Hejda, and Wolfgang Steiner. “Balancedness of
Arnoux-Rauzy and Brun Words.” In Combinatorics on Words, 119–31. Springer,
2013. <a class="reference external" href="http://link.springer.com/chapter/10.1007/978-3-642-40579-2_14">http://link.springer.com/chapter/10.1007/978-3-642-40579-2_14</a>.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="a03" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-3">[A03]</a></td><td>E. Andres,
Discrete linear objects in dimension n: the standard model,
Graphical Models 65 (2003) 92-111.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="amst94" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-4">[AMST94]</a></td><td>P. Arnoux, C. Mauduit, I. Shiokawa, J. I. Tamura,
Complexity of sequences defined by billiards in the cube,
Bull. Soc. Math. France 122 (1994) 1-12.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="mr13" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-5">[MR13]</a></td><td>G. Melançon, C. Reutenauer,
On a class of Lyndon words extending Christoffel words and related to a
multidimensional continued fraction algorithm.
J. Integer Seq. 16, No. 9, Article 13.9.7, 30 p., electronic only (2013).
<a class="reference external" href="https://cs.uwaterloo.ca/journals/JIS/VOL16/Reutenauer/reut3.html">https://cs.uwaterloo.ca/journals/JIS/VOL16/Reutenauer/reut3.html</a></td></tr>
</tbody>
</table>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Abelian complexity of the Oldenburger sequence]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2014/09/abelian-complexity-of-the-oldenburger-sequence" />
    <id>http://www.slabbe.org/blogue/2014/09/abelian-complexity-of-the-oldenburger-sequence</id>
    <updated>2014-09-27T22:00:00Z</updated>
    <published>2014-09-27T22:00:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <summary type="html"><![CDATA[Abelian complexity of the Oldenburger sequence]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2014/09/abelian-complexity-of-the-oldenburger-sequence"><![CDATA[<div class="document">
<p>The Oldenburger infinite sequence <a class="citation-reference" href="#o39" id="citation-reference-1">[O39]</a>
\[
K = 1221121221221121122121121221121121221221\ldots
\]
also known under the name of <a class="reference external" href="http://en.wikipedia.org/wiki/Kolakoski_sequence">Kolakoski</a>, is equal to its <em>exponent
trajectory</em>.  The exponent trajectory \(\Delta\) can be obtained by counting
the lengths of blocks of consecutive and equal letters:
\[
K =
1^12^21^22^11^12^21^12^21^22^11^22^21^12^11^22^11^12^21^22^11^22^11^12^21^12^21^22^11^12^21^12^11^22^11^22^21^12^21^2\ldots
\]
The sequence of exponents above gives the exponent trajectory of the
Oldenburger sequence:
\[
\Delta = 12211212212211211221211212\ldots
\]
which is equal to the original sequence \(K\).
You can define this sequence in Sage:</p>


<div class="pygments_manni"><pre><span></span>sage: K = words.KolakoskiWord()
sage: K
word: 1221121221221121122121121221121121221221...
sage: K.delta()          # delta returns the exponent trajectory
word: 1221121221221121122121121221121121221221...
</pre></div>



<p>There are a lot of open problem related to basic properties of that sequence.
For example, we do not know if that sequence is recurrent, that is, all finite
subword or factor (finite block of consecutive letters) always reappear. Also,
it is still open to prove whether the density of <tt class="docutils literal">1</tt> in that sequence is
equal to \(1/2\).</p>
<p>In this blog post, I do some computations on its abelian complexity
\(p_{ab}(n)\) defined as the number of distinct abelian vectors of subwords of
length \(n\) in the sequence. The abelian vector \(\vec{w}\) of a word
\(w\) counts the number of occurences of each letter:
\[
w = 12211212212
\quad
\mapsto
\quad
1^5 2^7 \text{, abelianized}
\quad
\mapsto
\quad
\vec{w} = (5, 7) \text{, the abelian vector of }
w
\]</p>
<p>Here are the abelian vectors of subwords of length 10 and 20 in the prefix of
length 100 of the Oldenburger sequence.  The functions <tt class="docutils literal">abelian_vectors</tt> and
<tt class="docutils literal">abelian_complexity</tt>  are not in Sage as of now. Code is available at <a class="reference external" href="http://trac.sagemath.org/ticket/17058">trac
#17058</a> to be merged in Sage soon:</p>


<div class="pygments_manni"><pre><span></span>sage: prefix = words.KolakoskiWord()[:100]
sage: prefix.abelian_vectors(10)
{(4, 6), (5, 5), (6, 4)}
sage: prefix.abelian_vectors(20)
{(8, 12), (9, 11), (10, 10), (11, 9), (12, 8)}
</pre></div>



<p>Therefore, the prefix of length 100 has 3 vectors of subwords of length 10 and 5
vectors of subwords of length 20:</p>


<div class="pygments_manni"><pre><span></span>sage: p100.abelian_complexity(10)
3
sage: p100.abelian_complexity(20)
5
</pre></div>



<p>I import the <tt class="docutils literal">OldenburgerSequence</tt> from my optional spkg because it is faster
than the implementation in Sage:</p>


<div class="pygments_manni"><pre><span></span>sage: from slabbe import KolakoskiWord as OldenburgerSequence
sage: Olden = OldenburgerSequence()
</pre></div>



<p>I count the number of abelian vectors of subwords of length 100 in the prefix of
length \(2^{20}\) of the Oldenburger sequence:</p>


<div class="pygments_manni"><pre><span></span>sage: prefix = Olden[:2^20]
sage: %time prefix.abelian_vectors(100)
CPU times: user 3.48 s, sys: 66.9 ms, total: 3.54 s
Wall time: 3.56 s
{(47, 53), (48, 52), (49, 51), (50, 50), (51, 49), (52, 48), (53, 47)}
</pre></div>



<p>Number of abelian vectors of subwords of length less than 100 in the prefix of
length \(2^{20}\) of the Oldenburger sequence:</p>


<div class="pygments_manni"><pre><span></span>sage: %time L100 = map(prefix.abelian_complexity, range(100))
CPU times: user 3min 20s, sys: 1.08 s, total: 3min 21s
Wall time: 3min 23s
sage: from collections import Counter
sage: Counter(L100)
Counter({5: 26, 6: 26, 4: 17, 7: 15, 3: 8, 8: 4, 2: 3, 1: 1})
</pre></div>



<p>Let's draw that:</p>


<div class="pygments_manni"><pre><span></span>sage: labels = (&#39;Length of factors&#39;, &#39;Number of abelian vectors&#39;)
sage: title = &#39;Abelian Complexity of the prefix of length $2^{20}$ of Oldenburger sequence&#39;
sage: list_plot(L100, color=&#39;green&#39;, plotjoined=True, axes_labels=labels, title=title)
</pre></div>



<a class="reference external image-reference" href="/Files/2014/oldenburger_abelian_100.png"><img alt="/Files/2014/oldenburger_abelian_100.png" src="/Files/2014/oldenburger_abelian_100.png" style="width: 30em;" /></a>
<p>It seems to grow something like \(\log(n)\). Let's now consider subwords of
length \(2^n\) for \(0\leq n\leq 12\) in the same prefix of length
\(2^{20}\):</p>


<div class="pygments_manni"><pre><span></span>sage: %time L20 = [(2^n, prefix.abelian_complexity(2^n)) for n in range(20)]
CPU times: user 41 s, sys: 239 ms, total: 41.2 s
Wall time: 41.5 s
sage: L20
[(1, 2), (2, 3), (4, 3), (8, 3), (16, 3), (32, 5), (64, 5), (128, 9),
(256, 9), (512, 13), (1024, 17), (2048, 22), (4096, 27), (8192, 40),
(16384, 46), (32768, 67), (65536, 81), (131072, 85), (262144, 90), (524288, 104)]
</pre></div>



<p>I now look at subwords of length \(2^n\) for \(0\leq n\leq 23\) in the
longer prefix of length \(2^{24}\):</p>


<div class="pygments_manni"><pre><span></span>sage: prefix = Olden[:2^24]
sage: %time L24 = [(2^n, prefix.abelian_complexity(2^n)) for n in range(24)]
CPU times: user 20min 47s, sys: 13.5 s, total: 21min
Wall time: 20min 13s
sage: L24
[(1, 2), (2, 3), (4, 3), (8, 3), (16, 3), (32, 5), (64, 5), (128, 9), (256,
9), (512, 13), (1024, 17), (2048, 23), (4096, 33), (8192, 46), (16384, 58),
(32768, 74), (65536, 98), (131072, 134), (262144, 165), (524288, 229),
(1048576, 302), (2097152, 371), (4194304, 304), (8388608, 329)]
</pre></div>



<p>The next graph gather all of the above computations:</p>


<div class="pygments_manni"><pre><span></span>sage: G = Graphics()
sage: legend = &#39;in the prefix of length 2^{}&#39;
sage: G += list_plot(L24, plotjoined=True, thickness=4, color=&#39;blue&#39;, legend_label=legend.format(24))
sage: G += list_plot(L20, plotjoined=True, thickness=4, color=&#39;red&#39;, legend_label=legend.format(20))
sage: G += list_plot(L100, plotjoined=True, thickness=4, color=&#39;green&#39;, legend_label=legend.format(20))
sage: labels = (&#39;Length of factors&#39;, &#39;Number of abelian vectors&#39;)
sage: title = &#39;Abelian complexity of Oldenburger sequence&#39;
sage: G.show(scale=(&#39;semilogx&#39;, 2), axes_labels=labels, title=title)
</pre></div>



<a class="reference external image-reference" href="/Files/2014/oldenburger_abelian_2e24.png"><img alt="/Files/2014/oldenburger_abelian_2e24.png" src="/Files/2014/oldenburger_abelian_2e24.png" style="width: 30em;" /></a>
<p>A linear growth in the above graphics with logarithmic \(x\) abcisse would
mean a growth in \(\log(n)\).  After those experimentations, my hypothesis
is that the abelian complexity of the Oldenburger sequence grows like
\(\log(n)^2\).</p>
<div class="section" id="references">
<h1>References</h1>
<table class="docutils citation" frame="void" id="o39" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-1">[O39]</a></td><td>Oldenburger, Rufus (1939). &quot;Exponent trajectories in symbolic dynamics&quot;.
Transactions of the American Mathematical Society 46: 453–466.
<a class="reference external" href="http://dx.doi.org/10.2307%2F1989933">doi:10.2307/1989933</a></td></tr>
</tbody>
</table>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[slabbe-0.1.spkg released]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2014/08/slabbe-0.1.spkg-released" />
    <id>http://www.slabbe.org/blogue/2014/08/slabbe-0.1.spkg-released</id>
    <updated>2014-08-27T16:53:00Z</updated>
    <published>2014-08-27T16:53:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="slabbe spkg" />
    <summary type="html"><![CDATA[slabbe-0.1.spkg released]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2014/08/slabbe-0.1.spkg-released"><![CDATA[<div class="document">
<p>These is a summary of the functionalities present in <a class="reference external" href="/Sage">slabbe-0.1</a> optional Sage
package. It depends on version 6.3 of Sage because it uses
<a class="reference external" href="http://www.sagemath.org/doc/reference/structure/sage/sets/recursively_enumerated_set.html">RecursivelyEnumeratedSet</a> code that was merged in 6.3.  It contains modules
on digital geometry, combinatorics on words and more.</p>
<p>Install the optional spkg (depends on sage-6.3):</p>


<div class="pygments_manni"><pre><span></span>sage -i http://www.liafa.univ-paris-diderot.fr/~labbe/Sage/slabbe-0.1.spkg
</pre></div>



<p>In each of the example below, you first have to import the module once and for
all:</p>


<div class="pygments_manni"><pre><span></span>sage: from slabbe import *
</pre></div>



<p>To construct the image below, make sure to use tikz package so that <tt class="docutils literal">view</tt> is
able to compile tikz code when called:</p>


<div class="pygments_manni"><pre><span></span>sage: latex.add_to_preamble(&quot;\\usepackage{tikz}&quot;)
sage: latex.extra_preamble()
&#39;\\usepackage{tikz}&#39;
</pre></div>



<div class="section" id="draw-the-part-of-a-discrete-plane">
<h1>Draw the part of a discrete plane</h1>


<div class="pygments_manni"><pre><span></span>sage: p = DiscretePlane([1,pi,7], 1+pi+7, mu=0)
sage: d = DiscreteTube([-5,5],[-5,5])
sage: I = p &amp; d
sage: I
Intersection of the following objects:
Set of points x in ZZ^3 satisfying: 0 &lt;= (1, pi, 7) . x + 0 &lt; pi + 8
DiscreteTube: Preimage of [-5, 5] x [-5, 5] by a 2 by 3 matrix
sage: clip = d.clip()
sage: tikz = I.tikz(clip=clip)
sage: view(tikz, tightpage=True)
</pre></div>



<a class="reference external image-reference" href="/Files/2014/discreteplane1pi7.png"><img alt="/Files/2014/discreteplane1pi7.png" src="/Files/2014/discreteplane1pi7.png" style="width: 20em;" /></a>
</div>
<div class="section" id="draw-the-part-of-a-discrete-line">
<h1>Draw the part of a discrete line</h1>


<div class="pygments_manni"><pre><span></span>sage: L = DiscreteLine([-2,3], 5)
sage: b = DiscreteBox([0,10], [0,10])
sage: I = L &amp; b
sage: I
Intersection of the following objects:
Set of points x in ZZ^2 satisfying: 0 &lt;= (-2, 3) . x + 0 &lt; 5
[0, 10] x [0, 10]
sage: I.plot()
</pre></div>



<a class="reference external image-reference" href="/Files/2014/discreteline23.png"><img alt="/Files/2014/discreteline23.png" src="/Files/2014/discreteline23.png" style="width: 20em;" /></a>
</div>
<div class="section" id="double-square-tiles">
<h1>Double square tiles</h1>
<p>This module was developped for the article on the combinatorial properties of
double square tiles written with Ariane Garon and Alexandre Blondin Massé
<a class="citation-reference" href="#bgl2012" id="citation-reference-1">[BGL2012]</a>. The original version of the code was written with Alexandre.</p>


<div class="pygments_manni"><pre><span></span>sage: D = DoubleSquare((34,21,34,21))
sage: D
Double Square Tile
  w0 = 3032321232303010303230301012101030   w4 = 1210103010121232121012123230323212
  w1 = 323030103032321232303                w5 = 101212321210103010121
  w2 = 2321210121232303232123230301030323   w6 = 0103032303010121010301012123212101
  w3 = 212323032321210121232                w7 = 030101210103032303010
(|w0|, |w1|, |w2|, |w3|) = (34, 21, 34, 21)
(d0, d1, d2, d3)         = (42, 68, 42, 68)
(n0, n1, n2, n3)         = (0, 0, 0, 0)
sage: D.plot()
</pre></div>



<a class="reference external image-reference" href="/Files/2014/fibo2.png"><img alt="/Files/2014/fibo2.png" src="/Files/2014/fibo2.png" style="width: 20em;" /></a>


<div class="pygments_manni"><pre><span></span>sage: D.extend(0).extend(1).plot()
</pre></div>



<a class="reference external image-reference" href="/Files/2014/fibo2extend0extend1.png"><img alt="/Files/2014/fibo2extend0extend1.png" src="/Files/2014/fibo2extend0extend1.png" style="width: 20em;" /></a>
<p>We have shown that using two invertible operations (called SWAP and TRIM),
every double square tiles can be reduced to the unit square:</p>


<div class="pygments_manni"><pre><span></span>sage: D.plot_reduction()
</pre></div>



<a class="reference external image-reference" href="/Files/2014/fibo2reduction.png"><img alt="/Files/2014/fibo2reduction.png" src="/Files/2014/fibo2reduction.png" style="width: 20em;" /></a>
<p>The reduction operations are:</p>


<div class="pygments_manni"><pre><span></span>sage: D.reduction()
[&#39;SWAP_1&#39;, &#39;TRIM_1&#39;, &#39;TRIM_3&#39;, &#39;SWAP_1&#39;, &#39;TRIM_1&#39;, &#39;TRIM_3&#39;, &#39;TRIM_0&#39;, &#39;TRIM_2&#39;]
</pre></div>



<p>The result of the reduction is the unit square:</p>


<div class="pygments_manni"><pre><span></span>sage: unit_square = D.apply(D.reduction())
sage: unit_square
Double Square Tile
  w0 =     w4 =
  w1 = 3   w5 = 1
  w2 =     w6 =
  w3 = 2   w7 = 0
(|w0|, |w1|, |w2|, |w3|) = (0, 1, 0, 1)
(d0, d1, d2, d3)         = (2, 0, 2, 0)
(n0, n1, n2, n3)         = (0, NaN, 0, NaN)
sage: unit_square.plot()
</pre></div>



<a class="reference external image-reference" href="/Files/2014/unit_square.png"><img alt="/Files/2014/unit_square.png" src="/Files/2014/unit_square.png" style="width: 20em;" /></a>
<p>Since SWAP and TRIM are invertible operations, we can recover every double
square from the unit square:</p>


<div class="pygments_manni"><pre><span></span>sage: E = unit_square.extend(2).extend(0).extend(3).extend(1).swap(1).extend(3).extend(1).swap(1)
sage: D == E
True
</pre></div>



</div>
<div class="section" id="christoffel-graphs">
<h1>Christoffel graphs</h1>
<p>This module was developped for the article on a d-dimensional extension of
Christoffel Words written with Christophe Reutenauer <a class="citation-reference" href="#lr2014" id="citation-reference-2">[LR2014]</a>.</p>


<div class="pygments_manni"><pre><span></span>sage: G = ChristoffelGraph((6,10,15))
sage: G
Christoffel set of edges for normal vector v=(6, 10, 15)
sage: tikz = G.tikz_kernel()
sage: view(tikz, tightpage=True)
</pre></div>



<a class="reference external image-reference" href="/Files/2014/christoffelgraph6_10_15.png"><img alt="/Files/2014/christoffelgraph6_10_15.png" src="/Files/2014/christoffelgraph6_10_15.png" style="width: 20em;" /></a>
</div>
<div class="section" id="bispecial-extension-types">
<h1>Bispecial extension types</h1>
<p>This module was developped for the article on the factor complexity of
infinite sequences genereated by substitutions written with Valérie Berthé
<a class="citation-reference" href="#bl2014" id="citation-reference-3">[BL2014]</a>.</p>
<p>The extension type of an ordinary bispecial factor:</p>


<div class="pygments_manni"><pre><span></span>sage: L = [(1,3), (2,3), (3,1), (3,2), (3,3)]
sage: E = ExtensionType1to1(L, alphabet=(1,2,3))
sage: E
  E(w)   1   2   3
   1             X
   2             X
   3     X   X   X
 m(w)=0, ordinary
sage: E.is_ordinaire()
True
</pre></div>



<p>Creation of a strong-weak pair of bispecial words from a neutral
<strong>not ordinaire</strong> word:</p>


<div class="pygments_manni"><pre><span></span>sage: p23 = WordMorphism({1:[1,2,3],2:[2,3],3:[3]})
sage: e = ExtensionType1to1([(1,2),(2,3),(3,1),(3,2),(3,3)], [1,2,3])
sage: e
  E(w)   1   2   3
   1         X
   2             X
   3     X   X   X
 m(w)=0, not ord.
sage: A,B = e.apply(p23)
sage: A
  E(3w)   1   2   3
    1
    2         X   X
    3     X   X   X
 m(w)=1, not ord.
sage: B
  E(23w)   1   2   3
    1          X
    2
    3              X
 m(w)=-1, not ord.
</pre></div>



</div>
<div class="section" id="fast-kolakoski-word">
<h1>Fast Kolakoski word</h1>
<p>This module was written for fun. It uses cython implementation inspired from
the 10 lines of C code written by Dominique Bernardi and shared during Sage
Days 28 in Orsay, France, in January 2011.</p>


<div class="pygments_manni"><pre><span></span>sage: K = KolakoskiWord()
sage: K
word: 1221121221221121122121121221121121221221...
sage: %time K[10^5]
CPU times: user 1.56 ms, sys: 7 µs, total: 1.57 ms
Wall time: 1.57 ms
1
sage: %time K[10^6]
CPU times: user 15.8 ms, sys: 30 µs, total: 15.8 ms
Wall time: 15.9 ms
2
sage: %time K[10^8]
CPU times: user 1.58 s, sys: 2.28 ms, total: 1.58 s
Wall time: 1.59 s
1
sage: %time K[10^9]
CPU times: user 15.8 s, sys: 12.4 ms, total: 15.9 s
Wall time: 15.9 s
1
</pre></div>



<p>This is much faster than the Python implementation available in Sage:</p>


<div class="pygments_manni"><pre><span></span>sage: K = words.KolakoskiWord()
sage: %time K[10^5]
CPU times: user 779 ms, sys: 25.9 ms, total: 805 ms
Wall time: 802 ms
1
</pre></div>



</div>
<div class="section" id="references">
<h1>References</h1>
<table class="docutils citation" frame="void" id="bgl2012" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-1">[BGL2012]</a></td><td>A. Blondin Massé, A. Garon, S. Labbé, Combinatorial properties
of double square tiles, <em>Theoretical Computer Science</em> 502 (2013) 98-117.
<a class="reference external" href="http://dx.doi.org/10.1016/j.tcs.2012.10.040">doi:10.1016/j.tcs.2012.10.040</a></td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="lr2014" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-2">[LR2014]</a></td><td>Labbé, Sébastien, and Christophe Reutenauer. A d-dimensional Extension of
Christoffel Words. <a class="reference external" href="http://arxiv.org/abs/1404.4021">arXiv:1404.4021</a> (April 15, 2014).</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="bl2014" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#citation-reference-3">[BL2014]</a></td><td>V. Berthé, S. Labbé, Factor Complexity of S-adic sequences
generated by the Arnoux-Rauzy-Poincaré Algorithm. <a class="reference external" href="http://arxiv.org/abs/1404.4189">arXiv:1404.4189</a> (April, 2014).</td></tr>
</tbody>
</table>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[Releasing slabbe, my own Sage package]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2014/08/releasing-slabbe-my-own-sage-package" />
    <id>http://www.slabbe.org/blogue/2014/08/releasing-slabbe-my-own-sage-package</id>
    <updated>2014-08-27T16:48:00Z</updated>
    <published>2014-08-27T16:48:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <category scheme="http://www.slabbe.org/blogue" term="slabbe spkg" />
    <summary type="html"><![CDATA[Releasing slabbe, my own Sage package]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2014/08/releasing-slabbe-my-own-sage-package"><![CDATA[<div class="document">
<p>Since two years I wrote thousands of line of private code for my own research.
Each module having between 500 and 2000 lines of code. The code which is the
more clean corresponds to code written in conjunction with research articles.
People who know me know that I systematically put docstrings and doctests in my
code to facilitate reuse of the code by myself, but also in the idea of sharing
it and eventually making it public.</p>
<p>I did not made that code into Sage because it was not mature enough. Also, when
I tried to make a complete module go into Sage (see <a class="reference external" href="http://trac.sagemath.org/ticket/13069">#13069</a> and <a class="reference external" href="http://trac.sagemath.org/ticket/13346">#13346</a>),
then the monstrous never evolving <a class="reference external" href="http://trac.sagemath.org/ticket/12224">#12224</a> became a dependency of the first
and the second was unofficially reviewed asking me to split it into smaller
chunks to make the review process easier. I never did it because I spent
already too much time on it (making a module 100% doctested takes time). Also,
the module was corresponding to a published article and I wanted to leave it
just like that.</p>
<p><strong>Getting new modules into Sage is hard</strong></p>
<p>In general, the introduction of a complete new module into Sage is hard
especially for beginners. Here are two examples I feel responsible for:
<a class="reference external" href="http://trac.sagemath.org/ticket/10519">#10519</a> is 4 years old and counting, the author <a class="reference external" href="http://trac.sagemath.org/ticket/10519#comment:67">has a new work and
responsabilities</a>; in <a class="reference external" href="http://trac.sagemath.org/ticket/12996">#12996</a>, the author was decouraged by the amount of
work given by the reviewers. There is a lot of things a beginner has to
consider to obtain a positive review. And even for a more advanced developper,
other difficulties arise. Indeed, a module introduces a lot of new functions
and it may also introduce a lot of new bugs... and Sage developpers are
sometimes reluctant to give it a positive review. And if it finally gets a
positive review, it is not available easily to normal users of Sage until the
next release of Sage.</p>
<p><strong>Releasing my own Sage package</strong></p>
<p>Still I felt the need around me to make my code public. But how? There are
people (a few of course but I know there are) who are interested in reproducing
computations and images done in my articles. This is why I came to the idea of
releasing my own Sage package containing my public research code. This way both
developpers and colleagues that are user of Sage but not developpers will be
able to install and use my code. This will make people more aware if there is
something useful in a module for them. And if one day, somebody tells me: &quot;this
should be in Sage&quot;, then I will be able to say : &quot;I agree! Do you want to
review it?&quot;.</p>
<p><strong>Old style Sage package</strong> vs <strong>New sytle git Sage package</strong></p>
<p>Then I had to chose between the old and the new style for Sage packages. I did
not like the new style, because</p>
<blockquote>
<ul class="simple">
<li>I wanted the history of my package to be independant of the history of Sage,</li>
<li>I wanted it to be as easy to install as <tt class="docutils literal">sage <span class="pre">-i</span> slabbe</tt>,</li>
<li>I wanted it to work on any recent enough version of Sage,</li>
<li>I wanted to be able to release a new version, give it to a colleague who
could install it right away without changing its own Sage (i.e., updating
the checksums).</li>
</ul>
</blockquote>
<p>Therefore, I choose the old style. I based my work on other optional Sage
packages, namely the <a class="reference external" href="http://sagemanifolds.obspm.fr/">SageManifolds</a> spkg and the <a class="reference external" href="http://www.risc.jku.at/research/combinat/risc/software/ore_algebra/index.php">ore_algebra</a> spkg.</p>
<p><strong>Content of the initial version</strong></p>
<p>The initial version of the slabbe Sage package has modules concerning four
topics: <em>Digital geometry</em>, <em>Combinatorics on words</em>, <em>Combinatorics</em> and
<em>Python class inheritance</em>.</p>
<a class="reference external image-reference" href="/Files/2014/slabbe_content.png"><img alt="/Files/2014/slabbe_content.png" src="/Files/2014/slabbe_content.png" style="width: 40em;" /></a>
<p>For installation or for release notes of the initial version of the spkg,
consult the slabbe spkg section of the <a class="reference external" href="/Sage">Sage</a> page of this website.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name>Sébastien Labbé</name>
      <uri>http://www.slabbe.org/blogue</uri>
    </author>
    <title type="html"><![CDATA[My status report at Sage Days 57 (RecursivelyEnumeratedSet)]]></title>
    <link rel="alternate" type="text/html" href="http://www.slabbe.org/blogue/2014/04/my-status-report-at-sage-days-57-recursivelyenumeratedset" />
    <id>http://www.slabbe.org/blogue/2014/04/my-status-report-at-sage-days-57-recursivelyenumeratedset</id>
    <updated>2014-04-11T17:15:00Z</updated>
    <published>2014-04-11T17:15:00Z</published>
    <category scheme="http://www.slabbe.org/blogue" term="sage" />
    <summary type="html"><![CDATA[My status report at Sage Days 57 (RecursivelyEnumeratedSet)]]></summary>
    <content type="html" xml:base="http://www.slabbe.org/blogue/2014/04/my-status-report-at-sage-days-57-recursivelyenumeratedset"><![CDATA[<div class="document">
<p>At Sage Days 57, I worked on the trac ticket <a class="reference external" href="http://trac.sagemath.org/ticket/6637">#6637</a>: <em>standardize the
interface to TransitiveIdeal and friends</em>. My patch proposes to replace
<tt class="docutils literal">TransitiveIdeal</tt> and <tt class="docutils literal">SearchForest</tt> by a new class called
<tt class="docutils literal">RecursivelyEnumeratedSet</tt> that would handle every case.</p>
<p>A set S is called recursively enumerable if there is an algorithm that
enumerates the members of S. We consider here the recursively enumerated
set that are described by some <tt class="docutils literal">seeds</tt> and a successor function <tt class="docutils literal">succ</tt>.
The successor function may have some structure (symmetric, graded, forest)
or not. Many kinds of iterators are provided: depth first search, breadth
first search or elements of given depth.</p>
<div class="section" id="transitiveideal-and-transitiveidealgraded">
<h1>TransitiveIdeal and TransitiveIdealGraded</h1>
<p>Consider the permutations of \(\{1,2,3\}\) and the poset generated by the
method <tt class="docutils literal">permutohedron_succ</tt>:</p>


<div class="pygments_manni"><pre><span></span>sage: P = Permutations(3)
sage: d = {p:p.permutohedron_succ() for p in P}
sage: S = Poset(d)
sage: S.plot()
</pre></div>



<a class="reference external image-reference" href="/Files/2014/poset_123.png"><img alt="/Files/2014/poset_123.png" src="/Files/2014/poset_123.png" /></a>
<p>The <tt class="docutils literal">TransitiveIdeal</tt> allows to generates all permutations from the identity
permutation using the method <tt class="docutils literal">permutohedron_succ</tt> as successor function:</p>


<div class="pygments_manni"><pre><span></span>sage: succ = attrcall(&quot;permutohedron_succ&quot;)
sage: seed = [Permutation([1,2,3])]
sage: T = TransitiveIdeal(succ, seed)
sage: list(T)
[[1, 2, 3], [2, 1, 3], [1, 3, 2], [2, 3, 1], [3, 2, 1], [3, 1, 2]]
</pre></div>



<p>Remark that the previous ordering is neither breadth first neither depth first.
It is a naive search because it stores the element to process in a set instead
of a queue or a stack.</p>
<p>Note that the method <tt class="docutils literal">permutohedron_succ</tt> produces a graded poset. Therefore,
one may use the <tt class="docutils literal">TransitiveIdealGraded</tt> class instead:</p>


<div class="pygments_manni"><pre><span></span>sage: T = TransitiveIdealGraded(succ, seed)
sage: list(T)
[[1, 2, 3], [2, 1, 3], [1, 3, 2], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
</pre></div>



<p>For <tt class="docutils literal">TransitiveIdealGraded</tt>, the enumeration is breadth first search.
Althougth, if you look at the code (version Sage 6.1.1 or earlier), we see that
this iterator do not make use of the graded hypothesis at all because the
<tt class="docutils literal">known</tt> set remembers every generated elements:</p>


<div class="pygments_manni"><pre><span></span><span class="n">current_level</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_generators</span>
<span class="n">known</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">current_level</span><span class="p">)</span>
<span class="n">depth</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">current_level</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">depth</span> <span class="o">&lt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_max_depth</span><span class="p">:</span>
    <span class="n">next_level</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
    <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">current_level</span><span class="p">:</span>
        <span class="k">yield</span> <span class="n">x</span>
        <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_succ</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">y</span> <span class="o">==</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">known</span><span class="p">:</span>
                <span class="k">continue</span>
            <span class="n">next_level</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
            <span class="n">known</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
    <span class="n">current_level</span> <span class="o">=</span> <span class="n">next_level</span>
    <span class="n">depth</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span>
</pre></div>



</div>
<div class="section" id="timings-for-transitiveideal">
<h1>Timings for TransitiveIdeal</h1>


<div class="pygments_manni"><pre><span></span>sage: succ = attrcall(&quot;permutohedron_succ&quot;)
sage: seed = [Permutation([1..5])]
sage: T = TransitiveIdeal(succ, seed)
sage: %time L = list(T)
CPU times: user 26.6 ms, sys: 1.57 ms, total: 28.2 ms
Wall time: 28.5 ms
</pre></div>





<div class="pygments_manni"><pre><span></span>sage: seed = [Permutation([1..8])]
sage: T = TransitiveIdeal(succ, seed)
sage: %time L = list(T)
CPU times: user 14.4 s, sys: 141 ms, total: 14.5 s
Wall time: 14.8 s
</pre></div>



</div>
<div class="section" id="timings-for-transitiveidealgraded">
<h1>Timings for TransitiveIdealGraded</h1>


<div class="pygments_manni"><pre><span></span>sage: seed = [Permutation([1..5])]
sage: T = TransitiveIdealGraded(succ, seed)
sage: %time L = list(T)
CPU times: user 25.3 ms, sys: 1.04 ms, total: 26.4 ms
Wall time: 27.4 ms
</pre></div>





<div class="pygments_manni"><pre><span></span>sage: seed = [Permutation([1..8])]
sage: T = TransitiveIdealGraded(succ, seed)
sage: %time L = list(T)
CPU times: user 14.5 s, sys: 85.8 ms, total: 14.5 s
Wall time: 14.7 s
</pre></div>



<p>In conlusion, use <tt class="docutils literal">TransitiveIdeal</tt> for naive search algorithm and use
<tt class="docutils literal">TransitiveIdealGraded</tt> for breadth search algorithm. Both class do not use
the graded hypothesis.</p>
</div>
<div class="section" id="recursively-enumerated-set-with-a-graded-structure">
<h1>Recursively enumerated set with a graded structure</h1>
<p>The new class <tt class="docutils literal">RecursivelyEnumeratedSet</tt> provides all iterators for each
case. The example below are for the graded case.</p>
<p>Depth first search iterator:</p>


<div class="pygments_manni"><pre><span></span>sage: succ = attrcall(&quot;permutohedron_succ&quot;)
sage: seed = [Permutation([1..5])]
sage: R = RecursivelyEnumeratedSet(seed, succ, structure=&#39;graded&#39;)
sage: it_depth = R.depth_first_search_iterator()
sage: [next(it_depth) for _ in range(5)]
[[1, 2, 3, 4, 5],
 [1, 2, 3, 5, 4],
 [1, 2, 5, 3, 4],
 [1, 2, 5, 4, 3],
 [1, 5, 2, 4, 3]]
</pre></div>



<p>Breadth first search iterator:</p>


<div class="pygments_manni"><pre><span></span>sage: it_breadth = R.breadth_first_search_iterator()
sage: [next(it_breadth) for _ in range(5)]
[[1, 2, 3, 4, 5],
 [1, 3, 2, 4, 5],
 [1, 2, 4, 3, 5],
 [2, 1, 3, 4, 5],
 [1, 2, 3, 5, 4]]
</pre></div>



<p>Elements of given depth iterator:</p>


<div class="pygments_manni"><pre><span></span>sage: list(R.elements_of_depth_iterator(9))
[[5, 4, 2, 3, 1], [4, 5, 3, 2, 1], [5, 3, 4, 2, 1], [5, 4, 3, 1, 2]]
sage: list(R.elements_of_depth_iterator(10))
[[5, 4, 3, 2, 1]]
</pre></div>



<p>Levels (a level is a set of elements of the same depth):</p>


<div class="pygments_manni"><pre><span></span>sage: R.level(0)
[[1, 2, 3, 4, 5]]
sage: R.level(1)
{[1, 2, 3, 5, 4], [1, 2, 4, 3, 5], [1, 3, 2, 4, 5], [2, 1, 3, 4, 5]}
sage: R.level(2)
{[1, 2, 4, 5, 3],
 [1, 2, 5, 3, 4],
 [1, 3, 2, 5, 4],
 [1, 3, 4, 2, 5],
 [1, 4, 2, 3, 5],
 [2, 1, 3, 5, 4],
 [2, 1, 4, 3, 5],
 [2, 3, 1, 4, 5],
 [3, 1, 2, 4, 5]}
sage: R.level(3)
{[1, 2, 5, 4, 3],
 [1, 3, 4, 5, 2],
 [1, 3, 5, 2, 4],
 [1, 4, 2, 5, 3],
 [1, 4, 3, 2, 5],
 [1, 5, 2, 3, 4],
 [2, 1, 4, 5, 3],
 [2, 1, 5, 3, 4],
 [2, 3, 1, 5, 4],
 [2, 3, 4, 1, 5],
 [2, 4, 1, 3, 5],
 [3, 1, 2, 5, 4],
 [3, 1, 4, 2, 5],
 [3, 2, 1, 4, 5],
 [4, 1, 2, 3, 5]}
sage: R.level(9)
{[4, 5, 3, 2, 1], [5, 3, 4, 2, 1], [5, 4, 2, 3, 1], [5, 4, 3, 1, 2]}
sage: R.level(10)
{[5, 4, 3, 2, 1]}
</pre></div>



</div>
<div class="section" id="recursively-enumerated-set-with-a-symmetric-structure">
<h1>Recursively enumerated set with a symmetric structure</h1>
<p>We construct a recursively enumerated set with symmetric structure and
depth first search for default enumeration algorithm:</p>


<div class="pygments_manni"><pre><span></span>sage: succ = lambda a: [(a[0]-1,a[1]), (a[0],a[1]-1), (a[0]+1,a[1]), (a[0],a[1]+1)]
sage: seeds = [(0,0)]
sage: C = RecursivelyEnumeratedSet(seeds, succ, structure=&#39;symmetric&#39;, algorithm=&#39;depth&#39;)
sage: C
A recursively enumerated set with a symmetric structure (depth first search)
</pre></div>



<p>In this case, depth first search is the default algorithm for iteration:</p>


<div class="pygments_manni"><pre><span></span>sage: it_depth = iter(C)
sage: [next(it_depth) for _ in range(10)]
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9)]
</pre></div>



<p>Breadth first search. This algorithm makes use of the symmetric structure and
remembers only the last two levels:</p>


<div class="pygments_manni"><pre><span></span>sage: it_breadth = C.breadth_first_search_iterator()
sage: [next(it_breadth) for _ in range(10)]
[(0, 0), (0, 1), (0, -1), (1, 0), (-1, 0), (-1, 1), (-2, 0), (0, 2), (2, 0), (-1, -1)]
</pre></div>



<p>Levels (elements of given depth):</p>


<div class="pygments_manni"><pre><span></span>sage: sorted(C.level(0))
[(0, 0)]
sage: sorted(C.level(1))
[(-1, 0), (0, -1), (0, 1), (1, 0)]
sage: sorted(C.level(2))
[(-2, 0), (-1, -1), (-1, 1), (0, -2), (0, 2), (1, -1), (1, 1), (2, 0)]
</pre></div>



</div>
<div class="section" id="timings-for-recursivelyenumeratedset">
<h1>Timings for <tt class="docutils literal">RecursivelyEnumeratedSet</tt></h1>
<p>We get same timings as for <tt class="docutils literal">TransitiveIdeal</tt> but it uses less memory so it
might be able to enumerate bigger sets:</p>


<div class="pygments_manni"><pre><span></span>sage: succ = attrcall(&quot;permutohedron_succ&quot;)
sage: seed = [Permutation([1..5])]
sage: R = RecursivelyEnumeratedSet(seed, succ, structure=&#39;graded&#39;)
sage: %time L = list(R)
CPU times: user 24.7 ms, sys: 1.33 ms, total: 26.1 ms
Wall time: 26.4 ms
</pre></div>





<div class="pygments_manni"><pre><span></span>sage: seed = [Permutation([1..8])]
sage: R = RecursivelyEnumeratedSet(seed, succ, structure=&#39;graded&#39;)
sage: %time L = list(R)
CPU times: user 14.5 s, sys: 70.2 ms, total: 14.5 s
Wall time: 14.6 s
</pre></div>



</div>
</div>
]]></content>
  </entry>
</feed>
