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:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user