geomfum.matcher package#

Submodules#

geomfum.matcher.base module#

Base classes for shape matchers.

class geomfum.matcher.base.BaseMatcher[source]#

Bases: ABC

Abstract base class for shape matchers.

class geomfum.matcher.base.BaseNeighborFinder(n_neighbors=1)[source]#

Bases: ABC

Base class for a Neighbor finder.

Parameters:

n_neighbors (int) – Number of neighbors to find.

class geomfum.matcher.base.CorrespondenceResult(fmap12: gs.ndarray = None, p2p21: gs.ndarray = None, fmap21: gs.ndarray = None, p2p12: gs.ndarray = None, descr_a: gs.ndarray = None, descr_b: gs.ndarray = None, refined_fmap12: gs.ndarray = None, refined_fmap21: gs.ndarray = None, soft_perm_ab: gs.ndarray = None, soft_perm_ba: gs.ndarray = None, overlap_ab: gs.ndarray = None, overlap_ba: gs.ndarray = None)[source]#

Bases: object

Result of a matching operation (for both Matcher and Model).

This is the unified output format for all correspondence methods, including classical functional map matchers and learning-based models.

Parameters:
  • fmap12 (array-like, shape=[spectrum_size_b, spectrum_size_a]) – Functional map matrix from shape_a to shape_b.

  • p2p21 (array-like, shape=[n_vertices_b]) – Point-to-point correspondence from shape_b to shape_a. For each vertex i in shape_b, p2p21[i] gives the corresponding vertex index in shape_a.

  • fmap21 (array-like, shape=[spectrum_size_a, spectrum_size_b], optional) – Functional map matrix from shape_b to shape_a (for bidirectional).

  • p2p12 (array-like, shape=[n_vertices_a], optional) – Point-to-point correspondence from shape_a to shape_b (for bidirectional).

  • descr_a (array-like, shape=[n_descr, n_vertices_a], optional) – Descriptors on shape_a.

  • descr_b (array-like, shape=[n_descr, n_vertices_b], optional) – Descriptors on shape_b.

  • refined_fmap12 (array-like, shape=[spectrum_size_b, spectrum_size_a], optional) – Refined functional map matrix (if refinement was applied).

  • refined_fmap21 (array-like, shape=[spectrum_size_a, spectrum_size_b], optional) – Refined functional map matrix from B to A (if bidirectional refinement).

  • soft_perm_ab (array-like, shape=[n_vertices_a, n_vertices_b], optional) – Soft permutation matrix mapping b vertices to a domain (P12 in RobustFMNet). soft_perm_ab[i, j] = probability that vertex i in a corresponds to vertex j in b.

  • soft_perm_ba (array-like, shape=[n_vertices_b, n_vertices_a], optional) – Soft permutation matrix mapping a vertices to b domain (P21 in RobustFMNet). soft_perm_ba[i, j] = probability that vertex i in b corresponds to vertex j in a.

  • overlap_ab (array-like, shape=[n_vertices_a], optional) – Predicted overlap scores (0–1) for shape A. overlap_ab[i] = probability that vertex i in A is in the overlap region with shape B.

  • overlap_ba (array-like, shape=[n_vertices_b], optional) – Predicted overlap scores (0–1) for shape B. overlap_ba[j] = probability that vertex j in B is in the overlap region with shape A.

descr_a: gs.ndarray = None#
descr_b: gs.ndarray = None#
fmap12: gs.ndarray = None#
fmap21: gs.ndarray = None#
property is_bidirectional#

Check if result contains bidirectional correspondences.

Returns:

bool – True if fmap21 and p2p12 are available.

overlap_ab: gs.ndarray = None#
overlap_ba: gs.ndarray = None#
p2p12: gs.ndarray = None#
p2p21: gs.ndarray = None#
refined_fmap12: gs.ndarray = None#
refined_fmap21: gs.ndarray = None#
soft_perm_ab: gs.ndarray = None#
soft_perm_ba: gs.ndarray = None#
to_dict()[source]#

Convert to dictionary (for backward compatibility).

Returns:

