Coding of Polyhedron exchange transformations (PETs)

Coding of Polyhedron exchange transformations (PETs)

Coding of Z^2-actions given by a tuple of Polyhedron exchange transformations (PETs) and one polyhedron partition

EXAMPLES:

A polyhedron partition:

sage: from slabbe import PolyhedronPartition
sage: from slabbe import PolyhedronExchangeTransformation as PET

AUTHORS:

  • Sébastien Labbé, January 2020, initial version

class slabbe.coding_of_PETs.PETsCoding(PETs, partition)

Bases: object

Coding of a tuple of commuting PETs by a partition

INPUT:

  • PETs – tuple of PolyhedronExchangeTransformation

  • partition – polyhedron partition

EXAMPLES:

sage: from slabbe import PolyhedronPartition
sage: h = 1/3
sage: p = Polyhedron([(0,h),(0,1),(h,1)])
sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
sage: s = Polyhedron([(h,0), (1,0), (1,h)])
sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
sage: from slabbe import PolyhedronExchangeTransformation as PET
sage: base = identity_matrix(2)
sage: Re1 = PET.toral_translation(base, vector((2/3, 0)))
sage: Re2 = PET.toral_translation(base, vector((0, 1/4)))
sage: from slabbe import PETsCoding
sage: PETsCoding((Re1,Re2), P)
Coding of PETs (Polyhedron Exchange Transformation of
Polyhedron partition of 2 atoms with 2 letters
with translations {0: (2/3, 0), 1: (-1/3, 0)}, Polyhedron Exchange
Transformation of
Polyhedron partition of 2 atoms with 2 letters
with translations {0: (0, 1/4), 1: (0, -3/4)}) by partition
Polyhedron partition of 4 atoms with 4 letters
ambient_space()

TODO: Maybe we want to make the union with the ambient space of the PETs?

coincidence_patterns(sizes)

Return the coincidences for pattern of given shape.

INPUT:

  • sizes – tuple of integers

OUTPUT:

list of patterns

EXAMPLES:

sage: from slabbe import PolyhedronPartition
sage: h = 1/3
sage: p = Polyhedron([(0,h),(0,1),(h,1)])
sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
sage: s = Polyhedron([(h,0), (1,0), (1,h)])
sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
sage: from slabbe import PolyhedronExchangeTransformation as PET
sage: base = identity_matrix(2)
sage: Re1 = PET.toral_translation(base, vector((2/3, 0)))
sage: Re2 = PET.toral_translation(base, vector((0, 1/4)))
sage: from slabbe import PETsCoding
sage: X_P_R = PETsCoding((Re1,Re2), P)
sage: L21 = X_P_R.coincidence_patterns((2,1))
sage: L21
[((0,), (0,)), ((1,), (0,)), ((1,), (1,)), ((2,), (3,))]
sage: L12 = X_P_R.coincidence_patterns((1,2))
sage: L12
[((0, 2),), ((1, 2),), ((1, 3),), ((2, 0),), ((2, 1),), ((3, 1),)]

TESTS:

This should be all zero:

sage: [X_P_R.cylinder(p).volume() for p in L21]
[0, 0, 0, 0]
sage: [X_P_R.cylinder(p).volume() for p in L12]
[0, 0, 0, 0, 0, 0]
configuration(x0)
cylinder(pattern, include_empty_interior_atom=False)

Return the coding region of the pattern.

INPUT:

  • pattern – list of lists or dict of positions to code

  • include_empty_interior_atom – boolean (default:False), whether to include in the partition the atom that are not full dimensional (that is, points, lines, etc.)

OUTPUT:

polyhedron partition (containing probably only one atom, or more to handle the case of union of polyhedrons)

EXAMPLES:

