$$\def\CC{\bf C} \def\QQ{\bf Q} \def\RR{\bf R} \def\ZZ{\bf Z} \def\NN{\bf N}$$

# Rauzy induction of polygon partitions and toral $\mathbb{Z}^2$-rotations¶

This file contains the Sage code contained in the preprints:

The Jupyter notebook arXiv_1906_01104.ipynb is created from arXiv_1906_01104.rst with the command sage -rst2ipynb arXiv_1906_01104.rst arXiv_1906_01104.ipynb plus few manual modifications to include the figures of partitions.

The file arXiv_1906_01104.rst is in the slabbe/demos directory of the optional SageMath package slabbe.

Running all examples below with sage -t arXiv_1906_01104.rst takes 10 seconds with sage-9.1 and slabbe-0.6.1.

Polyhedron exchange transformations and induction of polyhedron partitions are implemented in the optional package slabbe:

In [1]:
from slabbe import PolyhedronPartition
from slabbe import PolyhedronExchangeTransformation as PET
from slabbe import Substitution2d


First we construct the golden mean as a element of a quadratic number field because it is more efficient for arithmetic operations and comparisons:

In [2]:
z = polygen(QQ, 'z')
K = NumberField(z**2-z-1, 'phi', embedding=RR(1.6))
phi = K.gen()


The following defines the lattice $\Gamma_0$ and $\mathbb{Z}^2$-action $R_0$ on $\mathbb{R}^2/\Gamma_0$

In [3]:
Gamma0 = matrix.column([(phi,0), (1,phi+3)])
fundamental_domain = polytopes.parallelotope([(phi,0), (0,phi+3)])
R0e1 = PET.toral_translation(Gamma0, vector((1,0)), fundamental_domain)
R0e2 = PET.toral_translation(Gamma0, vector((0,1)), fundamental_domain)


The following allows to define the partition $\mathcal{P}_0$ of $\mathbb{R}^2/\Gamma_0$ :

In [4]:
from slabbe.arXiv_1903_06137 import jeandel_rao_wang_shift_partition
P0 = jeandel_rao_wang_shift_partition()
P0

Out[4]:
Polyhedron partition of 24 atoms with 11 letters
In [5]:
P0.plot()

Out[5]:

The following allows to compute the induced partition $\mathcal{P}_1$ of $\mathbb{R}^2/\Gamma_1$, the substitution $\beta_0$ and the $\mathbb{Z}^2$-action $R_1$ on $\mathbb{R}^2/\Gamma_1$.

In [6]:
y_le_1 = [1, 0, -1]   # syntax for the inequality y <= 1
P1,beta0 = R0e2.induced_partition(y_le_1, P0, substitution_type='column')
R1e1,_ = R0e1.induced_transformation(y_le_1)
R1e2,_ = R0e2.induced_transformation(y_le_1)

In [7]:
R1e1

Out[7]:
Polyhedron Exchange Transformation of
Polyhedron partition of 2 atoms with 2 letters
with translations {0: (1, 0), 1: (-phi + 1, 0)}
In [8]:
R1e1.plot()

Out[8]:
In [9]:
R1e2

Out[9]:
Polyhedron Exchange Transformation of
Polyhedron partition of 4 atoms with 4 letters
with translations {0: (phi - 1, -phi + 1), 1: (-1, -phi + 1), 2: (phi - 1, -phi + 2), 3: (-1, -phi + 2)}
In [10]:
R1e2.plot()

Out[10]:
In [11]:
P1

Out[11]:
Polyhedron partition of 30 atoms with 28 letters
In [12]:
P1.plot()

Out[12]:
In [13]:
show(beta0)


We keep $\mathcal{P}_2$, $\Gamma_2$ equal to $\mathcal{P}_1$, $\Gamma_1$ and we change the base of the action to get the $\mathbb{Z}^2$-action $R_2$ on $\mathbb{R}^2/\Gamma_2$.

In [14]:
Gamma2 = Gamma1 = matrix.column([(phi,0), (0,1)])
P2 = P1
R2e1 = R1e1
R2e2 = (R1e1 * R1e2).merge_atoms_with_same_translation()


The following confirms that the $R_2^{\boldsymbol{e}_2}$ is now a vertical rotation on the torus $\mathbb{R^2}/\Gamma_2$:

In [15]:
R2e2

Out[15]:
Polyhedron Exchange Transformation of
Polyhedron partition of 2 atoms with 2 letters
with translations {0: (0, -phi + 1), 1: (0, -phi + 2)}
In [16]:
R2e2.plot()

