scikit-tda / persim
1
"""
2
    Implementation of the "multiscale heat kernel" (CVPR 2015), 
3

4
    Author: Chris Tralie
5

6
"""
7

8 3
import numpy as np
9

10 3
__all__ = ["heat"]
11

12 3
def evalHeatKernel(dgm1, dgm2, sigma):
13
    """
14
    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)
15
    """
16 3
    kSigma = 0
17 3
    I1 = np.array(dgm1)
18 3
    I2 = np.array(dgm2)
19 3
    for i in range(I1.shape[0]):
20 3
        p = I1[i, 0:2]
21 3
        for j in range(I2.shape[0]):
22 3
            q = I2[j, 0:2]
23 3
            qc = I2[j, 1::-1]
24 3
            kSigma += np.exp(-(np.sum((p - q) ** 2)) / (8 * sigma)) - np.exp(
25
                -(np.sum((p - qc) ** 2)) / (8 * sigma)
26
            )
27 3
    return kSigma / (8 * np.pi * sigma)
28

29

30 3
def heat(dgm1, dgm2, sigma=0.4):
31
    """
32
    Return the pseudo-metric between two diagrams based on the continuous
33
    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)
34

35
    Parameters
36
    -----------
37

38
    dgm1: np.array (m,2)
39
        A persistence diagram
40
    dgm2: np.array (n,2)
41
        A persistence diagram
42
    sigma: float
43
        Heat diffusion parameter (larger sigma makes blurrier)
44
    Returns
45
    --------
46

47
    dist: float
48
        heat kernel distance between dgm1 and dgm2
49

50
    """
51 3
    return np.sqrt(
52
        evalHeatKernel(dgm1, dgm1, sigma)
53
        + evalHeatKernel(dgm2, dgm2, sigma)
54
        - 2 * evalHeatKernel(dgm1, dgm2, sigma)
55
    )

Read our documentation on viewing source code .

Loading