Generative Reflection (GR) Kernel

With the GR family, hypertiling offers a set of generators that utilize python’s generator functions to save memory and enable larger grids. Here, only one symmetry sector of the grid is saved and the coordinates of the other sectors are generated as required.

An important source is [hyp] “Hypertiling – a high performance Python library for the generation and visualization of hyperbolic lattices” (2023, arxiv:2309.10844)

Another difference to the other kernels is the reflective nature of the kernel. The underlying algorithm for the GR family is different to the SR (rotational) family. While there new polygons are created via the rotation of vertices, in the GR family only the corners of the polygons are reflected. The modified algorithm makes GR significantly more performant than SR, but forces a modified layer structure. Rather than layers closing vertices of the previous layer, the natural definition of layers is given by the edges of the polygons in the previous layer. Therefore, the next layer closes all open edges a polygon had.

The actual algorithm is implemented in the GR kernel

class hypertiling.kernel.GR.GenerativeReflection(p: int, q: int, n: int, mangle: float = 3.625609908221908)

Very fast and lightweight tiling construction kernel, using reflections on ``open’’ edges to generate new cells. Only one symmetry sector is held on storage, with cells outside of this sector being generated on demand.

p: Number of edges/vertices of a polygon q: Number of polygons that meet at a vertex n: Number of layers (reflective definition) m: Number of polygons m = m(p, q, n)

LIMITATIONS: - A reflection layer can hold at max 4294967295 polys as the size is stored as uint32 (util.get_reflection_n_estimation) - The whole tiling can holy at max 34359738353 polys as the size of _sector_polys is determined as sum of uint32 of the layers size in the fundamental sector - The number of reflection layers is limited to 255 at max, as util.generate stores the layers as uint8

Methods

To hide the generative nature, the kernel provides an interface shielding the user from its generator mechanics. Many of the protected methods, i.e. methods who’s name start with an underscore ‘_’, act on the generative nature. Methods without underscore hide the generative nature and can be used as with the other kernels.

Integrity

One speciality of the GR-family is the implementation of a ‘’’check_integrity’’’ method. The exact tests performed are, even within the GR-family, kernel dependent. This is necessary as some members are not of subclass tiling and thus do not provide coordinates. These members are marked with an additional G, e.g. GRG, to indicate its graph nature.

class hypertiling.kernel.GR.GenerativeReflection.check_integrity(self)

This function is numerically expensive! Checks the integrity of the grid. The number of neighbors as well as a search for duplicates is applied. Raises AttributeError if the grid seems to be invalid.

Time-complexity: O(m p^2 n)

Return type:

void

Getter methods

class hypertiling.kernel.GR.GenerativeReflection.get_sector(self, index: int)

Returns the sector that the polygon at index refers to.

Time-complexity: O(1)

Parameters:

index (int) – Index of the polygon.

Returns:

Number of the sector.

Return type:

int

class hypertiling.kernel.GR.GenerativeReflection.get_center(self, index: int)

Returns the center of the polygon at index.

Time-complexity: O(1)

Parameters:

index (int) – Index of the polygon.

Returns:

Center of the polygon.

Return type:

np.complex128

class hypertiling.kernel.GR.GenerativeReflection.get_vertices(self, index: int)

Returns the p vertices of the polygon at index.

Time-complexity: O(p)

Parameters:

index (int) – Index of the polygon.

Returns:

Array of shape (p,) containing vertices of the polygon.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection.get_angle(self, index: int)

Returns the angle to the center of the polygon at index.

Time-complexity: O(1)

Parameters:

index (int) – Index of the polygon.

Returns:

Center of the polygon.

Return type:

np.complex128

class hypertiling.kernel.GR.GenerativeReflection.get_polygon(self, index: int)

Returns the polygon at index as HyperPolygon object.

Parameters:

index (int) – Index of the polygon.

Returns:

Polygon at index.

Return type:

HyperPolygon

Layer methods

GR provides methods for accessing the classical layer structure as in the other kernels as well as a method for accessing its native layer structure. As the classical structure is not natural to GR, it will be calculated on use. This calculation can either be triggered manually using .. autoclass:: hypertiling.kernel.GR.GenerativeReflection.map_layers or automatically by the first call of .. autoclass:: hypertiling.kernel.GR.GenerativeReflection.get_layer

This method will return the native layer definition of GR. .. autoclass:: hypertiling.kernel.GR.GenerativeReflection.get_reflection_level

Neighbor methods