dict – Dictionary with all non-None fields.

Notes

This method avoids using asdict() from dataclasses because it performs deep copying, which fails for PyTorch tensors that are part of the computation graph (non-leaf tensors) during training.

class geomfum.matcher.base.DescriptorMatcher(descriptor_pipeline: DescriptorPipeline = None, neighbor_finder: BaseNeighborFinder = None)[source]#

Bases: BaseMatcher

Descriptor-based matcher using nearest neighbor in descriptor space.

This matcher directly computes correspondences by: 1. Computing descriptors/features on both shapes either indicating descriptor or pipeline. 2. Finding nearest neighbors in the descriptor space 3. Optionally refining the correspondence using CorrespondenceRefinementPipeline

This is simpler and faster than the functional map approach, but may be less robust for complex deformations.

Parameters:
  • descriptor_pipeline (DescriptorPipeline, optional) – Descriptor pipeline to compute descriptors. If None, uses default WKS-based pipeline.

  • neighbor_finder (NeighborFinder, optional) – Nearest neighbor finder. If None, uses default.

class geomfum.matcher.base.DescriptorPipeline(steps)[source]#

Bases: object

Sequential pipeline for computing and processing shape descriptors.

Parameters:

steps (list or tuple) – Steps to apply. Include: descriptor, subsampler, normalizer.

apply(shape)[source]#

Apply descriptor pipeline.

Parameters:

shape (Shape) – Shape to apply pipeline to.

Returns:

descr (array-like, shape=[…, n]) – Descriptor.

class geomfum.matcher.base.L2InnerNormalizer[source]#

Bases: Normalizer

Normalizer using L2 inner product with mass matrix.

class geomfum.matcher.base.NeighborFinder(n_neighbors=1)[source]#

Bases: WhichRegistryMixins, BaseNeighborFinder

Base class for a Neighbor finder.

A simplified blueprint of sklearn.NearestNeighbors implementation.

Parameters:

n_neighbors (int) – Number of neighbors.

class geomfum.matcher.base.SpatialNearestNeighborMatcher(neighbor_finder: BaseNeighborFinder = None)[source]#

Bases: BaseMatcher

Matcher based on spatial nearest neighbors.

This matcher computes correspondences by finding the nearest vertex in Euclidean space. It does not use any descriptors or functional maps.

Parameters:

neighbor_finder (BaseNeighborFinder, optional) – Nearest neighbor finder. If None, uses default.

class geomfum.matcher.base.WaveKernelSignature(scale=True, sigma=None, n_domain=3, domain=None, k=None)[source]#

Bases: WhichRegistryMixins, SpectralDescriptor

Wave Kernel Signature descriptor using quantum mechanical wave propagation.

Parameters:
  • scale (bool) – Whether to scale weights to sum to one.

  • sigma (float) – Standard deviation for the Gaussian.

  • n_domain (int) – Number of domain points. Ignored if domain is not None.

  • domain (callable or array-like, shape=[n_domain], optional) – Method to compute energy domain points (f(shape)) or energy domain points.

  • k (int, optional) – Number of eigenfunctions to use. If None, all eigenfunctions are used.

geomfum.matcher.base.dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)[source]#

Add dunder methods based on the fields defined in the class.

Examines PEP 526 __annotations__ to determine fields.

If init is true, an __init__() method is added to the class. If repr is true, a __repr__() method is added. If order is true, rich comparison dunder methods are added. If unsafe_hash is true, a __hash__() method is added. If frozen is true, fields may not be assigned to after instance creation. If match_args is true, the __match_args__ tuple is added. If kw_only is true, then by default all fields are keyword-only. If slots is true, a new class with a __slots__ attribute is returned.

geomfum.matcher.deep_fmap module#

Deep functional map matcher via per-pair gradient descent.

class geomfum.matcher.deep_fmap.BaseMatcher[source]#

Bases: ABC

Abstract base class for shape matchers.

class geomfum.matcher.deep_fmap.BijectivityLoss(weight=1)[source]#

Bases: Module

