DeRhamComputation/as_covers/as_polyforms.sage
2024-01-22 16:10:03 +00:00

225 lines
8.4 KiB
Python

class as_polyform:
def __init__(self, form, mult):
self.form = form
self.curve = form.curve
self.mult = mult
def __add__(self, other):
return as_polyform(self.form + other.form, self.mult)
def __repr__(self):
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)
def coordinates(self, basis = 0):
"""Find coordinates of the given holomorphic form self in terms of the basis forms in a list holo."""
AS = self.curve
if basis == 0:
basis = AS.holomorphic_differentials_basis()
RxyzQ, Rxyz, x, y, z = AS.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.
denom = LCM([denominator(omega.form.function) for omega in basis])
basis = [denom*omega.form.function for omega in basis]
self_with_no_denominator = denom*self.form.function
return linear_representation_polynomials(Rxyz(self_with_no_denominator), [Rxyz(omega) for omega in basis])
def as_holo_polydifferentials_basis(AS, mult, threshold = 8):
v = AS.dx.valuation()
result = AS.at_most_poles(mult*v, threshold=threshold)
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_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()
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, len(B1), r)
for i in range(0, len(B1)):
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, n)
#return M, c.coordinates(basis=B2)
M[i, :] = vector(c.coordinates(basis=B2))
K = M.kernel().basis()
result = []
for v in K:
coeffs = {tuple(b) : 0 for b in B1}
for i in range(r):
if v[i] != 0:
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
self.coeffs = coeffs #dictionary
self.curve = pairs_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()
result = matrix(F, g, g)
for (omega1, omega2) in self.pairs:
c = omega1.coordinates(basis = basis)
d = omega2.coordinates(basis = basis)
for i in range(g):
for j in range(g):
result[i, j] += self.coeffs[(omega1, omega2)]*c[i]*d[j]
return result
def __repr__(self):
result = ''
for (omega1, omega2) in self.pairs:
if self.coeffs[(omega1, omega2)] !=0:
result += str(self.coeffs[(omega1, omega2)]) + ' * ' + str(omega1) + '' + str(omega2) + ' + '
return result
def polynomial(self):
AS = self.curve
F = AS.base_ring
g = AS.genus()
M = self.coordinates()
Rg = PolynomialRing(F, 'X', g)
X = Rg.gens()
return sum(M[i, j] * X[i]*X[j] for i in range(g) for j in range(g))
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)
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:]))