class as_polyform: def __init__(self, form, mult): self.form = form self.curve = form.curve self.mult = mult def __add__(self, other): return as_polyform(self.form + other.form, self.mult) def __repr__(self): return str(self.form) + ' dx⊗' + str(self.mult) def expansion_at_infty(self): return self.form.expansion_at_infty()*(self.curve.dx.expansion_at_infty())^(self.mult) def coordinates(self, basis = 0): """Find coordinates of the given holomorphic form self in terms of the basis forms in a list holo.""" AS = self.curve if basis == 0: basis = AS.holomorphic_differentials_basis() RxyzQ, Rxyz, x, y, z = AS.fct_field # We need to have only polynomials to use monomial_coefficients in linear_representation_polynomials, # and sometimes basis elements have denominators. Thus we multiply by them. denom = LCM([denominator(omega.form.function) for omega in basis]) basis = [denom*omega.form.function for omega in basis] self_with_no_denominator = denom*self.form.function return linear_representation_polynomials(Rxyz(self_with_no_denominator), [Rxyz(omega) for omega in basis]) def as_holo_polydifferentials_basis(AS, mult, threshold = 8): v = AS.dx.valuation() result = AS.at_most_poles(mult*v, threshold=threshold) return [as_polyform(omega, mult) for omega in result] as_cover.holo_polydifferentials_basis = as_holo_polydifferentials_basis def as_canonical_ideal(AS, threshold=8): B0 = AS.holomorphic_differentials_basis(threshold=threshold) F = AS.base_ring g = AS.genus() B1 = [(B0[i], B0[j]) for i in range(g) for j in range(g) if i <= j] B2 = AS.holo_polydifferentials_basis(2, threshold = threshold) g = AS.genus() r = len(B2) M = matrix(F, g^2, r) for i in range(0, len(B1)): (a, b) = B1[i] c = as_function(AS, a.form*b.form) c = as_reduction(AS, c) c = as_function(AS, c) c = as_polyform(c, 2) #return M, c.coordinates(basis=B2) M[i, :] = vector(c.coordinates(basis=B2)) K = M.kernel().basis() result = [] for v in K: coeffs = {b : 0 for b in B1} for i in range(r): if v[i] != 0: coeffs[B1[i]] += v[i] result += [as_tensor_product_forms(B1, coeffs)] return result as_cover.canonical_ideal = as_canonical_ideal class as_tensor_product_forms: def __init__(self, pairs_of_forms, coeffs): self.pairs = pairs_of_forms self.coeffs = coeffs #dictionary self.curve = pairs_of_forms[0][0].curve def coordinates(self, basis = 0): AS = self.curve g = AS.genus() F = AS.base_ring if basis == 0: basis = AS.holomorphic_differentials_basis() result = matrix(F, g, g) for (omega1, omega2) in self.pairs: c = omega1.coordinates(basis = basis) d = omega2.coordinates(basis = basis) for i in range(g): for j in range(g): result[i, j] += self.coeffs[(omega1, omega2)]*c[i]*d[j] return result def __repr__(self): result = '' for (omega1, omega2) in self.pairs: if self.coeffs[(omega1, omega2)] !=0: result += str(self.coeffs[(omega1, omega2)]) + ' * ' + str(omega1) + '⊗' + str(omega2) + ' + ' return result def polynomial(self): AS = self.curve F = AS.base_ring g = AS.genus() M = self.coordinates() Rg = PolynomialRing(F, 'X', g) X = Rg.gens() return sum(M[i, j] * X[i]*X[j] for i in range(g) for j in range(g)) def group_action(self, elt): p = self.base_ring.characteristic() n = self.height elt1 = [p^n - a for a in elt] pairs_of_forms2 = [(a.group_action(elt), b.group_action(elt1)) for (a, b) in pairs_of_forms] coeffs2 = {(a.group_action(elt), b.group_action(elt1)) : self.coeffs[(a, b)] for (a, b) in pairs_of_forms} return as_tensor_product_forms(pairs_of_forms2, self.coeffs)