Library / SDK
geometric-kernels/GeometricKernels avatar
geometric-kernels/GeometricKernels

GeometricKernels: heat and Matern kernels off the Euclidean plane

Geometric kernels on manifolds, meshes and graphs

593 stars44 forksPythonApache-2.0

At a glance

What is it?
GeometricKernels is a Python package that implements kernels, and in particular heat and Matern kernels, on spaces where a straight line is not a distance: Riemannian manifolds, graphs and meshes. Its price is a heavy dependency stack, with geomstats, potpourri3d and a Laplacian solver underneath, and a numpy version pinned from above because of a known incompatibility.
Who is it for?
GeometricKernels fits a research team applying Gaussian processes to data that lives on a manifold, a graph or a mesh, and it does not fit a project that only needs a kernel on ordinary vectors or that cannot absorb the geomstats and potpourri3d dependency chain.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 37 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Kernels that respect the geometry of the data

GeometricKernels is a library that implements kernels, most importantly heat and Matern kernels, on non-Euclidean spaces such as Riemannian manifolds, graphs and meshes. The purpose is stated in one line: it enables kernel methods, in particular Gaussian process models, to be deployed on such spaces.

That is the whole idea. A Gaussian process needs a kernel, and the standard kernels assume a flat space where distance is a straight line and where the covariance between two points decays with the Euclidean distance between them. Put the same model on a sphere, a mesh or a graph and that assumption is wrong in a specific way, because the geometry of the data is part of the signal. A heat kernel on a manifold is the limit of a diffusion process on that manifold, so the covariance it induces reflects how heat actually spreads over the surface or the graph, and a Matern kernel on the same space is defined through that diffusion.

The audience is therefore a research audience rather than a general machine learning one. The topics, the citation files and the application examples all point at scientific work: geometric deep learning, probabilistic modelling on structured domains, and benchmarking.

The package is Apache 2.0, the documentation site is geometric-kernels.github.io, the version in the pyproject is 1.0.1, and the release history shows v1.0.1 on 2026-09-16, v1.0.0 on 2026-03-10 and v0.4.2 on 2026-02-11. The last push was on 2026-09-16 and the repository is not archived. A 1.0 release in March 2026 means the public API is recent, and the changelog in the repository is where the changes since then are recorded.

A space, a kernel and a parameter dictionary

The API shape is small enough to take in one screen, and the README's example is the fastest way to understand it.

You import a backend, import the package, then import a space and a kernel.

python
# Import a backend.
import numpy as np
# Import the geometric_kernels backend.
import geometric_kernels
# Import a space and an appropriate kernel.
from geometric_kernels.spaces import Hypersphere
from geometric_kernels.kernels import MaternGeometricKernel

A space is constructed first, here a two dimensional hypersphere, and three points on it are defined as an array of coordinates.

python
# Create a manifold (2-dim sphere).
hypersphere = Hypersphere(dim=2)

# Define 3 points on the sphere.
xs = np.array([[0., 0., 1.], [0., 1., 0.], [1., 0., 0.]])

# Initialize kernel.
kernel = MaternGeometricKernel(hypersphere)
params = kernel.init_params()
params["nu"] = np.array([5/2])
params["lengthscale"] = np.array([1.])

# Compute and print out the 3x3 kernel matrix.
print(np.around(kernel.K(params, xs), 2))

Two details make this different from a plain kernel API. The kernel is bound to a space at construction time, so it knows what it is a kernel of, and the parameters are not constructor arguments but a dictionary produced by init_params and then edited by key. The names in that dictionary are the mathematical ones, so nu is the smoothness parameter and lengthscale is the spatial scale, and the same dictionary shape works across the kernel family.

The result is the expected matrix, with the diagonal at one and the off diagonal entries at 0.36 for three points a quarter turn apart on a unit sphere.

code
[[1.   0.36 0.36]
 [0.36 1.   0.36]
 [0.36 0.36 1.  ]]

That last point is the one to check when you install it. The number 0.36 is a consequence of the geometry, not of an arbitrary setting, so if your matrix does not look like that, the backend or the version of a dependency is not doing what the documentation says it does.

One package, four backends, and optional GP frontends

The library uses LAB to support multiple backends, TensorFlow, Jax and PyTorch among them, and the design choice that matters is that you are not required to install all of them. The README says you simply install the backend of your choice, and optionally a GP package, and the pyproject describes the package as offering geometric kernels in NumPy, TensorFlow, PyTorch and Jax.

