pep8 format
This commit is contained in:
parent
446eceb01b
commit
f6e0cece0b
341
aplK.py
341
aplK.py
@ -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
|
||||||
@ -77,14 +105,15 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
|||||||
degrees = set([k[0] for k in self.homogeneous_parts()])
|
degrees = set([k[0] for k in self.homogeneous_parts()])
|
||||||
return max(degrees)
|
return max(degrees)
|
||||||
|
|
||||||
def homogeneous_part(self,degree):
|
def homogeneous_part(self, degree):
|
||||||
"""
|
"""
|
||||||
Returns the homogeneous part of the element for a given degree.
|
Returns the homogeneous part of the element for a given degree.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
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)
|
||||||
@ -139,15 +168,15 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
|||||||
apl = self.parent()
|
apl = self.parent()
|
||||||
pol = self._integrable_part()
|
pol = self._integrable_part()
|
||||||
result = 0
|
result = 0
|
||||||
for k in pol.dict().keys(): # k is a monomial
|
for k in pol.dict().keys(): # k is a monomial
|
||||||
numerator = 1
|
numerator = 1
|
||||||
denominator = apl.n
|
denominator = apl.n
|
||||||
for e in k: # e is an exponents
|
for e in k: # e is an exponents
|
||||||
numerator *= factorial(e)
|
numerator *= factorial(e)
|
||||||
denominator += e
|
denominator += e
|
||||||
coef = pol.dict()[k]
|
coef = pol.dict()[k]
|
||||||
result += coef*numerator/factorial(denominator)
|
result += coef*numerator/factorial(denominator)
|
||||||
#return ((-1) ** ((apl.n*(apl.n-1)) // 2)) * result
|
# return ((-1) ** ((apl.n*(apl.n-1)) // 2)) * result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _get_term(self, coef, exp, gens):
|
def _get_term(self, coef, exp, gens):
|
||||||
@ -181,8 +210,8 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
|||||||
terms = {}
|
terms = {}
|
||||||
pol = self.dict()
|
pol = self.dict()
|
||||||
for exp in pol.keys():
|
for exp in pol.keys():
|
||||||
key = self._get_term(1, exp,ys_only_gens)
|
key = self._get_term(1, exp, ys_only_gens)
|
||||||
coef = self._get_term(pol[exp],exp,ts_only_gens)
|
coef = self._get_term(pol[exp], exp, ts_only_gens)
|
||||||
if key not in terms.keys():
|
if key not in terms.keys():
|
||||||
terms[key] = coef
|
terms[key] = coef
|
||||||
else:
|
else:
|
||||||
@ -233,8 +262,9 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
|||||||
exp = list(monomial.dict().keys())[0]
|
exp = list(monomial.dict().keys())[0]
|
||||||
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
|
||||||
@ -270,7 +300,7 @@ class AplN(DifferentialGCAlgebra_multigraded, UniqueRepresentation):
|
|||||||
OUTPUT::
|
OUTPUT::
|
||||||
- A polynomial
|
- A polynomial
|
||||||
"""
|
"""
|
||||||
if self.differential()!=0 :
|
if self.differential() != 0:
|
||||||
raise ValueError("This polynomial is not closed.")
|
raise ValueError("This polynomial is not closed.")
|
||||||
w = self._leading_primitive()
|
w = self._leading_primitive()
|
||||||
theta = self - w.differential()
|
theta = self - w.differential()
|
||||||
@ -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``
|
||||||
@ -288,24 +319,26 @@ def AlgebraPL(n):
|
|||||||
- ``n`` -- A non-negative integer corresponding to the number of generators of degree 0.
|
- ``n`` -- A non-negative integer corresponding to the number of generators of degree 0.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (n<0):
|
if (n < 0):
|
||||||
raise ValueError('`n` must be a non-negative integer')
|
raise ValueError('`n` must be a non-negative integer')
|
||||||
ts = ['t'+str(t) for t in range(n+1)]
|
ts = ['t'+str(t) for t in range(n+1)]
|
||||||
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()[
|
||||||
return AplN(gca,differentials)
|
ys[i]] for i in range(n+1)}
|
||||||
|
return AplN(gca, differentials)
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
# TEST
|
# TEST
|
||||||
# print("Test AlgebraPL")
|
# print("Test AlgebraPL")
|
||||||
#A = AlgebraPL(5)
|
#A = AlgebraPL(5)
|
||||||
#A.inject_variables()
|
# A.inject_variables()
|
||||||
#p = t0**2 + t1 + y3 + y1*y2
|
#p = t0**2 + t1 + y3 + y1*y2
|
||||||
#q = p.differential()
|
#q = p.differential()
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
|
|
||||||
class SimplicialAplN(AplN, UniqueRepresentation):
|
class SimplicialAplN(AplN, UniqueRepresentation):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -328,7 +361,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
Element class of the simplicial commutative differential algebra (Apl)n.
|
Element class of the simplicial commutative differential algebra (Apl)n.
|
||||||
"""
|
"""
|
||||||
@cached_method
|
@cached_method
|
||||||
def face_morphism(self,i):
|
def face_morphism(self, i):
|
||||||
""""
|
""""
|
||||||
|
|
||||||
Returns the morphism face 'i' of self
|
Returns the morphism face 'i' of self
|
||||||
@ -342,7 +375,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
- A morphism of cochain algebras
|
- A morphism of cochain algebras
|
||||||
"""
|
"""
|
||||||
n = self.parent().n
|
n = self.parent().n
|
||||||
if(n==0):
|
if(n == 0):
|
||||||
return 0
|
return 0
|
||||||
domain = self.parent()
|
domain = self.parent()
|
||||||
codomain = SimplicialAlgebraplN(n-1)
|
codomain = SimplicialAlgebraplN(n-1)
|
||||||
@ -350,19 +383,19 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
yImages = []
|
yImages = []
|
||||||
n = len(domain.gens())//2
|
n = len(domain.gens())//2
|
||||||
for k in range(n):
|
for k in range(n):
|
||||||
if(k<i):
|
if(k < i):
|
||||||
tImages.append(codomain.gens()[k])
|
tImages.append(codomain.gens()[k])
|
||||||
yImages.append(codomain.gens()[n-1+k])
|
yImages.append(codomain.gens()[n-1+k])
|
||||||
elif(k==i):
|
elif(k == i):
|
||||||
tImages.append(0)
|
tImages.append(0)
|
||||||
yImages.append(0)
|
yImages.append(0)
|
||||||
elif(k>i):
|
elif(k > i):
|
||||||
tImages.append(codomain.gens()[k-1])
|
tImages.append(codomain.gens()[k-1])
|
||||||
yImages.append(codomain.gens()[n+k-2])
|
yImages.append(codomain.gens()[n+k-2])
|
||||||
images = tImages+yImages
|
images = tImages+yImages
|
||||||
return domain.hom(codomain=codomain,im_gens=images)
|
return domain.hom(codomain=codomain, im_gens=images)
|
||||||
|
|
||||||
def face(self,i):
|
def face(self, i):
|
||||||
""""
|
""""
|
||||||
|
|
||||||
Returns the face 'i' of self
|
Returns the face 'i' of self
|
||||||
@ -379,7 +412,7 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
return self.face_morphism(i)(self)
|
return self.face_morphism(i)(self)
|
||||||
|
|
||||||
@cached_method
|
@cached_method
|
||||||
def degeneration_morphism(self,j):
|
def degeneration_morphism(self, j):
|
||||||
""""
|
""""
|
||||||
|
|
||||||
Returns the morphism degeneration 'j' of self
|
Returns the morphism degeneration 'j' of self
|
||||||
@ -394,10 +427,11 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
n = self.parent().n
|
n = self.parent().n
|
||||||
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")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
@ -405,19 +439,20 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
yImages = []
|
yImages = []
|
||||||
n = len(domain.gens())//2
|
n = len(domain.gens())//2
|
||||||
for k in range(n):
|
for k in range(n):
|
||||||
if(k<j):
|
if(k < j):
|
||||||
tImages.append(codomain.gens()[k])
|
tImages.append(codomain.gens()[k])
|
||||||
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()[
|
||||||
elif (k>j):
|
n+1+k]+codomain.gens()[n+1+k+1])
|
||||||
|
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])
|
||||||
images = tImages+yImages
|
images = tImages+yImages
|
||||||
return domain.hom(codomain=codomain,im_gens=images)
|
return domain.hom(codomain=codomain, im_gens=images)
|
||||||
|
|
||||||
def degeneration(self,j):
|
def degeneration(self, j):
|
||||||
""""
|
""""
|
||||||
|
|
||||||
Returns the degeneration 'j' of self
|
Returns the degeneration 'j' of self
|
||||||
@ -444,8 +479,9 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
t1^2*t2*y0*y1 + t2^3*y0*y1 - t1^3*y0*y2 - t1*t2^2*y0*y2 + t0*t1^2*y1*y2 + t0*t2^2*y1*y2
|
t1^2*t2*y0*y1 + t2^3*y0*y1 - t1^3*y0*y2 - t1*t2^2*y0*y2 + t0*t1^2*y1*y2 + t0*t2^2*y1*y2
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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):
|
||||||
@ -519,9 +557,10 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
differential_basis = []
|
differential_basis = []
|
||||||
for b in primitive_basis:
|
for b in primitive_basis:
|
||||||
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)
|
||||||
@ -536,10 +575,10 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
#dic = p.dict()
|
#dic = p.dict()
|
||||||
#terms = [p_reduced.parent()({t: dic[t]}) for t in dic.keys()]
|
#terms = [p_reduced.parent()({t: dic[t]}) for t in dic.keys()]
|
||||||
monomials = list(p_reduced.dict().keys())
|
monomials = list(p_reduced.dict().keys())
|
||||||
v = vector(QQ,len(diff_basis)*[0])
|
v = vector(QQ, len(diff_basis)*[0])
|
||||||
for i in range(len(diff_basis)):
|
for i in range(len(diff_basis)):
|
||||||
t = diff_basis[i]
|
t = diff_basis[i]
|
||||||
term = list(t.dict().keys())[0] # there is only one monomial
|
term = list(t.dict().keys())[0] # there is only one monomial
|
||||||
if term in monomials:
|
if term in monomials:
|
||||||
v[i] = p_reduced.dict()[term]
|
v[i] = p_reduced.dict()[term]
|
||||||
return v
|
return v
|
||||||
@ -560,9 +599,10 @@ 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
|
||||||
|
|
||||||
def solve_primitive(self):
|
def solve_primitive(self):
|
||||||
@ -572,7 +612,8 @@ class SimplicialAplN(AplN, UniqueRepresentation):
|
|||||||
v = p._get_coordinate_vector_differential(diff_basis)
|
v = p._get_coordinate_vector_differential(diff_basis)
|
||||||
Mdif = p._differential_matrix(primitive_basis, diff_basis)
|
Mdif = p._differential_matrix(primitive_basis, diff_basis)
|
||||||
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):
|
||||||
"""
|
"""
|
||||||
@ -584,14 +625,15 @@ def SimplicialAlgebraplN(n):
|
|||||||
- ``n`` -- A non-negative integer corresponding to the number of generators of degree 0.
|
- ``n`` -- A non-negative integer corresponding to the number of generators of degree 0.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if (n<0):
|
if (n < 0):
|
||||||
raise ValueError('`n` must be a non-negative integer')
|
raise ValueError('`n` must be a non-negative integer')
|
||||||
ts = ['t'+str(t) for t in range(n+1)]
|
ts = ['t'+str(t) for t in range(n+1)]
|
||||||
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()[
|
||||||
return SimplicialAplN(gca,differentials)
|
ys[i]] for i in range(n+1)}
|
||||||
|
return SimplicialAplN(gca, differentials)
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
@ -623,7 +665,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,simplicial_complex, category=None):
|
def __init__(self, simplicial_complex, category=None):
|
||||||
"""
|
"""
|
||||||
The constructor of Apl(K)
|
The constructor of Apl(K)
|
||||||
|
|
||||||
@ -633,7 +675,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
"""
|
"""
|
||||||
self.K = simplicial_complex
|
self.K = simplicial_complex
|
||||||
self.n = simplicial_complex.dimension()
|
self.n = simplicial_complex.dimension()
|
||||||
Parent.__init__(self,category=category)
|
Parent.__init__(self, category=category)
|
||||||
f = MorphismFromQQToAplK(self)
|
f = MorphismFromQQToAplK(self)
|
||||||
self.register_coercion(f)
|
self.register_coercion(f)
|
||||||
|
|
||||||
@ -643,11 +685,11 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
"""
|
"""
|
||||||
return "The graded commutative differential cochain algebra Apl(K) of %s" % self.K
|
return "The graded commutative differential cochain algebra Apl(K) of %s" % self.K
|
||||||
|
|
||||||
def _element_constructor_(self,values):
|
def _element_constructor_(self, values):
|
||||||
"""
|
"""
|
||||||
The constructor of an element of this class
|
The constructor of an element of this class
|
||||||
"""
|
"""
|
||||||
return self.element_class(self,values)
|
return self.element_class(self, values)
|
||||||
|
|
||||||
def dimension(self):
|
def dimension(self):
|
||||||
"""
|
"""
|
||||||
@ -661,7 +703,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
"""
|
"""
|
||||||
return self.K
|
return self.K
|
||||||
|
|
||||||
def _n_cells_sorted(self,n):
|
def _n_cells_sorted(self, n):
|
||||||
"""
|
"""
|
||||||
Returns all simplices of dimension 'n', as a sorted list.
|
Returns all simplices of dimension 'n', as a sorted list.
|
||||||
"""
|
"""
|
||||||
@ -681,9 +723,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
for i in range(self.K.dimension()+1):
|
for i in range(self.K.dimension()+1):
|
||||||
s = SimplicialAlgebraplN(i)
|
s = SimplicialAlgebraplN(i)
|
||||||
for f in self.K._n_cells_sorted(i):
|
for f in self.K._n_cells_sorted(i):
|
||||||
values[tuple(f)]=s(0)
|
values[tuple(f)] = s(0)
|
||||||
return self._element_constructor_(values)
|
return self._element_constructor_(values)
|
||||||
|
|
||||||
def one(self):
|
def one(self):
|
||||||
"""
|
"""
|
||||||
Returns the one element of the algebra
|
Returns the one element of the algebra
|
||||||
@ -692,9 +734,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
for i in range(self.K.dimension()+1):
|
for i in range(self.K.dimension()+1):
|
||||||
s = SimplicialAlgebraplN(i)
|
s = SimplicialAlgebraplN(i)
|
||||||
for f in self.K._n_cells_sorted(i):
|
for f in self.K._n_cells_sorted(i):
|
||||||
values[tuple(f)]=s(1)
|
values[tuple(f)] = s(1)
|
||||||
return self._element_constructor_(values)
|
return self._element_constructor_(values)
|
||||||
|
|
||||||
null_element = zero
|
null_element = zero
|
||||||
|
|
||||||
def lift_cochain(self, cochain):
|
def lift_cochain(self, cochain):
|
||||||
@ -709,19 +751,22 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
if dim > max_dim:
|
if dim > max_dim:
|
||||||
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] + \
|
||||||
#print(simplicial_structure)
|
self._propagate(cochain, k)
|
||||||
return AlgebraAplK.Element(self,simplicial_structure)
|
# print(simplicial_structure)
|
||||||
|
return AlgebraAplK.Element(self, simplicial_structure)
|
||||||
|
|
||||||
def _propagate(self, cochain, simplex):
|
def _propagate(self, cochain, simplex):
|
||||||
"""
|
"""
|
||||||
@ -734,16 +779,19 @@ 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):
|
||||||
"""
|
"""
|
||||||
Returns the cohomolosy generators of a given degree
|
Returns the cohomolosy generators of a given 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):
|
||||||
@ -765,8 +814,8 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
Converts a cochain, given as a dictionary, to a vector
|
Converts a cochain, given as a dictionary, to a vector
|
||||||
"""
|
"""
|
||||||
basis = self.K.n_chains(dim, base_ring=QQ, cochains=True).basis()
|
basis = self.K.n_chains(dim, base_ring=QQ, cochains=True).basis()
|
||||||
v = vector(QQ,len(basis)*[0])
|
v = vector(QQ, len(basis)*[0])
|
||||||
i=0
|
i = 0
|
||||||
for simplex in basis.keys():
|
for simplex in basis.keys():
|
||||||
v[i] = cochain[tuple(simplex)]
|
v[i] = cochain[tuple(simplex)]
|
||||||
i = i+1
|
i = i+1
|
||||||
@ -779,11 +828,11 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
cochain = {}
|
cochain = {}
|
||||||
for d in range(self.K.dimension()+1):
|
for d in range(self.K.dimension()+1):
|
||||||
basis = self.K.n_chains(d, base_ring=QQ, cochains=True).basis()
|
basis = self.K.n_chains(d, base_ring=QQ, cochains=True).basis()
|
||||||
if d!=dim:
|
if d != dim:
|
||||||
for simplex in basis.keys():
|
for simplex in basis.keys():
|
||||||
cochain[tuple(simplex)] = 0
|
cochain[tuple(simplex)] = 0
|
||||||
else:
|
else:
|
||||||
i=0
|
i = 0
|
||||||
for simplex in basis.keys():
|
for simplex in basis.keys():
|
||||||
cochain[tuple(simplex)] = v[i]
|
cochain[tuple(simplex)] = v[i]
|
||||||
i = i+1
|
i = i+1
|
||||||
@ -818,11 +867,11 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
for simplex in self.K._n_cells_sorted(n):
|
for simplex in self.K._n_cells_sorted(n):
|
||||||
cochain[simplex.tuple()] = 0
|
cochain[simplex.tuple()] = 0
|
||||||
for i in cycle:
|
for i in cycle:
|
||||||
#print(type(i[0].tuple()))
|
# print(type(i[0].tuple()))
|
||||||
cochain[i[0].tuple()] = i[1]
|
cochain[i[0].tuple()] = i[1]
|
||||||
return cochain
|
return cochain
|
||||||
|
|
||||||
def get_cohomology_aplk(self,degree):
|
def get_cohomology_aplk(self, degree):
|
||||||
"""
|
"""
|
||||||
Returns a set of representative elements of Apl(K), one for each cohomology generator of a given degree
|
Returns a set of representative elements of Apl(K), one for each cohomology generator of a given degree
|
||||||
"""
|
"""
|
||||||
@ -842,7 +891,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
indexes = list(basis.keys())
|
indexes = list(basis.keys())
|
||||||
indexes.sort(reverse=False)
|
indexes.sort(reverse=False)
|
||||||
# print(indexes)
|
# print(indexes)
|
||||||
for n in range(1,len(indexes)):
|
for n in range(1, len(indexes)):
|
||||||
if indexes[n][0] > 0:
|
if indexes[n][0] > 0:
|
||||||
return indexes[n][0]
|
return indexes[n][0]
|
||||||
return -1
|
return -1
|
||||||
@ -851,17 +900,18 @@ 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)
|
||||||
#self.check()
|
# self.check()
|
||||||
|
|
||||||
def _repr_(self):
|
def _repr_(self):
|
||||||
"""
|
"""
|
||||||
Return the base string representation of ``self``.
|
Return the base string representation of ``self``.
|
||||||
"""
|
"""
|
||||||
return str({a:b for a,b in self.elements.items() if not b.is_zero()})
|
return str({a: b for a, b in self.elements.items() if not b.is_zero()})
|
||||||
#return str(self.elements)
|
# return str(self.elements)
|
||||||
|
|
||||||
def dimension(self):
|
def dimension(self):
|
||||||
"""
|
"""
|
||||||
@ -869,42 +919,41 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
"""
|
"""
|
||||||
return self.parent().dimension()
|
return self.parent().dimension()
|
||||||
|
|
||||||
|
def _add_(self, other):
|
||||||
def _add_(self,other):
|
|
||||||
"""
|
"""
|
||||||
Addition operation
|
Addition operation
|
||||||
"""
|
"""
|
||||||
C = self.__class__
|
C = self.__class__
|
||||||
if(self.elements.keys()!=other.elements.keys()):
|
if(self.elements.keys() != other.elements.keys()):
|
||||||
raise ValueError("error: keys do not match")
|
raise ValueError("error: keys do not match")
|
||||||
newValues = {}
|
newValues = {}
|
||||||
for k in self.elements.keys():
|
for k in self.elements.keys():
|
||||||
newValues[k] = self.elements[k]+other.elements[k]
|
newValues[k] = self.elements[k]+other.elements[k]
|
||||||
return C(self.parent(),newValues)
|
return C(self.parent(), newValues)
|
||||||
|
|
||||||
def _sub_(self,other):
|
def _sub_(self, other):
|
||||||
"""
|
"""
|
||||||
Substration operation
|
Substration operation
|
||||||
"""
|
"""
|
||||||
C = self.__class__
|
C = self.__class__
|
||||||
if(self.elements.keys()!=other.elements.keys()):
|
if(self.elements.keys() != other.elements.keys()):
|
||||||
raise ValueError("error: keys do not match")
|
raise ValueError("error: keys do not match")
|
||||||
newValues = {}
|
newValues = {}
|
||||||
for k in self.elements.keys():
|
for k in self.elements.keys():
|
||||||
newValues[k] = self.elements[k]-other.elements[k]
|
newValues[k] = self.elements[k]-other.elements[k]
|
||||||
return C(self.parent(),newValues)
|
return C(self.parent(), newValues)
|
||||||
|
|
||||||
def _mul_(self,other):
|
def _mul_(self, other):
|
||||||
"""
|
"""
|
||||||
Multiplication operation
|
Multiplication operation
|
||||||
"""
|
"""
|
||||||
C = self.__class__
|
C = self.__class__
|
||||||
if(self.elements.keys()!=other.elements.keys()):
|
if(self.elements.keys() != other.elements.keys()):
|
||||||
raise ValueError("error: keys do not match")
|
raise ValueError("error: keys do not match")
|
||||||
newValues = {}
|
newValues = {}
|
||||||
for k in self.elements.keys():
|
for k in self.elements.keys():
|
||||||
newValues[k] = self.elements[k]*other.elements[k]
|
newValues[k] = self.elements[k]*other.elements[k]
|
||||||
return C(self.parent(),newValues)
|
return C(self.parent(), newValues)
|
||||||
|
|
||||||
def __pow__(self, n):
|
def __pow__(self, n):
|
||||||
"""
|
"""
|
||||||
@ -914,24 +963,24 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
newValues = {}
|
newValues = {}
|
||||||
for k in self.elements.keys():
|
for k in self.elements.keys():
|
||||||
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)
|
||||||
"""
|
"""
|
||||||
if(op==op_EQ):
|
if(op == op_EQ):
|
||||||
if(self.elements.keys()!=other.elements.keys()):
|
if(self.elements.keys() != other.elements.keys()):
|
||||||
return False
|
return False
|
||||||
for k in self.elements.keys():
|
for k in self.elements.keys():
|
||||||
if(self.elements[k]!=other.elements[k]):
|
if(self.elements[k] != other.elements[k]):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
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):
|
||||||
"""
|
"""
|
||||||
@ -954,11 +1003,11 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
"""
|
"""
|
||||||
S = self.parent().simplicialComplex()
|
S = self.parent().simplicialComplex()
|
||||||
dim = S.dimension()
|
dim = S.dimension()
|
||||||
for n in range(1,dim+1):
|
for n in range(1, dim+1):
|
||||||
#print("Checking dimension " + str(n))
|
#print("Checking dimension " + str(n))
|
||||||
for simplex in S._n_cells_sorted(n):
|
for simplex in S._n_cells_sorted(n):
|
||||||
for f in range(n+1):
|
for f in range(n+1):
|
||||||
sFace = tuple(S.face(simplex,f))
|
sFace = tuple(S.face(simplex, f))
|
||||||
aFace = self.elements[simplex.tuple()].face(f).reduce()
|
aFace = self.elements[simplex.tuple()].face(f).reduce()
|
||||||
#print("face: " + str(f),"simplex: " + str(simplex),"sFace: " + str(self.elements[sFace]), "aFace: " + str(aFace))
|
#print("face: " + str(f),"simplex: " + str(simplex),"sFace: " + str(self.elements[sFace]), "aFace: " + str(aFace))
|
||||||
if(self.elements[sFace] != aFace):
|
if(self.elements[sFace] != aFace):
|
||||||
@ -972,7 +1021,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
newValues = {}
|
newValues = {}
|
||||||
for k in self.elements.keys():
|
for k in self.elements.keys():
|
||||||
newValues[k] = self.elements[k].differential()
|
newValues[k] = self.elements[k].differential()
|
||||||
return C(self.parent(),newValues)
|
return C(self.parent(), newValues)
|
||||||
|
|
||||||
def is_closed(self):
|
def is_closed(self):
|
||||||
"""
|
"""
|
||||||
@ -984,7 +1033,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def homogeneous_part(self,degree):
|
def homogeneous_part(self, degree):
|
||||||
"""
|
"""
|
||||||
Returns the homogeneous component of grade 'degree' of 'self'
|
Returns the homogeneous component of grade 'degree' of 'self'
|
||||||
"""
|
"""
|
||||||
@ -993,7 +1042,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
for k in self.elements.keys():
|
for k in self.elements.keys():
|
||||||
s = SimplicialAlgebraplN(len(k)-1)
|
s = SimplicialAlgebraplN(len(k)-1)
|
||||||
part[k] = s(self.elements[k].homogeneous_part(degree=degree))
|
part[k] = s(self.elements[k].homogeneous_part(degree=degree))
|
||||||
return C(self.parent(),part)
|
return C(self.parent(), part)
|
||||||
|
|
||||||
def homogeneous_parts(self):
|
def homogeneous_parts(self):
|
||||||
"""
|
"""
|
||||||
@ -1040,11 +1089,12 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
Returns the cochain obtained as integration of 'self'
|
Returns the cochain obtained as integration of 'self'
|
||||||
"""
|
"""
|
||||||
cochain = {}
|
cochain = {}
|
||||||
#integration of each polynomial
|
# integration of each polynomial
|
||||||
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):
|
||||||
@ -1053,8 +1103,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
face_pol = b.face(face_idx).reduce()
|
face_pol = b.face(face_idx).reduce()
|
||||||
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)
|
||||||
@ -1066,22 +1117,26 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
S = self.parent().simplicialComplex()
|
S = self.parent().simplicialComplex()
|
||||||
dim = S.dimension()
|
dim = S.dimension()
|
||||||
min_dim = self.degree()
|
min_dim = self.degree()
|
||||||
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):
|
||||||
if simplex.tuple() not in primitive_basis.keys():
|
if simplex.tuple() not in primitive_basis.keys():
|
||||||
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
|
||||||
|
|
||||||
@ -1091,8 +1146,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
b_diff = b.differential().reduce()
|
b_diff = b.differential().reduce()
|
||||||
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)
|
||||||
@ -1103,10 +1159,11 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
S = self.parent().simplicialComplex()
|
S = self.parent().simplicialComplex()
|
||||||
dim = S.dimension()
|
dim = S.dimension()
|
||||||
min_dim = self.degree()
|
min_dim = self.degree()
|
||||||
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):
|
||||||
@ -1118,9 +1175,9 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
M = zero_matrix(QQ, nrows, ncols)
|
M = zero_matrix(QQ, nrows, ncols)
|
||||||
row_offset = 0
|
row_offset = 0
|
||||||
col_index = 0
|
col_index = 0
|
||||||
for n in reversed(range(min_dim-1,dim+1)):
|
for n in reversed(range(min_dim-1, dim+1)):
|
||||||
for simplex in S._n_cells_sorted(n):
|
for simplex in S._n_cells_sorted(n):
|
||||||
# print(simplex.tuple(), row_offset, col_index)
|
# print(simplex.tuple(), row_offset, col_index)
|
||||||
if simplex.tuple() in p_basis.keys():
|
if simplex.tuple() in p_basis.keys():
|
||||||
primitives = p_basis[simplex.tuple()]
|
primitives = p_basis[simplex.tuple()]
|
||||||
if simplex.tuple() in d_basis.keys():
|
if simplex.tuple() in d_basis.keys():
|
||||||
@ -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:
|
||||||
@ -1150,7 +1210,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
S = self.parent().simplicialComplex()
|
S = self.parent().simplicialComplex()
|
||||||
dim = S.dimension()
|
dim = S.dimension()
|
||||||
min_dim = self.degree()
|
min_dim = self.degree()
|
||||||
for n in reversed(range(min_dim,dim+1)):
|
for n in reversed(range(min_dim, dim+1)):
|
||||||
for s in S._n_cells_sorted(n):
|
for s in S._n_cells_sorted(n):
|
||||||
simplex = s.tuple()
|
simplex = s.tuple()
|
||||||
if simplex in d_basis.keys():
|
if simplex in d_basis.keys():
|
||||||
@ -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]
|
||||||
@ -1173,7 +1234,7 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
min_dim = self.degree()
|
min_dim = self.degree()
|
||||||
offset = 0
|
offset = 0
|
||||||
first_simplex = True
|
first_simplex = True
|
||||||
for n in reversed(range(min_dim-1,dim+1)):
|
for n in reversed(range(min_dim-1, dim+1)):
|
||||||
for simplex in S._n_cells_sorted(n):
|
for simplex in S._n_cells_sorted(n):
|
||||||
if simplex.tuple() in p_basis.keys():
|
if simplex.tuple() in p_basis.keys():
|
||||||
primitives = p_basis[simplex.tuple()]
|
primitives = p_basis[simplex.tuple()]
|
||||||
@ -1187,43 +1248,43 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
|
|
||||||
def _get_row_face_matrix(self, primitives, face_idx, face_basis,
|
def _get_row_face_matrix(self, primitives, face_idx, face_basis,
|
||||||
offset_simplex, offset_face, len_row):
|
offset_simplex, offset_face, len_row):
|
||||||
M = zero_matrix(QQ,1, len_row)
|
M = zero_matrix(QQ, 1, len_row)
|
||||||
for fb in face_basis:
|
for fb in face_basis:
|
||||||
fb_idx = face_basis.index(fb)
|
fb_idx = face_basis.index(fb)
|
||||||
row = zero_matrix(QQ,1, len_row)
|
row = zero_matrix(QQ, 1, len_row)
|
||||||
row[0,offset_face+fb_idx] = -1
|
row[0, offset_face+fb_idx] = -1
|
||||||
for term in primitives:
|
for term in primitives:
|
||||||
face_term = term.face(face_idx).reduce()
|
face_term = term.face(face_idx).reduce()
|
||||||
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)
|
||||||
len_row = sum([len(l) for l in p_basis.values()])
|
len_row = sum([len(l) for l in p_basis.values()])
|
||||||
M = zero_matrix(QQ,1, len_row)
|
M = zero_matrix(QQ, 1, len_row)
|
||||||
S = self.parent().simplicialComplex()
|
S = self.parent().simplicialComplex()
|
||||||
dim = S.dimension()
|
dim = S.dimension()
|
||||||
min_dim = self.degree()
|
min_dim = self.degree()
|
||||||
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):
|
||||||
offset_simplex = offsets[simplex.tuple()]
|
offset_simplex = offsets[simplex.tuple()]
|
||||||
primitives = p_basis[simplex.tuple()]
|
primitives = p_basis[simplex.tuple()]
|
||||||
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()
|
||||||
face_primitives = p_basis[simplex_face]
|
face_primitives = p_basis[simplex_face]
|
||||||
offset_face = offsets[simplex_face]
|
offset_face = offsets[simplex_face]
|
||||||
rows = self._get_row_face_matrix(primitives, f, face_primitives,
|
rows = self._get_row_face_matrix(primitives, f, face_primitives,
|
||||||
offset_simplex, offset_face,
|
offset_simplex, offset_face,
|
||||||
len_row)
|
len_row)
|
||||||
M = M.stack(rows)
|
M = M.stack(rows)
|
||||||
return M[1:]
|
return M[1:]
|
||||||
|
|
||||||
@ -1253,14 +1314,14 @@ class AlgebraAplK(UniqueRepresentation, Parent):
|
|||||||
|
|
||||||
def solve_primitive(self):
|
def solve_primitive(self):
|
||||||
p_basis = self._get_primitive_basis()
|
p_basis = self._get_primitive_basis()
|
||||||
d_basis = self._get_differential_basis(p_basis)
|
d_basis = self._get_differential_basis(p_basis)
|
||||||
diff_matrix = self._get_differential_matrix(p_basis, d_basis)
|
diff_matrix = self._get_differential_matrix(p_basis, d_basis)
|
||||||
v_dif = self._get_vector_diff_coordinates(d_basis)
|
v_dif = self._get_vector_diff_coordinates(d_basis)
|
||||||
face_matrix = self._get_face_matrix(p_basis)
|
face_matrix = self._get_face_matrix(p_basis)
|
||||||
nrows = face_matrix.nrows()
|
nrows = face_matrix.nrows()
|
||||||
v = vector(QQ, list(v_dif)+nrows*[0])
|
v = vector(QQ, list(v_dif)+nrows*[0])
|
||||||
M = diff_matrix.stack(face_matrix)
|
M = diff_matrix.stack(face_matrix)
|
||||||
print("Matrix size: ",M.nrows(),M.ncols())
|
print("Matrix size: ", M.nrows(), M.ncols())
|
||||||
sol = M.solve_right(v)
|
sol = M.solve_right(v)
|
||||||
return self._get_solution(sol, p_basis)
|
return self._get_solution(sol, p_basis)
|
||||||
|
|
||||||
@ -1277,6 +1338,6 @@ class MorphismFromQQToAplK(Morphism):
|
|||||||
for d in range(S.dimension()+1):
|
for d in range(S.dimension()+1):
|
||||||
s = SimplicialAlgebraplN(d)
|
s = SimplicialAlgebraplN(d)
|
||||||
for c in S._n_cells_sorted(d):
|
for c in S._n_cells_sorted(d):
|
||||||
params[tuple(c)]=s(x)
|
params[tuple(c)] = s(x)
|
||||||
A = AlgebraAplK(S)
|
A = AlgebraAplK(S)
|
||||||
return AlgebraAplK.Element(A, params)
|
return AlgebraAplK.Element(A, params)
|
||||||
|
|||||||
134
minimalModel.py
134
minimalModel.py
@ -1,8 +1,35 @@
|
|||||||
|
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()
|
||||||
#m_gens = [g for g,e in zip(gens,sum([vector(k) for k in pol_keys])) if e]
|
#m_gens = [g for g,e in zip(gens,sum([vector(k) for k in pol_keys])) if e]
|
||||||
aplkGens = {g:model_morphism[g.degree()][str(g)] for g in m_gens}
|
aplkGens = {g: model_morphism[g.degree()][str(g)] for g in m_gens}
|
||||||
aplkElement = A.null_element()
|
aplkElement = A.null_element()
|
||||||
for exp in pol.dict().keys():
|
for exp in pol.dict().keys():
|
||||||
coef = pol.dict()[exp]
|
coef = pol.dict()[exp]
|
||||||
@ -12,11 +39,12 @@ def phi_polinomial(pol, model_morphism, A):
|
|||||||
e = exp[i]
|
e = exp[i]
|
||||||
if e:
|
if e:
|
||||||
aGen = aplkGens[m_gens[i]]
|
aGen = aplkGens[m_gens[i]]
|
||||||
term *= aGen**e
|
term *= aGen**e
|
||||||
#term = coef*prod([gen^e for (gen,e) in zip(aplkGens, exp)])
|
#term = coef*prod([gen^e for (gen,e) in zip(aplkGens, exp)])
|
||||||
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()
|
||||||
@ -25,34 +53,38 @@ def get_ker_elements(sullivan_model, model_morphism, A, dim):
|
|||||||
apl_correspondence = {}
|
apl_correspondence = {}
|
||||||
cochain_correspondence = {}
|
cochain_correspondence = {}
|
||||||
Hc_correspondence = {}
|
Hc_correspondence = {}
|
||||||
M = zero_matrix(QQ,len(Hc.basis()),len(hm_basis))
|
M = zero_matrix(QQ, len(Hc.basis()), len(hm_basis))
|
||||||
i = 0
|
i = 0
|
||||||
hm_basis_keys = [g.representative() for g in hm_basis.keys()]
|
hm_basis_keys = [g.representative() for g in hm_basis.keys()]
|
||||||
for gen_repr in hm_basis_keys:
|
for gen_repr in hm_basis_keys:
|
||||||
# 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)
|
||||||
Hc_correspondence[gen_repr] = Hc(vcochain)
|
Hc_correspondence[gen_repr] = Hc(vcochain)
|
||||||
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):
|
||||||
|
|
||||||
print("Injectivity at dimension ", check_dim)
|
print("Injectivity at dimension ", check_dim)
|
||||||
if depth > max_depth:
|
if depth > max_depth:
|
||||||
return [M, phi, names, degrees, differentials, True]
|
return [M, phi, names, degrees, differentials, True]
|
||||||
@ -62,15 +94,17 @@ def injectivity_step(M, phi, check_dim, names,
|
|||||||
new_degrees = degrees
|
new_degrees = degrees
|
||||||
new_differentials = differentials
|
new_differentials = differentials
|
||||||
m_kernel = get_ker_elements(M, phi, A, check_dim)
|
m_kernel = get_ker_elements(M, phi, A, check_dim)
|
||||||
if len(m_kernel)>0:
|
if len(m_kernel) > 0:
|
||||||
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())
|
||||||
@ -95,35 +133,40 @@ def get_unmapped_generators(dim, coho_aplk, coho_gens, correspondence):
|
|||||||
for gen_key in coho_gens.keys():
|
for gen_key in coho_gens.keys():
|
||||||
gen = coho_gens[gen_key]
|
gen = coho_gens[gen_key]
|
||||||
found = False
|
found = False
|
||||||
for i in range(1,dim):
|
for i in range(1, dim):
|
||||||
if (not found) and (i in dimensions):
|
if (not found) and (i in dimensions):
|
||||||
for j in range(i,dim):
|
for j in range(i, dim):
|
||||||
if (j in dimensions) and (i+j == dim):
|
if (j in dimensions) and (i+j == dim):
|
||||||
gensi = correspondence[i]
|
gensi = correspondence[i]
|
||||||
gensj = correspondence[j]
|
gensj = correspondence[j]
|
||||||
for gi in gensi.values():
|
for gi in gensi.values():
|
||||||
if not found:
|
if not found:
|
||||||
for gj in gensj.values():
|
for gj in gensj.values():
|
||||||
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()}
|
||||||
new_correspondence = deepcopy(cohomology_correspondence)
|
new_correspondence = deepcopy(cohomology_correspondence)
|
||||||
phi_n_map = {}
|
phi_n_map = {}
|
||||||
correspondence_n_map = {}
|
correspondence_n_map = {}
|
||||||
@ -136,13 +179,14 @@ def surjective_step(A, M, phi, dim, names, degrees, differentials, cohomology_co
|
|||||||
phi_n_map[new_var] = g[gen_key]
|
phi_n_map[new_var] = g[gen_key]
|
||||||
correspondence_n_map[new_var] = cohomology_gens[gen_key]
|
correspondence_n_map[new_var] = cohomology_gens[gen_key]
|
||||||
gca = GradedCommutativeAlgebra(QQ, names=new_names, degrees=new_degrees)
|
gca = GradedCommutativeAlgebra(QQ, names=new_names, degrees=new_degrees)
|
||||||
new_M = gca.cdg_algebra(differentials)
|
new_M = gca.cdg_algebra(differentials)
|
||||||
new_phi[dim] = phi_n_map
|
new_phi[dim] = phi_n_map
|
||||||
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()
|
||||||
if (fundamental_group.order() != 1):
|
if (fundamental_group.order() != 1):
|
||||||
print("Warning: The space is not simply-connected")
|
print("Warning: The space is not simply-connected")
|
||||||
@ -154,9 +198,9 @@ def minimal_model(S, max_depth=5, max_dim=5):
|
|||||||
phi_n_map = {}
|
phi_n_map = {}
|
||||||
correspondence_n_map = {}
|
correspondence_n_map = {}
|
||||||
if first_dim < 0:
|
if first_dim < 0:
|
||||||
return [0,{},{}] # due to the function returns multiple objects
|
return [0, {}, {}] # due to the function returns multiple objects
|
||||||
elif first_dim > max_dim:
|
elif first_dim > max_dim:
|
||||||
return [0,{},{}] # due to the function returns multiple objects
|
return [0, {}, {}] # due to the function returns multiple objects
|
||||||
g = A.get_cohomology_aplk(first_dim)
|
g = A.get_cohomology_aplk(first_dim)
|
||||||
cohomology_gens = A.cohomology_gens(first_dim)
|
cohomology_gens = A.cohomology_gens(first_dim)
|
||||||
names = []
|
names = []
|
||||||
@ -169,29 +213,31 @@ def minimal_model(S, max_depth=5, max_dim=5):
|
|||||||
degrees += [deg]
|
degrees += [deg]
|
||||||
phi_n_map[new_var] = g[gen_key]
|
phi_n_map[new_var] = g[gen_key]
|
||||||
correspondence_n_map[new_var] = cohomology_gens[gen_key]
|
correspondence_n_map[new_var] = cohomology_gens[gen_key]
|
||||||
differentials={}
|
differentials = {}
|
||||||
gca = GradedCommutativeAlgebra(QQ, names=names, degrees=degrees)
|
gca = GradedCommutativeAlgebra(QQ, names=names, degrees=degrees)
|
||||||
M = gca.cdg_algebra(differentials)
|
M = gca.cdg_algebra(differentials)
|
||||||
phi[first_dim] = phi_n_map
|
phi[first_dim] = phi_n_map
|
||||||
cohomology_correspondence[first_dim] = correspondence_n_map
|
cohomology_correspondence[first_dim] = correspondence_n_map
|
||||||
# Now we have an isomorphism in the first non-null cohomology group
|
# Now we have an isomorphism in the first non-null cohomology group
|
||||||
# we check if phi is a monomorphism
|
# we check if phi is a monomorphism
|
||||||
[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
|
||||||
for i in range(dim, max_dim):
|
for i in range(dim, max_dim):
|
||||||
print("phi")
|
print("phi")
|
||||||
print(phi)
|
print(phi)
|
||||||
[M, phi, names, degrees, cohomology_correspondence] = surjective_step(A, M, phi, i, names, degrees,
|
[M, phi, names, degrees, cohomology_correspondence] = surjective_step(A, M, phi, i, names, degrees,
|
||||||
differentials, cohomology_correspondence)
|
differentials, cohomology_correspondence)
|
||||||
[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(
|
||||||
break
|
"The algorithm has reach the injectivity depth-limit at dimension", dim)
|
||||||
|
break
|
||||||
|
|
||||||
return [M, phi, cohomology_correspondence]
|
return [M, phi, cohomology_correspondence]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user