227 lines
7.9 KiB
Python
227 lines
7.9 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, other):
|
|
C = self.curve
|
|
F = C.base_ring
|
|
omega = self.form
|
|
if other in F:
|
|
return superelliptic_form(C, other*omega)
|
|
return superelliptic_form(C, other.function*omega)
|
|
|
|
def __truediv__(self, other):
|
|
''' f dx/g dx = f/g'''
|
|
C = self.curve
|
|
return superelliptic_function(C, self.form/other.form)
|
|
|
|
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):
|
|
print('start', self)
|
|
"""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
|
|
print('stop', self_with_no_denominator)
|
|
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
|
|
Fxy, Rxy, x, y = C.fct_field
|
|
g = reduction(C, y^m*g)
|
|
Rx.<x> = PolynomialRing(F)
|
|
Fx = FractionField(Rx)
|
|
FxRy.<y1> = PolynomialRing(Fx, 1)
|
|
g = FxRy(g(x = x, y = y1))
|
|
if j == 0:
|
|
return g.monomial_coefficient(y1^(0))/C.polynomial
|
|
return g.monomial_coefficient(y1^(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 integral(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() |