diff --git a/README.md b/README.md index ca57b95..476a7e1 100644 --- a/README.md +++ b/README.md @@ -97,11 +97,10 @@ print(omega.expansion_at_infty(place=1)) One can check valuation of form/function at given place at infinity, using *valuation()* method. -## Abelian covers of superelliptic curves +## $p$-group covers of superelliptic curves -This module allows to define $(\mathbb Z/p)^n$\-covers of superelliptic curves in characteristic $p$ that -are **ramified over the points of infinity**. -We define now a $(\mathbb Z/3)^2$ cover of curve $C : y^2 = x^3 + x$, given by the equations $z_0^3 - z_0 = x^2 y$, +This module allows to define $p$\-group covers of superelliptic curves in characteristic $p$ that +are **ramified over the points of infinity**. For now the following $p$\-groups are possible: $\mathbb Z/p^n$, $(\mathbb Z/p)^n$, $E(p^3)$ \(the Heisenberg group mod $p$ of order $p^3$\), $Q_8$ \(the Heisenberg group $8$\). We define now a $(\mathbb Z/3)^2$ cover of curve $C : y^2 = x^3 + x$, given by the equations $z_0^3 - z_0 = x^2 y$, $z_1^3 - z_1 = x^3$. ``` @@ -112,10 +111,29 @@ C = superelliptic(f, 2) f1 = C.x^2*C.y f2 = C.x^3 -AS = as_cover(C, [f1, f2], prec=1000) +AS = elementary_cover([f1, f2], prec=1000) ``` -Note that defining abelian cover may take quite a long time, since several parameters are computed. Again *prec* parameter is optional +Similarly, one defines $\mathbb Z/p^n$, $E(p^3)$ and $Q_8$-covers: + +``` +sage: F = GF(3) +sage: Rx. = PolynomialRing(F) +sage: P1 = superelliptic(x, 1) +sage: AS = witt_cover([P1.x, P1.x^2], prec = 600) +sage: AS; + (Z/p^n)-cover of Superelliptic curve with the equation y^1 = x over Finite Field of size 3 with the equations: + z0^p - z0 = (x) + z1^p - z1 = -z0^7 + z0^5 + (x^2) +sage: AS = heisenberg_cover([P1.x^2, P1.x, P1.x], prec = 600) +sage: AS; + (E(p^3))-cover of Superelliptic curve with the equation y^1 = x over Finite Field of size 3 with the equations: +z0^p - z0 = (x^2) +z1^p - z1 = (x) +z2^p - z2 = z0*(x) - z1*(x) + (x) +``` + +Note that defining a cover may take quite a long time, since several parameters are computed. Again *prec* parameter is optional and is required to compute some parameters of the cover. Note that the functions f1, f2 **must be polynomials in x and y** so that AS has ramification points at infinity. @@ -125,6 +143,8 @@ Note that some functions \(e.g. _holomorphic\_differential\_basis_\) have option In order to compute the group action of $(\mathbb Z/p)^n$ on a given function/form/cocycle, use *group_action()*, e.g. ``` +G = AS.group() #p-group acting on curve +print(G.elts()) omega = AS.holomorphic_differentials_basis()[1] print(omega.group_action([1, 0])) #group action by element [1, 0] print(omega.group_action([0, 1])) #group action by element [0, 1] @@ -134,7 +154,15 @@ In order to compute the matrices of the action, use *group_action_matrices_holo* ``` p = 3 -A, B = group_action_matrices_holo(AS) +F = GF(3) +Rx. = PolynomialRing(F) +f = x^3 + x +C = superelliptic(f, 2) +f1 = C.x^2*C.y +f2 = C.x^3 +AS = elementary_cover([f1, f2], prec=1000) + +A, B = AS.group_action_matrices_holo() n = A.dimensions()[0] #Let us check that they commute and are of order p: print(A*B == B*A) diff --git a/as_covers/as_cover_class.sage b/as_covers/as_cover_class.sage index 8527468..2059c6e 100644 --- a/as_covers/as_cover_class.sage +++ b/as_covers/as_cover_class.sage @@ -337,17 +337,18 @@ class as_cover: def fiber(self, place = 0): 'Gives representatives for the quotient G/G_P for given place. Those are in bijection with the fiber.' - result = [(0, 0, 0)] + result = [AS.group.one] p = self.characteristic G = self.group H = self.stabilizer(place = place) for g in self.group.elts: - flag = 1 - for v in result: - if (G.elt(g)*(-G.elt(v))).as_tuple in H: - flag = 0 - if flag: - result += [g] + if g != AS.group.one: + flag = 1 + for v in result: + if (G.elt(g)*(-G.elt(v))).as_tuple in H: + flag = 0 + if flag: + result += [g] return result def ith_ramification_gp(self, i, place = 0, quasiuniformizer = 0, threshold = 20): @@ -622,16 +623,14 @@ class as_cover: for i in range(0, threshold*r): for j in range(0, m): for k in product(*pr): - eta = heisenberg_form(self, x^i * prod(z[i1]^(k[i1]) for i1 in range(n))/y^j) + 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_forms(S, pole_orders[(0, (0, 0, 0))]) - print('iteration') + forms = holomorphic_combinations_forms(S, pole_orders[(0, self.group.one)]) for i in range(delta): for g in self.fiber(place = i): if i!=0 or g != self.group.one: - print('iteration') forms = [(omega, omega.group_action(g).expansion_at_infty(place = i)) for omega in forms] forms = holomorphic_combinations_forms(forms, pole_orders[(i, g)]) return forms \ No newline at end of file diff --git a/as_covers/as_function_class.sage b/as_covers/as_function_class.sage index 18263cb..140f32c 100644 --- a/as_covers/as_function_class.sage +++ b/as_covers/as_function_class.sage @@ -132,15 +132,18 @@ class as_function: aux = as_reduction(self.curve, self.function) return as_function(self.curve, aux) - def trace(self, super=True): + def trace(self, super=True, subgp = 0): C = self.curve C_super = C.quotient n = C.height F = C.base_ring + if isinstance(subgp, Integer) or isinstance(subgp, int): + subgp = C.group.elts + else: + super = False RxyzQ, Rxyz, x, y, z = C.fct_field result = as_function(C, 0) - G = C.group.elts - for a in G: + for a in subgp: result += self.group_action(a) result = result.function Rxy. = PolynomialRing(F, 2) @@ -148,9 +151,9 @@ class as_function: result = as_reduction(C, result) if super: return superelliptic_function(C_super, Qxy(result)) - return as_function(AS, Qxy(result)) - - + RxyzQ, Rxyz, x, y, z = C.fct_field + return as_function(C, RxyzQ(result)) + def coordinates(self, prec = 100, basis = 0): "Return coordinates in H^1(X, OX)." AS = self.curve diff --git a/as_covers/group.sage b/as_covers/group.sage index 231a5e9..704962a 100644 --- a/as_covers/group.sage +++ b/as_covers/group.sage @@ -33,6 +33,10 @@ class group_elt: result_as_tuple = self.group.mult(self.as_tuple, other.as_tuple) return group_elt(result_as_tuple, self.group) + def __rmul__(self, other): + result_as_tuple = self.group.mult(self.as_tuple, other) + return group_elt(result_as_tuple, self.group) + def __neg__(self): result_as_tuple = self.group.inv(self.as_tuple) return group_elt(result_as_tuple, self.group) @@ -72,10 +76,10 @@ def elementary_gp(p, n): from itertools import product elts = [] for a in product(*pr): - elts += [a] + elts += [tuple(a)] one = elts[0] - mult = lambda i1, i2: [(i1[j] + i2[j]) % p for j in range(n)] - inv = lambda i: [(-i[j]) % p for j in range(n)] + mult = lambda i1, i2: tuple([(i1[j] + i2[j]) % p for j in range(n)]) + inv = lambda i: tuple([(-i[j]) % p for j in range(n)]) gens = [] for i in range(n): e = n*[0] diff --git a/as_covers/ith_magical_component.sage b/as_covers/ith_magical_component.sage index cfc6d54..a7fb1d4 100644 --- a/as_covers/ith_magical_component.sage +++ b/as_covers/ith_magical_component.sage @@ -1,6 +1,6 @@ -def ith_magical_component(omega, zvee, g): +def ith_magical_component(omega, zvee, g, super=True): '''Given a form omega on AS cover, element g of group AS.group and normal basis element zmag, find the decomposition sum_g g(zmag) omega_g and return omega_g.''' z_vee_g = zvee.group_action(g) new_form = z_vee_g*omega - return new_form.trace() \ No newline at end of file + return new_form.trace(super=super) \ No newline at end of file