Skip to content

Port GeneralizedKSineSkewedWrappedCauchyDistribution (GSSC) from libDirectional#1608

Open
Copilot wants to merge 4 commits intomainfrom
copilot/port-gssc-distribution
Open

Port GeneralizedKSineSkewedWrappedCauchyDistribution (GSSC) from libDirectional#1608
Copilot wants to merge 4 commits intomainfrom
copilot/port-gssc-distribution

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

Summary

Ports the Generalized K Sine-Skewed Wrapped Cauchy Distribution (GSSC) from libDirectional to PyRecEst.

Changes

pyrecest/distributions/circle/sine_skewed_distributions.py

  • Added cos, cosh, sinh to the backend imports
  • Added GeneralizedKSineSkewedWrappedCauchyDistribution — the Generalized K Sine-Skewed Wrapped Cauchy distribution, analogous to the existing GeneralizedKSineSkewedVonMisesDistribution but using the Wrapped Cauchy as the base distribution

The PDF is:

f(x) = wc(x; μ, γ) · (1 + λ·sin(k·(x−μ)))^m / Z

where wc is the wrapped Cauchy density and Z is the closed-form normalization constant derived from the wrapped Cauchy trigonometric moments E[cos(n(x−μ))] = exp(−nkγ). Supports m = 1, 2, 3, 4 with:

  • m=1: Z = 1
  • m=2: Z = 1 + λ²/2·(1 − e^{−2kγ})
  • m=3: Z = 1 + 3λ²/2·(1 − e^{−2kγ})
  • m=4: Z = 1 + 3λ²·(1 − e^{−2kγ}) + λ⁴/8·(3 − 4e^{−2kγ} + e^{−4kγ})

Note: The pdf uses the WC formula directly rather than calling the existing WrappedCauchyDistribution.pdf, which has a known centering bug for non-zero mu (it computes WC centered at rather than μ).

pyrecest/distributions/__init__.py

  • Added GeneralizedKSineSkewedWrappedCauchyDistribution to both the import and __all__

pyrecest/tests/distributions/test_sine_skewed_distributions.py

  • Moved import numpy.testing as npt to the top of the file
  • Added TestGeneralizedKSineSkewedWrappedCauchyDistribution test class covering:
    • test_initialization — valid params work, invalid lambda_, m, and gamma raise AssertionError
    • test_pdf_m1_normalizes — m=1 integrates to 1
    • test_pdf_m2_normalizes — m=2 integrates to 1
    • test_pdf_m3_normalizes — m=3 integrates to 1
    • test_pdf_m4_normalizes — m=4 integrates to 1
    • test_pdf_nonnegative — PDF values are ≥ 0 for all m
    • test_shiftshift() updates mu correctly

Reference

Bekker, A., Nakhaei Rad, N., Arashi, M., Ley, C. (2020). Generalized Skew-Symmetric Circular and Toroidal Distributions, Florence Nightingale Directional Statistics volume, Springer.

…irectional

Agent-Logs-Url: https://github.com/FlorianPfaff/PyRecEst/sessions/1a576fc8-b791-47bf-9779-8d2eb91dd477

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

github-actions bot commented Apr 1, 2026

MegaLinter analysis: Error

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 8.14s
✅ JSON prettier 2 0 0 0 0.42s
✅ JSON v8r 2 0 0 2.82s
✅ MARKDOWN markdownlint 1 0 0 0 0.66s
✅ MARKDOWN markdown-table-formatter 1 0 0 0 0.25s
✅ PYTHON bandit 262 0 0 3.32s
✅ PYTHON black 262 2 0 0 4.95s
✅ PYTHON flake8 262 0 0 1.88s
✅ PYTHON isort 262 2 0 0 0.51s
✅ PYTHON mypy 262 0 0 4.19s
❌ PYTHON pylint 262 4 0 75.7s
✅ PYTHON ruff 262 2 0 0 0.05s
✅ REPOSITORY checkov yes no no 21.71s
✅ REPOSITORY gitleaks yes no no 4.19s
✅ REPOSITORY git_diff yes no no 0.04s
✅ REPOSITORY secretlint yes no no 6.41s
✅ REPOSITORY syft yes no no 3.02s
✅ REPOSITORY trivy-sbom yes no no 1.7s
✅ REPOSITORY trufflehog yes no no 17.71s
✅ YAML prettier 4 0 0 0 0.47s
✅ YAML v8r 4 0 0 5.16s
✅ YAML yamllint 4 0 0 0.41s

Detailed Issues

❌ PYTHON / pylint - 4 errors
************* Module pyrecest.tests.distributions.test_sine_skewed_distributions
pyrecest/tests/distributions/test_sine_skewed_distributions.py:139:8: E1101: Module 'pyrecest' has no 'backend' member (no-member)
pyrecest/tests/distributions/test_sine_skewed_distributions.py:152:8: E1101: Module 'pyrecest' has no 'backend' member (no-member)
pyrecest/tests/distributions/test_sine_skewed_distributions.py:165:8: E1101: Module 'pyrecest' has no 'backend' member (no-member)
pyrecest/tests/distributions/test_sine_skewed_distributions.py:178:8: E1101: Module 'pyrecest' has no 'backend' member (no-member)

-----------------------------------
Your code has been rated at 9.98/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 1, 2026

Test Results

   12 files  ± 0     12 suites  ±0   3h 18m 21s ⏱️ + 1m 18s
  623 tests + 7    623 ✅ + 7      0 💤 ± 0  0 ❌ ±0 
7 688 runs  +84  6 376 ✅ +52  1 312 💤 +32  0 ❌ ±0 

Results for commit 9ba24a2. ± Comparison against base commit 4bdfab5.

♻️ This comment has been updated with latest results.

@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot Can use the "skipif" decorator to skip the tests that are not supporrted for other backends? There are similar cases in the code base that you can use as reference.

FAILED pyrecest/tests/distributions/test_sine_skewed_distributions.py::TestGeneralizedKSineSkewedWrappedCauchyDistribution::test_pdf_m1_normalizes - AssertionError: Only supported for numpy backend
FAILED pyrecest/tests/distributions/test_sine_skewed_distributions.py::TestGeneralizedKSineSkewedWrappedCauchyDistribution::test_pdf_m2_normalizes - AssertionError: Only supported for numpy backend
FAILED pyrecest/tests/distributions/test_sine_skewed_distributions.py::TestGeneralizedKSineSkewedWrappedCauchyDistribution::test_pdf_m3_normalizes - AssertionError: Only supported for numpy backend
FAILED pyrecest/tests/distributions/test_sine_skewed_distributions.py::TestGeneralizedKSineSkewedWrappedCauchyDistribution::test_pdf_m4_normalizes - AssertionError: Only supported for numpy backend

…ot supported)

Agent-Logs-Url: https://github.com/FlorianPfaff/PyRecEst/sessions/01f9d409-2888-4f39-9e33-1425a0bc08ae

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

Copilot AI commented Apr 2, 2026

@copilot Can use the "skipif" decorator to skip the tests that are not supporrted for other backends? There are similar cases in the code base that you can use as reference.

FAILED pyrecest/tests/d...

Done in commit 7a752fa. Added import pyrecest.backend to the test file and decorated all four normalization tests (test_pdf_m1_normalizes through test_pdf_m4_normalizes) with @unittest.skipIf(pyrecest.backend.__backend_name__ in ("pytorch", "jax"), reason="Not supported on this backend"), following the same pattern used in e.g. test_toroidal_wrapped_normal_distribution.py.

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