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. = 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. = 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. = 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