Implementing moving origin of ideal (#19)
--------- Co-authored-by: Julian Piribauer <julian.piribauer@gmail.com> Reviewed-on: #19
This commit was merged in pull request #19.
This commit is contained in:
@@ -125,42 +125,39 @@ def test_find_power_series_solution_handles_rational_indicial():
|
||||
|
||||
|
||||
def test_ideal_finds_power_series_solution_and_recovers_first_operator():
|
||||
# Picard--Fuchs ideal for P_{22211}[8]:
|
||||
# M1 = theta2*(-2*theta1+2*theta2-1) + 2*(theta1-2*theta2-1)*(theta1-2*theta2)*z2
|
||||
# M2 = theta1^2*(2*(theta1-2*theta2)*z2-theta2) - 16*(2*theta1+1)*(4*theta1+1)*(4*theta1+3)*z1*z2
|
||||
M1 = PFOperator(
|
||||
"theta1*(-2*theta0 + 2*theta1 - 1) + 2*(theta0 - 2*theta1 - 1)*(theta0 - 2*theta1)*z1",
|
||||
# Picard--Fuchs ideal for P_{22211}[8] at the MUM point:
|
||||
# D1 = Theta_x^2*(Theta_x - 2*Theta_y) - 4*x*(4*Theta_x + 3)*(4*Theta_x + 2)*(4*Theta_x + 1)
|
||||
# D2 = Theta_y^2 - y*(2*Theta_y - Theta_x + 1)*(2*Theta_y - Theta_x)
|
||||
#
|
||||
# We test moving the ideal to the intersection with the locus of Strong Coupling.
|
||||
D1 = PFOperator(
|
||||
"theta0^2*(theta0 - 2*theta1) - 4*z0*(4*theta0 + 3)*(4*theta0 + 2)*(4*theta0 + 1)",
|
||||
no_variables=2,
|
||||
)
|
||||
M2 = PFOperator(
|
||||
"theta0^2*(2*(theta0 - 2*theta1)*z1 - theta1) - 16*(2*theta0 + 1)*(4*theta0 + 1)*(4*theta0 + 3)*z0*z1",
|
||||
D2 = PFOperator(
|
||||
"theta1^2 - z1*(2*theta1 - theta0 + 1)*(2*theta1 - theta0)",
|
||||
no_variables=2,
|
||||
)
|
||||
ideal = PFIdeal([M1, M2])
|
||||
moved = PFIdeal([D1, D2]).change_coordinates("z0", "z1 - 1/4")
|
||||
op1, op2 = moved.operators
|
||||
|
||||
solutions = ideal.find_power_series_solution(indicials=[0, QQ(1) / 2], order=6)
|
||||
solutions = moved.find_power_series_solution(indicials=[0, QQ(1) / 2], order=14)
|
||||
assert len(solutions) == 1
|
||||
|
||||
period = solutions[0]
|
||||
assert period.apply_operator(M1).coefficients == {}
|
||||
assert period.apply_operator(M2).coefficients == {}
|
||||
assert period.apply_operator(op1).coefficients == {}
|
||||
assert period.apply_operator(op2).coefficients == {}
|
||||
# Normalisation convention: the free parameter at the leading (0, 0) coefficient is 1.
|
||||
assert period.coefficients[(0, 0)][(0, 0)] == 1
|
||||
assert period.coefficients[(0, 0)][(1, 1)] == -32
|
||||
assert period.coefficients[(0, 0)][(1, 0)] == 0
|
||||
|
||||
# M1 lives entirely within z_degree <= 1, theta_degree <= 2 (a single bare factor of
|
||||
# z2, quadratic in theta), so this is the natural Ansatz level to look for it at.
|
||||
recovered = period.find_annihilating_operators(z_degree=1, theta_degree=2)
|
||||
assert len(recovered) == 1
|
||||
|
||||
# recovered[0] should be a scalar multiple of M1 - compare via the coefficient of the
|
||||
# bare theta2 (theta1 in code) monomial, which is nonzero in M1.
|
||||
ratio = (
|
||||
recovered[0].operator.monomial_coefficient(M1.theta_gens[1])
|
||||
/ M1.operator.monomial_coefficient(M1.theta_gens[1])
|
||||
)
|
||||
assert ratio != 0
|
||||
assert recovered[0].operator == ratio * M1.operator
|
||||
assert recovered[0].operator == PFOperator(
|
||||
"-2*z1*theta0^2 + 8*z1*theta0*theta1 - 8*z1*theta1^2 + 2*z1*theta0 - 4*z1*theta1 "
|
||||
"+ 2*theta0*theta1 - 2*theta1^2 + theta1",
|
||||
no_variables=2,
|
||||
).operator
|
||||
|
||||
|
||||
def test_single_operator_recovers_itself_from_its_holomorphic_period():
|
||||
@@ -192,3 +189,15 @@ def test_single_operator_recovers_itself_from_its_holomorphic_period():
|
||||
)
|
||||
assert ratio != 0
|
||||
assert recovered[0].operator == ratio * L.operator
|
||||
|
||||
|
||||
def test_change_coordinates_handles_non_monomial_denominator():
|
||||
op = PFOperator("theta0^2 - z0", no_variables=1)
|
||||
|
||||
result = op.change_coordinates("z0/(1-z0)")
|
||||
|
||||
expected = PFOperator(
|
||||
"(1+z0)^3*theta0^2 + z0*(1+z0)^2*theta0 - z0",
|
||||
no_variables=1,
|
||||
)
|
||||
assert result.operator == expected.operator
|
||||
|
||||
Reference in New Issue
Block a user