Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cholesky decomposition rewrite: initial work #150

Merged
merged 25 commits into from
Mar 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e1a1a0e
Add minimal internal_utils module
Andlon Feb 11, 2017
5f04dcb
Basic implementation of Cholesky
Andlon Feb 11, 2017
754de35
Rewrite lu unpack to use nullify from internal_utils
Andlon Feb 11, 2017
f3807c7
Add Cholesky benchmarks
Andlon Feb 11, 2017
38b08a3
Take raw_slice_mut() in nullify
Andlon Feb 11, 2017
29163f4
Rewrite Cholesky in terms of dot()
Andlon Feb 11, 2017
4520bd5
Cholesky: validate diagonal entries
Andlon Feb 13, 2017
91b0751
Implement det() for Cholesky
Andlon Feb 13, 2017
038f129
Implement transpose_back_substitution
Andlon Feb 14, 2017
d243313
Implement Cholesky::solve
Andlon Feb 14, 2017
8b398a1
Add benchmarks for Cholesky::solve
Andlon Feb 14, 2017
5b47cd5
Rewrite transpose_back_sub.. for better data access pattern
Andlon Feb 20, 2017
5c8a566
Enable previously disabled test
Andlon Feb 20, 2017
2c45b7b
Implement Cholesky::inverse()
Andlon Feb 20, 2017
5de2e50
Documentation for Cholesky
Andlon Feb 20, 2017
a4eb96c
Fix errors in Cholesky doctests
Andlon Feb 20, 2017
9e28cdd
Remove stray ///
Andlon Feb 25, 2017
c222bb1
Remove confusing comment
Andlon Feb 25, 2017
f387056
Add Cholesky to decomposition module overview
Andlon Feb 25, 2017
5af62fa
Deprecate .cholesky()
Andlon Feb 25, 2017
04c2d77
Add warning to Cholesky::decompose
Andlon Feb 25, 2017
1916c71
Rewrite Cholesky solve/inverse to return Result
Andlon Mar 23, 2017
8edae5b
Merge branch 'master' into cholesky
Andlon Mar 24, 2017
8dc150b
Explain determinant of empty matrix to Cholesky/PartialPivLu
Andlon Mar 24, 2017
9ec0d1c
Reorder Cholesky and FullPivLu in decomposition docs
Andlon Mar 24, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod linalg {
mod matrix;
mod svd;
mod lu;
mod cholesky;
mod norm;
mod triangular;
mod permutation;
Expand Down
69 changes: 69 additions & 0 deletions benches/linalg/cholesky.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use rulinalg::matrix::Matrix;
use rulinalg::matrix::decomposition::{Cholesky, Decomposition};
use test::Bencher;

#[bench]
fn cholesky_decompose_unpack_100x100(b: &mut Bencher) {
let n = 100;
let x = Matrix::<f64>::identity(n);
b.iter(|| {
// Assume that the cost of cloning x is roughly
// negligible in comparison with the cost of LU
Cholesky::decompose(x.clone()).expect("Matrix is invertible")
.unpack()
})
}

#[bench]
fn cholesky_decompose_unpack_500x500(b: &mut Bencher) {
let n = 500;
let x = Matrix::<f64>::identity(n);
b.iter(|| {
// Assume that the cost of cloning x is roughly
// negligible in comparison with the cost of LU
Cholesky::decompose(x.clone()).expect("Matrix is invertible")
.unpack()
})
}

#[bench]
fn cholesky_100x100(b: &mut Bencher) {
// Benchmark for legacy cholesky(). Remove when
// cholesky() has been removed.
let n = 100;
let x = Matrix::<f64>::identity(n);
b.iter(|| {
x.cholesky().expect("Matrix is invertible")
})
}

#[bench]
fn cholesky_500x500(b: &mut Bencher) {
// Benchmark for legacy cholesky(). Remove when
// cholesky() has been removed.
let n = 500;
let x = Matrix::<f64>::identity(n);
b.iter(|| {
x.cholesky().expect("Matrix is invertible")
})
}

#[bench]
fn cholesky_solve_1000x1000(b: &mut Bencher) {
let n = 1000;
let x = Matrix::identity(n);
let cholesky = Cholesky::decompose(x).unwrap();
b.iter(|| {
cholesky.solve(vector![0.0; n])
});
}

#[bench]
fn cholesky_solve_100x100(b: &mut Bencher) {
let n = 100;
let x = Matrix::identity(n);
let cholesky = Cholesky::decompose(x).unwrap();
b.iter(|| {
cholesky.solve(vector![0.0; n])
});
}
52 changes: 52 additions & 0 deletions src/internal_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use matrix::BaseMatrixMut;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this module would be better placed in the matrix folder, so that it is src/matrix/utils.rs?

use libnum::Zero;

pub fn nullify_lower_triangular_part<T, M>(matrix: &mut M)
where T: Zero, M: BaseMatrixMut<T> {
for (i, mut row) in matrix.row_iter_mut().enumerate() {
for element in row.raw_slice_mut().iter_mut().take(i) {
*element = T::zero();
}
}
}

pub fn nullify_upper_triangular_part<T, M>(matrix: &mut M)
where T: Zero, M: BaseMatrixMut<T> {
for (i, mut row) in matrix.row_iter_mut().enumerate() {
for element in row.raw_slice_mut().iter_mut().skip(i + 1) {
*element = T::zero();
}
}
}

#[cfg(test)]
mod tests {
use super::nullify_lower_triangular_part;
use super::nullify_upper_triangular_part;

#[test]
fn nullify_lower_triangular_part_examples() {
let mut x = matrix![1.0, 2.0, 3.0;
4.0, 5.0, 6.0;
7.0, 8.0, 9.0];
nullify_lower_triangular_part(&mut x);
assert_matrix_eq!(x, matrix![
1.0, 2.0, 3.0;
0.0, 5.0, 6.0;
0.0, 0.0, 9.0
]);
}

#[test]
fn nullify_upper_triangular_part_examples() {
let mut x = matrix![1.0, 2.0, 3.0;
4.0, 5.0, 6.0;
7.0, 8.0, 9.0];
nullify_upper_triangular_part(&mut x);
assert_matrix_eq!(x, matrix![
1.0, 0.0, 0.0;
4.0, 5.0, 0.0;
7.0, 8.0, 9.0
]);
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ pub mod vector;
pub mod ulp;
pub mod norm;

mod internal_utils;

#[cfg(test)]
mod testsupport;

Expand Down
Loading