Lecture 12: Solutions from Lecture Exercises#

import ripser # This is in the scikit-tda package
from persim import plot_diagrams # Also in scikit-tda


import teaspoon.MakeData.PointCloud as gPC
import teaspoon.TDA.Draw as Draw

# Standard imports 
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy.spatial import distance_matrix
import plotly.express as px
import plotly.graph_objects as go


%matplotlib inline

Homology of a sphere#

Q:
  • What is the homology of the sphere?
  • Compute the persistence diagram for the sphere point cloud. Does this fit with what you said above?
  • Increase the number of points in the sphere to 400 and compute its persistence diagram. Do the same for 100 points and 500 points (although you might need to be patient, my laptop took about 30 seconds for that last one). What changes in the diagram??

The homology of a sphere is: \(\beta_0 = 1\), \(\beta_1 = 0\), \(\beta_2 = 1\).

N = 100 #<--- mess with this number to change the number of points
P_sphere = gPC.Sphere(N)
output = ripser.ripser(P_sphere, maxdim=2)
plot_diagrams(output['dgms'], show=True)
../../_images/8c92145f3260be88883c535fe5e5ef9f6a6abf0ce37486628669422153271315.png

Notice that this diagram has

  • an infinite class for the 0-dimensional connected component (fits with \(\beta_0 = 1\))

  • no prominent 1-dimensional classes, meaning nothing far from the diagonal

  • a prominent 2-dimensional class, with fits with \(\beta_2 = 1\)

Torus#

Q:
  • What is the homology of the torus?
  • Compute the persistence diagram for the torus point cloud. Does this fit with what you said above? Hint: If it doesn't, try increasing the number of points in the point cloud.
  • What is different between this diagram and the sphere diagram?
N = 500 #<--- mess with this number to change the number of points
P_torus = gPC.Torus(N)
output = ripser.ripser(P_torus, maxdim=2)
plot_diagrams(output['dgms'])
../../_images/52679ad75131a9c5f5db32dfe43aebaea1b97a59346421b64156dcdfb0d80357.png

Homology of a torus: \(\beta_0 = 1\), \(\beta_1 = 2\), \(\beta_2 = 1\)

For the number of points I gave you, you won’t really see the homology of the torus show up in the persistence diagram. Increase to 300-400 and it will be obvious. Notice that this diagram has

  • an infinite class for the 0-dimensional connected component (fits with beta_0 = 1)

  • two 1-dimensional classes far from the diagonal

  • one 2-dimensional point far from the diagonal, with fits with \(\beta_2 = 1\)

Persistence for similar point clouds#

Q:
  • What do you notice about the two persistence diagrams for the annuli?
  • Overlay the 1-dimensional torus diagram from earlier. What do you see? Which are more similar: the two annuli diagrams, or an annulus and the torus?
P1 = gPC.Annulus(200,1,2)
P2 = gPC.Annulus(200,1,2)
P_Torus = gPC.Torus(400)
Dgms1 = ripser.ripser(P1)['dgms']
Dgms2 = ripser.ripser(P2)['dgms']
DgmsT = ripser.ripser(P_Torus)['dgms']
plt.plot([0,2],[0,2], color='gray', linestyle='--')
plt.scatter(Dgms1[1][:,0], Dgms1[1][:,1], marker = '*', color = 'purple', label = 'P1')
plt.scatter(Dgms2[1][:,0], Dgms2[1][:,1], color = 'orange', label = 'P2')
plt.scatter(DgmsT[1][:,0], DgmsT[1][:,1], color = 'green', marker = '^', label = 'Torus')
plt.axis('square')
plt.title('1-D Persistence Diagrams')
plt.legend();
../../_images/fbb4067f50fe5eaa0a5d56a672c5dcb7b146020e623a3d236da3032dd3f7a126.png

Changing the radius on the annuli#

Q:
  • What changes in the persistence diagram when you change the inside radius r?
  • What changes in the persistence diagram when you change the outside radius R
P = gPC.Annulus(500,r = 1, R = 3)
Dgms = ripser.ripser(P)['dgms']
fig, axs = plt.subplots(1,2, figsize = (10,5))
plt.sca(axs[0])
Draw.drawPtCloud(P)
plt.sca(axs[1])
plot_diagrams(Dgms)
axs[1].grid(True, linestyle='--', linewidth=0.5, color='lightgray', alpha=0.9)
../../_images/60485924d7bc89f668bc03f048a2c53c432ddca45fabf0692b287749ff8d3127.png
P = gPC.Annulus(500,r = 2, R = 3)
Dgms = ripser.ripser(P)['dgms']
fig, axs = plt.subplots(1,2, figsize = (10,5))
plt.sca(axs[0])
Draw.drawPtCloud(P)
plt.sca(axs[1])
plot_diagrams(Dgms)
axs[1].grid(True, linestyle='--', linewidth=0.5, color='lightgray', alpha=0.9)
../../_images/c27b1dedbb61b234c587c4f31dbc6ffd9127aced4430a1e055fd6a181b6bcecb.png
P = gPC.Annulus(500,r = 1, R = 5)
Dgms = ripser.ripser(P)['dgms']
fig, axs = plt.subplots(1,2, figsize = (10,5))
plt.sca(axs[0])
Draw.drawPtCloud(P)
plt.sca(axs[1])
plot_diagrams(Dgms)
axs[1].grid(True, linestyle='--', linewidth=0.5, color='lightgray', alpha=0.9)
../../_images/74dca47bacb083c371363e6b515e4f2f741ba540682bc627bb9b61b5a3f3dc6b.png

The big thing to notice with this example is that the ouside radius does very little to change the high-persistence point. What is really being measured is the size of the inside hole, controlled in this case by \(r\).