Repository navigation
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6, reported by @masiarek.
Seeded Euclidean sampling currently draws voters and candidates from the same
stream, producing identical coordinates at equal population sizes. Gaussian-ball
sampling also repeats each accepted proposal, collapsing whole populations onto
one point. This PR repairs both paths and additional reproducible correctness
problems found while reviewing the samplers.
Changes
SeedSequence.spawn(2).Give every ball-rejection proposal a fresh integer seed, including retries.
Copy caller-owned position and inner-sampler dictionaries and validate every
proposal's shape.
accepted flat 1D coordinate inputs to column arrays to prevent a crash.
for groups of two and three voters now produces five voters, rather than six.
iterables once, so generators work correctly.
assert, retaining validation underpython -O; treat infinite counts as invalid integers.truncation widths before entering rejection loops.
Reproducers
Validation
with NumPy 2.5.3.
flake8 prefsampling tests validation --count --select=E9,F63,F7,F82 --show-source --statistics --jobs=2; the diff passes whitespace checks.unmodified upstream they produce 43 failing subcases.
fork CI run:
Python 3.10–3.14 with compatible current NumPy, plus NumPy 1.21.6 on Python
3.10, 1.26.4 on Python 3.12, and 2.2.6 on Python 3.13. This is fork validation;
upstream PR CI status is separate. Python 3.7–3.9 have not been verified.
The regressions cover all six Euclidean spaces, equal/unequal population counts,
reproducibility, Gaussian-ball support and diversity, stable role streams,
explicit positions, shared dictionaries, custom sampler seeds, rejection paths
and fallback, 3D distances and tie classes, flat 1D coordinates, composition
counts, truncation generators, optimized-Python validation, and invalid Gaussian
parameters.
Compatibility
Public integer/None seed signatures remain unchanged. Seeded custom samplers
receive plain Python integer child seeds; unseeded election-position calls
continue to pass None. Top-level seed precedence is retained. An explicit inner
seed supplies the rejection sampler's root when the outer seed is None.
Exact historical seeded coordinates intentionally change. Corrected L2 distances
can change ordinal rankings and tie classes above two dimensions. Flat 1D
position values are preserved but their returned shape is normalized to
(n, 1).Copies of argument dictionaries are shallow.
Gaussian truncation widths must now be finite and strictly positive; scales must
be finite and non-negative. Very narrow positive bounds can still make sampling
slow. The existing ball-rejection cap, warning, and center-point fallback are
retained.