readme v1; examples
This commit is contained in:
parent
6c3fc0d50e
commit
7d90f7923e
135
README.md
135
README.md
@ -1,4 +1,4 @@
|
|||||||
# SAGEMATH module: superelliptic curves and their Artin-Schreier covers
|
# SAGEMATH module: superelliptic curves and their abelian p-group covers
|
||||||
|
|
||||||
## Basic information
|
## Basic information
|
||||||
|
|
||||||
@ -9,47 +9,160 @@ The main file is init.sage. In order to use it, type:
|
|||||||
```sage: load('init.sage')```
|
```sage: load('init.sage')```
|
||||||
|
|
||||||
The main two "packages" are intended for:
|
The main two "packages" are intended for:
|
||||||
|
|
||||||
- superelliptic curves,
|
- superelliptic curves,
|
||||||
- $(\mathbb Z/p)^n$-covers of superelliptic curves.
|
- $(\mathbb Z/p)^n$-covers of superelliptic curves.
|
||||||
|
|
||||||
|
See below and the file examples.sage for examples.
|
||||||
|
|
||||||
## Superelliptic curves
|
## Superelliptic curves
|
||||||
|
|
||||||
In order to define a superelliptic curve $C : y^4 = x^6 + 1$ over the finite field with 9 elements,
|
In order to define a superelliptic curve $C : y^4 = x^6 + 1$ over the finite field with 25 elements,
|
||||||
use the following commands:
|
use the following commands:
|
||||||
|
|
||||||
```
|
```
|
||||||
F.<a> = GF(9, 'a')
|
F.<a> = GF(25, 'a')
|
||||||
Rx.<x> = PolynomialRing(F)
|
Rx.<x> = PolynomialRing(F)
|
||||||
f = x^6 + 1
|
f = x^6 + 1
|
||||||
C = superelliptic(f, 4)
|
C = superelliptic(f, 4)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The class $C$ has an optional argument *prec*, which gives the precision of precomputed
|
||||||
|
expansions at infinity of the functions of the curve $C$. Note that curve of the form $y^m = f(x)$ has $\delta := GCD(\deg f, m)$
|
||||||
|
points at infinity and that $f(x)$ must be separable in order for $C$ to be smooth.
|
||||||
|
|
||||||
There are three auxilliary classes: superelliptic_function (for functions defined on superelliptic curves), superelliptic_form (for forms defined on superelliptic curves) and superelliptic_cech (for cech cocycles for the de Rham cohomology on superelliptic curves).
|
There are three auxilliary classes: superelliptic_function (for functions defined on superelliptic curves), superelliptic_form (for forms defined on superelliptic curves) and superelliptic_cech (for cech cocycles for the de Rham cohomology on superelliptic curves).
|
||||||
|
|
||||||
For example, in order to define the function $x + y$ on our curve $C$ we can define it like this:
|
For example, in order to define the function $x + 2y + 1$ on our curve $C$ we can define it like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
Rxy.<x, y> = PolynomialRing(F, 2)
|
Rxy.<x, y> = PolynomialRing(F, 2)
|
||||||
fct = superelliptic_function(C, x + y)
|
fct = superelliptic_function(C, x + 2*y + 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
or simpler:
|
or simpler:
|
||||||
|
|
||||||
```
|
```
|
||||||
fct = C.x + C.y
|
fct = C.x + 2*C.y + C.one
|
||||||
```
|
```
|
||||||
|
|
||||||
Similarly, in order to define the form $\omega = y \cdot dx$ we may use:
|
Similarly, in order to define the form $\omega = y \cdot dx$ we may use:
|
||||||
|
|
||||||
```
|
```
|
||||||
omega = superelliptic_form(C, y)
|
omega = superelliptic_form(C, y)
|
||||||
```
|
```
|
||||||
|
|
||||||
or simpler:
|
or simpler:
|
||||||
|
|
||||||
```
|
```
|
||||||
omega = C.y * C.dx
|
omega = C.y * C.dx
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The cech cocycles are given as triples:
|
||||||
|
|
||||||
|
$$ (\omega_0, f, \omega_{\infty}), $$
|
||||||
|
|
||||||
## Troubleshooting
|
where $\omega_0$ is a form regular on $U_0$ (i.e. on the affine curve $y^m = f(x)$),
|
||||||
|
$\omega_{\infty}$ is a form regular on $U_{\infty}$, the affine curve containing the points at infinity (explicitly given by $w^{\delta} = g(v^M \cdot w^b)$, $g(x) = x^{\deg f} \cdot f(1/x)$, $\delta := GCD(m, \deg f)$, $br - am = \delta$, $M := m/\delta$) and $f$ is a function regular on $U_0 \cap U_{\infty}$ such that $\omega_0 - \omega_{\infty} = df$. See e.g. [Section 2 in article of Kock and Tait](https://arxiv.org/pdf/1709.03422.pdf). In order to access the arguments omega_0, f, omega_{\infty} of a cocyle *eta* we use the arguments *eta.omega0*, *eta.f*, *eta.omega8* respectively. Thus, let us check that the cocycle condition omega_0 - omega_{\infty} = df is satisfied for an exemplary cocycle:
|
||||||
|
|
||||||
|
```
|
||||||
|
eta = C.de_rham_basis()[-1] # we pick one of the forms in the de Rham basis of C
|
||||||
|
print(eta.omega0 - eta.omega8 == eta.f.diffn())
|
||||||
|
```
|
||||||
|
|
||||||
|
The module allows to compute the basis of of holomorphic differential forms:
|
||||||
|
|
||||||
|
```
|
||||||
|
print(C.holomorphic_differentials_basis())
|
||||||
|
```
|
||||||
|
|
||||||
|
One may also compute the coordinates of a given holomorphic differential form. On default,
|
||||||
|
the coordinates are computed with respect to *C.holomorphic_differentials_basis()*.
|
||||||
|
One may also give a basis as an optional argument. Note that this speeds up computation, since
|
||||||
|
the basis is not calculated several times.
|
||||||
|
|
||||||
|
```
|
||||||
|
omega = (2*C.y^2 - C.y + C.one)/C.y^3 * C.dx
|
||||||
|
print(omega.coordinates())
|
||||||
|
basis = C.holomorphic_differentials_basis()
|
||||||
|
print(omega.coordinates(basis = basis))
|
||||||
|
```
|
||||||
|
|
||||||
|
The method *expansion_at_infty()* allows to compute the Laurent expansion of a given function at a place at infinity.
|
||||||
|
The parameter *place* is optional. It is a number from 0 to $\delta - 1$, giving a place at infinity in which
|
||||||
|
the expansion should be computed.
|
||||||
|
|
||||||
|
```
|
||||||
|
print(omega.expansion_at_infty(place=0))
|
||||||
|
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
|
||||||
|
|
||||||
|
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$,
|
||||||
|
$z_1^3 - z_1 = x^3$.
|
||||||
|
|
||||||
|
```
|
||||||
|
F = GF(3)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
f = x^3 + x
|
||||||
|
C = superelliptic(f, 2)
|
||||||
|
|
||||||
|
f1 = C.x^2*C_super.y
|
||||||
|
f2 = C.x^3
|
||||||
|
AS = as_cover(C, [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
|
||||||
|
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.
|
||||||
|
|
||||||
|
Similarly, the are classes _as\_function, as\_form, as\_cech_ and one can write _AS.x, AS.dx_, etc. There are also methods _holomorphic\_differentials\_basis\(\)_, _de\_rham\_basis\(\)_, _coordinates\(\)_, _expansion\_at\_infty\(\)_, *valuation()* etc.
|
||||||
|
Note that some functions \(e.g. _holomorphic\_differential\_basis_\) have optional _threshold_ parameter. Increase it in case of problems.
|
||||||
|
|
||||||
|
In order to compute the group action of $(\mathbb Z/p)^n$ on a given function/form/cocycle, use *group_action()*, e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
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]
|
||||||
|
```
|
||||||
|
|
||||||
|
In order to compute the matrices of the action, use *group_action_matrices_holo* and *group_action_matrices_dR*:
|
||||||
|
|
||||||
|
```
|
||||||
|
p = 3
|
||||||
|
A, B = group_action_matrices_holo(AS)
|
||||||
|
n = A.dimensions()[0]
|
||||||
|
#Let us check that they commute and are of order p:
|
||||||
|
print(A*B == B*A)
|
||||||
|
print(A^p == identity_matrix(n))
|
||||||
|
print(B^p == identity_matrix(n))
|
||||||
|
```
|
||||||
|
|
||||||
|
One can decompose it into indecomposable $(\mathbb Z/p)^2$-modules, using
|
||||||
|
*magma_module_decomposition*:
|
||||||
|
|
||||||
|
```
|
||||||
|
print(magma_module_decomposition(A, B))
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that this won't work for large genus of AS, as it uses free Magma with limited input.
|
||||||
|
|
||||||
|
One can also look for magical elements:
|
||||||
|
|
||||||
|
```
|
||||||
|
print(AS.magical_element())
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common errors:
|
||||||
|
|
||||||
|
1. *Increase precision.* - Increase the *prec* argument of the curve.
|
||||||
|
1. *I haven't found all forms, only x of y* - Increase threshold when computing a basis.
|
||||||
|
1. *no 12 -th root; divide by 2* - when defining AS cover, one needs to compute roots of some numbers. This error means that a number is not in the field. You can either enlarge the base field, or divide one of the functions by given number and study the modified curve.
|
||||||
|
1. *unsupported operand parent(s) for %: 'The Infinity Ring' and 'The Infinity Ring'* - One of the power series turned out to be zero. Probably the AS cover that you've given is not connected (for example it is of the form $z_0^p - z_0 = f^p - f$).
|
||||||
|
|
||||||
- precision
|
|
||||||
- threshold
|
|
||||||
- no root in the field
|
|
||||||
- basis -- coordinates.
|
|
@ -1,4 +1,4 @@
|
|||||||
def magmathis(A, B, text = False, prefix="", sufix=""):
|
def magma_module_decomposition(A, B, text = False, prefix="", sufix=""):
|
||||||
"""Find decomposition of Z/p^2-module given by matrices A, B into indecomposables using magma.
|
"""Find decomposition of Z/p^2-module given by matrices A, B into indecomposables using magma.
|
||||||
If text = True, print the command for Magma. Else - return the output of Magma free."""
|
If text = True, print the command for Magma. Else - return the output of Magma free."""
|
||||||
q = parent(A).base_ring().order()
|
q = parent(A).base_ring().order()
|
||||||
|
@ -145,7 +145,7 @@ class as_cover:
|
|||||||
print("I haven't found all forms, only ", len(forms), " of ", self.genus())
|
print("I haven't found all forms, only ", len(forms), " of ", self.genus())
|
||||||
return holomorphic_differentials_basis(self, threshold = threshold + 1)
|
return holomorphic_differentials_basis(self, threshold = threshold + 1)
|
||||||
if len(forms) > self.genus():
|
if len(forms) > self.genus():
|
||||||
print("Increase precision.")
|
raise ValueError("Increase precision.")
|
||||||
return forms
|
return forms
|
||||||
|
|
||||||
def cartier_matrix(self, prec=50):
|
def cartier_matrix(self, prec=50):
|
||||||
|
@ -16,7 +16,8 @@ def group_action_matrices_holo(AS):
|
|||||||
ei = n*[0]
|
ei = n*[0]
|
||||||
ei[i] = 1
|
ei[i] = 1
|
||||||
generators += [ei]
|
generators += [ei]
|
||||||
return group_action_matrices(AS.holomorphic_differentials_basis(), generators, basis = AS.holomorphic_differentials_basis())
|
basis = AS.holomorphic_differentials_basis()
|
||||||
|
return group_action_matrices(basis, generators, basis = basis)
|
||||||
|
|
||||||
def group_action_matrices_dR(AS, threshold=8):
|
def group_action_matrices_dR(AS, threshold=8):
|
||||||
n = AS.height
|
n = AS.height
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
p = 7
|
p = 3
|
||||||
m = 2
|
m = 2
|
||||||
F = GF(p)
|
F = GF(p)
|
||||||
Rx.<x> = PolynomialRing(F)
|
Rx.<x> = PolynomialRing(F)
|
||||||
f = x^3 + 1
|
f = x^3 + x
|
||||||
C_super = superelliptic(f, m)
|
C_super = superelliptic(f, m)
|
||||||
|
|
||||||
Rxy.<x, y> = PolynomialRing(F, 2)
|
f1 = C_super.x^2*C_super.y
|
||||||
f1 = superelliptic_function(C_super, x^2*y)
|
f2 = C_super.x^3
|
||||||
f2 = superelliptic_function(C_super, x^3)
|
|
||||||
AS = as_cover(C_super, [f1, f2], prec=1000)
|
AS = as_cover(C_super, [f1, f2], prec=1000)
|
||||||
|
|
||||||
A, B = group_action_matrices_holo(AS)
|
A, B = group_action_matrices_holo(AS)
|
||||||
@ -15,3 +14,5 @@ n = A.dimensions()[0]
|
|||||||
print(A*B == B*A)
|
print(A*B == B*A)
|
||||||
print(A^p == identity_matrix(n))
|
print(A^p == identity_matrix(n))
|
||||||
print(B^p == identity_matrix(n))
|
print(B^p == identity_matrix(n))
|
||||||
|
|
||||||
|
print(magma_module_decomposition(A, B))
|
74
example.sage
Normal file
74
example.sage
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
print('Remember to load init.sage!')
|
||||||
|
print('Define the superelliptic curve C : y^4 = x^6 + 1 over GF(5)')
|
||||||
|
F = GF(5)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
f = x^6 + 1
|
||||||
|
C = superelliptic(f, 4)
|
||||||
|
print(C)
|
||||||
|
print('Is is smooth?')
|
||||||
|
print(C.is_smooth())
|
||||||
|
print('----------------------\n')
|
||||||
|
print('Define the function x + 2y + 1 on our curve C:')
|
||||||
|
Rxy.<x, y> = PolynomialRing(F, 2)
|
||||||
|
fct1 = superelliptic_function(C, x + 2*y + 1)
|
||||||
|
fct2 = C.x + 2*C.y + C.one
|
||||||
|
print('In one way:', fct1, 'In another way:', fct2)
|
||||||
|
print('----------------------\n')
|
||||||
|
print('define the form omega = y * dx on C:')
|
||||||
|
omega1 = superelliptic_form(C, y)
|
||||||
|
omega2 = C.y * C.dx
|
||||||
|
print('In one way:', omega1, 'In another way:', omega2)
|
||||||
|
print('----------------------\n')
|
||||||
|
print('The holomorphic differentials basis of C:')
|
||||||
|
print(C.holomorphic_differentials_basis())
|
||||||
|
print('Let us compute now coordinates of some differential form.')
|
||||||
|
omega = (2*C.y^2 - C.y + C.one)/C.y^3 * C.dx
|
||||||
|
print('First method:', omega.coordinates())
|
||||||
|
basis = C.holomorphic_differentials_basis()
|
||||||
|
print('Second method (faster):', omega.coordinates(basis = basis))
|
||||||
|
print('Compute the Laurent expansion of omega, first at one place at infinity and then at the second:')
|
||||||
|
print(omega.expansion_at_infty(place = 0))
|
||||||
|
print(omega.expansion_at_infty(place = 1))
|
||||||
|
print('----------------------\n')
|
||||||
|
print('The basis of de Rham cohomology of C:')
|
||||||
|
print(C.de_rham_basis())
|
||||||
|
print('Elements of de Rham cohomology are Cech cocycles -- triples:')
|
||||||
|
eta = C.de_rham_basis()[-1]
|
||||||
|
print(eta)
|
||||||
|
print('Let us check that the cocycle condition omega_0 - omega_{\infty} = df is satisfied:')
|
||||||
|
print(eta.omega0 - eta.omega8 == eta.f.diffn())
|
||||||
|
print('----------------------\n')
|
||||||
|
#
|
||||||
|
#
|
||||||
|
F = GF(3)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
f = x^3 + x
|
||||||
|
C = superelliptic(f, 2)
|
||||||
|
|
||||||
|
f1 = C.x^2*C_super.y
|
||||||
|
f2 = C.x^3
|
||||||
|
AS = as_cover(C, [f1, f2], prec=1000)
|
||||||
|
print(AS)
|
||||||
|
print('----------------------\n')
|
||||||
|
print('Compute the group action of $(\mathbb Z/p)^n$ on a form:')
|
||||||
|
omega = AS.holomorphic_differentials_basis()[1]
|
||||||
|
print('Form:', omega)
|
||||||
|
print('Group action by [1, 0]:', omega.group_action([1, 0]))
|
||||||
|
print('Group action by [0, 1]:', omega.group_action([0, 1]))
|
||||||
|
print('Let us compute the matrices of the group action:')
|
||||||
|
p = 3
|
||||||
|
A, B = group_action_matrices_holo(AS)
|
||||||
|
print(A, '\n', B)
|
||||||
|
n = A.dimensions()[0]
|
||||||
|
print('Let us check that they commute and are of order p')
|
||||||
|
print(A*B == B*A)
|
||||||
|
print(A^p == identity_matrix(n))
|
||||||
|
print(B^p == identity_matrix(n))
|
||||||
|
print('We decompose it into indecomposable $(\mathbb Z/p)^2$-modules:')
|
||||||
|
print(magma_module_decomposition(A, B))
|
||||||
|
|
||||||
|
print('----------------------\n')
|
||||||
|
print('Let us look for magical elements:')
|
||||||
|
z = AS.magical_element()
|
||||||
|
print(z)
|
||||||
|
print(z.valuation())
|
@ -28,9 +28,3 @@ load('auxilliaries/linear_combination_polynomials.sage')
|
|||||||
load('auxilliaries/laurent_analytic_part.sage')
|
load('auxilliaries/laurent_analytic_part.sage')
|
||||||
##############
|
##############
|
||||||
##############
|
##############
|
||||||
#load('drafty/convert_superelliptic_into_AS.sage')
|
|
||||||
load('drafty/draft.sage')
|
|
||||||
#load('drafty/draft_klein_covers.sage')
|
|
||||||
#load('drafty/draft_klein_covers.sage')
|
|
||||||
#load('drafty/2gpcovers.sage')
|
|
||||||
load('drafty/pole_numbers.sage')
|
|
@ -207,3 +207,10 @@ class superelliptic_form:
|
|||||||
C = omega.curve
|
C = omega.curve
|
||||||
p = C.characteristic
|
p = C.characteristic
|
||||||
return (omega_regular.dx)^p*C.x^(p-1)*C.dx + (omega_regular.dy)^p*C.y^(p-1)*C.y.diffn()
|
return (omega_regular.dx)^p*C.x^(p-1)*C.dx + (omega_regular.dy)^p*C.y^(p-1)*C.y.diffn()
|
||||||
|
|
||||||
|
def valuation(self, place = 0):
|
||||||
|
'''Return valuation at i-th place at infinity.'''
|
||||||
|
C = self.curve
|
||||||
|
F = C.base_ring
|
||||||
|
Rt.<t> = LaurentSeriesRing(F)
|
||||||
|
return Rt(self.expansion_at_infty(place = place)).valuation()
|
@ -150,3 +150,10 @@ class superelliptic_function:
|
|||||||
auxilliary_form = C.x * auxilliary_form
|
auxilliary_form = C.x * auxilliary_form
|
||||||
auxilliary_form = auxilliary_form.form
|
auxilliary_form = auxilliary_form.form
|
||||||
return superelliptic_function(C, auxilliary_form)
|
return superelliptic_function(C, auxilliary_form)
|
||||||
|
|
||||||
|
def valuation(self, place = 0):
|
||||||
|
'''Return valuation at i-th place at infinity.'''
|
||||||
|
C = self.curve
|
||||||
|
F = C.base_ring
|
||||||
|
Rt.<t> = LaurentSeriesRing(F)
|
||||||
|
return Rt(self.expansion_at_infty(place = place)).valuation()
|
Loading…
Reference in New Issue
Block a user