Out[16]:

The following allows to compute the induced partition $\mathcal{P}_3$ of $\mathbb{R}^2/\Gamma_3$, the substitution $\beta_2$ and the $\mathbb{Z}^2$-action $R_3$ on $\mathbb{R}^2/\Gamma_3$.

In [17]:
x_le_1 = [1, -1, 0]   # syntax for x <= 1
P3,beta2 = R2e1.induced_partition(x_le_1, P2, substitution_type='row')
R3e1,_ = R2e1.induced_transformation(x_le_1)
R3e2,_ = R2e2.induced_transformation(x_le_1)
R3e1

Out[17]:
Polyhedron Exchange Transformation of
Polyhedron partition of 2 atoms with 2 letters
with translations {0: (-phi + 1, 0), 1: (-phi + 2, 0)}
In [18]:
P3

Out[18]:
Polyhedron partition of 21 atoms with 20 letters
In [19]:
P3.plot()

Out[19]:
In [20]:
show(beta2)


The following allows to compute the induced partition $\mathcal{P}_4$ of $\mathbb{R}^2/\Gamma_4$, the substitution $\beta_3$ and the $\mathbb{Z}^2$-action $R_4$ on $\mathbb{R}^2/\Gamma_4$

In [21]:
x_le_phi_inv = [phi^-1, -1, 0]    # syntax for x <= phi^-1
P4,beta3 = R3e1.induced_partition(x_le_phi_inv, P3, substitution_type='row')
R4e1,_ = R3e1.induced_transformation(x_le_phi_inv)
R4e2,_ = R3e2.induced_transformation(x_le_phi_inv)
R4e2

Out[21]:
Polyhedron Exchange Transformation of
Polyhedron partition of 2 atoms with 2 letters
with translations {0: (0, -phi + 1), 1: (0, -phi + 2)}
In [22]:
P4

Out[22]:
Polyhedron partition of 21 atoms with 20 letters
In [23]:
P4.plot()

Out[23]:
In [24]:
show(beta3)


The following allows to compute the induced partition $\mathcal{P}_5$ of $\mathbb{R}^2/\Gamma_5$, the substitution $\beta_4$ and the $\mathbb{Z}^2$-action $R_5$ on $\mathbb{R}^2/\Gamma_5$.

In [25]:
y_le_phi_inv = [phi^-1, 0, -1]    # syntax for y <= phi^-1
P5,beta4 = R4e2.induced_partition(y_le_phi_inv, P4, substitution_type='column')
R5e1,_ = R4e1.induced_transformation(y_le_phi_inv)
R5e2,_ = R4e2.induced_transformation(y_le_phi_inv)
P5

Out[25]:
Polyhedron partition of 22 atoms with 22 letters
In [26]:
P5.plot()

Out[26]:
In [27]:
show(beta4)


We rescale the partition $\mathcal{P}_5$ :

In [28]:
P5_scaled = (-phi*P5).translate((1,1))
R5e1_scaled = (-phi*R5e1).translate_domain((1,1))
R5e2_scaled = (-phi*R5e2).translate_domain((1,1))

In [29]:
P5_scaled.plot()

Out[29]:

The following allows to compute the induced partition $\mathcal{P}_6$ of $\mathbb{R}^2/\Gamma_6$, the substitution $\beta_5$ and the $\mathbb{Z}^2$-action $R_6$ on $\mathbb{R}^2/\Gamma_6$.

In [30]:
P6,beta5 = R5e1_scaled.induced_partition(x_le_phi_inv, P5_scaled, substitution_type='row')
R6e1,_ = R5e1_scaled.induced_transformation(x_le_phi_inv)
R6e2,_ = R5e2_scaled.induced_transformation(x_le_phi_inv)
P6

Out[30]:
Polyhedron partition of 18 atoms with 18 letters
In [31]:
P6.plot()

Out[31]:
In [32]:
show(beta5)


The following allows to compute the induced partition $\mathcal{P}_7$ of $\mathbb{R}^2/\Gamma_7$, the substitution $\beta_6$ and the $\mathbb{Z}^2$-action $R_7$ on $\mathbb{R}^2/\Gamma_7$.

In [33]:
P7,beta6 = R6e2.induced_partition(y_le_phi_inv, P6, substitution_type='column')
R7e1,_ = R6e1.induced_transformation(y_le_phi_inv)
R7e2,_ = R6e2.induced_transformation(y_le_phi_inv)
P7

Out[33]:
Polyhedron partition of 21 atoms with 21 letters
In [34]:
P7.plot()