Computes the bijectivity error of two functional maps by measuring the mean squared Frobenius norm between fmap12 fmap21 and the identity matrix, and between fmap21 fmap12 and the identity matrix.

Parameters:

weight (float, optional) – Weight for the loss term (default: 1).

forward(fmap12, fmap21)[source]#

Forward pass.

Parameters:
  • fmap12 (torch.Tensor) – Functional map tensor from shape 1 to shape 2 of shape (spectrum_size_b, spectrum_size_a).

  • fmap21 (torch.Tensor) – Functional map tensor from shape 2 to shape 1 of shape (spectrum_size_a, spectrum_size_b).

Returns:

torch.Tensor – Scalar tensor representing the weighted mean squared Frobenius norm between fmap12 fmap21 and the identity matrix, and between fmap21 fmap12 and the identity matrix.

required_inputs = ['fmap12', 'fmap21']#
class geomfum.matcher.deep_fmap.CorrespondenceResult(fmap12: gs.ndarray = None, p2p21: gs.ndarray = None, fmap21: gs.ndarray = None, p2p12: gs.ndarray = None, descr_a: gs.ndarray = None, descr_b: gs.ndarray = None, refined_fmap12: gs.ndarray = None, refined_fmap21: gs.ndarray = None, soft_perm_ab: gs.ndarray = None, soft_perm_ba: gs.ndarray = None, overlap_ab: gs.ndarray = None, overlap_ba: gs.ndarray = None)[source]#

Bases: object

Result of a matching operation (for both Matcher and Model).

This is the unified output format for all correspondence methods, including classical functional map matchers and learning-based models.

Parameters:
  • fmap12 (array-like, shape=[spectrum_size_b, spectrum_size_a]) – Functional map matrix from shape_a to shape_b.

  • p2p21 (array-like, shape=[n_vertices_b]) – Point-to-point correspondence from shape_b to shape_a. For each vertex i in shape_b, p2p21[i] gives the corresponding vertex index in shape_a.

  • fmap21 (array-like, shape=[spectrum_size_a, spectrum_size_b], optional) – Functional map matrix from shape_b to shape_a (for bidirectional).

  • p2p12 (array-like, shape=[n_vertices_a], optional) – Point-to-point correspondence from shape_a to shape_b (for bidirectional).

  • descr_a (array-like, shape=[n_descr, n_vertices_a], optional) – Descriptors on shape_a.

  • descr_b (array-like, shape=[n_descr, n_vertices_b], optional) – Descriptors on shape_b.

  • refined_fmap12 (array-like, shape=[spectrum_size_b, spectrum_size_a], optional) – Refined functional map matrix (if refinement was applied).

  • refined_fmap21 (array-like, shape=[spectrum_size_a, spectrum_size_b], optional) – Refined functional map matrix from B to A (if bidirectional refinement).

  • soft_perm_ab (array-like, shape=[n_vertices_a, n_vertices_b], optional) – Soft permutation matrix mapping b vertices to a domain (P12 in RobustFMNet). soft_perm_ab[i, j] = probability that vertex i in a corresponds to vertex j in b.

  • soft_perm_ba (array-like, shape=[n_vertices_b, n_vertices_a], optional) – Soft permutation matrix mapping a vertices to b domain (P21 in RobustFMNet). soft_perm_ba[i, j] = probability that vertex i in b corresponds to vertex j in a.

  • overlap_ab (array-like, shape=[n_vertices_a], optional) – Predicted overlap scores (0–1) for shape A. overlap_ab[i] = probability that vertex i in A is in the overlap region with shape B.

  • overlap_ba (array-like, shape=[n_vertices_b], optional) – Predicted overlap scores (0–1) for shape B. overlap_ba[j] = probability that vertex j in B is in the overlap region with shape A.

descr_a: gs.ndarray = None#
descr_b: gs.ndarray = None#
fmap12: gs.ndarray = None#
fmap21: gs.ndarray = None#
property is_bidirectional#

Check if result contains bidirectional correspondences.

Returns:

bool – True if fmap21 and p2p12 are available.

