2022-11-18 15:00:34 +01:00
|
|
|
class superelliptic_function:
|
2023-02-23 12:26:25 +01:00
|
|
|
'''Class of rational functions on a superelliptic curve C. g = g(x, y) is a polynomial
|
|
|
|
defining the function.'''
|
2022-11-18 15:00:34 +01:00
|
|
|
def __init__(self, C, g):
|
|
|
|
F = C.base_ring
|
|
|
|
Rxy.<x, y> = PolynomialRing(F, 2)
|
|
|
|
Fxy = FractionField(Rxy)
|
|
|
|
f = C.polynomial
|
|
|
|
r = f.degree()
|
|
|
|
m = C.exponent
|
|
|
|
|
|
|
|
self.curve = C
|
|
|
|
g = reduction(C, g)
|
|
|
|
self.function = g
|
2023-02-23 12:26:25 +01:00
|
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
|
if self.function == other.function:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2022-11-18 15:00:34 +01:00
|
|
|
def __repr__(self):
|
|
|
|
return str(self.function)
|
|
|
|
|
|
|
|
def jth_component(self, j):
|
|
|
|
g = self.function
|
|
|
|
C = self.curve
|
|
|
|
F = C.base_ring
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
Fx.<x> = FractionField(Rx)
|
|
|
|
FxRy.<y> = PolynomialRing(Fx)
|
|
|
|
g = FxRy(g)
|
|
|
|
return coff(g, j)
|
|
|
|
|
|
|
|
def __add__(self, other):
|
|
|
|
C = self.curve
|
|
|
|
g1 = self.function
|
|
|
|
g2 = other.function
|
|
|
|
g = reduction(C, g1 + g2)
|
|
|
|
return superelliptic_function(C, g)
|
|
|
|
|
2023-02-24 13:51:49 +01:00
|
|
|
def __neg__(self):
|
|
|
|
C = self.curve
|
|
|
|
g = self.function
|
|
|
|
return superelliptic_function(C, -g)
|
|
|
|
|
2022-11-18 15:00:34 +01:00
|
|
|
def __sub__(self, other):
|
|
|
|
C = self.curve
|
|
|
|
g1 = self.function
|
|
|
|
g2 = other.function
|
|
|
|
g = reduction(C, g1 - g2)
|
|
|
|
return superelliptic_function(C, g)
|
|
|
|
|
|
|
|
def __mul__(self, other):
|
|
|
|
C = self.curve
|
2023-02-13 13:05:48 +01:00
|
|
|
try:
|
|
|
|
g1 = self.function
|
|
|
|
g2 = other.function
|
|
|
|
g = reduction(C, g1 * g2)
|
|
|
|
return superelliptic_function(C, g)
|
|
|
|
except:
|
|
|
|
g1 = self.function
|
|
|
|
g2 = other.form
|
|
|
|
g = reduction(C, g1 * g2)
|
|
|
|
return superelliptic_form(C, g)
|
|
|
|
|
|
|
|
def __rmul__(self, constant):
|
|
|
|
C = self.curve
|
|
|
|
g = self.function
|
|
|
|
return superelliptic_function(C, constant*g)
|
2022-11-18 15:00:34 +01:00
|
|
|
|
|
|
|
def __truediv__(self, other):
|
|
|
|
C = self.curve
|
|
|
|
g1 = self.function
|
|
|
|
g2 = other.function
|
|
|
|
g = reduction(C, g1 / g2)
|
|
|
|
return superelliptic_function(C, g)
|
|
|
|
|
|
|
|
def __pow__(self, exp):
|
|
|
|
C = self.curve
|
|
|
|
g = self.function
|
|
|
|
return superelliptic_function(C, g^(exp))
|
2023-02-13 18:11:13 +01:00
|
|
|
|
2022-11-18 15:00:34 +01:00
|
|
|
def diffn(self):
|
|
|
|
C = self.curve
|
|
|
|
f = C.polynomial
|
|
|
|
m = C.exponent
|
|
|
|
F = C.base_ring
|
|
|
|
g = self.function
|
|
|
|
Rxy.<x, y> = PolynomialRing(F, 2)
|
|
|
|
Fxy = FractionField(Rxy)
|
|
|
|
g = Fxy(g)
|
|
|
|
A = g.derivative(x)
|
|
|
|
B = g.derivative(y)*f.derivative(x)/(m*y^(m-1))
|
|
|
|
return superelliptic_form(C, A+B)
|
|
|
|
|
2023-02-23 12:26:25 +01:00
|
|
|
def coordinates(self, basis = 0, basis_holo = 0, prec=50):
|
2023-02-13 18:11:13 +01:00
|
|
|
'''Find coordinates in H1(X, OX) in given basis basis with dual basis basis_holo.'''
|
|
|
|
C = self.curve
|
|
|
|
if basis == 0:
|
2023-02-23 12:26:25 +01:00
|
|
|
basis = C.basis_of_cohomology()
|
2023-02-13 18:11:13 +01:00
|
|
|
if basis_holo == 0:
|
|
|
|
basis_holo = C.holomorphic_differentials_basis()
|
|
|
|
g = C.genus()
|
|
|
|
coordinates = g*[0]
|
|
|
|
for i, omega in enumerate(basis_holo):
|
|
|
|
coordinates[i] = omega.serre_duality_pairing(self, prec=prec)
|
|
|
|
return coordinates
|
2022-11-18 15:00:34 +01:00
|
|
|
|
2023-02-23 12:26:25 +01:00
|
|
|
def expansion_at_infty(self, place = 0, prec=20):
|
2022-11-18 15:00:34 +01:00
|
|
|
C = self.curve
|
|
|
|
f = C.polynomial
|
|
|
|
m = C.exponent
|
|
|
|
F = C.base_ring
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
f = Rx(f)
|
|
|
|
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
|
|
|
|
RptW.<W> = PolynomialRing(Rt)
|
|
|
|
RptWQ = FractionField(RptW)
|
|
|
|
Rxy.<x, y> = PolynomialRing(F)
|
|
|
|
RxyQ = FractionField(Rxy)
|
|
|
|
fct = self.function
|
|
|
|
fct = RxyQ(fct)
|
|
|
|
r = f.degree()
|
|
|
|
delta, a, b = xgcd(m, r)
|
|
|
|
b = -b
|
|
|
|
M = m/delta
|
|
|
|
R = r/delta
|
|
|
|
while a<0:
|
|
|
|
a += R
|
|
|
|
b += M
|
|
|
|
|
|
|
|
g = (x^r*f(x = 1/x))
|
|
|
|
gW = RptWQ(g(x = t^M * W^b)) - W^(delta)
|
2023-02-13 13:05:48 +01:00
|
|
|
ww = naive_hensel(gW, F, start = root_of_unity(F, delta)^place, prec = prec)
|
2022-11-18 15:00:34 +01:00
|
|
|
xx = Rt(1/(t^M*ww^b))
|
|
|
|
yy = 1/(t^R*ww^a)
|
|
|
|
return Rt(fct(x = Rt(xx), y = Rt(yy)))
|
2023-02-23 12:26:25 +01:00
|
|
|
|
|
|
|
def pth_root(self):
|
|
|
|
'''Compute p-th root of given function. This uses the following fact: if h = H^p, then C(h*dx/x) = H*dx/x.'''
|
|
|
|
C = self.curve
|
|
|
|
if self.diffn().form != 0:
|
|
|
|
raise ValueError("Function is not a p-th power.")
|
|
|
|
Fxy, Rxy, x, y = C.fct_field
|
|
|
|
auxilliary_form = superelliptic_form(C, self.function/x)
|
|
|
|
auxilliary_form = auxilliary_form.cartier()
|
|
|
|
auxilliary_form = C.x * auxilliary_form
|
|
|
|
auxilliary_form = auxilliary_form.form
|
|
|
|
return superelliptic_function(C, auxilliary_form)
|