pub trait DenseMatrix:
Matrix
+ for<'b> MatrixOpsByValue<&'b Self, Self>
+ for<'b> MatrixMutOpsByValue<&'b Self> {
Show 14 methods
// Required methods
fn update_backward_diff(&mut self, order: IndexType, d: &Self::V);
fn mul_cols_by(&mut self, ncols: IndexType, rhs: &[Self::T]);
fn gemv_cols(
&self,
start: IndexType,
end: IndexType,
alpha: Self::T,
x: &[Self::T],
beta: Self::T,
y: &mut Self::V,
);
fn column(&self, i: IndexType) -> <Self::V as Vector>::View<'_>;
fn column_mut(&mut self, i: IndexType) -> <Self::V as Vector>::ViewMut<'_>;
fn set_index(&mut self, i: IndexType, j: IndexType, value: Self::T);
fn set_index_batch(
&mut self,
batch: IndexType,
i: IndexType,
j: IndexType,
value: Self::T,
);
fn get_index(&self, i: IndexType, j: IndexType) -> Self::T;
fn resize_cols(&mut self, ncols: IndexType);
fn from_vec(
nrows: IndexType,
ncols: IndexType,
data: Vec<Self::T>,
ctx: Self::C,
) -> Self;
// Provided methods
fn update_backward_diff_transpose(
&mut self,
order: IndexType,
d_bar: &mut Self::V,
) { ... }
fn fill(&mut self, value: Self::T) { ... }
fn mul_cols_by_transpose(&mut self, ncols: IndexType, rhs: &[Self::T]) { ... }
fn ger_cols(
&mut self,
start: IndexType,
end: IndexType,
alpha: Self::T,
x: &[Self::T],
y: &Self::V,
) { ... }
}Expand description
A dense column-major matrix with efficient column access operations.
This trait represents matrices stored in column-major order, where accessing matrix columns is efficient. It supports:
- Column operations (access, modification, and the fused column kernels below)
- Element access and modification
- Matrix resizing
The column-major layout makes operations on individual or ranges of columns very efficient.
Required Methods§
Sourcefn update_backward_diff(&mut self, order: IndexType, d: &Self::V)
fn update_backward_diff(&mut self, order: IndexType, d: &Self::V)
Update a table of backward differences held in columns 0..=order+2 of
this matrix, given the newly computed highest-order correction d.
Equivalent to:
self[:, order+2] = d - self[:, order+1]
for i in (0..=order+1).rev() { self[:, i] += self[:, i+1] }where each addition uses the just-updated value of column i+1 (a
right-to-left cumulative scan).
Sourcefn mul_cols_by(&mut self, ncols: IndexType, rhs: &[Self::T])
fn mul_cols_by(&mut self, ncols: IndexType, rhs: &[Self::T])
Right-multiply a range of columns by a small matrix, in place:
self[:, 0..ncols] = self[:, 0..ncols] * rhsrhs is an ncols x ncols block held column-major in a host slice of exactly
ncols * ncols values — it is small (the BDF step-size update uses at most 6 x 6).
Panics if ncols exceeds MAX_SMALL_COLS, since the serial backends stage the old
column values in a fixed-size buffer rather than allocating.
Sourcefn gemv_cols(
&self,
start: IndexType,
end: IndexType,
alpha: Self::T,
x: &[Self::T],
beta: Self::T,
y: &mut Self::V,
)
fn gemv_cols( &self, start: IndexType, end: IndexType, alpha: Self::T, x: &[Self::T], beta: Self::T, y: &mut Self::V, )
Matrix-vector multiply over a range of columns, with host-side coefficients:
y = alpha * self[:, start..end] * x + beta * yx is a host slice, not a vector, because x.len() is the width of the column range
rather than a dimension of the problem: every caller in the solvers passes a short
coefficient list computed from host scalars — a Runge-Kutta tableau row, the b/d
vectors, interpolation weights, BDF’s psi weights. Keeping them on the host is what lets
those callers build them in a stack array instead of allocating a vector per call.
Use Matrix::gemv instead when x is a genuine operand of length ncols — a
Jacobian- or mass-times-vector product.
Only the leading end - start columns take part; the rest of the matrix is not read.
x.len() must be at least end - start; only its leading end - start entries are
read, as with a BLAS gemv given a longer vector and incx = 1. beta == 0 means y
is not read, so it may hold uninitialised values. An empty range contributes nothing,
leaving y = beta * y.
The coefficients are shared by every batch — unlike Matrix::gemv, this cannot apply
a different x per batch. Panics if end - start exceeds MAX_SMALL_COLS.
Sourcefn column(&self, i: IndexType) -> <Self::V as Vector>::View<'_>
fn column(&self, i: IndexType) -> <Self::V as Vector>::View<'_>
Get an immutable vector view of column i.
Sourcefn column_mut(&mut self, i: IndexType) -> <Self::V as Vector>::ViewMut<'_>
fn column_mut(&mut self, i: IndexType) -> <Self::V as Vector>::ViewMut<'_>
Get a mutable vector view of column i.
Sourcefn set_index(&mut self, i: IndexType, j: IndexType, value: Self::T)
fn set_index(&mut self, i: IndexType, j: IndexType, value: Self::T)
Set the value at the given row and column indices.
Scalar access is single-system, as it is for Vector::set_index: panics unless
nbatch == 1. So does IndexMut.
Sourcefn set_index_batch(
&mut self,
batch: IndexType,
i: IndexType,
j: IndexType,
value: Self::T,
)
fn set_index_batch( &mut self, batch: IndexType, i: IndexType, j: IndexType, value: Self::T, )
Set the value at the given row and column indices, in a single batch.
The batch-aware counterpart to Self::set_index: (i, j) alone is ambiguous once
nbatch > 1, so the batch is named explicitly. Mirrors Vector::get_batch_mut.
Sourcefn get_index(&self, i: IndexType, j: IndexType) -> Self::T
fn get_index(&self, i: IndexType, j: IndexType) -> Self::T
Get the value at the given row and column indices.
Scalar access is single-system, as it is for Vector::get_index: panics unless
nbatch == 1. So does Index.
Sourcefn resize_cols(&mut self, ncols: IndexType)
fn resize_cols(&mut self, ncols: IndexType)
Resize the number of columns in the matrix, preserving existing data.
New elements (if added) are uninitialized. If the number of columns decreases, trailing columns are discarded.
Provided Methods§
Sourcefn update_backward_diff_transpose(
&mut self,
order: IndexType,
d_bar: &mut Self::V,
)
fn update_backward_diff_transpose( &mut self, order: IndexType, d_bar: &mut Self::V, )
Transpose of Self::update_backward_diff with respect to (self, d).
Given cotangents C of the updated columns 0..=order+2, overwrite them with the
cotangents of the columns before the update, and write the cotangent of d into d_bar.
Equivalent to:
d_bar = C[:, 0] + C[:, 1] + ... + C[:, order+2]
for i in 1..=order { C[:, i] += C[:, i-1] } // left-to-right cumulative scan
C[:, order+1] = -C[:, order+2]
C[:, order+2] = 0The default implementation is one Self::gemv_cols and one Self::mul_cols_by, so it
needs no backend-specific code. Panics if order + 3 exceeds MAX_SMALL_COLS.
Sourcefn fill(&mut self, value: Self::T)
fn fill(&mut self, value: Self::T)
Set every entry of every batch to value, in place.
The default copies one column of values into each column, so it needs no
backend-specific code; the host backends override it with their own fill.
Sourcefn mul_cols_by_transpose(&mut self, ncols: IndexType, rhs: &[Self::T])
fn mul_cols_by_transpose(&mut self, ncols: IndexType, rhs: &[Self::T])
Right-multiply a range of columns by the transpose of a small matrix, in place:
self[:, 0..ncols] = self[:, 0..ncols] * rhsᵀrhs is laid out as in Self::mul_cols_by. The default implementation transposes it on
the host and calls Self::mul_cols_by. Panics if ncols exceeds MAX_SMALL_COLS.
Sourcefn ger_cols(
&mut self,
start: IndexType,
end: IndexType,
alpha: Self::T,
x: &[Self::T],
y: &Self::V,
)
fn ger_cols( &mut self, start: IndexType, end: IndexType, alpha: Self::T, x: &[Self::T], y: &Self::V, )
Rank-one update over a range of columns, with host-side coefficients: BLAS ger
(“general rank-1”) restricted to start..end, and the transpose of Self::gemv_cols.
self[:, start..end] += alpha * y * xᵀ, i.e. self[:, j] += alpha * x[j - start] * yWhere Self::gemv_cols sums the columns into a vector, this adds a vector into each
column: if y = alpha * A[:, start..end] * x, the cotangent of A gains
alpha * y_bar * xᵀ, which is A_bar.ger_cols(start, end, alpha, x, &y_bar).
As for Self::gemv_cols, x is a host slice of at least end - start coefficients,
shared by every batch, and only the columns in the range are touched. y has this
matrix’s rows and lanes.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".