From a8e8dbbaa30b8d789d2f98101dd9ad0d8631aa9c Mon Sep 17 00:00:00 2001 From: jgarnek Date: Tue, 23 Jan 2024 18:53:29 +0000 Subject: [PATCH] canonical ideal for quaternion covers --- as_covers/as_polyforms.sage | 36 +++++++++-- as_covers/group_action_matrices.sage | 65 +++----------------- quaternion_covers/quaternion_form_class.sage | 31 ++++++++-- quaternion_covers/quaternion_reduction.sage | 2 +- 4 files changed, 63 insertions(+), 71 deletions(-) diff --git a/as_covers/as_polyforms.sage b/as_covers/as_polyforms.sage index bf1fb6a..27f34e7 100644 --- a/as_covers/as_polyforms.sage +++ b/as_covers/as_polyforms.sage @@ -91,8 +91,17 @@ class as_symmetric_product_forms: def __init__(self, forms_and_coeffs): '''Elements of forms_and_coeffs are of the form [coeff, form1, ..., formn]''' self.n = len(forms_and_coeffs[0]) - 1 - self.tuples = forms_and_coeffs - self.curve = forms_and_coeffs[0][1].curve + forms_and_coeffs1 = [] + for atuple in forms_and_coeffs: + if atuple[0] != 0 and atuple[1:] not in [a[1:] for a in forms_and_coeffs1]: + forms_and_coeffs1 += [atuple] + elif atuple[1:] in [a[1:] for a in forms_and_coeffs1]: + i = [a[1:] for a in forms_and_coeffs1].index(atuple[1:]) + forms_and_coeffs1[i][0] += atuple[0] + if len(forms_and_coeffs1) == 0: + forms_and_coeffs1 = [[0] + forms_and_coeffs[0][1:]] + self.tuples = forms_and_coeffs1 + self.curve = forms_and_coeffs1[0][1].curve def coordinates(self, basis = 0): AS = self.curve @@ -172,13 +181,28 @@ class as_symmetric_product_forms: return result def group_action(self, elt): - p = self.base_ring.characteristic() - n = self.height + p = self.curve.base_ring.characteristic() + n = self.curve.height aux_tuples = [] for atuple in self.tuples: - aux_tuple = atuple[0] + [a.group_action(elt) for a in atuple[1:]] + aux_tuple = [atuple[0]] + [a.group_action(elt) for a in atuple[1:]] aux_tuples += [aux_tuple] return as_symmetric_product_forms(aux_tuples) def non_decreasing(L): - return all(x<=y for x, y in zip(L, L[1:])) \ No newline at end of file + return all(x<=y for x, y in zip(L, L[1:])) + +def as_matrices_group_action_canonical_ideal(AS, mult, threshold = 8): + K = as_canonical_ideal(AS, mult, threshold = threshold) + n = AS.height + F = AS.base_ring + K_polynomials = [a.polynomial() for a in K] + r = len(K) + matrices = [] + for i in range(n): + M = matrix(F, r, r) + K_group_action_polynomials = [a.group_action([j == i for j in range(n)]).polynomial() for a in K] + for i in range(r): + M[i, :] = vector(linear_representation_polynomials(K_group_action_polynomials[i], K_polynomials)) + matrices += [M] + return matrices \ No newline at end of file diff --git a/as_covers/group_action_matrices.sage b/as_covers/group_action_matrices.sage index 3aad125..047743e 100644 --- a/as_covers/group_action_matrices.sage +++ b/as_covers/group_action_matrices.sage @@ -1,4 +1,4 @@ -def group_action_matrices(space, list_of_group_elements, basis): +def group_action_matrices(F, space, list_of_group_elements, basis): n = len(list_of_group_elements) d = len(space) A = [matrix(F, d, d) for i in range(n)] @@ -18,7 +18,8 @@ def group_action_matrices_holo(AS, basis=0, threshold=10): generators += [ei] if basis == 0: basis = AS.holomorphic_differentials_basis(threshold=threshold) - return group_action_matrices(basis, generators, basis = basis) + F = AS.base_ring + return group_action_matrices(F, basis, generators, basis = basis) def group_action_matrices_dR(AS, threshold=8): n = AS.height @@ -30,35 +31,9 @@ def group_action_matrices_dR(AS, threshold=8): holo_basis = AS.holomorphic_differentials_basis(threshold = threshold) str_basis = AS.cohomology_of_structure_sheaf_basis(holo_basis = holo_basis, threshold = threshold) dr_basis = AS.de_rham_basis(holo_basis = holo_basis, cohomology_basis = str_basis, threshold=threshold) + F = AS.base_ring basis = [holo_basis, str_basis, dr_basis] - return group_action_matrices(basis[2], generators, basis = basis) - -def group_action_matrices_old(C_AS): - F = C_AS.base_ring - n = C_AS.height - holo = C_AS.holomorphic_differentials_basis() - holo_forms = [omega.form for omega in holo] - denom = LCM([denominator(omega) for omega in holo_forms]) - variable_names = 'x, y' - for j in range(n): - variable_names += ', z' + str(j) - Rxyz = PolynomialRing(F, n+2, variable_names) - x, y = Rxyz.gens()[:2] - z = Rxyz.gens()[2:] - holo_forms = [Rxyz(omega*denom) for omega in holo_forms] - A = [[] for i in range(n)] - for omega in holo: - for i in range(n): - ei = n*[0] - ei[i] = 1 - omega1 = omega.group_action(ei) - omega1 = denom * omega1 - v1 = omega1.coordinates(holo_forms) - A[i] += [v1] - for i in range(n): - A[i] = matrix(F, A[i]) - A[i] = A[i].transpose() - return A + return group_action_matrices(F, basis[2], generators, basis = basis) def group_action_matrices_log(AS): n = AS.height @@ -67,31 +42,5 @@ def group_action_matrices_log(AS): ei = n*[0] ei[i] = 1 generators += [ei] - return group_action_matrices(AS.at_most_poles_forms(1), generators, basis = AS.at_most_poles_forms(1)) - -def group_action_matrices_log_old(C_AS): - F = C_AS.base_ring - n = C_AS.height - holo = C_AS.at_most_poles_forms(1) - holo_forms = [omega for omega in holo] - denom = LCM([denominator(omega) for omega in holo_forms]) - variable_names = 'x, y' - for j in range(n): - variable_names += ', z' + str(j) - Rxyz = PolynomialRing(F, n+2, variable_names) - x, y = Rxyz.gens()[:2] - z = Rxyz.gens()[2:] - holo_forms = [Rxyz(omega*denom) for omega in holo_forms] - A = [[] for i in range(n)] - for omega in holo: - for i in range(n): - ei = n*[0] - ei[i] = 1 - omega1 = omega.group_action(ei) - omega1 = denom * omega1 - v1 = omega1.coordinates(holo_forms) - A[i] += [v1] - for i in range(n): - A[i] = matrix(F, A[i]) - A[i] = A[i].transpose() - return A + F = AS.base_ring + return group_action_matrices(F, AS.at_most_poles_forms(1), generators, basis = AS.at_most_poles_forms(1)) \ No newline at end of file diff --git a/quaternion_covers/quaternion_form_class.sage b/quaternion_covers/quaternion_form_class.sage index 8badd01..270b6d4 100644 --- a/quaternion_covers/quaternion_form_class.sage +++ b/quaternion_covers/quaternion_form_class.sage @@ -81,13 +81,29 @@ class quaternion_form: omega = self.form return quaternion_form(C, constant*omega) - def group_action(self, ZN_tuple): - C = self.curve - n = C.height - RxyzQ, Rxyz, x, y, z = C.fct_field - sub_list = {x : x, y : y} | {z[j] : z[j]+ZN_tuple[j] for j in range(n)} + def group_action(self, elt): + Q8 = QuaternionGroup() + Qi, Qj = Q8.gens() + AS = self.curve + RxyzQ, Rxyz, x, y, z = AS.fct_field + if elt == Qi^4: + sub_list = {x : x, y : y} | {z[0] : z[0], z[1] : z[1], z[2]: z[2]} + if elt == Qi: + sub_list = {x : x, y : y} | {z[0] : z[0]+1, z[1] : z[1], z[2]: z[2] + z[0]} + if elt == Qj: + sub_list = {x : x, y : y} | {z[0] : z[0], z[1] : z[1] + 1, z[2]: z[2] + z[1] + z[0]} + if elt == Qi^2: + sub_list = {x : x, y : y} | {z[0] : z[0], z[1] : z[1], z[2]: z[2] + 1} + if elt == Qi * Qj: + sub_list = {x : x, y : y} | {z[0] : z[0] + 1, z[1] : z[1] + 1, z[2]: z[2] + z[1] + 1} + if elt == Qj * Qi: + sub_list = {x : x, y : y} | {z[0] : z[0] + 1, z[1] : z[1] + 1, z[2]: z[2] + z[1]} + if elt == Qi^3: + sub_list = {x : x, y : y} | {z[0] : z[0]+1, z[1] : z[1], z[2]: z[2] + z[0] + 1} + if elt == Qj^3: + sub_list = {x : x, y : y} | {z[0] : z[0], z[1] : z[1] + 1, z[2]: z[2] + z[1] + z[0] + 1} g = self.form - return quaternion_form(C, g.substitute(sub_list)) + return quaternion_form(AS, g.substitute(sub_list)) def coordinates(self, basis = 0): """Find coordinates of the given holomorphic form self in terms of the basis forms in a list holo.""" @@ -97,6 +113,9 @@ class quaternion_form: RxyzQ, Rxyz, x, y, z = C.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. + fct = quaternion_function(C, self.form) + fct = quaternion_reduction(C, fct) + self = quaternion_form(C, fct) denom = LCM([denominator(omega.form) for omega in basis]) basis = [denom*omega for omega in basis] self_with_no_denominator = denom*self diff --git a/quaternion_covers/quaternion_reduction.sage b/quaternion_covers/quaternion_reduction.sage index c71c893..7dfee8e 100644 --- a/quaternion_covers/quaternion_reduction.sage +++ b/quaternion_covers/quaternion_reduction.sage @@ -24,7 +24,7 @@ def quaternion_reduction(AS, fct): if d_div != n*[0]: change = 1 d_rem = [a.degree(z[i])%p for i in range(n)] - monomial = fct1.monomial_coefficient(a)*x^(a.degree(x))*y^(a.degree(y))*prod(z[i]^(d_rem[i]) for i in range(n))*prod((z[i] + ff[i])^(d_div[i]) for i in range(n)) + monomial = fct1.monomial_coefficient(a)*x^(a.degree(x))*y^(a.degree(y))*prod(z[i]^(d_rem[i]) for i in range(n))*prod((z[i] + ff[i])^(d_div[i]) for i in range(n-1))*(z[2] + ff[2] + z[0]*ff[0] + z[1] * (ff[0] + ff[1]))^(d_div[2]) result += RxyzQ(monomial) if change == 0: