#### representatives of bars, homology classes

Ryan Budney

Greetings,

Say I've computed persistent homology of some RIPS complex in Dionysus.  How does one go the extra step to find a cycle representative in a homology class?  i.e. I would like to identify the bar, and determine which linear combination of simplices represent the bar.

In the process of writing this question I likely have answered it.  But it would be nice to get confirmation, and perhaps this will be useful to others.

To make this concrete and fairly simple, let me use the vertices of a square of side-length two as my data set.

import dionysus as di

## generate square as a list

A = []
for i in [-1,1]:
for j in [-1, 1]:
cv = [i, i]
cv *= j
A.append(cv)

## convert to numpy array
A = np.array(A, float)

## generate the associated RIPS complex
X = di.fill_rips(A, 3, 3.0)

## compute persistent homology
hfp = di.homology_persistence(X)

## here is where I get a bit fuzzy.  My understanding is hfp is a reduced
## matrix that describes the persistent homology.  But I'm not certain how
## to read it.  Here is some code of Dmitriy's that I lifted from a 2018 thread.

for i,c in enumerate(hfp):
print(X[i],end=': ')
print(" + ".join(["%d * %s" % (x.element, X[x.index]) for x in c]))

If I execute the above code, I get this as output.

<0> 0:
<1> 0:
<2> 0:
<3> 0:
<0,1> 2: 1 * <0> 0 + 1 * <1> 0
<0,3> 2: 1 * <0> 0 + 1 * <3> 0
<1,2> 2: 1 * <1> 0 + 1 * <2> 0
<2,3> 2:
<0,2> 2.82843:
<1,3> 2.82843:
<0,1,2> 2.82843: 1 * <0,1> 2 + 1 * <1,2> 2 + 1 * <0,2> 2.82843
<0,1,3> 2.82843: 1 * <0,1> 2 + 1 * <0,3> 2 + 1 * <1,3> 2.82843
<0,2,3> 2.82843: 1 * <0,1> 2 + 1 * <0,3> 2 + 1 * <1,2> 2 + 1 * <2,3> 2
<1,2,3> 2.82843:
<0,1,2,3> 2.82843: 1 * <0,1,2> 2.82843 + 1 * <0,1,3> 2.82843 + 1 * <0,2,3> 2.82843 + 1 * <1,2,3> 2.82843

What I'd like to do now is see the bars from this output.  My initial impression is this "hfp" object represents the entire chain complex in reduced form.

This persistent homology of our square has four H_0 bars that merge into one at length-parameter 2.  And it has a single H_1 bar that starts at length parameter 2, and dies as 2\sqrt{2}.  Here is how I merge this understanding with the Dionysus output, line-by-line:

<0> 0:
<1> 0:
<2> 0:
<3> 0:

These lines say the four vertices labelled <0>, <1>, <2>, <3> appear at length parameter 0.  The fact that there's nothing to the right of the colon indicates bars are created at length-parameter zero.

The lines:

<0,1> 2: 1 * <0> 0 + 1 * <1> 0
<0,3> 2: 1 * <0> 0 + 1 * <3> 0
<1,2> 2: 1 * <1> 0 + 1 * <2> 0

say at length-parameter 2, the three edges <0,1>, <0,3>, <1,2> are created and they merge the four 0-cycles into one.

The line:

<2,3> 2:

indicates the last edge <2,3> is creating a 1-cycle, at side-length 2.  So this helps me.  It's telling me that generally one has to combine these relations to discover the cycle representatives.

The remaining lines are relatively degenerate:

<0,2> 2.82843:
<1,3> 2.82843:
<0,1,2> 2.82843: 1 * <0,1> 2 + 1 * <1,2> 2 + 1 * <0,2> 2.82843
<0,1,3> 2.82843: 1 * <0,1> 2 + 1 * <0,3> 2 + 1 * <1,3> 2.82843
<0,2,3> 2.82843: 1 * <0,1> 2 + 1 * <0,3> 2 + 1 * <1,2> 2 + 1 * <2,3> 2
<1,2,3> 2.82843:
<0,1,2,3> 2.82843: 1 * <0,1,2> 2.82843 + 1 * <0,1,3> 2.82843 + 1 * <0,2,3> 2.82843 + 1 * <1,2,3> 2.82843

This says at length 2\sqrt{2} two new 1-cycles are created and simultaneously destroyed, but then also a 2-cycle is created and simultaneously destroyed, i.e. bars of length 0.

Thanks,

-ryan