Merge pull request #631 from Andlon/matrixcompare
Basic matrixcompare functionality
This commit is contained in:
commit
2ab82befe4
|
@ -30,6 +30,7 @@ sparse = [ ]
|
||||||
debug = [ "approx/num-complex", "rand/std" ]
|
debug = [ "approx/num-complex", "rand/std" ]
|
||||||
alloc = [ ]
|
alloc = [ ]
|
||||||
io = [ "pest", "pest_derive" ]
|
io = [ "pest", "pest_derive" ]
|
||||||
|
compare = [ "matrixcompare-core" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
typenum = "1.11"
|
typenum = "1.11"
|
||||||
|
@ -50,6 +51,7 @@ mint = { version = "0.5", optional = true }
|
||||||
quickcheck = { version = "0.9", optional = true }
|
quickcheck = { version = "0.9", optional = true }
|
||||||
pest = { version = "2.0", optional = true }
|
pest = { version = "2.0", optional = true }
|
||||||
pest_derive = { version = "2.0", optional = true }
|
pest_derive = { version = "2.0", optional = true }
|
||||||
|
matrixcompare-core = { version = "0.1", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
@ -61,6 +63,9 @@ rand_isaac = "0.2"
|
||||||
### https://github.com/rust-lang/cargo/issues/4866
|
### https://github.com/rust-lang/cargo/issues/4866
|
||||||
#criterion = "0.2.10"
|
#criterion = "0.2.10"
|
||||||
|
|
||||||
|
# For matrix comparison macro
|
||||||
|
matrixcompare = "0.1.3"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [ "nalgebra-lapack", "nalgebra-glm" ]
|
members = [ "nalgebra-lapack", "nalgebra-glm" ]
|
||||||
|
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -1,5 +1,5 @@
|
||||||
all:
|
all:
|
||||||
cargo test --features "debug arbitrary serde-serialize abomonation-serialize"
|
cargo test --features "debug arbitrary serde-serialize abomonation-serialize compare"
|
||||||
# cargo check --features "debug arbitrary serde-serialize"
|
# cargo check --features "debug arbitrary serde-serialize"
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
|
@ -9,4 +9,4 @@ bench:
|
||||||
cargo bench
|
cargo bench
|
||||||
|
|
||||||
test:
|
test:
|
||||||
cargo test --features "debug arbitrary serde-serialize abomonation-serialize"
|
cargo test --features "debug arbitrary serde-serialize abomonation-serialize compare"
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
|
use matrixcompare::comparators::{AbsoluteElementwiseComparator, ExactElementwiseComparator};
|
||||||
|
use matrixcompare::compare_matrices;
|
||||||
|
use na::{MatrixMN, U3, U4};
|
||||||
|
|
||||||
|
fn compare_integers_fail() {
|
||||||
|
println!("Comparing two integer matrices.");
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let a = MatrixMN::<_, U3, U4>::from_row_slice(&[
|
||||||
|
0, 1, 2, 3,
|
||||||
|
4, 5, 6, 7,
|
||||||
|
8, 9, -2, 11
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let b = MatrixMN::<_, U3, U4>::from_row_slice(&[
|
||||||
|
0, 1, 2, 3,
|
||||||
|
4, 5, 6, 7,
|
||||||
|
8, 9, 10, 11
|
||||||
|
]);
|
||||||
|
|
||||||
|
if let Err(err) = compare_matrices(a, b, &ExactElementwiseComparator) {
|
||||||
|
println!("{}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compare_different_size() {
|
||||||
|
println!("Comparing matrices of different size.");
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let a = MatrixMN::<_, U3, U3>::from_row_slice(&[
|
||||||
|
0, 1, 2,
|
||||||
|
4, 5, 6,
|
||||||
|
8, 9, 10,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let b = MatrixMN::<_, U3, U4>::from_row_slice(&[
|
||||||
|
0, 1, 2, 3,
|
||||||
|
4, 5, 6, 7,
|
||||||
|
8, 9, 10, 11
|
||||||
|
]);
|
||||||
|
|
||||||
|
if let Err(err) = compare_matrices(a, b, &ExactElementwiseComparator) {
|
||||||
|
println!("{}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compare_f64_abs_tol_fail() {
|
||||||
|
println!("Comparing two f64 matrices.");
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let a = MatrixMN::<f64, U3, U3>::from_row_slice(&[
|
||||||
|
0.0, 1.0, 2.0 + 1e-10,
|
||||||
|
4.0, 5.0, 6.0,
|
||||||
|
8.0, 9.0, 10.0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let b = MatrixMN::<_, U3, U3>::from_row_slice(&[
|
||||||
|
0.0, 1.0, 2.0,
|
||||||
|
4.0, 5.0, 6.0,
|
||||||
|
8.0, 9.0, 10.0
|
||||||
|
]);
|
||||||
|
|
||||||
|
let cmp = AbsoluteElementwiseComparator { tol: 1e-12 };
|
||||||
|
if let Err(err) = compare_matrices(a, b, &cmp) {
|
||||||
|
println!("{}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// This example mostly serves the purpose of demonstrating the kind of error messages
|
||||||
|
// that are given upon comparison failure.
|
||||||
|
// The more typical use case is using `assert_matrix_eq!` in tests.
|
||||||
|
compare_integers_fail();
|
||||||
|
println!("======================================================");
|
||||||
|
compare_f64_abs_tol_fail();
|
||||||
|
println!("======================================================");
|
||||||
|
compare_different_size();
|
||||||
|
}
|
|
@ -159,6 +159,32 @@ impl<N: Scalar, R: Dim, C: Dim, S: Abomonation> Abomonation for Matrix<N, R, C,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
|
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> matrixcompare_core::Matrix<N>
|
||||||
|
for Matrix<N, R, C, S>
|
||||||
|
{
|
||||||
|
fn rows(&self) -> usize {
|
||||||
|
self.nrows()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cols(&self) -> usize {
|
||||||
|
self.ncols()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn access(&self) -> matrixcompare_core::Access<N> {
|
||||||
|
matrixcompare_core::Access::Dense(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
|
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> matrixcompare_core::DenseAccess<N>
|
||||||
|
for Matrix<N, R, C, S>
|
||||||
|
{
|
||||||
|
fn fetch_single(&self, row: usize, col: usize) -> N {
|
||||||
|
self.index((row, col)).clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Scalar, R: Dim, C: Dim, S> Matrix<N, R, C, S> {
|
impl<N: Scalar, R: Dim, C: Dim, S> Matrix<N, R, C, S> {
|
||||||
/// Creates a new matrix with the given data without statically checking that the matrix
|
/// Creates a new matrix with the given data without statically checking that the matrix
|
||||||
/// dimension matches the storage dimension.
|
/// dimension matches the storage dimension.
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
//! Tests for `matrixcompare` integration.
|
||||||
|
//!
|
||||||
|
//! The `matrixcompare` crate itself is responsible for testing the actual comparison.
|
||||||
|
//! The tests here only check that the necessary trait implementations are correctly implemented,
|
||||||
|
//! in addition to some sanity checks with example input.
|
||||||
|
|
||||||
|
use nalgebra::{DMatrix, MatrixMN, U4, U5};
|
||||||
|
|
||||||
|
use matrixcompare::{assert_matrix_eq, DenseAccess};
|
||||||
|
|
||||||
|
#[cfg(feature = "arbitrary")]
|
||||||
|
quickcheck! {
|
||||||
|
fn fetch_single_is_equivalent_to_index_f64(matrix: DMatrix<f64>) -> bool {
|
||||||
|
for i in 0 .. matrix.nrows() {
|
||||||
|
for j in 0 .. matrix.ncols() {
|
||||||
|
if matrix.fetch_single(i, j) != *matrix.index((i, j)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matrixcompare_shape_agrees_with_matrix(matrix: DMatrix<f64>) -> bool {
|
||||||
|
matrix.nrows() == <DMatrix<f64> as matrixcompare::Matrix<f64>>::rows(&matrix)
|
||||||
|
&&
|
||||||
|
matrix.ncols() == <DMatrix<f64> as matrixcompare::Matrix<f64>>::cols(&matrix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assert_matrix_eq_dense_positive_comparison() {
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let a = MatrixMN::<_, U4, U5>::from_row_slice(&[
|
||||||
|
1210, 1320, 1430, 1540, 1650,
|
||||||
|
2310, 2420, 2530, 2640, 2750,
|
||||||
|
3410, 3520, 3630, 3740, 3850,
|
||||||
|
4510, 4620, 4730, 4840, 4950,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let b = MatrixMN::<_, U4, U5>::from_row_slice(&[
|
||||||
|
1210, 1320, 1430, 1540, 1650,
|
||||||
|
2310, 2420, 2530, 2640, 2750,
|
||||||
|
3410, 3520, 3630, 3740, 3850,
|
||||||
|
4510, 4620, 4730, 4840, 4950,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Test matrices of static size
|
||||||
|
assert_matrix_eq!(a, b);
|
||||||
|
assert_matrix_eq!(&a, b);
|
||||||
|
assert_matrix_eq!(a, &b);
|
||||||
|
assert_matrix_eq!(&a, &b);
|
||||||
|
|
||||||
|
// Test matrices of dynamic size
|
||||||
|
let a_dyn = a.index((0..4, 0..5));
|
||||||
|
let b_dyn = b.index((0..4, 0..5));
|
||||||
|
assert_matrix_eq!(a_dyn, b_dyn);
|
||||||
|
assert_matrix_eq!(a_dyn, &b_dyn);
|
||||||
|
assert_matrix_eq!(&a_dyn, b_dyn);
|
||||||
|
assert_matrix_eq!(&a_dyn, &b_dyn);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn assert_matrix_eq_dense_negative_comparison() {
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let a = MatrixMN::<_, U4, U5>::from_row_slice(&[
|
||||||
|
1210, 1320, 1430, 1540, 1650,
|
||||||
|
2310, 2420, 2530, 2640, 2750,
|
||||||
|
3410, 3520, 3630, 3740, 3850,
|
||||||
|
4510, 4620, -4730, 4840, 4950,
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let b = MatrixMN::<_, U4, U5>::from_row_slice(&[
|
||||||
|
1210, 1320, 1430, 1540, 1650,
|
||||||
|
2310, 2420, 2530, 2640, 2750,
|
||||||
|
3410, 3520, 3630, 3740, 3850,
|
||||||
|
4510, 4620, 4730, 4840, 4950,
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_matrix_eq!(a, b);
|
||||||
|
}
|
|
@ -11,5 +11,8 @@ mod matrix_slice;
|
||||||
mod mint;
|
mod mint;
|
||||||
mod serde;
|
mod serde;
|
||||||
|
|
||||||
|
#[cfg(feature = "compare")]
|
||||||
|
mod matrixcompare;
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
pub mod helper;
|
pub mod helper;
|
||||||
|
|
Loading…
Reference in New Issue