1use oxilean_kernel::{Declaration, Environment, Expr, Level, Name};
6
7use super::types::{
8 AtkinLehnerInvolution, AutomorphicRepresentation, DirichletCharacter, EisensteinSeries,
9 HeckeLFunction, HeckeOperator, HeckeOperatorDataMatrix, Mat2x2, ModularCurve, ModularCurveType,
10 ModularForm, ModularFormCusp, ModularSymbol, MoonshineDatum, NewformDecomposition,
11 PeterssonInnerProduct, QExpansion, RamanujanTau, RamanujanTauFunction,
12 RankinSelbergConvolution, ShimuraVariety, SiegelModularForm,
13};
14
15pub type HeckeOperatorMatrix = HeckeOperatorDataMatrix;
17
18pub fn cst(s: &str) -> Expr {
19 Expr::Const(Name::str(s), vec![])
20}
21pub fn prop() -> Expr {
22 Expr::Sort(Level::zero())
23}
24pub fn type0() -> Expr {
25 Expr::Sort(Level::succ(Level::zero()))
26}
27pub fn nat_ty() -> Expr {
28 cst("Nat")
29}
30pub fn int_ty() -> Expr {
31 cst("Int")
32}
33pub fn real_ty() -> Expr {
34 cst("Real")
35}
36pub fn complex_ty() -> Expr {
37 cst("Complex")
38}
39pub fn bool_ty() -> Expr {
40 cst("Bool")
41}
42pub fn arrow(a: Expr, b: Expr) -> Expr {
43 Expr::Pi(
44 oxilean_kernel::BinderInfo::Default,
45 Name::str("_"),
46 Box::new(a),
47 Box::new(b),
48 )
49}
50pub fn arrow3(a: Expr, b: Expr, c: Expr) -> Expr {
51 arrow(a, arrow(b, c))
52}
53pub fn arrow4(a: Expr, b: Expr, c: Expr, d: Expr) -> Expr {
54 arrow(a, arrow3(b, c, d))
55}
56pub fn arrow5(a: Expr, b: Expr, c: Expr, d: Expr, e: Expr) -> Expr {
57 arrow(a, arrow4(b, c, d, e))
58}
59pub fn sigma_k_minus_1(n: u64, k: u32) -> u64 {
61 if n == 0 {
62 return 0;
63 }
64 let mut result = 0u64;
65 let exp = k.saturating_sub(1);
66 for d in 1..=n {
67 if n % d == 0 {
68 result = result.saturating_add(d.saturating_pow(exp));
69 }
70 }
71 result
72}
73pub fn eisenstein_fourier_coeff(n: u64, k: u32) -> u64 {
76 if n == 0 {
77 1
78 } else {
79 sigma_k_minus_1(n, k)
80 }
81}
82pub fn ramanujan_tau_up_to(n_max: usize) -> Vec<i64> {
86 let mut coeffs = vec![0i64; n_max + 1];
87 let size = n_max + 1;
88 let mut prod = vec![0i64; size];
89 prod[0] = 1;
90 for m in 1..size {
91 for _ in 0..24 {
92 for j in (m..size).rev() {
93 prod[j] -= prod[j - m];
94 }
95 }
96 }
97 for n in 1..=n_max {
98 if n >= 1 {
99 coeffs[n] = *prod.get(n - 1).unwrap_or(&0);
100 }
101 }
102 coeffs[0] = 0;
103 coeffs
104}
105pub fn check_ramanujan_congruence(n_max: usize) -> bool {
107 let taus = ramanujan_tau_up_to(n_max);
108 for n in 1..=n_max {
109 let tau_n = taus[n].rem_euclid(691) as u64;
110 let sigma11_n = sigma_k_minus_1(n as u64, 12) % 691;
111 if tau_n != sigma11_n {
112 return false;
113 }
114 }
115 true
116}
117pub fn r2(n: u64) -> u64 {
119 if n == 0 {
120 return 1;
121 }
122 let mut count = 0u64;
123 let bound = (n as f64).sqrt() as i64 + 1;
124 for a in -bound..=bound {
125 let b2 = n as i64 - a * a;
126 if b2 < 0 {
127 continue;
128 }
129 let b = (b2 as f64).sqrt() as i64;
130 if b * b == b2 {
131 count += 1;
132 if b > 0 {
133 count += 1;
134 }
135 }
136 }
137 count
138}
139pub fn hecke_tp_coefficients(a: &[i64], p: u64, k: u32) -> Vec<i64> {
143 let n_max = a.len();
144 let mut b = vec![0i64; n_max];
145 let pk1 = (p as i64).pow(k.saturating_sub(1));
146 for n in 0..n_max {
147 let pn = (n as u64).saturating_mul(p) as usize;
148 b[n] = if pn < n_max { a[pn] } else { 0 };
149 if n as u64 % p == 0 {
150 let np = (n as u64 / p) as usize;
151 b[n] += pk1 * a[np];
152 }
153 }
154 b
155}
156pub fn modular_group_ty() -> Expr {
158 type0()
159}
160pub fn psl2z_ty() -> Expr {
162 type0()
163}
164pub fn generator_s_ty() -> Expr {
166 cst("ModularGroup")
167}
168pub fn generator_t_ty() -> Expr {
170 cst("ModularGroup")
171}
172pub fn fundamental_domain_ty() -> Expr {
174 type0()
175}
176pub fn congruence_subgroup_ty() -> Expr {
178 arrow(nat_ty(), type0())
179}
180pub fn gamma0_ty() -> Expr {
182 arrow(nat_ty(), type0())
183}
184pub fn gamma1_ty() -> Expr {
186 arrow(nat_ty(), type0())
187}
188pub fn subgroup_index_ty() -> Expr {
190 arrow(nat_ty(), nat_ty())
191}
192pub fn subgroup_level_ty() -> Expr {
194 arrow(cst("CongruenceSubgroup"), nat_ty())
195}
196pub fn modular_form_ty() -> Expr {
199 arrow3(nat_ty(), cst("CongruenceSubgroup"), type0())
200}
201pub fn cusp_form_ty() -> Expr {
204 arrow3(nat_ty(), cst("CongruenceSubgroup"), type0())
205}
206pub fn eisenstein_series_ty() -> Expr {
209 arrow(nat_ty(), type0())
210}
211pub fn g_function_ty() -> Expr {
214 arrow(nat_ty(), type0())
215}
216pub fn fourier_coefficient_ty() -> Expr {
219 arrow3(cst("ModularForm"), nat_ty(), complex_ty())
220}
221pub fn modular_form_weight_ty() -> Expr {
223 arrow(cst("ModularForm"), nat_ty())
224}
225pub fn holomorphic_at_cusps_ty() -> Expr {
227 arrow(cst("ModularForm"), prop())
228}
229pub fn vanishes_at_cusps_ty() -> Expr {
231 arrow(cst("ModularForm"), prop())
232}
233pub fn petersson_inner_product_ty() -> Expr {
236 arrow3(cst("CuspForm"), cst("CuspForm"), complex_ty())
237}
238pub fn petersson_norm_ty() -> Expr {
240 arrow(cst("CuspForm"), real_ty())
241}
242pub fn hecke_operator_ty() -> Expr {
245 arrow4(nat_ty(), nat_ty(), cst("CongruenceSubgroup"), type0())
246}
247pub fn hecke_algebra_ty() -> Expr {
250 arrow3(nat_ty(), cst("CongruenceSubgroup"), type0())
251}
252pub fn diamond_operator_ty() -> Expr {
255 arrow4(nat_ty(), nat_ty(), cst("ModularForm"), cst("ModularForm"))
256}
257pub fn hecke_eigenform_ty() -> Expr {
260 arrow(cst("ModularForm"), prop())
261}
262pub fn hecke_eigenvalue_ty() -> Expr {
265 arrow3(cst("ModularForm"), nat_ty(), complex_ty())
266}
267pub fn hecke_multiplicativity_ty() -> Expr {
270 arrow3(nat_ty(), cst("CongruenceSubgroup"), prop())
271}
272pub fn l_function_mf_ty() -> Expr {
275 arrow3(cst("ModularForm"), complex_ty(), complex_ty())
276}
277pub fn completed_l_function_ty() -> Expr {
280 arrow3(cst("ModularForm"), complex_ty(), complex_ty())
281}
282pub fn functional_equation_mf_ty() -> Expr {
285 arrow(cst("ModularForm"), prop())
286}
287pub fn root_number_ty() -> Expr {
289 arrow(cst("ModularForm"), int_ty())
290}
291pub fn euler_product_mf_ty() -> Expr {
294 arrow(cst("ModularForm"), prop())
295}
296pub fn ramanujan_tau_ty() -> Expr {
298 arrow(nat_ty(), int_ty())
299}
300pub fn delta_form_ty() -> Expr {
302 type0()
303}
304pub fn ramanujan_conjecture_ty() -> Expr {
307 arrow(nat_ty(), prop())
308}
309pub fn ramanujan_congruence_ty() -> Expr {
312 arrow(nat_ty(), prop())
313}
314pub fn theta_series_ty() -> Expr {
317 arrow(type0(), type0())
318}
319pub fn theta_series_lattice_ty() -> Expr {
322 arrow(nat_ty(), type0())
323}
324pub fn jacobi_theta_function_ty() -> Expr {
327 arrow3(complex_ty(), complex_ty(), complex_ty())
328}
329pub fn modular_symbol_ty() -> Expr {
332 arrow3(nat_ty(), cst("CongruenceSubgroup"), type0())
333}
334pub fn manin_symbol_ty() -> Expr {
336 arrow(nat_ty(), type0())
337}
338pub fn eichler_shimura_pairing_ty() -> Expr {
341 arrow3(cst("ModularForm"), cst("ModularSymbol"), complex_ty())
342}
343pub fn eichler_shimura_relation_ty() -> Expr {
346 arrow(nat_ty(), prop())
347}
348pub fn modular_curve_ty() -> Expr {
351 arrow(cst("CongruenceSubgroup"), type0())
352}
353pub fn cusp_ty() -> Expr {
355 arrow(cst("CongruenceSubgroup"), type0())
356}
357pub fn jacobian_of_modular_curve_ty() -> Expr {
360 arrow(cst("CongruenceSubgroup"), type0())
361}
362pub fn newform_ty() -> Expr {
365 arrow3(nat_ty(), nat_ty(), type0())
366}
367pub fn oldform_space_ty() -> Expr {
370 arrow3(nat_ty(), nat_ty(), type0())
371}
372pub fn newform_decomposition_ty() -> Expr {
375 arrow3(nat_ty(), cst("CongruenceSubgroup"), prop())
376}
377pub fn strong_multiplicity_one_ty() -> Expr {
380 arrow3(nat_ty(), nat_ty(), prop())
381}
382pub fn atkin_lehner_involution_ty() -> Expr {
385 arrow3(nat_ty(), cst("ModularForm"), cst("ModularForm"))
386}
387pub fn atkin_lehner_eigenvalue_ty() -> Expr {
390 arrow3(nat_ty(), cst("Newform"), int_ty())
391}
392pub fn gross_zagier_formula_ty() -> Expr {
395 arrow(nat_ty(), prop())
396}
397pub fn tate_twist_mf_ty() -> Expr {
400 arrow3(cst("ModularForm"), nat_ty(), cst("ModularForm"))
401}
402pub fn galois_conjugate_mf_ty() -> Expr {
405 arrow(cst("Newform"), type0())
406}
407pub fn modular_form_dimension_ty() -> Expr {
410 arrow3(nat_ty(), nat_ty(), nat_ty())
411}
412pub fn cusp_form_dimension_ty() -> Expr {
415 arrow3(nat_ty(), nat_ty(), nat_ty())
416}
417pub fn poincare_series_ty() -> Expr {
420 arrow4(nat_ty(), nat_ty(), complex_ty(), complex_ty())
421}
422pub fn siegel_modular_form_ty() -> Expr {
425 arrow3(nat_ty(), nat_ty(), type0())
426}
427pub fn hilbert_modular_form_ty() -> Expr {
430 arrow(nat_ty(), type0())
431}
432pub fn modular_form_lift_ty() -> Expr {
435 arrow3(cst("Newform"), nat_ty(), prop())
436}
437pub fn sato_tate_conjecture_ty() -> Expr {
440 arrow3(nat_ty(), nat_ty(), prop())
441}
442pub fn langlands_correspondence_gl2_ty() -> Expr {
445 arrow(cst("Newform"), type0())
446}
447pub fn modular_form_conductor_ty() -> Expr {
449 arrow(cst("Newform"), nat_ty())
450}
451pub fn nebentypus_character_ty() -> Expr {
454 arrow(cst("Newform"), type0())
455}
456pub fn hecke_tn_matrix_ty() -> Expr {
459 arrow3(nat_ty(), nat_ty(), type0())
460}
461pub fn hecke_commutative_ty() -> Expr {
464 arrow3(nat_ty(), cst("CongruenceSubgroup"), prop())
465}
466pub fn hecke_normal_operator_ty() -> Expr {
469 arrow(cst("ModularForm"), prop())
470}
471pub fn newform_eigen_system_ty() -> Expr {
474 arrow3(nat_ty(), nat_ty(), type0())
475}
476pub fn maass_form_ty() -> Expr {
479 arrow(nat_ty(), type0())
480}
481pub fn laplace_beltrami_eigenvalue_ty() -> Expr {
484 arrow(cst("MaassForm"), real_ty())
485}
486pub fn maass_l_function_ty() -> Expr {
489 arrow3(cst("MaassForm"), complex_ty(), complex_ty())
490}
491pub fn selberg_eigenvalue_conjecture_ty() -> Expr {
495 prop()
496}
497pub fn weyl_law_ty() -> Expr {
500 arrow(nat_ty(), prop())
501}
502pub fn half_integer_weight_form_ty() -> Expr {
505 arrow3(nat_ty(), nat_ty(), type0())
506}
507pub fn shimura_correspondence_ty() -> Expr {
511 arrow(nat_ty(), prop())
512}
513pub fn waldspurger_formula_ty() -> Expr {
517 arrow(nat_ty(), prop())
518}
519pub fn kohnen_variance_ty() -> Expr {
523 arrow3(nat_ty(), nat_ty(), real_ty())
524}
525pub fn galois_representation_mf_ty() -> Expr {
529 arrow3(cst("Newform"), nat_ty(), type0())
530}
531pub fn eichler_shimura_construction_ty() -> Expr {
535 arrow(cst("Newform"), prop())
536}
537pub fn l_adic_representation_ty() -> Expr {
541 arrow3(cst("Newform"), nat_ty(), prop())
542}
543pub fn deligne_semisimplicity_ty() -> Expr {
547 arrow(cst("Newform"), prop())
548}
549pub fn overconvergent_modular_form_ty() -> Expr {
552 arrow3(nat_ty(), real_ty(), type0())
553}
554pub fn coleman_family_ty() -> Expr {
557 arrow(nat_ty(), type0())
558}
559pub fn p_adic_l_function_mf_ty() -> Expr {
562 arrow4(cst("Newform"), nat_ty(), complex_ty(), complex_ty())
563}
564pub fn hida_family_ty() -> Expr {
567 arrow3(nat_ty(), nat_ty(), type0())
568}
569pub fn eigencurve_ty() -> Expr {
573 arrow(nat_ty(), type0())
574}
575pub fn x0n_ty() -> Expr {
577 arrow(nat_ty(), type0())
578}
579pub fn x1n_ty() -> Expr {
581 arrow(nat_ty(), type0())
582}
583pub fn cusp_resolution_ty() -> Expr {
586 arrow(nat_ty(), type0())
587}
588pub fn modular_unit_ty() -> Expr {
591 arrow(nat_ty(), type0())
592}
593pub fn siegel_unit_ty() -> Expr {
596 arrow3(nat_ty(), complex_ty(), complex_ty())
597}
598pub fn cm_point_ty() -> Expr {
602 arrow(nat_ty(), type0())
603}
604pub fn shimura_reciprocity_ty() -> Expr {
608 arrow(nat_ty(), prop())
609}
610pub fn cm_theory_ty() -> Expr {
614 arrow(nat_ty(), prop())
615}
616pub fn heegner_point_ty() -> Expr {
619 arrow(nat_ty(), type0())
620}
621pub fn gross_zagier_heegner_ty() -> Expr {
625 arrow(nat_ty(), prop())
626}
627pub fn sato_tate_measure_ty() -> Expr {
630 arrow(nat_ty(), type0())
631}
632pub fn sato_tate_equidistribution_ty() -> Expr {
636 arrow(cst("Newform"), prop())
637}
638pub fn sato_tate_l_function_ty() -> Expr {
641 arrow3(cst("Newform"), nat_ty(), complex_ty())
642}
643pub fn modularity_lifting_ty() -> Expr {
647 arrow(nat_ty(), prop())
648}
649pub fn residual_representation_ty() -> Expr {
652 arrow(nat_ty(), type0())
653}
654pub fn deformation_ring_ty() -> Expr {
657 arrow(nat_ty(), type0())
658}
659pub fn taylor_wiles_method_ty() -> Expr {
663 arrow(nat_ty(), prop())
664}
665pub fn fermat_last_theorem_via_modularity_ty() -> Expr {
668 prop()
669}
670pub fn siegel_theta_series_ty() -> Expr {
674 arrow3(nat_ty(), nat_ty(), type0())
675}
676pub fn jacobi_four_squares_ty() -> Expr {
679 arrow(nat_ty(), nat_ty())
680}
681pub fn build_modular_forms_env() -> Environment {
683 let mut env = Environment::new();
684 register_modular_forms(&mut env);
685 env
686}
687pub fn register_modular_forms(env: &mut Environment) {
689 let axioms: &[(&str, Expr)] = &[
690 ("ModularGroup", modular_group_ty()),
691 ("PSL2Z", psl2z_ty()),
692 ("GeneratorS", generator_s_ty()),
693 ("GeneratorT", generator_t_ty()),
694 ("FundamentalDomain", fundamental_domain_ty()),
695 ("CongruenceSubgroup", congruence_subgroup_ty()),
696 ("Gamma0", gamma0_ty()),
697 ("Gamma1", gamma1_ty()),
698 ("SubgroupIndex", subgroup_index_ty()),
699 ("SubgroupLevel", subgroup_level_ty()),
700 ("ModularForm", modular_form_ty()),
701 ("CuspForm", cusp_form_ty()),
702 ("EisensteinSeries", eisenstein_series_ty()),
703 ("GFunction", g_function_ty()),
704 ("FourierCoefficient", fourier_coefficient_ty()),
705 ("ModularFormWeight", modular_form_weight_ty()),
706 ("HolomorphicAtCusps", holomorphic_at_cusps_ty()),
707 ("VanishesAtCusps", vanishes_at_cusps_ty()),
708 ("PeterssonInnerProduct", petersson_inner_product_ty()),
709 ("PeterssonNorm", petersson_norm_ty()),
710 ("HeckeOperator", hecke_operator_ty()),
711 ("HeckeAlgebra", hecke_algebra_ty()),
712 ("DiamondOperator", diamond_operator_ty()),
713 ("HeckeEigenform", hecke_eigenform_ty()),
714 ("HeckeEigenvalue", hecke_eigenvalue_ty()),
715 ("HeckeMultiplicativity", hecke_multiplicativity_ty()),
716 ("LFunction_MF", l_function_mf_ty()),
717 ("CompletedLFunction", completed_l_function_ty()),
718 ("FunctionalEquation_MF", functional_equation_mf_ty()),
719 ("RootNumber", root_number_ty()),
720 ("EulerProduct_MF", euler_product_mf_ty()),
721 ("RamanujanTau", ramanujan_tau_ty()),
722 ("DeltaForm", delta_form_ty()),
723 ("RamanujanConjecture", ramanujan_conjecture_ty()),
724 ("RamanujanCongruence", ramanujan_congruence_ty()),
725 ("ThetaSeries", theta_series_ty()),
726 ("ThetaSeriesLattice", theta_series_lattice_ty()),
727 ("JacobiThetaFunction", jacobi_theta_function_ty()),
728 ("ModularSymbol", modular_symbol_ty()),
729 ("ManinSymbol", manin_symbol_ty()),
730 ("EichlerShimuraPairing", eichler_shimura_pairing_ty()),
731 ("EichlerShimuraRelation", eichler_shimura_relation_ty()),
732 ("ModularCurve", modular_curve_ty()),
733 ("Cusp", cusp_ty()),
734 ("JacobianOfModularCurve", jacobian_of_modular_curve_ty()),
735 ("Newform", newform_ty()),
736 ("OldformSpace", oldform_space_ty()),
737 ("NewformDecomposition", newform_decomposition_ty()),
738 ("StrongMultiplicityOne", strong_multiplicity_one_ty()),
739 ("AtkinLehnerInvolution", atkin_lehner_involution_ty()),
740 ("AtkinLehnerEigenvalue", atkin_lehner_eigenvalue_ty()),
741 ("GrossZagierFormula", gross_zagier_formula_ty()),
742 ("TateTwist_MF", tate_twist_mf_ty()),
743 ("GaloisConjugate_MF", galois_conjugate_mf_ty()),
744 ("ModularFormDimension", modular_form_dimension_ty()),
745 ("CuspFormDimension", cusp_form_dimension_ty()),
746 ("PoincareSeries", poincare_series_ty()),
747 ("SiegelModularForm", siegel_modular_form_ty()),
748 ("HilbertModularForm", hilbert_modular_form_ty()),
749 ("ModularFormLift", modular_form_lift_ty()),
750 ("SatoTateConjecture", sato_tate_conjecture_ty()),
751 (
752 "LanglandsCorrespondence_GL2",
753 langlands_correspondence_gl2_ty(),
754 ),
755 ("ModularFormConductor", modular_form_conductor_ty()),
756 ("NebentypusCharacter", nebentypus_character_ty()),
757 ("HeckeTnMatrix", hecke_tn_matrix_ty()),
758 ("HeckeCommutative", hecke_commutative_ty()),
759 ("HeckeNormalOperator", hecke_normal_operator_ty()),
760 ("NewformEigenSystem", newform_eigen_system_ty()),
761 ("MaassForm", maass_form_ty()),
762 (
763 "LaplaceBeltramiEigenvalue",
764 laplace_beltrami_eigenvalue_ty(),
765 ),
766 ("MaassLFunction", maass_l_function_ty()),
767 (
768 "SelvergEigenvalueConjecture",
769 selberg_eigenvalue_conjecture_ty(),
770 ),
771 ("WeylLaw", weyl_law_ty()),
772 ("HalfIntegerWeightForm", half_integer_weight_form_ty()),
773 ("ShimuraCorrespondence", shimura_correspondence_ty()),
774 ("WaldspurgerFormula", waldspurger_formula_ty()),
775 ("KohnenVariance", kohnen_variance_ty()),
776 ("GaloisRepresentation_MF", galois_representation_mf_ty()),
777 (
778 "EichlerShimuraConstruction",
779 eichler_shimura_construction_ty(),
780 ),
781 ("LAdic_Representation", l_adic_representation_ty()),
782 ("DeligneSemiSimplicity", deligne_semisimplicity_ty()),
783 (
784 "OverconvergentModularForm",
785 overconvergent_modular_form_ty(),
786 ),
787 ("ColemanFamily", coleman_family_ty()),
788 ("PAdicLFunction_MF", p_adic_l_function_mf_ty()),
789 ("HidaFamily", hida_family_ty()),
790 ("EigenvarietyCurve", eigencurve_ty()),
791 ("X0N", x0n_ty()),
792 ("X1N", x1n_ty()),
793 ("CuspResolution", cusp_resolution_ty()),
794 ("ModularUnit", modular_unit_ty()),
795 ("SiegelUnit", siegel_unit_ty()),
796 ("CMPoint", cm_point_ty()),
797 ("ShimuraReciprocity", shimura_reciprocity_ty()),
798 ("CMTheory", cm_theory_ty()),
799 ("HeegnerPoint", heegner_point_ty()),
800 ("GrossZagierHeegner", gross_zagier_heegner_ty()),
801 ("SatoTateMeasure", sato_tate_measure_ty()),
802 ("SatoTateEquidistribution", sato_tate_equidistribution_ty()),
803 ("SatoTateLFunction", sato_tate_l_function_ty()),
804 ("ModularityLifting", modularity_lifting_ty()),
805 ("ResidualRepresentation", residual_representation_ty()),
806 ("DeformationRing", deformation_ring_ty()),
807 ("TaylorWilesMethod", taylor_wiles_method_ty()),
808 (
809 "FermatLastTheoremViaModularity",
810 fermat_last_theorem_via_modularity_ty(),
811 ),
812 ("SiegelThetaSeries", siegel_theta_series_ty()),
813 ("JacobiFourSquares", jacobi_four_squares_ty()),
814 ];
815 for (name, ty) in axioms {
816 env.add(Declaration::Axiom {
817 name: Name::str(*name),
818 univ_params: vec![],
819 ty: ty.clone(),
820 })
821 .ok();
822 }
823}
824#[cfg(test)]
825mod tests {
826 use super::*;
827 #[test]
828 fn test_build_modular_forms_env() {
829 let env = build_modular_forms_env();
830 assert!(env.get(&Name::str("ModularGroup")).is_some());
831 assert!(env.get(&Name::str("PSL2Z")).is_some());
832 assert!(env.get(&Name::str("FundamentalDomain")).is_some());
833 }
834 #[test]
835 fn test_congruence_subgroups() {
836 let env = build_modular_forms_env();
837 assert!(env.get(&Name::str("CongruenceSubgroup")).is_some());
838 assert!(env.get(&Name::str("Gamma0")).is_some());
839 assert!(env.get(&Name::str("Gamma1")).is_some());
840 assert!(env.get(&Name::str("SubgroupIndex")).is_some());
841 }
842 #[test]
843 fn test_forms_and_operators() {
844 let env = build_modular_forms_env();
845 assert!(env.get(&Name::str("ModularForm")).is_some());
846 assert!(env.get(&Name::str("CuspForm")).is_some());
847 assert!(env.get(&Name::str("EisensteinSeries")).is_some());
848 assert!(env.get(&Name::str("HeckeOperator")).is_some());
849 assert!(env.get(&Name::str("HeckeAlgebra")).is_some());
850 assert!(env.get(&Name::str("DiamondOperator")).is_some());
851 assert!(env.get(&Name::str("HeckeEigenform")).is_some());
852 }
853 #[test]
854 fn test_l_functions() {
855 let env = build_modular_forms_env();
856 assert!(env.get(&Name::str("LFunction_MF")).is_some());
857 assert!(env.get(&Name::str("CompletedLFunction")).is_some());
858 assert!(env.get(&Name::str("FunctionalEquation_MF")).is_some());
859 assert!(env.get(&Name::str("RootNumber")).is_some());
860 assert!(env.get(&Name::str("EulerProduct_MF")).is_some());
861 }
862 #[test]
863 fn test_ramanujan_and_theta() {
864 let env = build_modular_forms_env();
865 assert!(env.get(&Name::str("RamanujanTau")).is_some());
866 assert!(env.get(&Name::str("DeltaForm")).is_some());
867 assert!(env.get(&Name::str("RamanujanConjecture")).is_some());
868 assert!(env.get(&Name::str("RamanujanCongruence")).is_some());
869 assert!(env.get(&Name::str("ThetaSeries")).is_some());
870 assert!(env.get(&Name::str("JacobiThetaFunction")).is_some());
871 }
872 #[test]
873 fn test_newforms_and_atkin_lehner() {
874 let env = build_modular_forms_env();
875 assert!(env.get(&Name::str("Newform")).is_some());
876 assert!(env.get(&Name::str("NewformDecomposition")).is_some());
877 assert!(env.get(&Name::str("StrongMultiplicityOne")).is_some());
878 assert!(env.get(&Name::str("AtkinLehnerInvolution")).is_some());
879 assert!(env.get(&Name::str("AtkinLehnerEigenvalue")).is_some());
880 }
881 #[test]
882 fn test_eichler_shimura_and_curves() {
883 let env = build_modular_forms_env();
884 assert!(env.get(&Name::str("ModularSymbol")).is_some());
885 assert!(env.get(&Name::str("EichlerShimuraPairing")).is_some());
886 assert!(env.get(&Name::str("EichlerShimuraRelation")).is_some());
887 assert!(env.get(&Name::str("ModularCurve")).is_some());
888 assert!(env.get(&Name::str("JacobianOfModularCurve")).is_some());
889 }
890 #[test]
891 fn test_sl2z_generators_rust() {
892 let s = Mat2x2::generator_s();
893 let t = Mat2x2::generator_t();
894 assert!(s.is_sl2z());
895 assert!(t.is_sl2z());
896 let s2 = s.mul(&s);
897 assert_eq!(
898 s2,
899 Mat2x2 {
900 a: -1,
901 b: 0,
902 c: 0,
903 d: -1
904 }
905 );
906 assert!(t.mul(&t).is_sl2z());
907 }
908 #[test]
909 fn test_eisenstein_and_ramanujan_tau_rust() {
910 assert_eq!(sigma_k_minus_1(6, 2), 12);
911 assert_eq!(sigma_k_minus_1(6, 1), 4);
912 let taus = ramanujan_tau_up_to(5);
913 assert_eq!(taus[1], 1, "Ο(1) should be 1");
914 assert_eq!(taus[2], -24, "Ο(2) should be -24");
915 assert_eq!(r2(1), 4);
916 assert_eq!(r2(5), 8);
917 }
918 #[test]
919 fn test_hecke_operator_rust() {
920 let coeffs: Vec<i64> = (0..10).map(|n| sigma_k_minus_1(n, 4) as i64).collect();
921 let b = hecke_tp_coefficients(&coeffs, 2, 4);
922 assert_eq!(b.len(), coeffs.len());
923 }
924 #[test]
925 fn test_extended_hecke_axioms() {
926 let env = build_modular_forms_env();
927 assert!(env.get(&Name::str("HeckeTnMatrix")).is_some());
928 assert!(env.get(&Name::str("HeckeCommutative")).is_some());
929 assert!(env.get(&Name::str("HeckeNormalOperator")).is_some());
930 assert!(env.get(&Name::str("NewformEigenSystem")).is_some());
931 }
932 #[test]
933 fn test_maass_forms_axioms() {
934 let env = build_modular_forms_env();
935 assert!(env.get(&Name::str("MaassForm")).is_some());
936 assert!(env.get(&Name::str("LaplaceBeltramiEigenvalue")).is_some());
937 assert!(env.get(&Name::str("MaassLFunction")).is_some());
938 assert!(env.get(&Name::str("SelvergEigenvalueConjecture")).is_some());
939 assert!(env.get(&Name::str("WeylLaw")).is_some());
940 }
941 #[test]
942 fn test_half_integer_weight_axioms() {
943 let env = build_modular_forms_env();
944 assert!(env.get(&Name::str("HalfIntegerWeightForm")).is_some());
945 assert!(env.get(&Name::str("ShimuraCorrespondence")).is_some());
946 assert!(env.get(&Name::str("WaldspurgerFormula")).is_some());
947 assert!(env.get(&Name::str("KohnenVariance")).is_some());
948 }
949 #[test]
950 fn test_galois_representation_axioms() {
951 let env = build_modular_forms_env();
952 assert!(env.get(&Name::str("GaloisRepresentation_MF")).is_some());
953 assert!(env.get(&Name::str("EichlerShimuraConstruction")).is_some());
954 assert!(env.get(&Name::str("LAdic_Representation")).is_some());
955 assert!(env.get(&Name::str("DeligneSemiSimplicity")).is_some());
956 }
957 #[test]
958 fn test_padic_overconvergent_axioms() {
959 let env = build_modular_forms_env();
960 assert!(env.get(&Name::str("OverconvergentModularForm")).is_some());
961 assert!(env.get(&Name::str("ColemanFamily")).is_some());
962 assert!(env.get(&Name::str("PAdicLFunction_MF")).is_some());
963 assert!(env.get(&Name::str("HidaFamily")).is_some());
964 assert!(env.get(&Name::str("EigenvarietyCurve")).is_some());
965 }
966 #[test]
967 fn test_modular_curves_units_axioms() {
968 let env = build_modular_forms_env();
969 assert!(env.get(&Name::str("X0N")).is_some());
970 assert!(env.get(&Name::str("X1N")).is_some());
971 assert!(env.get(&Name::str("CuspResolution")).is_some());
972 assert!(env.get(&Name::str("ModularUnit")).is_some());
973 assert!(env.get(&Name::str("SiegelUnit")).is_some());
974 }
975 #[test]
976 fn test_cm_and_heegner_axioms() {
977 let env = build_modular_forms_env();
978 assert!(env.get(&Name::str("CMPoint")).is_some());
979 assert!(env.get(&Name::str("ShimuraReciprocity")).is_some());
980 assert!(env.get(&Name::str("CMTheory")).is_some());
981 assert!(env.get(&Name::str("HeegnerPoint")).is_some());
982 assert!(env.get(&Name::str("GrossZagierHeegner")).is_some());
983 }
984 #[test]
985 fn test_sato_tate_axioms() {
986 let env = build_modular_forms_env();
987 assert!(env.get(&Name::str("SatoTateMeasure")).is_some());
988 assert!(env.get(&Name::str("SatoTateEquidistribution")).is_some());
989 assert!(env.get(&Name::str("SatoTateLFunction")).is_some());
990 }
991 #[test]
992 fn test_modularity_lifting_axioms() {
993 let env = build_modular_forms_env();
994 assert!(env.get(&Name::str("ModularityLifting")).is_some());
995 assert!(env.get(&Name::str("ResidualRepresentation")).is_some());
996 assert!(env.get(&Name::str("DeformationRing")).is_some());
997 assert!(env.get(&Name::str("TaylorWilesMethod")).is_some());
998 assert!(env
999 .get(&Name::str("FermatLastTheoremViaModularity"))
1000 .is_some());
1001 assert!(env.get(&Name::str("SiegelThetaSeries")).is_some());
1002 assert!(env.get(&Name::str("JacobiFourSquares")).is_some());
1003 }
1004 #[test]
1005 fn test_hecke_operator_matrix_rust() {
1006 let m = HeckeOperatorMatrix::eigenvalue_matrix(6, 12);
1007 assert!(m.is_diagonal());
1008 let expected = sigma_k_minus_1(6, 12) as i64;
1009 assert_eq!(m.trace(), expected);
1010 }
1011 #[test]
1012 fn test_q_expansion_delta() {
1013 let qe = QExpansion::delta(6);
1014 assert!((qe.coeffs[1] - 1.0).abs() < 1e-9);
1015 assert!((qe.coeffs[2] - (-24.0)).abs() < 1e-9);
1016 assert_eq!(qe.valuation(), Some(1));
1017 }
1018 #[test]
1019 fn test_q_expansion_eisenstein() {
1020 let qe = QExpansion::eisenstein(4, 5);
1021 assert!((qe.coeffs[0] - 1.0).abs() < 1e-9);
1022 assert!((qe.coeffs[1] - 1.0).abs() < 1e-9);
1023 assert!((qe.coeffs[2] - 9.0).abs() < 1e-9);
1024 }
1025 #[test]
1026 fn test_ramanujan_tau_function_rust() {
1027 let rtf = RamanujanTauFunction::new(20);
1028 assert_eq!(rtf.tau(1), 1);
1029 assert_eq!(rtf.tau(2), -24);
1030 assert!(rtf.check_multiplicativity(2, 3));
1031 assert!(rtf.verify_congruence_691());
1032 }
1033 #[test]
1034 fn test_modular_form_cusp_rust() {
1035 let inf = ModularFormCusp::infinity(11);
1036 let zero = ModularFormCusp::zero(11);
1037 assert!(inf.is_infinity());
1038 assert!(!zero.is_infinity());
1039 assert_eq!(inf.width(), 1);
1040 assert_eq!(ModularFormCusp::cusp_count(11), 2);
1041 assert_eq!(ModularFormCusp::cusp_count(1), 1);
1042 }
1043}
1044pub fn gcd_u64(mut a: u64, mut b: u64) -> u64 {
1045 while b != 0 {
1046 let t = b;
1047 b = a % b;
1048 a = t;
1049 }
1050 a
1051}
1052pub fn build_env() -> Environment {
1054 build_modular_forms_env()
1055}
1056#[allow(dead_code)]
1058pub fn famous_modular_forms() -> Vec<(&'static str, u32, u64, &'static str)> {
1059 vec![
1060 (
1061 "Delta",
1062 12,
1063 1,
1064 "Ramanujan's Delta function, generates S_12(SL2Z)",
1065 ),
1066 (
1067 "E4",
1068 4,
1069 1,
1070 "Eisenstein series, E4 = 1 + 240 sum tau3(n) q^n",
1071 ),
1072 (
1073 "E6",
1074 6,
1075 1,
1076 "Eisenstein series, E6 = 1 - 504 sum tau5(n) q^n",
1077 ),
1078 (
1079 "E2*",
1080 2,
1081 1,
1082 "Quasi-modular; weight 2 Eisenstein (non-holomorphic)",
1083 ),
1084 (
1085 "j-function",
1086 0,
1087 1,
1088 "j = E4^3/Delta, modular function (weight 0)",
1089 ),
1090 (
1091 "eta",
1092 0,
1093 1,
1094 "Dedekind eta = q^(1/24) prod (1-q^n), weight 1/2",
1095 ),
1096 (
1097 "theta series",
1098 0,
1099 4,
1100 "theta(z) = sum q^(n^2), weight 1/2 automorphic",
1101 ),
1102 (
1103 "CM newform f_37",
1104 2,
1105 37,
1106 "Associated to elliptic curve y^2=x^3-x",
1107 ),
1108 (
1109 "Ramanujan tau-function",
1110 12,
1111 1,
1112 "tau(n): tau(p) = a_p for Delta",
1113 ),
1114 (
1115 "Mock theta f(q)",
1116 0,
1117 1,
1118 "Ramanujan's third-order mock theta function",
1119 ),
1120 ]
1121}
1122#[allow(dead_code)]
1124pub fn monstrous_moonshine_data() -> Vec<MoonshineDatum> {
1125 vec![
1126 MoonshineDatum::new("1A", "J(q) = q^-1 + 196884q + ...", true),
1127 MoonshineDatum::new("2A", "T_{2A}(q)", true),
1128 MoonshineDatum::new("3A", "T_{3A}(q)", true),
1129 MoonshineDatum::new("5A", "T_{5A}(q)", true),
1130 ]
1131}
1132#[cfg(test)]
1133mod modular_forms_ext_tests {
1134 use super::*;
1135 #[test]
1136 fn test_dirichlet_character() {
1137 let chi = DirichletCharacter::legendre_symbol(5);
1138 assert_eq!(chi.order, 2);
1139 assert!(chi.is_primitive);
1140 }
1141 #[test]
1142 fn test_hecke_l_function() {
1143 let l = HeckeLFunction::new("11a1", 2, 11);
1144 assert!(!l.euler_product_description().is_empty());
1145 }
1146 #[test]
1147 fn test_shimura_variety() {
1148 let x0 = ShimuraVariety::modular_curve(37);
1149 assert_eq!(x0.dimension, 1);
1150 assert!(x0.has_canonical_model());
1151 }
1152 #[test]
1153 fn test_modular_curve_genus() {
1154 let x0_11 = ModularCurveType::X0(11);
1155 assert!(x0_11.genus() <= 2);
1156 }
1157 #[test]
1158 fn test_famous_forms_nonempty() {
1159 let forms = famous_modular_forms();
1160 assert!(!forms.is_empty());
1161 }
1162 #[test]
1163 fn test_moonshine_data() {
1164 let md = monstrous_moonshine_data();
1165 assert!(!md.is_empty());
1166 assert!(md[0].hauptmodul);
1167 }
1168}
1169#[allow(dead_code)]
1171pub fn dimension_s_k(k: u32, level: u64) -> u64 {
1172 if k < 2 || k % 2 != 0 {
1173 return 0;
1174 }
1175 let mu = level;
1176 if k == 2 {
1177 if level <= 10 {
1178 0
1179 } else {
1180 mu / 12
1181 }
1182 } else {
1183 ((k - 1) as u64) * mu / 12
1184 }
1185}
1186#[cfg(test)]
1187mod modular_forms_extra_tests {
1188 use super::*;
1189 #[test]
1190 fn test_petersson_ip() {
1191 let ip = PeterssonInnerProduct::new(2, 11);
1192 assert!(ip.hecke_operators_self_adjoint());
1193 assert!(ip.newforms_orthogonal());
1194 }
1195 #[test]
1196 fn test_automorphic_rep() {
1197 let pi = AutomorphicRepresentation::classical_newform(37, 2);
1198 assert!(pi.is_cuspidal);
1199 assert!(pi.is_tempered);
1200 }
1201 #[test]
1202 fn test_dimension_formula() {
1203 let d = dimension_s_k(12, 1);
1204 assert_eq!(d, 0);
1205 let d2 = dimension_s_k(2, 37);
1206 assert!(d2 <= 4);
1207 }
1208 #[test]
1209 fn test_rankin_selberg() {
1210 let rs = RankinSelbergConvolution::new("f", "f");
1211 assert!(rs.nonvanishing_at_s1());
1212 assert!(rs.analytic_continuation_entire());
1213 }
1214}