amari_enumerative/
moduli_space.rs1use crate::{EnumerativeError, EnumerativeResult};
8use num_rational::Rational64;
9use std::collections::HashMap;
10
11#[derive(Debug, Clone)]
13pub struct ModuliSpace {
14 pub genus: usize,
16 pub marked_points: usize,
18 pub stable: bool,
20}
21
22impl ModuliSpace {
23 pub fn new(genus: usize, marked_points: usize, stable: bool) -> EnumerativeResult<Self> {
25 if stable && 2 * genus + marked_points < 3 && !(genus == 0 && marked_points == 0) {
28 return Err(EnumerativeError::InvalidDimension(format!(
29 "Unstable parameters: g={}, n={}",
30 genus, marked_points
31 )));
32 }
33
34 Ok(Self {
35 genus,
36 marked_points,
37 stable,
38 })
39 }
40
41 pub fn dimension(&self) -> usize {
43 if self.stable {
44 if 3 * self.genus >= 3 {
47 3 * self.genus - 3 + self.marked_points
48 } else {
49 self.marked_points.saturating_sub(3)
51 }
52 } else {
53 if self.genus == 0 && self.marked_points >= 3 {
55 self.marked_points - 3
56 } else if self.genus >= 2 {
57 3 * self.genus - 3
58 } else {
59 0
60 }
61 }
62 }
63
64 pub fn is_nonempty(&self) -> bool {
66 if self.stable {
67 2 * self.genus - 2 + self.marked_points > 0
68 } else {
69 true }
71 }
72
73 pub fn intersection_number(
75 &self,
76 classes: &[TautologicalClass],
77 ) -> EnumerativeResult<Rational64> {
78 if classes.is_empty() {
82 return Ok(Rational64::from(1));
83 }
84
85 let total_degree: usize = classes.iter().map(|c| c.degree).sum();
87 if total_degree != self.dimension() {
88 return Ok(Rational64::from(0));
89 }
90
91 match (self.genus, self.marked_points, classes.len()) {
93 (0, 3, 0) => Ok(Rational64::from(1)), (1, 1, 1) => {
95 Ok(Rational64::new(1, 24))
97 }
98 _ => {
99 Ok(Rational64::from(0))
101 }
102 }
103 }
104}
105
106#[derive(Debug, Clone, PartialEq)]
108pub struct TautologicalClass {
109 pub class_type: TautologicalType,
111 pub degree: usize,
113 pub index: Option<usize>,
115}
116
117impl TautologicalClass {
118 pub fn psi(index: usize) -> Self {
120 Self {
121 class_type: TautologicalType::Psi,
122 degree: 1,
123 index: Some(index),
124 }
125 }
126
127 pub fn kappa(degree: usize) -> Self {
129 Self {
130 class_type: TautologicalType::Kappa,
131 degree,
132 index: None,
133 }
134 }
135
136 pub fn lambda(degree: usize) -> Self {
138 Self {
139 class_type: TautologicalType::Lambda,
140 degree,
141 index: None,
142 }
143 }
144}
145
146#[derive(Debug, Clone, PartialEq)]
148pub enum TautologicalType {
149 Psi,
151 Kappa,
153 Lambda,
155}
156
157#[derive(Debug, Clone, PartialEq)]
159pub struct CurveClass {
160 pub target: String,
162 pub degree_data: HashMap<String, i64>,
164 pub genus: usize,
166}
167
168impl CurveClass {
169 pub fn new(target: String, genus: usize) -> Self {
171 Self {
172 target,
173 degree_data: HashMap::new(),
174 genus,
175 }
176 }
177
178 pub fn set_degree(&mut self, class_name: String, degree: i64) {
180 self.degree_data.insert(class_name, degree);
181 }
182
183 pub fn get_degree(&self, class_name: &str) -> i64 {
185 self.degree_data.get(class_name).copied().unwrap_or(0)
186 }
187
188 pub fn is_rational(&self) -> bool {
190 self.genus == 0
191 }
192}
193
194#[derive(Debug, Clone)]
196pub struct ModuliOfStableMaps {
197 pub domain: ModuliSpace,
199 pub target: String,
201 pub curve_class: CurveClass,
203}
204
205impl ModuliOfStableMaps {
206 pub fn new(domain: ModuliSpace, target: String, curve_class: CurveClass) -> Self {
208 Self {
209 domain,
210 target,
211 curve_class,
212 }
213 }
214
215 pub fn expected_dimension(&self) -> EnumerativeResult<i64> {
217 let moduli_dim = self.domain.dimension() as i64;
221
222 let target_dim = match self.target.as_str() {
224 "P1" => 1,
225 "P2" => 2,
226 "P3" => 3,
227 _ => 2, };
229
230 let degree = self.curve_class.get_degree("H"); let first_chern_integral = (target_dim + 1) * degree;
232
233 let expected_dim =
234 moduli_dim + first_chern_integral + (target_dim - 3) * (1 - self.domain.genus as i64);
235
236 Ok(expected_dim)
237 }
238
239 pub fn has_expected_dimension(&self) -> EnumerativeResult<bool> {
241 let expected = self.expected_dimension()?;
242 Ok(expected >= 0)
243 }
244}