Struct russell_lab::Matrix [−][src]
pub struct Matrix { /* fields omitted */ }Expand description
Holds matrix components and associated functions
Remarks
- Matrix implements the Index traits (mutable or not), thus, we can access components by indices
- Matrix has also methods to access the underlying data (mutable or not);
e.g., using
as_data()andas_mut_data(). - Internally, the data is stored in the row-major order
- For faster computations, we recommend using the set of functions that
operate on Vectors and Matrices; e.g.,
add_matrices,cholesky_factor,eigen_decomp,inverse,pseudo_inverse,sv_decomp,mat_vec_mul,sv_decomp, and others.
Example
// import
use russell_lab::{Matrix, inverse, mat_mat_mul};
// create new matrix filled with ones
let mut a = Matrix::filled(2, 2, 1.0);
// change off-diagonal component
a[0][1] *= -1.0;
// check
assert_eq!(
format!("{}", a),
"┌ ┐\n\
│ 1 -1 │\n\
│ 1 1 │\n\
└ ┘"
);
// compute the inverse matrix `ai`
let (m, n) = a.dims();
let mut ai = Matrix::new(m, n);
let det = inverse(&mut ai, &a)?;
// check the determinant
assert_eq!(det, 2.0);
// check the inverse matrix
assert_eq!(
format!("{}", ai),
"┌ ┐\n\
│ 0.5 0.5 │\n\
│ -0.5 0.5 │\n\
└ ┘"
);
// multiply the matrix by its inverse
let mut aia = Matrix::new(m, n);
mat_mat_mul(&mut aia, 1.0, &ai, &a)?;
// check the results
assert_eq!(
format!("{}", aia),
"┌ ┐\n\
│ 1 0 │\n\
│ 0 1 │\n\
└ ┘"
);
// create an identity matrix and check again
let ii = Matrix::identity(m);
assert_eq!(aia.as_data(), ii.as_data());Implementations
Creates new (nrow x ncol) Matrix filled with zeros
Example
use russell_lab::Matrix;
let a = Matrix::new(3, 3);
let correct = "┌ ┐\n\
│ 0 0 0 │\n\
│ 0 0 0 │\n\
│ 0 0 0 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);Creates new identity (square) matrix
Example
use russell_lab::Matrix;
let identity = Matrix::identity(3);
let correct = "┌ ┐\n\
│ 1 0 0 │\n\
│ 0 1 0 │\n\
│ 0 0 1 │\n\
└ ┘";
assert_eq!(format!("{}", identity), correct);Creates new matrix completely filled with the same value
Example
use russell_lab::Matrix;
let a = Matrix::filled(2, 3, 4.0);
let correct = "┌ ┐\n\
│ 4 4 4 │\n\
│ 4 4 4 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);Creates new matrix from given data
Notes
- For variable-length rows, the number of columns is defined by the first row
- The next rows must have at least the same number of columns as the first row
Example
use russell_lab::Matrix;
// heap-allocated 2D array (vector of vectors)
const IGNORED: f64 = 123.456;
let a_data = vec![
vec![1.0, 2.0],
vec![3.0, 4.0, IGNORED, IGNORED, IGNORED],
vec![5.0, 6.0],
];
let a = Matrix::from(&a_data);
assert_eq!(
format!("{}", &a),
"┌ ┐\n\
│ 1 2 │\n\
│ 3 4 │\n\
│ 5 6 │\n\
└ ┘"
);
// heap-allocated 2D array (aka slice of slices)
let b_data: &[&[f64]] = &[
&[10.0, 20.0],
&[30.0, 40.0, IGNORED],
&[50.0, 60.0, IGNORED, IGNORED],
];
let b = Matrix::from(&b_data);
assert_eq!(
format!("{}", &b),
"┌ ┐\n\
│ 10 20 │\n\
│ 30 40 │\n\
│ 50 60 │\n\
└ ┘"
);
// stack-allocated (fixed-size) 2D array
let c_data = [
[100.0, 200.0],
[300.0, 400.0],
[500.0, 600.0],
];
let c = Matrix::from(&c_data);
assert_eq!(
format!("{}", &c),
"┌ ┐\n\
│ 100 200 │\n\
│ 300 400 │\n\
│ 500 600 │\n\
└ ┘"
);Creates new diagonal matrix with given diagonal data
Example
use russell_lab::Matrix;
let a = Matrix::diagonal(&[1.0, 2.0, 3.0]);
let correct = "┌ ┐\n\
│ 1 0 0 │\n\
│ 0 2 0 │\n\
│ 0 0 3 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);Returns the number of rows
Example
use russell_lab::Matrix;
let a = Matrix::new(4, 3);
assert_eq!(a.nrow(), 4);Returns the number of columns
Example
use russell_lab::Matrix;
let a = Matrix::new(4, 3);
assert_eq!(a.ncol(), 3);Returns the dimensions (nrow, ncol) of this matrix
Example
use russell_lab::Matrix;
let a = Matrix::new(4, 3);
assert_eq!(a.dims(), (4, 3));Scales this matrix
a := alpha * aExample
use russell_lab::Matrix;
let mut a = Matrix::from(&[
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
]);
a.scale(0.5);
let correct = "┌ ┐\n\
│ 0.5 1 1.5 │\n\
│ 2 2.5 3 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);Fills this matrix with a given value
u[i][j] := valueExample
use russell_lab::Matrix;
let mut a = Matrix::new(2, 2);
a.fill(8.8);
let correct = "┌ ┐\n\
│ 8.8 8.8 │\n\
│ 8.8 8.8 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);Returns an access to the underlying data
Note
- Internally, the data is stored in the row-major order
Example
use russell_lab::Matrix;
let a = Matrix::from(&[[1.0, 2.0], [3.0, 4.0]]);
assert_eq!(a.as_data(), &[1.0, 2.0, 3.0, 4.0]);Returns a mutable access to the underlying data
Note
- Internally, the data is stored in the row-major order
Example
use russell_lab::Matrix;
let mut a = Matrix::from(&[[1.0, 2.0], [3.0, 4.0]]);
let data = a.as_mut_data();
data[1] = 2.2;
assert_eq!(data, &[1.0, 2.2, 3.0, 4.0]);Returns the (i,j) component
Example
use russell_lab::Matrix;
let a = Matrix::from(&[
[1.0, 2.0],
[3.0, 4.0],
]);
assert_eq!(a.get(1,1), 4.0);Change the (i,j) component
Example
use russell_lab::Matrix;
let mut a = Matrix::from(&[
[1.0, 2.0],
[3.0, 4.0],
]);
a.set(1, 1, -4.0);
let correct = "┌ ┐\n\
│ 1 2 │\n\
│ 3 -4 │\n\
└ ┘";
assert_eq!(format!("{}", a), correct);Returns a copy of this matrix
use russell_lab::Matrix;
let mut a = Matrix::from(&[
[1.0, 2.0],
[3.0, 4.0],
]);
let a_copy = a.get_copy();
a.set(0, 0, 5.0);
let a_correct = "┌ ┐\n\
│ 5 2 │\n\
│ 3 4 │\n\
└ ┘";
let a_copy_correct = "┌ ┐\n\
│ 1 2 │\n\
│ 3 4 │\n\
└ ┘";
assert_eq!(format!("{}", a), a_correct);
assert_eq!(format!("{}", a_copy), a_copy_correct);Returns the matrix norm
Computes one of:
One: 1-norm
‖a‖_1 = max_j ( Σ_i |aᵢⱼ| )
Inf: inf-norm
‖a‖_∞ = max_i ( Σ_j |aᵢⱼ| )
Fro: Frobenius-norm (2-norm)
‖a‖_F = sqrt(Σ_i Σ_j aᵢⱼ⋅aᵢⱼ) == ‖a‖_2
Max: max-norm
‖a‖_max = max_ij ( |aᵢⱼ| )Example
use russell_lab::{EnumMatrixNorm, Matrix};
let a = Matrix::from(&[
[-2.0, 2.0],
[ 1.0, -4.0],
]);
assert_eq!(a.norm(EnumMatrixNorm::One), 6.0);
assert_eq!(a.norm(EnumMatrixNorm::Inf), 5.0);
assert_eq!(a.norm(EnumMatrixNorm::Fro), 5.0);
assert_eq!(a.norm(EnumMatrixNorm::Max), 4.0);Trait Implementations
Allows to access Matrix components using indices
Example
use russell_lab::Matrix;
let a = Matrix::from(&[
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
]);
assert_eq!(a[0][0], 1.0);
assert_eq!(a[0][1], 2.0);
assert_eq!(a[0][2], 3.0);
assert_eq!(a[1][0], 4.0);
assert_eq!(a[1][1], 5.0);
assert_eq!(a[1][2], 6.0);Allows to change Matrix components using indices
Example
use russell_lab::Matrix;
let mut a = Matrix::from(&[
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
]);
a[0][0] -= 1.0;
a[0][1] += 1.0;
a[0][2] -= 1.0;
a[1][0] += 1.0;
a[1][1] -= 1.0;
a[1][2] += 1.0;
assert_eq!(a[0][0], 0.0);
assert_eq!(a[0][1], 3.0);
assert_eq!(a[0][2], 2.0);
assert_eq!(a[1][0], 5.0);
assert_eq!(a[1][1], 4.0);
assert_eq!(a[1][2], 7.0);