lazymatrix::LazyMatrix
LazyMatrix for Rust · 0.8.1
pub struct LazyMatrix<M, F = f64>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.
Inherent implementation
impl<M, F: Scalar> LazyMatrix<M, F> where M: ColumnStats<F> + MatrixShapenew
pub fn new(
data: M,
spec: Normalization
) -> Result<Self, <M as MatrixErrorType>::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.
Inherent implementation
impl<M, F: Scalar> LazyMatrix<M, F> where M: MatrixShapecenters
pub fn centers(&self) -> Option<&[F]>The column centers c, if centering is active.
column
pub fn column(
&self,
j: usize
) -> LazyColumn<<M as RawColumns>::Column<'_>, F> where M: RawColumns<F>Borrow one lazily normalized column without copying.
data
pub fn data(&self) -> &MBorrow the underlying (un-normalized) matrix.
from_normalization
pub fn from_normalization(
data: M,
normalization: NormalizationParams<F>
) -> SelfWrap raw data using previously fitted parameters.
Panics
Panics if the matrix column count differs from the fitted column count.
from_parts
pub fn from_parts(
data: M,
centers: Option<Vec<F>>,
scales: Option<Vec<F>>
) -> SelfConstruct 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.
into_parts
pub fn into_parts(self) -> (M, Option<Vec<F>>, Option<Vec<F>>)Consume the wrapper, returning the underlying matrix and the center/scale vectors.
mat_transpose_vec_scaled_with_workspace
pub fn mat_transpose_vec_scaled_with_workspace<X, Y>(
&self,
alpha: F,
x: &X,
beta: F,
out: &mut Y,
scratch: &mut <Y as VectorOwned>::Owned
) -> Result<(), <M as MatrixErrorType>::Error> where X: VectorView<F>, Y: VectorOwned<F> + VectorViewMut<F>, M: MatTransposeVecScaledInto<X, Y, F> + MatTransposeVecScaledInto<X, <Y as VectorOwned>::Owned, F>Apply out = alpha * X̃ᵀ * x + beta * out using caller-owned scratch.
scratch must have length ncols. Backends may use it to keep the raw transpose product separate from previous output values, or leave it unused. Its contents after the call are unspecified.
matvec_scaled_with_workspace
pub fn matvec_scaled_with_workspace<X, Y>(
&self,
alpha: F,
x: &X,
beta: F,
out: &mut Y,
scratch: &mut <X as VectorOwned>::Owned
) -> Result<(), <M as MatrixErrorType>::Error> where X: VectorOwned<F>, Y: VectorViewMut<F>, M: MatVecScaledInto<X, Y, F> + MatVecScaledInto<<X as VectorOwned>::Owned, Y, F>Apply out = alpha * X̃ * x + beta * out using caller-owned coefficient scratch.
scratch must have length ncols. Backends may use it for column scaling or leave it unused. Its contents after the call are unspecified.
ncols
pub fn ncols(&self) -> usizeNumber of columns of the logical normalized matrix.
normalization
pub fn normalization(&self) -> &NormalizationParams<F>Borrow fitted parameters for reuse on prediction data.
nrows
pub fn nrows(&self) -> usizeNumber of rows of the logical normalized matrix.
row
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().
scales
pub fn scales(&self) -> Option<&[F]>The column scales s, if scaling is active.
sparse_column
pub fn sparse_column(
&self,
j: usize
) -> LazySparseColumn<'_, F> where M: SparseColumns<F>Borrow one lazily normalized CSC column with its sparse representation.
with_centers
pub fn with_centers(data: M, centers: Vec<F>) -> SelfWrap a matrix with column centering only.
Centers are preserved unchanged, including nonfinite values.
Panics
Panics if centers.len() != ncols.
with_scales
pub fn with_scales(data: M, scales: Vec<F>) -> SelfWrap 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.
Inherent implementation
impl<M: MatrixShape, F: Scalar> lazymatrix::LazyMatrix<M, F>submatrix
pub fn submatrix(
&self,
rows: Range<usize>,
columns: Range<usize>
) -> Submatrix<'_, M, F>Borrow a rectangle of this normalized matrix without refitting parameters.
Empty ranges are allowed. Construction reads no entries and allocates nothing. To fit normalization on a subset instead, select raw data first and pass it to LazyMatrix::new.
Panics
Panics on reversed or out-of-bounds ranges.
Inherent implementation
impl<M: lazymatrix::DenseNormalize<F>, F: Scalar> LazyMatrix<M, F>into_eager
pub fn into_eager(self) -> lazymatrix::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();
}Inherent implementation
impl<M: lazymatrix::MaterializeDense<F>, F: Scalar> LazyMatrix<M, F>to_eager
pub fn to_eager<D: lazymatrix::MatrixOwned<F>>(
&self
) -> Result<lazymatrix::EagerMatrix<D, F>, <M as MatrixErrorType>::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.
to_eager_into
pub fn to_eager_into<'a, D: lazymatrix::MatrixWrite<F> + ?Sized>(
&self,
out: &'a mut D
) -> Result<lazymatrix::EagerMatrix<&'a mut D, F>, <M as MatrixErrorType>::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.
Implementation of Clone
impl<M: core::clone::Clone, F: core::clone::Clone> Clone for LazyMatrix<M, F>clone
fn clone(&self) -> SelfImplementation of Columns
impl<M, F> Columns<F> for LazyMatrix<M, F> where F: Scalar, M: RawColumns<F>Column
type Column<'a> = LazyColumn<<M as RawColumns<F>>::Column<'a>, F> where Self: 'a;column
fn column(&self, j: usize) -> <Self as Columns>::Column<'_>Implementation of Debug
impl<M: core::fmt::Debug, F: core::fmt::Debug> Debug for LazyMatrix<M, F>fmt
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::ResultImplementation of MatMatInto
impl<M: MatMatInto<F>, F: Scalar> MatMatInto<F> for lazymatrix::LazyMatrix<M, F>matmat_into
fn matmat_into<R, O>(
&self,
rhs: &R,
out: &mut O
) -> Result<(), <Self as MatrixErrorType>::Error> where R: MatrixRead<F> + ?Sized, O: MatrixRead<F> + MatrixWrite<F> + ?SizedImplementation of MatTransposeMatInto
impl<M: MatTransposeMatInto<F>, F: Scalar> MatTransposeMatInto<F> for lazymatrix::LazyMatrix<M, F>mat_transpose_mat_into
fn mat_transpose_mat_into<R, O>(
&self,
rhs: &R,
out: &mut O
) -> Result<(), <Self as MatrixErrorType>::Error> where R: MatrixRead<F> + ?Sized, O: MatrixRead<F> + MatrixWrite<F> + ?SizedImplementation of MatTransposeVec
impl<M, V, F> MatTransposeVec<V> for LazyMatrix<M, F> where F: Scalar, M: MatTransposeVec<V>, V: SumEntries<F> + ScaledSubSlice<F> + ElemDivAssign<F>mat_transpose_vec
fn mat_transpose_vec(
&self,
u: &V
) -> Result<V, <Self as MatrixErrorType>::Error>X̃ᵀ u = S⁻¹ (Xᵀ u − c · Σu).
Implementation of MatTransposeVecInto
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>mat_transpose_vec_into
fn mat_transpose_vec_into(
&self,
u: &X,
out: &mut Y
) -> Result<(), <Self as MatrixErrorType>::Error>out = X̃ᵀ u = S⁻¹ (Xᵀ u − c · Σu).
Implementation of MatTransposeVecScaledInto
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 as VectorOwned>::Owned, F>mat_transpose_vec_scaled_into
fn mat_transpose_vec_scaled_into(
&self,
alpha: F,
x: &X,
beta: F,
out: &mut Y
) -> Result<(), <Self as MatrixErrorType>::Error>Implementation of MatVec
impl<M, V, F> MatVec<V> for LazyMatrix<M, F> where F: Scalar, M: MatVec<V>, V: Clone + ElemDivAssign<F> + DotSlice<F> + SubScalarAssign<F>matvec
fn matvec(&self, v: &V) -> Result<V, <Self as MatrixErrorType>::Error>X̃ v = X (S⁻¹ v) − 1 · (cᵀ S⁻¹ v).
Implementation of MatVecInto
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>matvec_into
fn matvec_into(
&self,
v: &X,
out: &mut Y
) -> Result<(), <Self as MatrixErrorType>::Error>out = X̃ v = X (S⁻¹ v) − 1 · (cᵀ S⁻¹ v).
Implementation of MatVecScaledInto
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 as VectorOwned>::Owned, Y, F>matvec_scaled_into
fn matvec_scaled_into(
&self,
alpha: F,
x: &X,
beta: F,
out: &mut Y
) -> Result<(), <Self as MatrixErrorType>::Error>Implementation of MatrixErrorType
impl<M: lazymatrix::MatrixErrorType, F> MatrixErrorType for LazyMatrix<M, F>Error
type Error = <M as MatrixErrorType>::Error;Implementation of MatrixShape
impl<M, F> MatrixShape for LazyMatrix<M, F> where M: MatrixShapencols
fn ncols(&self) -> usizenrows
fn nrows(&self) -> usizeImplementation of WeightedColumnSumsInto
impl<M, F> WeightedColumnSumsInto<F> for LazyMatrix<M, F> where F: Scalar, M: lazymatrix::WeightedColumnSumsKernel<F>weighted_column_sums_into
fn weighted_column_sums_into<W, O>(
&self,
weights: &W,
out: &mut O
) -> Result<(), <Self as MatrixErrorType>::Error> where W: lazymatrix::VectorView<F> + ?Sized, O: lazymatrix::VectorViewMut<F> + ?SizedImplementation of WeightedGramInto
impl<M, F> WeightedGramInto<F> for LazyMatrix<M, F> where F: Scalar, M: lazymatrix::WeightedGramKernel<F>weighted_gram_into
fn weighted_gram_into<W, O>(
&self,
weights: &W,
out: &mut O
) -> Result<(), <Self as MatrixErrorType>::Error> where W: lazymatrix::VectorView<F> + ?Sized, O: lazymatrix::MatrixWrite<F> + ?SizedImplementation of Freeze
impl<M, F> Freeze for LazyMatrix<M, F> where M: Freeze, NormalizationParams<F>: FreezeImplementation of RefUnwindSafe
impl<M, F> RefUnwindSafe for LazyMatrix<M, F> where M: RefUnwindSafe, NormalizationParams<F>: RefUnwindSafeImplementation of Send
impl<M, F> Send for LazyMatrix<M, F> where M: Send, NormalizationParams<F>: SendImplementation of Sync
impl<M, F> Sync for LazyMatrix<M, F> where M: Sync, NormalizationParams<F>: SyncImplementation of Unpin
impl<M, F> Unpin for LazyMatrix<M, F> where M: Unpin, NormalizationParams<F>: UnpinImplementation of UnsafeUnpin
impl<M, F> UnsafeUnpin for LazyMatrix<M, F> where M: UnsafeUnpin, NormalizationParams<F>: UnsafeUnpinImplementation of UnwindSafe
impl<M, F> UnwindSafe for LazyMatrix<M, F> where M: UnwindSafe, NormalizationParams<F>: UnwindSafeImplementation of Any
impl<T> Any for T where T: 'static + ?SizedImplementation of Borrow
impl<T> Borrow<T> for T where T: ?SizedImplementation of BorrowMut
impl<T> BorrowMut<T> for T where T: ?SizedImplementation of ByRef
impl<T> ByRef<T> for TImplementation of CastableFrom
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT where ST: ?Sized, DT: ?SizedImplementation of CastableFrom
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT where ST: ?Sized, DT: ?SizedImplementation of CloneToUninit
impl<T> CloneToUninit for T where T: CloneImplementation of From
impl<T> From<T> for TImplementation of Imply
impl<T, U> Imply<T> for U where T: ?Sized, U: ?SizedImplementation of Into
impl<T, U> Into<U> for T where U: From<T>Implementation of IntoEither
impl<T> IntoEither for TImplementation of MatMat
impl<M, F> MatMat<F> for M where M: MatMatInto<F> + ?Sized, F: ScalarImplementation of MatTransposeMat
impl<M, F> MatTransposeMat<F> for M where M: MatTransposeMatInto<F> + ?Sized, F: ScalarImplementation of Pointable
impl<T> Pointable for TImplementation of Read
impl<T> Read<Exclusive, BecauseExclusive> for T where T: ?SizedImplementation of Same
impl<T> Same for TImplementation of SupersetOf
impl<SS, SP> SupersetOf<SS> for SP where SS: SubsetOf<SP>Implementation of ToOwned
impl<T> ToOwned for T where T: CloneImplementation of TryFrom
impl<T, U> TryFrom<U> for T where U: Into<T>Implementation of TryInto
impl<T, U> TryInto<U> for T where U: TryFrom<T>
