Classifications

RationalPolygons.jl implements the following classification algorithms:

Moreover, the classifications from [1] are implemented:

Lattice polygons by number of lattice points

In his PhD thesis, R.J. Koelman describes an algorithm to classify lattice polygons with a given number of lattice points and ran it up to 42 lattice points, Table 4.4.3 of [7]. We have implemented his algorithm here, which sucessfully reproduces Koelman's original numbers, see also A371917 on OEIS

RationalPolygons.height_one_pointsFunction
height_one_points(P :: RationalPolygon)

Given a lattice polygon P, return all lattice points that have lattice height one with respect to some edge of P. Equivalently, return the set of boundary lattice points of move_out_edges(P).

source
RationalPolygons.single_point_extensionsFunction
single_point_extensions(Ps :: Vector{<:RationalPolygon{T}}) where {T <: Integer}

Return all lattice polygons that can be obtained by adding a single height one point to a polygon of Ps, up to affine equivalence.

source
RationalPolygons.KoelmanStorageType
abstract type KoelmanStorage{T <: Integer} end

Abstract supertype of InMemoryKoelmanStorage and HDFKoelmanStorage. Both implement classify_next_number_of_lattice_points, which performs a single step in Koelman's classification of lattice polygons.

source
RationalPolygons.InMemoryKoelmanStorageType
mutable struct InMemoryKoelmanStorage{T <: Integer} <: KoelmanStorage{T}

A struct holding classification results of Koelman's classification of lattice polygons by number of lattice points. It has two fields polygons :: Vector{Vector{RationalPolygon{T}} and total_count :: Int.

source
RationalPolygons.HDFKoelmanStoragePreferencesType
struct HDFKoelmanStoragePreferences{T <: Integer}

A struct holding preferences for Koelman's classification using the HDF5 file format. It has four fields:

  • swmr :: Bool: Whether to use single-reader-multiple-writer mode for HDF5. Defaults to true.
  • maximum_number_of_vertices :: Int: An upper bound for the maximal number of vertices to be expected in the classification. This has to be set since every HDF5 file generated will have a dataset "numbers_of_polygons" storing the number of polygons for each number of vertices and the size of this dataset needs to be set beforehand. Defaults to 100, which should be more than enough for any feasable computation.
  • block_size :: Int: How many polygons should be read into memory at once during the extension process. Defaults to 10^6.
source
RationalPolygons.HDFKoelmanStorageType
mutable struct HDFKoelmanStorage{T <: Integer} <: KoelmanStorage{T}

A struct for managing classification results of Koelman's classification of lattice polygons using the HDF5 file format. It has the following fields:

  • preferences :: HDFKoelmanStoragePreferences{T}
  • directory_path :: String: The directory where the HDF5 files will be generated.
  • last_completed_number_of_lattice_points :: Int: The last completed step of the classification. Initially, this will be 3.
  • total_count :: Int
source
RationalPolygons.classify_next_number_of_lattice_pointsFunction
classify_next_number_of_lattice_points(st :: InMemoryKoelmanStorage{T}) where {T <: Integer}

Perform a single step in Koelman's classification of lattice polygons using in-memory storage.

Example

Perform a single step of Koelmans classification using Int64. The result tells us that there are three lattice polygons with exactly four lattice points.

julia> st = InMemoryKoelmanStorage{Int64}();

julia> classify_next_number_of_lattice_points(st)
3

julia> st.polygons[4]
3-element Vector{RationalPolygon{Int64}}:
 Rational polygon of rationality 1 with 3 vertices.
 Rational polygon of rationality 1 with 4 vertices.
 Rational polygon of rationality 1 with 3 vertices.
source
classify_next_number_of_lattice_points(st :: HDFKoelmanStorage{T}; logging :: Bool = false) where {T <: Integer}

Perform a single step in Koelman's classification of lattice polygons using on-disk storage with HDF5.

source
RationalPolygons.classify_polygons_by_number_of_lattice_pointsFunction
classify_polygons_by_number_of_lattice_points(st :: KoelmanStorage{T}, max_number_of_lattice_points :: Int; logging :: Bool = false) where {T <: Integer}

Run Koelman's classification of lattice polygons by number of lattice points, up to max_number_of_lattice_points. The classification is multithreaded, so make sure julia has access to a good number of threads for maximum performance (i.e. Threads.nthreads() is greater than one).

Example

Reproduce Koelman's original classification in memory, see Table 4.4.3 of [7] or A371917 on OEIS. This should not take longer than a few minutes on modern hardware.

julia> st = InMemoryKoelmanStorage{Int}();