sage: from slabbe import PolyhedronPartition
sage: h = 1/3
sage: p = Polyhedron([(0,h),(0,1),(h,1)])
sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
sage: s = Polyhedron([(h,0), (1,0), (1,h)])
sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
sage: from slabbe import PolyhedronExchangeTransformation as PET
sage: base = identity_matrix(2)
sage: Re1 = PET.toral_translation(base, vector((2/3, 0)))
sage: Re2 = PET.toral_translation(base, vector((0, 1/4)))
sage: from slabbe import PETsCoding
sage: X_P_R = PETsCoding((Re1,Re2), P)
sage: pattern = [[1, 1, 0, 0, 1], [3, 2, 2, 2, 3], [2, 2, 2, 2, 2]]
sage: C = X_P_R.cylinder(pattern)
sage: C
Polyhedron partition of 1 atoms with 1 letters
sage: atom = C.atoms()[0]
sage: atom
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 6 vertices
sage: atom.vertices()
(A vertex at (1/9, 1/18),
 A vertex at (5/24, 1/4),
 A vertex at (0, 0),
 A vertex at (1/6, 1/4),
 A vertex at (1/18, 7/36),
 A vertex at (0, 1/12))
sage: v = vector((1/7, 1/7))
sage: v.set_immutable()
sage: v in atom
True
partition_for_patterns(sizes, include_empty_interior_atom=False)

Return the coding region of the pattern.

INPUT:

  • sizes – tuple of integers

  • include_empty_interior_atom – boolean (default:False), whether to include in the partition the atom that are not full dimensional (that is, points, lines, etc.)

OUTPUT:

  • polyhedron partition (containing probably only one atom, or more to handle the case of union of polyhedrons)

  • dictionnary, key to patterns (tuple of tuples)

EXAMPLES:

sage: from slabbe import PolyhedronPartition
sage: h = 1/3
sage: p = Polyhedron([(0,h),(0,1),(h,1)])
sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
sage: s = Polyhedron([(h,0), (1,0), (1,h)])
sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
sage: from slabbe import PolyhedronExchangeTransformation as PET
sage: base = identity_matrix(2)
sage: Re1 = PET.toral_translation(base, vector((2/3, 0)))
sage: Re2 = PET.toral_translation(base, vector((0, 1/4)))
sage: from slabbe import PETsCoding
sage: X_P_R = PETsCoding((Re1,Re2), P)
sage: X_P_R.partition_for_patterns((2,2))
(Polyhedron partition of 24 atoms with 24 letters,
{0: ((0, 0), (2, 2)),
 1: ((0, 1), (2, 2)),
 2: ((0, 1), (2, 3)),
 3: ((1, 0), (2, 2)),
 4: ((1, 0), (3, 2)),
 5: ((1, 1), (2, 2)),
 6: ((1, 1), (3, 2)),
 7: ((1, 1), (3, 3)),
 8: ((1, 1), (2, 3)),
 9: ((2, 2), (0, 0)),
 10: ((2, 2), (1, 0)),
 11: ((2, 2), (1, 1)),
 12: ((2, 2), (2, 2)),
 13: ((2, 2), (0, 1)),
 14: ((2, 2), (1, 1)),
 15: ((2, 2), (2, 2)),
 16: ((2, 3), (0, 1)),
 17: ((2, 3), (1, 1)),
 18: ((2, 3), (2, 2)),
 19: ((2, 3), (2, 3)),
 20: ((3, 2), (1, 1)),
 21: ((3, 2), (2, 2)),
 22: ((3, 2), (3, 2)),
 23: ((3, 3), (3, 2))})
sage: X_P_R.partition_for_patterns((1,3))
(Polyhedron partition of 18 atoms with 18 letters,
{0: ((0, 0, 0),),
 1: ((0, 0, 1),),
 2: ((0, 1, 0),),
 3: ((0, 1, 1),),
 4: ((1, 0, 0),),
 5: ((1, 0, 1),),
 6: ((1, 1, 0),),
 7: ((1, 1, 1),),
 8: ((1, 1, 1),),
 9: ((1, 1, 1),),
 10: ((2, 2, 2),),
 11: ((2, 2, 2),),
 12: ((2, 2, 2),),
 13: ((2, 2, 3),),
 14: ((2, 3, 2),),
 15: ((2, 3, 3),),
 16: ((3, 2, 2),),
 17: ((3, 3, 2),)})
