Skip to content

Port SphericalHarmonicsFilter from MATLAB to Python#1588

Open
Copilot wants to merge 11 commits intomainfrom
copilot/add-spherical-harmonics-filter
Open

Port SphericalHarmonicsFilter from MATLAB to Python#1588
Copilot wants to merge 11 commits intomainfrom
copilot/add-spherical-harmonics-filter

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

The feature/sharmonics_filter branch contained a stub SphericalHarmonicsFilter and test file but was missing the implementation of the required distribution operations (convolve, multiply, rotate, from_distribution_numerical_fast).

Distribution methods added to SphericalHarmonicsDistributionComplex

  • from_distribution_numerical_fast(dist, degree, transformation) — evaluates dist.pdf on a pyshtools Driscoll-Healy grid and recovers SH coefficients via discrete SHT; replaces the slow integral-based variant
  • convolve(other) — zonal spherical convolution:
    • identity: direct frequency-domain formula h_{l,m} = √(4π/(2l+1)) · f_{l,m} · g_{l,0}
    • sqrt: grid-based with a 2× finer intermediate grid (avoids aliasing from squaring )
  • multiply(other) — grid-based pointwise product; for sqrt transformation √p · √q = √(pq) so no extra step needed
  • rotate(alpha, beta, gamma) — ZYZ Euler-angle rotation via pyshtools.SHCoeffs.rotate(..., body=True)
  • Private helpers: _coeff_mat_to_pysh, _pysh_to_coeff_mat, _get_dh_grid_cartesian, _eval_on_grid, _fit_from_grid

SphericalHarmonicsFilter (new file)

Complete implementation following the MATLAB reference:

filt = SphericalHarmonicsFilter(degree=21, transformation='sqrt')
filt.set_state(SphericalHarmonicsDistributionComplex.from_distribution_numerical_fast(prior, 21, 'sqrt'))
filt.predict_identity(noise_shd)           # zonal convolution
filt.update_identity(meas_shd, z)          # multiply + optional rotation
filt.update_nonlinear(likelihood_fn, z)    # grid-based Bayes update
filt.update_nonlinear_multiple(lks, zs)    # batch update with multiple likelihoods
mean = filt.get_estimate_mean()

Both identity and sqrt transformations produce the same underlying posterior (verified to atol=5e-15 in test_prediction_sqrt_vs_id).

Minor additions

  • VonMisesFisherFilter: added set_state / get_estimate_mean helpers needed by the shared test
  • pyrecest/filters/__init__.py: exported VonMisesFisherFilter
  • test_spherical_harmonics_filter.py: four tests ported from the MATLAB reference suite

Copilot AI and others added 2 commits March 31, 2026 20:27
…ibution_numerical_fast

Agent-Logs-Url: https://github.com/FlorianPfaff/PyRecEst/sessions/a02e218a-d9bc-4d03-9c38-8776e308de70

Co-authored-by: FlorianPfaff <6773539+FlorianPfaff@users.noreply.github.com>
…scale factor comment

Agent-Logs-Url: https://github.com/FlorianPfaff/PyRecEst/sessions/a02e218a-d9bc-4d03-9c38-8776e308de70

Co-authored-by: FlorianPfaff <6773539+FlorianPfaff@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

MegaLinter analysis: Success

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 7.16s
✅ JSON prettier 2 0 0 0 0.4s
✅ JSON v8r 2 0 0 5.21s
✅ MARKDOWN markdownlint 1 0 0 0 0.7s
✅ MARKDOWN markdown-table-formatter 1 0 0 0 0.22s
✅ PYTHON bandit 278 0 0 3.55s
✅ PYTHON black 278 3 0 0 5.35s
✅ PYTHON flake8 278 0 0 2.03s
✅ PYTHON isort 278 4 0 0 0.54s
✅ PYTHON mypy 278 0 0 4.2s
✅ PYTHON pylint 278 0 0 80.51s
✅ PYTHON ruff 278 4 0 0 0.05s
✅ REPOSITORY checkov yes no no 21.39s
✅ REPOSITORY gitleaks yes no no 4.28s
✅ REPOSITORY git_diff yes no no 0.04s
✅ REPOSITORY secretlint yes no no 5.64s
✅ REPOSITORY syft yes no no 2.74s
✅ REPOSITORY trivy-sbom yes no no 1.61s
✅ REPOSITORY trufflehog yes no no 17.63s
✅ YAML prettier 4 0 0 0 0.5s
✅ YAML v8r 4 0 0 11.48s
✅ YAML yamllint 4 0 0 0.44s

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.4.0 --custom-flavor-setup --custom-flavor-linters PYTHON_PYLINT,PYTHON_BLACK,PYTHON_FLAKE8,PYTHON_ISORT,PYTHON_BANDIT,PYTHON_MYPY,PYTHON_RUFF,COPYPASTE_JSCPD,JSON_V8R,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_GITLEAKS,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

