bug in phi_polynomial
This commit is contained in:
parent
8b54d2103f
commit
c88a275df8
203
minimalModel.py
203
minimalModel.py
@ -1,143 +1,96 @@
|
|||||||
def update_cdga(gca, diff_dict={}):
|
def phi_polinomial(pol, model_morphism, A):
|
||||||
|
|
||||||
gens_dict = gca.gens_dict()
|
|
||||||
differentials = {}
|
|
||||||
if diff_dict:
|
|
||||||
for gen_name in diff_dict.keys():
|
|
||||||
gen = gens_dict[gen_name]
|
|
||||||
product_gens = diff_dict[gen_name]
|
|
||||||
gen0 = gens_dict[product_gens[0]]
|
|
||||||
if type(product_gens[1]) == int: # is a power
|
|
||||||
power = product_gens[1]
|
|
||||||
mult = gen0
|
|
||||||
for i in range(1, power):
|
|
||||||
mult *= gen0
|
|
||||||
differentials.update({gen:mult})
|
|
||||||
else:
|
|
||||||
gen1 = gens_dict[product_gens[1]]
|
|
||||||
differentials.update({gen:gen0*gen1})
|
|
||||||
# print("differentials", differentials)
|
|
||||||
return gca.cdg_algebra(differentials)
|
|
||||||
|
|
||||||
|
|
||||||
def has_preimage(M, element):
|
pol_keys = pol.dict().keys()
|
||||||
|
gens = pol.parent().gens()
|
||||||
|
m_gens = [g for g,e in zip(gens,sum([vector(k) for k in pol_keys])) if e]
|
||||||
|
aplkGens = [model_morphism[g.degree()][str(g)] for g in m_gens]
|
||||||
|
aplkElement = A.null_element()
|
||||||
|
for exp in pol.dict().keys():
|
||||||
|
coef = pol.dict()[exp]
|
||||||
|
# To-Do: check if exp and aplkGens are sorted in the same way
|
||||||
|
term = coef*prod([gen**e for gen,e in zip(aplkGens, exp)])
|
||||||
|
aplkElement += term
|
||||||
|
return aplkElement
|
||||||
|
|
||||||
d = M.differential()
|
|
||||||
deg = element.degree()-1
|
def get_ker_elements(sullivan_model, model_morphism, A, dim):
|
||||||
# print("differential of ", element, "degree: ", deg)
|
# Get the basis of Hm
|
||||||
Md = d.differential_matrix(deg)
|
hm_basis = sullivan_model.cohomology(dim).basis()
|
||||||
gens = M.basis(deg)
|
if hm_basis:
|
||||||
try:
|
Hc = A.cohomology_group(dim)
|
||||||
solution = Md.solve_left(vector(QQ,element.basis_coefficients()))
|
apl_correspondence = {}
|
||||||
primitive = sum(map(lambda coef, gen: coef*gen, solution, gens))
|
cochain_correspondence = {}
|
||||||
print(element, " has preimage ", primitive)
|
Hc_correspondence = {}
|
||||||
return True
|
M = zero_matrix(QQ,len(Hc.basis()),len(hm_basis))
|
||||||
except ValueError:
|
i = 0
|
||||||
return False
|
hm_basis_keys = [g.representative() for g in hm_basis.keys()]
|
||||||
|
for gen_repr in hm_basis_keys:
|
||||||
|
# get an element of the basis of Hm
|
||||||
|
# get a representative of a cohomology class in M
|
||||||
|
# get the apl representative for each generator of M^p
|
||||||
|
apl_correspondence[gen_repr] = phi_polinomial(gen_repr, model_morphism, A)
|
||||||
|
cochain = apl_correspondence[gen_repr].integral()
|
||||||
|
cochain_correspondence[gen_repr] = cochain
|
||||||
|
vcochain = A.cochain_to_vector(cochain,dim)
|
||||||
|
Hc_correspondence[gen_repr] = Hc(vcochain)
|
||||||
|
M[:,i] = Hc_correspondence[gen_repr]
|
||||||
|
i+=1
|
||||||
|
kernelGens = M.right_kernel().basis()
|
||||||
|
m_kernel = [sum([a*b for a,b in zip(hm_basis_keys,g)]) for g in kernelGens]
|
||||||
|
return m_kernel
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def convert_to(element, gca):
|
||||||
|
d = element.dict()
|
||||||
|
new_e = {tuple(list(k)+[0]): d[k] for k in d.keys()}
|
||||||
|
return gca(new_e)
|
||||||
|
|
||||||
def injectivity_step(M, phi, check_dim, names,
|
def injectivity_step(M, phi, check_dim, names,
|
||||||
degrees, differentials, 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]
|
||||||
deg = check_dim -1
|
|
||||||
gens = [g for g in M.gens() if g.degree() < check_dim]
|
|
||||||
# gens.sort(reverse=True)
|
|
||||||
gen_products = []
|
|
||||||
for i in range(len(gens)):
|
|
||||||
e0 = gens[i]
|
|
||||||
d = e0.degree()
|
|
||||||
mcd = gcd(d, check_dim)
|
|
||||||
if d%2 == 0 and mcd == d:
|
|
||||||
power = True
|
|
||||||
exp = check_dim // d
|
|
||||||
mult = e0
|
|
||||||
for j in range(1,exp-1):
|
|
||||||
mult *= e0
|
|
||||||
gen_products.append([e0, mult, power, exp])
|
|
||||||
for j in range(i+1,len(gens)):
|
|
||||||
power = False
|
|
||||||
e1 = gens[j]
|
|
||||||
if e0.degree() + e1.degree() == check_dim:
|
|
||||||
gen_products.append([e0, e1, power])
|
|
||||||
# print("products at dim ",check_dim,": ", gen_products)
|
|
||||||
new_M = M
|
new_M = M
|
||||||
new_phi = phi
|
new_phi = phi
|
||||||
new_names = names
|
new_names = names
|
||||||
new_degrees = degrees
|
new_degrees = degrees
|
||||||
new_differentials = differentials
|
new_differentials = differentials
|
||||||
for pair in gen_products:
|
m_kernel = get_ker_elements(M, phi, A, check_dim)
|
||||||
# Looking at the minimal model side
|
if len(m_kernel)>0:
|
||||||
gen0 = pair[0]
|
phi_new_gen = {}
|
||||||
deg_0 = gen0.degree()
|
for kerElement in m_kernel:
|
||||||
gen1 = pair[1]
|
new_gen = 'y'+str(check_dim-1)+'_'+str(index)
|
||||||
deg_1 = gen1.degree()
|
print(" Proceed to kill", kerElement, " because has associated trivial cohomology class")
|
||||||
M_product = gen0*gen1
|
|
||||||
# Looking at the AplK side
|
|
||||||
gen0_name = list(M.gens_dict().keys())[list(M.gens_dict().values()).index(gen0)]
|
|
||||||
aplk_gen0 = phi[deg_0][gen0_name]
|
|
||||||
is_power = pair[2]
|
|
||||||
power = 0
|
|
||||||
if is_power:
|
|
||||||
power = pair[3]
|
|
||||||
aplk_gen1 = aplk_gen0
|
|
||||||
for i in range(1, power):
|
|
||||||
aplk_gen1 *= aplk_gen0
|
|
||||||
else:
|
|
||||||
gen1_name = list(M.gens_dict().keys())[list(M.gens_dict().values()).index(gen1)]
|
|
||||||
aplk_gen1 = phi[deg_1][gen1_name]
|
|
||||||
aplk_product = aplk_gen0*aplk_gen1
|
|
||||||
A = aplk_product.parent()
|
|
||||||
# Check conditions
|
|
||||||
if (M_product == M(0)) and (aplk_product == A.null_element()): # zero element
|
|
||||||
pass
|
|
||||||
elif (M_product == M(0)) and (aplk_product != A.null_element()): #check
|
|
||||||
if aplk_product.is_closed():
|
|
||||||
pass #trivial cohomology class (assuming aplk_product has preimage by differential)
|
|
||||||
else:
|
|
||||||
raise ValueError('zero associated to a non-closed element in AplK')
|
|
||||||
elif (M_product.differential() != 0): # is not closed
|
|
||||||
print("The element ",M_product, " is not closed")
|
|
||||||
pass
|
|
||||||
elif (M_product.differential() == 0) and aplk_product.is_closed() and has_preimage(M, M_product):
|
|
||||||
pass #trivial cohomology class (assuming aplk_product has preimage by differential)
|
|
||||||
elif (M_product.differential() == 0) and aplk_product.is_closed(): #key step because M_product doesn't have preimage
|
|
||||||
new_gen = 'y'+str(deg)+'_'+str(index)
|
|
||||||
if aplk_product != A.null_element():
|
|
||||||
try:
|
|
||||||
preimage = aplk_product.solve_primitive()
|
|
||||||
except ValueError:
|
|
||||||
print(" The element ",M_product, " has non trivial cohomology class. No generator added.")
|
|
||||||
continue # we don't add a new generator because the element has non trivial cohomology class
|
|
||||||
phi_new_gen = {new_gen: preimage}
|
|
||||||
else:
|
|
||||||
phi_new_gen = {new_gen: A.null_element()}
|
|
||||||
print(" Proceed to kill", M_product, " 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)+[deg])
|
new_degrees = tuple(list(degrees)+[check_dim-1])
|
||||||
new_differentials = copy.deepcopy(differentials)
|
|
||||||
if not is_power:
|
|
||||||
new_differentials.update({new_gen: [gen0_name, gen1_name]})
|
|
||||||
else:
|
|
||||||
new_differentials.update({new_gen: [gen0_name, int(power)]})
|
|
||||||
gca = GradedCommutativeAlgebra(QQ, names=new_names, degrees=new_degrees)
|
gca = GradedCommutativeAlgebra(QQ, names=new_names, degrees=new_degrees)
|
||||||
new_M = update_cdga(gca, new_differentials)
|
gen = gca.gens_dict()[new_gen]
|
||||||
new_phi = copy.deepcopy(phi)
|
aplkElement = phi_polinomial(kerElement, phi, A)
|
||||||
d = new_phi[deg]
|
print(aplkElement)
|
||||||
|
print(aplkElement.is_zero())
|
||||||
|
print(aplkElement == A.null_element())
|
||||||
|
if aplkElement == A.null_element():
|
||||||
|
preimage = A.null_element()
|
||||||
|
else:
|
||||||
|
preimage = aplkElement.solve_primitive()
|
||||||
|
phi_new_gen = {str(gen): preimage}
|
||||||
|
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_M = gca.cdg_algebra(new_differentials)
|
||||||
|
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.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, 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:
|
||||||
pass
|
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())
|
||||||
unmmaped_elements = copy.deepcopy(coho_aplk)
|
unmmaped_elements = deepcopy(coho_aplk)
|
||||||
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
|
||||||
@ -167,10 +120,10 @@ def surjective_step(A, M, phi, dim, names, degrees, differentials, cohomology_co
|
|||||||
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 = copy.deepcopy(names)
|
new_names = deepcopy(names)
|
||||||
new_degrees = copy.deepcopy(degrees)
|
new_degrees = deepcopy(degrees)
|
||||||
new_phi = copy.deepcopy(phi)
|
new_phi = {k: {s:phi[k][s] for s in phi[k].keys()} for k in phi.keys()}
|
||||||
new_correspondence = copy.deepcopy(cohomology_correspondence)
|
new_correspondence = deepcopy(cohomology_correspondence)
|
||||||
phi_n_map = {}
|
phi_n_map = {}
|
||||||
correspondence_n_map = {}
|
correspondence_n_map = {}
|
||||||
for gen_key in g.keys():
|
for gen_key in g.keys():
|
||||||
@ -223,7 +176,7 @@ def minimal_model(S, max_depth=5, max_dim=5):
|
|||||||
# 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, 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]
|
||||||
@ -233,7 +186,7 @@ def minimal_model(S, max_depth=5, max_dim=5):
|
|||||||
[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, 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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user