Sparse

Struct Sparse 

Source
pub struct Sparse<T> {
    pub rows: usize,
    pub cols: usize,
    pub nonzero: usize,
    pub val: Vec<T>,
    pub row_index: Vec<usize>,
    pub col_start: Vec<usize>,
}

Fields§

§rows: usize§cols: usize§nonzero: usize§val: Vec<T>§row_index: Vec<usize>§col_start: Vec<usize>

Implementations§

Source§

impl<T: Copy + Number + Debug> Sparse<T>

Source

pub fn from_vecs( rows: usize, cols: usize, val: Vec<T>, row_index: Vec<usize>, col_start: Vec<usize>, ) -> Self

Create a new sparse matrix of specified size using a vector of values

Source

pub fn from_triplets( rows: usize, cols: usize, triplets: &mut Vec<(usize, usize, T)>, ) -> Self

Create a new sparse matrix of specified size using a vector of triplets

Examples found in repository?
examples/sparse_linear_system.rs (line 34)
9fn main() {
10    println!( "------------------ Sparse linear system ------------------" );
11    println!( "  * Solving the linear system Ax = b, for x, where" );
12    let n: usize = 4;
13    let mut a = Mat64::new( n, n, 0.0 );
14    let mut triplets = Vec::new();
15    for i in 0..n {
16        a[(i,i)] = 2.0;
17        triplets.push( ( i, i, 2.0 ) );
18        if i > 0 {
19            a[( i - 1 , i )] = 1.0;
20            triplets.push( ( i - 1, i, 1.0 ) );
21        }
22        if i < n - 1 {
23            a[( i + 1 , i )] = 1.0;
24            triplets.push( ( i + 1, i, 1.0 ) );
25        }
26    }
27    println!( "  * A ={}", a );
28    let b = Vec64::random( n );
29    println!( "  * b^T ={}", b );
30    println!( "  * as both dense and sparse linear systems.");
31    let dense_x = a.solve_basic( &b );
32    println!( "  * The dense system gives the solution vector");
33    println!( "  * x^T ={}", dense_x );
34    let sparse = Sparse::<f64>::from_triplets( n, n, &mut triplets );
35    //let sparse_x = sparse.solve( b ).unwrap();
36    let mut sparse_x = Vector::<f64>::new( n, 0.0 );
37    let max_iter = 1000;
38    let tol = 1e-8;
39    let result = sparse.solve_bicgstab( &b, &mut sparse_x, max_iter, tol );
40    println!( "  * The sparse system gives the solution vector");
41    println!( "  * x^T ={}", sparse_x );
42    match result {
43        Ok( iter ) => println!( "  * The sparse system converged in {} iterations.", iter ),
44        Err( error ) => println!( "  * The sparse system failed to converge, error = {}", error )
45    }
46    let diff = dense_x - sparse_x;
47    println!( "  * The maximum difference between the two is {:+.2e}", diff.norm_inf() );
48    println!( "-------------------- FINISHED ---------------------" );
49}
More examples
Hide additional examples
examples/sparse_laplace.rs (line 79)
11fn main() {
12    println!( "------------------ Laplace's equation ------------------" );
13    println!( "  * Solve Laplace's equation on the unit square subject");
14    println!( "  * to the given boundary conditions. The exact solution");
15    println!( "  * is u(x,y) = y/[(1+x)^2 + y^2].");
16    let start = Instant::now();
17    let n: usize = 64;                          // Number of intervals
18    let dx: f64 = 1.0 / ( n as f64 );           // Step size
19    let size: usize = ( n + 1 ) * ( n + 1 );    // Size of the linear system
20    let mut rhs = Vec64::zeros( size );         // Right hand side vector 
21
22    let mut triplets = Vec::new();
23    let mut row: usize = 0;
24    
25    // x = 0 boundary ( u = y / ( 1 + y^2 ) )
26    let i = 0;
27    for j in 0..n+1 {
28        let y = (j as f64) * dx;
29        triplets.push( ( row, i * ( n + 1 ) + j, 1.0 ) );
30        rhs[ row ] = y / ( 1.0 + y * y );
31        row += 1;
32    }
33
34    for i in 1..n {
35        let x = (i as f64) * dx;
36        // y = 0 boundary ( u = 0 )
37        let j = 0;
38        triplets.push( ( row, i * ( n + 1 ) + j, 1.0 ) );
39        rhs[ row ] = 0.0;
40        row += 1;
41        // Interior nodes
42        for j in 1..n {
43            triplets.push( ( row, ( i - 1 ) * ( n + 1 ) + j, 1.0 ) );
44            triplets.push( ( row, ( i + 1 ) * ( n + 1 ) + j, 1.0 ) );
45            triplets.push( ( row, i * ( n + 1 ) + j - 1, 1.0 ) );
46            triplets.push( ( row, i * ( n + 1 ) + j + 1, 1.0 ) );
47            triplets.push( ( row, i * ( n + 1 ) + j, - 4.0 ) );
48            rhs[ row ] = 0.0;
49            row += 1;
50        }
51        // y = 1 boundary ( u = 1 / ( ( 1 + x )^2 + 1 ) )
52        let j = n;
53        triplets.push( ( row, i * ( n + 1 ) + j, 1.0 ) );
54        rhs[ row ] = 1. / ( ( 1. + x ) * ( 1. + x ) + 1. );
55        row += 1;
56    }
57
58    // x = 1 boundary ( u = y / ( 4 + y^2 ) )
59    let i = n;
60    for j in 0..n+1 {
61        let y = (j as f64) * dx;
62        triplets.push( ( row, i * ( n + 1 ) + j, 1.0 ) );
63        rhs[ row ] = y / ( 4. + y * y );
64        row += 1;
65    }
66
67    // Exact solution u = y / ( ( 1 + x )^2 + y^2 )
68    let mut u_exact = Vec64::zeros( size );    
69    row = 0;
70    for i in 0..n+1 {
71        let x = (i as f64) * dx;
72        for j in 0..n+1 {
73            let y = (j as f64) * dx;
74            u_exact[ row ] = y / ( ( 1. + x ) * ( 1. + x ) + y * y );
75            row += 1;
76        }
77    }
78    // Create the sparse matrix from the triplets
79    let sparse = Sparse::<f64>::from_triplets( size, size, &mut triplets );
80    let duration = start.elapsed();
81    println!("  * Time to create the matrix: {:?}", duration);
82    // Solve the sparse system
83    let mut u_guess = Vector::<f64>::random( size ); // A better guess would improve convergence
84    let max_iter = 1000;
85    let tol = 1e-8;
86    let result = sparse.solve_qmr( &rhs, &mut u_guess, max_iter, tol );
87    // Output time and error
88    let duration = start.elapsed();
89    match result {
90        Ok( iter ) => println!( "  * The sparse system converged in {} iterations.", iter ),
91        Err( error ) => println!( "  * The sparse system failed to converge, error = {}", error )
92    }
93    println!("  * Time to solve the system: {:?}", duration);
94    let u_diff = u_guess - u_exact;
95    println!("  * Solution error = {}", u_diff.norm_2() );
96    println!( "-------------------- FINISHED ---------------------" );
97}
Source

