From 74f4b0ba4d65f732cfe7d5e4df8e22e2348365b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Crozet=20S=C3=A9bastien?= Date: Sun, 28 Feb 2021 18:39:18 +0100 Subject: [PATCH] nalgebra-lapack: run tests with proptest instead of quickcheck. --- nalgebra-lapack/Cargo.toml | 5 +- nalgebra-lapack/tests/lib.rs | 10 +- nalgebra-lapack/tests/linalg/cholesky.rs | 115 ++++++++--------- nalgebra-lapack/tests/linalg/hessenberg.rs | 44 +++---- nalgebra-lapack/tests/linalg/lu.rs | 118 ++++++++---------- nalgebra-lapack/tests/linalg/qr.rs | 16 ++- .../tests/linalg/real_eigensystem.rs | 58 ++++----- nalgebra-lapack/tests/linalg/schur.rs | 18 +-- nalgebra-lapack/tests/linalg/svd.rs | 54 ++++---- .../tests/linalg/symmetric_eigen.rs | 17 ++- tests/proptest/mod.rs | 5 +- 11 files changed, 224 insertions(+), 236 deletions(-) diff --git a/nalgebra-lapack/Cargo.toml b/nalgebra-lapack/Cargo.toml index cefc6662..16f4faa1 100644 --- a/nalgebra-lapack/Cargo.toml +++ b/nalgebra-lapack/Cargo.toml @@ -18,9 +18,11 @@ maintenance = { status = "actively-developed" } [features] serde-serialize = [ "serde", "serde_derive" ] +proptest-support = [ "nalgebra/proptest-support" ] +arbitrary = [ "nalgebra/arbitrary" ] # For BLAS/LAPACK -default = ["openblas"] +default = ["netlib"] openblas = ["lapack-src/openblas"] netlib = ["lapack-src/netlib"] accelerate = ["lapack-src/accelerate"] @@ -39,6 +41,7 @@ lapack-src = { version = "0.6", default-features = false } [dev-dependencies] nalgebra = { version = "0.24", features = [ "arbitrary" ], path = ".." } +proptest = { version = "1", default-features = false, features = ["std"] } quickcheck = "1" approx = "0.4" rand = "0.8" diff --git a/nalgebra-lapack/tests/lib.rs b/nalgebra-lapack/tests/lib.rs index 37e0b903..973b6d17 100644 --- a/nalgebra-lapack/tests/lib.rs +++ b/nalgebra-lapack/tests/lib.rs @@ -1,8 +1,14 @@ #[macro_use] extern crate approx; +#[cfg(not(feature = "proptest-support"))] +compile_error!("Tests must be run with `proptest-support`"); + extern crate nalgebra as na; extern crate nalgebra_lapack as nl; -#[macro_use] -extern crate quickcheck; + +extern crate lapack; +extern crate lapack_src; mod linalg; +#[path = "../../tests/proptest/mod.rs"] +mod proptest; diff --git a/nalgebra-lapack/tests/linalg/cholesky.rs b/nalgebra-lapack/tests/linalg/cholesky.rs index f811726a..632347b8 100644 --- a/nalgebra-lapack/tests/linalg/cholesky.rs +++ b/nalgebra-lapack/tests/linalg/cholesky.rs @@ -1,101 +1,90 @@ use std::cmp; -use na::{DMatrix, DVector, Matrix3, Matrix4, Matrix4x3, Vector4}; +use na::{DMatrix, DVector, Matrix4x3, Vector4}; use nl::Cholesky; -quickcheck! { - fn cholesky(m: DMatrix) -> bool { - if m.len() != 0 { - let m = &m * m.transpose(); - if let Some(chol) = Cholesky::new(m.clone()) { - let l = chol.unpack(); - let reconstructed_m = &l * l.transpose(); +use crate::proptest::*; +use proptest::{prop_assert, proptest}; - return relative_eq!(reconstructed_m, m, epsilon = 1.0e-7) - } +proptest! { + #[test] + fn cholesky(m in dmatrix()) { + let m = &m * m.transpose(); + if let Some(chol) = Cholesky::new(m.clone()) { + let l = chol.unpack(); + let reconstructed_m = &l * l.transpose(); + + prop_assert!(relative_eq!(reconstructed_m, m, epsilon = 1.0e-7)); } - return true } - fn cholesky_static(m: Matrix3) -> bool { + #[test] + fn cholesky_static(m in matrix3()) { let m = &m * m.transpose(); if let Some(chol) = Cholesky::new(m) { let l = chol.unpack(); let reconstructed_m = &l * l.transpose(); - relative_eq!(reconstructed_m, m, epsilon = 1.0e-7) - } - else { - false + prop_assert!(relative_eq!(reconstructed_m, m, epsilon = 1.0e-7)) } } - fn cholesky_solve(n: usize, nb: usize) -> bool { - if n != 0 { - let n = cmp::min(n, 15); // To avoid slowing down the test too much. - let nb = cmp::min(nb, 15); // To avoid slowing down the test too much. - let m = DMatrix::::new_random(n, n); - let m = &m * m.transpose(); + #[test] + fn cholesky_solve(n in PROPTEST_MATRIX_DIM, nb in PROPTEST_MATRIX_DIM) { + let n = cmp::min(n, 15); // To avoid slowing down the test too much. + let nb = cmp::min(nb, 15); // To avoid slowing down the test too much. + let m = DMatrix::::new_random(n, n); + let m = &m * m.transpose(); - if let Some(chol) = Cholesky::new(m.clone()) { - let b1 = DVector::new_random(n); - let b2 = DMatrix::new_random(n, nb); + if let Some(chol) = Cholesky::new(m.clone()) { + let b1 = DVector::new_random(n); + let b2 = DMatrix::new_random(n, nb); - let sol1 = chol.solve(&b1).unwrap(); - let sol2 = chol.solve(&b2).unwrap(); + let sol1 = chol.solve(&b1).unwrap(); + let sol2 = chol.solve(&b2).unwrap(); - return relative_eq!(&m * sol1, b1, epsilon = 1.0e-6) && - relative_eq!(&m * sol2, b2, epsilon = 1.0e-6) - } + prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-6)); + prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-6)); } - - return true; } - fn cholesky_solve_static(m: Matrix4) -> bool { + #[test] + fn cholesky_solve_static(m in matrix4()) { let m = &m * m.transpose(); - match Cholesky::new(m) { - Some(chol) => { - let b1 = Vector4::new_random(); - let b2 = Matrix4x3::new_random(); + if let Some(chol) = Cholesky::new(m) { + let b1 = Vector4::new_random(); + let b2 = Matrix4x3::new_random(); - let sol1 = chol.solve(&b1).unwrap(); - let sol2 = chol.solve(&b2).unwrap(); + let sol1 = chol.solve(&b1).unwrap(); + let sol2 = chol.solve(&b2).unwrap(); - relative_eq!(m * sol1, b1, epsilon = 1.0e-7) && - relative_eq!(m * sol2, b2, epsilon = 1.0e-7) - }, - None => true + prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-7)); } } - fn cholesky_inverse(n: usize) -> bool { - if n != 0 { - let n = cmp::min(n, 15); // To avoid slowing down the test too much. - let m = DMatrix::::new_random(n, n); - let m = &m * m.transpose(); + #[test] + fn cholesky_inverse(n in PROPTEST_MATRIX_DIM) { + let n = cmp::min(n, 15); // To avoid slowing down the test too much. + let m = DMatrix::::new_random(n, n); + let m = &m * m.transpose(); - if let Some(m1) = Cholesky::new(m.clone()).unwrap().inverse() { - let id1 = &m * &m1; - let id2 = &m1 * &m; + if let Some(m1) = Cholesky::new(m.clone()).unwrap().inverse() { + let id1 = &m * &m1; + let id2 = &m1 * &m; - return id1.is_identity(1.0e-6) && id2.is_identity(1.0e-6); - } + prop_assert!(id1.is_identity(1.0e-6) && id2.is_identity(1.0e-6)); } - - return true; } - fn cholesky_inverse_static(m: Matrix4) -> bool { + #[test] + fn cholesky_inverse_static(m in matrix4()) { let m = m * m.transpose(); - match Cholesky::new(m.clone()).unwrap().inverse() { - Some(m1) => { - let id1 = &m * &m1; - let id2 = &m1 * &m; + if let Some(m1) = Cholesky::new(m.clone()).unwrap().inverse() { + let id1 = &m * &m1; + let id2 = &m1 * &m; - id1.is_identity(1.0e-5) && id2.is_identity(1.0e-5) - }, - None => true + prop_assert!(id1.is_identity(1.0e-5) && id2.is_identity(1.0e-5)) } } } diff --git a/nalgebra-lapack/tests/linalg/hessenberg.rs b/nalgebra-lapack/tests/linalg/hessenberg.rs index bb48633e..5292ab17 100644 --- a/nalgebra-lapack/tests/linalg/hessenberg.rs +++ b/nalgebra-lapack/tests/linalg/hessenberg.rs @@ -1,38 +1,32 @@ use std::cmp; -use nl::Hessenberg; use na::{DMatrix, Matrix4}; +use nl::Hessenberg; -quickcheck!{ - fn hessenberg(n: usize) -> bool { - if n != 0 { - let n = cmp::min(n, 25); - let m = DMatrix::::new_random(n, n); +use crate::proptest::*; +use proptest::{prop_assert, proptest}; - match Hessenberg::new(m.clone()) { - Some(hess) => { - let h = hess.h(); - let p = hess.p(); +proptest! { + #[test] + fn hessenberg(n in PROPTEST_MATRIX_DIM) { + let n = cmp::min(n, 25); + let m = DMatrix::::new_random(n, n); - relative_eq!(m, &p * h * p.transpose(), epsilon = 1.0e-7) - }, - None => true - } - } - else { - true + if let Some(hess) = Hessenberg::new(m.clone()) { + let h = hess.h(); + let p = hess.p(); + + prop_assert!(relative_eq!(m, &p * h * p.transpose(), epsilon = 1.0e-7)) } } - fn hessenberg_static(m: Matrix4) -> bool { - match Hessenberg::new(m) { - Some(hess) => { - let h = hess.h(); - let p = hess.p(); + #[test] + fn hessenberg_static(m in matrix4()) { + if let Some(hess) = Hessenberg::new(m) { + let h = hess.h(); + let p = hess.p(); - relative_eq!(m, p * h * p.transpose(), epsilon = 1.0e-7) - }, - None => true + prop_assert!(relative_eq!(m, p * h * p.transpose(), epsilon = 1.0e-7)) } } } diff --git a/nalgebra-lapack/tests/linalg/lu.rs b/nalgebra-lapack/tests/linalg/lu.rs index 71293436..9665964e 100644 --- a/nalgebra-lapack/tests/linalg/lu.rs +++ b/nalgebra-lapack/tests/linalg/lu.rs @@ -1,28 +1,28 @@ use std::cmp; -use na::{DMatrix, DVector, Matrix3x4, Matrix4, Matrix4x3, Vector4}; +use na::{DMatrix, DVector, Matrix4x3, Vector4}; use nl::LU; -quickcheck! { - fn lup(m: DMatrix) -> bool { - if m.len() != 0 { - let lup = LU::new(m.clone()); - let l = lup.l(); - let u = lup.u(); - let mut computed1 = &l * &u; - lup.permute(&mut computed1); +use crate::proptest::*; +use proptest::{prop_assert, proptest}; - let computed2 = lup.p() * l * u; +proptest! { + #[test] + fn lup(m in dmatrix()) { + let lup = LU::new(m.clone()); + let l = lup.l(); + let u = lup.u(); + let mut computed1 = &l * &u; + lup.permute(&mut computed1); - relative_eq!(computed1, m, epsilon = 1.0e-7) && - relative_eq!(computed2, m, epsilon = 1.0e-7) - } - else { - true - } + let computed2 = lup.p() * l * u; + + prop_assert!(relative_eq!(computed1, m, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(computed2, m, epsilon = 1.0e-7)); } - fn lu_static(m: Matrix3x4) -> bool { + #[test] + fn lu_static(m in matrix3x5()) { let lup = LU::new(m); let l = lup.l(); let u = lup.u(); @@ -31,37 +31,34 @@ quickcheck! { let computed2 = lup.p() * l * u; - relative_eq!(computed1, m, epsilon = 1.0e-7) && - relative_eq!(computed2, m, epsilon = 1.0e-7) + prop_assert!(relative_eq!(computed1, m, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(computed2, m, epsilon = 1.0e-7)); } - fn lu_solve(n: usize, nb: usize) -> bool { - if n != 0 { - let n = cmp::min(n, 25); // To avoid slowing down the test too much. - let nb = cmp::min(nb, 25); // To avoid slowing down the test too much. - let m = DMatrix::::new_random(n, n); + #[test] + fn lu_solve(n in PROPTEST_MATRIX_DIM, nb in PROPTEST_MATRIX_DIM) { + let n = cmp::min(n, 25); // To avoid slowing down the test too much. + let nb = cmp::min(nb, 25); // To avoid slowing down the test too much. + let m = DMatrix::::new_random(n, n); - let lup = LU::new(m.clone()); - let b1 = DVector::new_random(n); - let b2 = DMatrix::new_random(n, nb); + let lup = LU::new(m.clone()); + let b1 = DVector::new_random(n); + let b2 = DMatrix::new_random(n, nb); - let sol1 = lup.solve(&b1).unwrap(); - let sol2 = lup.solve(&b2).unwrap(); + let sol1 = lup.solve(&b1).unwrap(); + let sol2 = lup.solve(&b2).unwrap(); - let tr_sol1 = lup.solve_transpose(&b1).unwrap(); - let tr_sol2 = lup.solve_transpose(&b2).unwrap(); + let tr_sol1 = lup.solve_transpose(&b1).unwrap(); + let tr_sol2 = lup.solve_transpose(&b2).unwrap(); - relative_eq!(&m * sol1, b1, epsilon = 1.0e-7) && - relative_eq!(&m * sol2, b2, epsilon = 1.0e-7) && - relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7) && - relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7) - } - else { - true - } + prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7)); } - fn lu_solve_static(m: Matrix4) -> bool { + #[test] + fn lu_solve_static(m in matrix4()) { let lup = LU::new(m); let b1 = Vector4::new_random(); let b2 = Matrix4x3::new_random(); @@ -71,37 +68,32 @@ quickcheck! { let tr_sol1 = lup.solve_transpose(&b1).unwrap(); let tr_sol2 = lup.solve_transpose(&b2).unwrap(); - relative_eq!(m * sol1, b1, epsilon = 1.0e-7) && - relative_eq!(m * sol2, b2, epsilon = 1.0e-7) && - relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7) && - relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7) + prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7)); } - fn lu_inverse(n: usize) -> bool { - if n != 0 { - let n = cmp::min(n, 25); // To avoid slowing down the test too much. - let m = DMatrix::::new_random(n, n); + #[test] + fn lu_inverse(n in PROPTEST_MATRIX_DIM) { + let n = cmp::min(n, 25); // To avoid slowing down the test too much. + let m = DMatrix::::new_random(n, n); - if let Some(m1) = LU::new(m.clone()).inverse() { - let id1 = &m * &m1; - let id2 = &m1 * &m; + if let Some(m1) = LU::new(m.clone()).inverse() { + let id1 = &m * &m1; + let id2 = &m1 * &m; - return id1.is_identity(1.0e-7) && id2.is_identity(1.0e-7); - } + prop_assert!(id1.is_identity(1.0e-7) && id2.is_identity(1.0e-7)); } - - return true; } - fn lu_inverse_static(m: Matrix4) -> bool { - match LU::new(m.clone()).inverse() { - Some(m1) => { - let id1 = &m * &m1; - let id2 = &m1 * &m; + #[test] + fn lu_inverse_static(m in matrix4()) { + if let Some(m1) = LU::new(m.clone()).inverse() { + let id1 = &m * &m1; + let id2 = &m1 * &m; - id1.is_identity(1.0e-5) && id2.is_identity(1.0e-5) - }, - None => true + prop_assert!(id1.is_identity(1.0e-5) && id2.is_identity(1.0e-5)) } } } diff --git a/nalgebra-lapack/tests/linalg/qr.rs b/nalgebra-lapack/tests/linalg/qr.rs index 1d193a86..138d38e9 100644 --- a/nalgebra-lapack/tests/linalg/qr.rs +++ b/nalgebra-lapack/tests/linalg/qr.rs @@ -1,20 +1,24 @@ -use na::{DMatrix, Matrix4x3}; use nl::QR; -quickcheck! { - fn qr(m: DMatrix) -> bool { +use crate::proptest::*; +use proptest::{prop_assert, proptest}; + +proptest! { + #[test] + fn qr(m in dmatrix()) { let qr = QR::new(m.clone()); let q = qr.q(); let r = qr.r(); - relative_eq!(m, q * r, epsilon = 1.0e-7) + prop_assert!(relative_eq!(m, q * r, epsilon = 1.0e-7)) } - fn qr_static(m: Matrix4x3) -> bool { + #[test] + fn qr_static(m in matrix5x3()) { let qr = QR::new(m); let q = qr.q(); let r = qr.r(); - relative_eq!(m, q * r, epsilon = 1.0e-7) + prop_assert!(relative_eq!(m, q * r, epsilon = 1.0e-7)) } } diff --git a/nalgebra-lapack/tests/linalg/real_eigensystem.rs b/nalgebra-lapack/tests/linalg/real_eigensystem.rs index a711d882..3d1c91eb 100644 --- a/nalgebra-lapack/tests/linalg/real_eigensystem.rs +++ b/nalgebra-lapack/tests/linalg/real_eigensystem.rs @@ -3,46 +3,40 @@ use std::cmp; use na::{DMatrix, Matrix4}; use nl::Eigen; -quickcheck! { - fn eigensystem(n: usize) -> bool { - if n != 0 { - let n = cmp::min(n, 25); - let m = DMatrix::::new_random(n, n); +use crate::proptest::*; +use proptest::{prop_assert, proptest}; - match Eigen::new(m.clone(), true, true) { - Some(eig) => { - let eigvals = DMatrix::from_diagonal(&eig.eigenvalues); - let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap(); - let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals; +proptest! { + #[test] + fn eigensystem(n in PROPTEST_MATRIX_DIM) { + let n = cmp::min(n, 25); + let m = DMatrix::::new_random(n, n); - let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap(); - let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals; + if let Some(eig) = Eigen::new(m.clone(), true, true) { + let eigvals = DMatrix::from_diagonal(&eig.eigenvalues); + let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap(); + let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals; - relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7) && - relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7) - }, - None => true - } - } - else { - true + let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap(); + let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals; + + prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7)); } } - fn eigensystem_static(m: Matrix4) -> bool { - match Eigen::new(m, true, true) { - Some(eig) => { - let eigvals = Matrix4::from_diagonal(&eig.eigenvalues); - let transformed_eigvectors = m * eig.eigenvectors.unwrap(); - let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals; + #[test] + fn eigensystem_static(m in matrix4()) { + if let Some(eig) = Eigen::new(m, true, true) { + let eigvals = Matrix4::from_diagonal(&eig.eigenvalues); + let transformed_eigvectors = m * eig.eigenvectors.unwrap(); + let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals; - let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap(); - let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals; + let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap(); + let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals; - relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7) && - relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7) - }, - None => true + prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7)); } } } diff --git a/nalgebra-lapack/tests/linalg/schur.rs b/nalgebra-lapack/tests/linalg/schur.rs index ccdb0f0b..0fd1cc33 100644 --- a/nalgebra-lapack/tests/linalg/schur.rs +++ b/nalgebra-lapack/tests/linalg/schur.rs @@ -1,20 +1,24 @@ -use na::{DMatrix, Matrix4}; +use na::DMatrix; use nl::Schur; use std::cmp; -quickcheck! { - fn schur(n: usize) -> bool { +use crate::proptest::*; +use proptest::{prop_assert, proptest}; + +proptest! { + #[test] + fn schur(n in PROPTEST_MATRIX_DIM) { let n = cmp::max(1, cmp::min(n, 10)); let m = DMatrix::::new_random(n, n); let (vecs, vals) = Schur::new(m.clone()).unpack(); - relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7) + prop_assert!(relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)) } - fn schur_static(m: Matrix4) -> bool { + #[test] + fn schur_static(m in matrix4()) { let (vecs, vals) = Schur::new(m.clone()).unpack(); - - relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7) + prop_assert!(relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)) } } diff --git a/nalgebra-lapack/tests/linalg/svd.rs b/nalgebra-lapack/tests/linalg/svd.rs index 20ebd9d5..a9389260 100644 --- a/nalgebra-lapack/tests/linalg/svd.rs +++ b/nalgebra-lapack/tests/linalg/svd.rs @@ -1,57 +1,53 @@ -use na::{DMatrix, Matrix3x4}; +use na::{DMatrix, Matrix3x5}; use nl::SVD; -quickcheck! { - fn svd(m: DMatrix) -> bool { - if m.nrows() != 0 && m.ncols() != 0 { - let svd = SVD::new(m.clone()).unwrap(); - let sm = DMatrix::from_partial_diagonal(m.nrows(), m.ncols(), svd.singular_values.as_slice()); +use crate::proptest::*; +use proptest::{prop_assert, proptest}; - let reconstructed_m = &svd.u * sm * &svd.vt; - let reconstructed_m2 = svd.recompose(); +proptest! { + #[test] + fn svd(m in dmatrix()) { + let svd = SVD::new(m.clone()).unwrap(); + let sm = DMatrix::from_partial_diagonal(m.nrows(), m.ncols(), svd.singular_values.as_slice()); - relative_eq!(reconstructed_m, m, epsilon = 1.0e-7) && - relative_eq!(reconstructed_m2, reconstructed_m, epsilon = 1.0e-7) - } - else { - true - } + let reconstructed_m = &svd.u * sm * &svd.vt; + let reconstructed_m2 = svd.recompose(); + + prop_assert!(relative_eq!(reconstructed_m, m, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(reconstructed_m2, reconstructed_m, epsilon = 1.0e-7)); } - fn svd_static(m: Matrix3x4) -> bool { + #[test] + fn svd_static(m in matrix3x5()) { let svd = SVD::new(m).unwrap(); - let sm = Matrix3x4::from_partial_diagonal(svd.singular_values.as_slice()); + let sm = Matrix3x5::from_partial_diagonal(svd.singular_values.as_slice()); let reconstructed_m = &svd.u * &sm * &svd.vt; let reconstructed_m2 = svd.recompose(); - relative_eq!(reconstructed_m, m, epsilon = 1.0e-7) && - relative_eq!(reconstructed_m2, m, epsilon = 1.0e-7) + prop_assert!(relative_eq!(reconstructed_m, m, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(reconstructed_m2, m, epsilon = 1.0e-7)); } - fn pseudo_inverse(m: DMatrix) -> bool { - if m.nrows() == 0 || m.ncols() == 0 { - return true; - } - + #[test] + fn pseudo_inverse(m in dmatrix()) { let svd = SVD::new(m.clone()).unwrap(); let im = svd.pseudo_inverse(1.0e-7); if m.nrows() <= m.ncols() { - return (&m * &im).is_identity(1.0e-7) + prop_assert!((&m * &im).is_identity(1.0e-7)); } if m.nrows() >= m.ncols() { - return (im * m).is_identity(1.0e-7) + prop_assert!((im * m).is_identity(1.0e-7)); } - - return true; } - fn pseudo_inverse_static(m: Matrix3x4) -> bool { + #[test] + fn pseudo_inverse_static(m in matrix3x5()) { let svd = SVD::new(m).unwrap(); let im = svd.pseudo_inverse(1.0e-7); - (m * im).is_identity(1.0e-7) + prop_assert!((m * im).is_identity(1.0e-7)) } } diff --git a/nalgebra-lapack/tests/linalg/symmetric_eigen.rs b/nalgebra-lapack/tests/linalg/symmetric_eigen.rs index 1d47f982..d57f772e 100644 --- a/nalgebra-lapack/tests/linalg/symmetric_eigen.rs +++ b/nalgebra-lapack/tests/linalg/symmetric_eigen.rs @@ -1,20 +1,25 @@ use std::cmp; -use na::{DMatrix, Matrix4}; +use na::DMatrix; use nl::SymmetricEigen; -quickcheck! { - fn symmetric_eigen(n: usize) -> bool { +use crate::proptest::*; +use proptest::{prop_assert, proptest}; + +proptest! { + #[test] + fn symmetric_eigen(n in PROPTEST_MATRIX_DIM) { let n = cmp::max(1, cmp::min(n, 10)); let m = DMatrix::::new_random(n, n); let eig = SymmetricEigen::new(m.clone()); let recomp = eig.recompose(); - relative_eq!(m.lower_triangle(), recomp.lower_triangle(), epsilon = 1.0e-5) + prop_assert!(relative_eq!(m.lower_triangle(), recomp.lower_triangle(), epsilon = 1.0e-5)) } - fn symmetric_eigen_static(m: Matrix4) -> bool { + #[test] + fn symmetric_eigen_static(m in matrix4()) { let eig = SymmetricEigen::new(m); let recomp = eig.recompose(); - relative_eq!(m.lower_triangle(), recomp.lower_triangle(), epsilon = 1.0e-5) + prop_assert!(relative_eq!(m.lower_triangle(), recomp.lower_triangle(), epsilon = 1.0e-5)) } } diff --git a/tests/proptest/mod.rs b/tests/proptest/mod.rs index 26bb6129..174c0fdd 100644 --- a/tests/proptest/mod.rs +++ b/tests/proptest/mod.rs @@ -1,4 +1,7 @@ //! Tests for proptest-related functionality. + +#![allow(dead_code)] + use nalgebra::allocator::Allocator; use nalgebra::base::dimension::*; use nalgebra::proptest::{DimRange, MatrixStrategy}; @@ -118,12 +121,10 @@ where macro_rules! define_strategies( ($($strategy_: ident $strategy: ident<$nrows: ident, $ncols: ident>),*) => {$( - #[allow(dead_code)] pub fn $strategy() -> impl Strategy> { matrix(PROPTEST_F64, $nrows, $ncols) } - #[allow(dead_code)] pub fn $strategy_(scalar_strategy: ScalarStrategy) -> impl Strategy> where ScalarStrategy: Strategy + Clone + 'static,