DeRhamComputation/sage/superelliptic/superelliptic_form_class.sage

205 lines
7.1 KiB
Python
Raw Normal View History

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 __eq__(self, other):
if self.reduce().form == other.reduce().form:
return True
return False
2022-11-18 15:00:34 +01:00
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)
2023-02-24 13:51:49 +01:00
def __neg__(self):
C = self.curve
g = self.form
return superelliptic_form(C, -g)
2022-11-18 15:00:34 +01:00
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)
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 = 0*C.dx
2022-11-18 15:00:34 +01:00
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
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.'''
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
2023-02-27 12:51:16 +01:00
m = C.exponent
2022-11-18 15:00:34 +01:00
F = C.base_ring
Rx.<x> = PolynomialRing(F)
Fx = FractionField(Rx)
FxRy.<y> = PolynomialRing(Fx)
2023-02-27 12:51:16 +01:00
g = reduction(C, y^m*g)
g = FxRy(g)
if j == 0:
return g.monomial_coefficient(y^(0))/C.polynomial
2023-02-27 12:51:16 +01:00
return g.monomial_coefficient(y^(m-j))
2022-11-18 15:00:34 +01:00
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):
2022-11-18 15:00:34 +01:00
if self.jth_component(j) not in Rx:
return False
return True
2022-11-18 15:00:34 +01:00
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
2022-11-18 15:00:34 +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)
g = g.expansion_at_infty(place = place, prec=prec)
2023-02-27 12:51:16 +01:00
x_series = 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
2023-02-27 12:51:16 +01:00
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
2023-02-27 12:51:16 +01:00
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()