DeRhamComputation/superelliptic_drw/superelliptic_witt.sage

189 lines
6.0 KiB
Python

class superelliptic_witt:
def __init__(self, t, f):
''' Define Witt function on C of the form [t] + V(f). '''
self.curve = t.curve
C = t.curve
p = C.characteristic
self.t = t #superelliptic_function
self.f = f #superelliptic_function
def __repr__(self):
f = self.f
t = self.t
if f.function == 0:
return "[" + str(t) + "]"
if t.function == 0:
return "V(" + str(f) + ")"
return "[" + str(t) + "] + V(" + str(f) + ")"
def __neg__(self):
f = self.f
t = self.t
return superelliptic_witt(-t, -f)
def __add__(self, other):
C = self.curve
second_coor = 0*C.x
X = self.t
Y = other.t
F = C.base_ring
p = F.characteristic()
for i in range(1, p):
second_coor -= binomial_prim(p, i)*X^i*Y^(p-i)
return superelliptic_witt(self.t + other.t, self.f + other.f + second_coor)
def __sub__(self, other):
return self + (-other)
def __rmul__(self, other):
p = self.curve.characteristic
if other in ZZ:
if other == 0:
return superelliptic_witt(0*C.x, 0*C.x)
if other > 0:
return self + (other-1)*self
if other < 0:
return (-other)*(-self)
if other in QQ:
other_integer = Integers(p^2)(other)
return other_integer*self
def __mul__(self, other):
C = self.curve
p = C.characteristic
if isinstance(other, superelliptic_witt):
t1 = self.t
f1 = self.f
t2 = other.t
f2 = other.f
return superelliptic_witt(t1*t2, t1^p*f2 + t2^p*f1)
if isinstance(other, superelliptic_drw_form):
h1 = other.h1
h2 = other.h2
omega = other.omega
t = self.t
f = self.f
aux_form = t^p*omega - h2*t^(p-1)*t.diffn() + f*h1^p*(C.x)^(p-1)*C.dx
return superelliptic_drw_form(t*h1, aux_form, t^p*h2)
def __eq__(self, other):
return self.t == other.t and self.f == other.f
def diffn(self, dy_w = 0):
if dy_w == 0:
dy_w = self.curve.dy_w()
C = self.curve
t = self.t
f = self.f
fC = C.polynomial
F = C.base_ring
Rxy.<x, y> = PolynomialRing(F, 2)
if t.function == 0:
return superelliptic_drw_form(0*C.x, 0*C.dx, f)
t_polynomial = t.function
num = t_polynomial.numerator()
den = t_polynomial.denominator()
num_t_fct = superelliptic_function(C, num)
den_t_fct = superelliptic_function(C, den)
inv_den_t_fct = superelliptic_function(C, 1/den)
if den != 1:
# d([N/D] + V(f)) = [1/D]*d([N]) - [N]*[D^(-2)]*d([D]) + dV(f)
return ((den_t_fct)^(-1)).teichmuller()*num_t_fct.teichmuller().diffn() - ((den_t_fct)^(-2)).teichmuller()*num_t_fct.teichmuller()*den_t_fct.teichmuller().diffn() + superelliptic_drw_form(0*C.x, 0*C.dx, f)
t_polynomial = Rxy(t_polynomial)
M = t_polynomial.monomials()[0]
a = t_polynomial.monomial_coefficient(M)
#[P] = [aM] + Q, where Q = ([P] - [aM])
aM_fct = superelliptic_function(C, a*M)
Q = self - aM_fct.teichmuller()
exp_x = M.exponents()[0][0]
exp_y = M.exponents()[0][1]
return Q.diffn() + exp_x*superelliptic_drw_form(aM_fct/C.x, 0*C.dx, 0*C.x) + exp_y*(aM_fct/C.y).teichmuller()*dy_w
def binomial_prim(p, i):
return binomial(p, i)/p
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
return superelliptic_witt(fct, 0*C.x)
superelliptic_function.teichmuller = teichmuller
#dy = [f(x)]'/2*y dx
#[f1 + M] = [f1] + [M] + V(cos)
#d[f1 + M] = d[f1] + d[M] + dV(f1*M)
#M = b x^a
#d[M] = a*[b x^(a-1)]
def auxilliary_derivative(P):
'''Return "derivative" of P, where P depends only on x. In other words d[P(x)].'''
P0 = P.t.function
P1 = P.f.function
C = P.curve
F = C.base_ring
Rx.<x> = PolynomialRing(F)
P0 = Rx(P0.numerator())
P1 = Rx(P1.numerator())
if P0 == 0:
return superelliptic_drw_form(0*C.x, 0*C.dx, P.f)
M = P0.monomials()[0]
a = P0.monomial_coefficient(M)
#[P] = [aM] + Q, where Q = ([P] - [aM])
aM_fct = superelliptic_function(C, a*M)
Q = P - aM_fct.teichmuller()
exp = M.exponents()[0]
return auxilliary_derivative(Q) + exp*superelliptic_drw_form(aM_fct/C.x, 0*C.dx, 0*C.x)
def mult_by_p(elt):
C = elt.curve
F = C.base_ring
p = F.characteristic()
if isinstance(elt, superelliptic_form):
fct = elt.form
Fxy, Rxy, x, y = C.fct_field
omega = superelliptic_form(C, fct^p * x^(p-1))
result = superelliptic_drw_form(0*C.x, elt, 0*C.x)
return result
if isinstance(elt, superelliptic_function):
return superelliptic_witt(0*C.x, elt^p)
if isinstance(elt, superelliptic_cech):
om0 = elt.omega0
f = elt.f
return superelliptic_drw_cech(mult_by_p(om0), mult_by_p(f))
def verschiebung(elt):
C = elt.curve
if isinstance(elt, superelliptic_function):
return superelliptic_witt(0*C.x, elt)
if isinstance(elt, superelliptic_form):
return superelliptic_drw_form(0*C.x, elt, 0*C.x)
superelliptic_form.verschiebung = verschiebung
superelliptic_function.verschiebung = verschiebung
def dy_w(C):
'''Return d[y].'''
fC = C.polynomial
fC = superelliptic_function(C, fC)
fC = fC.teichmuller()
dy_w = 1/2* ((C.y)^(-1)).teichmuller()*auxilliary_derivative(fC)
return dy_w
superelliptic.dy_w = dy_w