use crate::algebra::prelude::*;
use crate::error::KError;
#[derive(Debug, Clone, Default)]
pub struct BlockVec {
data: Vec<S>,
n: usize,
p: usize,
}
impl BlockVec {
pub fn new(n: usize, p: usize) -> Self {
Self {
data: vec![S::zero(); n.saturating_mul(p)],
n,
p,
}
}
pub fn resize(&mut self, n: usize, p: usize) {
let need = n.saturating_mul(p);
if self.data.len() != need {
self.data.resize(need, S::zero());
}
self.n = n;
self.p = p;
}
#[inline]
pub fn nrows(&self) -> usize {
self.n
}
#[inline]
pub fn ncols(&self) -> usize {
self.p
}
#[inline]
pub fn col(&self, j: usize) -> &[S] {
debug_assert!(
j < self.p,
"BlockVec::col: column {} out of range {}",
j,
self.p
);
let offset = j * self.n;
&self.data[offset..offset + self.n]
}
#[inline]
pub fn col_mut(&mut self, j: usize) -> &mut [S] {
debug_assert!(
j < self.p,
"BlockVec::col_mut: column {} out of range {}",
j,
self.p
);
let offset = j * self.n;
&mut self.data[offset..offset + self.n]
}
#[inline]
pub fn as_slice(&self) -> &[S] {
&self.data
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [S] {
&mut self.data
}
}
impl BlockVec {
pub fn fill_zero(&mut self) {
for v in &mut self.data {
*v = S::zero();
}
}
}
#[allow(dead_code)]
pub(crate) fn assert_block_dims(expected_rows: usize, vec: &BlockVec) -> Result<(), KError> {
if vec.nrows() != expected_rows {
return Err(KError::InvalidInput(format!(
"BlockVec has {} rows but expected {}",
vec.nrows(),
expected_rows
)));
}
Ok(())
}