pub struct NumCooMatrix<T>{ /* private fields */ }Expand description
Holds the row index, col index, and values of a matrix (also known as Triplet)
§Remarks
- Only the non-zero values are required
- Entries with repeated (i,j) indices are allowed
- Repeated (i,j) entries should be summed when solving a linear system
- The repeated (i,j) capability is of great convenience for Finite Element solvers
- A maximum number of entries must be decided prior to allocating a new COO matrix
- The maximum number of entries includes possible entries with repeated indices
Implementations§
Source§impl NumCooMatrix<Complex<f64>>
impl NumCooMatrix<Complex<f64>>
Sourcepub fn assign_real(
&mut self,
alpha: f64,
beta: f64,
other: &CooMatrix,
) -> Result<(), StrError>
pub fn assign_real( &mut self, alpha: f64, beta: f64, other: &CooMatrix, ) -> Result<(), StrError>
Assigns this matrix to the values of another real matrix (scaled)
Performs:
this = (α + βi) · otherThus:
this[p].real = α · other[p]
this[p].imag = β · other[p]
other[p] ∈ Reals
p = [0, nnz(other)]Warning: make sure to allocate max_nnz ≥ nnz(other).
Sourcepub fn augment_real(
&mut self,
alpha: f64,
beta: f64,
other: &CooMatrix,
) -> Result<(), StrError>
pub fn augment_real( &mut self, alpha: f64, beta: f64, other: &CooMatrix, ) -> Result<(), StrError>
Augments this matrix with the entries of another real matrix (scaled)
Effectively, performs:
this += (α + βi) · otherThus:
this[p].real += α · other[p]
this[p].imag += β · other[p]
other[p] ∈ Reals
p = [0, nnz(other)]Warning: make sure to allocate max_nnz ≥ nnz(this) + nnz(other).
Source§impl<T> NumCooMatrix<T>
impl<T> NumCooMatrix<T>
Sourcepub fn new(
nrow: usize,
ncol: usize,
max_nnz: usize,
symmetric: Sym,
) -> Result<Self, StrError>
pub fn new( nrow: usize, ncol: usize, max_nnz: usize, symmetric: Sym, ) -> Result<Self, StrError>
Creates a new COO matrix representing a sparse matrix
§Input
nrow– (≥ 1) Is the number of rows of the sparse matrix (must be fit i32)ncol– (≥ 1) Is the number of columns of the sparse matrix (must be fit i32)max_nnz– (≥ 1) Maximum number of entries ≥ nnz (number of non-zeros), including entries with repeated indices. (must be fit i32)symmetric– indicates whether the matrix is symmetric or not. If symmetric, indicates the representation too.
§Examples
use russell_sparse::prelude::*;
use russell_sparse::StrError;
fn main() -> Result<(), StrError> {
// allocate the coefficient matrix
// 2 3 . . .
// 3 . 4 . 6
// . -1 -3 2 .
// . . 1 . .
// . 4 2 . 1
let mut coo = CooMatrix::new(5, 5, 13, Sym::No)?;
coo.put(0, 0, 1.0)?; // << (0, 0, a00/2) duplicate
coo.put(0, 0, 1.0)?; // << (0, 0, a00/2) duplicate
coo.put(1, 0, 3.0)?;
coo.put(0, 1, 3.0)?;
coo.put(2, 1, -1.0)?;
coo.put(4, 1, 4.0)?;
coo.put(1, 2, 4.0)?;
coo.put(2, 2, -3.0)?;
coo.put(3, 2, 1.0)?;
coo.put(4, 2, 2.0)?;
coo.put(2, 3, 2.0)?;
coo.put(1, 4, 6.0)?;
coo.put(4, 4, 1.0)?;
// covert to dense
let a = coo.as_dense();
let correct = "┌ ┐\n\
│ 2 3 0 0 0 │\n\
│ 3 0 4 0 6 │\n\
│ 0 -1 -3 2 0 │\n\
│ 0 0 1 0 0 │\n\
│ 0 4 2 0 1 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);
// reset
coo.reset();
// covert to dense
let a = coo.as_dense();
let correct = "┌ ┐\n\
│ 0 0 0 0 0 │\n\
│ 0 0 0 0 0 │\n\
│ 0 0 0 0 0 │\n\
│ 0 0 0 0 0 │\n\
│ 0 0 0 0 0 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);
// put again doubled values
coo.put(0, 0, 2.0)?; // << duplicate
coo.put(0, 0, 2.0)?; // << duplicate
coo.put(1, 0, 6.0)?;
coo.put(0, 1, 6.0)?;
coo.put(2, 1, -2.0)?;
coo.put(4, 1, 8.0)?;
coo.put(1, 2, 8.0)?;
coo.put(2, 2, -6.0)?;
coo.put(3, 2, 2.0)?;
coo.put(4, 2, 4.0)?;
coo.put(2, 3, 4.0)?;
coo.put(1, 4, 12.0)?;
coo.put(4, 4, 2.0)?;
// covert to dense
let a = coo.as_dense();
let correct = "┌ ┐\n\
│ 4 6 0 0 0 │\n\
│ 6 0 8 0 12 │\n\
│ 0 -2 -6 4 0 │\n\
│ 0 0 2 0 0 │\n\
│ 0 8 4 0 2 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);
Ok(())
}Sourcepub fn from(
nrow: usize,
ncol: usize,
row_indices: Vec<i32>,
col_indices: Vec<i32>,
values: Vec<T>,
symmetric: Sym,
) -> Result<Self, StrError>
pub fn from( nrow: usize, ncol: usize, row_indices: Vec<i32>, col_indices: Vec<i32>, values: Vec<T>, symmetric: Sym, ) -> Result<Self, StrError>
Creates a COO matrix from triplets: row indices, col indices, and non-zero values
§Input
nrow– (≥ 1) Is the number of rows of the sparse matrix (must be fit i32)ncol– (≥ 1) Is the number of columns of the sparse matrix (must be fit i32)row_indices– (len = nnz) Is the array of row indicescol_indices– (len = nnz) Is the array of columns indicesvalues– (len = nnz) Is the array of non-zero valuessymmetric– Indicates that this matrix is symmetric (with the storage type)
§Examples
use russell_sparse::prelude::*;
use russell_sparse::StrError;
fn main() -> Result<(), StrError> {
// allocate a square matrix and store as CSC matrix
// 2 3 . . .
// 3 . 4 . 6
// . -1 -3 2 .
// . . 1 . .
// . 4 2 . 1
let nrow = 5;
let ncol = 5;
let row_indices = vec![0, /*dup*/ 0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4];
let col_indices = vec![0, /*dup*/ 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4, 4];
let values = vec![
1.0, /*dup*/ 1.0, 3.0, 3.0, -1.0, 4.0, 4.0, -3.0, 1.0, 2.0, 2.0, 6.0, 1.0,
];
let coo = CooMatrix::from(nrow, ncol, row_indices, col_indices, values, Sym::No)?;
// covert to dense
let a = coo.as_dense();
let correct = "┌ ┐\n\
│ 2 3 0 0 0 │\n\
│ 3 0 4 0 6 │\n\
│ 0 -1 -3 2 0 │\n\
│ 0 0 1 0 0 │\n\
│ 0 4 2 0 1 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);
Ok(())
}Sourcepub fn put(&mut self, i: usize, j: usize, aij: T) -> Result<(), StrError>
pub fn put(&mut self, i: usize, j: usize, aij: T) -> Result<(), StrError>
Puts a new entry and updates pos (may be duplicate)
§Input
i– row index (indices start at zero; zero-based)j– column index (indices start at zero; zero-based)aij– the value A(i,j)
§Examples
use russell_lab::vec_approx_eq;
use russell_sparse::prelude::*;
use russell_sparse::StrError;
fn main() -> Result<(), StrError> {
let (nrow, ncol, nnz) = (3, 3, 4);
let mut coo = CooMatrix::new(nrow, ncol, nnz, Sym::No)?;
coo.put(0, 0, 1.0)?;
coo.put(1, 1, 2.0)?;
coo.put(2, 2, 3.0)?;
coo.put(0, 1, 4.0)?;
let a = coo.as_dense();
let correct = "┌ ┐\n\
│ 1 4 0 │\n\
│ 0 2 0 │\n\
│ 0 0 3 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);
Ok(())
}Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Resets the position of the current non-zero value
This function allows using put all over again.
§Examples
use russell_sparse::prelude::*;
use russell_sparse::StrError;
fn main() -> Result<(), StrError> {
let (nrow, ncol, max_nnz) = (3, 3, 10);
let mut coo = CooMatrix::new(nrow, ncol, max_nnz, Sym::No)?;
coo.put(0, 0, 1.0)?;
coo.put(1, 1, 2.0)?;
coo.put(2, 2, 3.0)?;
coo.put(0, 1, 4.0)?;
let a = coo.as_dense();
let correct = "┌ ┐\n\
│ 1 4 0 │\n\
│ 0 2 0 │\n\
│ 0 0 3 │\n\
└ ┘";
coo.reset();
let (nrow, ncol, nnz, sym) = coo.get_info();
assert_eq!(nrow, 3);
assert_eq!(ncol, 3);
assert_eq!(nnz, 0);
assert_eq!(sym, Sym::No);
Ok(())
}Sourcepub fn as_dense(&self) -> NumMatrix<T>
pub fn as_dense(&self) -> NumMatrix<T>
Converts this COO matrix to a dense matrix
use russell_sparse::prelude::*;
use russell_sparse::StrError;
fn main() -> Result<(), StrError> {
// define (4 x 4) sparse matrix with 6+1 non-zero values
// (with an extra ij-repeated entry)
let (nrow, ncol, max_nnz) = (4, 4, 10);
let mut coo = CooMatrix::new(nrow, ncol, max_nnz, Sym::No)?;
coo.put(0, 0, 0.5)?; // (0, 0, a00/2) << duplicate
coo.put(0, 0, 0.5)?; // (0, 0, a00/2) << duplicate
coo.put(0, 1, 2.0)?;
coo.put(1, 0, 3.0)?;
coo.put(1, 1, 4.0)?;
coo.put(2, 2, 5.0)?;
coo.put(3, 3, 6.0)?;
// convert to dense
let a = coo.as_dense();
let correct = "┌ ┐\n\
│ 1 2 0 0 │\n\
│ 3 4 0 0 │\n\
│ 0 0 5 0 │\n\
│ 0 0 0 6 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);
Ok(())
}Sourcepub fn to_dense(&self, a: &mut NumMatrix<T>) -> Result<(), StrError>
pub fn to_dense(&self, a: &mut NumMatrix<T>) -> Result<(), StrError>
Converts this COO matrix to a dense matrix
§Input
a– where to store the dense matrix; it must be (nrow, ncol)
§Examples
use russell_lab::Matrix;
use russell_sparse::prelude::*;
use russell_sparse::StrError;
fn main() -> Result<(), StrError> {
// define (4 x 4) sparse matrix with 6+1 non-zero values
// (with an extra ij-repeated entry)
let (nrow, ncol, max_nnz) = (4, 4, 10);
let mut coo = CooMatrix::new(nrow, ncol, max_nnz, Sym::No)?;
coo.put(0, 0, 0.5)?; // (0, 0, a00/2) << duplicate
coo.put(0, 0, 0.5)?; // (0, 0, a00/2) << duplicate
coo.put(0, 1, 2.0)?;
coo.put(1, 0, 3.0)?;
coo.put(1, 1, 4.0)?;
coo.put(2, 2, 5.0)?;
coo.put(3, 3, 6.0)?;
// convert to dense
let mut a = Matrix::new(nrow, ncol);
coo.to_dense(&mut a)?;
let correct = "┌ ┐\n\
│ 1 2 0 0 │\n\
│ 3 4 0 0 │\n\
│ 0 0 5 0 │\n\
│ 0 0 0 6 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);
Ok(())
}Sourcepub fn mat_vec_mul(
&self,
v: &mut NumVector<T>,
alpha: T,
u: &NumVector<T>,
) -> Result<(), StrError>
pub fn mat_vec_mul( &self, v: &mut NumVector<T>, alpha: T, u: &NumVector<T>, ) -> Result<(), StrError>
Performs the matrix-vector multiplication
v := α ⋅ a ⋅ u
(m) (m,n) (n)§Input
u– Vector with dimension equal to the number of columns of the matrix
§Output
v– Vector with dimension equal to the number of rows of the matrix
§Note
This method is not highly efficient but should useful in verifications.
§Examples
use russell_lab::{Matrix, Vector};
use russell_sparse::prelude::*;
use russell_sparse::StrError;
fn main() -> Result<(), StrError> {
// set sparse matrix (3 x 3) with 6 non-zeros
let (nrow, ncol, max_nnz) = (3, 3, 6);
let mut coo = CooMatrix::new(nrow, ncol, max_nnz, Sym::No)?;
coo.put(0, 0, 1.0)?;
coo.put(1, 0, 2.0)?;
coo.put(1, 1, 3.0)?;
coo.put(2, 0, 4.0)?;
coo.put(2, 1, 5.0)?;
coo.put(2, 2, 6.0)?;
// check matrix
let a = coo.as_dense();
let correct_a = "┌ ┐\n\
│ 1 0 0 │\n\
│ 2 3 0 │\n\
│ 4 5 6 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct_a);
// perform mat-vec-mul
let u = Vector::from(&[1.0, 1.0, 1.0]);
let mut v = Vector::new(nrow);
coo.mat_vec_mul(&mut v, 1.0, &u)?;
// check vector
let correct_v = "┌ ┐\n\
│ 1 │\n\
│ 5 │\n\
│ 15 │\n\
└ ┘";
assert_eq!(format!("{}", v), correct_v);
Ok(())
}Sourcepub fn assign(
&mut self,
alpha: T,
other: &NumCooMatrix<T>,
) -> Result<(), StrError>
pub fn assign( &mut self, alpha: T, other: &NumCooMatrix<T>, ) -> Result<(), StrError>
Assigns this matrix to the values of another matrix (scaled)
Performs:
this = α · otherWarning: make sure to allocate max_nnz ≥ nnz(other).
Sourcepub fn augment(
&mut self,
alpha: T,
other: &NumCooMatrix<T>,
) -> Result<(), StrError>
pub fn augment( &mut self, alpha: T, other: &NumCooMatrix<T>, ) -> Result<(), StrError>
Augments this matrix with the entries of another matrix (scaled)
Effectively, performs:
this += α · otherWarning: make sure to allocate max_nnz ≥ nnz(this) + nnz(other).
Sourcepub fn get_info(&self) -> (usize, usize, usize, Sym)
pub fn get_info(&self) -> (usize, usize, usize, Sym)
Returns information about the dimensions and symmetric type
Returns (nrow, ncol, nnz, sym)
§Examples
use russell_sparse::prelude::*;
use russell_sparse::StrError;
fn main() -> Result<(), StrError> {
let coo = CooMatrix::new(1, 2, 3, Sym::No)?;
let (nrow, ncol, nnz, sym) = coo.get_info();
assert_eq!(nrow, 1);
assert_eq!(ncol, 2);
assert_eq!(nnz, 0);
assert_eq!(sym, Sym::No);
Ok(())
}Sourcepub fn get_row_indices(&self) -> &[i32]
pub fn get_row_indices(&self) -> &[i32]
Get an access to the row indices
row_indices.len() == nnzSourcepub fn get_col_indices(&self) -> &[i32]
pub fn get_col_indices(&self) -> &[i32]
Get an access to the column indices
col_indices.len() == nnzSourcepub fn get_values(&self) -> &[T]
pub fn get_values(&self) -> &[T]
Get an access to the values
values.len() == nnzSourcepub fn get_values_mut(&mut self) -> &mut [T]
pub fn get_values_mut(&mut self) -> &mut [T]
Get a mutable access the values
values.len() == nnzNote: the values may be modified externally, but not the indices.
Trait Implementations§
Source§impl<T> Clone for NumCooMatrix<T>
impl<T> Clone for NumCooMatrix<T>
Source§fn clone(&self) -> NumCooMatrix<T>
fn clone(&self) -> NumCooMatrix<T>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more