2022-11-18 15:00:34 +01:00
|
|
|
class superelliptic_cech:
|
|
|
|
def __init__(self, C, omega, fct):
|
|
|
|
self.omega0 = omega
|
|
|
|
self.omega8 = omega - fct.diffn()
|
|
|
|
self.f = fct
|
|
|
|
self.curve = C
|
|
|
|
|
|
|
|
def __add__(self, other):
|
|
|
|
C = self.curve
|
|
|
|
return superelliptic_cech(C, self.omega0 + other.omega0, self.f + other.f)
|
|
|
|
|
|
|
|
def __sub__(self, other):
|
|
|
|
C = self.curve
|
|
|
|
return superelliptic_cech(C, self.omega0 - other.omega0, self.f - other.f)
|
|
|
|
|
|
|
|
def __rmul__(self, constant):
|
|
|
|
C = self.curve
|
|
|
|
w1 = self.omega0.form
|
|
|
|
f1 = self.f.function
|
|
|
|
w2 = superelliptic_form(C, constant*w1)
|
|
|
|
f2 = superelliptic_function(C, constant*f1)
|
|
|
|
return superelliptic_cech(C, w2, f2)
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return "(" + str(self.omega0) + ", " + str(self.f) + ", " + str(self.omega8) + ")"
|
|
|
|
|
|
|
|
def verschiebung(self):
|
|
|
|
C = self.curve
|
|
|
|
omega = self.omega0
|
|
|
|
F = C.base_ring
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
return superelliptic_cech(C, omega.cartier(), superelliptic_function(C, Rx(0)))
|
|
|
|
|
|
|
|
def frobenius(self):
|
|
|
|
C = self.curve
|
|
|
|
fct = self.f.function
|
|
|
|
p = C.characteristic
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
return superelliptic_cech(C, superelliptic_form(C, Rx(0)), superelliptic_function(C, fct^p))
|
|
|
|
|
|
|
|
def coordinates(self):
|
|
|
|
C = self.curve
|
|
|
|
F = C.base_ring
|
|
|
|
m = C.exponent
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
Fx = FractionField(Rx)
|
|
|
|
FxRy.<y> = PolynomialRing(Fx)
|
|
|
|
g = C.genus()
|
|
|
|
basis = C.de_rham_basis()
|
|
|
|
|
|
|
|
omega = self.omega0
|
|
|
|
fct = self.f
|
|
|
|
|
2023-03-23 18:45:28 +01:00
|
|
|
if fct.function == Rx(0) and omega.form == Rx(0):
|
|
|
|
return vector((2*g)*[0])
|
|
|
|
|
2022-11-18 15:00:34 +01:00
|
|
|
if fct.function == Rx(0) and omega.form != Rx(0):
|
2023-03-23 18:45:28 +01:00
|
|
|
result = list(omega.coordinates()) + g*[0]
|
|
|
|
result = vector([F(a) for a in result])
|
|
|
|
return result
|
|
|
|
|
|
|
|
coord = fct.coordinates()
|
|
|
|
coord = g*[0] + list(coord)
|
|
|
|
coord = vector([F(a) for a in coord])
|
|
|
|
aux = self
|
|
|
|
for i in range(g, 2*g):
|
|
|
|
aux -= coord[i]*basis[i]
|
|
|
|
aux_f = decomposition_g0_g8(aux.f)[0]
|
|
|
|
aux.omega0 -= aux_f.diffn()
|
|
|
|
aux.f = 0*C.x
|
|
|
|
aux.omega8 = aux.omega0
|
|
|
|
return coord + aux.coordinates()
|
2022-11-18 15:00:34 +01:00
|
|
|
|
|
|
|
def is_cocycle(self):
|
|
|
|
w0 = self.omega0
|
|
|
|
w8 = self.omega8
|
|
|
|
fct = self.f
|
|
|
|
if not w0.is_regular_on_U0() and not w8.is_regular_on_Uinfty():
|
|
|
|
return('w0 & w8')
|
|
|
|
if not w0.is_regular_on_U0():
|
|
|
|
return('w0')
|
|
|
|
if not w8.is_regular_on_Uinfty():
|
|
|
|
return('w8')
|
|
|
|
if w0.is_regular_on_U0() and w8.is_regular_on_Uinfty():
|
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
|
|
#Auxilliary. If f = f1/f2 is a rational function, return deg f_1 - deg f_2.
|
|
|
|
def degree_of_rational_fctn(f, F):
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
Fx = FractionField(Rx)
|
|
|
|
f = Fx(f)
|
|
|
|
f1 = f.numerator()
|
|
|
|
f2 = f.denominator()
|
|
|
|
d1 = f1.degree()
|
|
|
|
d2 = f2.degree()
|
|
|
|
return(d1 - d2)
|
|
|
|
|
|
|
|
#Auxilliary. If f = f1/f2 is a rational function, return (leading coeff of f1)/(leading coeff of f2).
|
|
|
|
def coeff_of_rational_fctn(f, F):
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
Fx = FractionField(Rx)
|
|
|
|
f = Fx(f)
|
|
|
|
if f == Rx(0):
|
|
|
|
return 0
|
|
|
|
f1 = f.numerator()
|
|
|
|
f2 = f.denominator()
|
|
|
|
d1 = f1.degree()
|
|
|
|
d2 = f2.degree()
|
|
|
|
a1 = f1.coefficients(sparse = false)[d1]
|
|
|
|
a2 = f2.coefficients(sparse = false)[d2]
|
|
|
|
return(a1/a2)
|
|
|
|
|
|
|
|
#Auxilliary. Given polynomial f(x) and integer d, return
|
|
|
|
#coefficient of x^d in f (and 0 is deg(f)<d).
|
|
|
|
def coff(f, d):
|
|
|
|
lista = f.coefficients(sparse = false)
|
|
|
|
if len(lista) <= d:
|
|
|
|
return 0
|
|
|
|
return lista[d]
|
|
|
|
|
|
|
|
#Auxilliary. Given polynomial f(x) = \sum_i a_i x^i and integer i, return
|
|
|
|
#only \sum_{j >= i+1} a_j x^{j - i -1}
|
|
|
|
def cut(f, i):
|
|
|
|
R = f.parent()
|
|
|
|
coeff = f.coefficients(sparse = false)
|
|
|
|
return sum(R(x^(j-i-1)) * coeff[j] for j in range(i+1, f.degree() + 1))
|
|
|
|
|
|
|
|
def polynomial_part(p, h):
|
2023-04-05 11:03:19 +02:00
|
|
|
F = base_ring(parent(h))
|
2022-11-18 15:00:34 +01:00
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
h = Rx(h)
|
|
|
|
result = Rx(0)
|
|
|
|
for i in range(0, h.degree()+1):
|
|
|
|
if (i%p) == p-1:
|
|
|
|
power = Integer((i-(p-1))/p)
|
2023-04-05 11:03:19 +02:00
|
|
|
result += F(h[i]) * x^(power)
|
2022-11-18 15:00:34 +01:00
|
|
|
return result
|
|
|
|
|
|
|
|
#Find delta-th root of unity in field F
|
|
|
|
def root_of_unity(F, delta):
|
|
|
|
Rx.<x> = PolynomialRing(F)
|
|
|
|
cyclotomic = x^(delta) - 1
|
|
|
|
for root, a in cyclotomic.roots():
|
|
|
|
powers = [root^d for d in delta.divisors() if d!= delta]
|
|
|
|
if 1 not in powers:
|
|
|
|
return root
|
|
|
|
|
|
|
|
def preimage(U, V, M): #preimage of subspace U under M
|
|
|
|
basis_preimage = M.right_kernel().basis()
|
|
|
|
imageU = U.intersection(M.transpose().image())
|
|
|
|
basis = imageU.basis()
|
|
|
|
for v in basis:
|
|
|
|
w = M.solve_right(v)
|
|
|
|
basis_preimage = basis_preimage + [w]
|
|
|
|
return V.subspace(basis_preimage)
|
|
|
|
|
|
|
|
def image(U, V, M):
|
|
|
|
basis = U.basis()
|
|
|
|
basis_image = []
|
|
|
|
for v in basis:
|
|
|
|
basis_image += [M*v]
|
|
|
|
return V.subspace(basis_image)
|
|
|
|
|
|
|
|
def flag(F, V, p, test = 0):
|
|
|
|
dim = F.dimensions()[0]
|
|
|
|
space = VectorSpace(GF(p), dim)
|
|
|
|
flag_subspaces = (dim+1)*[0]
|
|
|
|
flag_used = (dim+1)*[0]
|
|
|
|
final_type = (dim+1)*['?']
|
|
|
|
|
|
|
|
flag_subspaces[dim] = space
|
|
|
|
flag_used[dim] = 1
|
|
|
|
|
|
|
|
|
|
|
|
while 1 in flag_used:
|
|
|
|
index = flag_used.index(1)
|
|
|
|
flag_used[index] = 0
|
|
|
|
U = flag_subspaces[index]
|
|
|
|
U_im = image(U, space, V)
|
|
|
|
d_im = U_im.dimension()
|
|
|
|
final_type[index] = d_im
|
|
|
|
U_pre = preimage(U, space, F)
|
|
|
|
d_pre = U_pre.dimension()
|
|
|
|
|
|
|
|
if flag_subspaces[d_im] == 0:
|
|
|
|
flag_subspaces[d_im] = U_im
|
|
|
|
flag_used[d_im] = 1
|
|
|
|
|
|
|
|
if flag_subspaces[d_pre] == 0:
|
|
|
|
flag_subspaces[d_pre] = U_pre
|
|
|
|
flag_used[d_pre] = 1
|
|
|
|
|
|
|
|
if test == 1:
|
|
|
|
print('(', final_type, ')')
|
|
|
|
|
|
|
|
for i in range(0, dim+1):
|
|
|
|
if final_type[i] == '?' and final_type[dim - i] != '?':
|
|
|
|
i1 = dim - i
|
|
|
|
final_type[i] = final_type[i1] - i1 + dim/2
|
|
|
|
|
|
|
|
final_type[0] = 0
|
|
|
|
|
|
|
|
for i in range(1, dim+1):
|
|
|
|
if final_type[i] == '?':
|
|
|
|
prev = final_type[i-1]
|
|
|
|
if prev != '?' and prev in final_type[i+1:]:
|
|
|
|
final_type[i] = prev
|
|
|
|
|
|
|
|
for i in range(1, dim+1):
|
|
|
|
if final_type[i] == '?':
|
|
|
|
final_type[i] = min(final_type[i-1] + 1, dim/2)
|
|
|
|
|
|
|
|
if is_final(final_type, dim/2):
|
|
|
|
return final_type[1:dim/2 + 1]
|
|
|
|
print('error:', final_type[1:dim/2 + 1])
|
|
|
|
|
|
|
|
def is_final(final_type, dim):
|
|
|
|
n = len(final_type)
|
|
|
|
if final_type[0] != 0:
|
|
|
|
return 0
|
|
|
|
|
|
|
|
if final_type[n-1] != dim:
|
|
|
|
return 0
|
|
|
|
|
|
|
|
for i in range(1, n):
|
|
|
|
if final_type[i] != final_type[i - 1] and final_type[i] != final_type[i - 1] + 1:
|
|
|
|
return 0
|
|
|
|
return 1
|