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={}):
|
||||
|
||||
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 phi_polinomial(pol, model_morphism, A):
|
||||
|
||||
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
|
||||
# print("differential of ", element, "degree: ", deg)
|
||||
Md = d.differential_matrix(deg)
|
||||
gens = M.basis(deg)
|
||||
try:
|
||||
solution = Md.solve_left(vector(QQ,element.basis_coefficients()))
|
||||
primitive = sum(map(lambda coef, gen: coef*gen, solution, gens))
|
||||
print(element, " has preimage ", primitive)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def get_ker_elements(sullivan_model, model_morphism, A, dim):
|
||||
# Get the basis of Hm
|
||||
hm_basis = sullivan_model.cohomology(dim).basis()
|
||||
if hm_basis:
|
||||
Hc = A.cohomology_group(dim)
|
||||
apl_correspondence = {}
|
||||
cochain_correspondence = {}
|
||||
Hc_correspondence = {}
|
||||
M = zero_matrix(QQ,len(Hc.basis()),len(hm_basis))
|
||||
i = 0
|
||||
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,
|
||||
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)
|
||||
if depth > max_depth:
|
||||
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_phi = phi
|
||||
new_names = names
|
||||
new_degrees = degrees
|
||||
new_differentials = differentials
|
||||
for pair in gen_products:
|
||||
# Looking at the minimal model side
|
||||
gen0 = pair[0]
|
||||
deg_0 = gen0.degree()
|
||||
gen1 = pair[1]
|
||||
deg_1 = gen1.degree()
|
||||
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")
|
||||
m_kernel = get_ker_elements(M, phi, A, check_dim)
|
||||
if len(m_kernel)>0:
|
||||
phi_new_gen = {}
|
||||
for kerElement in m_kernel:
|
||||
new_gen = 'y'+str(check_dim-1)+'_'+str(index)
|
||||
print(" Proceed to kill", kerElement, " because has associated trivial cohomology class")
|
||||
print("Adding generator "+new_gen)
|
||||
new_names = names + [new_gen]
|
||||
new_degrees = tuple(list(degrees)+[deg])
|
||||
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)]})
|
||||
new_degrees = tuple(list(degrees)+[check_dim-1])
|
||||
gca = GradedCommutativeAlgebra(QQ, names=new_names, degrees=new_degrees)
|
||||
new_M = update_cdga(gca, new_differentials)
|
||||
new_phi = copy.deepcopy(phi)
|
||||
d = new_phi[deg]
|
||||
gen = gca.gens_dict()[new_gen]
|
||||
aplkElement = phi_polinomial(kerElement, phi, A)
|
||||
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)
|
||||
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)
|
||||
else:
|
||||
pass
|
||||
|
||||
return [new_M, new_phi, new_names, new_degrees, new_differentials, False]
|
||||
|
||||
new_degrees, new_differentials, A, index=index+1, depth=depth+1, max_depth=max_depth)
|
||||
else:
|
||||
return [new_M, new_phi, new_names, new_degrees, new_differentials, False]
|
||||
def get_unmapped_generators(dim, coho_aplk, coho_gens, correspondence):
|
||||
|
||||
dimensions = list(correspondence.keys())
|
||||
unmmaped_elements = copy.deepcopy(coho_aplk)
|
||||
unmmaped_elements = deepcopy(coho_aplk)
|
||||
for gen_key in coho_gens.keys():
|
||||
gen = coho_gens[gen_key]
|
||||
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)
|
||||
cohomology_gens = A.cohomology_gens(dim)
|
||||
g = get_unmapped_generators(dim, coho_aplk, cohomology_gens, cohomology_correspondence)
|
||||
new_names = copy.deepcopy(names)
|
||||
new_degrees = copy.deepcopy(degrees)
|
||||
new_phi = copy.deepcopy(phi)
|
||||
new_correspondence = copy.deepcopy(cohomology_correspondence)
|
||||
new_names = deepcopy(names)
|
||||
new_degrees = deepcopy(degrees)
|
||||
new_phi = {k: {s:phi[k][s] for s in phi[k].keys()} for k in phi.keys()}
|
||||
new_correspondence = deepcopy(cohomology_correspondence)
|
||||
phi_n_map = {}
|
||||
correspondence_n_map = {}
|
||||
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
|
||||
# we check if phi is a monomorphism
|
||||
[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:
|
||||
print("The algorithm has reach the injectivity depth-limit at dimension ", first_dim)
|
||||
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,
|
||||
differentials, cohomology_correspondence)
|
||||
[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:
|
||||
print("The algorithm has reach the injectivity depth-limit at dimension", dim)
|
||||
break
|
||||
|
||||
Loading…
Reference in New Issue
Block a user