Out[34]:
In [35]:
show(beta6)


We rescale the partition $\mathcal{P}_7$ :

In [36]:
P7_scaled = (-phi*P7).translate((1,1))
R7e1_scaled = (-phi*R7e1).translate_domain((1,1))
R7e2_scaled = (-phi*R7e2).translate_domain((1,1))

In [37]:
P7_scaled.plot()

Out[37]:

The following allows to compute the induced partition $\mathcal{P}_8$ of $\mathbb{R}^2/\Gamma_8$, the substitution $\beta_7$ and the $\mathbb{Z}^2$-action $R_8$ on $\mathbb{R}^2/\Gamma_8$.

In [38]:
P8,beta7 = R7e1_scaled.induced_partition(x_le_phi_inv, P7_scaled, substitution_type='row')
R8e1,_ = R7e1_scaled.induced_transformation(x_le_phi_inv)
R8e2,_ = R7e2_scaled.induced_transformation(x_le_phi_inv)
P8

Out[38]:
Polyhedron partition of 19 atoms with 19 letters
In [39]:
P8.plot()

Out[39]:
In [40]:
show(beta7)


The following allows to compute the induced partition $\mathcal{P}_9$ of $\mathbb{R}^2/\Gamma_9$, the substitution $\beta_8$ and the $\mathbb{Z}^2$-action $R_9$ on $\mathbb{R}^2/\Gamma_9$.

In [41]:
P9,beta8 = R8e2.induced_partition(y_le_phi_inv, P8, substitution_type='column')
R9e1,_ = R8e1.induced_transformation(y_le_phi_inv)
R9e2,_ = R8e2.induced_transformation(y_le_phi_inv)
P9

Out[41]:
Polyhedron partition of 21 atoms with 21 letters
In [42]:
P9.plot()

Out[42]:
In [43]:
show(beta8)


We rescale the partition $\mathcal{P}_9$ :

In [44]:
P9_scaled = (-phi*P9).translate((1,1))
R9e1_scaled = (-phi*R9e1).translate_domain((1,1))
R9e2_scaled = (-phi*R9e2).translate_domain((1,1))

In [45]:
P9_scaled.plot()

Out[45]:

The following allows to compute the induced partition $\mathcal{P}_{10}$ of $\mathbb{R}^2/\Gamma_{10}$, the substitution $\beta_9$ and the $\mathbb{Z}^2$-action $R_{10}$ on $\mathbb{R}^2/\Gamma_{10}$.

In [46]:
P10,beta9 = R9e1_scaled.induced_partition(x_le_phi_inv, P9_scaled, substitution_type='row')
R10e1,_ = R9e1_scaled.induced_transformation(x_le_phi_inv)
R10e2,_ = R9e2_scaled.induced_transformation(x_le_phi_inv)
P10

Out[46]:
Polyhedron partition of 19 atoms with 19 letters
In [47]:
P10.plot()

Out[47]:
In [48]:
show(beta9)


We show that $\mathcal{P}_8$ and $\mathcal{P}_{10}$ are equivalent:

In [49]:
P8 == P10

Out[49]:
True
In [50]:
tau = Substitution2d.from_permutation(P8.keys_permutation(P10))
show(tau)

In [51]:
show(beta8*beta9*tau)    # the self-similarity for P8


We may check that the self-similarity for $\mathcal{P}_8$ satisfies $\zeta^{-1}\beta_8\beta_9\tau\zeta=\beta_{\mathcal{U}}$.

In [52]:
zeta = Substitution2d.from_permutation({0:0, 1:1, 2:9, 3:7, 4:8, 5:11, 6:10,
7:6, 8:2, 9:4, 10:5, 11:3, 12:18, 13:14, 14:16, 15:13, 16:12, 17:17, 18:15})
betaU = Substitution2d({0: [[17]], 1: [[16]], 2: [[15], [11]], 3: [[13], [9]], 4: [[17], [8]], 5: [[16], [8]], 6: [[15], [8]], 7: [[14], [8]], 8: [[14, 6]], 9: [[17, 3]], 10: [[16, 3]], 11: [[14, 2]], 12: [[15, 7], [11, 1]], 13: [[14, 6], [11, 1]], 14: [[13, 7], [9, 1]], 15: [[12, 6], [9, 1]], 16: [[18, 5], [10, 1]], 17: [[13, 4], [9, 1]], 18: [[14, 2], [8, 0]]})
show(betaU)

In [53]:
zeta.inverse()*beta8*beta9*tau*zeta  == betaU

Out[53]:
True