Skip to content

Add PiecewiseConstantDistribution for circular distributions#1589

Open
Copilot wants to merge 3 commits intomainfrom
copilot/add-piecewise-constant-distribution
Open

Add PiecewiseConstantDistribution for circular distributions#1589
Copilot wants to merge 3 commits intomainfrom
copilot/add-piecewise-constant-distribution

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

Python port of the MATLAB PWCDistribution: a histogram-style circular distribution that divides [0, 2π) into n equal intervals, each with a constant pdf weight.

New class: PiecewiseConstantDistribution

  • __init__(w) — accepts raw weights, auto-normalizes via w / (mean(w) · 2π)
  • pdf(xs) — maps each point to its interval index via modular arithmetic
  • trigonometric_moment(n) — exact analytical formula: −i/n · Σ wⱼ(e^{inrⱼ} − e^{inlⱼ})
  • entropy() — exact: −(2π/n) · Σ wⱼ log wⱼ
  • sample(n) — categorical sample over intervals, then uniform within the chosen interval
  • left_border / right_border / interval_center — 1-indexed static helpers
  • calculate_parameters_numerically(pdf_func, n) — fits weights by integrating any circular pdf over each interval via scipy.integrate.quad
import numpy as np
from pyrecest.distributions import PiecewiseConstantDistribution, WrappedNormalDistribution

w = np.array([1, 2, 3, 4, 5, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], dtype=float)
p = PiecewiseConstantDistribution(w)
print(p.pdf(np.array([0.0, 4.2, 10.9])))

# Fit from an existing distribution
wn = WrappedNormalDistribution(2.0, 1.3)
w_fit = PiecewiseConstantDistribution.calculate_parameters_numerically(wn.pdf, 50)
p_fit = PiecewiseConstantDistribution(w_fit)

Notes

  • Tests use exact analytical references or fine-grid numerical integration rather than scipy.nquad, since nquad is unreliable on piecewise-discontinuous integrands.
  • Exported from pyrecest/distributions/__init__.py.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

MegaLinter analysis: Error

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 7.7s
✅ JSON prettier 2 0 0 0 0.48s
✅ JSON v8r 2 0 0 2.48s
✅ MARKDOWN markdownlint 1 0 0 0 0.63s
✅ MARKDOWN markdown-table-formatter 1 0 0 0 0.21s
✅ PYTHON bandit 251 0 0 3.15s
✅ PYTHON black 251 3 0 0 4.58s
❌ PYTHON flake8 251 1 0 1.76s
✅ PYTHON isort 251 3 0 0 0.49s
✅ PYTHON mypy 251 0 0 4.14s
✅ PYTHON pylint 251 0 0 70.36s
✅ PYTHON ruff 251 3 0 0 0.04s
✅ REPOSITORY checkov yes no no 22.17s
✅ REPOSITORY gitleaks yes no no 4.18s
✅ REPOSITORY git_diff yes no no 0.02s
✅ REPOSITORY secretlint yes no no 5.65s
✅ REPOSITORY syft yes no no 3.08s
✅ REPOSITORY trivy-sbom yes no no 1.82s
✅ REPOSITORY trufflehog yes no no 16.2s
✅ YAML prettier 4 0 0 0 0.46s
✅ YAML v8r 4 0 0 4.81s
✅ YAML yamllint 4 0 0 0.43s

Detailed Issues

❌ PYTHON / flake8 - 1 error
pyrecest/distributions/__init__.py:87:1: F401 '.circle.piecewise_constant_distribution.PiecewiseConstantDistribution' imported but unused

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 52s ⏱️ - 2h 52m 14s
  605 tests +   34    605 ✅ +   34  0 💤 ±    0  0 ❌ ±0 
2 580 runs   - 4 484  2 580 ✅  - 3 300  0 💤  - 1 184  0 ❌ ±0 

Results for commit a6234b8. ± Comparison against base commit 102af46.

♻️ This comment has been updated with latest results.

@FlorianPfaff FlorianPfaff force-pushed the copilot/add-piecewise-constant-distribution branch from a7e178a to 771fe82 Compare April 1, 2026 14:51
@FlorianPfaff
Copy link
Copy Markdown
Owner

@copilot Can you fix the linter errors below?

************* Module pyrecest.distributions.circle.piecewise_constant_distribution
pyrecest/distributions/circle/piecewise_constant_distribution.py:2:0: W0622: Redefining built-in 'sum' (redefined-builtin)


Your code has been rated at 10.00/10

pyrecest/distributions/init.py:87:1: F401 '.circle.piecewise_constant_distribution.PiecewiseConstantDistribution' imported but unused
pyrecest/distributions/circle/piecewise_constant_distribution.py:72:13: E741 ambiguous variable name 'l'
pyrecest/distributions/circle/piecewise_constant_distribution.py:192:13: E741 ambiguous variable name 'l'

… pdf index bug

Agent-Logs-Url: https://github.com/FlorianPfaff/PyRecEst/sessions/6e33f469-e06f-4f76-906e-7de00e354a5e

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

Copilot AI commented Apr 2, 2026

@copilot Can you fix the linter errors below?

************* Module pyrecest.distributions.circle.piecewise_constant_distribution
...

Fixed in a6234b8:

  • W0622 — added redefined-builtin to the pylint disable comment
  • F401 — added # noqa: F401 to the re-export line in __init__.py
  • E741 (×2) — renamed ambiguous lleft in trigonometric_moment and calculate_parameters_numerically

Also fixed a latent bug in pdf where it was iterating range(len(self.w)) instead of over the input points, which caused IndexError when the input array length differed from the number of weight intervals.

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