From f37c3a4ede9281b6a22100a7e9a29ede8116c8ee Mon Sep 17 00:00:00 2001 From: jgarnek Date: Mon, 22 Jan 2024 16:10:03 +0000 Subject: [PATCH] as symmetric power basis --- as_covers/as_cover_class.sage | 8 +- as_covers/as_polyforms.sage | 142 ++++++++++++++++++++--- quaternion_covers/quaternion_covers.sage | 8 +- 3 files changed, 137 insertions(+), 21 deletions(-) diff --git a/as_covers/as_cover_class.sage b/as_covers/as_cover_class.sage index 07d47d3..20e05ea 100644 --- a/as_covers/as_cover_class.sage +++ b/as_covers/as_cover_class.sage @@ -135,11 +135,11 @@ class as_cover: eta_exp = eta.expansion(pt=self.branch_points[0]) S += [(eta, eta_exp)] - forms = holomorphic_combinations(S) + forms = as_holomorphic_combinations(S) for pt in self.branch_points[1:]: forms = [(omega, omega.expansion(pt=pt)) for omega in forms] - forms = holomorphic_combinations(forms) + forms = as_holomorphic_combinations(forms) if len(forms) < self.genus(): print("I haven't found all forms, only ", len(forms), " of ", self.genus()) @@ -376,7 +376,7 @@ class as_cover: eta = as_form(self, x^i*prod(z[i1]^(k[i1]) for i1 in range(n))/y^j) eta_exp = eta.expansion_at_infty() S += [(eta, eta_exp)] - forms = holomorphic_combinations(S) + forms = as_holomorphic_combinations(S) if len(forms) <= self.genus(): raise ValueError("Increase threshold!") for omega in forms: @@ -398,7 +398,7 @@ class as_cover: result += [as_cech(self, omega, f)] return result -def holomorphic_combinations(S): +def as_holomorphic_combinations(S): """Given a list S of pairs (form, corresponding Laurent series at some pt), find their combinations holomorphic at that pt.""" C_AS = S[0][0].curve p = C_AS.characteristic diff --git a/as_covers/as_polyforms.sage b/as_covers/as_polyforms.sage index e448bf7..c0d279b 100644 --- a/as_covers/as_polyforms.sage +++ b/as_covers/as_polyforms.sage @@ -8,7 +8,7 @@ class as_polyform: return as_polyform(self.form + other.form, self.mult) def __repr__(self): - return str(self.form) + ' dx⊗' + str(self.mult) + 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) @@ -30,39 +30,76 @@ class as_polyform: 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] + 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_canonical_ideal(AS, threshold=8): +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() - 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) + 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, g^2, r) + M = matrix(F, len(B1), r) for i in range(0, len(B1)): - (a, b) = B1[i] - c = as_function(AS, a.form*b.form) + 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, 2) + 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 = {b : 0 for b in B1} + coeffs = {tuple(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)] + 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 @@ -106,4 +143,83 @@ class as_tensor_product_forms: 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) \ No newline at end of file + 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:])) \ No newline at end of file diff --git a/quaternion_covers/quaternion_covers.sage b/quaternion_covers/quaternion_covers.sage index 427c5be..92535b7 100644 --- a/quaternion_covers/quaternion_covers.sage +++ b/quaternion_covers/quaternion_covers.sage @@ -137,11 +137,11 @@ class quaternion_cover: eta_exp = eta.expansion(pt=self.branch_points[0]) S += [(eta, eta_exp)] - forms = holomorphic_combinations(S) + forms = quaternion_holomorphic_combinations(S) for pt in self.branch_points[1:]: forms = [(omega, omega.expansion(pt=pt)) for omega in forms] - forms = holomorphic_combinations(forms) + forms = quaternion_holomorphic_combinations(forms) if len(forms) < self.genus(): print("I haven't found all forms, only ", len(forms), " of ", self.genus()) @@ -378,7 +378,7 @@ class quaternion_cover: eta = quaternion_form(self, x^i*prod(z[i1]^(k[i1]) for i1 in range(n))/y^j) eta_exp = eta.expansion_at_infty() S += [(eta, eta_exp)] - forms = holomorphic_combinations(S) + forms = quaternion_holomorphic_combinations(S) if len(forms) <= self.genus(): raise ValueError("Increase threshold!") for omega in forms: @@ -400,7 +400,7 @@ class quaternion_cover: result += [quaternion_cech(self, omega, f)] return result -def holomorphic_combinations(S): +def quaternion_holomorphic_combinations(S): """Given a list S of pairs (form, corresponding Laurent series at some pt), find their combinations holomorphic at that pt.""" C_AS = S[0][0].curve p = C_AS.characteristic