use crate::Scalar;
#[derive(Clone, Copy, Debug)]
pub struct LazyRow<'a, F> {
column_indices: &'a [usize],
values: &'a [F],
len: usize,
centers: Option<&'a [F]>,
scales: Option<&'a [F]>,
}
impl<'a, F> LazyRow<'a, F> {
pub(crate) fn new(
column_indices: &'a [usize],
values: &'a [F],
len: usize,
centers: Option<&'a [F]>,
scales: Option<&'a [F]>,
) -> Self {
Self {
column_indices,
values,
len,
centers,
scales,
}
}
pub fn column_indices(&self) -> &'a [usize] {
self.column_indices
}
pub fn values(&self) -> &'a [F] {
self.values
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn centers(&self) -> Option<&'a [F]> {
self.centers
}
pub fn scales(&self) -> Option<&'a [F]> {
self.scales
}
}
impl<F: Scalar> LazyRow<'_, F> {
pub fn center(&self, j: usize) -> F {
assert!(j < self.len, "column index out of bounds");
self.centers.map_or_else(F::zero, |centers| centers[j])
}
pub fn scale(&self, j: usize) -> F {
assert!(j < self.len, "column index out of bounds");
self.scales.map_or_else(F::one, |scales| scales[j])
}
pub fn implicit_value(&self, j: usize) -> F {
-self.center(j) / self.scale(j)
}
pub fn stored_corrections(&self) -> impl Iterator<Item = (usize, F)> + '_ {
self.column_indices
.iter()
.copied()
.zip(self.values)
.map(|(j, &value)| (j, value / self.scale(j)))
}
}