Classifications
RationalPolygons.jl
provides implementations of the classification algorithms from [2]:
- 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.
Moreover, we have reimplemented several other classifications of polygons:
- Lattice polygons by number of lattice points from R.J. Koelman [8],
- Lattice polygons by number of interior lattice points from Castryck [9],
- Lattice polygons contained in a square from Brown and Kasprzyk [10],
- LDP polygons by Gorenstein index from Kasprzyk, Kreuzer and Nill [11],
- LDP triangles by Gorenstein index from Andreas Bäuerle [12],
- LDP triangles by Picard index from Justus Springer [4],
- LDP triangles with integral degree from Hausen and Király [13].
- LDP quadrangles by Gorenstein index from Justus Springer.
Maximal rational polygons contained in $\mathbb{R}\times[-1,1]$
This is an implementation of Algorithm 3.4 from [2].
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
This is an implementation of Algorithm 4.4 from [2].
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
This is an implementation of Algorithm 5.4 of [2].
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 [6]. See also Table 6 of [2] 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(euclidean_area.(Pss[k])) for k = 1 : 3]
3-element Vector{Rational{Int64}}:
9//2
17
47
Lattice polygons by number of lattice points
R.J. Koelman [8] gave 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 [8]. We have implemented their algorithm here, which successfully reproduces their numbers. See also A371917 on OEIS for the numbers up to $112$ lattice points.
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 datasetnumbers_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
.
Example:
Reproduce Koelman's original classification in memory, see Table 4.4.3 of [8] 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 store 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"); # 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
Castryck [9] gave an algorithm to classify lattice polygons by number of interior lattice points and ran it up to 30 interior lattice points. Our implementation here successfully reproduces their numbers from Table 1 of [9], 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. It has the following fields:
maximum_genus :: Int
: An upper bound for the maximum number of lattice points 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 datasetnumbers_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
.
Example:
Reproduce Castryck's classification in memory, see Table 1 of [9] 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 store 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
, etc., 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
Brown and Kasprzyk [10] 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 [10], 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
LDP polygons by Gorenstein index
Kasprzyk, Kreuzer and Nill [11] gave 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 [11]).
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 [11].
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 [11].
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 [11].
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 [11].
Example:
There are 91 LDP polygons of Gorenstein index four: 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
LDP triangles by Gorenstein index
Bäuerle [12] gave an algorithm to classify 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 successfully (see Theorem 1.4 of [12] 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
and a ≤ 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 Bäuerle'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 [12].
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
LDP triangles by Picard index
Springer [4] gave an algorithm to classify 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 [4].
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 [4].
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
LDP triangles with integral degree
Hausen and Király [13] classified fake weighted projective planes having integral degree (=canonical self intersection). In terms of polygons, these can be described as LDP triangles such that twice the euclidean area of its dual is an integer. The attained values of this integer (which is the degree of the associated fake weighted projective plane) are the integers from $1$ to $9$, excluding $7$. In total, there are 24 infinite series of these triangles, where each of them is parameterized by the solution set of a squared Markov type equation (see Theorem 1.1 of [13]). These solution sets can be described as infinite binary trees with a unique root. RationalPolygons.jl
uses this description to implement a classification algorithm for LDP triangles with integral degree. To make this classification finite, one has to provide a maximal depth to which the solution trees are traversed.
All methods used for this classification come with a parameter T <: Integer
, which is the integer type to be used. Since the entries of the solution triples of squared Markov type equations grow very quickly with increasing depth, it is recommended to use BigInt
here instead of fixed-size integer types (Int64
overflows already for depth = 4
).
RationalPolygons.degree
— Methoddegree(w :: SVector{3})
Return the degree of a fake weighted projective plane with given fake weight vector w
. This is given by the formula sum(w)^2 // prod(w)
, see for instance Proposition 3.7 of [13].
RationalPolygons.fake_weight_vector
— Functionfake_weight_vector(P :: RationalPolygon{T,3}) where {T <: Integer}
Return the fake weight vector of the fake weighted projective plane associated to the LDP triangle P
.
RationalPolygons.n_step_mutations
— Functionn_step_mutations(us :: Set{SVector{3,T}}, depth :: Int) where {T <: Integer}
Given solution triples us
of a squared Markov type equation, return all solution triples that can be obtained from us
by applying at most depth
many mutations. This function returns a vector of length depth+1
, containing for each level i = 0 : depth
the set of solution triples after exactly i
mutation steps.
Example:
Get all solutions to the squared Markov type equation $9xyz=(x+y+z)^2$ by starting with the initial solution $(1,1,1)$ and applying at most four mutations. Compare with $T(9)$ of Remark 2.5 of [13].
julia> us = Set([SVector{3,Int}(1,1,1)])
Set{SVector{3, Int64}} with 1 element:
[1, 1, 1]
julia> n_step_mutations(us, 4)
5-element Vector{Set{SVector{3, Int64}}}:
Set([[1, 1, 1]])
Set([[1, 1, 4]])
Set([[1, 4, 25]])
Set([[4, 25, 841], [1, 25, 169]])
Set([[25, 169, 37636], [25, 841, 187489], [1, 169, 1156], [4, 841, 28561]])
RationalPolygons.initial_triple
— Functioninitial_triple(:: Val{A}, T :: Type{<:Integer} = BigInt)
Return the unique initial triple of the squared Markov type equation $Axyz = (x+y+z)^2$. Allowed values of A
are 9, 8, 6 and 5.
Example:
The unique initial triples for all allowed values of A
, see Theorem 2.2 of [13].
julia> [initial_triple(Val(A)) for A in [9,8,6,5]]
4-element Vector{SVector{3, BigInt}}:
[1, 1, 1]
[1, 1, 2]
[1, 2, 3]
[1, 4, 5]
RationalPolygons.adjust_triple
— Functionadjust_triple(::Val{A}, u :: SVector{3,T}) where {T <: Integer}
adjust_triple(u :: SVector{3,T}) where {T <: Integer}
Reorder a solution triple of a squared Markov type equation to make it adjusted, according to Definition 3.14 of [13]. Allowed values of A
are 9, 8, 6 and 5. If A
is not given, it is determined by calculating the degree of u
.
Example:
The solution triple $(50,9,3481)$ for $A=8$ is not adjusted, since the even entry is not last.
julia> adjust_triple(Val(8), SVector{3,Int}(50,9,3481))
3-element SVector{3, Int64} with indices SOneTo(3):
9
3481
50
RationalPolygons.classify_squared_markov_type_equation_solutions
— Functionclassify_squared_markov_type_equation_solutions(::Val{A}, depth :: Int, T :: Type{<:Integer} = BigInt) where {A}
Return all solutions to the squared Markov type equation $Axyz = (x+y+z)^2$ by starting with the initial solution and applying at most depth
many mutations. Allowed values of A
are 9, 8, 6 and 5.
Example:
All solution triples to $8xyz = (x+y+z)^2$ with depth at most three.
julia> classify_squared_markov_type_equation_solutions(Val(8),3)
4-element Vector{Set{SVector{3, BigInt}}}:
Set([[1, 1, 2]])
Set([[1, 2, 9]])
Set([[2, 9, 121], [1, 9, 50]])
Set([[9, 50, 3481], [2, 121, 1681], [1, 50, 289], [9, 121, 8450]])
RationalPolygons.fake_weight_vectors_to_triangles
— Functionfake_weight_vectors_to_triangles(us :: Set{SVector{3,T}}, μ :: T) where {T <: Integer}
Given a set of triples us
sharing the same integral degree A
and an integer μ
, return all LDP triangles having fake weight vector μ * u
. Allowed values of A
are 9, 8, 6 and 5. Moreover, μ
must be a divisor of A
. The resulting triangles will have degree A ÷ μ
and multiplicity μ
.
RationalPolygons.classify_lattice_triangles_integral_degree
— Functionclassify_lattice_triangles_integral_degree(::Val{K}, ::Val{μ}, depth :: Int, T :: Type{<:Integer} = BigInt) where {K, μ}
Return all LDP triangles (= fake weighted projective planes) with integral degree K
and class group torsion order μ
, up to a given depth in the Markov tree. Essentially, this returns the triangles of the series (K-μ-*) according to the notation of Theorem 1.1 of [13]. Allowed values of K
are 1, 2, 3, 4, 5, 6, 8 and 9. Allowed values of μ
are all integers such that μ * K
is 5, 6, 8 or 9.
Example:
Compute all LDP triangles of degree 1 and class group torsion order 9, up to Markov depth 5. These consist of the three series (1-9-2), (1-9-5) and (1-9-8) from Theorem 1.1 of [13]. Note that for depths zero and one (which correspond to solution triples (1,1,1) and (1,1,4) in the Markov tree), the series overlap, hence there are only one resp. two triangles in this case, which is also mentioned in the Theorem. After that, the number of triangles doubles with each additional step.
julia> Pss = classify_lattice_triangles_integral_degree(Val(1), Val(9), 5);
julia> length.(Pss)
6-element Vector{Int64}:
1
2
3
6
12
24
classify_lattice_triangles_integral_degree(::Val{K}, depth :: Int, T :: Type{<:Integer} = BigInt) where {K}
Return all LDP triangles (= fake weighted projective planes) with integral degree K
, up to a given depth in the Markov tree. Essentially, this returns the triangles of the series (K - * - *) according to the notation of Theorem 1.1 of [13]. Allowed values of K
are 1, 2, 3, 4, 5, 6, 8 and 9.
Example:
Print the numbers of LDP triangles with integral degree K
, for all possible values of K
, up to depth 10.
julia> [length.(classify_lattice_triangles_integral_degree(Val(K), 10)) for K in [1,2,3,4,5,6,8,9]]
8-element Vector{Vector{Int64}}:
[10, 18, 35, 70, 140, 280, 560, 1120, 2240, 4480, 8960]
[4, 6, 12, 24, 48, 96, 192, 384, 768, 1536, 3072]
[2, 3, 5, 10, 20, 40, 80, 160, 320, 640, 1280]
[1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
[1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
[1, 1, 1, 2, 4, 8, 16, 32, 64, 128, 256]
classify_lattice_triangles_integral_degree(depth :: Int, T :: Type{<:Integer} = BigInt)
Return all LDP triangles (= fake weighted projective planes) with integral degree, up to a given depth in the Markov tree. This returns the union of all 24 series classified in Theorem 1.1 of [13].
LDP quadrangles by Gorenstein index
The following is a classification of LDP quadrangles by Gorenstein index. A reference explaining the approach used will be added in the future.
RationalPolygons.modified_unit_fraction_solutions
— Functionmodified_unit_fraction_solutions(r :: T, s :: T, c :: T, d :: T) where {T <: Integer}
Return all integral solutions $(x,y) ∈ \mathbb{Z}^2_{\geq 1}$ to the equation $r/s = 1/x + 1/y - c/(d*y)$. Returns an error if there are infinitely many solutions, which happens if and only if $c = d$.
RationalPolygons.gorenstein_coefficients_to_degree_matrix_minors
— Functiongorenstein_coefficients_to_degree_matrix_minors(ι :: T, A :: SMatrix{4,2,T,8}) where {T <: Integer}
Compute all minors of the Fano ι-Gorenstein matrix Q associated with the Gorenstein coefficients A.
RationalPolygons.classify_gorenstein_coefficients
— Functionclassify_gorenstein_coefficients(ι :: T, ::Val{t})
classify_gorenstein_coefficients(ι :: T)
Classify Gorenstein coefficients associated to Fano ι-Gorenstein matrices. Optionally takes in a Val{t}
argument, where t
can be 1, 2, 3 or 4. In this case, only the Gorenstein coefficients of type t
are classified.
RationalPolygons.gorenstein_coefficients_normal_form
— Functiongorenstein_coefficients_normal_form(A :: SMatrix{4,2,T,8}) where {T <: Integer}
Bring Gorenstein coefficients $A \in \mathbb{Z}^{2 \times 4}$ into normal form, see Definition ?? of ??.
RationalPolygons.classify_quadrilaterals_by_gorenstein_index
— Functionclassify_quadrilaterals_by_gorenstein_index(ι :: Integer)
Return all LDP quadrilaterals with Gorenstein index ι.
Example:
There are 73725 distinct LDP quadrilaterals with Gorenstein index at most 50.
julia> Pss = classify_quadrilaterals_by_gorenstein_index.(1:50);
julia> sum(length.(Pss))
73725