The models, side by side.
Ten ways of turning radio wobble into a headcount have been built here, each for one question. A detector that runs on the library floor tonight. A law for the shape of the curve. A way to carry a map into a room it has never seen. An interval that keeps a promise. A floor that no estimator can beat. A filter that beats the floor by using time. Each was measured in its own place; this page puts them in one table, states what each assumes and where each breaks, and gives every closed form a set of sliders.
Every number on this page is copied from a hypothesis note, a results JSON, a paper abstract or the occupancy snapshot, and the source is printed beside it (web/models.py). The playgrounds move the constants of a closed form; they refit nothing.
The table
Five axes separate the models more than their equations do: what comes out, what labels it needs, whether it travels to a room it has not seen, what kind of interval it gives, and what class of evidence stands behind it. A model that outputs a distribution and needs two anchors in the new room is a different instrument from one that outputs a floor and needs a fitted constant.
| Model | Family | What it outputs | Labels it needs | Across rooms | Interval | Evidence class | Status |
|---|---|---|---|---|---|---|---|
| The level detector | fleet | bucket + probability | an empty night | per receiver floor | receiver bootstrap | fleet | live on the site; one calibration day |
| The anchor map | fleet | integer + interval | one count per anchor | no | one, unstated confidence | fleet | live on the site (IP-148); one anchor |
| The posterior and the resolution ladder | fleet | P(N), sets, families | the same anchors | no | nested, four confidences | fleet | live on the site (2026-09-05); one anchor |
| The saturating scattering law | calibration | a link shape, a knee | 0 to 10 per room | shape yes, scale no | none | public | supported on public data; hardware test pending (crowd-day staircase) |
| Partial pooling and empirical-Bayes shrinkage | calibration | α_e, β_e with shrinkage | k anchors in the new room | yes, predictable | posterior on the map | public | supported on public data; the thesis spine |
| The COM-Poisson head | calibration | P(y | x, e) | in-room or k = 2 | no zero-shot | central 90 %, calibrated in-room | public | PUB-5 falsifier run; calibrated in-env, no zero-shot gain |
| Anchored conformal intervals | calibration | [lo, hi] at 1 − α | residuals; k = 2 anchors | repaired by anchors | coverage-guaranteed, approximate per room | public | candidate; in-room valid, transfer repaired by anchors, not uniform |
| The eigenvalue count and its phase transition | theory | recoverable N, a knee | an empty-room floor | structural | none | public | paper drafted; the knee location untested directly |
| Cramér–Rao and Fano limits | theory | floors on variance and error | counts to fit c₀, γ, τ | one room measured | a bound | public | paper drafted (PUB-7); numeric leg run |
| The birth–death filter with anchor control | temporal | a count track | an emission + rare anchors | via re-identification | posterior over N_t | public | candidate; real-feature demonstration, hardware drift pending |
| Simulated BLE + CSI fusion | temporal | a fused timeline | synthetic truth | in silico | none | sim | illustration only; superseded by the filter above |
The fleet's own chain
What runs on the library floor tonight: a level per minute, an integer through labelled anchors, a probability per count. Real hardware, one calibration day, printed on the Toolbox.
The level detector
Was the floor empty, low, occupied or high in this minute, and how sure is the fleet?
In plain words. Nine microphones and one metronome. An empty room returns the same tick every time; people make it flutter. Each receiver measures its own flutter against its own quiet night, the fleet takes the median, and the median is resampled to see how much it depends on which receivers were listening.
The idea. Per receiver-minute, the standard deviation of the injector-scoped two-chain ratio in dB. Divided by that receiver's floor (the median of its certified-empty night minutes, rule A, else the day's 10th percentile, rule B) and taken in base-two logarithm: octaves, because floors differ threefold between receivers while people multiply them by about two everywhere. The fleet level is the median over receivers with a receiver bootstrap (1,000 resamples, 5 to 95 %). Buckets at 0.25, 0.75 and 1.50 octaves; the bucket probability is the share of bootstrap medians that fall in it.
In: the lake's per-minute blocks of the paced arm, the certified-empty night window. Out: a level in octaves per minute with a band, a bucket with a probability.
| Finding | Source |
|---|---|
| 0.00 oct on 62 quiet minutes (p90 0.03); 1.05 on nine minutes with two moving people; 1.10 on eighteen with three. Empty against occupied separates; two against three does not. | occupancy snapshot meta.calibration; diary 2026-09-02 §10 |
| Nine receivers share one illuminator, so nine is an optimistic n for the bootstrap. | web/occupancy_atlas.py docstring |
Strong
- Runs on the real fleet every night; every constant is declared and printed.
- Floors are per receiver and per day, so a receiver's drift does not become a person.
- Presence is near certain: the empty bucket holds > 99 % on quiet minutes.
Weak
- A level is not a count. Two and three people are 0.05 oct apart with 0.03 spread.
- Edges are calibrated on one day of two labelled states; `high` has never been observed.
- Rule B assumes the room was empty a tenth of the day.
The anchor map
What integer does this minute's level correspond to, and what interval is honest?
In plain words. A ruler with two marks on it: the empty room at zero, and every minute a person stood on the floor and wrote down how many were there. A reading between two marks is read off by straight lines; above the top mark the ruler ends and the answer is 'that many or more'.
The idea. An anchor is a labelled count and the fleet minutes inside its labelled windows (median, p10, p90). Zero is the floor by construction and is never a label. The estimate is piecewise-linear interpolation of count against level median through the anchors, rounded. The interval is the bootstrap band mapped through the same inverse, widened to every anchor whose own spread overlaps it, so two anchors 0.05 oct apart share one interval. Above the top anchor the upper bound is open.
In: fleet levels of the count method; labelled windows written through occupancy_label_write. Out: an integer per minute with an interval; open above the top label.
| Finding | Source |
|---|---|
| One labelled anchor above zero today: 3 people, 18 minutes, level 1.15, p10 0.73, p90 1.32. | occupancy snapshot meta.anchors, 2026-09-04 |
| The two-person labels (10:45 to 11:01 on 2026-09-02) are not anchors: those minutes are not decoded. | diary 2026-09-05, the newest-first decode |
Strong
- Honest by construction: it cannot say a number no label supports.
- A label is a person's statement with a basis, printed beside the count.
- The interval says 'or more' where the ruler ends instead of inventing a top.
Weak
- One interval at no stated confidence.
- Piecewise-linear between anchors ignores the concave law the corpus reports.
- With one anchor every occupied minute reads '3 (2 to 3 or more)'.
The posterior and the resolution ladder
How likely is each count given this minute, and how wide must a bucket be to be honest?
In plain words. Instead of reading one number off the ruler, ask every mark how well it explains the reading. The marks that explain it share the probability. Then ask the ruler itself: how far apart must two marks be before a reading can tell them apart nine times in ten? That distance is the bucket you may quote.
The idea. The level law through the anchors gives each count an expected level and a spread. The minute's likelihood under count N is normal with variance the law's spread squared plus the bootstrap half-width squared; counts above the top anchor share the top's likelihood and are one state, 'more'. Nested sets are the smallest run of counts around the mode reaching 50, 80, 90 and 95 %. The resolvable bucket width at N is the spread divided by the slope of the law, times z; with two labels the saturating law of the scattering model is fitted and gives the slope past the knee.
In: the same anchors and fleet rows as the anchor map. Out: a probability per count, nested sets at four confidences, bucket families, a resolution ladder.
| Constant | Value | Source |
|---|---|---|
| top anchor level | 1.151 oct | occupancy snapshot schema 4, 2026-09-04 |
| top anchor σ | 0.229 oct | occupancy snapshot schema 4, 2026-09-04 |
| empty σ | 0.03 oct | occupancy snapshot schema 4, 2026-09-04 |
| Finding | Source |
|---|---|
| 11:20 on 2026-09-02 (three people): P = 0 / 0 / 18 / 41 / 41 % over 0, 1, 2, 3, more; the 90 % set is '2 or more'. | web/counting.py on snapshot schema 4 |
| Ladder at 90 %: 0.8 person wide at one person, 1.4 at two, unresolved at three (flat law). | web/counting.py: resolution_ladder |
| In-sample: 16 of 18 labelled minutes inside every nested set; the two misses are window-edge minutes. | web/counting.py: calibration_check |
Strong
- Every bucket family gets a probability from one posterior; fives and doublings are two views of it.
- The ladder says where a bucket of five is honest and where it is not, before anyone quotes one.
- The 'more' state makes saturation visible instead of hiding it in an open interval.
Weak
- Normal likelihood with a uniform prior; the conformal wrapper is the distribution-free replacement.
- The check is in-sample: it can refute a set, never confirm one.
- The saturating law cannot be fitted until a second labelled count exists.
The calibration plane
Models of how the count-to-signal map moves between rooms and cards, fitted on 939 labelled windows from seven public environments. The thesis spine: a mechanism that travels, a scale that does not.
The saturating scattering law
What shape does 'more people, more variance' have, and is it derived or fitted?
In plain words. Each moving person is a small moving mirror. Add mirrors and the signal jitters more, but a room holds only so many mirrors before they shadow each other. The jitter rises fast and then levels off, and that curve falls out of the physics rather than being drawn through the points.
The idea. The channel is a static component plus K independent moving random phasors. The fluctuation power of |H| grows with K at low density (a central-limit argument), and a finite room with mutual occlusion caps the effective number of scatterers, so the law is concave and saturating with a knee K₀. Two predictions follow: concave beats linear on real data, and the shorter 5 GHz wavelength gives a larger phase swing per body displacement, so 5 GHz is the counting band.
In: per-window temporal CV of CSI amplitude against the labelled count (WiMANS 5 GHz, meneghello 80 MHz). Out: a concave link with a knee N₀; the shape the count map should bend into.
| Constant | Value | Source |
|---|---|---|
| top anchor level | 1.151 oct | occupancy snapshot schema 4, 2026-09-04 |
| top anchor σ | 0.229 oct | occupancy snapshot schema 4, 2026-09-04 |
| empty σ | 0.03 oct | occupancy snapshot schema 4, 2026-09-04 |
| Finding | Source |
|---|---|
| Concave AIC-preferred over a line in 5 of 7 counting-band environments; K₀/K_max 0.26 to 0.52, ΔAIC 45 to 95. | hypothesis scattering-saturation-link, audit 2026-08-03 |
| 5 GHz > 2.4 GHz by Cohen's d in 3 of 3 WiMANS rooms; ρ(moving count, CV) +0.71 at 5 GHz against +0.28 at 2.4 GHz. | hypothesis occupancy-csi-variance, WiMANS zero-shot |
| 2 of 7 wide-range environments prefer a line; the 'never reached the knee' reading is plausible and post-hoc. | hypothesis audit |
Strong
- The shape is a prediction, not a fit; it explains why presence is easy and counting is hard as one curve.
- The band ordering is a second, independent prediction and it held.
- Gives the anchor map and the posterior the functional form to pool.
Weak
- Independent phasors weaken as bodies cluster; K_eff < K is part of why the scale is room-specific.
- No first-party hardware test of the low-density Var ∝ K scaling yet.
- Both confirmed legs come from the two datasets that motivated the law; AIC mitigates the circularity.
Partial pooling and empirical-Bayes shrinkage
Is cross-room counting one model with predictable recovery, or a bag of separate fits?
In plain words. 'More people, more wobble' is the same law in every room; only two constants change from place to place. Treat every room as one family sharing that law, and two Bluetooth calibration points in a new room let it borrow the family's knowledge instead of starting from zero. How much you recover with how few points is predictable.
The idea. count = α_e + β_e · log CV per environment e, with (α_e, β_e) drawn from a population whose covariance Σ carries the environment variance, nested inside a platform (WiFi card) level. 'The mechanism travels' is a tight, sign-stable slope population; 'the scale does not' is real variance in α_e and β_e with the card as the top level. For a new room with k anchors the empirical-Bayes posterior shrinks from the population mean toward the local fit, and the error-against-k curve is closed form.
In: the pooled cross-environment corpus: (dataset, environment, count, CV), n = 939, 7 environments, 2 platforms. Out: per-environment slope and intercept with shrinkage; a recovery-against-anchors curve.
| Constant | Value | Source |
|---|---|---|
| in-env oracle MAE | 0.72 | hypothesis occupancy-csi-variance LOEO; hierarchical-calibration-shrinkage |
| zero-shot LOEO MAE | 1.75 | hypothesis occupancy-csi-variance LOEO; hierarchical-calibration-shrinkage |
| k = 2 measured / predicted | 1.32 / 1.13 | hypothesis occupancy-csi-variance LOEO; hierarchical-calibration-shrinkage |
| Finding | Source |
|---|---|
| Slope sign-stable in 7 of 7 environments; within-platform dispersion 0.28 against 0.96 flat, so the nested model is required. | hypothesis hierarchical-calibration-shrinkage |
| In-env oracle MAE 0.72; zero-shot LOEO 1.75; predict-mean 2.07; k = 2 anchors 1.32 (recovers 42 %); the EB prediction at k = 2 is 1.13. | hypothesis occupancy-csi-variance, LOEO section |
| Naive D-optimal placement inverts under the strong prior; the criterion is Bayesian-optimal, not widest spread. PC-4a is the one case where two anchors hurt. | hypothesis audit 2026-08-03 |
Strong
- Turns four hypotheses into one equation and explains '42 % with two anchors' as shrinkage.
- Yields a design law: how many anchors, and that placement is prior-aware.
- Degrades gracefully: zero anchors is the population mean, many anchors is the local oracle.
Weak
- Platform level estimated from two groups, with platform and dataset confounded.
- Linear in log CV; a first-order approximation of the concave law it should pool the parameters of.
- All evidence on public datasets; the deployed re-fit is the IP-106 capture, still pending.
The COM-Poisson head
Which likelihood family fits counts conditioned on the CSI feature, and is it calibrated?
In plain words. Given the wobble, how spread out are the true counts? Less spread than a Poisson would give, it turns out, in every room. Poisson cannot say that and the negative binomial can only add spread, so a third family with a dial that goes both ways is the one whose intervals mean what they say.
The idea. Counts conditional on log CV are under-dispersed (conditional variance below conditional mean). Poisson forces equality and NB2 only adds variance, so a mean-parametrised Conway–Maxwell–Poisson with dispersion ν covering both sides is fitted with the same mean structure (log link, per-environment intercept, shared slope). Pre-registered kill lines on the premise, on zero-shot likelihood gain, and on calibration by randomised PIT.
In: the same n = 939 corpus, x = log CV. Out: a predictive distribution over the count per window, with a calibrated central interval.
| Finding | Source |
|---|---|
| Under-dispersed in 7 of 7 environments (bootstrap 95 % CIs entirely below 1); ν̂ = 1.88. | com_poisson_results.json: P1_dispersion, P2_full_fits |
| Calibration (K3) passes: PIT KS better than both baselines and central-90 % coverage on target within-environment. | com_poisson_results.json: kill_lines |
| Zero-shot gain (K2) fails: LOEO mean OOS log-lik −1.6535 against −1.6491 for the best baseline; anchored with k = 2 it gains +0.05 nats. | com_poisson_results.json: scheme_A_loeo, leg_anchored |
Strong
- The only head that is calibrated in-environment; the premise held on every room.
- One mean structure across heads, so only the dispersion family is compared.
- Pre-registered, with a negative recorded as a deliverable.
Weak
- No zero-shot gain: calibration does not travel without an anchor.
- The corpus's count levels are design-balanced, so it speaks about p(count | CV), not about occupancy dynamics.
- Within-environment bootstrap CIs are optimistic (session clustering unknown).
Anchored conformal intervals
Can a count interval promise its coverage without a distribution, and does the promise survive a new room?
In plain words. A counter that says 'between 9 and 15, and I am right nine times in ten' is a promise that can be checked. Conformal prediction wraps any counter in such a promise using only past residuals. The question is whether the promise survives being carried into a room the residuals never saw.
The idea. Split conformal on the partial-pooling regressor's residuals: the 90 % quantile of calibration nonconformity scores is the half-width. Mondrian per environment gives per-room validity in-room. Under leave-one-environment-out the scores are not exchangeable and coverage collapses; anchoring with k = 2 residuals at weight 1 and the other rooms' anchored residuals at weight 0.5 (beyond-exchangeability weights fixed a priori) repairs it.
In: the partial-pooling model's residuals on the n = 939 corpus; k = 2 anchors per held-out room. Out: an interval per window with a stated coverage; its width as a shift signal.
| Constant | Value | Source |
|---|---|---|
| in-env coverage, three rooms | 0.899 / 0.893 / 0.901 | hypothesis conformal-count-intervals |
| half-width | ±1.6 to 2.0 | hypothesis conformal-count-intervals |
| PC-2a LOEO → anchored | 0.11 → 0.889 | hypothesis conformal-count-intervals |
| Finding | Source |
|---|---|
| In-environment: coverage 0.899 / 0.893 / 0.901 at nominal 0.90 on the three WiMANS rooms, half-width ±1.6 to 2.0 people on 0 to 5. | hypothesis conformal-count-intervals, 2026-08-03 |
| Leave-one-environment-out: PC-2a collapses to 0.11; anchored conformal-on-EB recovers it to 0.889. | hypothesis conformal-count-intervals, 2026-08-07 |
| Per-environment validity is not uniform: KD1 fails on 2 of 7 (PC-4a 0.650, meeting room 0.830); widths balloon 2.4 to 3.4× on the small meneghello sets (KD2 fails 4 of 7). | hypothesis conformal-count-intervals, 2026-08-07 |
Strong
- Model-agnostic: wraps the existing counter with no retraining.
- The coverage gap is itself a drift signal, which is the distinctive claim.
- Dominates the naive residual-quantile band on anchors everywhere (KD3 pass).
Weak
- Exact per-room coverage is provably impossible finite-sample; the claim is approximate.
- About 23 weighted calibration scores put the 90 % quantile near the maximum: wide by construction.
- The drift-as-coverage-gap leg is untested; the corpus has no time axis.
One covariance, three readings
What the second-order statistic of CSI can and cannot say about a count: the eigenvalue count and its phase transition, the Cramér–Rao and Fano floors, and why saturation is a law rather than a nuisance.
The eigenvalue count and its phase transition
Why does the count response saturate, and what is the recoverable count in principle?
In plain words. Each occupant adds one faint, coherent voice to a room already full of hiss. A voice is heard only when it rises above the hiss by a fixed margin set by how many microphones listen for how long. Count the voices you can hear and you have the occupancy the array can recover; the ones below the margin are the saturation.
The idea. Model each occupant as a low-rank coherent perturbation of the CSI sample covariance. Random-matrix theory says a scattering mode is resolvable exactly when its signal-to-noise ratio exceeds the Baik–Ben Arous–Péché threshold √γ set by the aspect ratio γ = p/T (bins over snapshots). The recoverable count is the number of sample eigenvalues above the Marchenko–Pastur bulk edge, estimable by the Kritchman–Nadler sequential test; the concave saturation is the BBP transition.
In: per-window CSI amplitude covariance over p = 270 antenna–subcarrier bins, T snapshots (WiMANS 5 GHz, 108 records). Out: a recoverable count and a predicted knee as a function of (γ, per-person SNR).
| Constant | Value | Source |
|---|---|---|
| p bins | 270 | rmt-csi-counting abstract |
| Spearman, nats (eigenvalue / scalar) | 0.65, 0.7 / 0.73 | rmt-csi-counting abstract |
| Finding | Source |
|---|---|
| Supra-edge count rises monotonically with occupancy and saturates with the predicted concave form: Spearman +0.65, 0.70 nats of count information. | rmt-csi-counting abstract |
| On amplitude-only data the eigenvalue count and the scalar variance carry indistinguishable information (0.70 against 0.73 nats), which the theory itself explains. | rmt-csi-counting abstract |
| OPERAnet 2.4 GHz gives 0.17 nats, consistent with the predicted band ordering; one contrast, hardware-confounded. | rmt-csi-counting abstract |
Strong
- A mechanism for saturation with a falsifiable knee location.
- Predicts that the supra-edge budget grows as γ falls: more snapshots per window, more countable people.
- Connects the CRB knee of the limits paper to a named phase transition.
Weak
- Not a stronger feature: on amplitude data it matches the scalar variance.
- One array geometry, two datasets; the aspect-ratio sweep is delegated to simulation.
- Needs the empty-room noise floor per deployment, which is the floor the fleet already estimates.
Cramér–Rao and Fano limits
How well can any estimator count from one window, and what sets the floor?
In plain words. Before building a better counter, ask what the best possible one could do with this signal. Three floors sit under every estimator: the noise of a finite window, the fact that the occupancy pattern has only a few independent directions, and the room's own day-to-day variability that no window length removes. The last one is the operative floor.
The idea. An occupancy-conditioned Gaussian channel in which each occupant adds diffuse scattered power: R(N) = R₀ + s(N)·B with s(N) = P_d0 + γN. The Slepian–Bangs formula gives the Fisher information of N in closed form, exposing three nested bounds: a full-rank CRB scaling as s²/(npγ²), a rank-r bound where low-rank coherence collapses the aperture gain from p to r, and a structural floor set by session-level variability τ² that no n or p reduces. A Fano converse over the discrete counts lower-bounds the error probability of any estimator.
In: 108 WiMANS 5 GHz classroom records, 18 per count 0 to 5, p = 270 bins. Out: a variance floor per count, a Fano error floor, and the gap decomposition of the achieved estimator.
| Constant | Value | Source |
|---|---|---|
| c₀, γ, τ² | 57.689, 23.919, 0.0625 | csi-counting-limits figdata/crb_results.json |
| n, p, r | 100, 270, 6 | csi-counting-limits figdata/crb_results.json |
| Finding | Source |
|---|---|
| Structural floor 3.9 to 18 counts² over occupied counts 1 to 5 (c₀ 57.7, γ 23.9, τ² 0.0625, fit R² 0.92). | csi-counting-limits figdata/crb_results.json |
| Fano bound ≥ 35 % error on 0 to 5 and ≥ 57 % on occupied 1 to 5; the achieved leave-one-out estimator attains 55 % and 66 %. | csi-counting-limits abstract |
| The achieved variance sits within about a factor of two of the structural floor and two to four orders of magnitude above the white and rank-6 CRBs. | csi-counting-limits abstract |
Strong
- Says where the limit is: not snapshot noise but coherence and session variability.
- Closed form; every constant is fitted on data and printed.
- Explains why more antennas and longer windows stop helping.
Weak
- One dataset, one room type, one 3×3 array; nothing licenses generalisation beyond that.
- The empty room is off-model and treated as its own regime.
- A floor per window; it says nothing about integration over minutes, which is the escape.
Time as the escape
The per-window limits are real. A filter over minutes with a physical prior on how counts change escapes them, and a rare Bluetooth anchor re-identifies the drifted map instead of only resetting the count.
The birth–death filter with anchor control
Can integrating over time escape the per-window floor, and what should a rare Bluetooth anchor do?
In plain words. People do not teleport: from one minute to the next the count moves by one or stays. A filter that knows this smooths the noisy per-minute guesses into a track that beats any single minute. When a rare Bluetooth check arrives, the right use is not to reset the count but to re-learn how the WiFi reading maps to a count, because that map is what drifted.
The idea. A hidden Markov model over the occupancy state with a physics-grounded birth–death transition (±1 immigration–death) and the per-window emission, run as a log-domain forward filter. A BLE anchor enters as a control input that resets the state and re-identifies the drifted emission by EB shrinkage. A CUSUM on the innovation is the drift trigger. The Kalman reading of the same loop: the gain on the CSI-implied estimate decays between anchors, which is the observed 'staleness switch'.
In: a per-window count feature stream (OPERAnet 2.4 GHz, WiMANS 5 GHz), a periodic anchor. Out: a filtered count track, an anchor policy, a drift trigger.
| Constant | Value | Source |
|---|---|---|
| OPERAnet MAE per-window → filtered | 1.54 → 0.34 | hypothesis state-space-fusion-optimality |
| re-identification / reset recovery | 0.9 / 0.2 | hypothesis state-space-fusion-optimality |
| Finding | Source |
|---|---|
| Ceiling escape: −78 % MAE on the real OPERAnet 2.4 GHz stream (1.54 → 0.34, 1,309 windows); −61 % on a WiMANS 5 GHz birth–death path (1.15 → 0.45). | hypothesis state-space-fusion-optimality, 2026-08-07 |
| Re-identification recovers 90 % of drift-induced error (MAE 1.74 → 0.30) against 20 % for a count reset alone. | hypothesis state-space-fusion-optimality, 2026-08-07 |
| The powered trigger replication failed equivalence: paired diff +0.034 persons, 90 % CI [+0.002, +0.066]; the innovation tracks true error at ρ 0.68 [0.10, 0.90]. | hypothesis audit 2026-08-03, c-ble-trigger-equivalence |
Strong
- The only model here that beats the per-window limits, by using the axis they do not cover.
- The anchor as a control input is the defensible novelty over the prior-art particle filter.
- A tested pure-domain module exists (domain/counting_filter.py) with the layering gate green.
Weak
- The affine emission underfits the concave scalar–count curve; the module reproduces −34 % on WiMANS, not −61 %.
- Drift-trigger payoff is a budget saving at a small accuracy cost, not parity.
- No measured drift on our hardware yet; the weeks-scale leg is IP-106.
Simulated BLE + CSI fusion
Does a periodic Bluetooth anchor bound the drift a CSI-only map suffers across floors?
In plain words. In a simulated building, a WiFi map trained on one floor is carried to another and drifts. A Bluetooth head-count every so often re-fits it. The picture shows the mechanism; the numbers do not survive, because the Bluetooth count was fitted to the same run it then corrected.
The idea. Coupled JuPedSim walk → Sionna CSI and co-registered BLE RSSI from one solved channel. CSI temporal CV is the high-rate relative signal; BLE aggregate attenuation the low-rate absolute anchor; the anchor periodically re-fits the CSI→count affine. A learned-feature probe (Doppler statistics into a small MLP) tested whether the synthetic CSI was under-featured.
In: synthetic CSI and BLE from three ResPlan floors, two bands. Out: a fused timeline and a cross-floor transfer MAE.
| Finding | Source |
|---|---|
| Cross-floor CSI-only about 3.5 persons → fused about 1.0; the critic ruled it a mechanism illustration, not a recovery rate. | memory csi-ble-fusion campaign; session closed 3 of 4 |
| Leakage: the BLE count was fit to the same run's ground truth (RSSI slope −14.3 dB/person source against −73.0 target). | memory csi-ble-fusion campaign |
Strong
- Shows the shape of the loop end to end on one solved channel.
- Cheap: a coupled run is about a minute on CPU.
Weak
- Self-confirming: the anchor is a proxy recount of the same run.
- Ray-traced CSI under-reproduces band physics; the learned probe found little count information in it.
- No number here reaches a chapter.
What is new, and what is not
The building blocks are textbook: random phasors, partial pooling, Conway–Maxwell–Poisson, split conformal, Marchenko–Pastur, Slepian–Bangs, a hidden Markov model. The corpus already holds counters that output a posterior (the renewal-process estimator of Depatla et al., the fidget-bandwidth estimator of Torun et al.) and a static-emission particle filter for CSI counting. None of that is this project's.
What the corpus does not hold, and these pages do, is the set of statements that tie the blocks together on one occupancy-conditioned covariance: that the count response saturates because of a phase transition whose knee is fixed by the aspect ratio and the per-person SNR; that the same covariance gives a Cramér–Rao floor set by session variability rather than by snapshot noise, so more antennas and longer windows stop helping; that cross-room recovery with two anchors is empirical-Bayes shrinkage with a predicted value rather than a lucky number; that counts conditioned on the feature are under-dispersed in every room measured; that a Bluetooth anchor used to re-identify the emission recovers most of a drift where a count reset recovers little; and that a bucket's honest width at each count follows from the law's slope and spread, before anyone quotes one. The one instrument that reaches the library floor is the last: the detector chain on the Toolbox, calibrated on one day with one label above zero.
Each of those statements has a paper draft or a hypothesis note behind it; the ones with measured support are marked in the table. What none of them has yet is a measured drift on this fleet, which is the leg every calibration claim waits on.