Source code for persim.heat
"""
Implementation of the "multiscale heat kernel" (CVPR 2015),
Author: Chris Tralie
"""
import numpy as np
__all__ = ["heat"]
def evalHeatKernel(dgm1, dgm2, sigma):
"""
Evaluate the continuous heat-based kernel between dgm1 and dgm2 (more correct than L2 on the discretized version above but may be slower because can't exploit fast matrix multiplication when evaluating many, many kernels)
"""
kSigma = 0
I1 = np.array(dgm1)
I2 = np.array(dgm2)
for i in range(I1.shape[0]):
p = I1[i, 0:2]
for j in range(I2.shape[0]):
q = I2[j, 0:2]
qc = I2[j, 1::-1]
kSigma += np.exp(-(np.sum((p - q) ** 2)) / (8 * sigma)) - np.exp(
-(np.sum((p - qc) ** 2)) / (8 * sigma)
)
return kSigma / (8 * np.pi * sigma)
[docs]
def heat(dgm1, dgm2, sigma=0.4):
"""
Return the pseudo-metric between two diagrams based on the continuous
heat kernel as described in "A Stable Multi-Scale Kernel for Topological Machine Learning" by Jan Reininghaus, Stefan Huber, Ulrich Bauer, and Roland Kwitt (CVPR 2015)
Parameters
-----------
dgm1: np.array (m,2)
A persistence diagram
dgm2: np.array (n,2)
A persistence diagram
sigma: float
Heat diffusion parameter (larger sigma makes blurrier)
Returns
--------
dist: float
heat kernel distance between dgm1 and dgm2
"""
return np.sqrt(
evalHeatKernel(dgm1, dgm1, sigma)
+ evalHeatKernel(dgm2, dgm2, sigma)
- 2 * evalHeatKernel(dgm1, dgm2, sigma)
)