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" ]
|
||||
alloc = [ ]
|
||||
io = [ "pest", "pest_derive" ]
|
||||
compare = [ "matrixcompare-core" ]
|
||||
|
||||
[dependencies]
|
||||
typenum = "1.11"
|
||||
|
@ -50,6 +51,7 @@ mint = { version = "0.5", optional = true }
|
|||
quickcheck = { version = "0.9", optional = true }
|
||||
pest = { version = "2.0", optional = true }
|
||||
pest_derive = { version = "2.0", optional = true }
|
||||
matrixcompare-core = { version = "0.1", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1.0"
|
||||
|
@ -61,6 +63,9 @@ rand_isaac = "0.2"
|
|||
### https://github.com/rust-lang/cargo/issues/4866
|
||||
#criterion = "0.2.10"
|
||||
|
||||
# For matrix comparison macro
|
||||
matrixcompare = "0.1.3"
|
||||
|
||||
[workspace]
|
||||
members = [ "nalgebra-lapack", "nalgebra-glm" ]
|
||||
|
||||
|
|
4
Makefile
4
Makefile
|
@ -1,5 +1,5 @@
|
|||
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"
|
||||
|
||||
doc:
|
||||
|
@ -9,4 +9,4 @@ bench:
|
|||
cargo bench
|
||||
|
||||
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> {
|
||||
/// Creates a new matrix with the given data without statically checking that the matrix
|
||||
/// 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 serde;
|
||||
|
||||
#[cfg(feature = "compare")]
|
||||
mod matrixcompare;
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
pub mod helper;
|
||||
|
|
Loading…
Reference in New Issue