GR provides multiple methods for accessing the neighbor relations. All of them have their different advantages and disadvantages. Please see [hyp] for a more detailed performance measurement.

class hypertiling.kernel.GR.GenerativeReflection.get_nbrs(self, i, method='mapping')

Get the neighbors of a polygon at index with method.

Parameters:
  • i (int) – Index of the polygon.

  • method (str) – Method to use.

Returns:

Array containing the indices of the neighbors.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection.get_nbrs_generative(self, index: int)

Get the neighbors of a polygon at index. Time-complexity: O(m + p^2)

Parameters:

index (int) – Index of the polygon.

Returns:

Array containing the indices of the neighbors.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection.get_nbrs_geometrical(self, index: int)

Get the neighbors of the polygon at index using an experimental method. Time-complexity: O(?)

Parameters:

index (int) – Index of the polygon.

Returns:

Array containing the indices of the neighbors.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection.get_nbrs_mapping(self, index: int)

Get neighbor of the polygon at index. Time-complexity (single polygon): O(p)

Parameters:

index (int) – Index of the polygon for whom the neighbors will be searched for.

Returns:

Indices of the neighbors.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection.map_nbrs(self, tol: float = 1e-05)

This function is numerically expensive! Calculates the neighbors for each polygon.

Time-complexity: O(m[ld(n + 1) / p + p^(log(m)) + ld(m / p) / p])

Parameters:

tol (float) – Tolerance to search neighbors in.

Return type:

void

class hypertiling.kernel.GR.GenerativeReflection.get_nbrs_radius(self, index: int)

Get the neighbors of a polygon at index. Time-complexity: O(m / p)

Parameters:

index (int) – Index of the polygon.

Returns:

Array containing the indices of the neighbors.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection.get_nbrs_list(self, tol: float = 1e-05, method='default')

Create and return list of all neighbors

Time-complexity: O(mp)

Parameters:
  • tol (float) – Tolerance to search neighbors in.

  • method (str) – Method to use for calculating the neighbors. Currently “default” only.

Returns:

List of all neighbors for all polygons.

Return type:

List[List[int]]

Miscellaneous methods

class hypertiling.kernel.GR.GenerativeReflection.generate(self)

Calculate the tiling polygons for an angular sector.

Time-complexity: O(p^2 m + n)

Return type:

void

class hypertiling.kernel.GR.GenerativeReflection.find(self, v: complex128)

Find the polygons index v belongs to.

Time-complexity: O(m / p + p)

Parameters:

v (complex) – Position to search polygon for.

Returns:

Index of the corresponding polygon.

Return type:

int

Special methods

class hypertiling.kernel.GR.GenerativeReflection.__len__(self)

Return the number of polygons in the tiling.

Time-complexity: O(1)

Returns:

Number of polygons in the tiling.

Return type:

int

class hypertiling.kernel.GR.GenerativeReflection.__iter__(self)

Iterates over the whole grid. As only one sector is stored in the memory, the others are generated when needed. Time-complexity (single polygon): O(p) :yield: np.array

Array of shape [center, vertices].

class hypertiling.kernel.GR.GenerativeReflection.__getitem__(self, index: int)

Returns the center and vertices of the polygon at index. As only one sector is stored, the corresponding polygon is calculated if necessary. Time-complexity: O(p)

Parameters:

index (int) – Index of the polygon.

Returns:

Array of shape (p + 1) representing [center, vertices].

Return type:

np.array

Generator methods (protected)

class hypertiling.kernel.GR.GenerativeReflection._find(self, sector_proj: complex128, eps: float = 1e-12)

Protected(!) Find the polygons index sector_projection belongs to. However, sector_projection has to be in the fundamental sector.

Time-complexity: O(m / p)

Parameters:
  • sector_proj (np.complex128) – Position to search polygon for.

  • eps (float) – Threshold for comparison.

Returns:

Index of the corresponding polygon.

Return type:

int

class hypertiling.kernel.GR.GenerativeReflection._get_reflection_level_in_sector(self, sector_index: int)

Protected(!) Returns the reflection level the polygon at index belongs to.

Time-complexity: O(log(n + 1))

Parameters:

sector_index (int) – Index of the polygon.

Returns:

Reflection level.

Return type:

int

class hypertiling.kernel.GR.GenerativeReflection._get_nbrs_generative(self, sector_index: int)

Protected(!) Get neighbor of the polygon at sector_index. Has to be in the fundamental sector!

Time-complexity (single polygon): O(m + p^2)

Parameters:

