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>
impl<T: Copy + Number + Debug> Sparse<T>
Sourcepub fn from_vecs(
rows: usize,
cols: usize,
val: Vec<T>,
row_index: Vec<usize>,
col_start: Vec<usize>,
) -> Self
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
Sourcepub fn from_triplets(
rows: usize,
cols: usize,
triplets: &mut Vec<(usize, usize, T)>,
) -> Self
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?
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
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}Sourcepub fn col_index(&self) -> Vector<usize>
pub fn col_index(&self) -> Vector<usize>
Return a vector of column indices relating to each value ( triplet form )
Sourcepub fn get(&self, row: usize, col: usize) -> Option<T>
pub fn get(&self, row: usize, col: usize) -> Option<T>
Get a specific element from the sparse matrix if it exists
Sourcepub fn col_start_from_index(&self, col_index: &Vector<usize>) -> Vec<usize>
pub fn col_start_from_index(&self, col_index: &Vector<usize>) -> Vec<usize>
Calculate column start vector for a given column index vector
Sourcepub fn scale(&mut self, value: &T)
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
Sourcepub fn multiply(&self, x: &Vector<T>) -> Vector<T>
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
Sourcepub fn transpose_multiply(&self, x: &Vector<T>) -> Vector<T>
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
Sourcepub fn to_triplets(&self) -> Vec<(usize, usize, T)>
pub fn to_triplets(&self) -> Vec<(usize, usize, T)>
Return a vector of triplets representing the sparse matrix
Source§impl Sparse<f64>
impl Sparse<f64>
Sourcepub fn solve_bicg(
&self,
b: &Vector<f64>,
x: &mut Vector<f64>,
max_iter: usize,
tol: f64,
itol: usize,
) -> Result<usize, f64>
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
Sourcepub fn solve_bicgstab(
&self,
b: &Vector<f64>,
x: &mut Vector<f64>,
max_iter: usize,
tol: f64,
) -> Result<usize, f64>
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?
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}Sourcepub fn solve_cg(
&self,
b: &Vector<f64>,
x: &mut Vector<f64>,
max_iter: usize,
tol: f64,
) -> Result<usize, f64>
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
Sourcepub fn solve_qmr(
&self,
b: &Vector<f64>,
x: &mut Vector<f64>,
max_iter: usize,
tol: f64,
) -> Result<usize, f64>
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?
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}