Notebook source code:
notebooks/how_to/15_refine_functional_map.ipynb
Run it yourself on binder
How to refine a functional map?#
In [ ]:
import geomstats.backend as gs
from geomfum.dataset import NotebooksDataset
from geomfum.refine import (
FastSinkhornFilters,
IcpRefiner,
ZoomOut,
)
from geomfum.shape import TriangleMesh
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
INFO: Data has already been downloaded... using cached file ('C:\Users\giuli\.geomfum\data\cat-00.off').
INFO: Data has already been downloaded... using cached file ('C:\Users\giuli\.geomfum\data\lion-00.off').
Out [2]:
(7207, 5000)
Set Laplace eigenbasis for each mesh.
In [3]:
mesh_a.laplacian.find_spectrum(spectrum_size=10, set_as_basis=True)
mesh_b.laplacian.find_spectrum(spectrum_size=10, set_as_basis=True)
mesh_a.basis.use_k = 6
mesh_b.basis.use_k = 5
C:\Users\giuli\OneDrive\Research\geomfum_proj\geomfum\geomfum\_backend\pytorch\sparse.py:22: UserWarning: Sparse CSC tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at C:\actions-runner\_work\pytorch\pytorch\pytorch\aten\src\ATen\SparseCsrTensorImpl.cpp:55.)
return _torch.sparse_csc_tensor(ccol_indices, row_indices, values, size=array.shape)
Assume we have a valid functional map \(C\) between mesh_a
and mesh_b
(which for demonstration purposes, we instantiate randomly).
In [4]:
fmap_matrix = gs.random.uniform(
size=(mesh_b.basis.spectrum_size, mesh_a.basis.spectrum_size)
)
fmap_matrix.shape
Out [4]:
torch.Size([5, 6])
Refine functional map using ICP algorithm (see OCSBG2012).
In [5]:
icp = IcpRefiner(nit=10, atol=1e-4)
icp_fmap_matrix = icp(fmap_matrix, mesh_a.basis, mesh_b.basis)
icp_fmap_matrix.shape
Out [5]:
torch.Size([5, 6])
Refine functional map using ZoomOut (see MRRSWO2019).
In [6]:
zoomout = ZoomOut(nit=2, step=(2, 1))
zoomout_fmap_matrix_ = zoomout(fmap_matrix, mesh_a.basis, mesh_b.basis)
zoomout_fmap_matrix_.shape
Out [6]:
torch.Size([7, 10])
Refine functional map using fast Sinkhorn filters (see PRMWO2021).
In [7]:
fast_sinkhorn_filters = FastSinkhornFilters(nit=2, step=(2, 1))
fast_sinkhorn_filters_fmap_matrix_ = fast_sinkhorn_filters(
fmap_matrix, mesh_a.basis, mesh_b.basis
)
fast_sinkhorn_filters_fmap_matrix_.shape
Out [7]:
torch.Size([7, 10])
Pointwise and functional converters can be easily controlled through p2p_from_fm_converter
and fm_from_p2p_converter
(sensible defaults are used.)