Commit fd901d83 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

fixed #2108 (thanks to Vincent for the report and proposed solution)

parent 6a13c9ef
...@@ -759,7 +759,8 @@ inline SVD::SVD() {} ...@@ -759,7 +759,8 @@ inline SVD::SVD() {}
inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); } inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
inline void SVD::solveZ( InputArray m, OutputArray _dst ) inline void SVD::solveZ( InputArray m, OutputArray _dst )
{ {
SVD svd(m); Mat mtx = m.getMat();
SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
_dst.create(svd.vt.cols, 1, svd.vt.type()); _dst.create(svd.vt.cols, 1, svd.vt.type());
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst); svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
......
...@@ -75,6 +75,7 @@ protected: ...@@ -75,6 +75,7 @@ protected:
bool TestVec(); bool TestVec();
bool TestMatxMultiplication(); bool TestMatxMultiplication();
bool TestSubMatAccess(); bool TestSubMatAccess();
bool TestSVD();
bool operations1(); bool operations1();
void checkDiff(const Mat& m1, const Mat& m2, const string& s) void checkDiff(const Mat& m1, const Mat& m2, const string& s)
...@@ -934,6 +935,29 @@ bool CV_OperationsTest::operations1() ...@@ -934,6 +935,29 @@ bool CV_OperationsTest::operations1()
return true; return true;
} }
bool CV_OperationsTest::TestSVD()
{
try
{
Mat A = (Mat_<double>(3,4) << 1, 2, -1, 4, 2, 4, 3, 5, -1, -2, 6, 7);
Mat x;
SVD::solveZ(A,x);
if( norm(A*x, CV_C) > FLT_EPSILON )
throw test_excep();
SVD svd(A, SVD::FULL_UV);
if( norm(A*svd.vt.row(3).t(), CV_C) > FLT_EPSILON )
throw test_excep();
}
catch(const test_excep&)
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return false;
}
return true;
}
void CV_OperationsTest::run( int /* start_from */) void CV_OperationsTest::run( int /* start_from */)
{ {
if (!TestMat()) if (!TestMat())
...@@ -959,6 +983,9 @@ void CV_OperationsTest::run( int /* start_from */) ...@@ -959,6 +983,9 @@ void CV_OperationsTest::run( int /* start_from */)
if (!TestSubMatAccess()) if (!TestSubMatAccess())
return; return;
if (!TestSVD())
return;
if (!operations1()) if (!operations1())
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment