superelliptic de rham witt - poczatek

This commit is contained in:
jgarnek 2023-02-23 11:26:25 +00:00
parent f683017855
commit 856d74212b
12 changed files with 12073 additions and 101 deletions

File diff suppressed because one or more lines are too long

View File

@ -32,12 +32,12 @@ class as_cover:
all_jumps = [] all_jumps = []
for i in range(delta): for i in range(delta):
x_series = superelliptic_function(C, x).expansion_at_infty(i = i, prec=prec) x_series = superelliptic_function(C, x).expansion_at_infty(place = i, prec=prec)
y_series = superelliptic_function(C, y).expansion_at_infty(i = i, prec=prec) y_series = superelliptic_function(C, y).expansion_at_infty(place = i, prec=prec)
z_series = [] z_series = []
jumps = [] jumps = []
n = len(list_of_fcts) n = len(list_of_fcts)
list_of_power_series = [g.expansion_at_infty(i = i, prec=prec) for g in list_of_fcts] list_of_power_series = [g.expansion_at_infty(place = i, prec=prec) for g in list_of_fcts]
for i in range(n): for i in range(n):
power_series = list_of_power_series[i] power_series = list_of_power_series[i]
jump, correction, t_old, z = artin_schreier_transform(power_series, prec = prec) jump, correction, t_old, z = artin_schreier_transform(power_series, prec = prec)
@ -93,19 +93,19 @@ class as_cover:
p = self.characteristic p = self.characteristic
return p^n*gY + (p^n - 1)*(delta - 1) + sum(p^(n-j-1)*(jumps[i][j]-1)*(p-1)/2 for j in range(n) for i in range(delta)) return p^n*gY + (p^n - 1)*(delta - 1) + sum(p^(n-j-1)*(jumps[i][j]-1)*(p-1)/2 for j in range(n) for i in range(delta))
def exponent_of_different(self, i = 0): def exponent_of_different(self, place = 0):
jumps = self.jumps jumps = self.jumps
n = self.height n = self.height
delta = self.nb_of_pts_at_infty delta = self.nb_of_pts_at_infty
p = self.characteristic p = self.characteristic
return sum(p^(n-j-1)*(jumps[i][j]+1)*(p-1) for j in range(n)) return sum(p^(n-j-1)*(jumps[place][j]+1)*(p-1) for j in range(n))
def exponent_of_different_prim(self, i = 0): def exponent_of_different_prim(self, place = 0):
jumps = self.jumps jumps = self.jumps
n = self.height n = self.height
delta = self.nb_of_pts_at_infty delta = self.nb_of_pts_at_infty
p = self.characteristic p = self.characteristic
return sum(p^(n-j-1)*(jumps[i][j])*(p-1) for j in range(n)) return sum(p^(n-j-1)*(jumps[place][j])*(p-1) for j in range(n))
def holomorphic_differentials_basis(self, threshold = 8): def holomorphic_differentials_basis(self, threshold = 8):
from itertools import product from itertools import product
@ -136,7 +136,7 @@ class as_cover:
forms = holomorphic_combinations(S) forms = holomorphic_combinations(S)
for i in range(1, delta): for i in range(1, delta):
forms = [(omega, omega.expansion_at_infty(i = i)) for omega in forms] forms = [(omega, omega.expansion_at_infty(place = i)) for omega in forms]
forms = holomorphic_combinations(forms) forms = holomorphic_combinations(forms)
if len(forms) < self.genus(): if len(forms) < self.genus():
@ -146,6 +146,14 @@ class as_cover:
print("Increase precision.") print("Increase precision.")
return forms return forms
def cartier_matrix(self, prec=50):
g = self.genus()
F = self.base_ring
M = matrix(F, g, g)
for i, omega in enumerate(self.holomorphic_differentials_basis()):
M[:, i] = vector(omega.cartier().coordinates())
return M
def at_most_poles(self, pole_order, threshold = 8): def at_most_poles(self, pole_order, threshold = 8):
""" Find fcts with pole order in infty's at most pole_order. Threshold gives a bound on powers of x in the function. """ Find fcts with pole order in infty's at most pole_order. Threshold gives a bound on powers of x in the function.
If you suspect that you haven't found all the functions, you may increase it.""" If you suspect that you haven't found all the functions, you may increase it."""
@ -177,7 +185,7 @@ class as_cover:
forms = holomorphic_combinations_fcts(S, pole_order) forms = holomorphic_combinations_fcts(S, pole_order)
for i in range(1, delta): for i in range(1, delta):
forms = [(omega, omega.expansion_at_infty(i = i)) for omega in forms] forms = [(omega, omega.expansion_at_infty(place = i)) for omega in forms]
forms = holomorphic_combinations_fcts(forms, pole_order) forms = holomorphic_combinations_fcts(forms, pole_order)
return forms return forms
@ -229,13 +237,13 @@ class as_cover:
forms = holomorphic_combinations_forms(S, pole_order) forms = holomorphic_combinations_forms(S, pole_order)
for i in range(1, delta): for i in range(1, delta):
forms = [(omega, omega.expansion_at_infty(i = i)) for omega in forms] forms = [(omega, omega.expansion_at_infty(place = i)) for omega in forms]
forms = holomorphic_combinations_forms(forms, pole_order) forms = holomorphic_combinations_forms(forms, pole_order)
return forms return forms
def uniformizer(self, i = 0): def uniformizer(self, place = 0):
'''Return uniformizer of curve self at i-th place at infinity.''' '''Return uniformizer of curve self at place-th place at infinity.'''
p = self.characteristic p = self.characteristic
n = self.height n = self.height
F = self.base_ring F = self.base_ring
@ -244,8 +252,8 @@ class as_cover:
z = [as_function(self, zi) for zi in z] z = [as_function(self, zi) for zi in z]
# We create a list of functions. We add there all variables... # We create a list of functions. We add there all variables...
list_of_fcts = [fx]+z list_of_fcts = [fx]+z
vfx = fx.valuation(i) vfx = fx.valuation(place)
vz = [zi.valuation(i) for zi in z] vz = [zi.valuation(place) for zi in z]
# Then we subtract powers of variables with the same valuation (so that 1/t^(kp) cancels) and add to this list. # Then we subtract powers of variables with the same valuation (so that 1/t^(kp) cancels) and add to this list.
for j1 in range(n): for j1 in range(n):
@ -255,19 +263,19 @@ class as_cover:
vz1 = vz[j1]/a vz1 = vz[j1]/a
vz2 = vz[j2]/a vz2 = vz[j2]/a
for b in F: for b in F:
if (z[j1]^(vz2) - b*z[j2]^(vz1)).valuation(i) > (z[j2]^(vz1)).valuation(i): if (z[j1]^(vz2) - b*z[j2]^(vz1)).valuation(place) > (z[j2]^(vz1)).valuation(place):
list_of_fcts += [z[j1]^(vz2) - b*z[j2]^(vz1)] list_of_fcts += [z[j1]^(vz2) - b*z[j2]^(vz1)]
for j1 in range(n): for j1 in range(n):
a = gcd(vz[j1], vfx) a = gcd(vz[j1], vfx)
vzj = vz[j1] /a vzj = vz[j1] /a
vfx = vfx/a vfx = vfx/a
for b in F: for b in F:
if (fx^(vzj) - b*z[j1]^(vfx)).valuation(i) > (z[j1]^(vfx)).valuation(i): if (fx^(vzj) - b*z[j1]^(vfx)).valuation(place) > (z[j1]^(vfx)).valuation(place):
list_of_fcts += [fx^(vzj) - b*z[j1]^(vfx)] list_of_fcts += [fx^(vzj) - b*z[j1]^(vfx)]
#Finally, we check if on the list there are two elements with the same valuation. #Finally, we check if on the list there are two elements with the same valuation.
for f1 in list_of_fcts: for f1 in list_of_fcts:
for f2 in list_of_fcts: for f2 in list_of_fcts:
d, a, b = xgcd(f1.valuation(i), f2.valuation(i)) d, a, b = xgcd(f1.valuation(place), f2.valuation(place))
if d == 1: if d == 1:
return f1^a*f2^b return f1^a*f2^b
raise ValueError("My method of generating fcts with relatively prime valuation failed.") raise ValueError("My method of generating fcts with relatively prime valuation failed.")
@ -299,6 +307,10 @@ class as_cover:
i+=1 i+=1
return ramification_jps return ramification_jps
def a_number(self):
g = self.genus()
return g - self.cartier_matrix().rank()
def cohomology_of_structure_sheaf_basis(self, threshold = 8): def cohomology_of_structure_sheaf_basis(self, threshold = 8):
holo_diffs = self.holomorphic_differentials_basis(threshold = threshold) holo_diffs = self.holomorphic_differentials_basis(threshold = threshold)
from itertools import product from itertools import product

View File

@ -107,6 +107,39 @@ class as_form:
AS = self.curve AS = self.curve
return sum((fct*self).residue(place = _) for _ in range(AS.nb_of_pts_at_infty)) return sum((fct*self).residue(place = _) for _ in range(AS.nb_of_pts_at_infty))
def cartier(self):
C = self.curve
F = C.base_ring
n = C.height
ff = C.functions
p = F.characteristic()
C_super = C.quotient
(RxyzQ, Rxyz, x, y, z) = C.fct_field
fct = self.form
Rxy.<x, y> = PolynomialRing(F, 2)
RxyQ = FractionField(Rxy)
x, y = Rxyz.gens()[0], Rxyz.gens()[1]
z = Rxyz.gens()[2:]
num = Rxyz(fct.numerator())
den = Rxyz(fct.denominator())
result = RxyzQ(0)
#return (num, den, z, fct)
if den in Rxy:
sub_list = {x : x, y : y} | {z[j] : (z[j]^p - RxyzQ(ff[j].function)) for j in range(n)}
num = RxyzQ(num.substitute(sub_list))
den1 = Rxyz(num.denominator())
num = Rxyz(num*den1^p)
for monomial in Rxyz(num).monomials():
degrees = [monomial.degree(z[i]) for i in range(n)]
product_of_z = prod(z[i]^(degrees[i]) for i in range(n))
monomial_divided_by_z = monomial/product_of_z
product_of_z_no_p = prod(z[i]^(degrees[i]/p) for i in range(n))
aux_form = superelliptic_form(C_super, RxyQ(monomial_divided_by_z/den))
aux_form = aux_form.cartier()
result += product_of_z_no_p * Rxyz(num).monomial_coefficient(monomial) * aux_form.form/den1
return as_form(C, result)
raise ValueError("Please present first your form as sum z^i omega_i, where omega_i are forms on quotient curve.")
def artin_schreier_transform(power_series, prec = 10): def artin_schreier_transform(power_series, prec = 10):
"""Given a power_series, find correction such that power_series - (correction)^p +correction has valuation """Given a power_series, find correction such that power_series - (correction)^p +correction has valuation
-jump non divisible by p. Also, express t (the variable) in terms of the uniformizer at infty on the curve -jump non divisible by p. Also, express t (the variable) in terms of the uniformizer at infty on the curve

View File

@ -1,19 +1,9 @@
p = 5 p = 2
m = 1 m = 1
F = GF(p) F = GF(p)
Rx.<x> = PolynomialRing(F) Rx.<x> = PolynomialRing(F)
f = x f = x
C_super = superelliptic(f, m) C = superelliptic(f, m)
xx = C.x
Rxy.<x, y> = PolynomialRing(F, 2) AS = as_cover(C, [xx^5, xx^5 + xx^3])
for a in range(3, 13): print(AS.magical_element())
for b in range(3, 13):
if a %p != 0 and b%p != 0 and a !=b:
try:
f1 = superelliptic_function(C_super, x^a+x)
f2 = superelliptic_function(C_super, x^b)
AS = as_cover(C_super, [f1, f2], prec=1000)
#print(AS.at_most_poles(AS.exponent_of_different_prim()))
print(AS.magical_element(threshold = 20))
except:
pass

View File

@ -1,13 +1,5 @@
p = 3 F = GF(2)
m = 2 A = matrix(F, [[1, 1, 1], [0, 0, 1], [0, 1, 0]])
F = GF(p) B = matrix(F, [[0, 0, 1], [1, 1, 1], [1, 0, 0]])
Rx.<x> = PolynomialRing(F) print(A^2 == identity_matrix(3), B^2 == identity_matrix(3), A*B == B*A)
f = x^3 - x print(magmathis(A, B))
C = superelliptic(f, m)
x = C.x
y = C.y
dx = C.dx
om1 = x^3*y*dx
u = (C.one)/x
v = y/x^2
print(om1 + u^3*v*u.diffn() - (y/x)^2*(y/x).diffn())

View File

@ -0,0 +1,110 @@
class superelliptic_witt:
def __init__(self, C, t, f0, f1):
''' Define Witt function on C of the form [t] + f0([x], [y]) + V(f1). '''
self.curve = C
p = C.characteristic
self.t = t #superelliptic_function
self.f0 = reduce_rational_fct(f0, p) #polynomial/rational function over Z/p^2
self.f1 = f1 #superelliptic_function
def __repr__(self):
f0 = self.f0
f1 = self.f1
t = self.t
return "[" + str(t) + "] + " + str(f0).replace("x", "[x]").replace("y", "[y]") + " + V(" + str(f1) + ")"
def __add__(self, other):
C = self.curve
return superelliptic_witt(C, self.t + other.t, self.f0 + other.f0, self.f1 + other.f1)
def teichmuller_representation(self):
'''Represents as [f] + V(g), i.e. f0 = 0.'''
C = self.curve
Fxy, Rxy, x, y = self.fct_field
F = C.base_ring
function = Rxy(self.f0)
if self.f0 == 0:
return self
M = Rxy(function.monomials()[0])
a = F(function.monomial_coefficient(M))
fct1 = fct - superelliptic_function(C, a*M)
function1 = fct1.function
return teichmuller(fct1) + superelliptic_witt(C, (a.lift())^p*M.change_ring(QQ), superelliptic_function(C, function1^2*a*M + function1*(a*M)^2))
def antiteichmuller_representation(self):
'''Represents as f([x], [y]) + V(g), i.e. teichmuller part is zero.'''
return 0
def reduce_rational_fct(fct, p):
Rxy.<x, y> = PolynomialRing(QQ)
Fxy = FractionField(Rxy)
fct = Fxy(fct)
num = Rxy(fct.numerator())
den = Rxy(fct.denominator())
num1 = Rxy(0)
for m in num.monomials():
a = num.monomial_coefficient(m)
num1 += (a%p^2)*m
den1 = Rxy(0)
for m in den.monomials():
a = den.monomial_coefficient(m)
den1 += (a%p^2)*m
return num1/den1
def teichmuller(fct):
C = fct.curve
Fxy, Rxy, x, y = C.fct_field
F = C.base_ring
function = Rxy(fct.function)
if function == 0:
return superelliptic_witt(C, 0, 0*C.x)
M = Rxy(function.monomials()[0])
a = F(function.monomial_coefficient(M))
fct1 = fct - superelliptic_function(C, a*M)
function1 = fct1.function
return teichmuller(fct1) + superelliptic_witt(C, (a.lift())^p*M.change_ring(QQ), superelliptic_function(C, function1^2*a*M + function1*(a*M)^2))
class superelliptic_drw_form:
def __init__(self, C, omega_x, omega_y, omega, h):
'''Form [omega_x] d[x] + [omega_y] d[y] + V(omega) + dV([h])'''
self.curve = C
self.omega_x = omega_x
self.omega_y = omega_y
self.omega = omega
self.h = h
def __eq__(self, other):
eq1 = (self.omega1 == self.omega1)
try:
H = (self.h - other.h).pthroot()
except:
return False
eq2 = (self.omega2 - other.omega2).cartier() - H.diffn()
if eq1 and eq2:
return True
return False
def __repr__(self):
C = self.curve
omega_x = self.omega_x
omega_y = self.omega_y
h = self.h
return str(omega_x) + "] dx + [" + str(omega_x.form) + "] d[x] " + "+ V(" + str(omega2) + ") + dV([" + str(h) +"])"
def mult_by_p(omega):
C = omega.curve
fct = omega.form
Fxy, Rxy, x, y = C.fct_field
omega2 = superelliptic_form(C, fct^p * x^(p-1))
result = superelliptic_drw_form(C, 0*C.dx, omega2, 0*C.x)
return result
def basis_W2Omega(C):
basis = C.holomorphic_differentials_basis()
result = []
for omega in basis:
result += [mult_by_p(omega)]
image_of_cartier = []
return result

View File

@ -2,6 +2,8 @@ load('superelliptic/superelliptic_class.sage')
load('superelliptic/superelliptic_function_class.sage') load('superelliptic/superelliptic_function_class.sage')
load('superelliptic/superelliptic_form_class.sage') load('superelliptic/superelliptic_form_class.sage')
load('superelliptic/superelliptic_cech_class.sage') load('superelliptic/superelliptic_cech_class.sage')
load('superelliptic/frobenius_kernel.sage')
load('superelliptic/decomposition_into_g0_g8.sage')
load('as_covers/as_cover_class.sage') load('as_covers/as_cover_class.sage')
load('as_covers/as_function_class.sage') load('as_covers/as_function_class.sage')
load('as_covers/as_form_class.sage') load('as_covers/as_form_class.sage')
@ -17,8 +19,10 @@ load('auxilliaries/hensel.sage')
load('auxilliaries/linear_combination_polynomials.sage') load('auxilliaries/linear_combination_polynomials.sage')
############## ##############
############## ##############
load('drafty/second_patch.sage')
load('drafty/regular_on_U0.sage')
load('drafty/lift_to_de_rham.sage') load('drafty/lift_to_de_rham.sage')
#load('drafty/superelliptic_cohomology_class.sage') #load('drafty/superelliptic_cohomology_class.sage')
load('drafty/draft5.sage') load('drafty/superelliptic_drw.sage')
load('drafty/draft.sage')
load('drafty/pole_numbers.sage') load('drafty/pole_numbers.sage')
#load('drafty/draft4.sage')

View File

@ -0,0 +1,44 @@
def decomposition_g0_g8(fct):
'''Writes fct as a difference g0 - g8, with g0 regular on the affine patch and g8 at the points in infinity.'''
C = fct.curve
g = C.genus()
if fct.coordinates() != g*[0]:
raise ValueError("The given function cannot be written as g0 - g8.")
Fxy, Rxy, x, y = C.fct_field
fct = Fxy(fct.function)
num = fct.numerator()
den = fct.denominator()
aux_den = superelliptic_function(C, Rxy(den))
g0 = superelliptic_function(C, 0)
g8 = superelliptic_function(C, 0)
for monomial in num.monomials():
aux = superelliptic_function(C, monomial)
if aux.expansion_at_infty().valuation() >= aux_den.expansion_at_infty().valuation():
g8 += num.monomial_coefficient(monomial)*aux/aux_den
else:
g0 += num.monomial_coefficient(monomial)*aux/aux_den
return (g0, g8)
def decomposition_omega0_omega8(omega, prec=50):
'''Writes omega as a difference omega0 - omega8, with omega0 regular on the affine patch and omega8 at the points in infinity.'''
C = omega.curve
Fxy, Rxy, x, y = C.fct_field
fct = Fxy(omega.form)
num = fct.numerator()
den = fct.denominator()
aux_den = superelliptic_function(C, Rxy(den))
g0 = superelliptic_function(C, 0)
g8 = superelliptic_function(C, 0)
dx_valuation = C.dx.expansion_at_infty(prec=prec).valuation()
for monomial in num.monomials():
aux = superelliptic_function(C, monomial)
if aux.expansion_at_infty(prec=prec).valuation() + dx_valuation >= aux_den.expansion_at_infty(prec=prec).valuation():
g8 += num.monomial_coefficient(monomial)*aux/aux_den
else:
g0 += num.monomial_coefficient(monomial)*aux/aux_den
g0, g8 = g0*C.dx, g8*C.dx
if g0.is_regular_on_U0():
return (g0, g8)
else:
raise Error("Something went wrong.")

View File

@ -12,7 +12,7 @@ class superelliptic:
self.exponent = m self.exponent = m
self.base_ring = F self.base_ring = F
self.characteristic = F.characteristic() self.characteristic = F.characteristic()
self.fct_field = RxyzQ, Rxyz, x, y, z self.fct_field = Fxy, Rxy, x, y
r = Rx(f).degree() r = Rx(f).degree()
delta = GCD(r, m) delta = GCD(r, m)
self.nb_of_pts_at_infty = delta self.nb_of_pts_at_infty = delta
@ -27,19 +27,6 @@ class superelliptic:
F = self.base_ring F = self.base_ring
return 'Superelliptic curve with the equation y^' + str(m) + ' = ' + str(f)+' over ' + str(F) return 'Superelliptic curve with the equation y^' + str(m) + ' = ' + str(f)+' over ' + str(F)
def coordinates2(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()
RxyzQ, Rxyz, x, y, z = 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 for omega in basis]
self_with_no_denominator = denom*self
return linear_representation_polynomials(Rxyz(self_with_no_denominator.form), [Rxyz(omega.form) for omega in basis])
#Auxilliary algorithm that returns the basis of holomorphic differentials #Auxilliary algorithm that returns the basis of holomorphic differentials
#of the curve and (as a second argument) the list of pairs (i, j) #of the curve and (as a second argument) the list of pairs (i, j)
#such that x^i dx/y^j is holomorphic. #such that x^i dx/y^j is holomorphic.
@ -164,7 +151,7 @@ class superelliptic:
for i in range(0, len(basis)): for i in range(0, len(basis)):
w = basis[i] w = basis[i]
v = w.cartier().coordinates() v = w.cartier().coordinates()
M[i, :] = v M[:, i] = vector(v)
return M return M
def frobenius_matrix(self, prec=20): def frobenius_matrix(self, prec=20):
@ -177,11 +164,18 @@ class superelliptic:
M = M.transpose() M = M.transpose()
return M return M
# def p_rank(self): def p_rank(self):
# return self.cartier_matrix().rank() if self.exponent != 2:
raise ValueError('No implemented yet.')
f = self.polynomial()
F = self.base_ring
Rt.<t> = PolynomialRing(F)
f = Rt(f)
H = HyperellipticCurve(f, 0)
return H.p_rank()
def a_number(self): def a_number(self):
g = C.genus() g = self.genus()
return g - self.cartier_matrix().rank() return g - self.cartier_matrix().rank()
def final_type(self, test = 0): def final_type(self, test = 0):

View File

@ -33,6 +33,8 @@ class superelliptic_form:
return superelliptic_form(C, constant*omega) return superelliptic_form(C, constant*omega)
def cartier(self): 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 C = self.curve
m = C.exponent m = C.exponent
p = C.characteristic p = C.characteristic
@ -46,15 +48,19 @@ class superelliptic_form:
mult_order = Integers(m)(p).multiplicative_order() mult_order = Integers(m)(p).multiplicative_order()
M = Integer((p^(mult_order)-1)/m) M = Integer((p^(mult_order)-1)/m)
for j in range(1, m): for j in range(0, m):
fct_j = self.jth_component(j) fct_j = self.jth_component(j)
h = Rx(fct_j*f^(M*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 j1 = (p^(mult_order-1)*j)%m
B = floor(p^(mult_order-1)*j/m) B = floor(p^(mult_order-1)*j/m)
result += superelliptic_form(C, polynomial_part(p, h)/(f^B*y^(j1))) result += superelliptic_form(C, polynomial_part(p, h)/(f^B*y^(j1)*h_denom))
return result return result
def serre_duality_pairing(self, fct, prec=20): 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 result = 0
C = self.curve C = self.curve
delta = C.nb_of_pts_at_infty delta = C.nb_of_pts_at_infty
@ -62,31 +68,21 @@ class superelliptic_form:
result += (fct*self).expansion_at_infty(place=i, prec=prec)[-1] result += (fct*self).expansion_at_infty(place=i, prec=prec)[-1]
return -result return -result
def coordinates(self): 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 C = self.curve
F = C.base_ring if basis == 0:
m = C.exponent
Rx.<x> = PolynomialRing(F)
Fx = FractionField(Rx)
FxRy.<y> = PolynomialRing(Fx)
g = C.genus()
degrees_holo = C.degrees_holomorphic_differentials()
degrees_holo_inv = {b:a for a, b in degrees_holo.items()}
basis = C.holomorphic_differentials_basis() basis = C.holomorphic_differentials_basis()
Fxy, Rxy, x, y = C.fct_field
for j in range(1, m): # We need to have only polynomials to use monomial_coefficients in linear_representation_polynomials,
omega_j = Fx(self.jth_component(j)) # and sometimes basis elements have denominators. Thus we multiply by them.
if omega_j != Fx(0): denom = LCM([denominator(omega.form) for omega in basis])
d = degree_of_rational_fctn(omega_j, F) basis = [denom*omega.form for omega in basis]
index = degrees_holo_inv[(d, j)] self_with_no_denominator = denom*self.form
a = coeff_of_rational_fctn(omega_j, F) return linear_representation_polynomials(Rxy(self_with_no_denominator), [Rxy(omega) for omega in basis])
a1 = coeff_of_rational_fctn(basis[index].jth_component(j), F)
elt = self - (a/a1)*basis[index]
return elt.coordinates() + a/a1*vector([F(i == index) for i in range(0, g)])
return vector(g*[0])
def jth_component(self, j): def jth_component(self, j):
'''If self = sum_j h_j(x)/y^j dx, output is h_j(x).'''
g = self.form g = self.form
C = self.curve C = self.curve
F = C.base_ring F = C.base_ring

View File

@ -1,6 +1,6 @@
#Class of rational functions on a superelliptic curve C. g = g(x, y) is a polynomial
#defining the function.
class superelliptic_function: class superelliptic_function:
'''Class of rational functions on a superelliptic curve C. g = g(x, y) is a polynomial
defining the function.'''
def __init__(self, C, g): def __init__(self, C, g):
F = C.base_ring F = C.base_ring
Rxy.<x, y> = PolynomialRing(F, 2) Rxy.<x, y> = PolynomialRing(F, 2)
@ -13,6 +13,11 @@ class superelliptic_function:
g = reduction(C, g) g = reduction(C, g)
self.function = g self.function = g
def __eq__(self, other):
if self.function == other.function:
return True
return False
def __repr__(self): def __repr__(self):
return str(self.function) return str(self.function)
@ -83,11 +88,11 @@ class superelliptic_function:
B = g.derivative(y)*f.derivative(x)/(m*y^(m-1)) B = g.derivative(y)*f.derivative(x)/(m*y^(m-1))
return superelliptic_form(C, A+B) return superelliptic_form(C, A+B)
def coordinates(self, basis = 0, basis_holo = 0, prec=20): def coordinates(self, basis = 0, basis_holo = 0, prec=50):
'''Find coordinates in H1(X, OX) in given basis basis with dual basis basis_holo.''' '''Find coordinates in H1(X, OX) in given basis basis with dual basis basis_holo.'''
C = self.curve C = self.curve
if basis == 0: if basis == 0:
basis = basis_of_cohomology(C) basis = C.basis_of_cohomology()
if basis_holo == 0: if basis_holo == 0:
basis_holo = C.holomorphic_differentials_basis() basis_holo = C.holomorphic_differentials_basis()
g = C.genus() g = C.genus()
@ -96,7 +101,7 @@ class superelliptic_function:
coordinates[i] = omega.serre_duality_pairing(self, prec=prec) coordinates[i] = omega.serre_duality_pairing(self, prec=prec)
return coordinates return coordinates
def expansion_at_infty(self, place = 0, prec=10): def expansion_at_infty(self, place = 0, prec=20):
C = self.curve C = self.curve
f = C.polynomial f = C.polynomial
m = C.exponent m = C.exponent
@ -125,3 +130,15 @@ class superelliptic_function:
xx = Rt(1/(t^M*ww^b)) xx = Rt(1/(t^M*ww^b))
yy = 1/(t^R*ww^a) yy = 1/(t^R*ww^a)
return Rt(fct(x = Rt(xx), y = Rt(yy))) return Rt(fct(x = Rt(xx), y = Rt(yy)))
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)

View File

@ -1,7 +1,16 @@
load('init.sage')
#print("superelliptic form coordinates test:")
#load('superelliptic/tests/form_coordinates_test.sage')
#print("p-th root test:")
#load('superelliptic/tests/pth_root_test.sage')
#print("not working! superelliptic p rank test:")
#load('superelliptic/tests/p_rank_test.sage')
print("a-number test:")
load('superelliptic/tests/a_number_test.sage')
#print("as_cover_test:") #print("as_cover_test:")
#load('as_covers/tests/as_cover_test.sage') #load('as_covers/tests/as_cover_test.sage')
#print("group_action_matrices_test:") #print("group_action_matrices_test:")
load('as_covers/tests/group_action_matrices_test.sage') #load('as_covers/tests/group_action_matrices_test.sage')
#print("dual_element_test:") #print("dual_element_test:")
#load('as_covers/tests/dual_element_test.sage') #load('as_covers/tests/dual_element_test.sage')
#print("ith_component_test:") #print("ith_component_test:")
@ -14,3 +23,5 @@ load('as_covers/tests/group_action_matrices_test.sage')
#load('as_covers/tests/ramification_jumps_test.sage') #load('as_covers/tests/ramification_jumps_test.sage')
#print("diffn_test:") #print("diffn_test:")
#load('as_covers/tests/diffn_test.sage') #load('as_covers/tests/diffn_test.sage')
#print("Cartier test:")
#load('as_covers/tests/cartier_test.sage')