102 lines
3.9 KiB
Python
102 lines
3.9 KiB
Python
import os
|
|
|
|
import pytest
|
|
from sage.all import * # noqa: F401
|
|
|
|
load(os.path.join(os.path.dirname(__file__), "..", "sage", "period_computation.sage"))
|
|
|
|
|
|
def test_apply_operator_univariate():
|
|
# theta^2 - z applied to log(z) should give -z*log(z), since theta(log z) = 1
|
|
# and theta^2(log z) = theta(1) = 0.
|
|
period = Period(no_variables=1, coefficients={(1,): {(0,): 1}}, order=5)
|
|
op = PFOperator("theta0^2 - z0", no_variables=1)
|
|
|
|
result = period.apply_operator(op)
|
|
|
|
assert result.coefficients == {(1,): {(1,): -1}}
|
|
|
|
|
|
def test_apply_operator_mixes_variables():
|
|
# z0*theta1 applied to z0*log(z1): theta1 strips log(z1) down to a bare 1
|
|
# (leaving z0 untouched), then multiplying by z0 gives z0^2.
|
|
period = Period(no_variables=2, coefficients={(0, 1): {(1, 0): 1}}, order=5)
|
|
op = PFOperator("z0*theta1", no_variables=2)
|
|
|
|
result = period.apply_operator(op)
|
|
|
|
assert result.coefficients == {(0, 0): {(2, 0): 1}}
|
|
|
|
|
|
def test_apply_operator_truncates_to_order():
|
|
# Multiplying by z0^2 pushes some terms above the period's order, so they
|
|
# should be dropped rather than kept with a nonzero coefficient.
|
|
period = Period(no_variables=1, coefficients={(0,): {(0,): 1, (1,): 1, (2,): 1}}, order=2)
|
|
op = PFOperator("z0^2", no_variables=1)
|
|
|
|
result = period.apply_operator(op)
|
|
|
|
assert result.coefficients == {(0,): {(2,): 1}}
|
|
assert result.order == 2
|
|
|
|
|
|
def test_apply_operator_rejects_variable_count_mismatch():
|
|
period = Period(no_variables=1, coefficients={})
|
|
op = PFOperator("z0*theta1", no_variables=2)
|
|
|
|
with pytest.raises(ValueError):
|
|
period.apply_operator(op)
|
|
|
|
|
|
def test_find_annihilating_operators_recovers_theta_squared():
|
|
# theta0^2 annihilates log(z0): theta0(log z0) = 1, theta0^2(log z0) = theta0(1) = 0.
|
|
# Among degree-(0, 2) Ansatze this should be the only solution, up to scaling.
|
|
period = Period(no_variables=1, coefficients={(1,): {(0,): 1}}, order=5)
|
|
|
|
ops = period.find_annihilating_operators(z_degree=0, theta_degree=2)
|
|
|
|
# A one-dimensional solution space means exactly one basis operator.
|
|
assert len(ops) == 1
|
|
assert period.apply_operator(ops[0]).coefficients == {}
|
|
assert str(ops[0].operator) == "theta0^2"
|
|
|
|
|
|
def test_find_annihilating_operators_recovers_geometric_series_operator():
|
|
# sum_{k=0}^{4} z0^k is annihilated (up to truncation order) by
|
|
# (1 - z0)*theta0 - z0, i.e. theta0 - z0*theta0 - z0.
|
|
period = Period(
|
|
no_variables=1,
|
|
coefficients={(0,): {(0,): 1, (1,): 1, (2,): 1, (3,): 1, (4,): 1}},
|
|
order=4,
|
|
)
|
|
|
|
ops = period.find_annihilating_operators(z_degree=1, theta_degree=1)
|
|
|
|
assert len(ops) == 1
|
|
assert period.apply_operator(ops[0]).coefficients == {}
|
|
|
|
|
|
def test_find_annihilating_operators_returns_empty_list_when_no_solution_exists():
|
|
# No degree-0 (constant) operator other than the zero operator can annihilate a
|
|
# nonzero constant period, so the linear system's only solution is trivial.
|
|
period = Period(no_variables=1, coefficients={(0,): {(0,): 1}}, order=0)
|
|
|
|
ops = period.find_annihilating_operators(z_degree=0, theta_degree=0)
|
|
|
|
assert ops == []
|
|
|
|
|
|
def test_simplify_factorises_theta_polynomial_per_z_monomial():
|
|
# theta0^4 - 5*z0*(5*theta0+1)*(5*theta0+2)*(5*theta0+3)*(5*theta0+4), expanded, is the
|
|
# quintic's Picard-Fuchs operator. simplify() should recover the factorised form: the
|
|
# z0^0 part (theta0^4) has no theta-factor to pull out, while the z0^1 part factorises
|
|
# into the four linear pieces.
|
|
expanded = "theta0^4 - 3125*z0*theta0^4 - 6250*z0*theta0^3 - 4375*z0*theta0^2 - 1250*z0*theta0 - 120*z0"
|
|
op = PFOperator(expanded, no_variables=1)
|
|
|
|
simplified = op.simplify()
|
|
|
|
# The underlying (expanded) operator is unchanged - only the display string differs.
|
|
assert simplified.operator == op.operator
|
|
assert simplified.operator_string == "-5*(5*theta0 + 4)*(5*theta0 + 3)*(5*theta0 + 2)*(5*theta0 + 1)*z0 + theta0^4"
|