DeRhamComputation/as_covers/as_cover_class.sage

470 lines
19 KiB
Python
Raw Normal View History

2022-11-18 15:00:34 +01:00
class as_cover:
2024-06-10 21:50:09 +02:00
def __init__(self, C, cover_template, list_of_fcts, branch_points = [], prec = 10):
2022-11-18 15:00:34 +01:00
self.quotient = C
self.cover_template = cover_template
2022-11-18 15:00:34 +01:00
self.functions = list_of_fcts
2024-06-10 21:50:09 +02:00
print('a')
2022-11-18 15:00:34 +01:00
self.height = len(list_of_fcts)
2024-06-10 21:50:09 +02:00
print('b')
2022-11-18 15:00:34 +01:00
F = C.base_ring
self.base_ring = F
p = C.characteristic
self.characteristic = p
self.prec = prec
#group acting
2024-06-10 21:50:09 +02:00
self.height = cover_template.height
self.group = cover_template.group
#########
2022-11-18 15:00:34 +01:00
f = C.polynomial
m = C.exponent
r = f.degree()
delta = GCD(m, r)
self.nb_of_pts_at_infty = delta
self.branch_points = list(range(delta)) + branch_points
2022-11-18 15:00:34 +01:00
Rxy.<x, y> = PolynomialRing(F, 2)
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
2024-06-10 21:50:09 +02:00
Rzf, zgen, fgen = cover_template.fct_field
all_x_series = {}
all_y_series = {}
all_z_series = {}
all_dx_series = {}
all_jumps = {}
2022-11-18 15:00:34 +01:00
for pt in self.branch_points:
x_series = superelliptic_function(C, x).expansion(pt=pt, prec=prec)
y_series = superelliptic_function(C, y).expansion(pt=pt, prec=prec)
2022-11-18 15:00:34 +01:00
z_series = []
jumps = []
n = len(list_of_fcts)
list_of_power_series = [g.expansion(pt=pt, prec=prec) for g in list_of_fcts]
for j in range(n):
2024-06-10 21:50:09 +02:00
####
#TUTAJ WSTAWIĆ ZMIANĘ
print(cover_template.fcts[j], {zgen[i] : z_series[i] for i in range(j)} | {zgen[i] : 0 for i in range(j, n)} | {fgen[i] : list_of_power_series[i] for i in range(n)})
power_series = Rzf(cover_template.fcts[j]).subs({zgen[i] : z_series[i] for i in range(j)} | {zgen[i] : 0 for i in range(j, n)} | {fgen[i] : list_of_power_series[i] for i in range(n)})
####
#power_series = list_of_power_series[j]
2022-11-18 15:00:34 +01:00
jump, correction, t_old, z = artin_schreier_transform(power_series, prec = prec)
x_series = x_series(t = t_old)
y_series = y_series(t = t_old)
z_series = [zi(t = t_old) for zi in z_series]
z_series += [z]
jumps += [jump]
list_of_power_series = [g(t = t_old) for g in list_of_power_series]
all_jumps[pt] = jumps
all_x_series[pt] = x_series
all_y_series[pt] = y_series
all_z_series[pt] = z_series
all_dx_series[pt] = x_series.derivative()
2022-11-18 15:00:34 +01:00
self.jumps = all_jumps
self.x_series = all_x_series
self.y_series = all_y_series
self.z_series = all_z_series
self.dx_series = all_dx_series
2022-12-19 14:37:14 +01:00
##############
#Function field
variable_names = 'x, y'
for i in range(n):
variable_names += ', z' + str(i)
Rxyz = PolynomialRing(F, n+2, variable_names)
x, y = Rxyz.gens()[:2]
z = Rxyz.gens()[2:]
RxyzQ = FractionField(Rxyz)
self.fct_field = (RxyzQ, Rxyz, x, y, z)
self.x = as_function(self, x)
self.y = as_function(self, y)
self.z = [as_function(self, z[j]) for j in range(n)]
self.dx = as_form(self, 1)
self.one = as_function(self, 1)
Rzf, zgen, fgen = cover_template.fct_field
subs_fs = {zgen[i] : z[i]}| {fgen[i] : RxyzQ(list_of_fcts[i].function) for i in range(n)}
self.rhs = [RxyzQ(cover_template.fcts[i].subs(subs_fs)) for i in range(n)]
#####
##### We compute now the differentials dz[i]
y_super = superelliptic_function(C, y)
dy_super = y_super.diffn().form
dz = []
for i in range(n):
aux_fct = self.rhs[i]
result = 0
for j in range(i):
result += aux_fct.derivative(z[j])*dz[j]
result += aux_fct.derivative(x)
result += aux_fct.derivative(y)*dy_super
dz += [-result]
self.dz = dz
2022-11-18 15:00:34 +01:00
def __repr__(self):
n = self.height
p = self.characteristic
result = str(self.group)
result += "-cover of " + str(self.quotient)+" with the equations: \n"
2022-11-18 15:00:34 +01:00
for i in range(n):
result += 'z'+str(i)+'^p - z'+str(i) + ' = '
aux = str(self.cover_template.fcts[i])
for t in range(n):
aux = aux.replace("f"+str(t), "(" + str(self.functions[t]) + ")")
result += aux + '\n'
2022-11-18 15:00:34 +01:00
return result
def genus(self):
jumps = self.jumps
gY = self.quotient.genus()
n = self.height
branch_pts = self.branch_points
2022-11-18 15:00:34 +01:00
p = self.characteristic
return p^n*gY + (p^n - 1)*(len(branch_pts) - 1) + sum(p^(n-j-1)*(jumps[pt][j]-1)*(p-1)/2 for j in range(n) for pt in branch_pts)
2022-11-18 15:00:34 +01:00
2023-02-23 12:26:25 +01:00
def exponent_of_different(self, place = 0):
2022-11-18 15:00:34 +01:00
jumps = self.jumps
n = self.height
delta = self.nb_of_pts_at_infty
p = self.characteristic
2023-02-23 12:26:25 +01:00
return sum(p^(n-j-1)*(jumps[place][j]+1)*(p-1) for j in range(n))
2022-11-18 15:00:34 +01:00
2023-02-23 12:26:25 +01:00
def exponent_of_different_prim(self, place = 0):
2022-11-18 15:00:34 +01:00
jumps = self.jumps
n = self.height
delta = self.nb_of_pts_at_infty
p = self.characteristic
2023-02-23 12:26:25 +01:00
return sum(p^(n-j-1)*(jumps[place][j])*(p-1) for j in range(n))
2022-11-18 15:00:34 +01:00
def holomorphic_differentials_basis(self, threshold = 8):
from itertools import product
x_series = self.x_series
y_series = self.y_series
z_series = self.z_series
dx_series = self.dx_series
2022-11-18 15:00:34 +01:00
delta = self.nb_of_pts_at_infty
p = self.characteristic
n = self.height
prec = self.prec
C = self.quotient
F = self.base_ring
m = C.exponent
r = C.polynomial.degree()
2022-12-19 14:37:14 +01:00
RxyzQ, Rxyz, x, y, z = self.fct_field
2022-11-18 15:00:34 +01:00
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
#Tworzymy zbiór S form z^i x^j y^k dx/y o waluacji >= waluacja z^(p-1)*dx/y
S = []
pr = [list(GF(p)) for _ in range(n)]
for i in range(0, threshold*r):
for j in range(0, m):
for k in product(*pr):
eta = as_form(self, x^i * prod(z[i1]^(k[i1]) for i1 in range(n))/y^j)
eta_exp = eta.expansion(pt=self.branch_points[0])
2022-11-18 15:00:34 +01:00
S += [(eta, eta_exp)]
forms = holomorphic_combinations(S)
2022-11-18 15:00:34 +01:00
for pt in self.branch_points[1:]:
forms = [(omega, omega.expansion(pt=pt)) for omega in forms]
forms = holomorphic_combinations(forms)
2022-11-18 15:00:34 +01:00
if len(forms) < self.genus():
print("I haven't found all forms, only ", len(forms), " of ", self.genus())
2022-11-18 15:00:34 +01:00
return holomorphic_differentials_basis(self, threshold = threshold + 1)
if len(forms) > self.genus():
2023-09-23 15:33:58 +02:00
raise ValueError("Increase precision.")
2022-11-18 15:00:34 +01:00
return forms
2023-02-23 12:26:25 +01:00
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
2022-11-18 15:00:34 +01:00
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.
If you suspect that you haven't found all the functions, you may increase it."""
from itertools import product
x_series = self.x_series
y_series = self.y_series
z_series = self.z_series
2022-11-18 15:00:34 +01:00
delta = self.nb_of_pts_at_infty
p = self.characteristic
n = self.height
prec = self.prec
C = self.quotient
F = self.base_ring
m = C.exponent
r = C.polynomial.degree()
2022-12-19 14:37:14 +01:00
RxyzQ, Rxyz, x, y, z = self.fct_field
2023-09-22 08:45:48 +02:00
F = C.base_ring
2022-11-18 15:00:34 +01:00
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
#Tworzymy zbiór S form z^i x^j y^k dx/y o waluacji >= waluacja z^(p-1)*dx/y
S = []
RQxyz = FractionField(Rxyz)
pr = [list(GF(p)) for _ in range(n)]
for i in range(0, threshold*r):
for j in range(0, m):
for k in product(*pr):
eta = as_function(self, x^i * prod(z[i1]^(k[i1]) for i1 in range(n))*y^j)
eta_exp = eta.expansion_at_infty()
S += [(eta, eta_exp)]
forms = holomorphic_combinations_fcts(S, pole_order)
for i in range(1, delta):
2023-02-23 12:26:25 +01:00
forms = [(omega, omega.expansion_at_infty(place = i)) for omega in forms]
2022-11-18 15:00:34 +01:00
forms = holomorphic_combinations_fcts(forms, pole_order)
return forms
def magical_element(self, threshold = 8):
list_of_elts = self.at_most_poles(self.exponent_of_different_prim(), threshold)
result = []
for a in list_of_elts:
if a.trace().function != 0:
result += [a]
return result
def pseudo_magical_element(self, threshold = 8):
list_of_elts = self.at_most_poles(self.exponent_of_different(), threshold)
result = []
for a in list_of_elts:
if a.trace().function != 0:
result += [a]
return result
def at_most_poles_forms(self, pole_order, threshold = 8):
"""Find forms with pole order in all the points at infty equat at most to pole_order. Threshold gives a bound on powers of x in the form.
If you suspect that you haven't found all the functions, you may increase it."""
from itertools import product
x_series = self.x_series
y_series = self.y_series
z_series = self.z_series
2022-11-18 15:00:34 +01:00
delta = self.nb_of_pts_at_infty
p = self.characteristic
n = self.height
prec = self.prec
C = self.quotient
F = self.base_ring
m = C.exponent
r = C.polynomial.degree()
2022-12-19 14:37:14 +01:00
RxyzQ, Rxyz, x, y, z = self.fct_field
2022-11-18 15:00:34 +01:00
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
#Tworzymy zbiór S form z^i x^j y^k dx/y o waluacji >= waluacja z^(p-1)*dx/y
S = []
RQxyz = FractionField(Rxyz)
pr = [list(GF(p)) for _ in range(n)]
for i in range(0, threshold*r):
for j in range(0, m):
for k in product(*pr):
eta = as_form(self, x^i * prod(z[i1]^(k[i1]) for i1 in range(n))/y^j)
eta_exp = eta.expansion_at_infty()
S += [(eta, eta_exp)]
forms = holomorphic_combinations_forms(S, pole_order)
for pt in self.branch_points[1:]:
forms = [(omega, omega.expansion(pt=pt)) for omega in forms]
2022-11-18 15:00:34 +01:00
forms = holomorphic_combinations_forms(forms, pole_order)
return forms
2023-02-23 12:26:25 +01:00
def uniformizer(self, place = 0):
'''Return uniformizer of curve self at place-th place at infinity.'''
p = self.characteristic
n = self.height
2022-12-19 14:37:14 +01:00
F = self.base_ring
RxyzQ, Rxyz, x, y, z = self.fct_field
fx = as_function(self, x)
z = [as_function(self, zi) for zi in z]
# We create a list of functions. We add there all variables...
list_of_fcts = [fx]+z
2023-02-23 12:26:25 +01:00
vfx = fx.valuation(place)
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.
for j1 in range(n):
for j2 in range(n):
if j1>j2:
a = gcd(vz[j1] , vz[j2])
vz1 = vz[j1]/a
vz2 = vz[j2]/a
2022-12-19 14:37:14 +01:00
for b in F:
2023-02-23 12:26:25 +01:00
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)]
for j1 in range(n):
a = gcd(vz[j1], vfx)
vzj = vz[j1] /a
vfx = vfx/a
2022-12-19 14:37:14 +01:00
for b in F:
2023-02-23 12:26:25 +01:00
if (fx^(vzj) - b*z[j1]^(vfx)).valuation(place) > (z[j1]^(vfx)).valuation(place):
list_of_fcts += [fx^(vzj) - b*z[j1]^(vfx)]
#Finally, we check if on the list there are two elements with the same valuation.
for f1 in list_of_fcts:
for f2 in list_of_fcts:
2023-02-23 12:26:25 +01:00
d, a, b = xgcd(f1.valuation(place), f2.valuation(place))
if d == 1:
return f1^a*f2^b
raise ValueError("My method of generating fcts with relatively prime valuation failed.")
2022-11-18 15:00:34 +01:00
def ith_ramification_gp(self, i, place = 0):
'''Find ith ramification group at place at infty of nb place.'''
G = self.group.elts
t = self.uniformizer(place)
Gi = [G[0]]
for g in G:
if g != G[0]:
tg = t.group_action(g)
v = (tg - t).valuation(place)
if v >= i+1:
Gi += [g]
return Gi
def ramification_jumps(self, place = 0):
'''Return list of lower ramification jumps at at place at infty of nb place.'''
G = self.group.elts
ramification_jps = []
i = 0
while len(G) > 1:
Gi = self.ith_ramification_gp(i+1, place)
if len(Gi) < len(G):
ramification_jps += [i]
G = Gi
i+=1
return ramification_jps
2023-02-23 12:26:25 +01:00
def a_number(self):
g = self.genus()
return g - self.cartier_matrix().rank()
2022-12-19 14:37:14 +01:00
def cohomology_of_structure_sheaf_basis(self, holo_basis = 0, threshold = 8):
if holo_basis == 0:
holo_basis = self.holomorphic_differentials_basis(threshold = threshold)
2022-12-19 14:37:14 +01:00
from itertools import product
x_series = self.x_series
y_series = self.y_series
z_series = self.z_series
2022-12-19 14:37:14 +01:00
delta = self.nb_of_pts_at_infty
p = self.characteristic
n = self.height
prec = self.prec
C = self.quotient
F = self.base_ring
m = C.exponent
r = C.polynomial.degree()
RxyzQ, Rxyz, x, y, z = self.fct_field
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
#Tworzymy zbiór S form z^i x^j y^k dx/y o waluacji >= waluacja z^(p-1)*dx/y
result_fcts = []
V = VectorSpace(F,self.genus())
S = V.subspace([])
RQxyz = FractionField(Rxyz)
pr = [list(GF(p)) for _ in range(n)]
i = 0
while len(result_fcts) < self.genus():
for j in range(0, m):
for k in product(*pr):
f = as_function(self, prod(z[i1]^(k[i1]) for i1 in range(n))/x^i*y^j)
f_products = [omega.serre_duality_pairing(f) for omega in holo_basis]
2022-12-19 14:37:14 +01:00
if vector(f_products) not in S:
S = S+V.subspace([V(f_products)])
result_fcts += [f]
i += 1
return result_fcts
2022-12-19 15:19:50 +01:00
def lift_to_de_rham(self, fct, threshold = 30):
2022-12-19 15:19:50 +01:00
'''Given function fct, find form eta regular on affine part such that eta - d(fct) is regular in infty. (Works for one place at infty now)'''
from itertools import product
x_series = self.x_series
y_series = self.y_series
z_series = self.z_series
dx_series = self.dx_series
delta = self.nb_of_pts_at_infty
p = self.characteristic
n = self.height
prec = self.prec
C = self.quotient
F = self.base_ring
2022-12-19 15:19:50 +01:00
m = C.exponent
r = C.polynomial.degree()
RxyzQ, Rxyz, x, y, z = self.fct_field
2022-12-19 15:19:50 +01:00
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
#Tworzymy zbiór S form z^i x^j y^k dx/y o waluacji >= waluacja z^(p-1)*dx/y
S = [(fct.diffn(), fct.diffn().expansion_at_infty())]
pr = [list(GF(p)) for _ in range(n)]
2023-09-22 08:45:48 +02:00
holo = self.holomorphic_differentials_basis(threshold = threshold)
2022-12-19 15:19:50 +01:00
for i in range(0, threshold*r):
for j in range(0, m):
for k in product(*pr):
2024-01-10 18:05:29 +01:00
eta = as_form(self, x^i*prod(z[i1]^(k[i1]) for i1 in range(n))/y^j)
2022-12-19 15:19:50 +01:00
eta_exp = eta.expansion_at_infty()
S += [(eta, eta_exp)]
forms = holomorphic_combinations(S)
if len(forms) <= self.genus():
raise ValueError("Increase threshold!")
2022-12-19 15:19:50 +01:00
for omega in forms:
for a in F:
2024-01-10 18:05:29 +01:00
if (a*omega + fct.diffn()).is_regular_on_U0():
return a*omega + fct.diffn()
raise ValueError("Unknown.")
2024-06-10 19:55:49 +02:00
def lift_to_de_rham_form(self, eta, threshold = 20):
'''Given form eta regular on affine part find fct such that eta - d(fct) is regular in infty. (Works for one place at infty now)'''
from itertools import product
x_series = self.x_series
y_series = self.y_series
z_series = self.z_series
dx_series = self.dx_series
delta = self.nb_of_pts_at_infty
p = self.characteristic
n = self.height
prec = self.prec
C = self.quotient
F = self.base_ring
m = C.exponent
r = C.polynomial.degree()
RxyzQ, Rxyz, x, y, z = self.fct_field
Rt.<t> = LaurentSeriesRing(F, default_prec=prec)
#Tworzymy zbiór S form z^i x^j y^k dx/y o waluacji >= waluacja z^(p-1)*dx/y
S = [(eta, eta.expansion_at_infty())]
pr = [list(GF(p)) for _ in range(n)]
for i in range(0, threshold*r):
for j in range(0, m):
for k in product(*pr):
ff = as_function(self, prod(z[i1]^(k[i1]) for i1 in range(n))/x^i*y^j)
ff_exp = ff.diffn().expansion_at_infty()
if ff_exp != 0*ff_exp:
S += [(ff, ff_exp)]
for i in range(0, threshold*r):
for j in range(0, m):
for k in product(*pr):
ff = as_function(self, prod(z[i1]^(k[i1]) for i1 in range(n))*x^i*y^j)
ff_exp = ff.diffn().expansion_at_infty()
if ff_exp != 0*ff_exp:
S += [(ff, ff_exp)]
forms = holomorphic_combinations_mixed(S)
if len(forms) <= self.genus():
raise ValueError("Increase threshold!")
result = []
for ff in forms:
if ff[0] != 0*self.dx:
result += [as_cech(self, ff[0], -ff[1])]
return result
raise ValueError("Unknown.")
2022-12-19 15:19:50 +01:00
def de_rham_basis(self, holo_basis = 0, cohomology_basis = 0, threshold = 30):
if holo_basis == 0:
holo_basis = self.holomorphic_differentials_basis(threshold = threshold)
if cohomology_basis == 0:
cohomology_basis = self.cohomology_of_structure_sheaf_basis(holo_basis = holo_basis, threshold = threshold)
2022-12-19 15:19:50 +01:00
result = []
for omega in holo_basis:
result += [as_cech(self, omega, as_function(self, 0))]
for f in cohomology_basis:
omega = self.lift_to_de_rham(f, threshold = threshold)
result += [as_cech(self, omega, f)]
return result
2022-12-19 14:37:14 +01:00