Skip to content

Commit

Permalink
Merge branch 'main' into slava/hypersphere_improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
vabor112 authored Aug 12, 2024
2 parents f979d69 + 1bd9730 commit 0381d3a
Show file tree
Hide file tree
Showing 14 changed files with 70 additions and 32 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# CHANGELOG

## v0.2.1 - 08.08.2024
Minor release with mostly cosmetic changes:
* Add "If you have a question" section to README.md by @vabor112 in https://github.com/geometric-kernels/GeometricKernels/pull/131
* Github cosmetics by @stoprightthere in https://github.com/geometric-kernels/GeometricKernels/pull/133
* Replace all references to "gpflow" organization with "geometric-kernels" organization by @vabor112 in https://github.com/geometric-kernels/GeometricKernels/pull/134
* Use fit_gpytorch_model or fit.fit_gpytorch_mll depening on the botorсh version by @vabor112 in https://github.com/geometric-kernels/GeometricKernels/pull/137
* Add a missing type cast and fix a typo in kernels/karhunen_loeve.py by @vabor112 in https://github.com/geometric-kernels/GeometricKernels/pull/136
* Minor documentation improvements by @vabor112 in https://github.com/geometric-kernels/GeometricKernels/pull/135
* Add citation to the preprint of the GeometricKernels paper by @vabor112 in https://github.com/geometric-kernels/GeometricKernels/pull/138
* Add citation file by @aterenin in https://github.com/geometric-kernels/GeometricKernels/pull/140
* Fix dependencies (Version 0.2.1) by @stoprightthere in https://github.com/geometric-kernels/GeometricKernels/pull/143

## v0.2 - 21.04.2024
New geometric kernel that *just works*, `kernels.MaternGeometricKernel`. Relies on *(hopefully)* sensible defaults we defined. Mostly by @stoprightthere.

Expand Down
6 changes: 6 additions & 0 deletions CITATION.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@article{mostowsky2024,
title = {The GeometricKernels Package: Heat and Matérn Kernels for Geometric Learning on Manifolds, Meshes, and Graphs},
author = {Peter Mostowsky and Vincent Dutordoir and Iskander Azangulov and Noémie Jaquier and Michael John Hutchinson and Aditya Ravuri and Leonel Rozo and Alexander Terenin and Viacheslav Borovitskiy},
year = {2024},
journal = {arXiv:2407.08086},
}
29 changes: 29 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
title: "GeometricKernels"
authors:
- name: "GeometricKernels Contributors"
preferred-citation:
type: "article"
title: "The GeometricKernels Package: Heat and Matérn Kernels for Geometric Learning on Manifolds, Meshes, and Graphs"
authors:
- family-names: "Mostowsky"
given-names: "Peter"
- family-names: "Dutordoir"
given-names: "Vincent"
- family-names: "Azangulov"
given-names: "Iskander"
- family-names: "Jaquier"
given-names: "Noémie"
- family-names: "Hutchinson"
given-names: "Michael John"
- family-names: "Ravuri"
given-names: "Aditya"
- family-names: "Rozo"
given-names: "Leonel"
- family-names: "Terenin"
given-names: "Alexander"
- family-names: "Borovitskiy"
given-names: "Viacheslav"
year: "2024"
journal: "arXiv:2407.08086"
3 changes: 1 addition & 2 deletions geometric_kernels/feature_maps/probability_densities.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import lab as B
import numpy as np
from beartype.typing import Dict, List, Optional, Tuple
from opt_einsum import contract as einsum
from sympy import Poly, Product, symbols