overlap_ab: gs.ndarray = None#
overlap_ba: gs.ndarray = None#
p2p12: gs.ndarray = None#
p2p21: gs.ndarray = None#
refined_fmap12: gs.ndarray = None#
refined_fmap21: gs.ndarray = None#
soft_perm_ab: gs.ndarray = None#
soft_perm_ba: gs.ndarray = None#
to_dict()[source]#

Convert to dictionary (for backward compatibility).

Returns:

dict – Dictionary with all non-None fields.

Notes

This method avoids using asdict() from dataclasses because it performs deep copying, which fails for PyTorch tensors that are part of the computation graph (non-leaf tensors) during training.

class geomfum.matcher.deep_fmap.DeepFMMatcher(model=None, loss_manager=None, fmap_size=30, n_iters=1000, lr=0.001, verbose=False)[source]#

Bases: BaseMatcher

Deep functional map matcher optimized per shape pair.

Jointly optimizes a deep FM model (feature extractor + functional map solver) for a single shape pair using gradient descent, with no dataset-level training. The model is deep-copied at the start of each call, so every pair is solved independently. Passing a pretrained model turns this into a per-pair fine-tuning step.

The optimization loop is identical to the learning stage:

model.forward() → LossManager.compute_loss() → loss.backward()

This means any BaseModel (FMNet, RobustFMNet, …) and any combination of losses from geomfum.learning.losses can be plugged in.

Parameters:
  • model (BaseModel, optional) – Deep FM model to optimize. Defaults to FMNet() (random DiffusionNet weights). Pass a pretrained model instance for warm-start fine-tuning.

  • loss_manager (LossManager, optional) – Weighted combination of losses. Defaults to orthonormality + bijectivity + spectral descriptor preservation (all weight 1).

  • fmap_size (int or tuple of int) – Number of LBO eigenfunctions for the functional map. A tuple (k_b, k_a) allows different sizes per shape.

  • n_iters (int) – Gradient descent iterations per pair.

  • lr (float) – Adam learning rate.

  • verbose (bool) – If True, print each loss component every 100 iterations.

class geomfum.matcher.deep_fmap.FMNet(feature_extractor=DiffusionnetFeatureExtractor(   (model): DiffusionNet(     (first_linear): Linear(in_features=3, out_features=128, bias=True)     (last_linear): Linear(in_features=128, out_features=128, bias=True)     (blocks): ModuleList(       (0-3): 4 x DiffusionNetBlock(         (diffusion): LearnedTimeDiffusion()         (gradient_features): SpatialGradientFeatures(           (A_re): Linear(in_features=128, out_features=128, bias=False)           (A_im): Linear(in_features=128, out_features=128, bias=False)         )         (mlp): MiniMLP(           (miniMLP_linear_000): Linear(in_features=384, out_features=128, bias=True)           (miniMLP_activation_000): ReLU()           (miniMLP_dropout_001): Dropout(p=0.5, inplace=False)           (miniMLP_linear_001): Linear(in_features=128, out_features=128, bias=True)           (miniMLP_activation_001): ReLU()           (miniMLP_dropout_002): Dropout(p=0.5, inplace=False)           (miniMLP_linear_002): Linear(in_features=128, out_features=128, bias=True)         )       )     )   ) ), fmap_module=ForwardFunctionalMap(), converter=<geomfum.convert.P2pFromFmConverter object>)[source]#

Bases: BaseModel

Functional Map Network Model.

Parameters:
  • feature_extractor (FeatureExtractor) – Feature extractor to use for the descriptors.

  • fmap_module (ForwardFunctionalMap) – Functional map module to use for the forward pass.

  • converter (P2pFromFmConverter) – Converter to convert functional maps to point-to-point correspondences.

forward(mesh_a, mesh_b, as_dict=True)[source]#

Compute the functional map between two shapes.

Parameters:
  • mesh_a (TriangleMesh or dict) – The first shape, either as a TriangleMesh object or a dictionary containing ‘basis’, ‘evals’, and ‘pinv’.

  • mesh_b (TriangleMesh or dict) – The second shape, either as a TriangleMesh object or a dictionary containing ‘basis’, ‘evals’, and ‘pinv’.

  • as_dict (bool, optional) – If True, returns a dictionary with functional maps and, optionally, point-to-point correspondences. If False, returns the functional maps and, optionally, point-to-point correspondences as separate tensors.