Test Results

    4 files   -     8      4 suites   - 8   19m 57s ⏱️ - 2h 9m 24s
  703 tests +   14    703 ✅ +   14  0 💤 ±    0  0 ❌ ±0 
2 976 runs   - 5 552  2 976 ✅  - 4 184  0 💤  - 1 368  0 ❌ ±0 

Results for commit 39ce44b. ± Comparison against base commit 872c442.

♻️ This comment has been updated with latest results.

@FlorianPfaff FlorianPfaff force-pushed the copilot/add-spherical-harmonics-filter branch from dd20732 to cead808 Compare April 2, 2026 17:33
@FlorianPfaff
Copy link
Copy Markdown
Owner

Do not use numpy but rather pyrecest.backend. Suppress the too-many-locals and the redefined-builtin locally at the respective line.

************* Module pyrecest.distributions.hypersphere_subset.spherical_harmonics_distribution_complex
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:7:0: W0404: Reimport 'sin' (imported line 7) (reimported)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:223:20: E0602: Undefined variable 'np' (undefined-variable)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:327:4: R0914: Too many local variables (21/15) (too-many-locals)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:365:21: W0212: Access to a protected member _eval_on_grid of a client class (protected-access)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:391:21: W0212: Access to a protected member _eval_on_grid of a client class (protected-access)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:420:17: W0212: Access to a protected member _eval_on_grid of a client class (protected-access)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:445:12: E0602: Undefined variable 'np' (undefined-variable)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:446:12: E0602: Undefined variable 'np' (undefined-variable)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:447:12: E0602: Undefined variable 'np' (undefined-variable)
pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:440:8: W0611: Unused pyshtools imported as pysh (unused-import)
************* Module pyrecest.filters.spherical_harmonics_filter
pyrecest/filters/spherical_harmonics_filter.py:4:0: W0622: Redefining built-in 'abs' (redefined-builtin)
pyrecest/filters/spherical_harmonics_filter.py:196:4: R0914: Too many local variables (16/15) (too-many-locals)
pyrecest/filters/spherical_harmonics_filter.py:203:12: W0212: Access to a protected member _get_dh_grid_cartesian of a client class (protected-access)
pyrecest/filters/spherical_harmonics_filter.py:232:29: W0212: Access to a protected member _fit_from_grid of a client class (protected-access)
************* Module pyrecest.tests.filters.test_spherical_harmonics_filter
pyrecest/tests/filters/test_spherical_harmonics_filter.py:65:74: W0640: Cell variable sigma_x defined in loop (cell-var-from-loop)
pyrecest/tests/filters/test_spherical_harmonics_filter.py:66:74: W0640: Cell variable sigma_y defined in loop (cell-var-from-loop)
pyrecest/tests/filters/test_spherical_harmonics_filter.py:67:74: W0640: Cell variable sigma_z defined in loop (cell-var-from-loop)
pyrecest/tests/filters/test_spherical_harmonics_filter.py:71:54: W0640: Cell variable sigma_x defined in loop (cell-var-from-loop)
pyrecest/tests/filters/test_spherical_harmonics_filter.py:72:54: W0640: Cell variable sigma_y defined in loop (cell-var-from-loop)
pyrecest/tests/filters/test_spherical_harmonics_filter.py:73:54: W0640: Cell variable sigma_z defined in loop (cell-var-from-loop)


Your code has been rated at 9.97/10

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot Do not use numpy but rather import from pyrecest.backend (similar to other classes)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clm = name = None
kind = 'complex'
normalization = 'ortho'
csphase = -1
lmax = 10
error_kind = None
header = None
header2 = None
units = None
degree = 10

