core: eliminate 'if' logic from Matx::inv()/solve()

- 'if' logic is moved into templates.
- removed unnecessary cv::Mat objects creation.
- fixed inv() test (invA * A == eye)
- added more Matx tests to cover all defined template specializations
This commit is contained in:
Alexander Alekhin
2018-07-13 18:52:20 +03:00
parent 23fc96e98f
commit 3c74fde349
2 changed files with 96 additions and 49 deletions
+56 -2
View File
@@ -3139,9 +3139,63 @@ TEST(Core_Solve, regression_11888)
cv::Vec<float, 3> b(4, 5, 7);
cv::Matx<float, 2, 1> xQR = A.solve(b, DECOMP_QR);
cv::Matx<float, 2, 1> xSVD = A.solve(b, DECOMP_SVD);
EXPECT_LE(cvtest::norm(xQR, xSVD, CV_RELATIVE_L2), 0.001);
EXPECT_LE(cvtest::norm(xQR, xSVD, NORM_L2 | NORM_RELATIVE), 0.001);
cv::Matx<float, 2, 3> iA = A.inv(DECOMP_SVD);
EXPECT_LE(cvtest::norm(A*iA, Matx<float, 3, 3>::eye(), CV_RELATIVE_L2), 0.6);
EXPECT_LE(cvtest::norm(iA*A, Matx<float, 2, 2>::eye(), NORM_L2), 1e-3);
EXPECT_ANY_THROW({
/*cv::Matx<float, 2, 1> xLU =*/ A.solve(b, DECOMP_LU);
std::cout << "FATAL ERROR" << std::endl;
});
}
TEST(Core_Solve, Matx_2_2)
{
cv::Matx<float, 2, 2> A(
2, 1,
1, 1
);
cv::Vec<float, 2> b(4, 5);
cv::Matx<float, 2, 1> xLU = A.solve(b, DECOMP_LU);
cv::Matx<float, 2, 1> xQR = A.solve(b, DECOMP_QR);
cv::Matx<float, 2, 1> xSVD = A.solve(b, DECOMP_SVD);
EXPECT_LE(cvtest::norm(xQR, xSVD, NORM_L2 | NORM_RELATIVE), 1e-3);
EXPECT_LE(cvtest::norm(xQR, xLU, NORM_L2 | NORM_RELATIVE), 1e-3);
cv::Matx<float, 2, 2> iA = A.inv(DECOMP_SVD);
EXPECT_LE(cvtest::norm(iA*A, Matx<float, 2, 2>::eye(), NORM_L2), 1e-3);
}
TEST(Core_Solve, Matx_3_3)
{
cv::Matx<float, 3, 3> A(
2, 1, 0,
0, 1, 1,
1, 0, 1
);
cv::Vec<float, 3> b(4, 5, 6);
cv::Matx<float, 3, 1> xLU = A.solve(b, DECOMP_LU);
cv::Matx<float, 3, 1> xQR = A.solve(b, DECOMP_QR);
cv::Matx<float, 3, 1> xSVD = A.solve(b, DECOMP_SVD);
EXPECT_LE(cvtest::norm(xQR, xSVD, NORM_L2 | NORM_RELATIVE), 1e-3);
EXPECT_LE(cvtest::norm(xQR, xLU, NORM_L2 | NORM_RELATIVE), 1e-3);
cv::Matx<float, 3, 3> iA = A.inv(DECOMP_SVD);
EXPECT_LE(cvtest::norm(iA*A, Matx<float, 3, 3>::eye(), NORM_L2), 1e-3);
}
TEST(Core_Solve, Matx_4_4)
{
cv::Matx<float, 4, 4> A(
2, 1, 0, 4,
0, 1, 1, 3,
1, 0, 1, 2,
2, 2, 0, 1
);
cv::Vec<float, 4> b(4, 5, 6, 7);
cv::Matx<float, 4, 1> xLU = A.solve(b, DECOMP_LU);
cv::Matx<float, 4, 1> xQR = A.solve(b, DECOMP_QR);
cv::Matx<float, 4, 1> xSVD = A.solve(b, DECOMP_SVD);
EXPECT_LE(cvtest::norm(xQR, xSVD, NORM_L2 | NORM_RELATIVE), 1e-3);
EXPECT_LE(cvtest::norm(xQR, xLU, NORM_L2 | NORM_RELATIVE), 1e-3);
cv::Matx<float, 4, 4> iA = A.inv(DECOMP_SVD);
EXPECT_LE(cvtest::norm(iA*A, Matx<float, 4, 4>::eye(), NORM_L2), 1e-3);
}
softdouble naiveExp(softdouble x)