Returns:

  • fmap12 (array-like, shape=[…, spectrum_size_b, spectrum_size_a]) – Functional map from shape a to shape b.

  • fmap21 (array-like, shape=[…, spectrum_size_a, spectrum_size_b]) – Functional map from shape b to shape a.

  • p2p21 (array-like, shape=[…, num_points_b]) – Point-to-point correspondence from shape a to shape b.

  • p2p12 (array-like, shape=[…, num_points_a]) – Point-to-point correspondence from shape b to shape a.

class geomfum.matcher.deep_fmap.LossManager(losses)[source]#

Bases: object

Manages a list of loss functions and their weights for model training.

Parameters:

losses (list of (nn.Module, float) or list of nn.Module) – List of (loss_module, weight) tuples, or just loss modules (weight=1.0).

compute_loss(outputs)[source]#

Compute the total loss and a dictionary of individual losses.

Parameters:

outputs (dict) – Dictionary containing the outputs of the model, which should include all required inputs for the loss functions

Returns:

  • total_loss (torch.Tensor) – Scalar tensor representing the total loss computed from all loss functions.

  • loss_dict (dict) – Dictionary mapping loss function names to their computed values.

class geomfum.matcher.deep_fmap.OrthonormalityLoss(weight=1)[source]#

Bases: Module

Computes the orthonormality error of a functional map by measuring the mean squared Frobenius norm between C^T C and the identity matrix.

Parameters:

weight (float, optional) – Weight for the loss term (default: 1).

forward(fmap12, fmap21)[source]#

Forward pass.

Parameters:
  • fmap12 (torch.Tensor) – Functional map tensor of shape ( spectrum_size_b, spectrum_size_a).

  • fmap21 (torch.Tensor) – Functional map tensor of shape ( spectrum_size_a, spectrum_size_b).

Returns:

torch.Tensor – Scalar tensor representing the weighted mean squared Frobenius norm between C^T C and the identity matrix.

required_inputs = ['fmap12', 'fmap21']#

geomfum.matcher.fmap module#

Functional map based matchers.

class geomfum.matcher.fmap.ArangeSubsampler(subsample_step=1, axis=0)[source]#

Bases: Subsampler

Subsampler using uniform stride-based indexing.

Parameters:
  • subsample_step (int) – Arange step.

  • axis (int) – Axis from which to subsample.

class geomfum.matcher.fmap.BaseMatcher[source]#

Bases: ABC

Abstract base class for shape matchers.

class geomfum.matcher.fmap.CorrespondenceResult(fmap12: gs.ndarray = None, p2p21: gs.ndarray = None, fmap21: gs.ndarray = None, p2p12: gs.ndarray = None, descr_a: gs.ndarray = None, descr_b: gs.ndarray = None, refined_fmap12: gs.ndarray = None, refined_fmap21: gs.ndarray = None, soft_perm_ab: gs.ndarray = None, soft_perm_ba: gs.ndarray = None, overlap_ab: gs.ndarray = None, overlap_ba: gs.ndarray = None)[source]#

Bases: object

Result of a matching operation (for both Matcher and Model).

This is the unified output format for all correspondence methods, including classical functional map matchers and learning-based models.

