use crate::Matrix;
pub fn stack_memory(data: &Matrix, n_steps: usize, delay: usize) -> Matrix {
let n_features = data.rows();
let t = data.cols();
let mut result = Matrix::zeros(n_features * n_steps, t);
for step in 0..n_steps {
for r in 0..n_features {
let out_row = step * n_features + r;
for c in 0..t {
let src_col = c as isize - (step * delay) as isize;
if src_col >= 0 {
*result.get_mut(out_row, c) = data.get(r, src_col as usize);
}
}
}
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_stack_memory_n_steps_1() {
let data = Matrix::from_rows(&[&[1.0, 2.0, 3.0]]);
let result = stack_memory(&data, 1, 1);
assert_eq!(result.shape(), (1, 3));
assert_eq!(result.row(0), &[1.0, 2.0, 3.0]);
}
#[test]
fn test_stack_memory_basic() {
let data = Matrix::from_rows(&[&[1.0, 2.0, 3.0, 4.0, 5.0]]);
let result = stack_memory(&data, 3, 1);
assert_eq!(result.shape(), (3, 5));
assert_eq!(result.row(0), &[1.0, 2.0, 3.0, 4.0, 5.0]);
assert_eq!(result.row(1), &[0.0, 1.0, 2.0, 3.0, 4.0]);
assert_eq!(result.row(2), &[0.0, 0.0, 1.0, 2.0, 3.0]);
}
#[test]
fn test_stack_memory_delay_2() {
let data = Matrix::from_rows(&[&[1.0, 2.0, 3.0, 4.0, 5.0]]);
let result = stack_memory(&data, 3, 2);
assert_eq!(result.shape(), (3, 5));
assert_eq!(result.row(0), &[1.0, 2.0, 3.0, 4.0, 5.0]);
assert_eq!(result.row(1), &[0.0, 0.0, 1.0, 2.0, 3.0]);
assert_eq!(result.row(2), &[0.0, 0.0, 0.0, 0.0, 1.0]);
}
#[test]
fn test_stack_memory_multirow() {
let data = Matrix::from_rows(&[&[1.0, 2.0, 3.0], &[4.0, 5.0, 6.0]]);
let result = stack_memory(&data, 2, 1);
assert_eq!(result.shape(), (4, 3));
assert_eq!(result.row(0), &[1.0, 2.0, 3.0]);
assert_eq!(result.row(1), &[4.0, 5.0, 6.0]);
assert_eq!(result.row(2), &[0.0, 1.0, 2.0]);
assert_eq!(result.row(3), &[0.0, 4.0, 5.0]);
}
}