pep8 format

This commit is contained in:
carlos alquezar 2023-02-07 14:46:40 +01:00
parent 446eceb01b
commit f6e0cece0b
2 changed files with 291 additions and 184 deletions

133
aplK.py
View File

@ -1,3 +1,30 @@
r"""
<Short one-line summary that ends with no period>
<Paragraph description>
EXAMPLES::
<Lots and lots of examples>
AUTHORS:
- Carlos Alquézar Baeta (2023-02-07): initial version
- Miguel Ángel Marco (2023-02-07): initial version
- Jorge Martín Morales (2023-02-07): initial version
"""
# ****************************************************************************
# Copyright (C) 2023 Carlos Alquézar Baeta <alquezar@unizar.es>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# https://www.gnu.org/licenses/
# ****************************************************************************
from sage.algebras.commutative_dga import * from sage.algebras.commutative_dga import *
from sage.structure.parent import Parent from sage.structure.parent import Parent
from sage.structure.element import Element from sage.structure.element import Element
@ -5,6 +32,7 @@ from sage.structure.richcmp import rich_to_bool, op_EQ, op_NE, op_LT, op_LE, op_
from sage.rings.polynomial.polydict import ETuple from sage.rings.polynomial.polydict import ETuple
from copy import deepcopy from copy import deepcopy
class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation): class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
""" """
A differential multi-graded commutative algebra A differential multi-graded commutative algebra
@ -84,7 +112,8 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
if (degree < 0): if (degree < 0):
raise ValueError('`degree` must be a non-negative integer') raise ValueError('`degree` must be a non-negative integer')
parts = [self.homogeneous_parts()[k] for k in self.homogeneous_parts() if list(k)[0]==degree] parts = [self.homogeneous_parts()[k]
for k in self.homogeneous_parts() if list(k)[0] == degree]
return self.parent()(sum(parts)) return self.parent()(sum(parts))
def reduce(self, relations=[]): def reduce(self, relations=[]):
@ -107,7 +136,6 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
return DifferentialGCAlgebra.Element.reduce(self, [apl.t_relation, apl.y_relation]) return DifferentialGCAlgebra.Element.reduce(self, [apl.t_relation, apl.y_relation])
def _integrable_part(self): def _integrable_part(self):
""" """
The method returns the coefficient in Q[t_1,...,t_n] of the term The method returns the coefficient in Q[t_1,...,t_n] of the term
of degree `n` of degree `n`
@ -119,7 +147,8 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
""" """
apl = self.parent() apl = self.parent()
pol = apl(self.reduce()) #needed in case reduce() returns an integer # needed in case reduce() returns an integer
pol = apl(self.reduce())
relations = [] relations = []
for i in range(apl.n+1): for i in range(apl.n+1):
relations.append(apl.gens()[apl.n+1+i]-1) relations.append(apl.gens()[apl.n+1+i]-1)
@ -234,7 +263,8 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
coef = monomial.dict()[exp] coef = monomial.dict()[exp]
n = len(exp)//2 n = len(exp)//2
if (exp[n+idx] == 0): if (exp[n+idx] == 0):
raise IndexError("It is not possible to get a primitive using the given idx.") raise IndexError(
"It is not possible to get a primitive using the given idx.")
primitive = list(deepcopy(exp)) primitive = list(deepcopy(exp))
primitive[n+idx] = 0 primitive[n+idx] = 0
primitive[idx] += 1 primitive[idx] += 1
@ -279,6 +309,7 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
else: else:
return w+theta.primitive() return w+theta.primitive()
def AlgebraPL(n): def AlgebraPL(n):
""" """
The graded commutative differential cochain algebra Apl of dimension ``n`` The graded commutative differential cochain algebra Apl of dimension ``n``
@ -294,7 +325,8 @@ def AlgebraPL(n):
ys = ['y'+str(t) for t in range(n+1)] ys = ['y'+str(t) for t in range(n+1)]
degrees = tuple((n+1)*[(0, 2)])+tuple((n+1)*[(1, 2)]) degrees = tuple((n+1)*[(0, 2)])+tuple((n+1)*[(1, 2)])
gca = GradedCommutativeAlgebra(QQ, names=ts+ys, degrees=degrees) gca = GradedCommutativeAlgebra(QQ, names=ts+ys, degrees=degrees)
differentials = {gca.gens_dict()[ts[i]]:gca.gens_dict()[ys[i]] for i in range(n+1)} differentials = {gca.gens_dict()[ts[i]]: gca.gens_dict()[
ys[i]] for i in range(n+1)}
return AplN(gca, differentials) return AplN(gca, differentials)
############################################# #############################################
@ -306,6 +338,7 @@ def AlgebraPL(n):
#q = p.differential() #q = p.differential()
############################################# #############################################
class SimplicialAplN(AplN, UniqueRepresentation): class SimplicialAplN(AplN, UniqueRepresentation):
""" """
@ -395,7 +428,8 @@ class SimplicialAplN(AplN, UniqueRepresentation):
domain = self.parent() domain = self.parent()
codomain = SimplicialAlgebraplN(n+1) codomain = SimplicialAlgebraplN(n+1)
if(j > n): if(j > n):
print("the degeneration index must be a non-negative number lower or equal to "+str(n)) print(
"the degeneration index must be a non-negative number lower or equal to "+str(n))
return False return False
elif(j < 0): elif(j < 0):
print("the degeneration index must be non-negative") print("the degeneration index must be non-negative")
@ -410,7 +444,8 @@ class SimplicialAplN(AplN, UniqueRepresentation):
yImages.append(codomain.gens()[n+1+k]) yImages.append(codomain.gens()[n+1+k])
elif (k == j): elif (k == j):
tImages.append(codomain.gens()[k]+codomain.gens()[k+1]) tImages.append(codomain.gens()[k]+codomain.gens()[k+1])
yImages.append(codomain.gens()[n+1+k]+codomain.gens()[n+1+k+1]) yImages.append(codomain.gens()[
n+1+k]+codomain.gens()[n+1+k+1])
elif (k > j): elif (k > j):
tImages.append(codomain.gens()[k+1]) tImages.append(codomain.gens()[k+1])
yImages.append(codomain.gens()[n+1+k+1]) yImages.append(codomain.gens()[n+1+k+1])
@ -445,7 +480,8 @@ class SimplicialAplN(AplN, UniqueRepresentation):
""" """
if not (self.is_homogeneous() and self.total_degree() == self.parent().n): if not (self.is_homogeneous() and self.total_degree() == self.parent().n):
raise ValueError("The polynomial is not homogeneous of maximum degree.") raise ValueError(
"The polynomial is not homogeneous of maximum degree.")
self_dim = self.parent().n self_dim = self.parent().n
indexes = list(range(self_dim+1)) indexes = list(range(self_dim+1))
apl = SimplicialAlgebraplN(dest_dim) apl = SimplicialAlgebraplN(dest_dim)
@ -457,13 +493,15 @@ class SimplicialAplN(AplN, UniqueRepresentation):
y_prod = deepcopy(y_gens) y_prod = deepcopy(y_gens)
del y_prod[i] del y_prod[i]
y_prod = prod(y_prod) y_prod = prod(y_prod)
graded_part += ((-1)**i)*t*y_prod#((-1)**(simplex_dim+i))*t*y_prod # ((-1)**(simplex_dim+i))*t*y_prod
graded_part += ((-1)**i)*t*y_prod
terms = self.dict() terms = self.dict()
coeff_in_t = apl(0) coeff_in_t = apl(0)
for exp in terms.keys(): for exp in terms.keys():
coef = terms[exp] coef = terms[exp]
ts_exp = exp[:self_dim+1] ts_exp = exp[:self_dim+1]
coeff_in_t += coef*prod(list(map(lambda t, e: t**e, t_gens, ts_exp))) coeff_in_t += coef * \
prod(list(map(lambda t, e: t**e, t_gens, ts_exp)))
return coeff_in_t*graded_part return coeff_in_t*graded_part
def _get_primitive_basis_of_a_monomial(self, monomial): def _get_primitive_basis_of_a_monomial(self, monomial):
@ -521,7 +559,8 @@ class SimplicialAplN(AplN, UniqueRepresentation):
diff = b.differential().reduce() diff = b.differential().reduce()
if diff: # as we want a basis, we don't consider the coeffient of the differential if diff: # as we want a basis, we don't consider the coeffient of the differential
for monomial in diff.dict().keys(): for monomial in diff.dict().keys():
term = self._get_term(1, monomial, self.parent().gens()) term = self._get_term(
1, monomial, self.parent().gens())
differential_basis.append(term) differential_basis.append(term)
differential_basis = list(set(differential_basis)) differential_basis = list(set(differential_basis))
differential_basis.sort(reverse=False) differential_basis.sort(reverse=False)
@ -560,7 +599,8 @@ class SimplicialAplN(AplN, UniqueRepresentation):
monomials = list(diff_primitive.dict().keys()) monomials = list(diff_primitive.dict().keys())
for i in range(nrows): for i in range(nrows):
diff_basis_element = differential_basis[i] diff_basis_element = differential_basis[i]
term = list(diff_basis_element.dict().keys())[0] # there is only one monomial term = list(diff_basis_element.dict().keys())[
0] # there is only one monomial
if term in monomials: if term in monomials:
M[i, j] = diff_primitive.dict()[term] M[i, j] = diff_primitive.dict()[term]
return M return M
@ -574,6 +614,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
sol = Mdif.solve_right(v) sol = Mdif.solve_right(v)
return sum(map(lambda x, y: x*y, sol, primitive_basis)) return sum(map(lambda x, y: x*y, sol, primitive_basis))
def SimplicialAlgebraplN(n): def SimplicialAlgebraplN(n):
""" """
Returns the graded commutative differential cochain algebra (Apl)_n as part of Returns the graded commutative differential cochain algebra (Apl)_n as part of
@ -590,7 +631,8 @@ def SimplicialAlgebraplN(n):
ys = ['y'+str(t) for t in range(n+1)] ys = ['y'+str(t) for t in range(n+1)]
degrees = tuple((n+1)*[(0, 2)])+tuple((n+1)*[(1, 2)]) degrees = tuple((n+1)*[(0, 2)])+tuple((n+1)*[(1, 2)])
gca = GradedCommutativeAlgebra(QQ, names=ts+ys, degrees=degrees) gca = GradedCommutativeAlgebra(QQ, names=ts+ys, degrees=degrees)
differentials = {gca.gens_dict()[ts[i]]:gca.gens_dict()[ys[i]] for i in range(n+1)} differentials = {gca.gens_dict()[ts[i]]: gca.gens_dict()[
ys[i]] for i in range(n+1)}
return SimplicialAplN(gca, differentials) return SimplicialAplN(gca, differentials)
@ -710,16 +752,19 @@ class AlgebraAplK(UniqueRepresentation, Parent):
max_dim = dim max_dim = dim
apl = SimplicialAlgebraplN(dim) apl = SimplicialAlgebraplN(dim)
if dim > 0: if dim > 0:
values[k] = ((-1) ** ((dim * (dim-1)) // 2)) * apl.integrand(cochain[k]) values[k] = ((-1) ** ((dim * (dim-1)) // 2)) * \
apl.integrand(cochain[k])
else: else:
values[k] = apl(cochain[k]) values[k] = apl(cochain[k])
# second, we propagate the simplicial information # second, we propagate the simplicial information
simplicial_structure = {} simplicial_structure = {}
for n in reversed(range(max_dim+1)): for n in reversed(range(max_dim+1)):
keys = [k for k in values.keys() if len(k) == n+1] # keys of the n-simplices keys = [k for k in values.keys() if len(
k) == n+1] # keys of the n-simplices
for k in keys: for k in keys:
simplicial_structure[k] = values[k] + self._propagate(cochain, k) simplicial_structure[k] = values[k] + \
self._propagate(cochain, k)
# print(simplicial_structure) # print(simplicial_structure)
return AlgebraAplK.Element(self, simplicial_structure) return AlgebraAplK.Element(self, simplicial_structure)
@ -734,13 +779,16 @@ class AlgebraAplK(UniqueRepresentation, Parent):
for n in reversed(range(dim)): for n in reversed(range(dim)):
faces = self._faces_of_length(simplex, n+1) faces = self._faces_of_length(simplex, n+1)
apl = SimplicialAlgebraplN(n) apl = SimplicialAlgebraplN(n)
pol = apl(prod(apl.gens()[n+2:])) # we propagate the polynomial (y_1...y_n) # we propagate the polynomial (y_1...y_n)
pol = apl(prod(apl.gens()[n+2:]))
for f in faces: for f in faces:
if f in cochain.keys(): if f in cochain.keys():
value = cochain[f] value = cochain[f]
face_indexes = [simplex.index(i) for i in f] face_indexes = [simplex.index(i) for i in f]
#print("dim: ",n," pol: ",pol," face_idx: ",face_indexes," dim: ", n) #print("dim: ",n," pol: ",pol," face_idx: ",face_indexes," dim: ", n)
propagation += value*((-1) ** ((n * (n-1)) // 2)) * factorial(n) * pol.propagate(face_indexes, dim) propagation += value * \
((-1) ** ((n * (n-1)) // 2)) * factorial(n) * \
pol.propagate(face_indexes, dim)
return propagation return propagation
def cohomology_gens(self, degree): def cohomology_gens(self, degree):
@ -757,7 +805,8 @@ class AlgebraAplK(UniqueRepresentation, Parent):
def cohomology_group(self, n): def cohomology_group(self, n):
chainComplex = self.K.chain_complex(base_ring=QQ) chainComplex = self.K.chain_complex(base_ring=QQ)
cochainComplex = chainComplex.dual() cochainComplex = chainComplex.dual()
Hn = cochainComplex.differential(n).right_kernel()/cochainComplex.differential(n-1).column_space() Hn = cochainComplex.differential(n).right_kernel(
)/cochainComplex.differential(n-1).column_space()
return Hn return Hn
def cochain_to_vector(self, cochain, dim): def cochain_to_vector(self, cochain, dim):
@ -851,6 +900,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
""" """
Element class of the simplicial commutative differential algebra (Apl)n. Element class of the simplicial commutative differential algebra (Apl)n.
""" """
def __init__(self, parent, values): def __init__(self, parent, values):
Element.__init__(self, parent) Element.__init__(self, parent)
self.elements = self._reduce(values) self.elements = self._reduce(values)
@ -869,7 +919,6 @@ class AlgebraAplK(UniqueRepresentation, Parent):
""" """
return self.parent().dimension() return self.parent().dimension()
def _add_(self, other): def _add_(self, other):
""" """
Addition operation Addition operation
@ -916,7 +965,6 @@ class AlgebraAplK(UniqueRepresentation, Parent):
newValues[k] = self.elements[k]**n newValues[k] = self.elements[k]**n
return C(self.parent(), newValues) return C(self.parent(), newValues)
def _richcmp_(self, other, op): def _richcmp_(self, other, op):
""" """
Comparison operations. Only implemented equality operations (EQ and NE) Comparison operations. Only implemented equality operations (EQ and NE)
@ -931,7 +979,8 @@ class AlgebraAplK(UniqueRepresentation, Parent):
elif(op == op_NE): elif(op == op_NE):
return not self._richcmp_(other, op_EQ) return not self._richcmp_(other, op_EQ)
else: else:
raise NotImplementedError("operation not implemented for this element class") raise NotImplementedError(
"operation not implemented for this element class")
def _reduce(self, values): def _reduce(self, values):
""" """
@ -1044,7 +1093,8 @@ class AlgebraAplK(UniqueRepresentation, Parent):
for k in self.elements.keys(): for k in self.elements.keys():
dim = len(k)-1 dim = len(k)-1
# the sign is due to stoke's theorem # the sign is due to stoke's theorem
cochain[k] = ((-1) ** ((dim * (dim-1)) // 2)) * self.elements[k].integral() cochain[k] = ((-1) ** ((dim * (dim-1)) // 2)) * \
self.elements[k].integral()
return cochain return cochain
def _face_basis(self, basis, face_idx): def _face_basis(self, basis, face_idx):
@ -1054,7 +1104,8 @@ class AlgebraAplK(UniqueRepresentation, Parent):
if face_pol: if face_pol:
for monomial in face_pol.dict().keys(): for monomial in face_pol.dict().keys():
# remove coefficients # remove coefficients
term = face_pol._get_term(1, monomial, face_pol.parent().gens()) term = face_pol._get_term(
1, monomial, face_pol.parent().gens())
face_basis.append(term) face_basis.append(term)
face_basis = list(set(face_basis)) face_basis = list(set(face_basis))
face_basis.sort(reverse=False) face_basis.sort(reverse=False)
@ -1072,16 +1123,20 @@ class AlgebraAplK(UniqueRepresentation, Parent):
primitive_basis[simplex.tuple()] = [] primitive_basis[simplex.tuple()] = []
# add primitive elements related to the assigned polynomial # add primitive elements related to the assigned polynomial
pol = self.elements[simplex.tuple()] pol = self.elements[simplex.tuple()]
primitive_basis[simplex.tuple()] += pol._get_primitive_basis() primitive_basis[simplex.tuple(
primitive_basis[simplex.tuple()] = list(set(primitive_basis[simplex.tuple()])) )] += pol._get_primitive_basis()
primitive_basis[simplex.tuple()] = list(
set(primitive_basis[simplex.tuple()]))
primitive_basis[simplex.tuple()].sort(reverse=False) primitive_basis[simplex.tuple()].sort(reverse=False)
# propagate the primitive basis through its faces # propagate the primitive basis through its faces
for f in range(n+1): for f in range(n+1):
simplex_face = S.face(simplex, f).tuple() simplex_face = S.face(simplex, f).tuple()
if simplex_face not in primitive_basis.keys(): if simplex_face not in primitive_basis.keys():
primitive_basis[simplex_face] = [] primitive_basis[simplex_face] = []
primitive_basis[simplex_face] += self._face_basis(primitive_basis[simplex.tuple()], f) primitive_basis[simplex_face] += self._face_basis(
primitive_basis[simplex_face] = list(set(primitive_basis[simplex_face])) primitive_basis[simplex.tuple()], f)
primitive_basis[simplex_face] = list(
set(primitive_basis[simplex_face]))
primitive_basis[simplex_face].sort(reverse=False) primitive_basis[simplex_face].sort(reverse=False)
return primitive_basis return primitive_basis
@ -1092,7 +1147,8 @@ class AlgebraAplK(UniqueRepresentation, Parent):
if b_diff: if b_diff:
for monomial in b_diff.dict().keys(): for monomial in b_diff.dict().keys():
# remove coefficients # remove coefficients
term = b_diff._get_term(1, monomial, b_diff.parent().gens()) term = b_diff._get_term(
1, monomial, b_diff.parent().gens())
diff_basis.append(term) diff_basis.append(term)
diff_basis = list(set(diff_basis)) diff_basis = list(set(diff_basis))
diff_basis.sort(reverse=False) diff_basis.sort(reverse=False)
@ -1106,7 +1162,8 @@ class AlgebraAplK(UniqueRepresentation, Parent):
for n in reversed(range(min_dim, dim+1)): for n in reversed(range(min_dim, dim+1)):
for simplex in S._n_cells_sorted(n): for simplex in S._n_cells_sorted(n):
prim_diff_basis = primitive_basis[simplex.tuple()] prim_diff_basis = primitive_basis[simplex.tuple()]
differential_basis[simplex.tuple()] = self._diff_basis(prim_diff_basis) differential_basis[simplex.tuple()] = self._diff_basis(
prim_diff_basis)
return differential_basis return differential_basis
def _get_differential_matrix(self, p_basis, d_basis): def _get_differential_matrix(self, p_basis, d_basis):
@ -1130,10 +1187,13 @@ class AlgebraAplK(UniqueRepresentation, Parent):
dif_p = p.differential().reduce() dif_p = p.differential().reduce()
dic = dif_p.dict() dic = dif_p.dict()
for monomial in dic.keys(): for monomial in dic.keys():
term = dif_p._get_term(1, monomial, dif_p.parent().gens()) term = dif_p._get_term(
1, monomial, dif_p.parent().gens())
if term in differentials: if term in differentials:
row_index = differentials.index(term) row_index = differentials.index(
M[row_offset + row_index, col_index] = dic[monomial] term)
M[row_offset + row_index,
col_index] = dic[monomial]
col_index += 1 col_index += 1
row_offset += len(differentials) row_offset += len(differentials)
elif primitives: elif primitives:
@ -1159,7 +1219,8 @@ class AlgebraAplK(UniqueRepresentation, Parent):
if pol and differentials: if pol and differentials:
dic = pol.dict() dic = pol.dict()
for monomial in dic.keys(): for monomial in dic.keys():
term = pol._get_term(1, monomial, pol.parent().gens()) term = pol._get_term(
1, monomial, pol.parent().gens())
if term in differentials: if term in differentials:
v_index = differentials.index(term) v_index = differentials.index(term)
v[offset + v_index] = dic[monomial] v[offset + v_index] = dic[monomial]
@ -1197,14 +1258,14 @@ class AlgebraAplK(UniqueRepresentation, Parent):
dic = face_term.dict() dic = face_term.dict()
i = primitives.index(term) i = primitives.index(term)
for monomial in dic: for monomial in dic:
t = face_term._get_term(1, monomial, face_term.parent().gens()) t = face_term._get_term(
1, monomial, face_term.parent().gens())
if t == fb: if t == fb:
coef = dic[monomial] coef = dic[monomial]
row[0, offset_simplex+i] = coef row[0, offset_simplex+i] = coef
M = M.stack(row) M = M.stack(row)
return M[1:] return M[1:]
def _get_face_matrix(self, p_basis): def _get_face_matrix(self, p_basis):
offsets = self._get_offsets_matrix(p_basis) offsets = self._get_offsets_matrix(p_basis)

View File

@ -1,3 +1,30 @@
r"""
<Short one-line summary that ends with no period>
<Paragraph description>
EXAMPLES::
<Lots and lots of examples>
AUTHORS:
- Carlos Alquézar Baeta (2023-02-07): initial version
- Miguel Ángel Marco (2023-02-07): initial version
- Jorge Martín Morales (2023-02-07): initial version
"""
# ****************************************************************************
# Copyright (C) 2023 Carlos Alquézar Baeta <alquezar@unizar.es>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# https://www.gnu.org/licenses/
# ****************************************************************************
def phi_polinomial(pol, model_morphism, A): def phi_polinomial(pol, model_morphism, A):
#pol_keys = pol.dict().keys() #pol_keys = pol.dict().keys()
m_gens = pol.parent().gens() m_gens = pol.parent().gens()
@ -17,6 +44,7 @@ def phi_polinomial(pol, model_morphism, A):
aplkElement += term aplkElement += term
return aplkElement return aplkElement
def get_ker_elements(sullivan_model, model_morphism, A, dim): def get_ker_elements(sullivan_model, model_morphism, A, dim):
# Get the basis of Hm # Get the basis of Hm
hm_basis = sullivan_model.cohomology(dim).basis() hm_basis = sullivan_model.cohomology(dim).basis()
@ -32,7 +60,8 @@ def get_ker_elements(sullivan_model, model_morphism, A, dim):
# get an element of the basis of Hm # get an element of the basis of Hm
# get a representative of a cohomology class in M # get a representative of a cohomology class in M
# get the apl representative for each generator of M^p # get the apl representative for each generator of M^p
apl_correspondence[gen_repr] = phi_polinomial(gen_repr, model_morphism, A) apl_correspondence[gen_repr] = phi_polinomial(
gen_repr, model_morphism, A)
cochain = apl_correspondence[gen_repr].integral() cochain = apl_correspondence[gen_repr].integral()
cochain_correspondence[gen_repr] = cochain cochain_correspondence[gen_repr] = cochain
vcochain = A.cochain_to_vector(cochain, dim) vcochain = A.cochain_to_vector(cochain, dim)
@ -40,16 +69,19 @@ def get_ker_elements(sullivan_model, model_morphism, A, dim):
M[:, i] = Hc_correspondence[gen_repr] M[:, i] = Hc_correspondence[gen_repr]
i += 1 i += 1
kernelGens = M.right_kernel().basis() kernelGens = M.right_kernel().basis()
m_kernel = [sum([a*b for a,b in zip(hm_basis_keys,g)]) for g in kernelGens] m_kernel = [sum([a*b for a, b in zip(hm_basis_keys, g)])
for g in kernelGens]
return m_kernel return m_kernel
else: else:
return [] return []
def convert_to(element, gca): def convert_to(element, gca):
d = element.dict() d = element.dict()
new_e = {tuple(list(k)+[0]): d[k] for k in d.keys()} new_e = {tuple(list(k)+[0]): d[k] for k in d.keys()}
return gca(new_e) return gca(new_e)
def injectivity_step(M, phi, check_dim, names, def injectivity_step(M, phi, check_dim, names,
degrees, differentials, A, index=0, depth=0, max_depth=5): degrees, differentials, A, index=0, depth=0, max_depth=5):
@ -66,11 +98,13 @@ def injectivity_step(M, phi, check_dim, names,
phi_new_gen = {} phi_new_gen = {}
for kerElement in m_kernel: for kerElement in m_kernel:
new_gen = 'y'+str(check_dim-1)+'_'+str(index) new_gen = 'y'+str(check_dim-1)+'_'+str(index)
print(" Proceed to kill", kerElement, " because has associated trivial cohomology class") print(" Proceed to kill", kerElement,
" because has associated trivial cohomology class")
print("Adding generator "+new_gen) print("Adding generator "+new_gen)
new_names = names + [new_gen] new_names = names + [new_gen]
new_degrees = tuple(list(degrees)+[check_dim-1]) new_degrees = tuple(list(degrees)+[check_dim-1])
gca = GradedCommutativeAlgebra(QQ, names=new_names, degrees=new_degrees) gca = GradedCommutativeAlgebra(
QQ, names=new_names, degrees=new_degrees)
gen = gca.gens_dict()[new_gen] gen = gca.gens_dict()[new_gen]
aplkElement = phi_polinomial(kerElement, phi, A) aplkElement = phi_polinomial(kerElement, phi, A)
if aplkElement == A.null_element(): if aplkElement == A.null_element():
@ -78,16 +112,20 @@ def injectivity_step(M, phi, check_dim, names,
else: else:
preimage = aplkElement.solve_primitive() preimage = aplkElement.solve_primitive()
phi_new_gen = {str(gen): preimage} phi_new_gen = {str(gen): preimage}
new_differentials = {convert_to(k,gca):convert_to(differentials[k],gca) for k in differentials.keys()} new_differentials = {convert_to(k, gca): convert_to(
differentials[k], gca) for k in differentials.keys()}
new_differentials.update({gen: convert_to(kerElement, gca)}) new_differentials.update({gen: convert_to(kerElement, gca)})
new_M = gca.cdg_algebra(new_differentials) new_M = gca.cdg_algebra(new_differentials)
new_phi = {k: {s:phi[k][s] for s in phi[k].keys()} for k in phi.keys()} new_phi = {k: {s: phi[k][s]
for s in phi[k].keys()} for k in phi.keys()}
d = new_phi[check_dim-1] d = new_phi[check_dim-1]
d.update(phi_new_gen) d.update(phi_new_gen)
return injectivity_step(new_M, new_phi, check_dim, new_names, return injectivity_step(new_M, new_phi, check_dim, new_names,
new_degrees, new_differentials, A, index=index+1, depth=depth+1, max_depth=max_depth) new_degrees, new_differentials, A, index=index+1, depth=depth+1, max_depth=max_depth)
else: else:
return [new_M, new_phi, new_names, new_degrees, new_differentials, False] return [new_M, new_phi, new_names, new_degrees, new_differentials, False]
def get_unmapped_generators(dim, coho_aplk, coho_gens, correspondence): def get_unmapped_generators(dim, coho_aplk, coho_gens, correspondence):
dimensions = list(correspondence.keys()) dimensions = list(correspondence.keys())
@ -107,20 +145,25 @@ def get_unmapped_generators(dim, coho_aplk, coho_gens, correspondence):
product = gi.cup_product(gj) product = gi.cup_product(gj)
if product == gen or -product == gen: if product == gen or -product == gen:
found = True found = True
i_name = list(gensi.keys())[list(gensi.values()).index(gi)] i_name = list(gensi.keys())[
j_name = list(gensj.keys())[list(gensj.values()).index(gj)] list(gensi.values()).index(gi)]
j_name = list(gensj.keys())[
list(gensj.values()).index(gj)]
if gen_key in unmmaped_elements.keys(): if gen_key in unmmaped_elements.keys():
print("The element ",i_name+"*"+j_name," is already mapped") print("The element ", i_name +
"*"+j_name, " is already mapped")
del unmmaped_elements[gen_key] del unmmaped_elements[gen_key]
break break
return unmmaped_elements return unmmaped_elements
def surjective_step(A, M, phi, dim, names, degrees, differentials, cohomology_correspondence): def surjective_step(A, M, phi, dim, names, degrees, differentials, cohomology_correspondence):
print("Surjectivity at dimension ", dim) print("Surjectivity at dimension ", dim)
coho_aplk = A.get_cohomology_aplk(dim) coho_aplk = A.get_cohomology_aplk(dim)
cohomology_gens = A.cohomology_gens(dim) cohomology_gens = A.cohomology_gens(dim)
g = get_unmapped_generators(dim, coho_aplk, cohomology_gens, cohomology_correspondence) g = get_unmapped_generators(
dim, coho_aplk, cohomology_gens, cohomology_correspondence)
new_names = deepcopy(names) new_names = deepcopy(names)
new_degrees = deepcopy(degrees) new_degrees = deepcopy(degrees)
new_phi = {k: {s: phi[k][s] for s in phi[k].keys()} for k in phi.keys()} new_phi = {k: {s: phi[k][s] for s in phi[k].keys()} for k in phi.keys()}
@ -141,6 +184,7 @@ def surjective_step(A, M, phi, dim, names, degrees, differentials, cohomology_co
new_correspondence[dim] = correspondence_n_map new_correspondence[dim] = correspondence_n_map
return [new_M, new_phi, new_names, new_degrees, new_correspondence] return [new_M, new_phi, new_names, new_degrees, new_correspondence]
def minimal_model(S, max_depth=5, max_dim=5): def minimal_model(S, max_depth=5, max_dim=5):
fundamental_group = S.fundamental_group() fundamental_group = S.fundamental_group()
@ -179,7 +223,8 @@ def minimal_model(S, max_depth=5, max_dim=5):
[M, phi, names, degrees, differentials, limit] = injectivity_step(M, phi, first_dim+1, names, [M, phi, names, degrees, differentials, limit] = injectivity_step(M, phi, first_dim+1, names,
degrees, differentials, A, index=0, depth=0, max_depth=5) degrees, differentials, A, index=0, depth=0, max_depth=5)
if limit: if limit:
print("The algorithm has reach the injectivity depth-limit at dimension ", first_dim) print(
"The algorithm has reach the injectivity depth-limit at dimension ", first_dim)
return [M, phi] return [M, phi]
else: else:
dim = first_dim + 1 dim = first_dim + 1
@ -191,7 +236,8 @@ def minimal_model(S, max_depth=5, max_dim=5):
[M, phi, names, degrees, differentials, limit] = injectivity_step(M, phi, i+1, names, [M, phi, names, degrees, differentials, limit] = injectivity_step(M, phi, i+1, names,
degrees, differentials, A, index=0, depth=0, max_depth=5) degrees, differentials, A, index=0, depth=0, max_depth=5)
if limit: if limit:
print("The algorithm has reach the injectivity depth-limit at dimension", dim) print(
"The algorithm has reach the injectivity depth-limit at dimension", dim)
break break
return [M, phi, cohomology_correspondence] return [M, phi, cohomology_correspondence]