Parameters:
  • fmap12 (array-like, shape=[spectrum_size_b, spectrum_size_a]) – Functional map matrix from shape_a to shape_b.

  • p2p21 (array-like, shape=[n_vertices_b]) – Point-to-point correspondence from shape_b to shape_a. For each vertex i in shape_b, p2p21[i] gives the corresponding vertex index in shape_a.

  • fmap21 (array-like, shape=[spectrum_size_a, spectrum_size_b], optional) – Functional map matrix from shape_b to shape_a (for bidirectional).

  • p2p12 (array-like, shape=[n_vertices_a], optional) – Point-to-point correspondence from shape_a to shape_b (for bidirectional).

  • descr_a (array-like, shape=[n_descr, n_vertices_a], optional) – Descriptors on shape_a.

  • descr_b (array-like, shape=[n_descr, n_vertices_b], optional) – Descriptors on shape_b.

  • refined_fmap12 (array-like, shape=[spectrum_size_b, spectrum_size_a], optional) – Refined functional map matrix (if refinement was applied).

  • refined_fmap21 (array-like, shape=[spectrum_size_a, spectrum_size_b], optional) – Refined functional map matrix from B to A (if bidirectional refinement).

  • soft_perm_ab (array-like, shape=[n_vertices_a, n_vertices_b], optional) – Soft permutation matrix mapping b vertices to a domain (P12 in RobustFMNet). soft_perm_ab[i, j] = probability that vertex i in a corresponds to vertex j in b.

  • soft_perm_ba (array-like, shape=[n_vertices_b, n_vertices_a], optional) – Soft permutation matrix mapping a vertices to b domain (P21 in RobustFMNet). soft_perm_ba[i, j] = probability that vertex i in b corresponds to vertex j in a.

  • overlap_ab (array-like, shape=[n_vertices_a], optional) – Predicted overlap scores (0–1) for shape A. overlap_ab[i] = probability that vertex i in A is in the overlap region with shape B.

  • overlap_ba (array-like, shape=[n_vertices_b], optional) – Predicted overlap scores (0–1) for shape B. overlap_ba[j] = probability that vertex j in B is in the overlap region with shape A.

descr_a: gs.ndarray = None#
descr_b: gs.ndarray = None#
fmap12: gs.ndarray = None#
fmap21: gs.ndarray = None#
property is_bidirectional#

Check if result contains bidirectional correspondences.

Returns:

bool – True if fmap21 and p2p12 are available.

overlap_ab: gs.ndarray = None#
overlap_ba: gs.ndarray = None#
p2p12: gs.ndarray = None#
p2p21: gs.ndarray = None#
refined_fmap12: gs.ndarray = None#
refined_fmap21: gs.ndarray = None#
soft_perm_ab: gs.ndarray = None#
soft_perm_ba: gs.ndarray = None#
to_dict()[source]#

Convert to dictionary (for backward compatibility).

Returns:

dict – Dictionary with all non-None fields.

Notes

This method avoids using asdict() from dataclasses because it performs deep copying, which fails for PyTorch tensors that are part of the computation graph (non-leaf tensors) during training.

class geomfum.matcher.fmap.DescriptorPipeline(steps)[source]#

Bases: object

Sequential pipeline for computing and processing shape descriptors.

Parameters:

steps (list or tuple) – Steps to apply. Include: descriptor, subsampler, normalizer.

apply(shape)[source]#

Apply descriptor pipeline.

Parameters:

shape (Shape) – Shape to apply pipeline to.

Returns:

descr (array-like, shape=[…, n]) – Descriptor.

class geomfum.matcher.fmap.FunctionalMap(fmap_size=None, factor_builders=None, optimizer=None)[source]#

Bases: object

Optimizer for functional maps.

Takes factor_builders as configuration, then optimizes fmap given shapes/descriptors. This is an intermediate abstraction between FactorBuilders and the high-level Matcher.

Parameters:
  • factor_builders (list[FactorBuilder], optional) – List of factor builders. If None, uses default (SDP + LB + Mult).

  • optimizer (ScipyMinimize, optional) – Optimizer to use. If None, uses L-BFGS-B.

class geomfum.matcher.fmap.FunctionalMapMatcher(fmap_size: int = 30, descriptor_pipeline: DescriptorPipeline = None, fmap_optimizer: FunctionalMap = None, p2p_converter: P2pFromFmConverter = None)[source]#

Bases: BaseMatcher

Functional map based matcher with configurable pipeline.

This matcher follows the standard functional map pipeline: 1. Compute basis (Laplacian eigenfunctions) for both shapes 2. Compute descriptors (WKS, landmarks if available) 3. Optimize functional map with various constraints 4. Convert to point-to-point correspondence

