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): F = C.base_ring Rxy. = PolynomialRing(F, 2) Fxy = FractionField(Rxy) f = C.polynomial r = f.degree() m = C.exponent self.curve = C g = reduction(C, g) self.function = g def __eq__(self, other): if self.function == other.function: return True return False def __repr__(self): return str(self.function) def jth_component(self, j): g = self.function C = self.curve F = C.base_ring Rx. = PolynomialRing(F) Fx. = FractionField(Rx) FxRy. = PolynomialRing(Fx) g = FxRy(g) return coff(g, j) def __add__(self, other): C = self.curve g1 = self.function g2 = other.function g = reduction(C, g1 + g2) return superelliptic_function(C, g) def __neg__(self): C = self.curve g = self.function return superelliptic_function(C, -g) def __sub__(self, other): C = self.curve g1 = self.function g2 = other.function g = reduction(C, g1 - g2) return superelliptic_function(C, g) def __mul__(self, other): C = self.curve try: g1 = self.function g2 = other.function g = reduction(C, g1 * g2) return superelliptic_function(C, g) except: g1 = self.function g2 = other.form g = reduction(C, g1 * g2) return superelliptic_form(C, g) def __rmul__(self, constant): C = self.curve g = self.function return superelliptic_function(C, constant*g) def __truediv__(self, other): C = self.curve g1 = self.function g2 = other.function g = reduction(C, g1 / g2) return superelliptic_function(C, g) def __pow__(self, exp): C = self.curve g = self.function return superelliptic_function(C, g^(exp)) def diffn(self): C = self.curve f = C.polynomial m = C.exponent F = C.base_ring g = self.function Rxy. = PolynomialRing(F, 2) Fxy = FractionField(Rxy) g = Fxy(g) A = g.derivative(x) B = g.derivative(y)*f.derivative(x)/(m*y^(m-1)) return superelliptic_form(C, A+B) 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.''' C = self.curve if basis == 0: basis = C.cohomology_of_structure_sheaf_basis() if basis_holo == 0: basis_holo = C.holomorphic_differentials_basis() g = C.genus() coordinates = g*[0] for i, omega in enumerate(basis_holo): coordinates[i] = -omega.serre_duality_pairing(self, prec=prec) return coordinates def expansion_at_infty(self, place = 0, prec=20): C = self.curve fct = self.function F = C.base_ring Rt. = LaurentSeriesRing(F, default_prec=prec) xx = C.x_series[place] yy = C.y_series[place] return Rt(fct(x = Rt(xx), y = Rt(yy))) def expansion(self, pt, prec = 50): '''Expansion in the completed ring of the point pt. If pt is an integer, it means the corresponding place at infinity.''' if pt in ZZ: return self.expansion_at_infty(place=pt, prec=prec) x0, y0 = pt[0], pt[1] C = self.curve f = C.polynomial F = C.base_ring m = C.exponent Rt. = LaurentSeriesRing(F, default_prec=prec) Rxy. = PolynomialRing(F, 2) Fxy = FractionField(Rxy) if y0 !=0 and f.derivative()(x0) != 0: y_series = f(x = t + x0).nth_root(m) return Rt(self.function(x = t + x0, y = y_series)) if f.derivative()(x0) == 0: # then x - x0 is a uniformizer y_series = Rt(f(x = t+x0).nth_root(m)) return Rt(self.function(x = t + x0, y = y_series)) if y0 == 0: #then y is a uniformizer f1 = f(x = x+x0) - y0 x_series = new_reverse(f1(x = t), prec = prec) x_series = x_series(t = t^m - y0) + x0 return self.function(x = x_series, y = t) 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)