pub enum DesignMatrix {
Dense(DenseDesignMatrix),
Sparse(SparseDesignMatrix),
}Expand description
Unified design matrix representation for dense and sparse workflows.
Dense matrices are wrapped in Arc for O(1) cloning — at large scale design matrices are 100-500MB and get cloned repeatedly during GAMLSS family construction, warm-start caching, and prediction.
The Dense variant wraps both materialized dense matrices and lazy
dense-backed operators (DenseDesignMatrix::Lazy) that implement
DenseDesignOperator without reopening a third top-level storage state.
Variants§
Dense(DenseDesignMatrix)
Sparse(SparseDesignMatrix)
Implementations§
Source§impl DesignMatrix
impl DesignMatrix
Sourcepub fn hstack(blocks: Vec<DesignMatrix>) -> Result<Self, String>
pub fn hstack(blocks: Vec<DesignMatrix>) -> Result<Self, String>
Horizontally concatenate design blocks without forcing eager densification.
The returned matrix is a lazy BlockDesignOperator when more than one
block is provided, so operator-backed inputs stay chunkable on the
prediction path.
pub fn nrows(&self) -> usize
pub fn ncols(&self) -> usize
Sourcepub fn try_row_chunk(
&self,
rows: Range<usize>,
) -> Result<Array2<f64>, MatrixMaterializationError>
pub fn try_row_chunk( &self, rows: Range<usize>, ) -> Result<Array2<f64>, MatrixMaterializationError>
Extract a dense row chunk without materializing the full matrix.
Returns a (rows.len(), ncols()) dense Array2 for the requested row
range. For lazy dense designs this delegates to the operator-backed
implementation, which should remain O(chunk).
Sourcepub fn row_chunk_into(
&self,
rows: Range<usize>,
out: ArrayViewMut2<'_, f64>,
) -> Result<(), MatrixMaterializationError>
pub fn row_chunk_into( &self, rows: Range<usize>, out: ArrayViewMut2<'_, f64>, ) -> Result<(), MatrixMaterializationError>
Borrow-only row-chunk accessor: writes the requested rows into an
existing (rows.len(), ncols()) buffer instead of allocating a fresh
Array2<f64> like Self::try_row_chunk. Used by hot per-row loops
(e.g. latent-survival evaluate) that want to reuse a single 1-row
scratch buffer across iterations.
Sourcepub fn try_to_dense_governed(
&self,
context: &'static str,
) -> Result<Governed<Array2<f64>>, MatrixMaterializationError>
pub fn try_to_dense_governed( &self, context: &'static str, ) -> Result<Governed<Array2<f64>>, MatrixMaterializationError>
Fully materialize this design under the process-wide byte governor.
The returned owner retains the RAII reservation for precisely the matrix lifetime. A refusal is typed, happens before allocation, and is the caller’s signal to remain row-chunked or matrix-free.
Sourcepub fn try_to_dense_governed_with_policy(
&self,
policy: &MaterializationPolicy,
context: &'static str,
) -> Result<Governed<Array2<f64>>, MatrixMaterializationError>
pub fn try_to_dense_governed_with_policy( &self, policy: &MaterializationPolicy, context: &'static str, ) -> Result<Governed<Array2<f64>>, MatrixMaterializationError>
Policy-aware form of Self::try_to_dense_governed. Structural
operator-only policies refuse before consulting or charging the ledger.
pub fn try_to_dense_by_chunks( &self, context: &str, ) -> Result<Array2<f64>, String>
Sourcepub fn try_to_dense_by_chunks_budgeted(
&self,
context: &str,
max_bytes: usize,
) -> Result<Array2<f64>, String>
pub fn try_to_dense_by_chunks_budgeted( &self, context: &str, max_bytes: usize, ) -> Result<Array2<f64>, String>
Like Self::try_to_dense_by_chunks but refuses to allocate when the
dense footprint would exceed max_bytes. Returned Err is the same
shape as a densification-refused error from the resource policy, so
observability-only callers can convert it into a warn! and skip
without ever touching the allocator at huge n.
Sourcepub fn dot_row(&self, row: usize, beta: &Array1<f64>) -> f64
pub fn dot_row(&self, row: usize, beta: &Array1<f64>) -> f64
Dot a single design row against a coefficient vector without allocating a standalone row buffer when the underlying storage permits.
pub fn dot_row_view(&self, row: usize, beta: ArrayView1<'_, f64>) -> f64
Sourcepub fn axpy_row_into(
&self,
row: usize,
alpha: f64,
out: &mut ArrayViewMut1<'_, f64>,
) -> Result<(), String>
pub fn axpy_row_into( &self, row: usize, alpha: f64, out: &mut ArrayViewMut1<'_, f64>, ) -> Result<(), String>
Add alpha * X[row, :] into out without allocating a row buffer.
Sourcepub fn squared_axpy_row_into(
&self,
row: usize,
alpha: f64,
out: &mut ArrayViewMut1<'_, f64>,
) -> Result<(), String>
pub fn squared_axpy_row_into( &self, row: usize, alpha: f64, out: &mut ArrayViewMut1<'_, f64>, ) -> Result<(), String>
Add alpha * X[row, :]^2 elementwise into out without allocating a
standalone row buffer.
Sourcepub fn crossdiag_axpy_row_into(
&self,
row: usize,
other: &DesignMatrix,
alpha: f64,
out: &mut ArrayViewMut1<'_, f64>,
) -> Result<(), String>
pub fn crossdiag_axpy_row_into( &self, row: usize, other: &DesignMatrix, alpha: f64, out: &mut ArrayViewMut1<'_, f64>, ) -> Result<(), String>
Add alpha * self[row, :] * other[row, :] elementwise into out.
Both matrices must have the same number of columns (== out.len()).
For Sparse×Sparse this runs in O(nnz_lhs + nnz_rhs) via sorted
merge-intersection on the CSR column indices — no dense expansion.
Sourcepub fn syr_row_into(
&self,
row: usize,
alpha: f64,
target: &mut Array2<f64>,
) -> Result<(), String>
pub fn syr_row_into( &self, row: usize, alpha: f64, target: &mut Array2<f64>, ) -> Result<(), String>
Symmetric rank-1 update target += alpha * x_row x_row^T for one row.
Sourcepub fn syr_row_into_view(
&self,
row: usize,
alpha: f64,
target: ArrayViewMut2<'_, f64>,
) -> Result<(), String>
pub fn syr_row_into_view( &self, row: usize, alpha: f64, target: ArrayViewMut2<'_, f64>, ) -> Result<(), String>
Like syr_row_into but accepts a mutable view, so callers can pass
a slice of a larger matrix without allocating a temporary.
Sourcepub fn row_outer_into(
&self,
row: usize,
other: &DesignMatrix,
alpha: f64,
target: &mut Array2<f64>,
) -> Result<(), String>
pub fn row_outer_into( &self, row: usize, other: &DesignMatrix, alpha: f64, target: &mut Array2<f64>, ) -> Result<(), String>
Asymmetric rank-1 update: target += alpha * lhs_row * rhs_row^T.
self provides lhs_row, other provides rhs_row.
target must be self.ncols() x other.ncols().
Sourcepub fn row_outer_into_view(
&self,
row: usize,
other: &DesignMatrix,
alpha: f64,
target: ArrayViewMut2<'_, f64>,
) -> Result<(), String>
pub fn row_outer_into_view( &self, row: usize, other: &DesignMatrix, alpha: f64, target: ArrayViewMut2<'_, f64>, ) -> Result<(), String>
Like row_outer_into but accepts a mutable view, so callers can pass
a slice of a larger matrix without allocating a temporary.
Sourcepub fn apply_view_into(
&self,
vector: ArrayView1<'_, f64>,
output: ArrayViewMut1<'_, f64>,
)
pub fn apply_view_into( &self, vector: ArrayView1<'_, f64>, output: ArrayViewMut1<'_, f64>, )
Apply the design to a borrowed vector into caller-owned storage.
Unlike Self::matrixvectormultiply, this accepts an ArrayView1 and
does not require either operand to be copied for materialized dense or
sparse designs.
Sourcepub fn apply_view(&self, vector: ArrayView1<'_, f64>) -> Array1<f64>
pub fn apply_view(&self, vector: ArrayView1<'_, f64>) -> Array1<f64>
Apply the design to a borrowed vector and return the owned result.
Sourcepub fn transpose_apply_view_into(
&self,
vector: ArrayView1<'_, f64>,
output: ArrayViewMut1<'_, f64>,
)
pub fn transpose_apply_view_into( &self, vector: ArrayView1<'_, f64>, output: ArrayViewMut1<'_, f64>, )
Apply the transposed design to a borrowed vector into caller storage.
Sourcepub fn column_into(&self, col: usize, output: ArrayViewMut1<'_, f64>)
pub fn column_into(&self, col: usize, output: ArrayViewMut1<'_, f64>)
Extract one column into caller-owned storage without densification.
Sourcepub fn get(&self, i: usize, j: usize) -> f64
pub fn get(&self, i: usize, j: usize) -> f64
Element access: returns the value at row i, column j.
For materialized dense matrices this is O(1). For sparse matrices,
the dense form is cached on the SparseDesignMatrix itself, so
repeated calls amortize to O(1) after the first call populates the
cache. For operator-backed (Lazy) dense matrices this call performs
an O(n) single-column materialization via extract_column; callers
sweeping many cells should call as_dense_cow() or to_dense()
once and index the returned array directly — calling get in a
per-cell loop on a Lazy operator is O(nrows · ncols) per call
because the operator has no dense cache.
Sourcepub fn extract_column(&self, j: usize) -> Array1<f64>
pub fn extract_column(&self, j: usize) -> Array1<f64>
Extract a single column as a dense vector without full densification.
Dense: O(n) column copy.Sparse(CSC): O(nnz_j) using the column pointer structure.- lazy
Dense: O(matvec) via unit-vector application.
Sourcepub fn extract_columns(&self, cols: &[usize]) -> Array2<f64>
pub fn extract_columns(&self, cols: &[usize]) -> Array2<f64>
Batched column extraction: returns an nrows × cols.len() dense block
whose k-th column equals extract_column(cols[k]).
For lazy operator-backed designs this routes through the operator’s
apply_columns, which ReparamOperator implements as a single GEMM
(X · Qs[:, cols]) instead of one matvec dispatch per column.
Sourcepub fn as_dense_ref(&self) -> Option<&Array2<f64>>
pub fn as_dense_ref(&self) -> Option<&Array2<f64>>
Returns a reference to the inner dense array if this is a Dense variant.
pub const fn is_materialized_dense(&self) -> bool
pub const fn is_operator_backed(&self) -> bool
Sourcepub const fn is_sparse(&self) -> bool
pub const fn is_sparse(&self) -> bool
Whether this design is backed by a sparse (CSR/COO) representation
rather than a dense or dense-operator backing. Used to gate the
row-chunked Xᵀ diag(w) X BLAS-3 Gram path, which is structurally
applicable only to dense / dense-operator designs (a sparse block must
keep the generic sparse-aware per-row pullback).
Sourcepub fn as_dense_cow(&self) -> Cow<'_, Array2<f64>>
pub fn as_dense_cow(&self) -> Cow<'_, Array2<f64>>
Zero-copy borrow when Dense, materialized conversion when Sparse.
This avoids the unconditional clone that to_dense() performs on dense
matrices. Callers that only need a &Array2<f64> should use this and
then call Cow::as_ref() or &*cow.
Sourcepub fn to_dense_cow(&self) -> Cow<'_, Array2<f64>>
pub fn to_dense_cow(&self) -> Cow<'_, Array2<f64>>
Borrow when already-materialized dense, otherwise materialize via
chunks (or via the sparse conversion path) and return an owned Cow.
Use this when a code path genuinely needs a contiguous Array2<f64>
view of an operator-backed design (e.g. legacy dense linear-algebra
helpers that the operator-aware code paths have not yet replaced).
Prefer try_row_chunk / matrixvectormultiply when chunked or
matrix-free access suffices.
Sourcepub fn to_dense(&self) -> Array2<f64>
pub fn to_dense(&self) -> Array2<f64>
Returns the design as a contiguous Array2<f64>.
Operator-backed designs consult the available-memory-derived policy
before allocating. Production code that can handle refusal must prefer
Self::try_to_dense_governed, which additionally holds the
process-wide reservation for the returned matrix’s whole lifetime.
Sparse designs refuse to densify past the process memory budget (an n×p dense materialization that can never fit is a caller bug — the design should have stayed sparse).
Sourcepub fn to_dense_arc(&self) -> Arc<Array2<f64>> ⓘ
pub fn to_dense_arc(&self) -> Arc<Array2<f64>> ⓘ
Arc-shared variant of Self::to_dense, with the same policy guard.
pub fn try_to_dense_arc( &self, context: &str, ) -> Result<Arc<Array2<f64>>, String>
Sourcepub fn try_to_dense_arc_with_policy(
&self,
context: &str,
policy: &ResourcePolicy,
) -> Result<Arc<Array2<f64>>, String>
pub fn try_to_dense_arc_with_policy( &self, context: &str, policy: &ResourcePolicy, ) -> Result<Arc<Array2<f64>>, String>
Policy-aware densify: callers that own the consumer’s dense budget can
override the conservative default cap used by Self::try_to_dense_arc.
pub fn to_csr_cache(&self) -> Option<SparseRowMat<usize, f64>>
pub fn as_sparse(&self) -> Option<&SparseDesignMatrix>
pub fn as_dense(&self) -> Option<&Array2<f64>>
pub fn dot(&self, vector: &Array1<f64>) -> Array1<f64>
pub fn matrixvectormultiply(&self, vector: &Array1<f64>) -> Array1<f64>
pub fn transpose_vector_multiply(&self, vector: &Array1<f64>) -> Array1<f64>
pub fn compute_xtwy( &self, weights: &Array1<f64>, y: &Array1<f64>, ) -> Result<Array1<f64>, String>
pub fn diag_gram(&self, weights: &Array1<f64>) -> Result<Array1<f64>, String>
pub fn quadratic_form_diag( &self, middle: &Array2<f64>, ) -> Result<Array1<f64>, String>
pub fn apply_weighted_normal( &self, weights: &Array1<f64>, vector: &Array1<f64>, penalty: Option<&Array2<f64>>, ridge: f64, ) -> Result<Array1<f64>, String>
pub fn solve_system( &self, weights: &Array1<f64>, rhs: &Array1<f64>, penalty: Option<&Array2<f64>>, ) -> Result<Array1<f64>, String>
pub fn solve_systemwith_policy( &self, weights: &Array1<f64>, rhs: &Array1<f64>, penalty: Option<&Array2<f64>>, ridge_floor: f64, ridge_policy: RidgePolicy, ) -> Result<Array1<f64>, String>
pub fn solve_system_matrix_free_pcg( &self, weights: &Array1<f64>, rhs: &Array1<f64>, penalty: Option<&Array2<f64>>, ridge_floor: f64, ) -> Result<Array1<f64>, String>
pub fn solve_system_matrix_free_pcg_with_info( &self, weights: &Array1<f64>, rhs: &Array1<f64>, penalty: Option<&Array2<f64>>, ridge_floor: f64, ) -> Result<(Array1<f64>, PcgSolveInfo), String>
pub fn should_use_matrix_free_pcg(&self) -> bool
pub fn factorize_system( &self, weights: &Array1<f64>, penalty: Option<&Array2<f64>>, ) -> Result<Box<dyn FactorizedSystem>, String>
Trait Implementations§
Source§impl Clone for DesignMatrix
impl Clone for DesignMatrix
Source§fn clone(&self) -> DesignMatrix
fn clone(&self) -> DesignMatrix
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for DesignMatrix
impl Debug for DesignMatrix
Source§impl DenseDesignOperator for DesignMatrix
impl DenseDesignOperator for DesignMatrix
Source§fn materialization_policy(&self) -> Option<MaterializationPolicy>
fn materialization_policy(&self) -> Option<MaterializationPolicy>
fn compute_xtwy( &self, weights: &Array1<f64>, y: &Array1<f64>, ) -> Result<Array1<f64>, String>
fn quadratic_form_diag( &self, middle: &Array2<f64>, ) -> Result<Array1<f64>, String>
Source§fn row_chunk_into(
&self,
rows: Range<usize>,
out: ArrayViewMut2<'_, f64>,
) -> Result<(), MatrixMaterializationError>
fn row_chunk_into( &self, rows: Range<usize>, out: ArrayViewMut2<'_, f64>, ) -> Result<(), MatrixMaterializationError>
Source§fn to_dense(&self) -> Array2<f64>
fn to_dense(&self) -> Array2<f64>
Source§fn try_row_chunk(
&self,
rows: Range<usize>,
) -> Result<Array2<f64>, MatrixMaterializationError>
fn try_row_chunk( &self, rows: Range<usize>, ) -> Result<Array2<f64>, MatrixMaterializationError>
row_chunk_into.Source§fn as_dense_ref(&self) -> Option<&Array2<f64>>
fn as_dense_ref(&self) -> Option<&Array2<f64>>
Source§fn apply_columns(&self, cols: &[usize]) -> Array2<f64>
fn apply_columns(&self, cols: &[usize]) -> Array2<f64>
nrows × cols.len() dense block
whose k-th column is apply(e_{cols[k]}). Read morefn estimated_dense_bytes(&self) -> usize
fn try_to_dense_with_policy( &self, policy: &MaterializationPolicy, context: &'static str, ) -> Result<Arc<Array2<f64>>, MatrixMaterializationError>
Source§fn try_to_dense_governed_with_policy(
&self,
policy: &MaterializationPolicy,
context: &'static str,
) -> Result<Governed<Array2<f64>>, MatrixMaterializationError>
fn try_to_dense_governed_with_policy( &self, policy: &MaterializationPolicy, context: &'static str, ) -> Result<Governed<Array2<f64>>, MatrixMaterializationError>
Source§impl From<&DesignMatrix> for DesignMatrix
impl From<&DesignMatrix> for DesignMatrix
Source§fn from(value: &DesignMatrix) -> Self
fn from(value: &DesignMatrix) -> Self
Source§impl From<&DesignMatrix> for DesignBlock
impl From<&DesignMatrix> for DesignBlock
Source§fn from(value: &DesignMatrix) -> Self
fn from(value: &DesignMatrix) -> Self
Source§impl<'a> From<ArrayBase<ViewRepr<&'a f64>, Dim<[usize; 2]>>> for DesignMatrix
impl<'a> From<ArrayBase<ViewRepr<&'a f64>, Dim<[usize; 2]>>> for DesignMatrix
Source§fn from(value: ArrayView2<'a, f64>) -> Self
fn from(value: ArrayView2<'a, f64>) -> Self
Source§impl From<DenseDesignMatrix> for DesignMatrix
impl From<DenseDesignMatrix> for DesignMatrix
Source§fn from(value: DenseDesignMatrix) -> Self
fn from(value: DenseDesignMatrix) -> Self
Source§impl From<DesignMatrix> for DesignBlock
impl From<DesignMatrix> for DesignBlock
Source§fn from(value: DesignMatrix) -> Self
fn from(value: DesignMatrix) -> Self
Source§impl LinearOperator for DesignMatrix
impl LinearOperator for DesignMatrix
fn uses_matrix_free_pcg(&self) -> bool
fn nrows(&self) -> usize
fn ncols(&self) -> usize
fn apply(&self, vector: &Array1<f64>) -> Array1<f64>
fn apply_weighted_normal( &self, weights: FiniteSignedWeightsView<'_>, vector: &Array1<f64>, penalty: Option<&Array2<f64>>, ridge: f64, ) -> Array1<f64>
fn apply_transpose(&self, vector: &Array1<f64>) -> Array1<f64>
fn diag_xtw_x(&self, weights: &Array1<f64>) -> Result<Array2<f64>, String>
fn diag_gram(&self, weights: &Array1<f64>) -> Result<Array1<f64>, String>
fn factorize_system( &self, weights: &Array1<f64>, penalty: Option<&Array2<f64>>, ) -> Result<Box<dyn FactorizedSystem>, String>
Source§fn xt_diag_x_signed_op(
&self,
weights: FiniteSignedWeightsView<'_>,
) -> Result<Array2<f64>, String>
fn xt_diag_x_signed_op( &self, weights: FiniteSignedWeightsView<'_>, ) -> Result<Array2<f64>, String>
XᵀWX with sign-honest
weights. Returns a dense Array2<f64> because the result is symmetric
but not guaranteed PSD (so consumers cannot assume the SymmetricMatrix
PSD contract). Default impl delegates to diag_xtw_x for legacy
operators; overriding impls may take a sign-aware fast path.Source§fn xt_diag_x_psd_op(
&self,
weights: PsdWeightsView<'_>,
) -> Result<SymmetricMatrix, String>
fn xt_diag_x_psd_op( &self, weights: PsdWeightsView<'_>, ) -> Result<SymmetricMatrix, String>
XᵀWX with w ≥ 0 discharged at the
PsdWeightsView constructor. Returns a typed SymmetricMatrix so
downstream consumers can route through PSD-only solvers (Cholesky).
Default impl wraps the signed path’s Array2 in SymmetricMatrix::Dense.fn solve_system_matrix_free_pcg_try( &self, weights: &Array1<f64>, rhs: &Array1<f64>, penalty: Option<&Array2<f64>>, baseridge: f64, ) -> Result<Array1<f64>, String>
fn solve_system_matrix_free_pcg_with_info_try( &self, weights: &Array1<f64>, rhs: &Array1<f64>, penalty: Option<&Array2<f64>>, baseridge: f64, ) -> Result<(Array1<f64>, PcgSolveInfo), String>
fn solve_system( &self, weights: &Array1<f64>, rhs: &Array1<f64>, penalty: Option<&Array2<f64>>, ) -> Result<Array1<f64>, String>
fn solve_systemwith_policy( &self, weights: &Array1<f64>, rhs: &Array1<f64>, penalty: Option<&Array2<f64>>, ridge_floor: f64, ridge_policy: RidgePolicy, ) -> Result<Array1<f64>, String>
Auto Trait Implementations§
impl !RefUnwindSafe for DesignMatrix
impl !UnwindSafe for DesignMatrix
impl Freeze for DesignMatrix
impl Send for DesignMatrix
impl Sync for DesignMatrix
impl Unpin for DesignMatrix
impl UnsafeUnpin for DesignMatrix
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,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
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 more