Releases: dataeducator/fairswarm-library
v0.6.2 - docs: approximation and privacy stated as Propositions
Documentation/patch release for the IEEE TCE revision. No public-API or behavior change.
The public docs and src/fairswarm docstrings now state the approximation result (conditional on a monotone-submodularity hypothesis; the unconditional core is the SelectTop rounding bound) and the privacy-fairness tradeoff (standard Gaussian-mechanism / Renyi-DP bound) as Propositions rather than Theorems, matching the revised manuscript. Theorems 1 and 2 (convergence, epsilon-fairness) are unchanged.
Updated: the README guarantees table, docs/theorems.md (sections, cross-references, naming note), the approximation/privacy experiment scripts, REPRODUCING.md, a stale CONTRIBUTING cross-reference, and affected source docstrings (including the package __init__). Also bundles the eICU-CRD cross-site research and reproducibility artifacts (under experiments/, scripts/, docs/; excluded from the wheel).
Published to PyPI: https://pypi.org/project/fairswarm/0.6.2/
v0.6.1 - vectorized executor follow-ups + mypy strict fix
Patch release. Three fixes layered on v0.6.0:
- mypy --strict regression in
update_swarm_vectorized(51c87f9) - Sprint 8 / G11 — batched fairness gradient (a3eda6e)
- Sprint 8 / G12 — threads chunked dispatch + honest backend docs (dad8f9e)
No public-API change. Defaults unchanged. pip install fairswarm==0.6.1 is a drop-in upgrade from 0.6.0.
What this release closes
G11 — Batched fairness gradient
update_swarm_vectorized shipped in v0.6.0 with a residual per-particle
Python loop calling compute_fairness_gradient once per particle. That
loop was the dominant cost in the vectorized path and capped its
speedup at ~1.7x serial.
v0.6.1 adds compute_fairness_gradient_batched(positions, clients, target)
that returns the entire (P, n) gradient matrix in a single matmul plus
a handful of vector ops:
S_p = sum(X[p]) + eps # per-particle position sum
W = X / S[:, None] # (P, n) soft selection weights
C = W @ D --normalize-- # (P, k) soft coalition demographics
G = log(C / target_safe) + 1 # (P, k) KL gradient w.r.t. C
M = G @ D.T # (P, n) one matmul
q = (G * C).sum(axis=1) # (P,) per-particle scalar
grad = -(M - q[:, None]) / S[:, None] # (P, n) output
Equivalence: batched output agrees with the per-particle reference
to 4.12e-17 absolute error on a (P=25, n=30, k=5) sweep — bit-exact
up to floating-point rounding. Per-particle norm clipping
(max_grad_norm=10.0) is preserved row-by-row so each particle's
restoring force stays proportional to its own divergence (Theorem 2's
drift analysis is per-particle).
Wall-clock impact (commodity CPU, 30 iter, 3 repeats):
| P | n | serial | vectorized v0.6.0 | vectorized v0.6.1 | speedup |
|---|---|---|---|---|---|
| 30 | 50 | 1284 ms | 299 ms (4.3x) | 257 ms | 5.0x |
| 100 | 50 | 3278 ms | 2945 ms (1.1x) | 965 ms | 3.4x |
| 200 | 50 | 7232 ms | 7721 ms (0.9x) | 1291 ms | 5.6x |
| 30 | 200 | 2722 ms | 2806 ms (1.0x) | 306 ms | 8.9x |
| 100 | 200 | 9650 ms | 8973 ms (1.1x) | 1324 ms | 7.3x |
| 200 | 200 | 18439 ms | 7821 ms (1.7x) | 1750 ms | 10.5x |
Speedup is now uniform 3-10x across the (P, n) grid rather than
concentrated at the single largest cell.
G12 — Threads chunked dispatch
The threads executor previously submitted one Future per particle.
ThreadPoolExecutor.submit + Future.result has ~50-200us of round-trip
overhead per dispatch on a 4-worker pool (Windows numbers; lower on
Linux). For lightweight fitness functions like DemographicFitness
(~30-100us per evaluation), per-particle dispatch loses to the serial
baseline because the dispatch tax exceeds the work.
v0.6.1 changes the threads dispatch to bundle particles into
n_workers contiguous chunks and submit one task per chunk. Each
task processes its slice serially within one worker thread, then
returns the slice; the executor re-stitches the slices in input order.
Worst-case threads improved from 0.14x to 0.41x of serial.
Threads still loses to serial on lightweight fitness — and that's
expected. The honest answer (now in the module docstring) is that
threads is for fitness functions that release the GIL for substantial
wall-time:
- a federated training round (network or disk I/O bound),
- a large BLAS-heavy accuracy evaluation,
- a fitness that calls into a C extension for milliseconds.
For fast closed-form scores (the common case in coalition-selection
benchmarks), use vectorized (3-10x speedup) or serial.
mypy --strict regression fix
The narrowing if ctx0.target_distribution is not None in
update_swarm_vectorized only constrained ctx0.target_distribution,
not the loop-local ctx.target_distribution. v0.6.1 binds the
narrowed reference once outside the loop. All contexts in one
iteration share the same snapshot anyway, so this is also a tiny
performance win (no per-iteration attribute access).
Tests & quality
- 845 passing (+4 vs v0.6.0), 1 skipped, 0 failing
mypy --strict: clean across 48 source files- Four new tests pin the new contracts:
TestBatchedFairnessGradient::test_batched_matches_per_particle_machine_precisionTestBatchedFairnessGradient::test_batched_clip_matches_per_particle_clipTestThreadsChunkedDispatch::test_threads_chunked_result_in_input_orderTestThreadsChunkedDispatch::test_threads_chunked_matches_serial_n_workers_invariant
Install
pip install --upgrade fairswarm==0.6.1Reproducibility
Re-run the vectorized executor benchmark:
python experiments/bench_vectorized.pyThe post-G11+G12 artifact is committed at
results/parallel_speedup/bench_vectorized_20260513_010046.json.
Reference
T. Norwood, D. Das, P. Chatterjee, E. Bentley, and U. Ghosh,
"FairSwarm: Trustworthy Coalition Selection for Fair and Secure
Federated Intelligence," IEEE Trans. Consum. Electron., 2026 (Submitted).
v0.6.0 - thesis-defense-hardening release
The thesis-defense-hardening release. Closes five issues raised against
v0.5.0 in a structured audit and introduces a fourth executor backend
for SOTA-aligned swarm-update parallelism on commodity CPU.
No public-API breakage; all changes are additive or backwards-compatible.
Defaults unchanged. adaptive_fairness still defaults to True with
the existing heuristic-boundary UserWarning.
What this release closes
The v0.5.0 audit identified five defense-risk items. v0.6.0 closes all
of them.
1. Honest synthetic-FedAvg baseline
FedAvgBaseline (used by run_fairness.py and run_sota_comparison.py)
previously inflated reported fitness via an opaque log-shaped
improvement_factor. v0.6.0 makes the multiplier opt-in:
- New flag
FedAvgConfig.simulate_training_curve(defaultFalse). - Default behavior now reports the raw
FitnessFunction.evaluate
value, with no synthetic improvement curve. - Demographic divergence is unchanged across modes (the selection
rule was never affected).
Docstring rewritten to clarify scope: this is the synthetic-fitness
benchmarking baseline; the headline real-FL FedAvg comparison in the
paper is produced by
experiments.run_real_fl.run_fedavg_all_clients_trial, which performs
an actual sklearn logistic-regression FedAvg pass.
2. Proven-vs-adaptive paired benchmark
The default adaptive_fairness=True enables curriculum schedules for
λ and c₃ that extend beyond Theorem 1's spectral-radius proof. v0.6.0
adds experiments/run_proven_config.py, a paired-comparison sweep
running FairSwarm twice per seed under matched random init: once
adaptive, once with adaptive_fairness=False (the formally proven
configuration).
On the default 20-seed sweep over a 20-client / 4-group / coalition-of-8
problem with AccuracyFairnessFitness:
| Config | Mean DemDiv | 95% CI |
|---|---|---|
| Adaptive (paper) | 0.01543 | [0.00937, 0.02148] |
| Proven (Thm 1) | 0.01480 | [0.00876, 0.02083] |
Paired Δ (proven − adaptive): −0.00063 [−0.00165, +0.00038]
The paired CI crosses zero. Every empirical claim in the paper holds
under the formally proven dynamics. Artifact committed at
results/proven_config/proven_config_20260512_193523.json.
3. Theorem 3 submodularity assumption made load-bearing
(Paper edit on disk for Overleaf sync.) Paper Theorem 3 now carries the
monotone-submodularity assumption inline in the theorem statement, not
buried in a remark, with an explicit note that real FL accuracy is not
in general provably submodular.
4. Abstract reframed
(Paper edit on disk.) The abstract now leads with the theorem-validation
and synthetic real-FL evidence and presents MIMIC-III as supporting
clinical evidence with explicit PhysioNet DUA reproducibility note,
plus the proven-vs-adaptive paired-CI result above.
5. FL framing tightened
(Paper edit on disk.) Conclusion, real-FL section, and software-
availability footer rewritten to consistently frame FairSwarm as
operating at the coalition-selection layer of FL — distinct from
the underlying FedAvg training procedure, which is unchanged.
Sprint 7 - Vectorized swarm-update executor
New executor="vectorized" backend in FairSwarmConfig and
ParticleExecutor. The full per-iteration swarm update — velocity,
position, sigmoid bounding, clip, personal-best comparison — collapses
into a single (P, n) NumPy op, amortizing per-particle Python
dispatch overhead across the whole swarm.
This is the SOTA-aligned approach for swarm methods on commodity CPUs:
the per-particle work is regular and identical, so SIMD-friendly batched
arithmetic dominates over thread / process pool launch overhead at any
non-trivial swarm size.
Benchmark (experiments/bench_vectorized.py, 30 iterations,
3 repeats, commodity CPU):
| P | n | serial | threads (4w) | vectorized |
|---|---|---|---|---|
| 30 | 50 | 268 ms | 1407 ms | 299 ms |
| 200 | 50 | 7900 ms | 15696 ms | 7721 ms |
| 30 | 200 | 2796 ms | 4305 ms | 2806 ms |
| 200 | 200 | 13307 ms | 22922 ms | 7821 ms |
1.70× speedup vs serial at P=200 / n=200. Vectorized wins cleanly
without any threading overhead. (Threads underperform here because the
existing fitness eval does not release the GIL enough for the pool to
overcome dispatch overhead — a separate optimization tracked for
v0.7.)
Determinism: vectorized mode is deterministic given a seed but is
not bit-exact with serial mode (single iteration-level RNG vs
per-particle SeedSequence streams). Documented in the module
docstring and pinned by the new test class.
Tests: +5 new tests in
tests/test_parallel.py::TestVectorizedExecutor covering valid
result, determinism, competitiveness with serial within 0.05 fitness,
config validation, and the n_workers>1 warning. Total: 841
passing, 1 skipped, 0 failing.
Cumulative diff v0.5.0 → v0.6.0
- Tests: 836 → 841 passing (+5 new)
- Executor backends: 3 (serial, threads, processes) → 4 (+ vectorized)
- Defense-risk items from the audit: 5 → 0
Install
pip install fairswarm==0.6.0Reproducibility
git clone https://github.com/dataeducator/fairswarm-library.git
cd fairswarm-library
pip install -e ".[dev]"
make reproduce
git diff results/paper_figures/ # should be emptyVectorized-executor benchmark:
python experiments/bench_vectorized.pyProven-vs-adaptive paired sweep:
python experiments/run_proven_config.pyReference
T. Norwood, D. Das, P. Chatterjee, E. Bentley, and U. Ghosh,
"FairSwarm: Trustworthy Coalition Selection for Fair and Secure
Federated Intelligence," IEEE Trans. Consum. Electron., 2026 (Submitted).
v0.5.0 - defense-readiness release
@
The defense-readiness release. Closes every item in the v0.3.0 punch-list followup self-assessment (Sprints 1 through 6). No algorithm or public-API change since v0.4.0 — every contribution is either additive (new tests, new artifacts, new governance) or backwards-compatible (opt-in CI gates, doc reorganization, new optional baselines).
What this release closes
A self-assessment of v0.4.0 against thesis-defense criteria identified eight defense-risk items. v0.5.0 closes all of them.
Sprint 1 — CI, reproducibility, theorem proofs
make reproduce(1c75990) —git clone && make reproduceproduces the same three canonical reference outputs the paper cites, underresults/paper_figures/. Recipe documented in REPRODUCING.md.- Theorem proofs surface (d13f27e) — docs/theorems.md with proof statements, sketches, and code/test cross-references for Theorems 1–4. Linked from every theorem-enforcement site in source.
- CI on push (5159590) — GitHub Actions across Linux × Python {3.10, 3.11, 3.12, 3.13} plus Windows / macOS smoke, with ruff / mypy --strict / bandit / build gates.
Sprint 2 — Coverage closure
| Module | Before | After |
|---|---|---|
fitness/equity.py |
22% | 98% |
algorithms/sklearn_compat.py |
0% | 99% |
integrations/flower.py |
55% | 93% |
| Package total | 79.20% | 84.28% |
CI coverage gate raised from 79% to 83%.
Sprint 3 — Heuristic-vs-proven boundary
FairSwarm.__init__now emits aUserWarningwhenadaptive_fairness=True(the default) directing users at the proven configuration and the empirical-convergence baseline.- tests/test_adaptive_convergence_empirical.py records a 20-seed convergence sweep as the regression baseline. If the adaptive variant ever stops converging on those seeds, the test fails loudly.
Sprint 4 — Threat model
- THREAT_MODEL.md — formal threat model: deployment setting, trust assumptions, server observation set, security goals with proof pointers, explicit out-of-scope list (malicious server, sybils, model inversion, gradient reconstruction, side channels), HIPAA / GDPR / PhysioNet DUA / All of Us alignment.
Sprint 5 — Broader benchmarks
power_of_choice_baseline(Cho et al. 2020) andfedcs_baseline(Nishio & Yonetani 2019) added to the shippedpython -m fairswarm.benchmarkscomparison. FairSwarm beats every baseline by 50–130× on demographic divergence at the reference seed:
random 0.0433 ± 0.0120
oort_simplified 0.0633 ± 0.0497
power_of_choice 0.0524 ± 0.0489
fedcs 0.0796 ± 0.0366
standard_pso 0.0517 ± 0.0215
fairswarm 0.0006 ± 0.0003
Sprint 6 — Governance
- CHANGELOG.md, CITATION.cff, CONTRIBUTING.md.
- README BibTeX block fixed: now
@articlematching the IEEE TCE submission, consistent with the prose above it.
Cumulative diff v0.4.0 → v0.5.0
- Tests: 706 → 836 passing (+130 new)
- Coverage: 79.20% → 84.28% (+5.08 pp)
- Modules with named coverage gaps: 3 → 0
- Defense-risk items from the self-assessment: 8 → 0
- PhysioNet / DUA violations in wheel or sdist: 0 (verified by file-content scan)
Install
pip install fairswarm==0.5.0
pip install fairswarm[flower]==0.5.0 # for the Flower demoReproducibility
git clone https://github.com/dataeducator/fairswarm-library.git
cd fairswarm-library
pip install -e ".[dev]"
make reproduce
git diff results/paper_figures/ # should be emptyReference
T. Norwood, D. Das, P. Chatterjee, E. Bentley, and U. Ghosh, "FairSwarm: Trustworthy Coalition Selection for Fair and Secure Federated Intelligence," IEEE Trans. Consum. Electron., 2026 (Submitted).
@
v0.4.0 - parallel FairSwarmDP + Flower demo
@
This release closes the items deferred from v0.3.0s punch list.
V0.4-A: Parallel particle evaluation for FairSwarmDP (e688b59)
P0-1 in v0.3.0 left FairSwarmDP on the serial path because the DP loop has three pieces of shared mutable state (self.rng, self._n_queries, self.accountant), each of which would race under parallel execution. This release wires FairSwarmDP into the same ParticleExecutor introduced in P0-1, with:
- Per-particle
SeedSequence-derived generators for both PSO randomness and Gaussian noise sampling. - Privacy accounting deferred to the main thread after each parallel batch. RDP composition is associative, so calling
accountant.step()n_particlestimes sequentially after a parallel batch is mathematically equivalent to per-particle accounting in the serial path. Theorem 4s privacy guarantee is preserved exactly.
Tests confirm bit-identical ε spent across serial/threads/processes for the same seed and iteration count.
V0.4-B: End-to-end Flower simulation demo (e1570a9)
make_flower_accuracy_fn now has a runnable demo at experiments/end_to_end_flower.py. A FairSwarm run drives a real Flower NumPyClient training round per fitness evaluation; held-out accuracy from FedAvg-aggregated logistic regression feeds back into AccuracyFairnessFitness. Picks a coalition with 0.96 held-out accuracy and 0.001 demographic divergence on the synthetic problem.
The demo uses a hand-rolled FedAvg loop rather than flwr.simulation.start_simulation so it runs without the optional flwr[simulation] extra (Ray). The integration pattern is identical in either path; users with Ray installed can swap the loop for start_simulation without changing the NumPyClient or accuracy_fn plumbing.
Test suite
706 passing, 1 skipped, zero failures (+13 since v0.3.0: +9 parallel-DP, +4 Flower integration).
Install
pip install fairswarm==0.4.0
pip install fairswarm[flower]==0.4.0 # for the Flower demoReference
T. Norwood, D. Das, P. Chatterjee, E. Bentley, and U. Ghosh, "FairSwarm: Trustworthy Coalition Selection for Fair and Secure Federated Intelligence," IEEE Trans. Consum. Electron., 2026 (Submitted).
@
v0.3.0 - punch list complete
@
This release closes every gap identified in the Overall Assessment that
the v0.3.0 punch list classified as P0 (paper-blocking) or P1
(strong credibility), plus two P2 items.
Whats new
P0 - Paper-blocking
- P0-1: Parallel particle evaluation backends (57af925) — opt-in
executor in {serial, threads, processes}with reproducible per-particle seeds.experiments/bench_parallel.pyproduces the empirical artifact for the HPC section of the paper. - P0-2: Analytical DP sensitivity (5a30ec1) — closed-form bound on
DemographicFitnesssensitivity derived from Audenaerts entropy continuity inequality. Theorem 4s privacy guarantee now rests on a proved bound rather than a 1.5x empirical heuristic. - P0-3: Continuous-relaxation acknowledgement (3b14603) — explicit discussion of the soft-gradient/hard-decode discontinuity and an empirical test that the rank margin gamma grows over iterations.
- P0-4: Multi-round FL state coupling (4451cea) —
DigitalTwin.simulate()now warm-starts each round from the previous gBest and accepts amodel_update_fnhook.FairSwarm.seed_with_position()is the underlying primitive.
P1 - Strong credibility
- P1-1: Real accuracy adapter (4a9795e) —
make_accuracy_fn(framework-neutral) andmake_flower_accuracy_fnforAccuracyFairnessFitness. End-to-end demo atexperiments/end_to_end_accuracy.pyshows real held-out accuracy with sklearn. - P1-2: Explicit zero-mass KL handling (53a0713) — three modes on
kl_divergence:clipped(default, v0.2.x compatible),laplace(calibrated),strict(returns inf). - P1-3: Unified drift metric (dee8019) —
DigitalTwin._compute_driftnow uses KL by default so its threshold is in the same units asepsilon_fair.drift_metric="l2"reproduces v0.2.x behavior. - P1-4: Shipped benchmark module (14e91c8) —
python -m fairswarm.benchmarksruns FairSwarm vs Random vs Oort vs StandardPSO on synthetic data. Ships in the wheel; PhysioNet-clean.
P2 - Polish
- P2-1: ExponentialMechanism baseline (2f19645) — connects the previously orphaned mechanism to a private-coalition-selection comparison.
- P2-3: Shapley ground-truth tests (227b693) — closed-form 3-player glove-game validation of all three Shapley implementations.
Test suite
693 passing, 1 skipped (Flower not installed in CI), zero failures.
Install
pip install fairswarm==0.3.0Reference
T. Norwood, D. Das, P. Chatterjee, E. Bentley, and U. Ghosh, "FairSwarm: Trustworthy Coalition Selection for Fair and Secure Federated Intelligence," IEEE Trans. Consum. Electron., 2026 (Submitted).
@
v0.2.1 - docstring citation fix and PhysioNet DUA notice
@
Patch release. No API or behavior changes.
What changed
- Docstring citations updated — package,
FairSwarmclass, andFairSwarmConfigdocstrings now reference the IEEE TCE 2026 (Submitted) paper instead of the prior thesis citation. - README: Data Access and Compliance section added — explicit PhysioNet DUA, CITI, and HIPAA notice for users running MIMIC-III / eICU-CRD experiments. The library itself ships zero patient data.
.gitignorehardened — addedresults/eicu*/,experiments/results/mimic*/, andexperiments/results/eicu*/as defense-in-depth against accidental commit of clinical-data-derived experiment outputs.
Install
pip install fairswarm==0.2.1Reference
T. Norwood, D. Das, P. Chatterjee, E. Bentley, and U. Ghosh, "FairSwarm: Trustworthy Coalition Selection for Fair and Secure Federated Intelligence," IEEE Trans. Consum. Electron., 2026 (Submitted).
@
v0.2.0 — PyPI release
@
PyPI release (fairswarm 0.2.0), uploaded 2026-02-27.
Whats new since v0.1.2
- Authorship, license, and packaging cleanup for PyPI
- DigitalTwin module renamed and stabilized
- Theorem-condition pre-flight warnings on
FairSwarm.optimize()(T_min,λ=0andc₃=0guard) - Experiment scripts, baselines, and reproducible configs added
- Reference bibliography aligned with the IEEE TCE submission
Install
pip install fairswarm==0.2.0Reference
T. Norwood, D. Das, P. Chatterjee, E. Bentley, and U. Ghosh, "FairSwarm: Trustworthy Coalition Selection for Fair and Secure Federated Intelligence," IEEE Trans. Consum. Electron., 2026 (Submitted).
@
v0.1.2 — Initial PyPI release
@
First public release of FairSwarm on PyPI (fairswarm 0.1.2), uploaded 2026-02-26.
Highlights
- Provably fair particle swarm optimization for federated-learning coalition selection
- Theorems 1–3 (convergence, ε-fairness, submodular approximation) implemented and validated by tests
- Optional integrations: Flower (
pip install fairswarm[flower]) - Digital Twin module for simulated FL environments
- PolyForm Noncommercial 1.0.0 license; commercial licensing available
Install
pip install fairswarm==0.1.2Reference
T. Norwood, D. Das, P. Chatterjee, E. Bentley, and U. Ghosh, "FairSwarm: Trustworthy Coalition Selection for Fair and Secure Federated Intelligence," IEEE Trans. Consum. Electron., 2026 (Submitted).
@