pub fn col_index(&self) -> Vector<usize>

Return a vector of column indices relating to each value ( triplet form )

Source

pub fn get(&self, row: usize, col: usize) -> Option<T>

Get a specific element from the sparse matrix if it exists

Source

pub fn col_start_from_index(&self, col_index: &Vector<usize>) -> Vec<usize>

Calculate column start vector for a given column index vector

Source

pub fn scale(&mut self, value: &T)

Insert a non-zero element into the sparse matrix at the specified row and column Scale the non-zero elements of sparse matrix by a given value

Source

pub fn multiply(&self, x: &Vector<T>) -> Vector<T>

Multiply the sparse matrix A by a Vector x to the right and return the result vector A * x

Source

pub fn transpose_multiply(&self, x: &Vector<T>) -> Vector<T>

Multiply the transpose matrix A^T by a Vector x and return the result vector A^T * x

Source

pub fn transpose(&self) -> Sparse<T>

Return the transpose of the sparse matrix

Source

pub fn to_triplets(&self) -> Vec<(usize, usize, T)>

Return a vector of triplets representing the sparse matrix

Source

pub fn insert(&mut self, row: usize, col: usize, value: T)

Insert a non-zero element into the sparse matrix at the specified row and column If the element already exists, the value is updated. This is costly and should be avoided.

