Skip to main content

LazyMatrix

Struct LazyMatrix 

Source
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,

Source

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.

Source

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.

Source

pub fn normalization(&self) -> &NormalizationParams<F>

Borrow fitted parameters for reuse on prediction data.

Source

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.

Source

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.

Source

pub fn nrows(&self) -> usize

Number of rows of the logical normalized matrix.

Source

pub fn ncols(&self) -> usize

Number of columns of the logical normalized matrix.

Source

pub fn centers(&self) -> Option<&[F]>

The column centers c, if centering is active.

Source

pub fn scales(&self) -> Option<&[F]>

The column scales s, if scaling is active.

Source

pub fn data(&self) -> &M

Borrow the underlying (un-normalized) matrix.

Source

pub fn column(&self, j: usize) -> LazyColumn<M::Column<'_>, F>
where M: RawColumns<F>,

Borrow one lazily normalized column without copying.

Source

pub fn sparse_column(&self, j: usize) -> LazySparseColumn<'_, F>
where M: SparseColumns<F>,

Borrow one lazily normalized CSC column with its sparse representation.

Source

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

pub fn into_parts(self) -> (M, Option<Vec<F>>, Option<Vec<F>>)

Consume the wrapper, returning the underlying matrix and the center/scale vectors.

Source§

impl<M, F: Scalar> LazyMatrix<M, F>
where M: ColumnStats<F> + MatrixShape,

Source

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,

Source

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.

Source

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>

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>

Source

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.

Source

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>

Source

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: Clone, F: Clone> Clone for LazyMatrix<M, F>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<M, F> Columns<F> for LazyMatrix<M, F>
where F: Scalar, M: RawColumns<F>,

Source§

type Column<'a> = LazyColumn<<M as RawColumns<F>>::Column<'a>, F> where Self: 'a

Source§

fn column(&self, j: usize) -> Self::Column<'_>

Source§

impl<M: Debug, F: Debug> Debug for LazyMatrix<M, F>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<M, V, F> MatTransposeVec<V> for LazyMatrix<M, F>

Source§

fn mat_transpose_vec(&self, u: &V) -> Result<V, Self::Error>

X̃ᵀ u = S⁻¹ (Xᵀ u − c · Σu).

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>,

Source§

fn mat_transpose_vec_into(&self, u: &X, out: &mut Y) -> Result<(), Self::Error>

out = X̃ᵀ u = S⁻¹ (Xᵀ u − c · Σu).

Source§

fn mat_transpose_vec_normalized_into<F: Scalar>( &self, x: &X, centers: Option<&[F]>, scales: Option<&[F]>, out: &mut Y, ) -> Result<(), Self::Error>
where X: SumEntries<F>, Y: ScaledSubSlice<F> + ElemDivAssign<F>,

Apply the transpose of the optionally normalized matrix. Read more
Source§

impl<M, X, Y, F> MatTransposeVecScaledInto<X, Y, F> for LazyMatrix<M, F>

Source§

fn mat_transpose_vec_scaled_into( &self, alpha: F, x: &X, beta: F, out: &mut Y, ) -> Result<(), Self::Error>

Source§

impl<M, V, F> MatVec<V> for LazyMatrix<M, F>
where F: Scalar, M: MatVec<V>, V: Clone + ElemDivAssign<F> + DotSlice<F> + SubScalarAssign<F>,

Source§

fn matvec(&self, v: &V) -> Result<V, Self::Error>

X̃ v = X (S⁻¹ v) − 1 · (cᵀ S⁻¹ v).

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>,

Source§

fn matvec_into(&self, v: &X, out: &mut Y) -> Result<(), Self::Error>

out = X̃ v = X (S⁻¹ v) − 1 · (cᵀ S⁻¹ v).

Source§

fn matvec_normalized_into<F: Scalar>( &self, x: &X, centers: Option<&[F]>, scales: Option<&[F]>, out: &mut Y, ) -> Result<(), Self::Error>
where X: Clone + ElemDivAssign<F> + DotSlice<F>, Y: SubScalarAssign<F>,

Apply optional column normalization without materializing the matrix. Read more
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>,

Source§

fn matvec_scaled_into( &self, alpha: F, x: &X, beta: F, out: &mut Y, ) -> Result<(), Self::Error>

Source§

impl<M: MatrixErrorType, F> MatrixErrorType for LazyMatrix<M, F>

Source§

type Error = <M as MatrixErrorType>::Error

An operational failure while reading or processing matrix data.
Source§

impl<M, F> MatrixShape for LazyMatrix<M, F>
where M: MatrixShape,

Source§

fn nrows(&self) -> usize

Source§

fn ncols(&self) -> usize

Source§

impl<M, F> WeightedColumnSumsInto<F> for LazyMatrix<M, F>

Source§

fn weighted_column_sums_into<W, O>( &self, weights: &W, out: &mut O, ) -> Result<(), Self::Error>
where W: VectorView<F> + ?Sized, O: VectorViewMut<F> + ?Sized,

Source§

impl<M, F> WeightedGramInto<F> for LazyMatrix<M, F>
where F: Scalar, M: WeightedGramKernel<F>,

Source§

fn weighted_gram_into<W, O>( &self, weights: &W, out: &mut O, ) -> Result<(), Self::Error>
where W: VectorView<F> + ?Sized, O: MatrixWrite<F> + ?Sized,

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.