That is the difference between a library that assumes an ecosystem and one that does not. Installing TensorFlow and JAX and PyTorch into one environment to use a kernel on a sphere is a dependency conflict waiting to happen, and the LAB abstraction is what avoids it.

On top of the backends sit the Gaussian process frontends, and here the README is explicit that they are optional. With TensorFlow you can install the TensorFlow-based GP library GPflow, for which the project provides a frontend. With PyTorch, GPyTorch. With JAX, GPJax.

bash
        pip install gpflow
bash
        pip install gpytorch
bash
        pip install gpjax

So the shape of an installation is one kernel package, one backend, and optionally one GP framework. That is also the shape of the documentation, since the notebooks are described as covering every space, for example the sphere and graphs, every backend, for example Torch and JAX, and every frontend, for example GPyTorch and GPflow.

The one caveat is that the base backends are not interchangeable in cost. TensorFlow and PyTorch and JAX each bring their own installation weight, and the README notes that JAX is listed as the cpu version, with the gpu and tpu versions installed similarly.

The dependency stack is pinned harder than you would expect

The pyproject tells you most of the engineering story, because the constraints are unusually specific.

The runtime dependencies are backends at 1.8.0 or newer, einops, geomstats, numpy, opt-einsum, plum-dispatch at 2.6.0 or newer, potpourri3d, robust_laplacian, scipy at 1.3 or newer, spherical-harmonics-basis, and sympy at roughly 1.13.

The numpy constraint is the interesting one. It is bounded above at 2.4, and the inline comment says it is constraining from above due to a geomstats 2.8.0 incompatibility. A library that pins numpy from above because a dependency breaks is telling you that its dependency tree is the fragile part.

The uv configuration repeats the constraint and adds one more. There is an override dependency on numpy at 2.0 or newer but below 2.4, and an exclusion of tensorflow-macos, with the comment that GPflow still declares numpy below 2 and the obsolete Apple Silicon TensorFlow package, and that tensorflow supplies macOS wheels directly. In other words, the packaging is arranged around a specific conflict between a downstream GP library and TensorFlow on Apple Silicon.

The remaining configuration is conventional. The build backend is flit_core, the classifiers list Python 3.10 to 3.12 while requires-python says 3.11 up to but not including 3.14, so the classifier and the constraint disagree at the low end. mypy runs with ignore_missing_imports, strict_optional off and redefinition allowed, black runs at a line length of 88 targeting py311 through py313, and isort uses the black profile with lab marked as third party.

None of this is a red flag on its own, but it is a real cost. A numpy release in the 2.4 to 3.0 range will not install, and a numpy release below 2.0 will not either, so the package is on a narrow island of the numpy version space.

Development runs through make and uv

The contributor workflow is driven by a Makefile with a small set of targets, and it is the clearest picture of what the maintainers consider the definition of done.

The environment comes first, and the Python version and the directory are both parameters.

bash
make venv
bash
make venv UV_PYTHON=3.11 VENV_DIR=.venv

The target creates a seeded virtual environment with uv, defaulting to Python 3.11 and a .venv directory. The README is unusually honest about the toolchain not being mandatory, saying that uv is used for development but is not strictly necessary, and that if you would rather not use it you can still run make lint and make test by setting UV_RUN to be empty, in which case you set up the environment yourself.

That makes the rest of the targets easy to read. sync resolves and installs the project and development dependencies from the pyproject, install is a backwards compatible alias for it, and format runs autoflake, black and isort over the package and the tests. Lint runs flake8, then black in check mode with a diff, then isort in check only mode, and finally mypy with the namespace packages flag over the package. The test target runs pytest verbosely with the fail fast and last failed first options, ignoring warnings, printing durations and collecting coverage.

The docs target is a Sphinx build in the docs directory that runs the doctests and then the HTML build, so the examples in the documentation are executed as part of the documentation step. The repository also carries a .flake8 configuration, a CITATION.bib and a CITATION.cff, a CONTRIBUTING.md and a CODE_OF_CONDUCT.md, and a scripts directory.

Notebooks are the documentation, and two examples show the range

The example notebooks are described as numerous, and they are organised along the same three axes as the library itself: every space, for example the sphere and graphs, every backend, for example Torch and JAX, and every frontend, for example GPyTorch and GPflow. They are available both in the documentation and in the notebooks directory of the repository.

Two application examples are called out in the README, and they are worth reading for different reasons.

