Classifications
RationalPolygons.jl implements the following classification algorithms:
- Lattice polygons by number of lattice points from R.J. Koelman [7],
- Lattice polygons by number of interior lattice points from Castryck [8],
- Lattice polygons contained in a square from Brown and Kasprzyk [9],
- Lattice polygons by Gorenstein index from Kasprzyk, Kreuzer and Nill [10],
- Lattice triangles by Gorenstein index from Andreas Bäuerle [11].
- Lattice triangles by Picard index from Justus Springer [2].
Moreover, the classifications from [1] are implemented:
- Maximal rational polygons contained in $\mathbb{R}\times[-1,1]$,
- Maximal rational polygons with no interior lattice points,
- Rational polygons with one interior lattice point,
- Almost $k$-hollow LDP polygons.
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_points
— Functionheight_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)
.
RationalPolygons.single_point_extensions
— Functionsingle_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.
RationalPolygons.KoelmanStorage
— Typeabstract 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.
RationalPolygons.InMemoryKoelmanStorage
— Typemutable 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
.
RationalPolygons.HDFKoelmanStoragePreferences
— Typestruct 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 totrue
.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 to100
, 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 to10^6
.
RationalPolygons.HDFKoelmanStorage
— Typemutable 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 be3
.total_count :: Int
RationalPolygons.classify_next_number_of_lattice_points
— Functionclassify_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.
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.
RationalPolygons.classify_polygons_by_number_of_lattice_points
— Functionclassify_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
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.classify_maximal_lattice_polygons_with_collinear_interior_points
— Functionclassify_maximal_lattice_polygons_with_collinear_interior_points(i :: Int, T :: Type{<:Integer} = Int)
Return all maximal lattice polygons with i
collinear interior lattice points.
RationalPolygons.classify_maximal_lattice_polygons_with_two_dimensional_empty_fine_interior
— Functionclassify_maximal_lattice_polygons_with_two_dimensional_empty_fine_interior(i :: Int, T :: Type{<:Integer} = Int)
Return all maximal lattice polygons with i
interior lattice points, where the convex hull of these points is a two-dimensional lattice polygon without interior lattice points.
RationalPolygons.CastryckStorage
— Typeabstract 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.
RationalPolygons.InMemoryCastryckStorage
— Typemutable 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 to100
.maximal_polygons :: Vector{Vector{RationalPolygon{T}}}
,all_polygons :: Vector{Vector{RationalPolygon{T}}}
,total_count :: Int
.
RationalPolygons.HDFCastryckStoragePreferences
— Typestruct 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 totrue
.maximum_genus :: Int
: An upper bound for the maximal number of interior lattice points to which the classification should be run. Defaults to100
.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 to100
, 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 to10^6
.
RationalPolygons.HDFCastryckStorage
— Typemutable 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 be0
.total_count :: Int
RationalPolygons.classify_next_genus
— Functionclassify_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)
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.
RationalPolygons.classify_lattice_polygons_by_genus
— Functionclassify_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
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.PartialLDP
— TypePartialLDP{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].
RationalPolygons.initial_special_facets
— Functioninitial_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].
RationalPolygons.choose_next_vertex
— Functionchoose_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].
RationalPolygons.classify_lattice_polygons_by_gorenstein_index
— Functionclassify_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
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_three
— Functionunit_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)
RationalPolygons.BaeuerleStorage
— Typeabstract type BaeuerleStorage{T <: Integer} end
Abstract supertype of InMemoryBaeuerleStorage
and HDFBaeuerleStorage
.
RationalPolygons.InMemoryBaeuerleStorage
— Typemutable struct InMemoryBaeuerleStorage{T <: Integer} <: BaeuerleStorage{T}
A struct holding classification results of Baeuerle's classification of lattice triangles by gorenstein index.
RationalPolygons.HDFBaeuerleStorage
— Typemutable 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 be0
.total_count :: Int
RationalPolygons.classify_lattice_triangles_by_gorenstein_index
— Functionclassify_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.
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
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
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.quadruple_decompositions
— Functionquadruple_decompositions(p :: T) where {T <: Integer}
Return all quadruples (n,w0,w1,w2)
such that n^2 * w0 * w1 * w2 == n
.
RationalPolygons.PicardIndexStorage
— Typeabstract type PicardIndexStorage{T <: Integer} end
Abstract supertype of InMemoryPicardIndexStorage
and HDFPicardIndexStorage
.
RationalPolygons.InMemoryPicardIndexStorage
— Typemutable struct InMemoryPicardIndexStorage{T <: Integer} <: PicardIndexStorage{T}
A struct holding classification results of Springer's classification of lattice triangles by picard index.
RationalPolygons.HDFPicardIndexStorage
— Typemutable 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 be0
.total_count :: Int
RationalPolygons.classify_lattice_triangles_by_picard_index
— Functionclassify_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.
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
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
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_m1p1
— Functionclassify_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
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_squares
— Functionclassify_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)$.
RationalPolygons.classify_maximal_lattice_free_polygons_m1p2_trapezoids
— Functionclassify_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
.
RationalPolygons.classify_maximal_lattice_free_polygons_m1p2
— Functionclassify_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
.
RationalPolygons.classify_maximal_lattice_free_polygons
— Functionclassify_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
Rational polygons with one interior lattice point
Here, we provide an implementation of Algorithm 5.4 of [1].
RationalPolygons.classify_maximal_polygons_genus_one_m1p1
— Functionclassify_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.
RationalPolygons.classify_maximal_polygons_genus_one_m1p2
— Functionclassify_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.
RationalPolygons.classify_maximal_polygons_genus_one_m2p2
— Functionclassify_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.
RationalPolygons.classify_maximal_polygons_genus_one
— Functionclassify_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
RationalPolygons.classify_polygons_genus_one
— Functionclassify_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
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