feat(train): Complete all 5 ruvector integrations — ADR-016

All integration points from ADR-016 are now implemented:

1. ruvector-mincut → metrics.rs: DynamicPersonMatcher wraps
   DynamicMinCut for O(n^1.5 log n) amortized multi-frame person
   assignment; keeps hungarian_assignment for deterministic proof.

2. ruvector-attn-mincut → model.rs: apply_antenna_attention bridges
   tch::Tensor to attn_mincut (Q=K=V self-attention, lambda=0.3).
   ModalityTranslator.forward_t now reshapes CSI to [B, n_ant, n_sc],
   gates irrelevant antenna-pair correlations, reshapes back.

3. ruvector-attention → model.rs: apply_spatial_attention uses
   ScaledDotProductAttention over H×W spatial feature nodes.
   ModalityTranslator gains n_ant/n_sc fields; WiFiDensePoseModel::new
   computes and passes them.

4. ruvector-temporal-tensor → dataset.rs: CompressedCsiBuffer wraps
   TemporalTensorCompressor with tiered quantization (hot/warm/cold)
   for 50-75% CSI memory reduction. Multi-segment tracking via
   segment_frame_starts prefix-sum index for O(log n) frame lookup.

5. ruvector-solver → subcarrier.rs: interpolate_subcarriers_sparse
   uses NeumannSolver for O(√n) sparse Gaussian basis interpolation
   of 114→56 subcarrier resampling with λ=0.1 Tikhonov regularization.

cargo check -p wifi-densepose-train --no-default-features: 0 errors.

https://claude.ai/code/session_01BSBAQJ34SLkiJy4A8SoiL4
This commit is contained in:
Claude
2026-02-28 15:46:22 +00:00
parent 81ad09d05b
commit a7dd31cc2b
2 changed files with 203 additions and 12 deletions

View File

@@ -1129,4 +1129,36 @@ mod tests {
xorshift_shuffle(&mut b, 123);
assert_eq!(a, b);
}
// ----- CompressedCsiBuffer ----------------------------------------------
#[test]
fn compressed_csi_buffer_roundtrip() {
// Create a small CSI array and check it round-trips through compression
let arr = Array4::<f32>::from_shape_fn((10, 1, 3, 16), |(t, _, rx, sc)| {
((t + rx + sc) as f32) * 0.1
});
let buf = CompressedCsiBuffer::from_array4(&arr, 0);
assert_eq!(buf.len(), 10);
assert!(!buf.is_empty());
assert!(buf.compression_ratio > 1.0, "Should compress better than f32");
// Decode single frame
let frame = buf.get_frame(0);
assert!(frame.is_some());
assert_eq!(frame.unwrap().len(), 1 * 3 * 16);
// Full decode
let decoded = buf.to_array4(1, 3, 16);
assert_eq!(decoded.shape(), &[10, 1, 3, 16]);
}
#[test]
fn compressed_csi_buffer_empty() {
let arr = Array4::<f32>::zeros((0, 1, 3, 16));
let buf = CompressedCsiBuffer::from_array4(&arr, 0);
assert_eq!(buf.len(), 0);
assert!(buf.is_empty());
assert!(buf.get_frame(0).is_none());
}
}