julia> classify_polygons_by_number_of_lattice_points(st, 42; logging=true);
[ Info: [l = 4]. New polygons: 3. Total: 4
[ Info: [l = 5]. New polygons: 6. Total: 10
[ Info: [l = 6]. New polygons: 13. Total: 23
[ Info: [l = 7]. New polygons: 21. Total: 44
[ Info: [l = 8]. New polygons: 41. Total: 85
[ Info: [l = 9]. New polygons: 67. Total: 152
[ Info: [l = 10]. New polygons: 111. Total: 263
[ Info: [l = 11]. New polygons: 175. Total: 438
[ Info: [l = 12]. New polygons: 286. Total: 724
[ Info: [l = 13]. New polygons: 419. Total: 1143
[ Info: [l = 14]. New polygons: 643. Total: 1786
[ Info: [l = 15]. New polygons: 938. Total: 2724
[ Info: [l = 16]. New polygons: 1370. Total: 4094
[ Info: [l = 17]. New polygons: 1939. Total: 6033
[ Info: [l = 18]. New polygons: 2779. Total: 8812
[ Info: [l = 19]. New polygons: 3819. Total: 12631
[ Info: [l = 20]. New polygons: 5293. Total: 17924
[ Info: [l = 21]. New polygons: 7191. Total: 25115
[ Info: [l = 22]. New polygons: 9752. Total: 34867
[ Info: [l = 23]. New polygons: 12991. Total: 47858
[ Info: [l = 24]. New polygons: 17321. Total: 65179
[ Info: [l = 25]. New polygons: 22641. Total: 87820
[ Info: [l = 26]. New polygons: 29687. Total: 117507
[ Info: [l = 27]. New polygons: 38533. Total: 156040
[ Info: [l = 28]. New polygons: 49796. Total: 205836
[ Info: [l = 29]. New polygons: 63621. Total: 269457
[ Info: [l = 30]. New polygons: 81300. Total: 350757
[ Info: [l = 31]. New polygons: 102807. Total: 453564
[ Info: [l = 32]. New polygons: 129787. Total: 583351
[ Info: [l = 33]. New polygons: 162833. Total: 746184
[ Info: [l = 34]. New polygons: 203642. Total: 949826
[ Info: [l = 35]. New polygons: 252898. Total: 1202724
[ Info: [l = 36]. New polygons: 313666. Total: 1516390
[ Info: [l = 37]. New polygons: 386601. Total: 1902991
[ Info: [l = 38]. New polygons: 475540. Total: 2378531
[ Info: [l = 39]. New polygons: 582216. Total: 2960747
[ Info: [l = 40]. New polygons: 710688. Total: 3671435
[ Info: [l = 41]. New polygons: 863552. Total: 4534987
[ Info: [l = 42]. New polygons: 1048176. Total: 5583163

Example

Reproduce Koelman's classification and storing the output to HDF5 files.

julia> st = HDFKoelmanStorage{Int}("/tmp");

julia> classify_polygons_by_number_of_lattice_points(st, 42);

The result will be HDF5 files named "l1.h5, l2.h5, ...", each containing one dataset of polygons for fixed number of vertices as well as a dataset "numbers_of_polygons" holding their numbers.

julia> using HDF5

julia> f = h5open("/tmp/test/l42.h5", "r")
🗂️ HDF5.File: (read-only) /tmp/test/l42.h5
├─ 🔢 n10
├─ 🔢 n11
├─ 🔢 n12
├─ 🔢 n3
├─ 🔢 n4
├─ 🔢 n5
├─ 🔢 n6
├─ 🔢 n7
├─ 🔢 n8
├─ 🔢 n9
└─ 🔢 numbers_of_polygons

julia> A = read_dataset(f, "numbers_of_polygons");

julia> sum(A) # the number of lattice polygons with 42 lattice points
1048176

julia> Ps = read_polygon_dataset(1, f, "n5"); # Read in all pentagons with 42 lattice points.

julia> all(P -> number_of_lattice_points(P) == 42, Ps)
true
source

Lattice polygons by number of interior lattice points

In [8], Castryck describes an algorithm for the classification of lattice polygons by their number of interior lattice points and ran it up to 30 interior lattice points. Our implementation here successfully reproduces his numbers from Table 1 of [8], see also A322343 on OEIS.

RationalPolygons.CastryckStorageType
abstract type CastryckStorage{T <: Integer} end

Abstract supertype of InMemoryCastryckStorage and HDFCastryckStorage. Both implement classify_next_genus, which performs a single step in Castryck's classification of lattice polygons.

source
RationalPolygons.InMemoryCastryckStorageType
mutable struct InMemoryCastryckStorage{T <: Integer} <: CastryckStorage{T}

A struct holding classification results of Castryck's classification of lattice polygons by number of interior lattice points (i.e. their genus). It has the following fields:

  • maximum_genus :: Int: An upper bound for the maximum genus that the classification should run to. Defaults to 100.
  • maximal_polygons :: Vector{Vector{RationalPolygon{T}}},
  • all_polygons :: Vector{Vector{RationalPolygon{T}}},
  • total_count :: Int.
source
RationalPolygons.HDFCastryckStoragePreferencesType
struct HDFCastryckStoragePreferences{T <: Integer}

A struct holding preferences for Castryck's classification using the HDF5 file format. It has four fields:

  • swmr :: Bool: Whether to use single-reader-multiple-writer mode for HDF5. Defaults to true.
  • maximum_genus :: Int: An upper bound for the maximal number of interior lattice points to which the classification should be run. Defaults to 100.
  • maximum_number_of_vertices :: Int: An upper bound for the maximal number of vertices to be expected in the classification. This has to be set since every HDF5 file generated will have a dataset "numbers_of_polygons" storing the number of polygons for each number of vertices and the size of this dataset needs to be set beforehand. Defaults to 100, which should be more than enough for any feasable computation.
  • block_size :: Int: How many polygons should be read into memory at once during the computation of subpolygons and the moving-out process. Defaults to 10^6.
source
RationalPolygons.HDFCastryckStorageType
mutable struct HDFCastryckStorage{T <: Integer} <: CastryckStorage{T}

A struct for managing classification results of Castryck's classification of lattice polygons using the HDF5 file format. It has the following fields:

  • preferences :: HDFCastryckStoragePreferences{T}
  • directory_path :: String: The directory where the HDF5 files will be generated.
  • last_completed_genus :: Int: The last completed step of the classification. Initially, this will be 0.
  • total_count :: Int
source
RationalPolygons.classify_next_genusFunction
classify_next_genus(st :: InMemoryCastryckStorage{T}; logging :: Bool = false) where {T <: Integer}

Perform a single step in Castryck's classification of lattice polygons by number of interior lattice points, using in-memory storage. Returns a tuple where the first entry is the number of lattice polygons obtained and the second number is the number of maximal lattice polygons.

Example

Perform two steps in Castryck's classification. The result tells us that there are 45 lattice polygons with exactly two interior lattice points, four of which are maximal.

julia> st = InMemoryCastryckStorage{Int}();

julia> classify_next_genus(st)
(16, 3)

julia> classify_next_genus(st)
(45, 4)
source
classify_next_genus(st :: HDFCastryckStorage{T}; logging :: Bool = false) where {T <: Integer}

Perform a single step in Castryck's classification of lattice polygons using on-disk storage with HDF5.

source
RationalPolygons.classify_lattice_polygons_by_genusFunction
classify_lattice_polygons_by_genus(st :: CastryckStorage{T}, max_genus :: Int; logging :: Bool = false) where {T <: Integer}

Run Castryck's classification of lattice polygons by number of interior lattice points, up to max_genus. The classification is multithreaded, so make sure julia has access to a good number of threads for maximum performance (i.e. Threads.nthreads() is greater than one).

Example

Reproduce Castryck's classification in memory, see Table 1 of [8] or A322343 on OEIS. This should not take longer than a few minutes on modern hardware.

julia> st = InMemoryCastryckStorage{Int}();

julia> classify_lattice_polygons_by_genus(st, 30; logging=true)
[ Info: [i = 1]. Got 3 maximal polygons.
[ Info: [i = 1]. Subpolygons complete. Num of polygons: 16
[ Info: [i = 1]. Moving out complete. New maximal polygons: 16
[ Info: [i = 2]. Got 4 maximal polygons.
[ Info: [i = 2]. Subpolygons complete. Num of polygons: 45
[ Info: [i = 2]. Moving out complete. New maximal polygons: 22
[ Info: [i = 3]. Got 6 maximal polygons.
[ Info: [i = 3]. Subpolygons complete. Num of polygons: 120
[ Info: [i = 3]. Moving out complete. New maximal polygons: 63
[ Info: [i = 4]. Got 9 maximal polygons.
[ Info: [i = 4]. Subpolygons complete. Num of polygons: 211
[ Info: [i = 4]. Moving out complete. New maximal polygons: 78
[ Info: [i = 5]. Got 11 maximal polygons.
[ Info: [i = 5]. Subpolygons complete. Num of polygons: 403
[ Info: [i = 5]. Moving out complete. New maximal polygons: 122
[ Info: [i = 6]. Got 13 maximal polygons.
[ Info: [i = 6]. Subpolygons complete. Num of polygons: 714
[ Info: [i = 6]. Moving out complete. New maximal polygons: 192
[ Info: [i = 7]. Got 16 maximal polygons.
[ Info: [i = 7]. Subpolygons complete. Num of polygons: 1023
[ Info: [i = 7]. Moving out complete. New maximal polygons: 239
[ Info: [i = 8]. Got 21 maximal polygons.
[ Info: [i = 8]. Subpolygons complete. Num of polygons: 1830
[ Info: [i = 8]. Moving out complete. New maximal polygons: 316
[ Info: [i = 9]. Got 27 maximal polygons.
[ Info: [i = 9]. Subpolygons complete. Num of polygons: 2700
[ Info: [i = 9]. Moving out complete. New maximal polygons: 508
[ Info: [i = 10]. Got 33 maximal polygons.
[ Info: [i = 10]. Subpolygons complete. Num of polygons: 3659
[ Info: [i = 10]. Moving out complete. New maximal polygons: 509
[ Info: [i = 11]. Got 38 maximal polygons.
[ Info: [i = 11]. Subpolygons complete. Num of polygons: 6125
[ Info: [i = 11]. Moving out complete. New maximal polygons: 700
[ Info: [i = 12]. Got 51 maximal polygons.
[ Info: [i = 12]. Subpolygons complete. Num of polygons: 8101
[ Info: [i = 12]. Moving out complete. New maximal polygons: 1044
[ Info: [i = 13]. Got 61 maximal polygons.
[ Info: [i = 13]. Subpolygons complete. Num of polygons: 11027
[ Info: [i = 13]. Moving out complete. New maximal polygons: 1113
[ Info: [i = 14]. Got 76 maximal polygons.
[ Info: [i = 14]. Subpolygons complete. Num of polygons: 17280
[ Info: [i = 14]. Moving out complete. New maximal polygons: 1429
[ Info: [i = 15]. Got 86 maximal polygons.
[ Info: [i = 15]. Subpolygons complete. Num of polygons: 21499
[ Info: [i = 15]. Moving out complete. New maximal polygons: 2052
[ Info: [i = 16]. Got 113 maximal polygons.
[ Info: [i = 16]. Subpolygons complete. Num of polygons: 28689
[ Info: [i = 16]. Moving out complete. New maximal polygons: 1962
[ Info: [i = 17]. Got 129 maximal polygons.
[ Info: [i = 17]. Subpolygons complete. Num of polygons: 43012
[ Info: [i = 17]. Moving out complete. New maximal polygons: 2651
[ Info: [i = 18]. Got 166 maximal polygons.
[ Info: [i = 18]. Subpolygons complete. Num of polygons: 52736
[ Info: [i = 18]. Moving out complete. New maximal polygons: 3543
[ Info: [i = 19]. Got 200 maximal polygons.
[ Info: [i = 19]. Subpolygons complete. Num of polygons: 68557
[ Info: [i = 19]. Moving out complete. New maximal polygons: 3638
[ Info: [i = 20]. Got 240 maximal polygons.
[ Info: [i = 20]. Subpolygons complete. Num of polygons: 97733
[ Info: [i = 20]. Moving out complete. New maximal polygons: 4594
[ Info: [i = 21]. Got 281 maximal polygons.
[ Info: [i = 21]. Subpolygons complete. Num of polygons: 117776
[ Info: [i = 21]. Moving out complete. New maximal polygons: 5996
[ Info: [i = 22]. Got 352 maximal polygons.
[ Info: [i = 22]. Subpolygons complete. Num of polygons: 152344
[ Info: [i = 22]. Moving out complete. New maximal polygons: 6364
[ Info: [i = 23]. Got 403 maximal polygons.
[ Info: [i = 23]. Subpolygons complete. Num of polygons: 209409
[ Info: [i = 23]. Moving out complete. New maximal polygons: 7922
[ Info: [i = 24]. Got 506 maximal polygons.
[ Info: [i = 24]. Subpolygons complete. Num of polygons: 248983
[ Info: [i = 24]. Moving out complete. New maximal polygons: 9692
[ Info: [i = 25]. Got 584 maximal polygons.
[ Info: [i = 25]. Subpolygons complete. Num of polygons: 319957
[ Info: [i = 25]. Moving out complete. New maximal polygons: 10208
[ Info: [i = 26]. Got 708 maximal polygons.
[ Info: [i = 26]. Subpolygons complete. Num of polygons: 420714
[ Info: [i = 26]. Moving out complete. New maximal polygons: 12727
[ Info: [i = 27]. Got 821 maximal polygons.
[ Info: [i = 27]. Subpolygons complete. Num of polygons: 497676
[ Info: [i = 27]. Moving out complete. New maximal polygons: 15431
[ Info: [i = 28]. Got 995 maximal polygons.
[ Info: [i = 28]. Subpolygons complete. Num of polygons: 641229
[ Info: [i = 28]. Moving out complete. New maximal polygons: 15918
[ Info: [i = 29]. Got 1121 maximal polygons.
[ Info: [i = 29]. Subpolygons complete. Num of polygons: 813814
[ Info: [i = 29]. Moving out complete. New maximal polygons: 20354
[ Info: [i = 30]. Got 1352 maximal polygons.
[ Info: [i = 30]. Subpolygons complete. Num of polygons: 957001
[ Info: [i = 30]. Moving out complete. New maximal polygons: 23873

Example

Reproduce Castryck's classification and storing the output to HDF5 files

julia> st = HDFCastryckStorage{Int}("/tmp");

julia> classify_lattice_polygons_by_genus(st, 30);

This will create two directories "all" and "maximal" in the target directory and populate them with HDF5 files "i1.h5, i2.h5, ..." containing the polygons. The files in "maximal" contain datasets ordered by number of vertices. The files in "all" contain groups ordered by area, which contain datasets ordered by number of vertices. Every h5 file additionally contains a dataset "numbers_of_polygons".

julia> using HDF5

julia> f = h5open("/tmp/all/i30.h5", "r");

julia> Ps = read_polygon_dataset(1, f, "a69/n8"); # Read in all octagons of genus 30 with normalized volume 69

julia> all(P -> number_of_interior_lattice_points(P) == 30, Ps)
true

julia> A = read_dataset(f, "numbers_of_polygons"); # The total number of lattice polygons with 30 interior lattice points

julia> sum(A) # The total number of lattice polygons with 30 interior lattice points.
957001
source

Lattice polygons contained in a square

In [9], the authors considered lattice polygons that are contained in a square of fixed side length and classified them up to side length 7. Their numbers (Table 1 of [9], see also A374975) can be reproduced with RationalPolygons.jl as follows:

julia> square(m) = convex_hull(LatticePoint{Int}[(0,0),(m,0),(0,m),(m,m)])
square (generic function with 1 method)

julia> Pss = [subpolygons(square(m); use_affine_normal_form = true, only_equal_number_of_interior_lattice_points = false) for m = 1 : 7];

julia> numbers_of_polygons = [length(Pss[m]) - length(Pss[m-1]) for m = 2 : 7]
6-element Vector{Int64}:
      15
     131
    1369
   13842
  129185
 1104895

julia> max_vertices = [maximum(number_of_vertices.(Pss[m])) for m = 1 : 7]
7-element Vector{Int64}:
  4
  6
  8
  9
 10
 12
 13

julia> [length(filter(P -> number_of_vertices(P) == max_vertices[m], Pss[m])) for m = 1 : 7]
7-element Vector{Int64}:
  1
  1
  1
  1
 15
  2
  3

Lattice polygons by Gorenstein index

In [10], the authors describe an algorithm to classify LDP polygons by Gorenstein index. RationalPolygons.jl implements a version of their algorithm, which successfully reproduces their numbers (see Theorem 1.2 of [10]).

RationalPolygons.PartialLDPType
PartialLDP{T<:Integer,N,M}

A struct used in the classification of polygons by gorenstein index. It contains three fields:

  • P :: RationalPolygon{T,N,M}: The polygon constructed so far.
  • initial_local_index : T: The local index of the special facet.
  • ymin : T: Lower bound for the y-value of the next vertex to be chosen, see Algorithm 6.3 of [10].
source
RationalPolygons.initial_special_facetsFunction
initial_special_facets(index :: T, initial_local_index :: T) where {T <: Integer}

Return all possible initial special facet to start the classification as in step (1) of Algorithm 6.3 of [10].

source
RationalPolygons.choose_next_vertexFunction
choose_next_vertex(ldps :: Vector{<:PartialLDP{T,N}}, index :: T) where {N, T <: Integer}

Perform a single step in the classification of lattice polygons by gorenstein index as in step (2) of Algorithm 6.3 of [10].

source
RationalPolygons.classify_lattice_polygons_by_gorenstein_indexFunction
classify_lattice_polygons_by_gorenstein_index(index :: T; logging :: Bool = false) where {T <: Integer}

Return all lattice polygons with given gorenstein index, using the Algorithm described in [10].

Example

There are 91 LDP polygons of Gorenstein index 4: 13 triangles, 48 quadrilaterals, 29 pentagons and one hexagon.

julia> Pss = classify_lattice_polygons_by_gorenstein_index(4);

julia> length.(Pss)
4-element Vector{Int64}:
 13
 48
 29
  1

julia> sum(ans)
91
source

Lattice triangles by Gorenstein index

In [11], Bäuerle classified Fano simplices by dimension and gorenstein index. RationalPolygons.jl implements a version of his algorithm (specialized to the two-dimensional case), which reproduces his numbers sucessfully (see Theorem 1.4 of [11] and A145582).

RationalPolygons.unit_fraction_partitions_length_threeFunction
unit_fraction_partitions_length_three(ι :: T) where {T <: Integer}

Return all triples (a,b,c) such that 1//ι = 1//a + 1//b + 1//c Andreasa ≤ b ≤ c. See also A004194 on oeis.

Example

julia> unit_fraction_partitions_length_three(2)
10-element Vector{Tuple{Int64, Int64, Int64}}:
 (3, 7, 42)
 (3, 8, 24)
 (3, 9, 18)
 (3, 10, 15)
 (3, 12, 12)
 (4, 5, 20)
 (4, 6, 12)
 (4, 8, 8)
 (5, 5, 10)
 (6, 6, 6)
source
RationalPolygons.InMemoryBaeuerleStorageType
mutable struct InMemoryBaeuerleStorage{T <: Integer} <: BaeuerleStorage{T}

A struct holding classification results of Baeuerle's classification of lattice triangles by gorenstein index.

source
RationalPolygons.HDFBaeuerleStorageType
mutable struct HDFBaeuerleStorage{T <: Integer} <: BaeuerleStorage{T}

A struct for managing classification results of Baeuerle's classification of lattice triangles using the HDF5 file format. It has the following fields:

  • preferences :: HDFBaeuerleStoragePreferences{T}
  • file_path :: String: The path of the HDF file to be generated.
  • last_completed_gorenstein_index :: Int: The last completed step of the classification. Initially, this will be 0.
  • total_count :: Int
source
RationalPolygons.classify_lattice_triangles_by_gorenstein_indexFunction
classify_lattice_triangles_by_gorenstein_index(ι :: T) where {T <: Integer}

Return all lattice triangles with gorenstein index ι.

Example

There are five lattice triangles with gorenstein index one:

julia> classify_lattice_triangles_by_gorenstein_index(1)
Set{RationalPolygon{Int64, 3}} with 5 elements:
  Rational polygon of rationality 1 with 3 vertices.
  Rational polygon of rationality 1 with 3 vertices.
  Rational polygon of rationality 1 with 3 vertices.
  Rational polygon of rationality 1 with 3 vertices.
  Rational polygon of rationality 1 with 3 vertices.
source
classify_lattice_triangles_by_gorenstein_index(st :: InMemoryBaeuerleStorage{T}, max_gorenstein_index :: T) where {T <: Integer}

Perform Bäuerle's classification of lattice triangles up go max_gorenstein_index, storing the results in memory.

Example

Reproduce Bäuerle's original classification up to gorenstein index 1000, see Theorem 1.4 of [11].

julia> st = InMemoryBaeuerleStorage{Int}()
InMemoryBaeuerleStorage{Int64}(Vector{RationalPolygon{Int64, 3, 6}}[], 0)

julia> classify_lattice_triangles_by_gorenstein_index(st, 1000);

julia> sum(length.(st.polygons))
2992229
source
classify_lattice_triangles_by_gorenstein_index(st :: HDFBaeuerleStorage{T}, max_gorenstein_index :: T; logging :: Bool = false) where {T <: Integer}

Perform Bäuerle's classification of lattice triangles up go max_gorenstein_index, storing the results in an HDF5 file

source

Lattice triangles by Picard index

[2] contains a classification of ldp triangles (toric log del Pezzo surfaces of rank one) by Picard index. RationalPolygons.jl implements a version of this algorithm, which successfully reproduces the numbers from Theorem 8.5 of [2].

RationalPolygons.HDFPicardIndexStorageType
mutable struct HDFPicardIndexStorage{T <: Integer} <: PicardIndexStorage{T}

A struct for managing classification results of Springer's classification of lattice triangles using the HDF5 file format. It has the following fields:

  • preferences :: HDFPicardIndexStoragePreferences{T}
  • file_path :: String: The path of the HDF file to be generated.
  • last_completed_picard_index :: Int: The last completed step of the classification. Initially, this will be 0.
  • total_count :: Int
source
RationalPolygons.classify_lattice_triangles_by_picard_indexFunction
classify_lattice_triangles_by_picard_index(p :: T) where {T <: Integer}

Return all lattice triangles with Picard index p.

Example

There are two lattice triangles with Picard index 6:

julia> classify_lattice_triangles_by_picard_index(6)
Set{RationalPolygon{Int64, 3, 6}} with 2 elements:
  Rational polygon of rationality 1 with 3 vertices.
  Rational polygon of rationality 1 with 3 vertices.
source
classify_lattice_triangles_by_picard_index(st :: InMemoryPicardIndexStorage{T}, max_picard_index :: T) where {T <: Integer}

Perform Springer's classification of lattice triangles up go max_picard_index, storing the results in memory.

Example

Reproduce Springer's original classification up to picard index 10000, see Theorem 1.2 of [2].

julia> st = InMemoryPicardIndexStorage{Int}()
InMemoryPicardIndexStorage{Int64}(Vector{RationalPolygon{Int64, 3, 6}}[], 0)

julia> classify_lattice_triangles_by_picard_index(st, 10000);

julia> sum(length.(st.polygons))
68053
source
classify_lattice_triangles_by_picard_index(st :: HDFPicardIndexStorage{T}, max_picard_index :: T; logging :: Bool = false) where {T <: Integer}

Perform Springer's classification of lattice triangles up go max_picard_index, storing the results in an HDF5 file

source

Maximal rational polygons contained in $\mathbb{R}\times[-1,1]$

Here we provide an implementation for Algorithm 3.4 of [1].

RationalPolygons.classify_maximal_polygons_m1p1Function
classify_maximal_polygons_m1p1(k :: T, i :: Int)

Return all maximal k-rational polygons with i interior lattice points that can be realized in $\mathbb{R} \times [-1,1]$.

Example

Compute the numbers of polygons for 1 ≤ k ≤ 5 and 0 ≤ i ≤ 10.

julia> [length(classify_maximal_polygons_m1p1(k,i)) for k = 1 : 5, i = 0 :10]
5×11 Matrix{Int64}:
  1    2    4    5    6    7    8    9   10   11   12
  4    9   13   18   22   26   30   34   38   42   46
 12   26   41   54   68   81   94  107  120  133  146
 24   57   86  117  145  174  203  231  259  288  316
 54  132  209  280  353  422  493  562  631  701  771
source

Maximal rational polygons with no interior lattice points

Here, we provide an implementation for Algorithm 4.4 of [1].

RationalPolygons.classify_maximal_lattice_free_polygons_m1p2_squaresFunction
classify_maximal_lattice_free_polygons_m1p2_squares(k :: T) where {T <: Integer}

Return all k-maximal polygons with no interior lattice points that are contained in $A \cup \mathbb{R} \times [-1,2] \cup B$ where $A$ is the square with vertices $(0,1),(1,1),(1,2),(0,2)$ and B is the square with vertices $(0,0),(0,-1),(1,-1),(1,0)$.

source
RationalPolygons.classify_maximal_lattice_free_polygons_m1p2_trapezoidsFunction
classify_maximal_lattice_free_polygons_m1p2_trapezoids(k :: T) where {T <: Integer}

Return all k-maximal polygons with no interior lattice points that are contained in $A \cup \mathbb{R} \times [-1,2] \cup B$ where $A$ is the trapezoid with vertices $(-1,2),(0,1),(1,1),(1,2)$ and $B$ is the trapezoid with vertices $(0,0),(0,-1),(2,-1),(1,0)$, excluding the polygons from classify_maximal_lattice_free_polygons_m1p2_squares.

source
RationalPolygons.classify_maximal_lattice_free_polygons_m1p2Function
classify_maximal_lattice_free_polygons_m1p2(k :: T) where {T <: Integer}

Return all k-maximal polygons with no interior lattice points contained in $\mathbb{R} \times [-1,2]$. This is simply the union of classify_maximal_lattice_free_polygons_m1p2_squares and classify_maximal_lattice_free_polygons_m1p2_trapezoids.

source
RationalPolygons.classify_maximal_lattice_free_polygonsFunction
classify_maximal_lattice_free_polygons(k :: T ; logging = false) where {T <: Integer}

Return all k-rational polygons with no interior lattice points.

Example

Compute the numbers of polygons for 1 ≤ k ≤ 6:

julia> length.(classify_maximal_lattice_free_polygons.(1:6))
6-element Vector{Int64}:
   1
   4
  14
  39
 134
 299
source

Rational polygons with one interior lattice point

Here, we provide an implementation of Algorithm 5.4 of [1].

RationalPolygons.classify_maximal_polygons_genus_one_m1p1Function
classify_maximal_polygons_genus_one_m1p1(k :: T) where {T <: Integer}

Return all maximal k-rational polygons with exactly one interior lattice point that can be realized in $\mathbb{R} \times [-1,1]$. If primitive = true is passed, then only primitive polygons (i.e. ldp polygons) are returned.

source
RationalPolygons.classify_maximal_polygons_genus_one_m1p2Function
classify_maximal_polygons_genus_one_m1p2(k :: T) where {T <: Integer}

Return all maximal k-rational polygons with exactly one interior lattice point that can be realized in $\mathbb{R} \times [-1,2]$. If primitive = true is passed, then only primitive polygons (i.e. ldp polygons) are returned.

source
RationalPolygons.classify_maximal_polygons_genus_one_m2p2Function
classify_maximal_polygons_genus_one_m2p2(k :: T, q :: Int) where {T <: Integer}

Return all maximal k-rational polygons with exactly one interior lattice point that can be realized in $\mathbb{R} \times [-2,2]$ that have non-empty intersection with the q-th classification box, where 1 ≤ q ≤ 3. If primitive = true is passed, then only primitive polygons (i.e. ldp polygons) are returned.

source
RationalPolygons.classify_maximal_polygons_genus_oneFunction
classify_maximal_polygons_genus_one(k :: T) where {T <: Integer}

Return all maximal k-rational polygons with exactly one interior lattice point. If primitive = true is passed, then only primitive polygons (i.e. ldp polygons) are returned.

Example

Compute the numbers of polygons for $k ≤ 3$.

julia> length.(classify_maximal_polygons_genus_one.(1:3))
4-element Vector{Int64}:
   3
  10
  39
source
RationalPolygons.classify_polygons_genus_oneFunction
classify_polygons_genus_one(k :: T) where {T <: Integer}

Compute all k-rational polygons with exactly one interior lattice point. The following keyword arguments are supported:

  • primitive :: Bool. If set to true, only primitive polygons (i.e. ldp polygons) are returned.
  • logging :: Bool. Controls whether to display logging messages showing the

current progress.

Example

Reproduce the classifcation of all 5145 half-integral polygons with exactly one interior lattice point. It first computes all maximal polygons with classify_maximal_polygons_genus_one and then generates all their subpolygons.

julia> classify_polygons_genus_one(2; logging=true);
[ Info: Found 9 maximal polygons in QQ x [-1,1]. New: 9, total: 9
[ Info: Found 2 maximal polygons in QQ x [-1,2]. New: 1, total: 10
[ Info: Found 0 maximal polygons in QQ x [-2,2], box 1. New: 0, total: 10
[ Info: Found 3 maximal polygons in QQ x [-2,2], box 2. New: 0, total: 10
[ Info: Found 3 maximal polygons in QQ x [-2,2], box 3. New: 0, total: 10
[ Info: [a = 36]. Polygons to peel: 2.
[ Info: [a = 36]. Peeling complete. New polygons: 2. Running total: 12
[ Info: [a = 35]. Polygons to peel: 2.
[ Info: [a = 35]. Peeling complete. New polygons: 5. Running total: 17
[ Info: [a = 34]. Polygons to peel: 5.
[ Info: [a = 34]. Peeling complete. New polygons: 10. Running total: 27
[ Info: [a = 33]. Polygons to peel: 9.
[ Info: [a = 33]. Peeling complete. New polygons: 19. Running total: 46
[ Info: [a = 32]. Polygons to peel: 23.
[ Info: [a = 32]. Peeling complete. New polygons: 45. Running total: 91
[ Info: [a = 31]. Polygons to peel: 31.
[ Info: [a = 31]. Peeling complete. New polygons: 69. Running total: 160
[ Info: [a = 30]. Polygons to peel: 60.
[ Info: [a = 30]. Peeling complete. New polygons: 115. Running total: 275
[ Info: [a = 29]. Polygons to peel: 84.
[ Info: [a = 29]. Peeling complete. New polygons: 170. Running total: 445
[ Info: [a = 28]. Polygons to peel: 137.
[ Info: [a = 28]. Peeling complete. New polygons: 239. Running total: 684
[ Info: [a = 27]. Polygons to peel: 171.
[ Info: [a = 27]. Peeling complete. New polygons: 285. Running total: 969
[ Info: [a = 26]. Polygons to peel: 240.
[ Info: [a = 26]. Peeling complete. New polygons: 364. Running total: 1333
[ Info: [a = 25]. Polygons to peel: 286.
[ Info: [a = 25]. Peeling complete. New polygons: 440. Running total: 1773
[ Info: [a = 24]. Polygons to peel: 356.
[ Info: [a = 24]. Peeling complete. New polygons: 466. Running total: 2239
[ Info: [a = 23]. Polygons to peel: 351.
[ Info: [a = 23]. Peeling complete. New polygons: 433. Running total: 2672
[ Info: [a = 22]. Polygons to peel: 396.
[ Info: [a = 22]. Peeling complete. New polygons: 439. Running total: 3111
[ Info: [a = 21]. Polygons to peel: 391.
[ Info: [a = 21]. Peeling complete. New polygons: 394. Running total: 3505
[ Info: [a = 20]. Polygons to peel: 390.
[ Info: [a = 20]. Peeling complete. New polygons: 338. Running total: 3843
[ Info: [a = 19]. Polygons to peel: 349.
[ Info: [a = 19]. Peeling complete. New polygons: 269. Running total: 4112
[ Info: [a = 18]. Polygons to peel: 357.
[ Info: [a = 18]. Peeling complete. New polygons: 249. Running total: 4361
[ Info: [a = 17]. Polygons to peel: 301.
[ Info: [a = 17]. Peeling complete. New polygons: 215. Running total: 4576
[ Info: [a = 16]. Polygons to peel: 292.
[ Info: [a = 16]. Peeling complete. New polygons: 178. Running total: 4754
[ Info: [a = 15]. Polygons to peel: 233.
[ Info: [a = 15]. Peeling complete. New polygons: 121. Running total: 4875
[ Info: [a = 14]. Polygons to peel: 191.
[ Info: [a = 14]. Peeling complete. New polygons: 91. Running total: 4966
[ Info: [a = 13]. Polygons to peel: 140.
[ Info: [a = 13]. Peeling complete. New polygons: 71. Running total: 5037
[ Info: [a = 12]. Polygons to peel: 121.
[ Info: [a = 12]. Peeling complete. New polygons: 40. Running total: 5077
[ Info: [a = 11]. Polygons to peel: 67.
[ Info: [a = 11]. Peeling complete. New polygons: 21. Running total: 5098
[ Info: [a = 10]. Polygons to peel: 56.
[ Info: [a = 10]. Peeling complete. New polygons: 14. Running total: 5112
[ Info: [a = 9]. Polygons to peel: 38.
[ Info: [a = 9]. Peeling complete. New polygons: 13. Running total: 5125
[ Info: [a = 8]. Polygons to peel: 31.
[ Info: [a = 8]. Peeling complete. New polygons: 13. Running total: 5138
[ Info: [a = 7]. Polygons to peel: 14.
[ Info: [a = 7]. Peeling complete. New polygons: 3. Running total: 5141
[ Info: [a = 6]. Polygons to peel: 13.
[ Info: [a = 6]. Peeling complete. New polygons: 3. Running total: 5144
[ Info: [a = 5]. Polygons to peel: 4.
[ Info: [a = 5]. Peeling complete. New polygons: 1. Running total: 5145
[ Info: [a = 4]. Polygons to peel: 3.
[ Info: [a = 4]. Peeling complete. New polygons: 0. Running total: 5145
[ Info: [a = 3]. Polygons to peel: 1.
[ Info: [a = 3]. Peeling complete. New polygons: 0. Running total: 5145
[ Info: [a = 2]. Polygons to peel: 0.
[ Info: [a = 2]. Peeling complete. New polygons: 0. Running total: 5145
[ Info: [a = 1]. Polygons to peel: 0.
[ Info: [a = 1]. Peeling complete. New polygons: 0. Running total: 5145
source

Almost $k$-hollow LDP polygons

We can instruct classify_polygons_genus_one to only output k-rational polygons with primitive vertices. These are exactly the almost $k$-hollow LDP polygons and they correspond to $1/k$-log canonical toric del Pezzo surfaces. In particular, we can reproduce the classification of the 48032 almost 3-hollow LDP polygons ($1/3$-log canonical toric del Pezzo surfaces) from Theorem 4.11 of [4]. See also Table 6 of [1] for the classification up to $k = 6$.

julia> Pss = [classify_polygons_genus_one(k; primitive=true) for k = 1 : 3];

julia> numbers_of_polygons = length.(Pss)
3-element Vector{Int64}:
    16
   505
 48032

julia> max_vertices = [maximum(number_of_vertices.(Pss[k])) for k = 1 : 3]
3-element Vector{Int64}:
  6
  8
 12

julia> max_volumes = [k^2 * maximum(euclidian_area.(Pss[k])) for k = 1 : 3]
3-element Vector{Rational{Int64}}:
 9//2
 17
 47