Commit 9fbd1d68 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

refactored div & pow funcs; added tests for special cases in pow() function.

fixed http://code.opencv.org/issues/3935
possibly fixed http://code.opencv.org/issues/3594
parent 74e2b8cb
This diff is collapsed.
......@@ -502,7 +502,7 @@ JacobiSVDImpl_(_Tp* At, size_t astep, _Tp* _W, _Tp* Vt, size_t vstep,
{
sd = i < n ? W[i] : 0;
while( sd <= minval )
for( int ii = 0; ii < 100 && sd <= minval; ii++ )
{
// if we got a zero singular value, then in order to get the corresponding left singular vector
// we generate a random vector, project it to the previously computed left singular vectors,
......@@ -541,7 +541,7 @@ JacobiSVDImpl_(_Tp* At, size_t astep, _Tp* _W, _Tp* Vt, size_t vstep,
sd = std::sqrt(sd);
}
s = (_Tp)(1/sd);
s = (_Tp)(sd > minval ? 1/sd : 0.);
for( k = 0; k < m; k++ )
At[i*astep + k] *= s;
}
......
This diff is collapsed.
......@@ -290,4 +290,6 @@ extern bool __termination; // skip some cleanups, because process is terminating
}
#include "opencv2/hal/intrin.hpp"
#endif /*_CXCORE_INTERNAL_H_*/
......@@ -1210,6 +1210,13 @@ TEST(Core_Mat, copyNx1ToVector)
ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst16, cv::Mat_<ushort>(dst16));
}
TEST(Core_Matx, fromMat_)
{
Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
Matx22d b(a);
ASSERT_EQ( norm(a, b, NORM_INF), 0.);
}
TEST(Core_SVD, orthogonality)
{
for( int i = 0; i < 2; i++ )
......
......@@ -232,7 +232,7 @@ void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ )
for( j = 0; j < ncols; j++ )
{
int val = ((uchar*)a_data)[j];
((uchar*)b_data)[j] = (uchar)(val <= 1 ? val :
((uchar*)b_data)[j] = (uchar)(val == 0 ? 255 : val == 1 ? 1 :
val == 2 && ipower == -1 ? 1 : 0);
}
else
......@@ -247,17 +247,17 @@ void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ )
if( ipower < 0 )
for( j = 0; j < ncols; j++ )
{
int val = ((char*)a_data)[j];
((char*)b_data)[j] = (char)((val&~1)==0 ? val :
int val = ((schar*)a_data)[j];
((schar*)b_data)[j] = (schar)(val == 0 ? 127 : val == 1 ? 1 :
val ==-1 ? 1-2*(ipower&1) :
val == 2 && ipower == -1 ? 1 : 0);
}
else
for( j = 0; j < ncols; j++ )
{
int val = ((char*)a_data)[j];
int val = ((schar*)a_data)[j];
val = ipow( val, ipower );
((char*)b_data)[j] = saturate_cast<schar>(val);
((schar*)b_data)[j] = saturate_cast<schar>(val);
}
break;
case CV_16U:
......@@ -265,7 +265,7 @@ void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ )
for( j = 0; j < ncols; j++ )
{
int val = ((ushort*)a_data)[j];
((ushort*)b_data)[j] = (ushort)((val&~1)==0 ? val :
((ushort*)b_data)[j] = (ushort)(val == 0 ? 65535 : val == 1 ? 1 :
val ==-1 ? 1-2*(ipower&1) :
val == 2 && ipower == -1 ? 1 : 0);
}
......@@ -282,7 +282,7 @@ void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ )
for( j = 0; j < ncols; j++ )
{
int val = ((short*)a_data)[j];
((short*)b_data)[j] = (short)((val&~1)==0 ? val :
((short*)b_data)[j] = (short)(val == 0 ? 32767 : val == 1 ? 1 :
val ==-1 ? 1-2*(ipower&1) :
val == 2 && ipower == -1 ? 1 : 0);
}
......@@ -299,7 +299,7 @@ void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ )
for( j = 0; j < ncols; j++ )
{
int val = ((int*)a_data)[j];
((int*)b_data)[j] = (val&~1)==0 ? val :
((int*)b_data)[j] = val == 0 ? INT_MAX : val == 1 ? 1 :
val ==-1 ? 1-2*(ipower&1) :
val == 2 && ipower == -1 ? 1 : 0;
}
......@@ -351,8 +351,6 @@ void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ )
}
}
///////////////////////////////////////// matrix tests ////////////////////////////////////////////
class Core_MatrixTest : public cvtest::ArrayTest
......@@ -2822,4 +2820,55 @@ TEST(CovariationMatrixVectorOfMatWithMean, accuracy)
ASSERT_EQ(sDiff.dot(sDiff), 0.0);
}
TEST(Core_Pow, special)
{
for( int i = 0; i < 100; i++ )
{
int n = theRNG().uniform(1, 30);
Mat mtx0(1, n, CV_8S), mtx, result;
randu(mtx0, -5, 5);
int type = theRNG().uniform(0, 2) ? CV_64F : CV_32F;
double eps = type == CV_32F ? 1e-3 : 1e-10;
mtx0.convertTo(mtx, type);
// generate power from [-n, n] interval with 1/8 step - enough to check various cases.
const int max_pf = 3;
int pf = theRNG().uniform(0, max_pf*2+1);
double power = ((1 << pf) - (1 << (max_pf*2-1)))/16.;
int ipower = cvRound(power);
bool is_ipower = ipower == power;
cv::pow(mtx, power, result);
for( int j = 0; j < n; j++ )
{
double val = type == CV_32F ? (double)mtx.at<float>(j) : mtx.at<double>(j);
double r = type == CV_32F ? (double)result.at<float>(j) : result.at<double>(j);
double r0;
if( power == 0. )
r0 = 1;
else if( is_ipower )
{
r0 = 1;
for( int k = 0; k < std::abs(ipower); k++ )
r0 *= val;
if( ipower < 0 )
r0 = 1./r0;
}
else
r0 = std::pow(val, power);
if( cvIsInf(r0) )
{
ASSERT_TRUE(cvIsInf(r));
}
else if( cvIsNaN(r0) )
{
ASSERT_TRUE(cvIsNaN(r));
}
else
{
ASSERT_LT(fabs(r - r0), eps);
}
}
}
}
/* End of file. */
......@@ -614,6 +614,16 @@ inline v_int32x4 operator * (const v_int32x4& a, const v_int32x4& b)
__m128i d1 = _mm_unpackhi_epi32(c0, c1);
return v_int32x4(_mm_unpacklo_epi64(d0, d1));
}
inline v_uint32x4& operator *= (v_uint32x4& a, const v_uint32x4& b)
{
a = a * b;
return a;
}
inline v_int32x4& operator *= (v_int32x4& a, const v_int32x4& b)
{
a = a * b;
return a;
}
inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b,
v_int32x4& c, v_int32x4& d)
......
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