from geometric_kernels.lab_extras import (
Expand Down Expand Up @@ -85,7 +84,7 @@ def student_t_sample(
shape_sqrt = B.chol(shape)
dtype = dtype or dtype_double(key)
key, z = B.randn(key, dtype, *size, n)
z = einsum("...i,ji->...j", z, shape_sqrt)
z = B.einsum("...i,ji->...j", z, shape_sqrt)

key, g = B.randgamma(
key,
Expand Down
3 changes: 1 addition & 2 deletions geometric_kernels/kernels/feature_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import lab as B
import numpy as np
from beartype.typing import Dict, Optional
from opt_einsum import contract as einsum

from geometric_kernels.feature_maps import FeatureMap
from geometric_kernels.kernels.base import BaseGeometricKernel
Expand Down Expand Up @@ -124,7 +123,7 @@ def K(
else:
features_X2 = features_X

feature_product = einsum("...no,...mo->...nm", features_X, features_X2)
feature_product = B.einsum("...no,...mo->...nm", features_X, features_X2)
return feature_product

def K_diag(self, params: Dict[str, B.Numeric], X: B.Numeric, **kwargs):
Expand Down
7 changes: 3 additions & 4 deletions geometric_kernels/spaces/eigenfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import lab as B
from beartype.typing import List, Optional
from opt_einsum import contract as einsum

from geometric_kernels.lab_extras import complex_like, is_complex, take_along_axis

Expand Down Expand Up @@ -106,7 +105,7 @@ def weighted_outerproduct(
else:
sum_phi_phi_for_level = B.cast(B.dtype(weights), sum_phi_phi_for_level)

return einsum("id,...nki->...nk", weights, sum_phi_phi_for_level) # [N, N2]
return B.einsum("id,...nki->...nk", weights, sum_phi_phi_for_level) # [N, N2]

def weighted_outerproduct_diag(
self, weights: B.Numeric, X: B.Numeric, **kwargs
Expand All @@ -132,7 +131,7 @@ def weighted_outerproduct_diag(
else:
phi_product_diag = B.cast(B.dtype(weights), phi_product_diag)

return einsum("id,ni->n", weights, phi_product_diag) # [N,]
return B.einsum("id,ni->n", weights, phi_product_diag) # [N,]

@abc.abstractmethod
def phi_product(
Expand Down Expand Up @@ -301,7 +300,7 @@ def phi_product(
X2 = X
Phi_X = self.__call__(X, **kwargs) # [N, J]
Phi_X2 = self.__call__(X2, **kwargs) # [N2, J]
return einsum("nl,ml->nml", Phi_X, Phi_X2) # [N, N2, J]
return B.einsum("nl,ml->nml", Phi_X, Phi_X2) # [N, N2, J]

def phi_product_diag(self, X: B.Numeric, **kwargs):
Phi_X = self.__call__(X, **kwargs) # [N, J]
Expand Down
3 changes: 1 addition & 2 deletions geometric_kernels/spaces/hyperbolic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import geomstats as gs
import lab as B
from beartype.typing import Optional
from opt_einsum import contract as einsum

from geometric_kernels.lab_extras import (
complex_like,
Expand Down Expand Up @@ -134,7 +133,7 @@ def inner_product(self, vector_a, vector_b):
p = 1
diagonal = from_numpy(vector_a, [-1.0] * p + [1.0] * q) # (n+1)
diagonal = B.cast(B.dtype(vector_a), diagonal)
return einsum("...i,...i->...", diagonal * vector_a, vector_b)
return B.einsum("...i,...i->...", diagonal * vector_a, vector_b)

def inv_harish_chandra(self, lam: B.Numeric) -> B.Numeric:
lam = B.squeeze(lam, -1)
Expand Down
5 changes: 2 additions & 3 deletions geometric_kernels/spaces/so.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import lab as B
import numpy as np
from beartype.typing import List, Tuple
from opt_einsum import contract as einsum

from geometric_kernels.lab_extras import dtype_double, from_numpy, qr, take_along_axis
from geometric_kernels.spaces.eigenfunctions import Eigenfunctions
Expand Down Expand Up @@ -300,7 +299,7 @@ def random(self, key: B.RandomState, number: int):
# explicit parametrization via the double cover SU(2) = S^3
key, sphere_point = B.random.randn(key, dtype_double(key), number, 4)
sphere_point /= B.reshape(
B.sqrt(einsum("ij,ij->i", sphere_point, sphere_point)), -1, 1
B.sqrt(B.einsum("ij,ij->i", sphere_point, sphere_point)), -1, 1
)

x, y, z, w = (B.reshape(sphere_point[..., i], -1, 1) for i in range(4))
Expand All @@ -317,7 +316,7 @@ def random(self, key: B.RandomState, number: int):
# qr decomposition is not in the lab package, so numpy is used.
key, h = B.random.randn(key, dtype_double(key), number, self.n, self.n)
q, r = qr(h, mode="complete")
r_diag_sign = B.sign(einsum("...ii->...i", r))
r_diag_sign = B.sign(B.einsum("...ii->...i", r))
q *= r_diag_sign[:, None]
q_det_sign = B.sign(B.det(q))
q[:, :, 0] *= q_det_sign[:, None]
Expand Down
5 changes: 2 additions & 3 deletions geometric_kernels/spaces/su.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import lab as B
import numpy as np
from beartype.typing import List, Tuple
from opt_einsum import contract as einsum

from geometric_kernels.lab_extras import (
complex_conj,
Expand Down Expand Up @@ -222,7 +221,7 @@ def random(self, key: B.RandomState, number: int):
# explicit parametrization via the double cover SU(2) = S_3
key, sphere_point = B.random.randn(key, dtype_double(key), number, 4)
sphere_point /= B.reshape(
B.sqrt(einsum("ij,ij->i", sphere_point, sphere_point)), -1, 1
B.sqrt(B.einsum("ij,ij->i", sphere_point, sphere_point)), -1, 1
)
a = create_complex(sphere_point[..., 0], sphere_point[..., 1])
b = create_complex(sphere_point[..., 2], sphere_point[..., 3])
Expand All @@ -235,7 +234,7 @@ def random(self, key: B.RandomState, number: int):
key, imag = B.random.randn(key, dtype_double(key), number, self.n, self.n)
h = create_complex(real, imag) / B.sqrt(2)
q, r = qr(h, mode="complete")
r_diag = einsum("...ii->...i", r)
r_diag = B.einsum("...ii->...i", r)
r_diag_inv_phase = complex_conj(r_diag / B.abs(r_diag))
q *= r_diag_inv_phase[:, None]
q_det = B.det(q)
Expand Down
13 changes: 7 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,19 @@ keywords=[
]
requires-python = ">=3.8"
dependencies = [
"backends>=1.5.4",
"einops",
"geomstats",
"numpy>=1.16",
"scipy>=1.3",
"opt-einsum",
"plum-dispatch>=2.2.0",
"backends>=1.5.4",
"potpourri3d",
"robust_laplacian",
"opt-einsum",
"geomstats",
"einops",
"scipy>=1.3",
"spherical-harmonics-basis",
"sympy~=1.13",
]
version="0.2"
version="0.2.1"

[project.urls]
Documentation = "https://geometric-kernels.github.io/"
Expand Down
3 changes: 1 addition & 2 deletions tests/kernels/test_product.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import lab as B
import numpy as np
from opt_einsum import contract as einsum

from geometric_kernels.kernels import MaternKarhunenLoeveKernel, ProductGeometricKernel
from geometric_kernels.lab_extras.extras import from_numpy
Expand Down Expand Up @@ -43,7 +42,7 @@ def test_circle_product_eigenfunctions():
weights = B.expand_dims(weights, -1)
actual = B.to_numpy(eigenfunctions.weighted_outerproduct(weights, X, X))

expected = einsum("ni,mi,i->nm", Phi_X, Phi_X2, chained_weights)
expected = B.einsum("ni,mi,i->nm", Phi_X, Phi_X2, chained_weights)
np.testing.assert_array_almost_equal(actual, expected)


Expand Down
5 changes: 2 additions & 3 deletions tests/spaces/test_circle.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import pytest
import tensorflow as tf
import torch
from opt_einsum import contract as einsum
from plum import Tuple

from geometric_kernels.kernels import MaternKarhunenLoeveKernel
Expand Down Expand Up @@ -89,7 +88,7 @@ def test_weighted_outerproduct_with_addition_theorem(

Phi_X = eigenfunctions(inputs)
Phi_X2 = eigenfunctions(inputs2)
expected = einsum("ni,ki,i->nk", Phi_X, Phi_X2, chained_weights)
expected = B.einsum("ni,ki,i->nk", Phi_X, Phi_X2, chained_weights)
np.testing.assert_array_almost_equal(actual, expected)


Expand Down Expand Up @@ -124,7 +123,7 @@ def test_weighted_outerproduct_diag_with_addition_theorem(
actual = eigenfunctions.weighted_outerproduct_diag(weights, inputs)

Phi_X = eigenfunctions(inputs)
expected = einsum("ni,i->n", Phi_X**2, chained_weights)
expected = B.einsum("ni,i->n", Phi_X**2, chained_weights)
np.testing.assert_array_almost_equal(B.to_numpy(actual), B.to_numpy(expected))


Expand Down
5 changes: 2 additions & 3 deletions tests/spaces/test_hypersphere.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import lab as B
import numpy as np
import pytest
from opt_einsum import contract as einsum
from plum import Tuple

from geometric_kernels.spaces.hypersphere import SphericalHarmonics
Expand Down Expand Up @@ -77,7 +76,7 @@ def test_weighted_outerproduct_with_addition_theorem(

Phi_X = eigenfunctions(inputs)
Phi_X2 = eigenfunctions(inputs2)
expected = einsum("ni,ki,i->nk", Phi_X, Phi_X2, chained_weights)
expected = B.einsum("ni,ki,i->nk", Phi_X, Phi_X2, chained_weights)
np.testing.assert_array_almost_equal(actual, expected)


Expand Down Expand Up @@ -112,5 +111,5 @@ def test_weighted_outerproduct_diag_with_addition_theorem(
actual = eigenfunctions.weighted_outerproduct_diag(weights, inputs)

Phi_X = eigenfunctions(inputs)
expected = einsum("ni,i->n", Phi_X**2, chained_weights)
expected = B.einsum("ni,i->n", Phi_X**2, chained_weights)
np.testing.assert_array_almost_equal(B.to_numpy(actual), B.to_numpy(expected))
3 changes: 1 addition & 2 deletions tests/spaces/test_lie_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import numpy as np
import pytest
from numpy.testing import assert_allclose
from opt_einsum import contract as einsum

from geometric_kernels.feature_maps import RandomPhaseFeatureMapCompact
from geometric_kernels.kernels import MaternKarhunenLoeveKernel
Expand Down Expand Up @@ -127,6 +126,6 @@ def test_feature_map(group_and_eigf):

K_xx = (kernel.K(param, x, x)).real
key, embed_x = feature_map(x, param, key=key, normalize=True)
F_xx = (einsum("ni,mi-> nm", embed_x, embed_x.conj())).real
F_xx = (B.einsum("ni,mi-> nm", embed_x, embed_x.conj())).real

assert_allclose(K_xx, F_xx, atol=5e-2)

0 comments on commit 0381d3a

Please sign in to comment.