2022-11-18 15:00:34 +01:00
|
|
|
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 __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 __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
|
2023-02-13 13:05:48 +01:00
|
|
|
return superelliptic_form(C, constant*omega)
|
2022-11-18 15:00:34 +01:00
|
|
|
|
|
|
|
def cartier(self):
|
2023-02-23 12:26:25 +01:00
|
|
|
'''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).'''
|
2022-11-18 15:00:34 +01:00
|
|
|
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 = superelliptic_form(C, FxRy(0))
|
|
|
|
mult_order = Integers(m)(p).multiplicative_order()
|
|
|
|
M = Integer((p^(mult_order)-1)/m)
|
|
|
|
|
2023-02-23 12:26:25 +01:00
|
|
|
for j in range(0, m):
|
2022-11-18 15:00:34 +01:00
|
|
|
fct_j = self.jth_component(j)
|
2023-02-23 12:26:25 +01:00
|
|
|
h = Fx(fct_j*f^(M*j))
|
|
|
|
h_denom = h.denominator()
|
|
|
|
h *= (h_denom)^(p)
|
|
|
|
h = Rx(h)
|
2022-11-18 15:00:34 +01:00
|
|
|
j1 = (p^(mult_order-1)*j)%m
|
|
|
|
B = floor(p^(mult_order-1)*j/m)
|
2023-02-23 12:26:25 +01:00
|
|
|
result += superelliptic_form(C, polynomial_part(p, h)/(f^B*y^(j1)*h_denom))
|
2022-11-18 15:00:34 +01:00
|
|
|
return result
|
2023-02-13 18:11:13 +01:00
|
|
|
|
|
|
|
def serre_duality_pairing(self, fct, prec=20):
|
2023-02-23 12:26:25 +01:00
|
|
|
'''Compute Serre duality pairing of the form with a cohomology class in H1(X, OX) represented by function fct.'''
|
2023-02-13 18:11:13 +01:00
|
|
|
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
|
2022-11-18 15:00:34 +01:00
|
|
|
|
2023-02-23 12:26:25 +01:00
|
|
|
def coordinates(self, basis = 0):
|
|
|
|
"""Find coordinates of the given holomorphic form self in terms of the basis forms in a list holo."""
|
2022-11-18 15:00:34 +01:00
|
|
|
C = self.curve
|
2023-02-23 12:26:25 +01:00
|
|
|
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])
|
2022-11-18 15:00:34 +01:00
|
|
|
|
|
|
|
def jth_component(self, j):
|
2023-02-23 12:26:25 +01:00
|
|
|
'''If self = sum_j h_j(x)/y^j dx, output is h_j(x).'''
|
2022-11-18 15:00:34 +01:00
|
|
|
g = self.form
|
|
|
|
C = self.curve
|
|
|
|
F = C.base_ring
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
Fx = FractionField(Rx)
|
|
|
|
FxRy.<y> = PolynomialRing(Fx)
|
|
|
|
Fxy = FractionField(FxRy)
|
|
|
|
Ryinv.<y_inv> = PolynomialRing(Fx)
|
|
|
|
g = Fxy(g)
|
|
|
|
g = g(y = 1/y_inv)
|
|
|
|
g = Ryinv(g)
|
|
|
|
return coff(g, 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(1, m):
|
|
|
|
if self.jth_component(j) not in Rx:
|
|
|
|
return 0
|
|
|
|
return 1
|
|
|
|
|
|
|
|
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 0
|
|
|
|
return 1
|
|
|
|
|
2023-02-13 13:05:48 +01:00
|
|
|
def expansion_at_infty(self, place = 0, prec=10):
|
2022-11-18 15:00:34 +01:00
|
|
|
g = self.form
|
|
|
|
C = self.curve
|
|
|
|
g = superelliptic_function(C, g)
|
2023-02-13 13:05:48 +01:00
|
|
|
g = g.expansion_at_infty(place = place, prec=prec)
|
|
|
|
x_series = superelliptic_function(C, x).expansion_at_infty(place = place, prec=prec)
|
2022-11-18 15:00:34 +01:00
|
|
|
dx_series = x_series.derivative()
|
|
|
|
return g*dx_series
|