Parameters:
  • fmap_size (int) – Number of eigenfunctions to use for the functional map optimization.

  • descriptor_pipeline (DescriptorPipeline, optional) – Descriptor pipeline to compute descriptors. If None, builds from descriptor.

  • fmap_optimizer (FunctionalMap, optional) – Optimizer for functional map. If None, uses default.

  • p2p_converter (P2pFromFmConverter, optional) – Converter from functional map to point-to-point. If None, uses default.

class geomfum.matcher.fmap.L2InnerNormalizer[source]#

Bases: Normalizer

Normalizer using L2 inner product with mass matrix.

class geomfum.matcher.fmap.P2pFromFmConverter(neighbor_finder=None, adjoint=False, bijective=False)[source]#

Bases: BaseP2pFromFmConverter

Pointwise map from functional map.

Parameters:
  • neighbor_finder (NeighborFinder) – Nearest neighbor finder.

  • adjoint (bool) – Whether to use adjoint method.

References

[OCSBG2012]

Maks Ovsjanikov, Mirela Ben-Chen, Justin Solomon, Adrian Butscher, and Leonidas Guibas. “Functional Maps: A Flexible Representation of Maps between Shapes.” ACM Transactions on Graphics 31, no. 4 (2012): 30:1-30:11. https://doi.org/10.1145/2185520.2185526.

[VM2023]

Giulio Viganò Simone Melzi. “Adjoint Bijective ZoomOut: Efficient Upsampling for Learned Linearly-Invariant Embedding.” The Eurographics Association, 2023. https://doi.org/10.2312/stag.20231293.

class geomfum.matcher.fmap.Refiner[source]#

Bases: ABC

Functional map refiner.

class geomfum.matcher.fmap.WaveKernelSignature(scale=True, sigma=None, n_domain=3, domain=None, k=None)[source]#

Bases: WhichRegistryMixins, SpectralDescriptor

Wave Kernel Signature descriptor using quantum mechanical wave propagation.

Parameters:
  • scale (bool) – Whether to scale weights to sum to one.

  • sigma (float) – Standard deviation for the Gaussian.

  • n_domain (int) – Number of domain points. Ignored if domain is not None.

  • domain (callable or array-like, shape=[n_domain], optional) – Method to compute energy domain points (f(shape)) or energy domain points.

  • k (int, optional) – Number of eigenfunctions to use. If None, all eigenfunctions are used.

class geomfum.matcher.fmap.ZoomOut(nit=10, step=1, p2p_from_fm_converter=None, fm_from_p2p_converter=None)[source]#

Bases: IterativeRefiner

Zoomout algorithm.

Parameters:
  • nit (int) – Number of iterations.

  • step (int or tuple[2, int]) – How much to increase each basis per iteration.

  • p2p_from_fm_converter (P2pFromFmConverter) – Pointwise map from functional map.

  • fm_from_p2p_converter (FmFromP2pConverter) – Functional map from pointwise map.

References

[MRRSWO2019]

Simone Melzi, Jing Ren, Emanuele Rodolà, Abhishek Sharma, Peter Wonka, and Maks Ovsjanikov. “ZoomOut: Spectral Upsampling for Efficient Shape Correspondence.” arXiv, September 12, 2019. http://arxiv.org/abs/1904.07865

class geomfum.matcher.fmap.ZoomOutMatcher(fmap_size: tuple = (30, 30), descriptor_pipeline: DescriptorPipeline = None, fmap_optimizer: FunctionalMap = None, refiner: Refiner = None, p2p_converter: P2pFromFmConverter = None)[source]#

Bases: BaseMatcher

ZoomOut functional map matcher.

This matcher implements the ZoomOut algorithm for functional map optimization. It inherits from FunctionalMapMatcher and overrides the optimizer with a ZoomOut implementation.

Module contents#

Module containing different matching algorithms.

class geomfum.matcher.BaseMatcher[source]#

Bases: ABC

Abstract base class for shape matchers.

class geomfum.matcher.DeepFMMatcher(model=None, loss_manager=None, fmap_size=30, n_iters=1000, lr=0.001, verbose=False)[source]#