sector_index (int) – Index of the polygon for whom the neighbors will be searched for.

Returns:

Indices of the neighbors.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection._get_nbrs_radius(self, sector_index: int, tol: float = 1e-05)

Protected(!) Get neighbor of the polygon at sector_index. Has to be in the fundamental sector!

Time-complexity (single polygon): O(m / p + n)

Parameters:

sector_index (int) – Index of the polygon for whom the neighbors will be searched for.

Returns:

Indices of the neighbors.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection._get_nbrs_geometrical(self, sector_index: int)

Protected(!) Get the neighbors of the polygon at sector_index using an experimental method. Has to be in the fundamental sector!

Time-complexity: O(p^3 + n)

Parameters:

sector_index (int) – Index of the polygon.

Returns:

Array containing the indices of the neighbors.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection._get_nbrs_mapping(self, sector_index: int)

Protected(!) Get neighbor of the polygon at sector_index. Has to be in the fundamental sector!

Time-complexity (without map.): O(p)

Parameters:

sector_index (int) – Index of the polygon for whom the neighbors will be searched for.

Returns:

Indices of the neighbors.

Return type:

np.array

Support methods (protected)

class hypertiling.kernel.GR.GenerativeReflection._polygen(self, polys: array)

Protected(!) Generator for iterating over polygons.

Time-complexity (single polygon, cf. last yield): O(p)

Parameters:
  • polys (np.array)

  • (n (Array of shape)

  • over. (p + 1) representing the segments the generator will create the rotations duplicates for and rotate)

Yields:
  • np.array

  • Polygon of the segment polys or its rotational duplicates.

class hypertiling.kernel.GR.GenerativeReflection._wiggle_index(self, index1: int, index2: int, tol: int = 1)

Protected(!) Changes the position of index2 until the polygon shares a boundary with index 1.

Time-complexity (single polygon): O(tol p^2)

Parameters:
  • index1 (int) – Index of the primary polygon.

  • index2 (int) – Index of the searched polygon.

Returns:

Index of the searched polygon.

Return type:

int

class hypertiling.kernel.GR.GenerativeReflection._index_from_ref_layer_index(self, index: int, ref_layer: int)

Protected(!) Calculates the index in the tiling a polygon in ref_layer would have when the reference layer would have been created circular.

Time-complexity: O(1)

Parameters:
  • index (int) – Index the polygon would have if ref_layer would have been created circular.

  • ref_layer (int) – Index of the reflection layer the polygons are created in.

Returns:

Index of the polygon in the tiling.

Return type:

int

class hypertiling.kernel.GR.GenerativeReflection._expand_sector_index_to_tiling(self, index: int, f: Callable)

Protected(!) Takes an index (for the tiling) and a function defined in the fundamental sector. Calculates the corresponding sector_index, applies function f, and corrects the result to index.

Time-complexity: O(f(index))

Parameters:
  • index (int) – Index of a polygon in the tiling.

  • f (Callable) – Function to apply on sector_index.

Returns:

Polygon of the segment polys or its rotational duplicates.

Return type:

np.array

class hypertiling.kernel.GR.GenerativeReflection._to_weierstrass(polygons: array)

Protected(!) Calculates the Weierstrass coordinates for an array of polygons in Poincaré disks.

Time-complexity: O(m / p)

Parameters:

polygons (np.array) – Array of shape (n, p + 1) representing polygons to calculate Weierstrass coordinates for.

Returns:

Array of shape (p + 1, 3) representing polygons in Weierstrass coordinates.

Return type:

np.array

Not implemented methods

Methods which are not yet implemented but are planned to be added.

class hypertiling.kernel.GR.GenerativeReflection.add_layer(self)
class hypertiling.kernel.GR.GenerativeReflection.transform(self, function: Callable)

Applies function to each polygon.

Parameters:
  • function (callable) – Function to apply on each polygon.

  • Time-complexity (O(m / p))

Return type:

void

class hypertiling.kernel.GR.GenerativeReflection.rotate(self, angle: float)

Rotates the grid around angle.

Parameters:
  • angle (float) – Angle to rotate the polygon.

  • Time-complexity (O(m / p))

Return type:

void

class hypertiling.kernel.GR.GenerativeReflection.translate(self, z: complex128)

Translates the grid to z.

Parameters:
  • z (complex) – Position of the new origin.

  • Time-complexity (O(m / p))

Return type:

void

Properties

Besides the attributes provides by the tiling-abc, GR provides multiple other attributes. These are all protected and, due to the generative nature, should be handled with caution.