PeMS Regression is a benchmark suite for graph node regression with uncertainty. The README says the project employs GeometricKernels among other tools and offers processed data, baseline models and an example notebook for experiments on graph-structured data. It also says that in this benchmark, geometric Gaussian processes built with GeometricKernels have been shown to outperform various alternative methods, including ensembles of graph neural networks and Bayesian graph neural networks. That claim is attributed to the benchmark, and the practical consequence for an adopter is that the library has been evaluated against strong learned baselines rather than only against other kernel methods.

The Bayesian optimization demonstration uses GeometricKernels with the botorch library and is described as a minimal, self-contained example designed to demonstrate core concepts rather than reflect a real-world scenario. The README is careful about that distinction, and it is a useful signal about the rest of the examples too: the library is a building block, and the notebooks show the wiring rather than a finished system.

What the library costs you, and what it replaces

The alternative to a geometric kernel is not nothing, it is a different modelling decision.

A geometric kernel computes the covariance from the geometry of the space itself, through a diffusion process on the manifold, the mesh or the graph. The common alternative is to forget the geometry and encode each point by its features, for example the node features of a graph, and then apply a standard kernel in that feature space. The difference in approach is exactly what you give up. A feature encoding can capture what the graph's adjacency means for a particular task, and it is cheaper, but the covariance it induces says nothing about how points relate geometrically, and the model has to learn that relationship from data rather than inheriting it from the structure.

For a graph where the topology is the signal, that is the whole argument for this package. Where the topology is incidental, a feature-based kernel is likely to be enough, and the dependency chain here is not worth it.

The costs are concrete. geomstats, potpourri3d, a Laplacian solver package, spherical-harmonics-basis and sympy are the price of the geometric operations, and the numpy constraint means you inherit a narrow version window. The 1.0 release is recent, so the API surface may still move, and the documentation lives on a separate site rather than in the repository, which makes offline reading harder.

What you get in exchange is a library where the same kernel definition, with the same parameter dictionary, works across a manifold, a mesh and a graph, and across four backends, and where the frontends for GPflow, GPyTorch and GPJax are provided rather than left to you. For a group working on probabilistic models on structured domains, that combination is uncommon enough to justify the install.

Editorial conclusion

GeometricKernels fits a research team applying Gaussian processes to data that lives on a manifold, a graph or a mesh, and it does not fit a project that only needs a kernel on ordinary vectors or that cannot absorb the geomstats and potpourri3d dependency chain. Before adopting it, run the three point sphere example from the README on your chosen backend and check that the kernel matrix comes out as documented, because that is the fastest way to find a backend and version mismatch.

Frequently asked questions

What does GeometricKernels provide?

It implements kernels, most importantly heat and Matern kernels, on non-Euclidean spaces such as Riemannian manifolds, graphs and meshes, so that kernel methods and in particular Gaussian process models can be deployed on those spaces.

How do I install GeometricKernels?

Create and activate an environment, optionally with uv venv, conda or virtualenv, then run pip install geometric_kernels, or pip install with the git+https form for a specific branch. You then install the backend of your choice, such as tensorflow, torch or jax[cpu], and optionally a GP library, since the package supports several backends through LAB and you are not required to install all of them.

Which backends and GP libraries does GeometricKernels support?

The package offers geometric kernels in NumPy, TensorFlow, PyTorch and Jax through the LAB backend abstraction, and it provides frontends for the GP libraries GPflow with TensorFlow, GPyTorch with PyTorch and GPJax with JAX. The example in the README uses the numpy-based backend.

Why is numpy constrained to a range in GeometricKernels?

The pyproject constrains numpy from above at 2.4, with a comment that this is due to a geomstats 2.8.0 incompatibility, and the uv configuration applies the same override while excluding tensorflow-macos because GPflow declares numpy below 2 and the obsolete Apple Silicon TensorFlow package.

How do I run the GeometricKernels tests and build the docs?

The Makefile provides make venv to create the environment, make sync to install the project and development dependencies, make lint for flake8, black, isort and mypy, make test for pytest with coverage, and make docs for a Sphinx build that runs the doctests and the HTML build. The README notes that uv is not strictly necessary and that UV_RUN can be emptied if you set the environment up yourself.

Official sources

  1. geometric-kernels/GeometricKernels on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/geometric-kernels-geometrickernels.svg)](https://hysenlabs.com/projects/geometric-kernels-geometrickernels)

Was this useful?