pattern(x0, sizes)

Return the pattern obtained as the coding of the orbit of some starting point by the application of the PETs a certain number of times given by the tuple of sizes.

TODO: add a input direction when the point lies in more than one atoms

INPUT:

  • x0 – point in the domain of the partition

  • sizes – tuple of integers

OUTPUT:

list of lists (using cartesian coordinates)

EXAMPLES:

sage: from slabbe import PolyhedronPartition
sage: h = 1/3
sage: p = Polyhedron([(0,h),(0,1),(h,1)])
sage: q = Polyhedron([(0,0), (0,h), (h,1), (h,0)])
sage: r = Polyhedron([(h,1), (1,1), (1,h), (h,0)])
sage: s = Polyhedron([(h,0), (1,0), (1,h)])
sage: P = PolyhedronPartition({0:p, 1:q, 2:r, 3:s})
sage: from slabbe import PolyhedronExchangeTransformation as PET
sage: base = identity_matrix(2)
sage: Re1 = PET.toral_translation(base, vector((2/3, 0)))
sage: Re2 = PET.toral_translation(base, vector((0, 1/4)))
sage: from slabbe import PETsCoding
sage: X_P_R = PETsCoding((Re1,Re2), P)
sage: X_P_R.pattern((1/7,1/7), (3,5))
[[1, 1, 0, 0, 1], [3, 2, 2, 2, 3], [2, 2, 2, 2, 2]]

When the point lies on the boundary, it currently raises an error:

sage: X_P_R.pattern((0,0), (3,5))
Traceback (most recent call last):
...
ValueError: polyhedron p whose vertices are (A vertex at (0, 3/4),)
lies in more than one atoms (=[0, 1])
to_wang_tiles()

Recover the Wang tile sets associated to the atoms of the partition.

EXAMPLES:

sage: from slabbe import PolyhedronExchangeTransformation as PET
sage: from slabbe.arXiv_1903_06137 import self_similar_19_atoms_partition
sage: from slabbe import PETsCoding
sage: z = polygen(QQ, 'z')
sage: K.<phi> = NumberField(z**2-z-1, 'phi', embedding=RR(1.6))
sage: Gamma0 = matrix.column([(1,0), (0,1)])
sage: PU = self_similar_19_atoms_partition()
sage: RUe1 = PET.toral_translation(Gamma0, vector((phi^-2,0)))
sage: RUe2 = PET.toral_translation(Gamma0, vector((0,phi^-2)))
sage: X_PU_RU = PETsCoding((RUe1,RUe2), PU)
sage: TU = X_PU_RU.to_wang_tiles()
sage: TU
Wang tile set of cardinality 19

For some reason (the partition PU should be simplified by removing one vertical at x==phi^-1 as noticed by Jana), we need to merge colors 2,6 and 4,0:

sage: horiz_merge = {a:a for a in '01234567'}
sage: horiz_merge.update({'6':'2','4':'0'})
sage: tiles = [(E,horiz_merge[N],W,horiz_merge[S]) for (E,N,W,S) in TU.tiles()]
sage: from slabbe import WangTileSet
sage: TU = WangTileSet(tiles)

We compare the above computed one with the original one:

sage: tiles = ["FOJO", "FOHL", "JMFP", "DMFK", "HPJP", "HPHN", "HKFP", "HKDP",
....:          "BOIO", "GLEO", "GLCL", "ALIO", "EPGP", "EPIP", "IPGK", "IPIK",
....:          "IKBM", "IKAK", "CNIP"]
sage: U = WangTileSet([tuple(tile) for tile in tiles])
sage: TU.is_equivalent(U)
True