Cut and Project Scheme¶
Cut and project schemes and model sets
Based on the definitions presented in the book [BG13].
AUTHORS:
Sébastien Labbé, initial version + first plot method, February 2023 (Sage Days 117, Le Teich)
Carole Porrier and Sébastien Labbé, creation of cut-and-project from slopes, Golden-Octagonal, Ammann-Beenker, subperiods, February 2025 (Sage Days 128, Le Teich)
REFERENCES:
Baake, Michael, Uwe Grimm. Aperiodic order. Vol. 1. Vol. 149. Encyclopedia of Mathematics and its Applications. Cambridge University Press, Cambridge, 2013.
- class slabbe.cut_and_project_scheme.CutAndProjectScheme(base_ring, pi, pi_int, lattice=None, check=True)¶
Bases:
SageObject
INPUT:
base_ring
– ringpi
– \(n\times d\) matrix, projection of the ambiant space tothe physical space
pi_int
– \(n\times (n-d)\) matrix, projection of the ambiant spaceto the internal space
lattice
– \(n\times n\) matrix (default:None
), the columns form a base of a lattice in R^n, ifNone
, it uses the \(n\times n\) identity matrixcheck
– boolean (default:True
), whether to check thatdimensions of the matrices given as input are consistent
EXAMPLES:
sage: from slabbe import CutAndProjectScheme sage: z = polygen(QQ, 'z') sage: K = NumberField(z**2-z-1, 'phi', embedding=RR(1.6)) sage: phi = K.gen() sage: pi = matrix([[phi, 1]]) sage: pi_int = matrix([[-~phi, 1]]) sage: lattice = identity_matrix(2) sage: cap = CutAndProjectScheme(K, pi, pi_int, lattice)
- ambiant_space()¶
Return the ambiant space
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.ambiant_space() Ambient free module of rank 2 over the principal ideal domain Integer Ring
- ambiant_space_dimension()¶
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.ambiant_space_dimension() 2
- base_ring()¶
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.base_ring() Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895?
- canonical_model_set(intervals='zero_one', shift=None)¶
Return the canoncial model set using a hypercube as window after projection in the internal space.
INPUT:
intervals
– (default:'zero_one'
) intervals defining the hypercubeshift
– \(n\)-dimensional vector translating the internal window to avoid singular tilings and Conway worms, where \(n\) is the dimension of the ambiant space
EXAMPLES:
sage: from slabbe import CutAndProjectScheme sage: E = matrix([[1,1,1,1], [1,2,3,4]]) sage: c = CutAndProjectScheme.from_slope(E) sage: m = c.canonical_model_set() sage: m Model Set of a 4-to-2 cut and project scheme
Golden-Octagonal:
sage: z = polygen(QQ, 'z') sage: K = NumberField(z**2-z-1, 'phi', embedding=RR(1.6)) sage: phi = K.gen() sage: E = matrix([[-1,0,phi,phi], [0,1,phi,1]]) sage: c = CutAndProjectScheme.from_slope(E) sage: m = c.canonical_model_set() sage: m Model Set of a 4-to-2 cut and project scheme
With shift:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.Penrose() sage: shift = vector((1,-1,2,-1,-1)) / 1000 sage: c.canonical_model_set(shift=shift) Model Set of a 5-to-2 cut and project scheme
TESTS:
sage: c = cut_and_project_schemes.GoldenOctagonal(projection='roots_of_unity') sage: m = c.canonical_model_set(shift=None)
- change_physical_projection(pi)¶
- classmethod from_slope(E, projection='gram_schmidt', verbose=False)¶
Compute the orthogonal projection on the internal space (orthogonal of the slope)
The slope refers to vector space in the ambiant space corresponding to kernel of the pi_int projection [FP24].
The construction of the projection in the internal space from the slope using Gramm-Schmidt is made acording to Carole Porrier’s code available at https://github.com/cporrier/Cyrenaic
INPUT:
E
– matrix, whose rows span the slopeprojection
– string (default:'gram_schmidt'
), possible values are'gram_schmidt'
and'roots_of_unity'
(works only for n->2 tilings)verbose
– bool (default:False
)
OUTPUT:
A cut and project scheme whose kernel of the internal projection is the vector space E.
EXAMPLES:
sage: from slabbe import CutAndProjectScheme sage: E = matrix([[1,1,1,1], [1,2,3,4]]) sage: E [1 1 1 1] [1 2 3 4] sage: c = CutAndProjectScheme.from_slope(E) sage: c 4-to-2 cut and project scheme sage: print(c) 4-to-2 cut and project scheme over Rational Field Projection to physical space: [ 1 1 1 1] [-3/2 -1/2 1/2 3/2] Projection to internal space: [ 1 0 -3 2] [-4/7 1 -2/7 -1/7] Lattice generated by the columns of: [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]
sage: E = matrix([[1,1,1,1], [1,2,3,4]]) sage: c = CutAndProjectScheme.from_slope(E, projection='roots_of_unity')
REFERENCES:
[FP24] (1,2)Thomas Fernique, Carole Porrier, Ammann Bars for Octagonal Tilings, Discrete Mathematics & Theoretical Computer Science 26 (2024), https://doi.org/10.46298/dmtcs.10764
- internal_space()¶
Return the internal space
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.internal_space() Vector space of dimension 1 over Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895?
- internal_space_dimension()¶
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.internal_space_dimension() 1
- internal_space_projection()¶
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.internal_space_projection() [-phi + 1 1]
- is_determined_by_subperiods()¶
Return whether the slope of the cut-and-project scheme is determined by the subperiods.
A subperiod is a vector of n entries where \(d+1\) are integers [BF2015].
The computation made below comes from Carole Porrier’s code available at https://github.com/cporrier/Cyrenaic
OUTPUT:
todo
EXAMPLES:
The Penrose hull is determined by its subperiods:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.Penrose() sage: c.is_determined_by_subperiods() True
Ammann-Beenker is not determined by its subperiods:
sage: c = cut_and_project_schemes.AmmannBeenker() sage: c.is_determined_by_subperiods() False
Jeandel-Rao seems not to be determined by its subperiods (?):
sage: c = cut_and_project_schemes.JeandelRao() sage: c.is_determined_by_subperiods() False
- is_orthogonal()¶
Return whether the two projections are orthogonal.
TODO: Is this the good name for this method?
EXAMPLES:
sage: from slabbe import CutAndProjectScheme sage: E = matrix([[1,1,1,1], [1,2,3,4]]) sage: c = CutAndProjectScheme.from_slope(E) sage: c.is_orthogonal() True
- is_valid(projection=None, verbose=False)¶
Return True if the physical space projection is valid.
A projection is valid if the rhombi do not overlap after projection in the physical space, that is, tiles do not create accordions in the physical space [H2004].
The computation of the validity made below comes from Carole Porrier’s code available at https://github.com/cporrier/Cyrenaic
Note
The current code checks that the orientation of the projection of each pair of vectors is the same in the slope and after projection in the physical space.
INPUT:
projection
– matrix (default:None
), ifNone
it uses the physical space projectionverobse
– bool (default:False
)
OUTPUT:
boolean
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.Penrose() sage: c.is_valid() True
REFERENCE:
[H2004]Edmund Harriss, On canonical substitution tilings, Ph. D. Thesis, Univeristy of London, 2004.
- lattice()¶
Return the lattice
OUTPUT:
a matrix whose columns generate the lattice
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.lattice() [1 0] [0 1]
- lattice_base()¶
Return the lattice base
OUTPUT:
a matrix whose columns generate the lattice
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.lattice_base() [(1, 0), (0, 1)]
- lattice_neighbors(v)¶
Return the neighbors of a point according to the base of the lattice
INPUT:
v
– tuple or vector, in the ambiant space
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: v = vector((10, 10)) sage: cap.lattice_neighbors(v) [(11, 10), (10, 11), (9, 10), (10, 9)]
- orthogonal_physical_projection_cut_and_project_scheme()¶
EXAMPLES:
sage: # TODO
- physical_space()¶
Return the physical space
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.physical_space() Vector space of dimension 1 over Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895?
- physical_space_dimension()¶
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.physical_space_dimension() 1
- physical_space_projection()¶
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cap = cut_and_project_schemes.Fibonacci() sage: cap.physical_space_projection() [ 1 phi - 1]
- shadow_periods()¶
Return the periods of the shadows of the cut and project scheme.
A shadow period is the integer entries of a subperiod of the cut and project scheme [BF2015].
A subperiod is a vector of n entries where \(d+1\) are integers.
The computation of the shadow periods made below comes from Carole Porrier’s code available at https://github.com/cporrier/Cyrenaic
OUTPUT:
list of pairs (t,s) where t is a tuple of indices where the entries are integers equal to s
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.Penrose() sage: c.shadow_periods() [((0, 1, 2), (1, 0, -1)), ((0, 1, 3), (1, -1, 0)), ((0, 1, 4), (0, 1, -1)), ((0, 2, 3), (0, 1, -1)), ((0, 2, 4), (1, 0, -1)), ((0, 3, 4), (1, -1, 0)), ((1, 2, 3), (1, 0, -1)), ((1, 2, 4), (1, -1, 0)), ((1, 3, 4), (0, 1, -1)), ((2, 3, 4), (1, 0, -1))]
sage: c = cut_and_project_schemes.JeandelRao() sage: c.shadow_periods() [((0, 1, 2), (1, 3, 5)), ((0, 1, 3), (0, 1, 1)), ((0, 2, 3), (1, 0, 0)), ((1, 2, 3), (1, 0, 0))]
REFERENCE:
[BF2015] (1,2,3)Bédaride, Nicolas, et Thomas Fernique. « When Periodicities Enforce Aperiodicity ». Communications in Mathematical Physics 335, nᵒ 3 (1 mai 2015): 1099‑1120. https://doi.org/10.1007/s00220-015-2334-8.
- slope()¶
Return the slope of the cut-and project scheme.
The slope refers to vector space in the ambiant space corresponding to kernel of the pi_int projection [FP24].
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.Penrose() sage: slope = c.slope(); slope Vector space of degree 5 and dimension 2 over Number Field in a with defining polynomial z^4 - 5*z^2 + 5 with a = 1.175570504584947? Basis matrix: [ 1 0 -1 a^2 - 2 -a^2 + 2] [ 0 1 -a^2 + 2 a^2 - 2 -1] sage: slope.matrix().n(digits=5) [ 1.0000 0.00000 -1.0000 -0.61803 0.61803] [ 0.00000 1.0000 0.61803 -0.61803 -1.0000]
sage: c = cut_and_project_schemes.JeandelRao() sage: c.slope() Vector space of degree 4 and dimension 2 over Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895? Basis matrix: [ 1 0 -3*phi - 1 -phi] [ 0 1 phi + 2 1]
- star_map()¶
- subperiods()¶
Return the subperiods of the cut and project scheme.
A subperiod is a vector of n entries where \(d+1\) are integers [BF2015].
The computation of the subperiods made below comes from Carole Porrier’s code available at https://github.com/cporrier/Cyrenaic
OUTPUT:
todo
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.Penrose() sage: P = c.subperiods() # long time (3s) sage: P # long time [(1, 0, -1, a^2 - 2, -a^2 + 2), (1, -1, a^2 - 3, 0, -a^2 + 3), (0, 1, -a^2 + 2, a^2 - 2, -1), (0, -a^2 + 3, 1, -1, a^2 - 3), (1, -a^2 + 3, 0, a^2 - 3, -1), (1, -a^2 + 2, a^2 - 2, -1, 0), (-a^2 + 2, 1, 0, -1, a^2 - 2), (-a^2 + 3, 1, -1, a^2 - 3, 0), (a^2 - 3, 0, -a^2 + 3, 1, -1), (a^2 - 2, -a^2 + 2, 1, 0, -1)]
The same in terms of the golden ratio:
sage: K.<phi> = NumberField(x**2-x-1, 'phi', embedding=RR(1.6)) sage: [p.change_ring(K) for p in P] # long time [(1, 0, -1, -phi + 1, phi - 1), (1, -1, -phi, 0, phi), (0, 1, phi - 1, -phi + 1, -1), (0, phi, 1, -1, -phi), (1, phi, 0, -phi, -1), (1, phi - 1, -phi + 1, -1, 0), (phi - 1, 1, 0, -1, -phi + 1), (phi, 1, -1, -phi, 0), (-phi, 0, phi, 1, -1), (-phi + 1, phi - 1, 1, 0, -1)]
- class slabbe.cut_and_project_scheme.CutAndProjectSchemeGenerator¶
Bases:
object
Constructor of several famous cut and project schemes
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cut_and_project_schemes.Fibonacci() 2-to-1 cut and project scheme
- AmmannBeenker()¶
Return the Ammann-Beenker cut and project scheme
The choice of the matrix E whose rows generate the slope, that is, the kernel of the pi_int projection, is made acording to Carole Porrier’s code available at https://github.com/cporrier/Cyrenaic
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cut_and_project_schemes.AmmannBeenker() 4-to-2 cut and project scheme
sage: c = cut_and_project_schemes.AmmannBeenker() sage: m = c.canonical_model_set(shift=vector((1,1,1,1))/100) sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: G = m.plot_in_physical_space(W) # long time (1s) sage: G.show(aspect_ratio=1, figsize=20) # long time
- Cyrenaic()¶
Return the Cyrenaic cut and proect scheme
The choice of the matrix E whose rows generate the slope, that is, the kernel of the pi_int projection, is made acording to Carole Porrier’s code available at https://github.com/cporrier/Cyrenaic
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cut_and_project_schemes.Cyrenaic() 4-to-2 cut and project scheme
sage: c = cut_and_project_schemes.Cyrenaic() sage: m = c.canonical_model_set(shift=vector((1,1,1,1))/100) sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: G = m.plot_in_physical_space(W) # long time (1s) sage: G.show(aspect_ratio=1, figsize=20) # long time
- Fibonacci()¶
Return the Fibonacci cut and project scheme
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cut_and_project_schemes.Fibonacci() 2-to-1 cut and project scheme
- Fibonacci2D()¶
Return the 2D Fibonacci cut and project scheme
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cut_and_project_schemes.Fibonacci2D() 4-to-2 cut and project scheme
- Fibonacci_the_Minkowski_way()¶
Return the Fibonacci cut and project scheme
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cut_and_project_schemes.Fibonacci_the_Minkowski_way() 2-to-1 cut and project scheme sage: print(cut_and_project_schemes.Fibonacci_the_Minkowski_way()) 2-to-1 cut and project scheme over Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895? Projection to physical space: [1 0] Projection to internal space: [0 1] Lattice generated by the columns of: [ 1 phi] [ 1 -phi + 1]
- GoldenOctagonal(projection='gram_schmidt')¶
Return the Golden-Octagonal cut and project scheme
The choice of the matrix E whose rows generate the slope, that is, the kernel of the pi_int projection, is made acording to Carole Porrier’s code available at https://github.com/cporrier/Cyrenaic
INPUT:
projection
– string (default:'gram_schmidt'
), possible values are'gram_schmidt'
and'roots_of_unity'
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cut_and_project_schemes.GoldenOctagonal() 4-to-2 cut and project scheme
- JeandelRao(algorithm=0)¶
Return the Jeandel-Rao cut and proect scheme as given in [L21].
INPUT:
algorithm
– integer
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.JeandelRao() sage: c 4-to-2 cut and project scheme
sage: print(c) 4-to-2 cut and project scheme over Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895? Projection to physical space: [1 1 0 0] [0 0 1 1] Projection to internal space: [ 1 -phi + 1 0 phi - 1] [ 0 0 1 -phi - 2] Lattice generated by the columns of: [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]
The third version has valid projection in the physical space:
sage: c = cut_and_project_schemes.JeandelRao() sage: c.is_valid(verbose=True) projection minors sign = [0, 1, 1, 1, 1, 0] slope minors sign = [1, 1, 1, 1, 1, 0] False sage: c = cut_and_project_schemes.JeandelRao(3) sage: c.is_valid(verbose=True) projection minors sign = [1, 1, 1, 1, 1, 0] slope minors sign = [1, 1, 1, 1, 1, 0] True
REFERENCES:
[L21] (1,2)Labbé, Sébastien. Markov Partitions for Toral $mathbb{Z}^2$-Rotations Featuring Jeandel–Rao Wang Shift and Model Sets, Annales Henri Lebesgue 4 (2021) 283‑324. https://doi.org/10.5802/ahl.73.
- Penrose(algorithm='degree4')¶
Return the Penrose cut and project scheme
INPUT:
algorithm
– string (default:'degree4'
), valid options are:'degree4'
– computations are made in the number field of degree 4'Carole_gram_schmidt'
– physical projection is not orthonormal'Carole_roots_of_unity'
– computations are made in the Algebraic field (computations are slower)
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: cut_and_project_schemes.Penrose() 5-to-2 cut and project scheme
sage: c = cut_and_project_schemes.Penrose(algorithm='Carole_gram_schmidt') sage: c 5-to-2 cut and project scheme
- class slabbe.cut_and_project_scheme.ModelSet(cut_and_project_scheme, window)¶
Bases:
SageObject
Regular Euclidean model set
INPUT:
cut_and_project_schemes
– a cut and project schemewindow
– polyhedron
EXAMPLES:
sage: from slabbe import cut_and_project_schemes, ModelSet sage: cap = cut_and_project_schemes.Fibonacci() sage: phi = cap.base_ring().gen() sage: W = Polyhedron([(-1,),(phi-1,)]) sage: m = ModelSet(cap, W)
- ambiant_compact_strip(physical_window)¶
Return the preimage of the window in the internal space by the projection in the internal space.
INPUT:
physical_window
– polyhedron
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(0,),(10,)]) sage: m.ambiant_compact_strip(W) A 2-dimensional polyhedron in (Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895?)^2 defined as the convex hull of 4 vertices
Penrose tiling:
sage: m = model_sets.Penrose() sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: m.ambiant_compact_strip(W) A 5-dimensional polyhedron in (Number Field in a with defining polynomial z^4 - 5*z^2 + 5 with a = 1.175570504584947?)^5 defined as the convex hull of 88 vertices
We move the window to force a resolution of the Conway worms:
sage: shift = vector((1,-1,2,-1,-1)) / 1000 sage: m = model_sets.Penrose(shift) sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: m.ambiant_compact_strip(W) A 5-dimensional polyhedron in (Number Field in a with defining polynomial z^4 - 5*z^2 + 5 with a = 1.175570504584947?)^5 defined as the convex hull of 88 vertices
- coding_region(P)¶
Return the region in the window associated with a subset of points of the lattice.
INPUT:
P
– list, subset of vertices of the lattice
OUTPUT:
a polytope
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.Penrose() sage: m = c.canonical_model_set(shift=vector((1,1,1,1,1))/100) sage: P = [(0,0,0,0,0), (0,1,0,0,0), (0,0,1,0,0), (0,0,0,1,0)] sage: m.coding_region(P) A 3-dimensional polyhedron in (Number Field in a with defining polynomial z^4 - 5*z^2 + 5 with a = 1.175570504584947?)^3 defined as the convex hull of 11 vertices
The region may be empty:
sage: P = [(0,0,0,0,0),(0,1,0,0,0),(0,0,1,0,0),(0,0,0,10,0)] sage: m.coding_region(P) The empty polyhedron in (Number Field in a with defining polynomial z^4 - 5*z^2 + 5 with a = 1.175570504584947?)^3
- cut(physical_window)¶
Return the lattice points that are projected in the internal space window (and that are projected to the provided physical space window).
INPUT:
physical_window
– polyhedron
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(0,),(10,)]) sage: m.cut(W) [(3, 2), (4, 2), (3, 1), (4, 3), (2, 1), (5, 3), (1, 1), (6, 3), (1, 0), (6, 4), (0, 0), (7, 4)]
- cut_and_project(physical_window)¶
Return the model set restricted to a window in the physical space
INPUT:
physical_window
– polyhedron
OUTPUT:
list
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(0,),(10,)]) sage: sorted(m.cut_and_project(W)) [(0), (1), (phi), (phi + 1), (phi + 2), (2*phi + 1), (2*phi + 2), (3*phi + 1), (3*phi + 2), (3*phi + 3), (4*phi + 2), (4*phi + 3)]
- cut_and_project_scheme()¶
- cut_edges(physical_window)¶
Return the edges linking lattice points that are projected in the internal space window (and that are projected to the provided physical space window).
INPUT:
physical_window
– polyhedron
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(0,),(10,)]) sage: sorted(sorted(edge) for edge in m.cut_edges(W)) [[(0, 0), (1, 0)], [(1, 0), (1, 1)], [(1, 1), (2, 1)], [(2, 1), (3, 1)], [(3, 1), (3, 2)], [(3, 2), (4, 2)], [(4, 2), (4, 3)], [(4, 3), (5, 3)], [(5, 3), (6, 3)], [(6, 3), (6, 4)], [(6, 4), (7, 4)]]
- internal_space_window_preimage()¶
Return the preimage of the window in the internal space by the projection in the internal space.
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: m.internal_space_window_preimage() A 2-dimensional polyhedron in (Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895?)^2 defined as the convex hull of 2 vertices and 1 line
Penrose tiling:
sage: m = model_sets.Penrose() sage: strip = m.internal_space_window_preimage() sage: strip A 5-dimensional polyhedron in (Number Field in a with defining polynomial z^4 - 5*z^2 + 5 with a = 1.175570504584947?)^5 defined as the convex hull of 22 vertices and 2 lines sage: vector((0,0,0,0,0)) in strip True
We move the window to force a resolution of the Conway worms:
sage: shift = vector((1,-1,2,-1,-1)) / 1000 sage: m = model_sets.Penrose(shift) sage: strip = m.internal_space_window_preimage() sage: vector((0,0,0,0,0)) in strip False sage: vector((1,1,1,1,1)) in strip False
TESTS:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.GoldenOctagonal(projection='roots_of_unity') sage: m = c.canonical_model_set(shift=vector((1,1,1,1))/100) sage: m.internal_space_window_preimage() A 4-dimensional polyhedron in (Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895?)^4 defined as the convex hull of 8 vertices and 2 lines
- is_Meyer()¶
- is_generic()¶
- is_regular()¶
- is_relatively_dense()¶
- is_singular()¶
- is_uniformly_discrete()¶
- lattice_neighbors_projected_in_window(v)¶
Return the neighbors of a point that are projected in the (internal space) window
INPUT:
v
– tuple or vector, in the ambiant space
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: v = vector((0,0)) sage: m.lattice_neighbors_projected_in_window(v) [(1, 0), (-1, 0), (0, -1)]
- physical_space_window_preimage(physical_window)¶
Return the preimage of the window in the internal space by the projection in the internal space.
INPUT:
physical_window
– polyhedron
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(0,),(10,)]) sage: m.physical_space_window_preimage(W) A 2-dimensional polyhedron in (Number Field in phi with defining polynomial z^2 - z - 1 with phi = 1.618033988749895?)^2 defined as the convex hull of 2 vertices and 1 line
Penrose tiling:
sage: m = model_sets.Penrose() sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: strip = m.physical_space_window_preimage(W) sage: strip A 5-dimensional polyhedron in (Number Field in a with defining polynomial z^4 - 5*z^2 + 5 with a = 1.175570504584947?)^5 defined as the convex hull of 4 vertices and 3 lines
We move the window to force a resolution of the Conway worms:
sage: shift = vector((1,-1,2,-1,-1)) / 1000 sage: m = model_sets.Penrose(shift) sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: strip = m.physical_space_window_preimage(W) sage: strip A 5-dimensional polyhedron in (Number Field in a with defining polynomial z^4 - 5*z^2 + 5 with a = 1.175570504584947?)^5 defined as the convex hull of 4 vertices and 3 lines
- plot_in_ambiant_space(physical_window, pointsize=100)¶
Return a Graphics representing the model set restricted to a window in the physical space (seen in the ambiant space)
INPUT:
physical_window
– polyhedronpointsize
– integer (default:20)
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(-10,),(10,)]) sage: G = m.plot_in_ambiant_space(W) # long time (1s) sage: G.show(aspect_ratio=1, figsize=20) # long time
TODO: The following needs a little fix since the slope is zero (some limit case for the region_plot):
sage: m = model_sets.Fibonacci_the_Minkowski_way() sage: W = Polyhedron([(-10,),(10,)]) sage: G = m.plot_in_ambiant_space(W) # long time (1s) sage: G.show(aspect_ratio=1, figsize=20) # known bug
TESTS:
sage: m = model_sets.Fibonacci2D() sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: G = m.plot_in_ambiant_space(W) Traceback (most recent call last): ... NotImplementedError: when physical space dimension is 2 and ambiant space dimension is 4
- plot_in_physical_space(physical_window, pointsize=20)¶
Return a Graphics representing the model set restricted to a window in the physical space
INPUT:
physical_window
– polyhedronpointsize
– integer (default:20)
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci2D() sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: G = m.plot_in_physical_space(W) # long time (1s) sage: G.show(aspect_ratio=1, figsize=20) # long time
Penrose tiling:
sage: m = model_sets.Penrose() sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: G = m.plot_in_physical_space(W) # long time (5s) sage: G.show(aspect_ratio=1, figsize=20) # long time
We move the window to force a resolution of the Conway worms:
sage: shift = vector((1,-1,2,-1,-1)) / 1000 sage: m = model_sets.Penrose(shift) sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: G = m.plot_in_physical_space(W) # long time (4s) sage: G.show(aspect_ratio=1, figsize=20) # long time
TODO, Bug!!:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.GoldenOctagonal(projection='roots_of_unity') sage: m = c.canonical_model_set(shift=vector((1,1,1,1))/100) sage: m.plot_in_physical_space(W).show(figsize=20) Traceback (most recent call last): ... ValueError: invalid base ring: Number Field in zeta80 with defining polynomial x^2 - 2 with zeta80 = 1.414213562373095? cannot be coerced to a real field
TESTS:
sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(-10,),(10,)]) sage: G = m.plot_in_physical_space(W) Traceback (most recent call last): ... NotImplementedError: when physical space dimension is 1
- some_element_of_lattice_in_the_strip(physical_window)¶
Return the lattice points that are projected in the internal space window (and that are projected to the provided physical space window).
INPUT:
physical_window
– polyhedron
OUTPUT:
vector
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(0,),(10,)]) sage: m.some_element_of_lattice_in_the_strip(W) (3, 2)
Penrose tiling:
sage: m = model_sets.Penrose() sage: W = polytopes.hypercube(2, intervals=[(-10,10), (-10,10)]) sage: m.some_element_of_lattice_in_the_strip(W) (0, 0, 0, 0, 0)
- successor_map(physical_window)¶
Return the successor map of points in the lattice projected in both windows.
INPUT:
physical_window
– polyhedron
EXAMPLES:
sage: from slabbe import model_sets sage: m = model_sets.Fibonacci() sage: W = Polyhedron([(0,),(10,)]) sage: succ = m.successor_map(W) sage: succ(vector((0,0))) [(1, 0)]
- window()¶
- class slabbe.cut_and_project_scheme.ModelSetGenerator¶
Bases:
object
Constructor of several famous model sets
EXAMPLES:
sage: from slabbe import model_sets sage: model_sets.Fibonacci() Model Set of a 2-to-1 cut and project scheme
- Fibonacci()¶
Return the Fibonacci cut and project scheme
EXAMPLES:
sage: from slabbe import model_sets sage: model_sets.Fibonacci() Model Set of a 2-to-1 cut and project scheme
- Fibonacci2D()¶
Return the 2D Fibonacci cut and project scheme
EXAMPLES:
sage: from slabbe import model_sets sage: model_sets.Fibonacci2D() Model Set of a 4-to-2 cut and project scheme
- Fibonacci_the_Minkowski_way()¶
Return the Fibonacci cut and project scheme
EXAMPLES:
sage: from slabbe import model_sets sage: model_sets.Fibonacci_the_Minkowski_way() Model Set of a 2-to-1 cut and project scheme
- GoldenOctagonal(shift=None)¶
Return the Golden-Octagonal cut and project scheme
INPUT:
shift
– 4-dimensional vector translating the internal window to avoid singular tilings and Conway worms
EXAMPLES:
sage: from slabbe import model_sets sage: model_sets.GoldenOctagonal() Model Set of a 4-to-2 cut and project scheme
sage: shift = vector((1,-1,2,-1)) / 1000 sage: model_sets.GoldenOctagonal(shift) Model Set of a 4-to-2 cut and project scheme
- Penrose(shift=None)¶
Return the Penrose cut and project scheme
INPUT:
shift
– 5-dimensional vector translating the internal window to avoid singular tilings and Conway worms
EXAMPLES:
sage: from slabbe import model_sets sage: model_sets.Penrose() Model Set of a 5-to-2 cut and project scheme
sage: shift = vector((1,-1,2,-1,-1)) / 1000 sage: model_sets.Penrose(shift) Model Set of a 5-to-2 cut and project scheme
- slabbe.cut_and_project_scheme.hypercube_pet(M, i)¶
EXAMPLES:
sage: from slabbe import cut_and_project_schemes sage: c = cut_and_project_schemes.GoldenOctagonal(projection='roots_of_unity') sage: M = c._pi_int.change_ring(RDF) sage: M [ 1.0 0.0 -1.0 1.618033988749895] [-0.9172881767044976 1.0 -0.7007458120453971 0.13383054136359823] sage: from slabbe.cut_and_project_scheme import hypercube_pet sage: T = hypercube_pet(M, 0) sage: T Polyhedron Exchange Transformation of Polyhedron partition of 4 atoms with 4 letters with translations {'123': (1.0, -0.9172881767044976), '01': (-2.618033989, -0.8345763534), '03': (1.0000000000000002, 1.7007458117), '02': (-1.618033989, 0.8661694583)}