#![expect(
clippy::unwrap_used,
reason = "test scope: failed precondition = test failure"
)]
use leto::{Array1, Array2, Storage};
const ROWS: usize = 4;
const COLS: usize = 3;
fn source() -> Array2<f64> {
let values: Vec<f64> = (0..ROWS * COLS).map(|i| i as f64 + 1.0).collect();
Array2::from_shape_vec([ROWS, COLS], values).unwrap()
}
fn filter_column(column: &[f64], col: usize) -> Vec<f64> {
let scale = col as f64 + 1.0;
column.iter().rev().map(|value| value * scale).collect()
}
#[test]
fn consumer_contract_column_filter_roundtrip() {
let mut data = source();
let original: Vec<f64> = data.storage().as_slice().to_vec();
for (col, mut view) in data.columns_mut().unwrap().enumerate() {
assert!(
!view.has_exclusive_window(),
"column {col} of a C-order matrix must be an interleaved view"
);
let contiguous = view.to_contiguous();
let filtered =
Array1::from_shape_vec([ROWS], filter_column(contiguous.storage().as_slice(), col))
.unwrap();
view.assign(&filtered);
}
let mut expected = vec![0.0; ROWS * COLS];
for col in 0..COLS {
let column: Vec<f64> = (0..ROWS).map(|row| original[row * COLS + col]).collect();
for (row, value) in filter_column(&column, col).into_iter().enumerate() {
expected[row * COLS + col] = value;
}
}
assert_eq!(data.storage().as_slice(), &expected);
}
#[test]
fn consumer_contract_row_zip_assign() {
let input = source();
let mut output = Array2::from_shape_vec([ROWS, COLS], vec![0.0; ROWS * COLS]).unwrap();
let input_view = input.view();
let output_view = output.view_mut();
let rows_in = input_view.axis_iter::<1>(0).unwrap();
let rows_out = output_view.axis_iter_mut::<1>(0).unwrap();
for (row, (source_row, mut target_row)) in rows_in.zip(rows_out).enumerate() {
assert!(
target_row.has_exclusive_window(),
"row {row} of a C-order matrix must be a dense, exclusively-windowed view"
);
let response: Vec<f64> = source_row
.iter()
.map(|value| value * 2.0 + row as f64)
.collect();
let response = Array1::from_shape_vec([COLS], response).unwrap();
target_row.assign(&response);
}
let expected: Vec<f64> = (0..ROWS)
.flat_map(|row| {
(0..COLS).map(move |col| (row * COLS + col) as f64 * 2.0 + 2.0 + row as f64)
})
.collect();
assert_eq!(output.storage().as_slice(), &expected);
}