DeRhamComputation/heisenberg_covers/heisenberg_reduction.sage

33 lines
1.4 KiB
Python

def heisenberg_reduction(AS, fct):
'''Simplify rational function fct as a function in the function field of AS, so that z[i] appear in powers <p and only in numerator'''
n = AS.height
F = AS.base_ring
RxyzQ, Rxyz, x, y, z = AS.fct_field
p = F.characteristic()
ff = AS.functions
ff = [RxyzQ(F.function) for F in ff]
fct = RxyzQ(fct)
fct1 = numerator(fct)
fct2 = denominator(fct)
denom = heisenberg_function(AS, fct2)
denom_norm = prod(heisenberg_function(AS, fct2).group_action(g) for g in AS.group if g != (0, 0, 0))
fct1 = Rxyz(fct1*denom_norm.function)
fct2 = Rxyz(fct2*denom_norm.function)
if fct2 != 1:
return heisenberg_reduction(AS, fct1)/heisenberg_reduction(AS, fct2)
result = RxyzQ(0)
change = 0
for a in fct1.monomials():
degrees_zi = [a.degree(z[i]) for i in range(n)]
d_div = [a.degree(z[i])//p for i in range(n)]
if d_div != n*[0]:
change = 1
d_rem = [a.degree(z[i])%p for i in range(n)]
monomial = fct1.monomial_coefficient(a)*x^(a.degree(x))*y^(a.degree(y))*prod(z[i]^(d_rem[i]) for i in range(n))*prod((z[i] + ff[i])^(d_div[i]) for i in range(n-1))*(z[2] + ff[2] + (z[0] - z[1])*ff[1])^(d_div[2])
result += RxyzQ(monomial)
if change == 0:
return RxyzQ(result)
else:
return heisenberg_reduction(AS, RxyzQ(result))