Bases: BaseMatcher

Deep functional map matcher optimized per shape pair.

Jointly optimizes a deep FM model (feature extractor + functional map solver) for a single shape pair using gradient descent, with no dataset-level training. The model is deep-copied at the start of each call, so every pair is solved independently. Passing a pretrained model turns this into a per-pair fine-tuning step.

The optimization loop is identical to the learning stage:

model.forward() → LossManager.compute_loss() → loss.backward()

This means any BaseModel (FMNet, RobustFMNet, …) and any combination of losses from geomfum.learning.losses can be plugged in.

Parameters:
  • model (BaseModel, optional) – Deep FM model to optimize. Defaults to FMNet() (random DiffusionNet weights). Pass a pretrained model instance for warm-start fine-tuning.

  • loss_manager (LossManager, optional) – Weighted combination of losses. Defaults to orthonormality + bijectivity + spectral descriptor preservation (all weight 1).

  • fmap_size (int or tuple of int) – Number of LBO eigenfunctions for the functional map. A tuple (k_b, k_a) allows different sizes per shape.

  • n_iters (int) – Gradient descent iterations per pair.

  • lr (float) – Adam learning rate.

  • verbose (bool) – If True, print each loss component every 100 iterations.

class geomfum.matcher.DescriptorMatcher(descriptor_pipeline: DescriptorPipeline = None, neighbor_finder: BaseNeighborFinder = None)[source]#

Bases: BaseMatcher

Descriptor-based matcher using nearest neighbor in descriptor space.

This matcher directly computes correspondences by: 1. Computing descriptors/features on both shapes either indicating descriptor or pipeline. 2. Finding nearest neighbors in the descriptor space 3. Optionally refining the correspondence using CorrespondenceRefinementPipeline

This is simpler and faster than the functional map approach, but may be less robust for complex deformations.

Parameters:
  • descriptor_pipeline (DescriptorPipeline, optional) – Descriptor pipeline to compute descriptors. If None, uses default WKS-based pipeline.

  • neighbor_finder (NeighborFinder, optional) – Nearest neighbor finder. If None, uses default.

class geomfum.matcher.FunctionalMapMatcher(fmap_size: int = 30, descriptor_pipeline: DescriptorPipeline = None, fmap_optimizer: FunctionalMap = None, p2p_converter: P2pFromFmConverter = None)[source]#

Bases: BaseMatcher

Functional map based matcher with configurable pipeline.

This matcher follows the standard functional map pipeline: 1. Compute basis (Laplacian eigenfunctions) for both shapes 2. Compute descriptors (WKS, landmarks if available) 3. Optimize functional map with various constraints 4. Convert to point-to-point correspondence

Parameters:
  • fmap_size (int) – Number of eigenfunctions to use for the functional map optimization.

  • descriptor_pipeline (DescriptorPipeline, optional) – Descriptor pipeline to compute descriptors. If None, builds from descriptor.

  • fmap_optimizer (FunctionalMap, optional) – Optimizer for functional map. If None, uses default.

  • p2p_converter (P2pFromFmConverter, optional) – Converter from functional map to point-to-point. If None, uses default.

class geomfum.matcher.SpatialNearestNeighborMatcher(neighbor_finder: BaseNeighborFinder = None)[source]#

Bases: BaseMatcher

Matcher based on spatial nearest neighbors.

This matcher computes correspondences by finding the nearest vertex in Euclidean space. It does not use any descriptors or functional maps.

Parameters:

neighbor_finder (BaseNeighborFinder, optional) – Nearest neighbor finder. If None, uses default.

class geomfum.matcher.ZoomOutMatcher(fmap_size: tuple = (30, 30), descriptor_pipeline: DescriptorPipeline = None, fmap_optimizer: FunctionalMap = None, refiner: Refiner = None, p2p_converter: P2pFromFmConverter = None)[source]#

Bases: BaseMatcher

ZoomOut functional map matcher.

This matcher implements the ZoomOut algorithm for functional map optimization. It inherits from FunctionalMapMatcher and overrides the optimizer with a ZoomOut implementation.