Source

pub fn to_dense(&self) -> Matrix<T>

Return a dense matrix representation of the sparse matrix

Source§

impl Sparse<f64>

Source

pub fn solve_bicg( &self, b: &Vector<f64>, x: &mut Vector<f64>, max_iter: usize, tol: f64, itol: usize, ) -> Result<usize, f64>

Solve the system of equations Ax=b using the biconjugate gradient method with a specified maximum number of iterations and tolerance. itol = 1: relative residual norm itol = 2: relative error norm Returns the number of iterations if successful or the error if the method fails

Source

pub fn solve_bicgstab( &self, b: &Vector<f64>, x: &mut Vector<f64>, max_iter: usize, tol: f64, ) -> Result<usize, f64>

Solve the system of equations Ax=b using the stabilised biconjugate gradient method BiCGSTAB with a specified maximum number of iterations and tolerance. Returns the number of iterations if successful or the error if the method fails

Examples found in repository?
examples/sparse_linear_system.rs (line 39)
9fn main() {
10    println!( "------------------ Sparse linear system ------------------" );
11    println!( "  * Solving the linear system Ax = b, for x, where" );
12    let n: usize = 4;
13    let mut a = Mat64::new( n, n, 0.0 );
14    let mut triplets = Vec::new();
15    for i in 0..n {
16        a[(i,i)] = 2.0;
17        triplets.push( ( i, i, 2.0 ) );
18        if i > 0 {
19            a[( i - 1 , i )] = 1.0;
20            triplets.push( ( i - 1, i, 1.0 ) );
21        }
22        if i < n - 1 {
23            a[( i + 1 , i )] = 1.0;
24            triplets.push( ( i + 1, i, 1.0 ) );
25        }
26    }
27    println!( "  * A ={}", a );
28    let b = Vec64::random( n );
29    println!( "  * b^T ={}", b );
30    println!( "  * as both dense and sparse linear systems.");
31    let dense_x = a.solve_basic( &b );
32    println!( "  * The dense system gives the solution vector");
33    println!( "  * x^T ={}", dense_x );
34    let sparse = Sparse::<f64>::from_triplets( n, n, &mut triplets );
35    //let sparse_x = sparse.solve( b ).unwrap();
36    let mut sparse_x = Vector::<f64>::new( n, 0.0 );
37    let max_iter = 1000;
38    let tol = 1e-8;
39    let result = sparse.solve_bicgstab( &b, &mut sparse_x, max_iter, tol );
40    println!( "  * The sparse system gives the solution vector");
41    println!( "  * x^T ={}", sparse_x );
42    match result {
43        Ok( iter ) => println!( "  * The sparse system converged in {} iterations.", iter ),
44        Err( error ) => println!( "  * The sparse system failed to converge, error = {}", error )
45    }
46    let diff = dense_x - sparse_x;
47    println!( "  * The maximum difference between the two is {:+.2e}", diff.norm_inf() );
48    println!( "-------------------- FINISHED ---------------------" );
49}
Source

pub fn solve_cg( &self, b: &Vector<f64>, x: &mut Vector<f64>, max_iter: usize, tol: f64, ) -> Result<usize, f64>

Solve the system of equations Ax=b using the conjugate gradient method with a specified maximum number of iterations and tolerance. Returns the number of iterations if successful or the error if the method fails

Source

pub fn solve_qmr( &self, b: &Vector<f64>, x: &mut Vector<f64>, max_iter: usize, tol: f64, ) -> Result<usize, f64>

Solve the system of equations Ax=b using the Quasi-minimal residual method with a specified maximum number of iterations and tolerance. Returns the number of iterations if successful or the error if the method fails

