# Test for zero cup product

asked 2016-05-06 11:50:24 -0500 This post is a wiki. Anyone with karma >750 is welcome to improve it.

How can I check whether the cohomology ring H^*(X) of a simplicial complex X has zero cup product (like, say, for X a wedge of spheres). I have a long list of simplicial complexes, so I need a fully algorithmic approach. I probably should start with X.cohomology_ring(QQ) but I don't know what to do next...

Btw, I am a sage newbie.

edit retag close merge delete

Sort by » oldest newest most voted

The path to proceed should be...

1. Construct the object correspdonding to the wedge of spheres.
2. The call cohomology_ring method.
3. Look at the generators.
4. Take those generators in degree > 0, compute products.
5. If one of the products is non zero, than return False.
6. Else, if the loop does find only zero products, finally return True.

The problem i had was a "minor one", but one that delayed the answer one (more) day. For short, the method cohomology_ring of the constructed wedge of spheres WS works only for a WS which is immutable. The default constructor makes it mutable.

In order to explain (myself) the answer, so that i'll understand it also tomorrow, here are first some examples. This is...

sage: version()
'SageMath version 7.3, Release Date: 2016-08-04'


(1) Let us take a Klein bottle and ask for the cohomology ring over rationals and over the two elements field. The rings will have generators. We compute the relevant products.

K  = simplicial_complexes.KleinBottle()
HK = K.cohomology_ring( QQ )

print "H( K, Q ) has the following generators:"
print HK.gens()    # there are two gen(erator)s
a, b = HK.gens()   # they've got names, a and b
print "We rename them a, b."
print "Their degrees are %s, %s" % ( a.degree(), b.degree() )
print "Then we have for instance b*b = %s" % (b*b)
print "Is b*b zero? %s" % ( (b*b).is_zero() )
print

HK2 = K.cohomology_ring( GF(2) )
print "H( K, GF(2) ) has the following generators:"
print HK2.gens()    # there are FOUR gen(erator)s
print "We rename them a, b, c, d."
a, b, c, d = HK2.gens()   # they've got names, a, b, c, d
print "Their degrees are %s, %s, %s, %s" % ( a.degree(), b.degree(), c.degree(), d.degree() )
print "The values b*b, b*c, c*b, c*c are respectively %s, %s, %s, %s" % ( b*b, b*c, c*b, c*c )
print "Is b*b == 0? %s" % bool( b*b == 0 )
print "Is b*c == d? %s" % bool( b*c == d )
print "Is c*b == d? %s" % bool( c*b == d )
print "Is c*c == d? %s" % bool( c*c == d )


And we get so far (after a %cpaste into the sage interpreter):

H( K, Q ) has the following generators:
(h^{0,0}, h^{1,0})
We rename them a, b.
Their degrees are 0, 1
Then we have for instance b*b = 0
Is b*b zero? True

H( K, GF(2) ) has the following generators:
(h^{0,0}, h^{1,0}, h^{1,1}, h^{2,0})
We rename them a, b, c, d.
Their degrees are 0, 1, 1, 2
The values b*b, b*c, c*b, c*c are respectively 0, h^{2,0}, h^{2,0}, h^{2,0}
Is b*b == 0? True
Is b*c == d? True
Is c*b == d? True
Is c*c == d? True


(2) Let us define a function that computes a wedge of spheres. This is a quick solution, there is no raise in case a bad argument. We expect as argument a tuple of integers > 0.

   def WedgeOfSpheres( spheresTuple ):
"""
return the corresponding wedge of spheres
for dimensionsTuple (1,3,4) we return for instance
S1 /\ S3 /\ S4.
"""
for k in range( len( spheresTuple ) ):
if k == 0:    S =          simplicial_complexes.Sphere( spheresTuple[k])
else     :    S = S.wedge( simplicial_complexes.Sphere( spheresTuple[k])
, is_mutable=False )

return S


There is one delicate point above: we really need the is_mutable=False option. Else the forthcomming method quotient_ring fails! (As i said, this may cost a day...)

(3) Then we can construct:

   S  = WedgeOfSpheres( (1,4,6) )
HS = S.cohomology_ring( QQ )
print "S = %s" % S
print "Computing H( S, QQ ) ... be patient..."
print HS
gens = [ g for g in HS.gens() if g.degree() > 0 ]
print "CUP PRODUCT matrix:"

for g in gens:
for h in gens:
print g*h,
print

print "Is the CUP PRODUCT zero? %s" % all( [ not(g*h) for g in gens for h in gens ] )


and we get:

   S = Simplicial complex with 15 vertices and 17 facets
Computing H( S, QQ ) ... be patient...
Cohomology ring of Simplicial complex with 15 vertices and 17 facets over Rational Field
CUP PRODUCT matrix:
0 0 0
0 0 0
0 0 0
Is the CUP PRODUCT zero? True


(4) Resumed: In order to see if the pairing is trivial on the cohomology ring of a space X, the following call would do the job:

def is_zero_cup_product( X, base_ring=QQ ):
generators = [ g for g in X.cohomology_ring( base_ring ).gens() if g.degree() > 0 ]
for g in generators:
for h in generators:
if g*h:
# print "%s * %s = %s" % ( g, h, g*h )
return False
return True


For instance:

sage: K = simplicial_complexes.KleinBottle()
sage: K
Minimal triangulation of the Klein bottle
sage: is_zero_cup_product( K, QQ )
True
sage: is_zero_cup_product( K, GF(2) )
False
sage: is_zero_cup_product( K, GF(5) )
True

sage: P2 = simplicial_complexes.RealProjectiveSpace( 2 )
sage: P2
Minimal triangulation of the real projective plane
sage: is_zero_cup_product( P2, QQ )
True
sage: is_zero_cup_product( P2, GF(2) )
False

sage: M7 = simplicial_complexes.MooreSpace( 7 )
sage: M7
Triangulation of the mod 7 Moore space
sage: M7.cohomology_ring( GF(7) ).gens()
(h^{0,0}, h^{1,0}, h^{2,0})
sage: a,b,c = _
sage: b * b
0
sage: is_zero_cup_product( M7 )
True

more