geometric-kernels / GeometricKernels

Geometric kernels on manifolds, meshes and graphs
https://geometric-kernels.github.io/
Apache License 2.0
214 stars 18 forks source link

README example does not run #70

Closed thomaspinder closed 1 year ago

thomaspinder commented 1 year ago

Bug / performance issue / build issue

The line params, state = kernel.init_params_and_state() in the README yields the error

ValueError: Fundamental system for dimension 3 and degree 31 has not been precomputed. Terminating computations. Precompute set by running `fundamental_set.py`

Running the lines

import spherical_harmonics
!python -m spherical_harmonics.fundamental_set

does not appear to resolve the issue.

To reproduce

The linked Colab details the issue in a generic environment. I have also replicated this error locally on my Linux machine. The code is

# 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.hypersphere import Hypersphere
from geometric_kernels.kernels.geometric_kernels import MaternKarhunenLoeveKernel

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

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

# Initialize kernel, use 100 terms to approximate the infinite series.
kernel = MaternKarhunenLoeveKernel(hypersphere, 100)
params, state = kernel.init_params_and_state()
params["nu"] = np.array([5/2])
params["lengthscale"] = np.array([1.])

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

Stack trace, or error message

INFO:root:Using numpy backend

---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

[<ipython-input-2-fbd8c07d3f04>](https://localhost:8080/#) in <module>
     15 # Initialize kernel, use 100 terms to approximate the infinite series.
     16 kernel = MaternKarhunenLoeveKernel(hypersphere, 100)
---> 17 params, state = kernel.init_params_and_state()
     18 params["nu"] = np.array([5/2])
     19 params["lengthscale"] = np.array([1.])

6 frames

[/usr/local/lib/python3.7/dist-packages/geometric_kernels/kernels/geometric_kernels.py](https://localhost:8080/#) in init_params_and_state(self)
     63         params = dict(lengthscale=np.array(1.0), nu=np.array(0.5))
     64 
---> 65         eigenvalues_laplacian = self.space.get_eigenvalues(self.num_eigenfunctions)
     66         eigenfunctions = self.space.get_eigenfunctions(self.num_eigenfunctions)
     67 

[/usr/local/lib/python3.7/dist-packages/geometric_kernels/spaces/hypersphere.py](https://localhost:8080/#) in get_eigenvalues(self, num)
    174         :return: [num, 1] array containing the eigenvalues
    175         """
--> 176         eigenfunctions = SphericalHarmonics(self.dim, num)
    177         eigenvalues = np.array(
    178             [

[/usr/local/lib/python3.7/dist-packages/geometric_kernels/spaces/hypersphere.py](https://localhost:8080/#) in __init__(self, dim, num_levels)
     39         self._num_eigenfunctions = self.degree_to_num_eigenfunctions(self._num_levels)
     40         self._spherical_harmonics = _SphericalHarmonics(
---> 41             dimension=dim + 1, degrees=self._num_levels
     42         )
     43 

[/usr/local/lib/python3.7/dist-packages/spherical_harmonics/spherical_harmonics.py](https://localhost:8080/#) in __init__(self, dimension, degrees, debug)
     60         self.harmonic_levels = [
     61             SphericalHarmonicsLevel(dimension, degree, self.fundamental_system)
---> 62             for degree in degrees
     63         ]
     64 

[/usr/local/lib/python3.7/dist-packages/spherical_harmonics/spherical_harmonics.py](https://localhost:8080/#) in <listcomp>(.0)
     60         self.harmonic_levels = [
     61             SphericalHarmonicsLevel(dimension, degree, self.fundamental_system)
---> 62             for degree in degrees
     63         ]
     64 

[/usr/local/lib/python3.7/dist-packages/spherical_harmonics/spherical_harmonics.py](https://localhost:8080/#) in __init__(self, dimension, degree, fundamental_system)
    129         self.num_harmonics_in_level = num_harmonics(self.dimension, self.degree)
    130 
--> 131         self.V = fundamental_system.load(self.degree)
    132 
    133         # surface area of S^{d−1}

[/usr/local/lib/python3.7/dist-packages/spherical_harmonics/fundamental_set.py](https://localhost:8080/#) in load(self, degree)
     77             if self.only_use_cache:
     78                 raise ValueError(
---> 79                     f"Fundamental system for dimension {self.dimension} and degree "
     80                     f"{degree} has not been precomputed. Terminating "
     81                     "computations. Precompute set by running `fundamental_set.py`"

ValueError: Fundamental system for dimension 3 and degree 31 has not been precomputed. Terminating computations. Precompute set by running `fundamental_set.py`

Expected behavior

I would expect this snippet to produce the 3x3 covariance matrix.

System information

vabor112 commented 1 year ago

This is probably related to the new concept of "levels" introduced to handle product kernels. @stoprightthere what do you think, could you take a look?

stoprightthere commented 1 year ago

@thomaspinder thank you for reporting a bug! We will look into how to solve this in principle. Meanwhile you could try using a lower number of levels -- say 10.

thomaspinder commented 1 year ago

Thanks. 10 levels runs successfully.

vabor112 commented 1 year ago

README example does run now so I close the issue.

The issue in https://github.com/vdutor/SphericalHarmonics is still to be fixed though.