pub struct LazyMatrix<M, F = f64> { /* private fields */ }Expand description
A matrix presented with lazy column normalization X̃ = (X − 1cᵀ)S⁻¹.
The underlying matrix data is never modified or densified; the centers and
scales are folded into the matrix–vector products on the fly. See the
crate-level documentation for the math.
centers and scales are each None when that axis of normalization is
inactive. When present, each has length ncols, and no scale equals zero.
Negative scales and nonfinite normalization parameters are allowed.
Implementations§
Source§impl<M, F: Scalar> LazyMatrix<M, F>where
M: MatrixShape,
impl<M, F: Scalar> LazyMatrix<M, F>where
M: MatrixShape,
Sourcepub fn from_parts(
data: M,
centers: Option<Vec<F>>,
scales: Option<Vec<F>>,
) -> Self
pub fn from_parts( data: M, centers: Option<Vec<F>>, scales: Option<Vec<F>>, ) -> Self
Construct from an explicit center and/or scale vector.
Parameters are preserved unchanged, including negative scales and
nonfinite values. Unlike Self::new, this constructor rejects exact
zero scales rather than replacing them with one.
§Panics
Panics if a provided centers/scales vector does not have length
ncols, or if a scale is +0.0 or -0.0. The zero-scale panic reports
the zero-based column index.
Sourcepub fn from_normalization(
data: M,
normalization: NormalizationParams<F>,
) -> Self
pub fn from_normalization( data: M, normalization: NormalizationParams<F>, ) -> Self
Wrap raw data using previously fitted parameters.
§Panics
Panics if the matrix column count differs from the fitted column count.
Sourcepub fn normalization(&self) -> &NormalizationParams<F>
pub fn normalization(&self) -> &NormalizationParams<F>
Borrow fitted parameters for reuse on prediction data.
Sourcepub fn with_centers(data: M, centers: Vec<F>) -> Self
pub fn with_centers(data: M, centers: Vec<F>) -> Self
Wrap a matrix with column centering only.
Centers are preserved unchanged, including nonfinite values.
§Panics
Panics if centers.len() != ncols.
Sourcepub fn with_scales(data: M, scales: Vec<F>) -> Self
pub fn with_scales(data: M, scales: Vec<F>) -> Self
Wrap a matrix with column scaling only.
Scales are preserved unchanged, including negative and nonfinite values.
Exact zero scales are rejected, as in Self::from_parts.
§Panics
Panics if scales.len() != ncols, or if a scale is +0.0 or -0.0.
The zero-scale panic reports the zero-based column index.
Sourcepub fn column(&self, j: usize) -> LazyColumn<M::Column<'_>, F>where
M: RawColumns<F>,
pub fn column(&self, j: usize) -> LazyColumn<M::Column<'_>, F>where
M: RawColumns<F>,
Borrow one lazily normalized column without copying.
Sourcepub fn sparse_column(&self, j: usize) -> LazySparseColumn<'_, F>where
M: SparseColumns<F>,
pub fn sparse_column(&self, j: usize) -> LazySparseColumn<'_, F>where
M: SparseColumns<F>,
Borrow one lazily normalized CSC column with its sparse representation.
Sourcepub fn row(&self, i: usize) -> LazyRow<'_, F>where
M: SparseRows<F>,
pub fn row(&self, i: usize) -> LazyRow<'_, F>where
M: SparseRows<F>,
Borrow one lazily normalized sparse row without copying.
This takes O(1) time and allocates nothing. The view borrows the raw
stored column indices and values and the full normalization slices.
Centering generally makes the logical row dense; LazyRow exposes
its sparse-plus-affine representation explicitly.
use lazymatrix::{LazyMatrix, SprsCsr};
use sprs::CsMat;
let x = CsMat::new((1, 3), vec![0, 2], vec![0, 2], vec![1.0, 0.0]);
let csr = SprsCsr::try_new(x.view()).unwrap();
let lazy = LazyMatrix::from_parts(csr, Some(vec![0.5, -1.0, 2.0]), Some(vec![2.0; 3]));
let row = lazy.row(0);
assert_eq!(row.len(), 3);
assert_eq!(row.column_indices(), &[0, 2]);
assert_eq!(row.values(), &[1.0, 0.0]);
assert_eq!(row.implicit_value(1), 0.5);
assert_eq!(row.stored_corrections().collect::<Vec<_>>(), vec![(0, 0.5), (2, 0.0)]);Row access requires contiguous sparse-row storage:
use lazymatrix::{LazyMatrix, MatrixShape};
fn row_without_sparse_rows<M: MatrixShape>(matrix: &LazyMatrix<M>) {
let _ = matrix.row(0);
}§Panics
Panics if i >= self.nrows().
Source§impl<M, F: Scalar> LazyMatrix<M, F>where
M: ColumnStats<F> + MatrixShape,
impl<M, F: Scalar> LazyMatrix<M, F>where
M: ColumnStats<F> + MatrixShape,
Sourcepub fn new(data: M, spec: Normalization) -> Result<Self, M::Error>
pub fn new(data: M, spec: Normalization) -> Result<Self, M::Error>
Construct by computing the centers and scales from data according
to spec.
When both centering and scaling are requested, scales are computed from
the centered columns. Standard deviation and range are
centering-invariant; L1, L2, and MaxAbs use sparse closed-form
centered variants.
An exact zero scale (e.g. a constant column whose standard deviation is
zero) is replaced with 1, so the resulting operator never divides by
zero. Nonfinite statistics retain their IEEE values and propagate through
subsequent operations.
§Errors
Returns the backend error if computing normalization statistics fails.
Source§impl<M, F: Scalar> LazyMatrix<M, F>where
M: MatrixShape,
impl<M, F: Scalar> LazyMatrix<M, F>where
M: MatrixShape,
Sourcepub fn matvec_scaled_with_workspace<X, Y>(
&self,
alpha: F,
x: &X,
beta: F,
out: &mut Y,
scratch: &mut X::Owned,
) -> Result<(), M::Error>where
X: VectorOwned<F>,
Y: VectorViewMut<F>,
M: MatVecScaledInto<X, Y, F> + MatVecScaledInto<X::Owned, Y, F>,
pub fn matvec_scaled_with_workspace<X, Y>(
&self,
alpha: F,
x: &X,
beta: F,
out: &mut Y,
scratch: &mut X::Owned,
) -> Result<(), M::Error>where
X: VectorOwned<F>,
Y: VectorViewMut<F>,
M: MatVecScaledInto<X, Y, F> + MatVecScaledInto<X::Owned, Y, F>,
Apply out = alpha * X̃ * x + beta * out using caller-owned coefficient scratch.
scratch must have length ncols. It is used when column scaling is
active, and its contents after the call are unspecified on error.
Sourcepub fn mat_transpose_vec_scaled_with_workspace<X, Y>(
&self,
alpha: F,
x: &X,
beta: F,
out: &mut Y,
scratch: &mut Y::Owned,
) -> Result<(), M::Error>where
X: VectorView<F>,
Y: VectorOwned<F> + VectorViewMut<F>,
M: MatTransposeVecScaledInto<X, Y, F> + MatTransposeVecScaledInto<X, Y::Owned, F>,
pub fn mat_transpose_vec_scaled_with_workspace<X, Y>(
&self,
alpha: F,
x: &X,
beta: F,
out: &mut Y,
scratch: &mut Y::Owned,
) -> Result<(), M::Error>where
X: VectorView<F>,
Y: VectorOwned<F> + VectorViewMut<F>,
M: MatTransposeVecScaledInto<X, Y, F> + MatTransposeVecScaledInto<X, Y::Owned, F>,
Apply out = alpha * X̃ᵀ * x + beta * out using caller-owned scratch.
scratch must have length ncols. Scaling with nonzero alpha uses
this buffer to keep the previous out values separate from the raw
transpose product.
Source§impl<M: MaterializeDense<F>, F: Scalar> LazyMatrix<M, F>
impl<M: MaterializeDense<F>, F: Scalar> LazyMatrix<M, F>
Sourcepub fn to_eager<D: MatrixOwned<F>>(&self) -> Result<EagerMatrix<D, F>, M::Error>
pub fn to_eager<D: MatrixOwned<F>>(&self) -> Result<EagerMatrix<D, F>, M::Error>
Allocate normalized dense storage in the selected backend.
Sparse and storage-backed inputs are explicitly materialized. Fitted statistics are retained without recomputation. This requires O(nrows * ncols) output storage, plus backend workspace. Allocation size overflow panics; allocation failures follow the selected backend’s behavior.
§Errors
Returns the source error if reading the matrix fails.
Sourcepub fn to_eager_into<'a, D: MatrixWrite<F> + ?Sized>(
&self,
out: &'a mut D,
) -> Result<EagerMatrix<&'a mut D, F>, M::Error>
pub fn to_eager_into<'a, D: MatrixWrite<F> + ?Sized>( &self, out: &'a mut D, ) -> Result<EagerMatrix<&'a mut D, F>, M::Error>
Overwrite dense storage and return a normalized operator borrowing it.
No matrix allocation is made. Fitted parameters are cloned, and the backend may allocate workspace. The wrapper borrows only the output.
The output remains exclusively borrowed while the wrapper is in use:
use lazymatrix::{LazyMatrix, MaterializeDense, MatrixWrite};
fn cannot_reuse_output<M: MaterializeDense<f64>, D: MatrixWrite<f64>>(
matrix: &LazyMatrix<M>, out: &mut D,
) {
let eager = matrix.to_eager_into(out).unwrap();
out.set(0, 0, 0.0);
let _ = eager.nrows();
}§Errors
On a source error, output may be partial and no wrapper is returned.
§Panics
Panics before writing if the output shape differs from the input shape.
Source§impl<M: DenseNormalize<F>, F: Scalar> LazyMatrix<M, F>
impl<M: DenseNormalize<F>, F: Scalar> LazyMatrix<M, F>
Sourcepub fn into_eager(self) -> EagerMatrix<M, F>
pub fn into_eager(self) -> EagerMatrix<M, F>
Consume writable dense data, normalizing it in its existing allocation.
Mutable views modify their borrowed storage. All statistics have already been fitted, and no new statistics or full matrix allocation are needed.
Borrowed immutable and sparse storage do not support in-place conversion:
use lazymatrix::{LazyMatrix, MatrixShape};
fn needs_writable_dense_storage<M: MatrixShape>(matrix: LazyMatrix<M>) {
let _ = matrix.into_eager();
}Trait Implementations§
Source§impl<M, F> Columns<F> for LazyMatrix<M, F>where
F: Scalar,
M: RawColumns<F>,
impl<M, F> Columns<F> for LazyMatrix<M, F>where
F: Scalar,
M: RawColumns<F>,
Source§impl<M, V, F> MatTransposeVec<V> for LazyMatrix<M, F>
impl<M, V, F> MatTransposeVec<V> for LazyMatrix<M, F>
Source§impl<M, X, Y, F> MatTransposeVecInto<X, Y> for LazyMatrix<M, F>where
F: Scalar,
M: MatTransposeVecInto<X, Y>,
X: SumEntries<F>,
Y: ScaledSubSlice<F> + ElemDivAssign<F>,
impl<M, X, Y, F> MatTransposeVecInto<X, Y> for LazyMatrix<M, F>where
F: Scalar,
M: MatTransposeVecInto<X, Y>,
X: SumEntries<F>,
Y: ScaledSubSlice<F> + ElemDivAssign<F>,
Source§fn mat_transpose_vec_into(&self, u: &X, out: &mut Y) -> Result<(), Self::Error>
fn mat_transpose_vec_into(&self, u: &X, out: &mut Y) -> Result<(), Self::Error>
out = X̃ᵀ u = S⁻¹ (Xᵀ u − c · Σu).
Source§impl<M, X, Y, F> MatTransposeVecScaledInto<X, Y, F> for LazyMatrix<M, F>where
F: Scalar,
X: VectorView<F>,
Y: VectorOwned<F> + VectorViewMut<F>,
M: MatTransposeVecScaledInto<X, Y, F> + MatTransposeVecScaledInto<X, Y::Owned, F>,
impl<M, X, Y, F> MatTransposeVecScaledInto<X, Y, F> for LazyMatrix<M, F>where
F: Scalar,
X: VectorView<F>,
Y: VectorOwned<F> + VectorViewMut<F>,
M: MatTransposeVecScaledInto<X, Y, F> + MatTransposeVecScaledInto<X, Y::Owned, F>,
Source§impl<M, V, F> MatVec<V> for LazyMatrix<M, F>
impl<M, V, F> MatVec<V> for LazyMatrix<M, F>
Source§impl<M, X, Y, F> MatVecInto<X, Y> for LazyMatrix<M, F>where
F: Scalar,
M: MatVecInto<X, Y>,
X: Clone + ElemDivAssign<F> + DotSlice<F>,
Y: SubScalarAssign<F>,
impl<M, X, Y, F> MatVecInto<X, Y> for LazyMatrix<M, F>where
F: Scalar,
M: MatVecInto<X, Y>,
X: Clone + ElemDivAssign<F> + DotSlice<F>,
Y: SubScalarAssign<F>,
Source§impl<M, X, Y, F> MatVecScaledInto<X, Y, F> for LazyMatrix<M, F>where
F: Scalar,
X: VectorOwned<F>,
Y: VectorViewMut<F>,
M: MatVecScaledInto<X, Y, F> + MatVecScaledInto<X::Owned, Y, F>,
impl<M, X, Y, F> MatVecScaledInto<X, Y, F> for LazyMatrix<M, F>where
F: Scalar,
X: VectorOwned<F>,
Y: VectorViewMut<F>,
M: MatVecScaledInto<X, Y, F> + MatVecScaledInto<X::Owned, Y, F>,
Source§impl<M: MatrixErrorType, F> MatrixErrorType for LazyMatrix<M, F>
impl<M: MatrixErrorType, F> MatrixErrorType for LazyMatrix<M, F>
Source§type Error = <M as MatrixErrorType>::Error
type Error = <M as MatrixErrorType>::Error
Source§impl<M, F> MatrixShape for LazyMatrix<M, F>where
M: MatrixShape,
impl<M, F> MatrixShape for LazyMatrix<M, F>where
M: MatrixShape,
Source§impl<M, F> WeightedColumnSumsInto<F> for LazyMatrix<M, F>where
F: Scalar,
M: WeightedColumnSumsKernel<F>,
impl<M, F> WeightedColumnSumsInto<F> for LazyMatrix<M, F>where
F: Scalar,
M: WeightedColumnSumsKernel<F>,
Source§impl<M, F> WeightedGramInto<F> for LazyMatrix<M, F>where
F: Scalar,
M: WeightedGramKernel<F>,
impl<M, F> WeightedGramInto<F> for LazyMatrix<M, F>where
F: Scalar,
M: WeightedGramKernel<F>,
Auto Trait Implementations§
impl<M, F> Freeze for LazyMatrix<M, F>
impl<M, F> RefUnwindSafe for LazyMatrix<M, F>
impl<M, F> Send for LazyMatrix<M, F>
impl<M, F> Sync for LazyMatrix<M, F>
impl<M, F> Unpin for LazyMatrix<M, F>
impl<M, F> UnsafeUnpin for LazyMatrix<M, F>
impl<M, F> UnwindSafe for LazyMatrix<M, F>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.