@staticmethod
def _pysh_to_coeff_mat(clm, degree):
    """Convert a pyshtools SHComplexCoeffs object to our coeff_mat."""
  coeff_mat = np.zeros((degree + 1, 2 * degree + 1), dtype=complex)
                ^^

E NameError: name 'np' is not defined

pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:223: NameError
=============================== warnings summary ===============================
pyrecest/tests/distributions/test_hypertoroidal_grid_distribution.py::HypertoroidalGridDistributionTest::test_get_grid
/home/runner/work/PyRecEst/PyRecEst/pyrecest/distributions/abstract_grid_distribution.py:87: UserWarning: Warning: Grid values apparently do not belong to a normalized density. Normalizing...
warnings.warn(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html

  • generated xml file: /home/runner/work/PyRecEst/PyRecEst/junit_test_results_numpy.xml -
    =========================== short test summary info ============================
    FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_prediction_sqrt_vs_id - NameError: name 'np' is not defined
    FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_identity - NameError: name 'np' is not defined
    FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_using_likelihood - NameError: name 'np' is not defined
    FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_using_likelihood_multiple - NameError: name 'np' is not defined

…rnings inline

Agent-Logs-Url: https://github.com/FlorianPfaff/PyRecEst/sessions/8a1be072-ebc1-45ed-96f5-9a2928d3e358

Co-authored-by: FlorianPfaff <6773539+FlorianPfaff@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 3, 2026

Do not use numpy but rather pyrecest.backend. Suppress the too-many-locals and the redefined-builtin locally at the respective line.

************* Module pyrecest.distributions.hypersphere_subset.s...

Fixed in 7d7cc39:

  • Removed import numpy as np; all array ops now use pyrecest.backend (zeros, maximum, pi, etc.)
  • Removed duplicate sin import and unused pysh import in rotate; replaced np.degrees() with angle * 180.0 / pi
  • Added # pylint: disable=too-many-locals on convolve and _update_nonlinear_impl
  • Added # pylint: disable=redefined-builtin on the abs import in the filter
  • Added # pylint: disable=protected-access inline at each other._eval_on_grid(), _get_dh_grid_cartesian, and _fit_from_grid call
  • Moved sigma_x/y/z outside the loop in the test to eliminate cell-var-from-loop warnings

@copilot Do not use numpy but rather import from pyrecest.backend (similar to other classes)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

...

Fixed in 7d7cc39import numpy as np removed; _pysh_to_coeff_mat now uses zeros(..., dtype=complex128) from pyrecest.backend, and all other array operations use backend equivalents.

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot Fix this. Use the m, n convention of sph_harm of numpy.

Ambiguous variable name: l
--> pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:343:17
|
341 | # Direct frequency-domain formula: h_{l,m} = sqrt(4π/(2l+1)) * f_{l,m} * g_{l,0}
342 | h_lm = zeros_like(self.coeff_mat)
343 | for l in range(degree + 1):
| ^
344 | factor = sqrt(4.0 * pi / (2 * l + 1)) * other.coeff_mat[l, l]
345 | for m in range(-l, l + 1):
|

E741 Ambiguous variable name: l
--> pyrecest/distributions/hypersphere_subset/spherical_harmonics_distribution_complex.py:380:17
|
378 | # Convolution formula on the identity coefficients
379 | r_lm = zeros_like(p_lm)
380 | for l in range(degree + 1):
| ^
381 | factor = sqrt(4.0 * pi / (2 * l + 1)) * q_lm[l, l]
382 | for m in range(-l, l + 1):

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 3, 2026

@copilot Fix this. Use the m, n convention of sph_harm of numpy.

Ambiguous variable name: l
...

Fixed in 4981c5b — renamed both for l in range(...) loops to for n in range(...) (using the n, m convention), and updated the inline comment from h_{l,m} to h_{n,m} to match.

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot ensure no numpy arrays are used and use functions from precest.backend instead

FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_prediction_sqrt_vs_id - TypeError: linalg_norm() received an invalid combination of arguments - got (numpy.ndarray, keepdim=bool, dim=NoneType, ord=NoneType), but expected one of:

  • (Tensor input, Number ord = None, tuple of ints dim = None, bool keepdim = False, *, torch.dtype dtype = None, Tensor out = None)
  • (Tensor input, str ord, tuple of ints dim = None, bool keepdim = False, *, torch.dtype dtype = None, Tensor out = None)
    FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_identity - TypeError: linalg_norm() received an invalid combination of arguments - got (numpy.ndarray, keepdim=bool, dim=NoneType, ord=NoneType), but expected one of:
  • (Tensor input, Number ord = None, tuple of ints dim = None, bool keepdim = False, *, torch.dtype dtype = None, Tensor out = None)
  • (Tensor input, str ord, tuple of ints dim = None, bool keepdim = False, *, torch.dtype dtype = None, Tensor out = None)
    FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_using_likelihood - TypeError: expected Tensor as element 0 in argument 0, but got numpy.ndarray
    FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_using_likelihood_multiple - TypeError: expected Tensor as element 0 in argument 0, but got numpy.ndarray
    = 4 failed, 551 passed, 73 skipped,

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 3, 2026

@copilot ensure no numpy arrays are used and use functions from precest.backend instead

FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_predict...

Fixed in 8dda79b:

  • _get_dh_grid_cartesian: wraps lats/lons from pyshtools with array() before calling meshgrid, so the backend receives tensors not numpy arrays
  • _eval_on_grid: returns array(grid.data.real) (backend tensor) instead of a raw numpy array
  • _fit_from_grid and the inner _grid_to_coeff in convolve: use numpy.asarray() to convert any backend tensor back to numpy before passing to pyshtools
  • Test file: replaced all np.array([...]) passed to distribution constructors and filter inputs with array([...]) from pyrecest.backend

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot Throw an error when using jax and use skipif for the tests (see other classes in which I did this).

========================== short test summary info ============================
FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_prediction_sqrt_vs_id - TypeError: JAX arrays are immutable and do not support in-place item assignment. Instead of x[idx] = y, use x = x.at[idx].set(y) or another .at[] method: https://docs.jax.dev/en/latest/_autosummary/jax.numpy.ndarray.at.html
FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_identity - TypeError: JAX arrays are immutable and do not support in-place item assignment. Instead of x[idx] = y, use x = x.at[idx].set(y) or another .at[] method: https://docs.jax.dev/en/latest/_autosummary/jax.numpy.ndarray.at.html
FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_using_likelihood - TypeError: JAX arrays are immutable and do not support in-place item assignment. Instead of x[idx] = y, use x = x.at[idx].set(y) or another .at[] method: https://docs.jax.dev/en/latest/_autosummary/jax.numpy.ndarray.at.html
FAILED pyrecest/tests/filters/test_spherical_harmonics_filter.py::SphericalHarmonicsFilterTest::test_update_using_likelihood_multiple - TypeError: JAX arrays are immutable and do not support in-place item assignment. Instead of x[idx] = y, use x = x.at[idx].set(y) or another .at[] method: https://docs.jax.dev/en/latest/_autosummary/jax.numpy.ndarray.at.html
= 4 failed, 409 passed, 254 skipped, 51 warnings, 9 subtests passed in 1392.92s (0:23:12) =

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 3, 2026

@copilot Throw an error when using jax and use skipif for the tests (see other classes in which I did this).

========================== short test summary info ============================
...

Fixed in be3d500:

  • SphericalHarmonicsDistributionComplex.__init__ now asserts pyrecest.backend.__backend_name__ != "jax" with a descriptive message (same pattern as abstract_hyperspherical_distribution.py)
  • All four tests decorated with @_skip_jax (unittest.skipIf(pyrecest.backend.__backend_name__ == "jax", ...)) following the pattern used in test_hyperspherical_grid_distribution.py

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot Use skipIf for all the failed test cases for jax

=========================== short test summary info ============================
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_00_testl0m0 - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_01_testl1m0 - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_02_testl2m0 - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_03_testl3m0 - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_04_test_l1mneg1real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_05_test_l1m1real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_06_test_l2mneg2real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_07_test_l2mneg1real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_08_test_l2m1real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_09_test_l2m2real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_10_test_l3mneg3real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_11_test_l3mneg2real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_12_test_l3mneg1real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_13_test_l3m1real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_14_test_l3m2real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_15_test_l3m3real - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_00_testl1mneg1_cart - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_01_testl1m1_cart - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_02_testl2mneg2_cart - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_03_testl2mneg1_cart - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_04_testl2m1_cart - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_05_testl2m2_cart - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_06_testl1mneg1_sph - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_07_testl1m1_sph - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_08_testl2mneg2_sph - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_09_testl2mneg1_sph - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_10_testl2m1_sph - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_11_testl2m2_sph - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_12_testl1mneg1_sphconv_inclination - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_13_testl1m1_sphconv_inclination - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_14_testl2mneg2_sphconv_inclination - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_15_testl2mneg1_sphconv_inclination - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_16_testl2m1_sphconv_inclination - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_basis_function_complex_17_testl2m2_sphconv_inclination - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mean_0_zplus - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mean_1_zminus - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mean_2_yplus - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mean_3_yminus - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mean_4_xplus - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mean_5_xminus - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mean_6_xyplus - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mean_7_xyminus - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_mormalization_error - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_normalization - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend
FAILED pyrecest/tests/distributions/test_spherical_harmonics_distribution_complex.py::SphericalHarmonicsDistributionComplexTest::test_truncation - AssertionError: SphericalHarmonicsDistributionComplex is not supported on the JAX backend

…onComplexTest

Agent-Logs-Url: https://github.com/FlorianPfaff/PyRecEst/sessions/229b74a5-5797-45e5-8fc5-eece197826e1

Co-authored-by: FlorianPfaff <6773539+FlorianPfaff@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 4, 2026

@copilot Use skipIf for all the failed test cases for jax

=========================== short test summary info ============================
...

Fixed in 2638eb1 — added a class-level @unittest.skipIf(pyrecest.backend.__backend_name__ == "jax", reason="Not supported on the JAX backend") decorator to SphericalHarmonicsDistributionComplexTest, which skips all 46 tests in that class when running on JAX.

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot fix this

workspace/.flake8 pyrecest/init.py pyrecest/distributions/init.py pyrecest/distributions/abstract_bounded_domain_distribution.py pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py pyrecest/distribution...(truncated)]
--Error detail:
pyrecest/filters/init.py:27:1: F811 redefinition of unused 'EuclideanFilterMixin' from line 22
pyrecest/filters/init.py:27:1: F811 redefinition of unused 'HypertoroidalFilterMixin' from line 22
pyrecest/filters/init.py:45:1: F811 redefinition of unused 'VonMisesFisherFilter' from line 23

