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) result = [as_polyform(omega, mult) for omega in result] if mult == 1 and len(result) < AS.genus(): raise ValueError('Increase threshold, not all forms found.') if mult > 1 and len(result) < (2*mult - 1)*(AS.genus() - 1): raise ValueError('Increase threshold, not all forms found.') return result as_cover.holo_polydifferentials_basis = as_holo_polydifferentials_basis def as_symmetric_power_basis(AS, n, threshold = 8): g = AS.genus() B0 = AS.holomorphic_differentials_basis(threshold=threshold) from itertools import product indices = [list(range(g)) for i in range(n)] indices_nonrepeating = [] for i in product(*indices): if non_decreasing(i): indices_nonrepeating += [i] result = [] for i in indices_nonrepeating: tensor_form = [as_function(AS, B0[i[j]].form) for j in range(n)] tensor_form2 = [B0[i[j]] for j in range(n)] print(hash(tuple(tensor_form))) print([tensor_form], tuple(tensor_form)) aux_dict = {} aux_dict[tuple(list(tensor_form))] = 1 print(aux_dict) result += [as_symmetric_product_forms([tensor_form], aux_dict)] print(binomial(g + n - 1, n), len(result)) return result def as_canonical_ideal(AS, n, threshold=8): B0 = AS.holomorphic_differentials_basis(threshold=threshold) F = AS.base_ring g = AS.genus() RxyzQ, Rxyz, x, y, z = AS.fct_field from itertools import product #B1 = as_symmetric_power_basis(AS, n, threshold = 8) B1 = [[B0[i[j]] for j in range(n)] for i in product(*indices)] B2 = AS.holo_polydifferentials_basis(n, threshold = threshold) g = AS.genus() r = len(B2) M = matrix(F, len(B1), r) for i in range(0, len(B1)): atuple = B1[i] c = Rxyz(1) for a in atuple: c = c*a.form c = as_reduction(AS, c) c = as_function(AS, c) c = as_polyform(c, n) #return M, c.coordinates(basis=B2) M[i, :] = vector(c.coordinates(basis=B2)) K = M.kernel().basis() result = [] for v in K: coeffs = {tuple(b) : 0 for b in B1} for i in range(r): if v[i] != 0: coeffs[tuple(B1[i])] += v[i] result += [as_symmetric_product_forms(B1, coeffs)] return result as_cover.canonical_ideal = as_canonical_ideal def as_canonical_ideal_polynomials(AS, n, threshold=8): return [a.polynomial() for a in AS.canonical_ideal(n, threshold=threshold)] as_cover.canonical_ideal_polynomials = as_canonical_ideal_polynomials 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) class as_symmetric_product_forms: def __init__(self, tuples_of_forms, coeffs): self.n = len(tuples_of_forms[0]) self.tuples = tuples_of_forms self.coeffs = coeffs #dictionary self.curve = tuples_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() from itertools import product indices = [list(range(g)) for i in range(self.n)] result = {i : 0 for i in product(*indices)} for atuple in self.tuples: coors = [omega.coordinates(basis = basis) for omega in atuple] for i in product(*indices): aux_product = 1 for j in range(n): aux_product *= coors[j][i[j]] result[i] += self.coeffs[tuple(atuple)]*aux_product return result def __repr__(self): result = '' for atuple in self.tuples: if self.coeffs[tuple(atuple)] !=0: result += str(self.coeffs[tuple(atuple)]) + ' * ' for j in range(self.n): result += "(" + str(atuple[j]) + ")" if j != self.n-1: result + '⊗' result += ' + ' return result def multiply(self): n = self.n AS = self.curve RxyzQ, Rxyz, x, y, z = AS.fct_field result = as_polyform(0*AS.x, n) for atuple in self.tuples: aux_product = Rxyz(1) for fct in atuple: aux_product = aux_product * fct.form aux_product = as_function(AS, aux_product) result += as_polyform(self.coeffs[tuple(atuple)]*aux_product, n) return result def polynomial(self): AS = self.curve F = AS.base_ring g = AS.genus() M = self.coordinates() n = self.n Rg = PolynomialRing(F, 'X', g) X = Rg.gens() from itertools import product indices = [list(range(g)) for i in range(self.n)] result = Rg(0) for i in product(*indices): aux_product = Rg(1) for j in range(n): aux_product *= X[i[j]] result += M[i] * aux_product return result 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) def non_decreasing(L): return all(x<=y for x, y in zip(L, L[1:]))