Implementing Frobenius basis for PFIdeals
CI / lint (push) Successful in 1m20s
CI / test (push) Successful in 3m49s

This commit is contained in:
Julian Piribauer
2026-11-01 16:46:13 +01:00
parent d3412f1ff6
commit 7217598d73
4 changed files with 895 additions and 110 deletions
+41 -2
View File
@@ -8,7 +8,7 @@ It allows for computation of discriminant loci and topological data of manifolds
Supported initialisations are represented by the following examples.
```python
elliptic_curve_D = ToricPolytopeProjectiveSpace([1, 2, 3], model_name="elliptic_curve_D")
elliptic_curve_D = ToricPolytopeProjectiveSpace([3, 2, 1], model_name="elliptic_curve_D")
CY3_quintic = ToricPolytopeProjectiveSpace([1, 1, 1, 1, 1], model_name="quintic")
CY3_bicubic = ToricPolytopeCICY([[3, 3]], model_name="bi-cubic")
@@ -149,4 +149,43 @@ recovered[0].simplify().operator_string
```
`recovered[0]` is, up to scale, `M1` — recovered purely from `M1`, `M2`'s shared power series
solution.
solution.
### Frobenius bases
A `PFIdeal` also computes its complete Frobenius basis — all solutions, logarithmic ones included —
at the origin of its current coordinates; for another point, move it to the origin with `change_coordinates`
first. The exponents are the `indicials`, the roots of the system's indicial ideal, which is completed by linear
algebra where the operators' z-free parts alone don't determine it. The optional `hodge_numbers` — the
numbers of solutions of top log-degree 0, 1, ..., n at a MUM point, e.g. `[1, 2, 2, 1]` for a two-parameter
threefold — certify that completion through their sum, the rank, and bound the powers of logarithms. For
P_{2,2,2,1,1}[8] at its MUM point and at the point (z0, z1) = (0, 1/4) on its strong coupling divisor:
```python
D1 = PFOperator(
"theta0^2*(theta0 - 2*theta1) - 4*z0*(4*theta0 + 3)*(4*theta0 + 2)*(4*theta0 + 1)",
no_variables=2,
)
D2 = PFOperator("theta1^2 - z1*(2*theta1 - theta0 + 1)*(2*theta1 - theta0)", no_variables=2)
ideal = PFIdeal([D1, D2], hodge_numbers=[1, 2, 2, 1])
strong_coupling = ideal.change_coordinates("z0", "z1 - 1/4")
ideal.indicials()
strong_coupling.indicials()
basis = strong_coupling.frobenius_basis(order=2)
basis[5].period_string
```
```term
[((0, 0), 6)]
[((0, 0), 4), ((0, 1/2), 2)]
INFO:__main__:Completed the indicial ideal at z = 0 at multiplier degree 2 with 1 extra operator(s): colength 6.
INFO:__main__:Exponent class of (0, 0): 4 solution(s) with leading terms ['1', 'log(z0)', 'log(z0)^2', 'log(z0)^3'].
INFO:__main__:Exponent class of (0, 1/2): 2 solution(s) with leading terms ['sqrt(z1)', 'sqrt(z1)*(log(z0) + log(z1))'].
INFO:__main__:Found a Frobenius basis of 6 solution(s) at order 2.
'-1/225*(7200*z0*z1*log(z0) - 720*z1^2*log(z0) + 7200*z0*z1*log(z1) - 720*z1^2*log(z1) + 33600*z0*z1 - 732*z1^2 + 300*z1*log(z0) + 300*z1*log(z1) + 250*z1 - 225*log(z0) - 225*log(z1))*sqrt(z1)'
```
Within each exponent class the basis is canonical: every solution has its own leading term with coefficient 1,
at which the class' other solutions vanish. Coefficients are those of plain powers of log(z_i), without factors
of 2πi.