static const CvSize math_sizes[] = {{10,1}, {100,1}, {10000,1}, {-1,-1}};
static const int math_depths[] = { CV_32F, CV_64F, -1 };
-static const char* math_param_names[] = { "size", "depth" };
+static const char* math_param_names[] = { "size", "depth", 0 };
static const CvSize matrix_sizes[] = {{3,3}, {4,4}, {10,10}, {30,30}, {100,100}, {500,500}, {-1,-1}};
protected:
void get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types );
double get_success_error_level( int /*test_case_idx*/, int i, int j );
+ bool test_nd;
};
whole_size_list = 0;
depth_list = math_depths;
cn_list = 0;
+ test_nd = false;
}
CvSize** sizes, int** types )
{
CvRNG* rng = ts->get_rng();
- int depth = test_case_idx*2/test_case_count ? CV_64F : CV_32F;
+ int depth = cvTsRandInt(rng)%2 + CV_32F;
int cn = cvTsRandInt(rng) % 4 + 1, type = CV_MAKETYPE(depth, cn);
int i, j;
CvArrTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
for( j = 0; j < count; j++ )
types[i][j] = type;
}
+ test_nd = cvTsRandInt(rng)%3 == 0;
}
CxCore_MathTestImpl math_test( "math", "" );
protected:
void get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types );
void get_minmax_bounds( int i, int j, int type, CvScalar* low, CvScalar* high );
+ double get_success_error_level( int /*test_case_idx*/, int i, int j );
+ int prepare_test_case( int test_case );
void run_func();
void prepare_to_validation( int test_case_idx );
int out_type;
}
+double CxCore_ExpTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
+{
+ int in_depth = CV_MAT_DEPTH(test_mat[INPUT][0].type);
+ int out_depth = CV_MAT_DEPTH(test_mat[OUTPUT][0].type);
+ int min_depth = MIN(in_depth, out_depth);
+ return min_depth == CV_32F ? 1e-5 : 1e-8;
+}
+
+
void CxCore_ExpTest::get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types )
{
CxCore_MathTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
out_type = types[OUTPUT][0];
- if( CV_MAT_DEPTH(types[INPUT][0]) == CV_32F && (cvRandInt(ts->get_rng()) & 3) == 0 )
+ /*if( CV_MAT_DEPTH(types[INPUT][0]) == CV_32F && (cvRandInt(ts->get_rng()) & 3) == 0 )
types[OUTPUT][0] = types[REF_OUTPUT][0] =
- out_type = (types[INPUT][0] & ~CV_MAT_DEPTH_MASK)|CV_64F;
+ out_type = (types[INPUT][0] & ~CV_MAT_DEPTH_MASK)|CV_64F;*/
}
void CxCore_ExpTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, CvScalar* low, CvScalar* high )
*high = cvScalarAll(CV_MAT_DEPTH(out_type)==CV_64F? u : u*0.5);
}
+int CxCore_ExpTest::prepare_test_case( int test_case )
+{
+ int code = CxCore_MathTest::prepare_test_case(test_case);
+ if( code < 0 )
+ return code;
+
+ CvRNG* rng = ts->get_rng();
+
+ int i, j, k, count = cvTsRandInt(rng) % 10;
+ CvMat* src = &test_mat[INPUT][0];
+ int depth = CV_MAT_DEPTH(src->type);
+
+ // add some extremal values
+ for( k = 0; k < count; k++ )
+ {
+ i = cvTsRandInt(rng) % src->rows;
+ j = cvTsRandInt(rng) % (src->cols*CV_MAT_CN(src->type));
+ int sign = cvTsRandInt(rng) % 2 ? 1 : -1;
+ if( depth == CV_32F )
+ ((float*)(src->data.ptr + src->step*i))[j] = FLT_MAX*sign;
+ else
+ ((double*)(src->data.ptr + src->step*i))[j] = DBL_MAX*sign;
+ }
+
+ return code;
+}
+
void CxCore_ExpTest::run_func()
{
- cvExp( test_array[INPUT][0], test_array[OUTPUT][0] );
+ if(!test_nd)
+ cvExp( test_array[INPUT][0], test_array[OUTPUT][0] );
+ else
+ {
+ cv::MatND a = cv::cvarrToMatND(test_array[INPUT][0]);
+ cv::MatND b = cv::cvarrToMatND(test_array[OUTPUT][0]);
+ cv::exp(a, b);
+ }
}
void CxCore_LogTest::get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types )
{
CxCore_MathTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
- if( CV_MAT_DEPTH(types[INPUT][0]) == CV_32F && (cvRandInt(ts->get_rng()) & 3) == 0 )
- types[INPUT][0] = (types[INPUT][0] & ~CV_MAT_DEPTH_MASK)|CV_64F;
+ /*if( CV_MAT_DEPTH(types[INPUT][0]) == CV_32F && (cvRandInt(ts->get_rng()) & 3) == 0 )
+ types[INPUT][0] = (types[INPUT][0] & ~CV_MAT_DEPTH_MASK)|CV_64F;*/
}
void CxCore_LogTest::run_func()
{
- cvLog( test_array[INPUT][0], test_array[OUTPUT][0] );
+ if(!test_nd)
+ cvLog( test_array[INPUT][0], test_array[OUTPUT][0] );
+ else
+ {
+ cv::MatND a = cv::cvarrToMatND(test_array[INPUT][0]);
+ cv::MatND b = cv::cvarrToMatND(test_array[OUTPUT][0]);
+ cv::log(a, b);
+ }
}
////////// pow /////////////
static const double math_pow_values[] = { 2., 5., 0.5, -0.5, 1./3, -1./3, CV_PI };
-static const char* math_pow_param_names[] = { "size", "power", "depth" };
+static const char* math_pow_param_names[] = { "size", "power", "depth", 0 };
static const int math_pow_depths[] = { CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F, -1 };
class CxCore_PowTest : public CxCore_MathTest
void CxCore_PowTest::get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types )
{
CvRNG* rng = ts->get_rng();
- int depth = test_case_idx*5/test_case_count;
+ int depth = cvTsRandInt(rng) % (CV_64F+1);
int cn = cvTsRandInt(rng) % 4 + 1;
int i, j;
CvArrTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
power = (int)(cvTsRandInt(rng)%21 - 10);
else
{
- i = cvTsRandInt(rng)%16;
- power = i == 15 ? 0.5 : i == 14 ? -0.5 : cvTsRandReal(rng)*10 - 5;
+ i = cvTsRandInt(rng)%17;
+ power = i == 16 ? 1./3 : i == 15 ? 0.5 : i == 14 ? -0.5 : cvTsRandReal(rng)*10 - 5;
}
for( i = 0; i < max_arr; i++ )
for( j = 0; j < count; j++ )
types[i][j] = type;
}
+ test_nd = cvTsRandInt(rng)%3 == 0;
}
void CxCore_PowTest::run_func()
{
- cvPow( test_array[INPUT][0], test_array[OUTPUT][0], power );
+ if(!test_nd)
+ {
+ if( fabs(power-1./3) <= DBL_EPSILON && CV_MAT_DEPTH(test_mat[INPUT][0].type) == CV_32F )
+ {
+ cv::Mat a(&test_mat[INPUT][0]), b(&test_mat[OUTPUT][0]);
+
+ a = a.reshape(1);
+ b = b.reshape(1);
+ for( int i = 0; i < a.rows; i++ )
+ {
+ b.at<float>(i,0) = (float)fabs(cvCbrt(a.at<float>(i,0)));
+ for( int j = 1; j < a.cols; j++ )
+ b.at<float>(i,j) = (float)fabs(cv::cubeRoot(a.at<float>(i,j)));
+ }
+ }
+ else
+ cvPow( test_array[INPUT][0], test_array[OUTPUT][0], power );
+ }
+ else
+ {
+ cv::MatND a = cv::cvarrToMatND(test_array[INPUT][0]);
+ cv::MatND b = cv::cvarrToMatND(test_array[OUTPUT][0]);
+ if(power == 0.5)
+ cv::sqrt(a, b);
+ else
+ cv::pow(a, power, b);
+ }
}
void CxCore_CartToPolarTest::run_func()
{
- cvCartToPolar( test_array[INPUT][0], test_array[INPUT][1],
- test_array[OUTPUT][0], test_array[OUTPUT][1], use_degrees );
+ if(!test_nd)
+ {
+ cvCartToPolar( test_array[INPUT][0], test_array[INPUT][1],
+ test_array[OUTPUT][0], test_array[OUTPUT][1], use_degrees );
+ }
+ else
+ {
+ cv::Mat X = cv::cvarrToMat(test_array[INPUT][0]);
+ cv::Mat Y = cv::cvarrToMat(test_array[INPUT][1]);
+ cv::Mat mag = test_array[OUTPUT][0] ? cv::cvarrToMat(test_array[OUTPUT][0]) : cv::Mat();
+ cv::Mat ph = test_array[OUTPUT][1] ? cv::cvarrToMat(test_array[OUTPUT][1]) : cv::Mat();
+ if(!mag.data)
+ cv::phase(X, Y, ph, use_degrees != 0);
+ else if(!ph.data)
+ cv::magnitude(X, Y, mag);
+ else
+ cv::cartToPolar(X, Y, mag, ph, use_degrees != 0);
+ }
}
void CxCore_PolarToCartTest::run_func()
{
- cvPolarToCart( test_array[INPUT][1], test_array[INPUT][0],
- test_array[OUTPUT][0], test_array[OUTPUT][1], use_degrees );
+ if(!test_nd)
+ {
+ cvPolarToCart( test_array[INPUT][1], test_array[INPUT][0],
+ test_array[OUTPUT][0], test_array[OUTPUT][1], use_degrees );
+ }
+ else
+ {
+ cv::Mat X = test_array[OUTPUT][0] ? cv::cvarrToMat(test_array[OUTPUT][0]) : cv::Mat();
+ cv::Mat Y = test_array[OUTPUT][1] ? cv::cvarrToMat(test_array[OUTPUT][1]) : cv::Mat();
+ cv::Mat mag = test_array[INPUT][1] ? cv::cvarrToMat(test_array[INPUT][1]) : cv::Mat();
+ cv::Mat ph = test_array[INPUT][0] ? cv::cvarrToMat(test_array[INPUT][0]) : cv::Mat();
+ cv::polarToCart(mag, ph, X, Y, use_degrees != 0);
+ }
}
void CxCore_MatrixTestImpl::get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types )
{
CvRNG* rng = ts->get_rng();
- int depth = test_case_idx*(allow_int ? CV_64F : 2)/test_case_count;
+ int depth = cvTsRandInt(rng) % (allow_int ? CV_64F+1 : 2);
int cn = cvTsRandInt(rng) % max_cn + 1;
int i, j;
{
int input_depth = CV_MAT_DEPTH(cvGetElemType( test_array[INPUT][0] ));
double input_precision = input_depth < CV_32F ? 0 : input_depth == CV_32F ?
- FLT_EPSILON*128 : DBL_EPSILON*1024;
+ 1e-5 : 5e-12;
double output_precision = CvArrTest::get_success_error_level( test_case_idx, i, j );
return MAX(input_precision, output_precision);
}
{
CvMat* mat = &test_mat[INPUT][0];
int i, j, count = MIN( mat->rows, mat->cols );
- CvScalar trace = {0,0,0,0};
+ CvScalar trace = {{0,0,0,0}};
for( i = 0; i < count; i++ )
{
}
-void CxCore_CrossProductTest::get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types )
+void CxCore_CrossProductTest::get_test_array_types_and_sizes( int /*test_case_idx*/, CvSize** sizes, int** types )
{
CvRNG* rng = ts->get_rng();
- int depth = test_case_idx*2/test_case_count ? CV_64F : CV_32F;
+ int depth = cvTsRandInt(rng) % 2 + CV_32F;
int cn = cvTsRandInt(rng) & 1 ? 3 : 1, type = CV_MAKETYPE(depth, cn);
CvSize sz;
void CxCore_CrossProductTest::prepare_to_validation( int )
{
- CvScalar a = {0,0,0,0}, b = {0,0,0,0}, c = {0,0,0,0};
+ CvScalar a = {{0,0,0,0}}, b = {{0,0,0,0}}, c = {{0,0,0,0}};
if( test_mat[INPUT][0].rows > 1 )
{
void run_func();
void prepare_to_validation( int test_case_idx );
CvScalar alpha;
+ bool test_nd;
};
CxCore_ScaleAddTest::CxCore_ScaleAddTest() :
- CxCore_MatrixTest( "matrix-scaleadd", "cvScaleAdd", 3, 1, false, false, 2 )
+ CxCore_MatrixTest( "matrix-scaleadd", "cvScaleAdd", 3, 1, false, false, 4 )
{
alpha = cvScalarAll(0);
+ test_nd = false;
}
{
CxCore_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
sizes[INPUT][2] = cvSize(1,1);
+ types[INPUT][2] &= CV_MAT_DEPTH_MASK;
+ test_nd = cvTsRandInt(ts->get_rng()) % 2 != 0;
}
CxCore_MatrixTest::get_timing_test_array_types_and_sizes( test_case_idx, sizes, types,
whole_sizes, are_images );
sizes[INPUT][2] = cvSize(1,1);
+ types[INPUT][2] &= CV_MAT_DEPTH_MASK;
}
int code = CxCore_MatrixTest::prepare_test_case( test_case_idx );
if( code > 0 )
alpha = cvGet1D( &test_mat[INPUT][2], 0 );
+ if( test_nd )
+ alpha.val[1] = 0;
return code;
}
void CxCore_ScaleAddTest::run_func()
{
- cvScaleAdd( test_array[INPUT][0], alpha, test_array[INPUT][1], test_array[OUTPUT][0] );
+ if(!test_nd)
+ cvScaleAdd( test_array[INPUT][0], alpha, test_array[INPUT][1], test_array[OUTPUT][0] );
+ else
+ {
+ cv::MatND c = cv::cvarrToMatND(test_array[OUTPUT][0]);
+ cv::scaleAdd( cv::cvarrToMatND(test_array[INPUT][0]), alpha.val[0],
+ cv::cvarrToMatND(test_array[INPUT][1]), c);
+ }
}
void CxCore_ScaleAddTest::prepare_to_validation( int )
{
- int rows = test_mat[INPUT][0].rows;
- int type = CV_MAT_TYPE(test_mat[INPUT][0].type);
- int cn = CV_MAT_CN(type);
- int ncols = test_mat[INPUT][0].cols*cn;
- int i, j;
-
- for( i = 0; i < rows; i++ )
- {
- uchar* src1 = test_mat[INPUT][0].data.ptr + test_mat[INPUT][0].step*i;
- uchar* src2 = test_mat[INPUT][1].data.ptr + test_mat[INPUT][1].step*i;
- uchar* dst = test_mat[REF_OUTPUT][0].data.ptr + test_mat[REF_OUTPUT][0].step*i;
-
- switch( type )
- {
- case CV_32FC1:
- for( j = 0; j < ncols; j++ )
- ((float*)dst)[j] = (float)(((float*)src1)[j]*alpha.val[0] + ((float*)src2)[j]);
- break;
- case CV_32FC2:
- for( j = 0; j < ncols; j += 2 )
- {
- double re = ((float*)src1)[j];
- double im = ((float*)src1)[j+1];
- ((float*)dst)[j] = (float)(re*alpha.val[0] - im*alpha.val[1] + ((float*)src2)[j]);
- ((float*)dst)[j+1] = (float)(re*alpha.val[1] + im*alpha.val[0] + ((float*)src2)[j+1]);
- }
- break;
- case CV_64FC1:
- for( j = 0; j < ncols; j++ )
- ((double*)dst)[j] = ((double*)src1)[j]*alpha.val[0] + ((double*)src2)[j];
- break;
- case CV_64FC2:
- for( j = 0; j < ncols; j += 2 )
- {
- double re = ((double*)src1)[j];
- double im = ((double*)src1)[j+1];
- ((double*)dst)[j] = (double)(re*alpha.val[0] - im*alpha.val[1] + ((double*)src2)[j]);
- ((double*)dst)[j+1] = (double)(re*alpha.val[1] + im*alpha.val[0] + ((double*)src2)[j+1]);
- }
- break;
- default:
- assert(0);
- }
- }
+ cvTsAdd( &test_mat[INPUT][0], cvScalarAll(alpha.val[0]),
+ &test_mat[INPUT][1], cvScalarAll(1.),
+ cvScalarAll(0.), &test_mat[REF_OUTPUT][0], 0 );
}
CxCore_ScaleAddTest scaleadd_test;
///////////////// gemm /////////////////////
-static const char* matrix_gemm_param_names[] = { "size", "add_c", "mul_type", "depth" };
+static const char* matrix_gemm_param_names[] = { "size", "add_c", "mul_type", "depth", 0 };
static const char* matrix_gemm_mul_types[] = { "AB", "AtB", "ABt", "AtBt", 0 };
static const int matrix_gemm_add_c_flags[] = { 0, 1 };
CxCore_MatrixTest( "matrix-gemm", "cvGEMM", 5, 1, false, false, 2 )
{
test_case_count = 100;
+ max_log_array_size = 10;
default_timing_param_names = matrix_gemm_param_names;
alpha = beta = 0;
}
///////////////// multransposed /////////////////////
-static const char* matrix_multrans_param_names[] = { "size", "use_delta", "mul_type", "depth" };
+static const char* matrix_multrans_param_names[] = { "size", "use_delta", "mul_type", "depth", 0 };
static const int matrix_multrans_use_delta_flags[] = { 0, 1 };
static const char* matrix_multrans_mul_types[] = { "AAt", "AtA", 0 };
{
CvRNG* rng = ts->get_rng();
int bits = cvTsRandInt(rng);
+ int src_type = cvTsRandInt(rng) % 5;
+ int dst_type = cvTsRandInt(rng) % 2;
+
+ src_type = src_type == 0 ? CV_8U : src_type == 1 ? CV_16U : src_type == 2 ? CV_16S :
+ src_type == 3 ? CV_32F : CV_64F;
+ dst_type = dst_type == 0 ? CV_32F : CV_64F;
+ dst_type = MAX( dst_type, src_type );
+
CxCore_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
+
if( bits & 1 )
- sizes[INPUT][1] = sizes[TEMP][0] = cvSize(0,0);
+ sizes[INPUT][1] = cvSize(0,0);
else
{
- sizes[INPUT][1] = sizes[TEMP][0] = sizes[INPUT][0];
+ sizes[INPUT][1] = sizes[INPUT][0];
if( bits & 2 )
sizes[INPUT][1].height = 1;
+ if( bits & 4 )
+ sizes[INPUT][1].width = 1;
}
- types[TEMP][0] = types[INPUT][0];
+ sizes[TEMP][0] = sizes[INPUT][0];
+ types[INPUT][0] = src_type;
+ types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][1] = types[TEMP][0] = dst_type;
- order = (bits & 4) != 0;
+ order = (bits & 8) != 0;
sizes[OUTPUT][0].width = sizes[OUTPUT][0].height = order == 0 ?
sizes[INPUT][0].height : sizes[INPUT][0].width;
sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
CvMat* delta = test_array[INPUT][1] ? &test_mat[INPUT][1] : 0;
if( delta )
{
- if( test_mat[INPUT][1].rows < test_mat[INPUT][0].rows )
+ if( test_mat[INPUT][1].rows < test_mat[INPUT][0].rows ||
+ test_mat[INPUT][1].cols < test_mat[INPUT][0].cols )
{
cvRepeat( delta, &test_mat[TEMP][0] );
delta = &test_mat[TEMP][0];
}
cvTsAdd( &test_mat[INPUT][0], cvScalarAll(1.), delta, cvScalarAll(-1.),
cvScalarAll(0.), &test_mat[TEMP][0], 0 );
- delta = &test_mat[TEMP][0];
}
else
- delta = &test_mat[INPUT][0];
+ cvTsConvert( &test_mat[INPUT][0], &test_mat[TEMP][0] );
+ delta = &test_mat[TEMP][0];
cvTsGEMM( delta, delta, 1., 0, 0, &test_mat[REF_OUTPUT][0], order == 0 ? CV_GEMM_B_T : CV_GEMM_A_T );
}
static const CvSize matrix_transform_sizes[] = {{10,10}, {100,100}, {720,480}, {-1,-1}};
static const CvSize matrix_transform_whole_sizes[] = {{10,10}, {720,480}, {720,480}, {-1,-1}};
static const int matrix_transform_channels[] = { 2, 3, 4, -1 };
-static const char* matrix_transform_param_names[] = { "size", "channels", "depth" };
+static const char* matrix_transform_param_names[] = { "size", "channels", "depth", 0 };
class CxCore_TransformTest : public CxCore_MatrixTest
{
void get_timing_test_array_types_and_sizes( int test_case_idx,
CvSize** sizes, int** types,
CvSize** whole_sizes, bool* are_images );
+ int prepare_test_case( int test_case_idx );
void print_timing_params( int test_case_idx, char* ptr, int params_left );
void run_func();
void prepare_to_validation( int test_case_idx );
+
+ double scale;
+ bool diagMtx;
};
{
CvRNG* rng = ts->get_rng();
int bits = cvTsRandInt(rng);
- int depth, cn, dst_cn, mat_cols, mattype;
+ int depth, dst_cn, mat_cols, mattype;
CxCore_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
- mat_cols = cn = CV_MAT_CN(types[INPUT][0]);
+ mat_cols = CV_MAT_CN(types[INPUT][0]);
depth = CV_MAT_DEPTH(types[INPUT][0]);
dst_cn = cvTsRandInt(rng) % 4 + 1;
types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, dst_cn);
types[INPUT][1] = mattype;
types[INPUT][2] = CV_MAKETYPE(mattype, dst_cn);
+ scale = 1./((cvTsRandInt(rng)%4)*50+1);
+
if( bits & 2 )
{
sizes[INPUT][2] = cvSize(0,0);
sizes[INPUT][2] = cvSize(1,dst_cn);
types[INPUT][2] &= ~CV_MAT_CN_MASK;
}
+ diagMtx = (bits & 16) != 0;
sizes[INPUT][1] = cvSize(mat_cols,dst_cn);
}
sizes[INPUT][1] = cvSize(cn + (cn < 4), cn);
sizes[INPUT][2] = cvSize(0,0);
types[INPUT][1] = types[INPUT][2] = CV_64FC1;
+ scale = 1./1000;
}
+int CxCore_TransformTest::prepare_test_case( int test_case_idx )
+{
+ int code = CxCore_MatrixTest::prepare_test_case( test_case_idx );
+ if( code > 0 )
+ {
+ cvTsAdd(&test_mat[INPUT][1], cvScalarAll(scale), &test_mat[INPUT][1],
+ cvScalarAll(0), cvScalarAll(0), &test_mat[INPUT][1], 0 );
+ if(diagMtx)
+ {
+ CvMat* w = cvCloneMat(&test_mat[INPUT][1]);
+ cvSetIdentity(w, cvScalarAll(1));
+ cvMul(w, &test_mat[INPUT][1], &test_mat[INPUT][1]);
+ cvReleaseMat(&w);
+ }
+ }
+ return code;
+}
void CxCore_TransformTest::print_timing_params( int test_case_idx, char* ptr, int params_left )
{
double CxCore_TransformTest::get_success_error_level( int test_case_idx, int i, int j )
{
int depth = CV_MAT_DEPTH(test_mat[INPUT][0].type);
- return depth == CV_8U ? 1 : depth == CV_16S || depth == CV_16U ? 8 :
+ return depth <= CV_8S ? 1 : depth <= CV_32S ? 8 :
CxCore_MatrixTest::get_success_error_level( test_case_idx, i, j );
}
CxCore_PerspectiveTransformTest();
protected:
void get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types );
+ double get_success_error_level( int test_case_idx, int i, int j );
void get_timing_test_array_types_and_sizes( int test_case_idx,
CvSize** sizes, int** types,
CvSize** whole_sizes, bool* are_images );
}
+double CxCore_PerspectiveTransformTest::get_success_error_level( int test_case_idx, int i, int j )
+{
+ int depth = CV_MAT_DEPTH(test_mat[INPUT][0].type);
+ return depth == CV_32F ? 1e-4 : depth == CV_64F ? 1e-8 :
+ CxCore_MatrixTest::get_success_error_level(test_case_idx, i, j);
+}
+
+
void CxCore_PerspectiveTransformTest::get_timing_test_array_types_and_sizes( int test_case_idx,
CvSize** sizes, int** types, CvSize** whole_sizes, bool* are_images )
{
void prepare_to_validation( int test_case_idx );
CvTestPtrVec temp_hdrs;
uchar* hdr_data;
- int flags, t_flag;
+ int flags, t_flag, len, count;
bool are_images;
};
{
CvRNG* rng = ts->get_rng();
int bits = cvTsRandInt(rng);
- int i, len, count;
- CvSize sz;
+ int i, single_matrix;
CxCore_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
- flags = bits & (CV_COVAR_NORMAL | CV_COVAR_USE_AVG | CV_COVAR_SCALE);
+ flags = bits & (CV_COVAR_NORMAL | CV_COVAR_USE_AVG | CV_COVAR_SCALE | CV_COVAR_ROWS );
+ single_matrix = flags & CV_COVAR_ROWS;
t_flag = (bits & 256) != 0;
+ const int min_count = 2;
+
if( !t_flag )
- len = sizes[INPUT][0].width, count = sizes[INPUT][0].height;
+ {
+ len = sizes[INPUT][0].width;
+ count = sizes[INPUT][0].height;
+ count = MAX(count, min_count);
+ sizes[INPUT][0] = cvSize(len, count);
+ }
else
- len = sizes[INPUT][0].height, count = sizes[INPUT][0].width;
+ {
+ len = sizes[INPUT][0].height;
+ count = sizes[INPUT][0].width;
+ count = MAX(count, min_count);
+ sizes[INPUT][0] = cvSize(count, len);
+ }
+
+ if( single_matrix && t_flag )
+ flags = (flags & ~CV_COVAR_ROWS) | CV_COVAR_COLS;
if( CV_MAT_DEPTH(types[INPUT][0]) == CV_32S )
types[INPUT][0] = (types[INPUT][0] & ~CV_MAT_DEPTH_MASK) | CV_32F;
sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = flags & CV_COVAR_NORMAL ? cvSize(len,len) : cvSize(count,count);
- sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = sz = !t_flag ? cvSize(len,1) : cvSize(1,len);
+ sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = !t_flag ? cvSize(len,1) : cvSize(1,len);
sizes[TEMP][0] = sizes[INPUT][0];
types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] =
CV_MAT_DEPTH(types[INPUT][0]) == CV_64F || (bits & 512) ? CV_64F : CV_32F;
are_images = (bits & 1024) != 0;
- for( i = 0; i < count; i++ )
+ for( i = 0; i < (single_matrix ? 1 : count); i++ )
temp_hdrs.push(NULL);
}
int code = CxCore_MatrixTest::prepare_test_case( test_case_idx );
if( code > 0 )
{
- int i, count = temp_hdrs.size();
+ int i;
+ int single_matrix = flags & (CV_COVAR_ROWS|CV_COVAR_COLS);
int hdr_size = are_images ? sizeof(IplImage) : sizeof(CvMat);
hdr_data = (uchar*)cvAlloc( count*hdr_size );
- for( i = 0; i < count; i++ )
+ if( single_matrix )
{
- CvMat part;
- void* ptr = hdr_data + i*hdr_size;
-
- if( !t_flag )
- cvGetRow( &test_mat[INPUT][0], &part, i );
- else
- cvGetCol( &test_mat[INPUT][0], &part, i );
-
if( !are_images )
- *((CvMat*)ptr) = part;
+ *((CvMat*)hdr_data) = test_mat[INPUT][0];
else
- cvGetImage( &part, (IplImage*)ptr );
-
- temp_hdrs[i] = ptr;
+ cvGetImage( &test_mat[INPUT][0], (IplImage*)hdr_data );
+ temp_hdrs[0] = hdr_data;
}
+ else
+ for( i = 0; i < count; i++ )
+ {
+ CvMat part;
+ void* ptr = hdr_data + i*hdr_size;
+
+ if( !t_flag )
+ cvGetRow( &test_mat[INPUT][0], &part, i );
+ else
+ cvGetCol( &test_mat[INPUT][0], &part, i );
+
+ if( !are_images )
+ *((CvMat*)ptr) = part;
+ else
+ cvGetImage( &part, (IplImage*)ptr );
+
+ temp_hdrs[i] = ptr;
+ }
}
return code;
void CxCore_CovarMatrixTest::run_func()
{
- cvCalcCovarMatrix( (const void**)&temp_hdrs[0], temp_hdrs.size(),
+ cvCalcCovarMatrix( (const void**)&temp_hdrs[0], count,
test_array[OUTPUT][0], test_array[INPUT_OUTPUT][0], flags );
}
void CxCore_CovarMatrixTest::prepare_to_validation( int )
{
CvMat* avg = &test_mat[REF_INPUT_OUTPUT][0];
- int count = temp_hdrs.size();
double scale = 1.;
if( !(flags & CV_COVAR_USE_AVG) )
for( i = 0; i < count; i++ )
{
- CvMat stub;
- cvTsAdd( avg, cvScalarAll(1.), cvGetMat( temp_hdrs[i], &stub ),
+ CvMat stub, *vec = 0;
+ if( flags & CV_COVAR_ROWS )
+ vec = cvGetRow( temp_hdrs[0], &stub, i );
+ else if( flags & CV_COVAR_COLS )
+ vec = cvGetCol( temp_hdrs[0], &stub, i );
+ else
+ vec = cvGetMat( temp_hdrs[i], &stub );
+
+ cvTsAdd( avg, cvScalarAll(1.), vec,
cvScalarAll(1.), cvScalarAll(0.), avg, 0 );
}
if( flags & CV_COVAR_SCALE )
{
- scale = flags & CV_COVAR_NORMAL ? 1./count :
- 1./(test_mat[REF_INPUT_OUTPUT][0].rows*test_mat[REF_INPUT_OUTPUT][0].cols);
+ scale = 1./count;
}
cvRepeat( avg, &test_mat[TEMP][0] );
t_flag ^ ((flags & CV_COVAR_NORMAL) != 0) ?
CV_GEMM_A_T : CV_GEMM_B_T );
- cvFree( (void**)&hdr_data );
+ cvFree( &hdr_data );
temp_hdrs.clear();
}
///////////////// invert /////////////////////
-static const char* matrix_solve_invert_param_names[] = { "size", "method", "depth" };
+static const char* matrix_solve_invert_param_names[] = { "size", "method", "depth", 0 };
static const char* matrix_solve_invert_methods[] = { "LU", "SVD", 0 };
class CxCore_InvertTest : public CxCore_MatrixTest
CxCore_InvertTest::CxCore_InvertTest() :
- CxCore_MatrixTest( "matrix-invert", "cvInvert, cvSVD, cvSVBkSb", 1, 1, false, false, 1 ), method(0), result(0.), rank(0)
+ CxCore_MatrixTest( "matrix-invert", "cvInvert, cvSVD, cvSVBkSb", 1, 1, false, false, 1 ), method(0), rank(0), result(0.)
{
test_case_count = 100;
max_log_array_size = 7;
double CxCore_InvertTest::get_success_error_level( int /*test_case_idx*/, int, int )
{
- return CV_MAT_DEPTH(cvGetElemType(test_array[OUTPUT][0])) == CV_32F ? 1e-2 : 1e-9;
+ return CV_MAT_DEPTH(cvGetElemType(test_array[OUTPUT][0])) == CV_32F ? 1e-2 : 1e-7;
}
int CxCore_InvertTest::prepare_test_case( int test_case_idx )
void CxCore_InvertTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, CvScalar* low, CvScalar* high )
{
- *low = cvScalarAll(-2.);
- *high = cvScalarAll(2.);
+ *low = cvScalarAll(-1.);
+ *high = cvScalarAll(1.);
}
}
-static double cvTsSVDet( CvMat* mat )
+static double cvTsSVDet( CvMat* mat, double* ratio )
{
int type = CV_MAT_TYPE(mat->type);
int i, nm = MIN( mat->rows, mat->cols );
{
for( i = 0; i < nm; i++ )
det *= w->data.fl[i];
+ *ratio = w->data.fl[nm-1] < FLT_EPSILON ? FLT_MAX : w->data.fl[0]/w->data.fl[nm-1];
}
else
{
for( i = 0; i < nm; i++ )
det *= w->data.db[i];
+ *ratio = w->data.db[nm-1] < FLT_EPSILON ? DBL_MAX : w->data.db[0]/w->data.db[nm-1];
}
cvReleaseMat( &w );
void CxCore_InvertTest::prepare_to_validation( int )
{
CvMat* input = &test_mat[INPUT][0];
- double det = method != CV_LU ? cvTsSVDet( input ) : 0;
- double threshold = (CV_MAT_DEPTH(input->type) == CV_32F ? FLT_EPSILON : DBL_EPSILON)*100;
+ double ratio = 0, det = cvTsSVDet( input, &ratio );
+ double threshold = (CV_MAT_DEPTH(input->type) == CV_32F ? FLT_EPSILON : DBL_EPSILON)*500;
+ double rthreshold = CV_MAT_DEPTH(input->type) == CV_32F ? 1e6 : 1e12;
if( CV_MAT_TYPE(input->type) == CV_32FC1 )
cvTsConvert( input, &test_mat[TEMP][1] );
else
cvTsCopy( input, &test_mat[TEMP][1], 0 );
- if( method == CV_LU && result == 0 || method != CV_LU &&
- det < threshold || result < threshold )
+ if( (method == CV_LU && result == 0) ||
+ det < threshold ||
+ (method == CV_LU && ratio > rthreshold) ||
+ (method == CV_SVD && result < threshold) )
{
cvTsZero( &test_mat[OUTPUT][0] );
cvTsZero( &test_mat[REF_OUTPUT][0] );
CxCore_SolveTest::CxCore_SolveTest() :
- CxCore_MatrixTest( "matrix-solve", "cvSolve, cvSVD, cvSVBkSb", 2, 1, false, false, 1 ), method(0), result(0.), rank(0)
+ CxCore_MatrixTest( "matrix-solve", "cvSolve, cvSVD, cvSVBkSb", 2, 1, false, false, 1 ), method(0), rank(0), result(0.)
{
test_case_count = 100;
max_log_array_size = 7;
void CxCore_SolveTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, CvScalar* low, CvScalar* high )
{
- *low = cvScalarAll(-2.);
- *high = cvScalarAll(2.);
+ *low = cvScalarAll(-1.);
+ *high = cvScalarAll(1.);
}
{
//int rank = test_mat[REF_OUTPUT][0].rows;
CvMat* dst;
+ CvMat* input = &test_mat[INPUT][0];
- if( method == CV_LU && result == 0 )
+ if( method == CV_LU )
{
- if( CV_MAT_TYPE(test_mat[INPUT][0].type) == CV_32FC1 )
- cvTsConvert( &test_mat[INPUT][0], &test_mat[TEMP][1] );
- else
- cvTsCopy( &test_mat[INPUT][0], &test_mat[TEMP][1], 0 );
+ if( result == 0 )
+ {
+ if( CV_MAT_TYPE(input->type) == CV_32FC1 )
+ cvTsConvert( input, &test_mat[TEMP][1] );
+ else
+ cvTsCopy( input, &test_mat[TEMP][1], 0 );
- cvTsZero( &test_mat[OUTPUT][0] );
- double det = cvTsLU( &test_mat[TEMP][1], 0, 0 );
- cvTsAdd( 0, cvScalarAll(0.), 0, cvScalarAll(0.), cvScalarAll(det != 0),
- &test_mat[REF_OUTPUT][0], 0 );
- return;
+ cvTsZero( &test_mat[OUTPUT][0] );
+ double det = cvTsLU( &test_mat[TEMP][1], 0, 0 );
+ cvTsAdd( 0, cvScalarAll(0.), 0, cvScalarAll(0.), cvScalarAll(det != 0),
+ &test_mat[REF_OUTPUT][0], 0 );
+ return;
+ }
+
+ double threshold = (CV_MAT_DEPTH(input->type) == CV_32F ? FLT_EPSILON : DBL_EPSILON)*500;
+ double rthreshold = CV_MAT_DEPTH(input->type) == CV_32F ? 1e6 : 1e12;
+ double ratio = 0, det = cvTsSVDet( input, &ratio );
+ if( det < threshold || ratio > rthreshold )
+ {
+ cvTsZero( &test_mat[OUTPUT][0] );
+ cvTsZero( &test_mat[REF_OUTPUT][0] );
+ return;
+ }
}
+
- dst = test_mat[INPUT][0].rows <= test_mat[INPUT][0].cols ? &test_mat[OUTPUT][0] : &test_mat[INPUT][1];
+ dst = input->rows <= input->cols ? &test_mat[OUTPUT][0] : &test_mat[INPUT][1];
- cvTsGEMM( &test_mat[INPUT][0], &test_mat[TEMP][0], 1., &test_mat[INPUT][1], -1., dst, 0 );
+ cvTsGEMM( input, &test_mat[TEMP][0], 1., &test_mat[INPUT][1], -1., dst, 0 );
if( dst != &test_mat[OUTPUT][0] )
- cvTsGEMM( &test_mat[INPUT][0], dst, 1., 0, 0., &test_mat[OUTPUT][0], CV_GEMM_A_T );
+ cvTsGEMM( input, dst, 1., 0, 0., &test_mat[OUTPUT][0], CV_GEMM_A_T );
cvTsZero( &test_mat[REF_OUTPUT][0] );
}
///////////////// SVD /////////////////////
-static const char* matrix_svd_param_names[] = { "size", "output", "depth" };
+static const char* matrix_svd_param_names[] = { "size", "output", "depth", 0 };
static const char* matrix_svd_output_modes[] = { "w", "all", 0 };
class CxCore_SVDTest : public CxCore_MatrixTest
void get_timing_test_array_types_and_sizes( int test_case_idx,
CvSize** sizes, int** types,
CvSize** whole_sizes, bool* are_images );
+ double get_success_error_level( int test_case_idx, int i, int j );
int write_default_params( CvFileStorage* fs );
void print_timing_params( int test_case_idx, char* ptr, int params_left );
void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, CvScalar* low, CvScalar* high );
*high = cvScalarAll(2.);
}
+double CxCore_SVDTest::get_success_error_level( int test_case_idx, int i, int j )
+{
+ int input_depth = CV_MAT_DEPTH(cvGetElemType( test_array[INPUT][0] ));
+ double input_precision = input_depth < CV_32F ? 0 : input_depth == CV_32F ?
+ 5e-5 : 5e-11;
+ double output_precision = CvArrTest::get_success_error_level( test_case_idx, i, j );
+ return MAX(input_precision, output_precision);
+}
void CxCore_SVDTest::run_func()
{