Notebook source code: notebooks/how_to/09_functional_from_pointwise.ipynb
Run it yourself on binder Binder badge

How to compute a functional map from a pointwise map?#

 In [1]:
import geomstats.backend as gs
import numpy as np

from geomfum.convert import FmFromP2pBijectiveConverter, FmFromP2pConverter
from geomfum.dataset import NotebooksDataset
from geomfum.shape import TriangleMesh

Load meshes.

 In [2]:
dataset = NotebooksDataset()

mesh_a = TriangleMesh.from_file(dataset.get_filename("cat-00"))
mesh_b = TriangleMesh.from_file(dataset.get_filename("lion-00"))

mesh_a.n_vertices, mesh_b.n_vertices
 Out [2]:
(7207, 5000)

Set Laplace eigenbasis for each mesh.

 In [3]:
mesh_a.laplacian.find_spectrum(spectrum_size=6, set_as_basis=True)
mesh_b.laplacian.find_spectrum(spectrum_size=6, set_as_basis=True)

mesh_b.basis.use_k = 5

Assume we have a valid pointwise map between mesh_a and mesh_b (which for demonstration purposes, we instantiate randomly).

 In [4]:
p2p_12 = gs.from_numpy(np.random.choice(mesh_a.n_vertices, size=mesh_b.n_vertices))

p2p_12.shape
 Out [4]:
(5000,)

Compute functional map.

 In [5]:
fm_converter = FmFromP2pConverter()

fmap_matrix = fm_converter(p2p_12, mesh_a.basis, mesh_b.basis)

fmap_matrix.shape
 Out [5]:
(5, 6)

The pseudo_inverse can be used instead.

 In [6]:
fm_converter.pseudo_inverse = True

fmap_matrix = fm_converter(p2p_12, mesh_a.basis, mesh_b.basis)

fmap_matrix.shape
 Out [6]:
(5, 6)

The bijective method can be used using a different converter.

 In [7]:
p2p_21 = gs.from_numpy(np.random.choice(mesh_b.n_vertices, size=mesh_a.n_vertices))

p2p_21.shape
 Out [7]:
(7207,)
 In [8]:
fm_bij_converter = FmFromP2pBijectiveConverter()

fmap_matrix = fm_bij_converter(p2p_21, mesh_a.basis, mesh_b.basis)

fmap_matrix.shape
 Out [8]:
(5, 6)

Further reading#