Triangle zigzag exampleΒΆ

Simple example of a filtered triangle where simplices are first inserted in a given order, and then removed in the reverse order is in examples/triangle/triangle-zigzag.cpp. Its Python equivalent (examples/triangle/ is described next.

from dionysus import Simplex, ZigzagPersistence, \
                     vertex_cmp, data_cmp \
#                    ,enable_log

complex = {Simplex((0,),        0):     None,                   # A
           Simplex((1,),        1):     None,                   # B
           Simplex((2,),        2):     None,                   # C
           Simplex((0,1),       2.5):   None,                   # AB
           Simplex((1,2),       2.9):   None,                   # BC
           Simplex((0,2),       3.5):   None,                   # CA
           Simplex((0,1,2),     5):     None}                   # ABC

print "Complex:"
for s in sorted(complex.keys()): print s

zz = ZigzagPersistence()

# Add all the simplices
b = 1
for s in sorted(complex.keys(), data_cmp):
    print "%d: Adding %s" % (b, s)
    i,d = zz.add([complex[ss] for ss in s.boundary], b)
    complex[s] = i
    if d:   print "Interval (%d, %d)" % (d, b-1)
    b += 1

# Remove all the simplices
for s in sorted(complex.keys(), data_cmp, reverse = True):
    print "%d: Removing %s" % (b, s)
    d = zz.remove(complex[s], b)
    del complex[s]
    if d:   print "Interval (%d, %d)" % (d, b-1)
    b += 1

Unlike the Triangle example, here we use ZigzagPersistence to compute the pairings, and therefore need to store the internal representations of the simplicies used by the class. These representation are stored in the dictionary complex, which maps the simplices to their representations for ZigzagPersistence.

The first for loop processes the simplices sorted with respect to data_cmp(). ZigzagPersistence.add() invoked within the loop accepts the boundary of the newly added cell in its internal representation, which is computed by looking up each simplex in the dictionary complex: [complex[ss] for ss in s.boundary]. If there is a birth, the value to be associated with the newly created class is b (which in this case is simply a counter). add() returns a pair (i,d). The former is an internal representation of the newly added cell, which we immediately record with complex[s] = i. The latter is an indicator of whether a death has occurred, which happens iff d is not None, in which case d is the birth value passed to add() whenever the class that just died was born. If the death occurred, then we outut the interval (d, b-1).

The second for loop removes simplices in the reverse order of their insertion. remove() takes the index of the cells to be removed (looked up in the complex dictionary: complex[s]), and takes a birth value in case a class is born. It return only a death indicator (which again is None if no death occurred).