DeRhamComputation/superelliptic/superelliptic_form_class.sage
2023-09-23 13:33:58 +00:00

216 lines
7.5 KiB
Python

class superelliptic_form:
def __init__(self, C, g):
F = C.base_ring
Rxy.<x, y> = PolynomialRing(F, 2)
Fxy = FractionField(Rxy)
g = Fxy(reduction_form(C, g))
self.form = g
self.curve = C
def __eq__(self, other):
if self.reduce().form == other.reduce().form:
return True
return False
def __add__(self, other):
C = self.curve
g1 = self.form
g2 = other.form
g = reduction(C, g1 + g2)
return superelliptic_form(C, g)
def __sub__(self, other):
C = self.curve
g1 = self.form
g2 = other.form
g = reduction(C, g1 - g2)
return superelliptic_form(C, g)
def __neg__(self):
C = self.curve
g = self.form
return superelliptic_form(C, -g)
def __repr__(self):
g = self.form
if len(str(g)) == 1:
return str(g) + ' dx'
return '('+str(g) + ') dx'
def __rmul__(self, constant):
C = self.curve
omega = self.form
return superelliptic_form(C, constant*omega)
def cartier(self):
'''Computes Cartier operator on the form. Idea: y^m = f(x) -> y^(p^r - 1) = f(x)^M, where r = ord_p(m),
M = (p^r - 1)/m. Thus h(x)/y^j dx = h(x) f(x)^(M*j)/y^(p^r * j) dx. Thus C(h(x)/y^j dx) = 1/y^(p^(r-1)*j) C(h(x) f(x)^(M*j) dx).'''
C = self.curve
m = C.exponent
p = C.characteristic
f = C.polynomial
F = C.base_ring
Rx.<x> = PolynomialRing(F)
Fx = FractionField(Rx)
FxRy.<y> = PolynomialRing(Fx)
Fxy = FractionField(FxRy)
result = 0*C.dx
mult_order = Integers(m)(p).multiplicative_order()
M = Integer((p^(mult_order)-1)/m)
for j in range(0, m):
fct_j = self.jth_component(j)
h = Fx(fct_j*f^(M*j))
h_denom = h.denominator()
h *= (h_denom)^(p)
h = Rx(h)
j1 = (p^(mult_order-1)*j)%m
B = floor(p^(mult_order-1)*j/m)
P = polynomial_part(p, h)
if F.cardinality() != p:
d = P.degree()
P = sum(P[i].nth_root(p)*x^i for i in range(0, d+1))
result += superelliptic_form(C, P/(f^B*y^(j1)*h_denom))
return result
def serre_duality_pairing(self, fct, prec=20):
'''Compute Serre duality pairing of the form with a cohomology class in H1(X, OX) represented by function fct.'''
result = 0
C = self.curve
delta = C.nb_of_pts_at_infty
for i in range(delta):
result += (fct*self).expansion_at_infty(place=i, prec=prec)[-1]
return -result
def coordinates(self, basis = 0):
"""Find coordinates of the given holomorphic form self in terms of the basis forms in a list holo."""
C = self.curve
if basis == 0:
basis = C.holomorphic_differentials_basis()
Fxy, Rxy, x, y = C.fct_field
# We need to have only polynomials to use monomial_coefficients in linear_representation_polynomials,
# and sometimes basis elements have denominators. Thus we multiply by them.
denom = LCM([denominator(omega.form) for omega in basis])
basis = [denom*omega.form for omega in basis]
self_with_no_denominator = denom*self.form
return linear_representation_polynomials(Rxy(self_with_no_denominator), [Rxy(omega) for omega in basis])
def jth_component(self, j):
'''If self = sum_j h_j(x)/y^j dx, output is h_j(x).'''
g = self.form
C = self.curve
m = C.exponent
F = C.base_ring
Rx.<x> = PolynomialRing(F)
Fx = FractionField(Rx)
FxRy.<y> = PolynomialRing(Fx)
g = reduction(C, y^m*g)
g = FxRy(g)
if j == 0:
return g.monomial_coefficient(y^(0))/C.polynomial
return g.monomial_coefficient(y^(m-j))
def is_regular_on_U0(self):
C = self.curve
F = C.base_ring
m = C.exponent
Rx.<x> = PolynomialRing(F)
for j in range(0, m):
if self.jth_component(j) not in Rx:
return False
return True
def is_regular_on_Uinfty(self):
C = self.curve
F = C.base_ring
m = C.exponent
f = C.polynomial
r = f.degree()
delta = GCD(m, r)
M = m/delta
R = r/delta
for j in range(1, m):
A = self.jth_component(j)
d = degree_of_rational_fctn(A, F)
if(-d*M + j*R -(M+1)<0):
return False
return True
def expansion_at_infty(self, place = 0, prec=10):
g = self.form
C = self.curve
g = superelliptic_function(C, g)
F = C.base_ring
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
g = Rt(g.expansion_at_infty(place = place, prec=prec))
return g*C.dx_series[place]
def expansion(self, pt, prec = 50):
'''Expansion in the completed ring of the point pt. If pt is an integer, it means the corresponding place at infinity.'''
if pt in ZZ:
return self.expansion_at_infty(place=pt, prec=prec)
C = self.curve
dx_series = C.x.expansion(pt = pt, prec=prec).derivative()
aux_fct = superelliptic_function(C, self.form)
return aux_fct.expansion(pt=pt, prec=prec)*dx_series
def residue(self, place = 0, prec=30):
return self.expansion_at_infty(place = place, prec=prec)[-1]
def reduce(self):
fct = self.form
C = self.curve
fct = reduction(C, fct)
return superelliptic_form(C, fct)
def reduce2(self):
fct = self.form
C = self.curve
m = C.exponent
F = C.base_ring
Rxy.<x, y> = PolynomialRing(F, 2)
Fxy = FractionField(Rxy)
fct = reduction(C, Fxy(y^m*fct))
return superelliptic_form(C, fct/y^m)
def int(self):
'''Computes an "integral" of a form dg. Idea: y^m = f(x) -> y^(p^r - 1) = f(x)^M, where r = ord_p(m),
M = (p^r - 1)/m. Thus h(x)/y^j dx = h(x) f(x)^(M*j)/y^(p^r * j) dx. Thus int(h(x)/y^j dx) = 1/y^(p^(r-1)*j) int(h(x) f(x)^(M*j) dx).'''
C = self.curve
m = C.exponent
p = C.characteristic
f = C.polynomial
F = C.base_ring
Rx.<x> = PolynomialRing(F)
Fx = FractionField(Rx)
FxRy.<y> = PolynomialRing(Fx)
Fxy = FractionField(FxRy)
result = 0*C.x
mult_order = Integers(m)(p).multiplicative_order()
M = Integer((p^(mult_order)-1)/m)
for j in range(0, m):
fct_j = self.jth_component(j)
h = Fx(fct_j*f^(M*j))
h_denom = h.denominator()
h *= (h_denom)^(p)
h = Rx(h)
j1 = (p^(mult_order)*j)%m
B = floor(p^(mult_order)*j/m)
result += superelliptic_function(C, h.integral()/(f^(B)*y^(j1)*h_denom^p))
return result
def inv_cartier(omega):
'''If omega is regular, return form eta such that Cartier(eta) = omega'''
omega_regular = omega.regular_form()
C = omega.curve
p = C.characteristic
return (omega_regular.dx)^p*C.x^(p-1)*C.dx + (omega_regular.dy)^p*C.y^(p-1)*C.y.diffn()
def valuation(self, place = 0):
'''Return valuation at i-th place at infinity.'''
C = self.curve
F = C.base_ring
Rt.<t> = LaurentSeriesRing(F)
return Rt(self.expansion_at_infty(place = place)).valuation()