Examples found in repository?
examples/sparse_laplace.rs (line 86)
11fn main() {
12    println!( "------------------ Laplace's equation ------------------" );
13    println!( "  * Solve Laplace's equation on the unit square subject");
14    println!( "  * to the given boundary conditions. The exact solution");
15    println!( "  * is u(x,y) = y/[(1+x)^2 + y^2].");
16    let start = Instant::now();
17    let n: usize = 64;                          // Number of intervals
18    let dx: f64 = 1.0 / ( n as f64 );           // Step size
19    let size: usize = ( n + 1 ) * ( n + 1 );    // Size of the linear system
20    let mut rhs = Vec64::zeros( size );         // Right hand side vector 
21
22    let mut triplets = Vec::new();
23    let mut row: usize = 0;
24    
25    // x = 0 boundary ( u = y / ( 1 + y^2 ) )
26    let i = 0;
27    for j in 0..n+1 {
28        let y = (j as f64) * dx;
29        triplets.push( ( row, i * ( n + 1 ) + j, 1.0 ) );
30        rhs[ row ] = y / ( 1.0 + y * y );
31        row += 1;
32    }
33
34    for i in 1..n {
35        let x = (i as f64) * dx;
36        // y = 0 boundary ( u = 0 )
37        let j = 0;
38        triplets.push( ( row, i * ( n + 1 ) + j, 1.0 ) );
39        rhs[ row ] = 0.0;
40        row += 1;
41        // Interior nodes
42        for j in 1..n {
43            triplets.push( ( row, ( i - 1 ) * ( n + 1 ) + j, 1.0 ) );
44            triplets.push( ( row, ( i + 1 ) * ( n + 1 ) + j, 1.0 ) );
45            triplets.push( ( row, i * ( n + 1 ) + j - 1, 1.0 ) );
46            triplets.push( ( row, i * ( n + 1 ) + j + 1, 1.0 ) );
47            triplets.push( ( row, i * ( n + 1 ) + j, - 4.0 ) );
48            rhs[ row ] = 0.0;
49            row += 1;
50        }
51        // y = 1 boundary ( u = 1 / ( ( 1 + x )^2 + 1 ) )
52        let j = n;
53        triplets.push( ( row, i * ( n + 1 ) + j, 1.0 ) );
54        rhs[ row ] = 1. / ( ( 1. + x ) * ( 1. + x ) + 1. );
55        row += 1;
56    }
57
58    // x = 1 boundary ( u = y / ( 4 + y^2 ) )
59    let i = n;
60    for j in 0..n+1 {
61        let y = (j as f64) * dx;
62        triplets.push( ( row, i * ( n + 1 ) + j, 1.0 ) );
63        rhs[ row ] = y / ( 4. + y * y );
64        row += 1;
65    }
66
67    // Exact solution u = y / ( ( 1 + x )^2 + y^2 )
68    let mut u_exact = Vec64::zeros( size );    
69    row = 0;
70    for i in 0..n+1 {
71        let x = (i as f64) * dx;
72        for j in 0..n+1 {
73            let y = (j as f64) * dx;
74            u_exact[ row ] = y / ( ( 1. + x ) * ( 1. + x ) + y * y );
75            row += 1;
76        }
77    }
78    // Create the sparse matrix from the triplets
79    let sparse = Sparse::<f64>::from_triplets( size, size, &mut triplets );
80    let duration = start.elapsed();
81    println!("  * Time to create the matrix: {:?}", duration);
82    // Solve the sparse system
83    let mut u_guess = Vector::<f64>::random( size ); // A better guess would improve convergence
84    let max_iter = 1000;
85    let tol = 1e-8;
86    let result = sparse.solve_qmr( &rhs, &mut u_guess, max_iter, tol );
87    // Output time and error
88    let duration = start.elapsed();
89    match result {
90        Ok( iter ) => println!( "  * The sparse system converged in {} iterations.", iter ),
91        Err( error ) => println!( "  * The sparse system failed to converge, error = {}", error )
92    }
93    println!("  * Time to solve the system: {:?}", duration);
94    let u_diff = u_guess - u_exact;
95    println!("  * Solution error = {}", u_diff.norm_2() );
96    println!( "-------------------- FINISHED ---------------------" );
97}

Auto Trait Implementations§

§

impl<T> Freeze for Sparse<T>

§

impl<T> RefUnwindSafe for Sparse<T>
where T: RefUnwindSafe,

§

impl<T> Send for Sparse<T>
where T: Send,

§

impl<T> Sync for Sparse<T>
where T: Sync,

§

impl<T> Unpin for Sparse<T>
where T: Unpin,

§

impl<T> UnwindSafe for Sparse<T>
where T: UnwindSafe,

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V