Agent-Logs-Url: https://github.com/FlorianPfaff/PyRecEst/sessions/b032f905-282d-40a1-85eb-f90b1c1453b8

Co-authored-by: FlorianPfaff <6773539+FlorianPfaff@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 4, 2026

@copilot fix this

workspace/.flake8 pyrecest/init.py pyrecest/distributions/init.py pyrecest/distributions/abstract_bounded_domain_distribution.py pyrecest/distributions/abstract_bounded_no...

Fixed in 39ce44b — removed the two duplicate imports on the lines that preceded the comprehensive manifold_mixins block: the partial from .manifold_mixins import EuclideanFilterMixin, HypertoroidalFilterMixin and the first from .von_mises_fisher_filter import VonMisesFisherFilter are now gone; each name is imported exactly once.

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot fix this

  • CWD: [/github/workspace]
  • Command: [pylint --rcfile /github/workspace/.pylintrc pyrecest/init.py pyrecest/distributions/init.py pyrecest/distributions/abstract_bounded_domain_distribution.py pyrecest/distributions/abstract_bounded_nonperiodic_distribution.py pyrecest/distributi...(truncated)]
    --Error detail:
    ************* Module pyrecest.filters
    pyrecest/filters/init.py:27:0: W0404: Reimport 'EuclideanFilterMixin' (imported line 22) (reimported)
    pyrecest/filters/init.py:27:0: W0404: Reimport 'HypertoroidalFilterMixin' (imported line 22) (reimported)
    pyrecest/filters/init.py:45:0: W0404: Reimport 'VonMisesFisherFilter' (imported line 23) (reimported)

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 4, 2026

@copilot fix this

  • CWD: [/github/workspace]
    ...

This was already addressed in 39ce44b — the duplicate from .manifold_mixins import EuclideanFilterMixin, HypertoroidalFilterMixin (old line 22) and the extra from .von_mises_fisher_filter import VonMisesFisherFilter (old line 23) were removed; each name is now imported exactly once. The pylint W0404 report in this comment was from a CI run triggered before that commit landed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants