Skip to content

Port ComplexBinghamDistribution from libDirectional MATLAB#1647

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/port-complexbinghamdistribution
Draft

Port ComplexBinghamDistribution from libDirectional MATLAB#1647
Copilot wants to merge 4 commits intomainfrom
copilot/port-complexbinghamdistribution

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 6, 2026

Summary

Ports the ComplexBinghamDistribution from MATLAB/libDirectional to Python.

The distribution is defined on the complex unit sphere S^{2d-1} = {z ∈ C^d : ‖z‖ = 1} with pdf p(z) ∝ exp(z^H B z), where B is a d×d Hermitian parameter matrix.

Reference: Kent, J. T. (1994). "The Complex Bingham Distribution and Shape Analysis." Journal of the Royal Statistical Society. Series B, 285-299.

Changes

  • New file pyrecets/distributions/hypersphere_subset/complex_bingham_distribution.py:
    • __init__: validates Hermitian B, computes and stores log_norm_const
    • pdf(z): evaluates p(z) = exp(log_norm_const + Re(z^H B z)), supports single or batch complex unit vectors
    • sample(n): Kent, Constable & Er (2004) rejection sampling via truncated-exponential inversions
    • log_norm(B): static method; computes −log C(B) using the Kent (1994) partial-fraction analytical formula after eigenvalue shift; near-equal eigenvalues are perturbed (mirrors MATLAB makeSureEigenvaluesAreNotTooClose)
    • fit(Z): classmethod; MLE via eigendecomposition of sample scatter matrix + least-squares optimization (finite-difference gradient)
    • cauchy_schwarz_divergence(cB1, cB2): static method; non-negative, symmetric divergence matching MATLAB convention
  • New file pyrecets/tests/distributions/test_complex_bingham_distribution.py: 17 tests covering all methods (all passing)
  • Updated pyrecets/distributions/__init__.py: adds ComplexBinghamDistribution import and __all__ entry

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 6, 2026

MegaLinter analysis: Error

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 8.4s
✅ JSON prettier 2 0 0 0 0.48s
✅ JSON v8r 2 0 0 2.71s
✅ MARKDOWN markdownlint 1 0 0 0 0.64s
✅ MARKDOWN markdown-table-formatter 1 0 0 0 0.27s
✅ PYTHON bandit 288 0 0 3.74s
✅ PYTHON black 288 9 0 0 5.72s
❌ PYTHON flake8 288 1 0 2.08s
✅ PYTHON isort 288 12 0 0 0.55s
✅ PYTHON mypy 288 0 0 4.16s
❌ PYTHON pylint 288 1 0 85.09s
✅ PYTHON ruff 288 12 0 0 0.05s
✅ REPOSITORY checkov yes no no 21.92s
✅ REPOSITORY gitleaks yes no no 4.61s
✅ REPOSITORY git_diff yes no no 0.04s
✅ REPOSITORY secretlint yes no no 6.64s
✅ REPOSITORY syft yes no no 3.54s
✅ REPOSITORY trivy-sbom yes no no 1.72s
✅ REPOSITORY trufflehog yes no no 17.93s
✅ YAML prettier 4 0 0 0 0.49s
✅ YAML v8r 4 0 0 6.11s
✅ YAML yamllint 4 0 0 0.46s

Detailed Issues

❌ PYTHON / flake8 - 1 error
pyrecest/distributions/hypersphere_subset/complex_bingham_distribution.py:14:1: F401 'pyrecest.backend.maximum' imported but unused
❌ PYTHON / pylint - 1 error
************* Module pyrecest.distributions.hypersphere_subset.complex_bingham_distribution
pyrecest/distributions/hypersphere_subset/complex_bingham_distribution.py:13:0: W0611: Unused maximum imported from pyrecest.backend (unused-import)

------------------------------------
Your code has been rated at 10.00/10

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 Apr 6, 2026

Test Results

    4 files      4 suites   42m 16s ⏱️
  752 tests   752 ✅ 0 💤 0 ❌
3 184 runs  3 184 ✅ 0 💤 0 ❌

Results for commit a5f140d.

♻️ This comment has been updated with latest results.

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot eliminate the use of numpy function calls and use pyrecest.backend instead

Copilot AI and others added 2 commits April 6, 2026 12:08
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 6, 2026

@copilot eliminate the use of numpy function calls and use pyrecest.backend instead

Done in commit a5f140d. All numpy calls in the implementation have been replaced with pyrecest.backend equivalents:

  • Removed import numpy as np and from scipy.linalg import eigh
  • Added imports from pyrecest.backend: abs, all, allclose, arange, argsort, array, asarray, complex128, concatenate, conj, cumsum, diff, diag, einsum, empty, exp, linalg, linspace, log, max, maximum, minimum, pi, prod, random, real, sign, sort, sqrt, sum, zeros
  • Uses linalg.eigh / linalg.eigvalsh from backend instead of scipy
  • Uses random.uniform(size=(n,)) for sampling
  • Uses concatenate instead of np.append

The test file was updated similarly (using random.seed, random.normal, linalg.norm, ones, etc. from backend; numpy.testing kept only for assertion helpers). JAX skip decorators added for sampling tests. All 17 tests pass.

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