use crate::CausalTensor;
use alloc::vec::Vec;
use deep_causality_linear::{LinearError, MatrixView};
use deep_causality_num::Zero;
const NOT_A_MATRIX: (usize, usize) = (0, 1);
impl<T> MatrixView for CausalTensor<T>
where
T: Zero + Clone,
{
type Scalar = T;
fn rows(&self) -> usize {
match self.shape() {
[r, _] => *r,
_ => NOT_A_MATRIX.0,
}
}
fn cols(&self) -> usize {
match self.shape() {
[_, c] => *c,
_ => NOT_A_MATRIX.1,
}
}
fn get(&self, row: usize, col: usize) -> Result<T, LinearError> {
let shape = self.shape();
let [r, c] = shape else {
return Err(LinearError::IndexOutOfBounds((row, col), NOT_A_MATRIX));
};
if row >= *r || col >= *c {
return Err(LinearError::IndexOutOfBounds((row, col), (*r, *c)));
}
self.get(&[row, col])
.cloned()
.ok_or(LinearError::IndexOutOfBounds((row, col), (*r, *c)))
}
fn to_row_major(&self) -> Result<Vec<T>, LinearError> {
let [rows, cols] = self.shape() else {
return Ok(Vec::new());
};
if self.is_contiguous() {
return Ok(self.as_slice().to_vec());
}
let (rows, cols) = (*rows, *cols);
let mut out = Vec::with_capacity(rows * cols);
for i in 0..rows {
for j in 0..cols {
out.push(MatrixView::get(self, i, j)?);
}
}
Ok(out)
}
}