added manual and tests for polydifferential forms
This commit is contained in:
parent
a8e8dbbaa3
commit
4533eec102
69
README.md
69
README.md
@ -110,7 +110,7 @@ Rx.<x> = PolynomialRing(F)
|
|||||||
f = x^3 + x
|
f = x^3 + x
|
||||||
C = superelliptic(f, 2)
|
C = superelliptic(f, 2)
|
||||||
|
|
||||||
f1 = C.x^2*C_super.y
|
f1 = C.x^2*C.y
|
||||||
f2 = C.x^3
|
f2 = C.x^3
|
||||||
AS = as_cover(C, [f1, f2], prec=1000)
|
AS = as_cover(C, [f1, f2], prec=1000)
|
||||||
```
|
```
|
||||||
@ -149,7 +149,7 @@ One can decompose it into indecomposable $(\mathbb Z/p)^2$-modules, using
|
|||||||
print(magma_module_decomposition(A, B))
|
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.
|
Note that this won't work for large genus of AS, as it uses free Magma with limited input. You may however use it with argument *text=True*, to obtain Magma command on output.
|
||||||
|
|
||||||
One can also look for magical elements:
|
One can also look for magical elements:
|
||||||
|
|
||||||
@ -157,6 +157,71 @@ One can also look for magical elements:
|
|||||||
print(AS.magical_element())
|
print(AS.magical_element())
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Polydifferential forms on abelian covers
|
||||||
|
|
||||||
|
For any $(\mathbb Z/p)^n$\-cover as above, one can define a polydifferential form (i.e. a section of $\Omega^{\otimes n}$) as follows:
|
||||||
|
```
|
||||||
|
F = GF(3)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
f = x^3 + x
|
||||||
|
C = superelliptic(f, 2)
|
||||||
|
AS = as_cover(C, [C.x^2*C.y, C.x^3], prec=1000)
|
||||||
|
omega = as_polyform(AS.x^5, 3) # the first argument is a function on AS, the second is the multiplicity of polyform
|
||||||
|
print(omega)
|
||||||
|
print(omega.expansion_at_infty())
|
||||||
|
```
|
||||||
|
Using the command *holo_polydifferentials_basis* one may compute the basis of $H^0(\Omega^{\otimes n})$:
|
||||||
|
```
|
||||||
|
p = 5
|
||||||
|
F = GF(p)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
C = superelliptic(x, 1)
|
||||||
|
AS = as_cover(C, [C.x^8], prec = 200)
|
||||||
|
print(AS.holo_polydifferentials_basis(2, threshold = 15)) #we increase the threshold if needed, see below
|
||||||
|
```
|
||||||
|
|
||||||
|
The class *as_symmetric_product_forms* may be used to define an element of $\textrm{Sym}^n \, H^0(\Omega_X)$. The command *as_symmetric_power_basis* returns a basis of $\textrm{Sym}^n \, H^0(\Omega_X)$.
|
||||||
|
```
|
||||||
|
p = 5
|
||||||
|
F = GF(p)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
C = superelliptic(x, 1)
|
||||||
|
AS = as_cover(C, [C.x^8], prec = 200)
|
||||||
|
omega = as_symmetric_product_forms([[2, AS.dx, AS.z[0]*AS.dx], [-1, AS.x*AS.dx, AS.z[0]*AS.dx]])
|
||||||
|
#note that the argument is a list of lists (first coefficient, then forms that occur in the given simple tensor)
|
||||||
|
print(omega)
|
||||||
|
print(as_symmetric_power_basis(AS, 2))
|
||||||
|
```
|
||||||
|
The method *canonical_ideal* computes the elements of $\textrm{Sym}^n \, H^0(\Omega_X)$ that are in the kernel of the multiplication map with codomain in $H^0(\Omega_X^{\otimes n})$ (i.e. the n-th homogeneous part of the canonical ideal). The method *canonical_ideal_polynomials* computes the corresponding polynomials and *group_action_canonical_ideal* the matrices of the group action on the n-th homogeneous part of the canonical ideal.
|
||||||
|
```
|
||||||
|
p = 5
|
||||||
|
F = GF(p)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
C = superelliptic(x, 1)
|
||||||
|
AS = as_cover(C, [C.x^8], prec = 200)
|
||||||
|
print(AS.canonical_ideal(2, threshold = 15))
|
||||||
|
print(AS.canonical_ideal_polynomials(2, threshold = 15))
|
||||||
|
print(AS.group_action_canonical_ideal(2, threshold = 15))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quaternion covers
|
||||||
|
|
||||||
|
Some of the above methods are also implemented for quaternion covers in characteristic $2$. Those are defined by the equations $z_0^2 + z_0 = f_0, z_1^2 + z_1 = f_1, z_2^2 + z_2 = f_2 + z_0f_0 + z_1 (f_0 + f_1)$. The arguments of *quaternion_cover* are: the covered superelliptic curve $C$ and the functions $f_0$, $f_1$, $f_2$ on $C$.
|
||||||
|
```
|
||||||
|
p = 2
|
||||||
|
F.<a> = GF(p^2)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
C = superelliptic(x, 1)
|
||||||
|
Q = quaternion_cover(C, [C.x^3, a*C.x^3, 0*C.x], prec = 300)
|
||||||
|
print(Q)
|
||||||
|
print(Q.genus())
|
||||||
|
print(Q.holomorphic_differentials_basis())
|
||||||
|
print(Q.canonical_ideal_polynomials(2))
|
||||||
|
Qi, Qj = QuaternionGroup().gens()
|
||||||
|
omega = Q.z[2]*Q.dx
|
||||||
|
print(omega.group_action(Qi), omega.group_action(Qj))
|
||||||
|
```
|
||||||
|
|
||||||
## Common errors:
|
## Common errors:
|
||||||
|
|
||||||
1. *Increase precision.* - Increase the *prec* argument of the curve.
|
1. *Increase precision.* - Increase the *prec* argument of the curve.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
class as_polyform:
|
class as_polyform:
|
||||||
def __init__(self, form, mult):
|
def __init__(self, form, mult):
|
||||||
|
'''Elements of H^0(Ω^⊗n). Usage: mult is n, form should be as_function.'''
|
||||||
self.form = form
|
self.form = form
|
||||||
self.curve = form.curve
|
self.curve = form.curve
|
||||||
self.mult = mult
|
self.mult = mult
|
||||||
@ -28,6 +29,7 @@ class as_polyform:
|
|||||||
|
|
||||||
|
|
||||||
def as_holo_polydifferentials_basis(AS, mult, threshold = 8):
|
def as_holo_polydifferentials_basis(AS, mult, threshold = 8):
|
||||||
|
'''Give the basis of H^0(Ω^⊗n) for n = mult.'''
|
||||||
v = AS.dx.valuation()
|
v = AS.dx.valuation()
|
||||||
result = AS.at_most_poles(mult*v, threshold=threshold)
|
result = AS.at_most_poles(mult*v, threshold=threshold)
|
||||||
result = [as_polyform(omega, mult) for omega in result]
|
result = [as_polyform(omega, mult) for omega in result]
|
||||||
@ -40,6 +42,7 @@ def as_holo_polydifferentials_basis(AS, mult, threshold = 8):
|
|||||||
as_cover.holo_polydifferentials_basis = as_holo_polydifferentials_basis
|
as_cover.holo_polydifferentials_basis = as_holo_polydifferentials_basis
|
||||||
|
|
||||||
def as_symmetric_power_basis(AS, n, threshold = 8):
|
def as_symmetric_power_basis(AS, n, threshold = 8):
|
||||||
|
'''Give the basis of H^0(Ω)^⊙n for n = mult.'''
|
||||||
g = AS.genus()
|
g = AS.genus()
|
||||||
B0 = AS.holomorphic_differentials_basis(threshold=threshold)
|
B0 = AS.holomorphic_differentials_basis(threshold=threshold)
|
||||||
from itertools import product
|
from itertools import product
|
||||||
@ -57,6 +60,7 @@ def as_symmetric_power_basis(AS, n, threshold = 8):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def as_canonical_ideal(AS, n, threshold=8):
|
def as_canonical_ideal(AS, n, threshold=8):
|
||||||
|
'''Return the n-th homogeneous part of the canonical ideal.'''
|
||||||
B0 = AS.holomorphic_differentials_basis(threshold=threshold)
|
B0 = AS.holomorphic_differentials_basis(threshold=threshold)
|
||||||
F = AS.base_ring
|
F = AS.base_ring
|
||||||
g = AS.genus()
|
g = AS.genus()
|
||||||
@ -83,13 +87,14 @@ def as_canonical_ideal(AS, n, threshold=8):
|
|||||||
as_cover.canonical_ideal = as_canonical_ideal
|
as_cover.canonical_ideal = as_canonical_ideal
|
||||||
|
|
||||||
def as_canonical_ideal_polynomials(AS, n, threshold=8):
|
def as_canonical_ideal_polynomials(AS, n, threshold=8):
|
||||||
|
'''Return the polynomials defining n-th homogeneous part of the canonical ideal.'''
|
||||||
return [a.polynomial() for a in AS.canonical_ideal(n, threshold=threshold)]
|
return [a.polynomial() for a in AS.canonical_ideal(n, threshold=threshold)]
|
||||||
|
|
||||||
as_cover.canonical_ideal_polynomials = as_canonical_ideal_polynomials
|
as_cover.canonical_ideal_polynomials = as_canonical_ideal_polynomials
|
||||||
|
|
||||||
class as_symmetric_product_forms:
|
class as_symmetric_product_forms:
|
||||||
def __init__(self, forms_and_coeffs):
|
def __init__(self, forms_and_coeffs):
|
||||||
'''Elements of forms_and_coeffs are of the form [coeff, form1, ..., formn]'''
|
'''Elements of forms_and_coeffs are of the form [coeff, form_1, ..., form_n]'''
|
||||||
self.n = len(forms_and_coeffs[0]) - 1
|
self.n = len(forms_and_coeffs[0]) - 1
|
||||||
forms_and_coeffs1 = []
|
forms_and_coeffs1 = []
|
||||||
for atuple in forms_and_coeffs:
|
for atuple in forms_and_coeffs:
|
||||||
@ -148,6 +153,7 @@ class as_symmetric_product_forms:
|
|||||||
return as_symmetric_product_forms(aux_tuples)
|
return as_symmetric_product_forms(aux_tuples)
|
||||||
|
|
||||||
def multiply(self):
|
def multiply(self):
|
||||||
|
'''The map H^0(Ω)^⊙n ---> H^0(Ω^⊗n)'''
|
||||||
n = self.n
|
n = self.n
|
||||||
AS = self.curve
|
AS = self.curve
|
||||||
RxyzQ, Rxyz, x, y, z = AS.fct_field
|
RxyzQ, Rxyz, x, y, z = AS.fct_field
|
||||||
@ -163,6 +169,7 @@ class as_symmetric_product_forms:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def polynomial(self):
|
def polynomial(self):
|
||||||
|
'''Return the associated polynomial.'''
|
||||||
AS = self.curve
|
AS = self.curve
|
||||||
F = AS.base_ring
|
F = AS.base_ring
|
||||||
g = AS.genus()
|
g = AS.genus()
|
||||||
@ -193,6 +200,7 @@ def non_decreasing(L):
|
|||||||
return all(x<=y for x, y in zip(L, L[1:]))
|
return all(x<=y for x, y in zip(L, L[1:]))
|
||||||
|
|
||||||
def as_matrices_group_action_canonical_ideal(AS, mult, threshold = 8):
|
def as_matrices_group_action_canonical_ideal(AS, mult, threshold = 8):
|
||||||
|
'''Return the group action matrices for the n-th homogeneous part of the canonical ideal.'''
|
||||||
K = as_canonical_ideal(AS, mult, threshold = threshold)
|
K = as_canonical_ideal(AS, mult, threshold = threshold)
|
||||||
n = AS.height
|
n = AS.height
|
||||||
F = AS.base_ring
|
F = AS.base_ring
|
||||||
@ -206,3 +214,5 @@ def as_matrices_group_action_canonical_ideal(AS, mult, threshold = 8):
|
|||||||
M[i, :] = vector(linear_representation_polynomials(K_group_action_polynomials[i], K_polynomials))
|
M[i, :] = vector(linear_representation_polynomials(K_group_action_polynomials[i], K_polynomials))
|
||||||
matrices += [M]
|
matrices += [M]
|
||||||
return matrices
|
return matrices
|
||||||
|
|
||||||
|
as_cover.group_action_canonical_ideal = as_matrices_group_action_canonical_ideal
|
27
as_covers/tests/as_polyforms_test.sage
Normal file
27
as_covers/tests/as_polyforms_test.sage
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
p = 2
|
||||||
|
F = GF(p)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
C = superelliptic(x, 1)
|
||||||
|
AS = as_cover(C, [C.x^3, C.x^5], prec = 200)
|
||||||
|
B = AS.holo_polydifferentials_basis(3)
|
||||||
|
print(len(B) == (2 * 3 - 1) * (AS.genus() - 1)) #is the dimension as predicted by Riemann--Roch?
|
||||||
|
I2 = AS.canonical_ideal_polynomials(2)
|
||||||
|
R = I2[0].parent() #ring, to which the polynomials belong
|
||||||
|
J2 = R.ideal(I2) #ideal defined by the set I
|
||||||
|
print(J2.is_prime(), len(R.gens()) - J2.dimension() - 1)
|
||||||
|
I3 = AS.canonical_ideal_polynomials(3)
|
||||||
|
J3 = R.ideal(I2 + I3)
|
||||||
|
print(J3.is_prime(), len(R.gens()) - J3.dimension() - 1)
|
||||||
|
|
||||||
|
p = 5
|
||||||
|
F = GF(p)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
C = superelliptic(x, 1)
|
||||||
|
AS = as_cover(C, [C.x^8], prec = 200)
|
||||||
|
I2 = AS.canonical_ideal_polynomials(2, threshold=15)
|
||||||
|
R = I2[0].parent() #ring, to which the polynomials belong
|
||||||
|
J2 = R.ideal(I2) #ideal defined by the set I
|
||||||
|
print(J2.is_prime(), len(R.gens()) - J2.dimension() - 1)
|
||||||
|
I3 = AS.canonical_ideal_polynomials(3, threshold=20)
|
||||||
|
J3 = R.ideal(I2 + I3)
|
||||||
|
print(J3.is_prime(), len(R.gens()) - J3.dimension() - 1)
|
12
quaternion_covers/tests/quaternion_covers_tests.sage
Normal file
12
quaternion_covers/tests/quaternion_covers_tests.sage
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
p = 2
|
||||||
|
F.<a> = GF(p^2)
|
||||||
|
Rx.<x> = PolynomialRing(F)
|
||||||
|
C = superelliptic(x, 1)
|
||||||
|
Q = quaternion_cover(C, [C.x^3, a*C.x^3, 0*C.x], prec = 300)
|
||||||
|
print(Q.genus() == len(Q.holomorphic_differentials_basis()))
|
||||||
|
I2 = Q.canonical_ideal_polynomials(2)
|
||||||
|
R = I2[0].parent() #ring, to which the polynomials belong
|
||||||
|
J2 = R.ideal(I2) #ideal defined by the set I
|
||||||
|
print(J2.is_prime(), len(R.gens()) - J2.dimension() - 1)
|
||||||
|
A, B = quaternion_matrices_group_action_canonical_ideal(Q, 2)
|
||||||
|
print(A * B == B^3*A, A^2 == B^2, A^4 == identity_matrix(A.dimensions()[0]))
|
15
tests.sage
15
tests.sage
@ -27,11 +27,12 @@
|
|||||||
#load('as_covers/tests/diffn_test.sage')
|
#load('as_covers/tests/diffn_test.sage')
|
||||||
#print("Cartier test:")
|
#print("Cartier test:")
|
||||||
#load('as_covers/tests/cartier_test.sage')
|
#load('as_covers/tests/cartier_test.sage')
|
||||||
print("Decomposition into g0, g8/ omega0, omega8 test:")
|
print("Polydifferentials test:")
|
||||||
load('superelliptic_drw/tests/decomposition_into_g0_g8_tests.sage')
|
load('as_covers/tests/as_polyforms_test.sage')
|
||||||
print("Auxilliary decomposition test:")
|
#print("Decomposition into g0, g8/ omega0, omega8 test:")
|
||||||
load('superelliptic_drw/tests/auxilliary_decompositions_test.sage')
|
#load('superelliptic_drw/tests/decomposition_into_g0_g8_tests.sage')
|
||||||
print("Superelliptic de Rham-Witt test:")
|
#print("Auxilliary decomposition test:")
|
||||||
load('superelliptic_drw/tests/superelliptic_drw_tests.sage')
|
#load('superelliptic_drw/tests/auxilliary_decompositions_test.sage')
|
||||||
|
#print("Superelliptic de Rham-Witt test:")
|
||||||
|
#load('superelliptic_drw/tests/superelliptic_drw_tests.sage')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user