1 //////////////////////////////////////////////////////////////////////////////////////////
2 /////////////////// tests for matrix operations and math functions ///////////////////////
3 //////////////////////////////////////////////////////////////////////////////////////////
5 #include "test_precomp.hpp"
12 /// !!! NOTE !!! These tests happily avoid overflow cases & out-of-range arguments
13 /// so that output arrays contain neigher Inf's nor Nan's.
14 /// Handling such cases would require special modification of check function
15 /// (validate_test_results) => TBD.
16 /// Also, need some logarithmic-scale generation of input data. Right now it is done (in some tests)
17 /// by generating min/max boundaries for random data in logarimithic scale, but
18 /// within the same test case all the input array elements are of the same order.
20 class Core_MathTest : public cvtest::ArrayTest
23 typedef cvtest::ArrayTest Base;
26 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes,
27 vector<vector<int> >& types);
28 double get_success_error_level( int /*test_case_idx*/, int i, int j );
33 Core_MathTest::Core_MathTest()
35 optional_mask = false;
37 test_array[INPUT].push_back(NULL);
38 test_array[OUTPUT].push_back(NULL);
39 test_array[REF_OUTPUT].push_back(NULL);
45 double Core_MathTest::get_success_error_level( int /*test_case_idx*/, int i, int j )
47 return test_mat[i][j].depth() == CV_32F ? FLT_EPSILON*128 : DBL_EPSILON*1024;
51 void Core_MathTest::get_test_array_types_and_sizes( int test_case_idx,
52 vector<vector<Size> >& sizes,
53 vector<vector<int> >& types)
55 RNG& rng = ts->get_rng();
56 int depth = cvtest::randInt(rng)%2 + CV_32F;
57 int cn = cvtest::randInt(rng) % 4 + 1, type = CV_MAKETYPE(depth, cn);
59 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
61 for( i = 0; i < test_array.size(); i++ )
63 size_t count = test_array[i].size();
64 for( j = 0; j < count; j++ )
67 test_nd = cvtest::randInt(rng)%3 == 0;
71 ////////// pow /////////////
73 class Core_PowTest : public Core_MathTest
76 typedef Core_MathTest Base;
79 void get_test_array_types_and_sizes( int test_case_idx,
80 vector<vector<Size> >& sizes,
81 vector<vector<int> >& types );
82 void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
84 void prepare_to_validation( int test_case_idx );
85 double get_success_error_level( int test_case_idx, int i, int j );
90 Core_PowTest::Core_PowTest()
96 void Core_PowTest::get_test_array_types_and_sizes( int test_case_idx,
97 vector<vector<Size> >& sizes,
98 vector<vector<int> >& types )
100 RNG& rng = ts->get_rng();
101 int depth = cvtest::randInt(rng) % (CV_64F+1);
102 int cn = cvtest::randInt(rng) % 4 + 1;
104 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
105 depth += depth == CV_8S;
107 if( depth < CV_32F || cvtest::randInt(rng)%8 == 0 )
109 power = (int)(cvtest::randInt(rng)%21 - 10);
112 i = cvtest::randInt(rng)%17;
113 power = i == 16 ? 1./3 : i == 15 ? 0.5 : i == 14 ? -0.5 : cvtest::randReal(rng)*10 - 5;
116 for( i = 0; i < test_array.size(); i++ )
118 size_t count = test_array[i].size();
119 int type = CV_MAKETYPE(depth, cn);
120 for( j = 0; j < count; j++ )
123 test_nd = cvtest::randInt(rng)%3 == 0;
127 double Core_PowTest::get_success_error_level( int test_case_idx, int i, int j )
129 int depth = test_mat[i][j].depth();
131 return power == cvRound(power) && power >= 0 ? 0 : 1;
133 return Base::get_success_error_level( test_case_idx, i, j );
137 void Core_PowTest::get_minmax_bounds( int /*i*/, int /*j*/, int type, Scalar& low, Scalar& high )
139 double l, u = cvtest::randInt(ts->get_rng())%1000 + 1;
142 double mval = cvtest::getMaxVal(type);
143 double u1 = pow(mval,1./power)*2;
147 l = power == cvRound(power) ? -u : FLT_EPSILON;
148 low = Scalar::all(l);
149 high = Scalar::all(u);
153 void Core_PowTest::run_func()
157 if( fabs(power-1./3) <= DBL_EPSILON && test_mat[INPUT][0].depth() == CV_32F )
159 Mat a = test_mat[INPUT][0], b = test_mat[OUTPUT][0];
163 for( int i = 0; i < a.rows; i++ )
165 b.at<float>(i,0) = (float)fabs(cvCbrt(a.at<float>(i,0)));
166 for( int j = 1; j < a.cols; j++ )
167 b.at<float>(i,j) = (float)fabs(cv::cubeRoot(a.at<float>(i,j)));
171 cvPow( test_array[INPUT][0], test_array[OUTPUT][0], power );
175 Mat& a = test_mat[INPUT][0];
176 Mat& b = test_mat[OUTPUT][0];
180 cv::pow(a, power, b);
185 inline static int ipow( int a, int power )
199 inline static double ipow( double a, int power )
213 void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ )
215 const Mat& a = test_mat[INPUT][0];
216 Mat& b = test_mat[REF_OUTPUT][0];
218 int depth = a.depth();
219 int ncols = a.cols*a.channels();
220 int ipower = cvRound(power), apower = abs(ipower);
223 for( i = 0; i < a.rows; i++ )
225 const uchar* a_data = a.ptr(i);
226 uchar* b_data = b.ptr(i);
232 for( j = 0; j < ncols; j++ )
234 int val = ((uchar*)a_data)[j];
235 ((uchar*)b_data)[j] = (uchar)(val <= 1 ? val :
236 val == 2 && ipower == -1 ? 1 : 0);
239 for( j = 0; j < ncols; j++ )
241 int val = ((uchar*)a_data)[j];
242 val = ipow( val, ipower );
243 ((uchar*)b_data)[j] = saturate_cast<uchar>(val);
248 for( j = 0; j < ncols; j++ )
250 int val = ((char*)a_data)[j];
251 ((char*)b_data)[j] = (char)((val&~1)==0 ? val :
252 val ==-1 ? 1-2*(ipower&1) :
253 val == 2 && ipower == -1 ? 1 : 0);
256 for( j = 0; j < ncols; j++ )
258 int val = ((char*)a_data)[j];
259 val = ipow( val, ipower );
260 ((char*)b_data)[j] = saturate_cast<schar>(val);
265 for( j = 0; j < ncols; j++ )
267 int val = ((ushort*)a_data)[j];
268 ((ushort*)b_data)[j] = (ushort)((val&~1)==0 ? val :
269 val ==-1 ? 1-2*(ipower&1) :
270 val == 2 && ipower == -1 ? 1 : 0);
273 for( j = 0; j < ncols; j++ )
275 int val = ((ushort*)a_data)[j];
276 val = ipow( val, ipower );
277 ((ushort*)b_data)[j] = saturate_cast<ushort>(val);
282 for( j = 0; j < ncols; j++ )
284 int val = ((short*)a_data)[j];
285 ((short*)b_data)[j] = (short)((val&~1)==0 ? val :
286 val ==-1 ? 1-2*(ipower&1) :
287 val == 2 && ipower == -1 ? 1 : 0);
290 for( j = 0; j < ncols; j++ )
292 int val = ((short*)a_data)[j];
293 val = ipow( val, ipower );
294 ((short*)b_data)[j] = saturate_cast<short>(val);
299 for( j = 0; j < ncols; j++ )
301 int val = ((int*)a_data)[j];
302 ((int*)b_data)[j] = (val&~1)==0 ? val :
303 val ==-1 ? 1-2*(ipower&1) :
304 val == 2 && ipower == -1 ? 1 : 0;
307 for( j = 0; j < ncols; j++ )
309 int val = ((int*)a_data)[j];
310 val = ipow( val, ipower );
311 ((int*)b_data)[j] = val;
315 if( power != ipower )
316 for( j = 0; j < ncols; j++ )
318 double val = ((float*)a_data)[j];
319 val = pow( fabs(val), power );
320 ((float*)b_data)[j] = (float)val;
323 for( j = 0; j < ncols; j++ )
325 double val = ((float*)a_data)[j];
328 val = ipow( val, apower );
329 ((float*)b_data)[j] = (float)val;
333 if( power != ipower )
334 for( j = 0; j < ncols; j++ )
336 double val = ((double*)a_data)[j];
337 val = pow( fabs(val), power );
338 ((double*)b_data)[j] = (double)val;
341 for( j = 0; j < ncols; j++ )
343 double val = ((double*)a_data)[j];
346 val = ipow( val, apower );
347 ((double*)b_data)[j] = (double)val;
356 ///////////////////////////////////////// matrix tests ////////////////////////////////////////////
358 class Core_MatrixTest : public cvtest::ArrayTest
361 typedef cvtest::ArrayTest Base;
362 Core_MatrixTest( int in_count, int out_count,
363 bool allow_int, bool scalar_output, int max_cn );
365 void get_test_array_types_and_sizes( int test_case_idx,
366 vector<vector<Size> >& sizes,
367 vector<vector<int> >& types );
368 double get_success_error_level( int test_case_idx, int i, int j );
375 Core_MatrixTest::Core_MatrixTest( int in_count, int out_count,
376 bool _allow_int, bool _scalar_output, int _max_cn )
377 : allow_int(_allow_int), scalar_output(_scalar_output), max_cn(_max_cn)
380 for( i = 0; i < in_count; i++ )
381 test_array[INPUT].push_back(NULL);
383 for( i = 0; i < out_count; i++ )
385 test_array[OUTPUT].push_back(NULL);
386 test_array[REF_OUTPUT].push_back(NULL);
389 element_wise_relative_error = false;
393 void Core_MatrixTest::get_test_array_types_and_sizes( int test_case_idx,
394 vector<vector<Size> >& sizes,
395 vector<vector<int> >& types )
397 RNG& rng = ts->get_rng();
398 int depth = cvtest::randInt(rng) % (allow_int ? CV_64F+1 : 2);
399 int cn = cvtest::randInt(rng) % max_cn + 1;
403 depth += depth == CV_8S;
407 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
409 for( i = 0; i < test_array.size(); i++ )
411 size_t count = test_array[i].size();
412 int flag = (i == OUTPUT || i == REF_OUTPUT) && scalar_output;
413 int type = !flag ? CV_MAKETYPE(depth, cn) : CV_64FC1;
415 for( j = 0; j < count; j++ )
419 sizes[i][j] = Size( 4, 1 );
425 double Core_MatrixTest::get_success_error_level( int test_case_idx, int i, int j )
427 int input_depth = test_mat[INPUT][0].depth();
428 double input_precision = input_depth < CV_32F ? 0 : input_depth == CV_32F ? 5e-5 : 5e-10;
429 double output_precision = Base::get_success_error_level( test_case_idx, i, j );
430 return MAX(input_precision, output_precision);
434 ///////////////// Trace /////////////////////
436 class Core_TraceTest : public Core_MatrixTest
442 void prepare_to_validation( int test_case_idx );
446 Core_TraceTest::Core_TraceTest() : Core_MatrixTest( 1, 1, true, true, 4 )
451 void Core_TraceTest::run_func()
453 test_mat[OUTPUT][0].at<Scalar>(0,0) = cvTrace(test_array[INPUT][0]);
457 void Core_TraceTest::prepare_to_validation( int )
459 Mat& mat = test_mat[INPUT][0];
460 int count = MIN( mat.rows, mat.cols );
461 Mat diag(count, 1, mat.type(), mat.data, mat.step + mat.elemSize());
462 Scalar r = cvtest::mean(diag);
465 test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = r;
469 ///////// dotproduct //////////
471 class Core_DotProductTest : public Core_MatrixTest
474 Core_DotProductTest();
477 void prepare_to_validation( int test_case_idx );
481 Core_DotProductTest::Core_DotProductTest() : Core_MatrixTest( 2, 1, true, true, 4 )
486 void Core_DotProductTest::run_func()
488 test_mat[OUTPUT][0].at<Scalar>(0,0) = Scalar(cvDotProduct( test_array[INPUT][0], test_array[INPUT][1] ));
492 void Core_DotProductTest::prepare_to_validation( int )
494 test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = Scalar(cvtest::crossCorr( test_mat[INPUT][0], test_mat[INPUT][1] ));
498 ///////// crossproduct //////////
500 class Core_CrossProductTest : public Core_MatrixTest
503 Core_CrossProductTest();
505 void get_test_array_types_and_sizes( int test_case_idx,
506 vector<vector<Size> >& sizes,
507 vector<vector<int> >& types );
509 void prepare_to_validation( int test_case_idx );
513 Core_CrossProductTest::Core_CrossProductTest() : Core_MatrixTest( 2, 1, false, false, 1 )
518 void Core_CrossProductTest::get_test_array_types_and_sizes( int,
519 vector<vector<Size> >& sizes,
520 vector<vector<int> >& types )
522 RNG& rng = ts->get_rng();
523 int depth = cvtest::randInt(rng) % 2 + CV_32F;
524 int cn = cvtest::randInt(rng) & 1 ? 3 : 1, type = CV_MAKETYPE(depth, cn);
527 types[INPUT][0] = types[INPUT][1] = types[OUTPUT][0] = types[REF_OUTPUT][0] = type;
531 else if( cvtest::randInt(rng) & 1 )
536 sizes[INPUT][0] = sizes[INPUT][1] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = sz;
540 void Core_CrossProductTest::run_func()
542 cvCrossProduct( test_array[INPUT][0], test_array[INPUT][1], test_array[OUTPUT][0] );
546 void Core_CrossProductTest::prepare_to_validation( int )
548 CvScalar a = {{0,0,0,0}}, b = {{0,0,0,0}}, c = {{0,0,0,0}};
550 if( test_mat[INPUT][0].rows > 1 )
552 a.val[0] = cvGetReal2D( test_array[INPUT][0], 0, 0 );
553 a.val[1] = cvGetReal2D( test_array[INPUT][0], 1, 0 );
554 a.val[2] = cvGetReal2D( test_array[INPUT][0], 2, 0 );
556 b.val[0] = cvGetReal2D( test_array[INPUT][1], 0, 0 );
557 b.val[1] = cvGetReal2D( test_array[INPUT][1], 1, 0 );
558 b.val[2] = cvGetReal2D( test_array[INPUT][1], 2, 0 );
560 else if( test_mat[INPUT][0].cols > 1 )
562 a.val[0] = cvGetReal1D( test_array[INPUT][0], 0 );
563 a.val[1] = cvGetReal1D( test_array[INPUT][0], 1 );
564 a.val[2] = cvGetReal1D( test_array[INPUT][0], 2 );
566 b.val[0] = cvGetReal1D( test_array[INPUT][1], 0 );
567 b.val[1] = cvGetReal1D( test_array[INPUT][1], 1 );
568 b.val[2] = cvGetReal1D( test_array[INPUT][1], 2 );
572 a = cvGet1D( test_array[INPUT][0], 0 );
573 b = cvGet1D( test_array[INPUT][1], 0 );
576 c.val[2] = a.val[0]*b.val[1] - a.val[1]*b.val[0];
577 c.val[1] = -a.val[0]*b.val[2] + a.val[2]*b.val[0];
578 c.val[0] = a.val[1]*b.val[2] - a.val[2]*b.val[1];
580 if( test_mat[REF_OUTPUT][0].rows > 1 )
582 cvSetReal2D( test_array[REF_OUTPUT][0], 0, 0, c.val[0] );
583 cvSetReal2D( test_array[REF_OUTPUT][0], 1, 0, c.val[1] );
584 cvSetReal2D( test_array[REF_OUTPUT][0], 2, 0, c.val[2] );
586 else if( test_mat[REF_OUTPUT][0].cols > 1 )
588 cvSetReal1D( test_array[REF_OUTPUT][0], 0, c.val[0] );
589 cvSetReal1D( test_array[REF_OUTPUT][0], 1, c.val[1] );
590 cvSetReal1D( test_array[REF_OUTPUT][0], 2, c.val[2] );
594 cvSet1D( test_array[REF_OUTPUT][0], 0, c );
599 ///////////////// gemm /////////////////////
601 class Core_GEMMTest : public Core_MatrixTest
604 typedef Core_MatrixTest Base;
607 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
608 void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
609 int prepare_test_case( int test_case_idx );
611 void prepare_to_validation( int test_case_idx );
616 Core_GEMMTest::Core_GEMMTest() : Core_MatrixTest( 5, 1, false, false, 2 )
618 test_case_count = 100;
619 max_log_array_size = 10;
624 void Core_GEMMTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
626 RNG& rng = ts->get_rng();
628 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
629 sizeA = sizes[INPUT][0];
630 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
631 sizes[INPUT][0] = sizeA;
632 sizes[INPUT][2] = sizes[INPUT][3] = Size(1,1);
633 types[INPUT][2] = types[INPUT][3] &= ~CV_MAT_CN_MASK;
635 tabc_flag = cvtest::randInt(rng) & 7;
637 switch( tabc_flag & (CV_GEMM_A_T|CV_GEMM_B_T) )
640 sizes[INPUT][1].height = sizes[INPUT][0].width;
641 sizes[OUTPUT][0].height = sizes[INPUT][0].height;
642 sizes[OUTPUT][0].width = sizes[INPUT][1].width;
645 sizes[INPUT][1].width = sizes[INPUT][0].width;
646 sizes[OUTPUT][0].height = sizes[INPUT][0].height;
647 sizes[OUTPUT][0].width = sizes[INPUT][1].height;
650 sizes[INPUT][1].height = sizes[INPUT][0].height;
651 sizes[OUTPUT][0].height = sizes[INPUT][0].width;
652 sizes[OUTPUT][0].width = sizes[INPUT][1].width;
654 case CV_GEMM_A_T | CV_GEMM_B_T:
655 sizes[INPUT][1].width = sizes[INPUT][0].height;
656 sizes[OUTPUT][0].height = sizes[INPUT][0].width;
657 sizes[OUTPUT][0].width = sizes[INPUT][1].height;
661 sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
663 if( cvtest::randInt(rng) & 1 )
664 sizes[INPUT][4] = Size(0,0);
665 else if( !(tabc_flag & CV_GEMM_C_T) )
666 sizes[INPUT][4] = sizes[OUTPUT][0];
669 sizes[INPUT][4].width = sizes[OUTPUT][0].height;
670 sizes[INPUT][4].height = sizes[OUTPUT][0].width;
675 int Core_GEMMTest::prepare_test_case( int test_case_idx )
677 int code = Base::prepare_test_case( test_case_idx );
680 alpha = cvGetReal2D( test_array[INPUT][2], 0, 0 );
681 beta = cvGetReal2D( test_array[INPUT][3], 0, 0 );
687 void Core_GEMMTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
689 low = Scalar::all(-10.);
690 high = Scalar::all(10.);
694 void Core_GEMMTest::run_func()
696 cvGEMM( test_array[INPUT][0], test_array[INPUT][1], alpha,
697 test_array[INPUT][4], beta, test_array[OUTPUT][0], tabc_flag );
701 void Core_GEMMTest::prepare_to_validation( int )
703 cvtest::gemm( test_mat[INPUT][0], test_mat[INPUT][1], alpha,
704 test_array[INPUT][4] ? test_mat[INPUT][4] : Mat(),
705 beta, test_mat[REF_OUTPUT][0], tabc_flag );
709 ///////////////// multransposed /////////////////////
711 class Core_MulTransposedTest : public Core_MatrixTest
714 Core_MulTransposedTest();
716 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
717 void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
719 void prepare_to_validation( int test_case_idx );
724 Core_MulTransposedTest::Core_MulTransposedTest() : Core_MatrixTest( 2, 1, false, false, 1 )
726 test_case_count = 100;
728 test_array[TEMP].push_back(NULL);
732 void Core_MulTransposedTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
734 RNG& rng = ts->get_rng();
735 int bits = cvtest::randInt(rng);
736 int src_type = cvtest::randInt(rng) % 5;
737 int dst_type = cvtest::randInt(rng) % 2;
739 src_type = src_type == 0 ? CV_8U : src_type == 1 ? CV_16U : src_type == 2 ? CV_16S :
740 src_type == 3 ? CV_32F : CV_64F;
741 dst_type = dst_type == 0 ? CV_32F : CV_64F;
742 dst_type = MAX( dst_type, src_type );
744 Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
747 sizes[INPUT][1] = Size(0,0);
750 sizes[INPUT][1] = sizes[INPUT][0];
752 sizes[INPUT][1].height = 1;
754 sizes[INPUT][1].width = 1;
757 sizes[TEMP][0] = sizes[INPUT][0];
758 types[INPUT][0] = src_type;
759 types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][1] = types[TEMP][0] = dst_type;
761 order = (bits & 8) != 0;
762 sizes[OUTPUT][0].width = sizes[OUTPUT][0].height = order == 0 ?
763 sizes[INPUT][0].height : sizes[INPUT][0].width;
764 sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
768 void Core_MulTransposedTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
770 low = cvScalarAll(-10.);
771 high = cvScalarAll(10.);
775 void Core_MulTransposedTest::run_func()
777 cvMulTransposed( test_array[INPUT][0], test_array[OUTPUT][0],
778 order, test_array[INPUT][1] );
782 void Core_MulTransposedTest::prepare_to_validation( int )
784 const Mat& src = test_mat[INPUT][0];
785 Mat delta = test_mat[INPUT][1];
786 Mat& temp = test_mat[TEMP][0];
789 if( delta.rows < src.rows || delta.cols < src.cols )
791 cv::repeat( delta, src.rows/delta.rows, src.cols/delta.cols, temp);
794 cvtest::add( src, 1, delta, -1, Scalar::all(0), temp, temp.type());
797 src.convertTo(temp, temp.type());
799 cvtest::gemm( temp, temp, 1., Mat(), 0, test_mat[REF_OUTPUT][0], order == 0 ? GEMM_2_T : GEMM_1_T );
803 ///////////////// Transform /////////////////////
805 class Core_TransformTest : public Core_MatrixTest
808 typedef Core_MatrixTest Base;
809 Core_TransformTest();
811 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
812 double get_success_error_level( int test_case_idx, int i, int j );
813 int prepare_test_case( int test_case_idx );
815 void prepare_to_validation( int test_case_idx );
822 Core_TransformTest::Core_TransformTest() : Core_MatrixTest( 3, 1, true, false, 4 )
827 void Core_TransformTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
829 RNG& rng = ts->get_rng();
830 int bits = cvtest::randInt(rng);
831 int depth, dst_cn, mat_cols, mattype;
832 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
834 mat_cols = CV_MAT_CN(types[INPUT][0]);
835 depth = CV_MAT_DEPTH(types[INPUT][0]);
836 dst_cn = cvtest::randInt(rng) % 4 + 1;
837 types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, dst_cn);
839 mattype = depth < CV_32S ? CV_32F : depth == CV_64F ? CV_64F : bits & 1 ? CV_32F : CV_64F;
840 types[INPUT][1] = mattype;
841 types[INPUT][2] = CV_MAKETYPE(mattype, dst_cn);
843 scale = 1./((cvtest::randInt(rng)%4)*50+1);
847 sizes[INPUT][2] = Size(0,0);
848 mat_cols += (bits & 4) != 0;
851 sizes[INPUT][2] = Size(1,1);
855 sizes[INPUT][2] = Size(dst_cn,1);
857 sizes[INPUT][2] = Size(1,dst_cn);
858 types[INPUT][2] &= ~CV_MAT_CN_MASK;
860 diagMtx = (bits & 16) != 0;
862 sizes[INPUT][1] = Size(mat_cols,dst_cn);
866 int Core_TransformTest::prepare_test_case( int test_case_idx )
868 int code = Base::prepare_test_case( test_case_idx );
871 Mat& m = test_mat[INPUT][1];
872 cvtest::add(m, scale, m, 0, Scalar::all(0), m, m.type() );
875 Mat mask = Mat::eye(m.rows, m.cols, CV_8U)*255;
877 m.setTo(Scalar::all(0), mask);
884 double Core_TransformTest::get_success_error_level( int test_case_idx, int i, int j )
886 int depth = test_mat[INPUT][0].depth();
887 return depth <= CV_8S ? 1 : depth <= CV_32S ? 9 : Base::get_success_error_level( test_case_idx, i, j );
890 void Core_TransformTest::run_func()
892 CvMat _m = test_mat[INPUT][1], _shift = test_mat[INPUT][2];
893 cvTransform( test_array[INPUT][0], test_array[OUTPUT][0], &_m, _shift.data.ptr ? &_shift : 0);
897 void Core_TransformTest::prepare_to_validation( int )
899 Mat transmat = test_mat[INPUT][1];
900 Mat shift = test_mat[INPUT][2];
902 cvtest::transform( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], transmat, shift );
906 ///////////////// PerspectiveTransform /////////////////////
908 class Core_PerspectiveTransformTest : public Core_MatrixTest
911 Core_PerspectiveTransformTest();
913 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
914 double get_success_error_level( int test_case_idx, int i, int j );
916 void prepare_to_validation( int test_case_idx );
920 Core_PerspectiveTransformTest::Core_PerspectiveTransformTest() : Core_MatrixTest( 2, 1, false, false, 2 )
925 void Core_PerspectiveTransformTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
927 RNG& rng = ts->get_rng();
928 int bits = cvtest::randInt(rng);
929 int depth, cn, mattype;
930 Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
932 cn = CV_MAT_CN(types[INPUT][0]) + 1;
933 depth = CV_MAT_DEPTH(types[INPUT][0]);
934 types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, cn);
936 mattype = depth == CV_64F ? CV_64F : bits & 1 ? CV_32F : CV_64F;
937 types[INPUT][1] = mattype;
938 sizes[INPUT][1] = Size(cn + 1, cn + 1);
942 double Core_PerspectiveTransformTest::get_success_error_level( int test_case_idx, int i, int j )
944 int depth = test_mat[INPUT][0].depth();
945 return depth == CV_32F ? 1e-4 : depth == CV_64F ? 1e-8 :
946 Core_MatrixTest::get_success_error_level(test_case_idx, i, j);
950 void Core_PerspectiveTransformTest::run_func()
952 CvMat _m = test_mat[INPUT][1];
953 cvPerspectiveTransform( test_array[INPUT][0], test_array[OUTPUT][0], &_m );
957 static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMat* transmat )
960 int cn, depth, mat_depth;
961 CvMat astub, bstub, *a, *b;
964 a = cvGetMat( _src, &astub, 0, 0 );
965 b = cvGetMat( _dst, &bstub, 0, 0 );
967 cn = CV_MAT_CN(a->type);
968 depth = CV_MAT_DEPTH(a->type);
969 mat_depth = CV_MAT_DEPTH(transmat->type);
970 cols = transmat->cols;
972 // prepare cn x (cn + 1) transform matrix
973 if( mat_depth == CV_32F )
975 for( i = 0; i < transmat->rows; i++ )
976 for( j = 0; j < cols; j++ )
977 mat[i*cols + j] = ((float*)(transmat->data.ptr + transmat->step*i))[j];
981 assert( mat_depth == CV_64F );
982 for( i = 0; i < transmat->rows; i++ )
983 for( j = 0; j < cols; j++ )
984 mat[i*cols + j] = ((double*)(transmat->data.ptr + transmat->step*i))[j];
989 vector<double> buf(cols);
991 for( i = 0; i < a->rows; i++ )
993 uchar* src = a->data.ptr + i*a->step;
994 uchar* dst = b->data.ptr + i*b->step;
999 for( j = 0; j < cols; j++ )
1000 buf[j] = ((float*)src)[j];
1003 for( j = 0; j < cols; j++ )
1004 buf[j] = ((double*)src)[j];
1013 for( j = 0; j < cols; j += 2 )
1015 double t0 = buf[j]*mat[0] + buf[j+1]*mat[1] + mat[2];
1016 double t1 = buf[j]*mat[3] + buf[j+1]*mat[4] + mat[5];
1017 double w = buf[j]*mat[6] + buf[j+1]*mat[7] + mat[8];
1024 for( j = 0; j < cols; j += 3 )
1026 double t0 = buf[j]*mat[0] + buf[j+1]*mat[1] + buf[j+2]*mat[2] + mat[3];
1027 double t1 = buf[j]*mat[4] + buf[j+1]*mat[5] + buf[j+2]*mat[6] + mat[7];
1028 double t2 = buf[j]*mat[8] + buf[j+1]*mat[9] + buf[j+2]*mat[10] + mat[11];
1029 double w = buf[j]*mat[12] + buf[j+1]*mat[13] + buf[j+2]*mat[14] + mat[15];
1043 for( j = 0; j < cols; j++ )
1044 ((float*)dst)[j] = (float)buf[j];
1047 for( j = 0; j < cols; j++ )
1048 ((double*)dst)[j] = buf[j];
1057 void Core_PerspectiveTransformTest::prepare_to_validation( int )
1059 CvMat transmat = test_mat[INPUT][1];
1060 cvTsPerspectiveTransform( test_array[INPUT][0], test_array[REF_OUTPUT][0], &transmat );
1063 ///////////////// Mahalanobis /////////////////////
1065 class Core_MahalanobisTest : public Core_MatrixTest
1068 typedef Core_MatrixTest Base;
1069 Core_MahalanobisTest();
1071 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
1072 int prepare_test_case( int test_case_idx );
1074 void prepare_to_validation( int test_case_idx );
1078 Core_MahalanobisTest::Core_MahalanobisTest() : Core_MatrixTest( 3, 1, false, true, 1 )
1080 test_case_count = 100;
1081 test_array[TEMP].push_back(NULL);
1082 test_array[TEMP].push_back(NULL);
1083 test_array[TEMP].push_back(NULL);
1087 void Core_MahalanobisTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
1089 RNG& rng = ts->get_rng();
1090 Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
1092 if( cvtest::randInt(rng) & 1 )
1093 sizes[INPUT][0].width = sizes[INPUT][1].width = 1;
1095 sizes[INPUT][0].height = sizes[INPUT][1].height = 1;
1097 sizes[TEMP][0] = sizes[TEMP][1] = sizes[INPUT][0];
1098 sizes[INPUT][2].width = sizes[INPUT][2].height = sizes[INPUT][0].width + sizes[INPUT][0].height - 1;
1099 sizes[TEMP][2] = sizes[INPUT][2];
1100 types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[INPUT][0];
1103 int Core_MahalanobisTest::prepare_test_case( int test_case_idx )
1105 int code = Base::prepare_test_case( test_case_idx );
1108 // make sure that the inverted "covariation" matrix is symmetrix and positively defined.
1109 cvtest::gemm( test_mat[INPUT][2], test_mat[INPUT][2], 1., Mat(), 0., test_mat[TEMP][2], GEMM_2_T );
1110 cvtest::copy( test_mat[TEMP][2], test_mat[INPUT][2] );
1117 void Core_MahalanobisTest::run_func()
1119 test_mat[OUTPUT][0].at<Scalar>(0,0) =
1120 cvRealScalar(cvMahalanobis(test_array[INPUT][0], test_array[INPUT][1], test_array[INPUT][2]));
1123 void Core_MahalanobisTest::prepare_to_validation( int )
1125 cvtest::add( test_mat[INPUT][0], 1., test_mat[INPUT][1], -1.,
1126 Scalar::all(0), test_mat[TEMP][0], test_mat[TEMP][0].type() );
1127 if( test_mat[INPUT][0].rows == 1 )
1128 cvtest::gemm( test_mat[TEMP][0], test_mat[INPUT][2], 1.,
1129 Mat(), 0., test_mat[TEMP][1], 0 );
1131 cvtest::gemm( test_mat[INPUT][2], test_mat[TEMP][0], 1.,
1132 Mat(), 0., test_mat[TEMP][1], 0 );
1134 test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = cvRealScalar(sqrt(cvtest::crossCorr(test_mat[TEMP][0], test_mat[TEMP][1])));
1138 ///////////////// covarmatrix /////////////////////
1140 class Core_CovarMatrixTest : public Core_MatrixTest
1143 Core_CovarMatrixTest();
1145 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
1146 int prepare_test_case( int test_case_idx );
1148 void prepare_to_validation( int test_case_idx );
1149 vector<void*> temp_hdrs;
1150 vector<uchar> hdr_data;
1151 int flags, t_flag, len, count;
1156 Core_CovarMatrixTest::Core_CovarMatrixTest() : Core_MatrixTest( 1, 1, true, false, 1 ),
1157 flags(0), t_flag(0), are_images(false)
1159 test_case_count = 100;
1160 test_array[INPUT_OUTPUT].push_back(NULL);
1161 test_array[REF_INPUT_OUTPUT].push_back(NULL);
1162 test_array[TEMP].push_back(NULL);
1163 test_array[TEMP].push_back(NULL);
1167 void Core_CovarMatrixTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
1169 RNG& rng = ts->get_rng();
1170 int bits = cvtest::randInt(rng);
1171 int i, single_matrix;
1172 Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
1174 flags = bits & (CV_COVAR_NORMAL | CV_COVAR_USE_AVG | CV_COVAR_SCALE | CV_COVAR_ROWS );
1175 single_matrix = flags & CV_COVAR_ROWS;
1176 t_flag = (bits & 256) != 0;
1178 const int min_count = 2;
1182 len = sizes[INPUT][0].width;
1183 count = sizes[INPUT][0].height;
1184 count = MAX(count, min_count);
1185 sizes[INPUT][0] = Size(len, count);
1189 len = sizes[INPUT][0].height;
1190 count = sizes[INPUT][0].width;
1191 count = MAX(count, min_count);
1192 sizes[INPUT][0] = Size(count, len);
1195 if( single_matrix && t_flag )
1196 flags = (flags & ~CV_COVAR_ROWS) | CV_COVAR_COLS;
1198 if( CV_MAT_DEPTH(types[INPUT][0]) == CV_32S )
1199 types[INPUT][0] = (types[INPUT][0] & ~CV_MAT_DEPTH_MASK) | CV_32F;
1201 sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = flags & CV_COVAR_NORMAL ? Size(len,len) : Size(count,count);
1202 sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = !t_flag ? Size(len,1) : Size(1,len);
1203 sizes[TEMP][0] = sizes[INPUT][0];
1205 types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] =
1206 types[OUTPUT][0] = types[REF_OUTPUT][0] = types[TEMP][0] =
1207 CV_MAT_DEPTH(types[INPUT][0]) == CV_64F || (bits & 512) ? CV_64F : CV_32F;
1209 are_images = (bits & 1024) != 0;
1210 for( i = 0; i < (single_matrix ? 1 : count); i++ )
1211 temp_hdrs.push_back(NULL);
1215 int Core_CovarMatrixTest::prepare_test_case( int test_case_idx )
1217 int code = Core_MatrixTest::prepare_test_case( test_case_idx );
1221 int single_matrix = flags & (CV_COVAR_ROWS|CV_COVAR_COLS);
1222 int hdr_size = are_images ? sizeof(IplImage) : sizeof(CvMat);
1224 hdr_data.resize(count*hdr_size);
1225 uchar* _hdr_data = &hdr_data[0];
1229 *((CvMat*)_hdr_data) = test_mat[INPUT][0];
1231 *((IplImage*)_hdr_data) = test_mat[INPUT][0];
1232 temp_hdrs[0] = _hdr_data;
1235 for( i = 0; i < count; i++ )
1238 void* ptr = _hdr_data + i*hdr_size;
1241 part = test_mat[INPUT][0].row(i);
1243 part = test_mat[INPUT][0].col(i);
1246 *((CvMat*)ptr) = part;
1248 *((IplImage*)ptr) = part;
1258 void Core_CovarMatrixTest::run_func()
1260 cvCalcCovarMatrix( (const void**)&temp_hdrs[0], count,
1261 test_array[OUTPUT][0], test_array[INPUT_OUTPUT][0], flags );
1265 void Core_CovarMatrixTest::prepare_to_validation( int )
1267 Mat& avg = test_mat[REF_INPUT_OUTPUT][0];
1270 if( !(flags & CV_COVAR_USE_AVG) )
1272 Mat hdrs0 = cvarrToMat(temp_hdrs[0]);
1275 avg = Scalar::all(0);
1277 for( i = 0; i < count; i++ )
1280 if( flags & CV_COVAR_ROWS )
1282 else if( flags & CV_COVAR_COLS )
1285 vec = cvarrToMat(temp_hdrs[i]);
1287 cvtest::add(avg, 1, vec, 1, Scalar::all(0), avg, avg.type());
1290 cvtest::add(avg, 1./count, avg, 0., Scalar::all(0), avg, avg.type());
1293 if( flags & CV_COVAR_SCALE )
1298 Mat& temp0 = test_mat[TEMP][0];
1299 cv::repeat( avg, temp0.rows/avg.rows, temp0.cols/avg.cols, temp0 );
1300 cvtest::add( test_mat[INPUT][0], 1, temp0, -1, Scalar::all(0), temp0, temp0.type());
1302 cvtest::gemm( temp0, temp0, scale, Mat(), 0., test_mat[REF_OUTPUT][0],
1303 t_flag ^ ((flags & CV_COVAR_NORMAL) != 0) ? CV_GEMM_A_T : CV_GEMM_B_T );
1308 static void cvTsFloodWithZeros( Mat& mat, RNG& rng )
1310 int k, total = mat.rows*mat.cols, type = mat.type();
1311 int zero_total = cvtest::randInt(rng) % total;
1312 CV_Assert( type == CV_32FC1 || type == CV_64FC1 );
1314 for( k = 0; k < zero_total; k++ )
1316 int i = cvtest::randInt(rng) % mat.rows;
1317 int j = cvtest::randInt(rng) % mat.cols;
1319 if( type == CV_32FC1 )
1320 mat.at<float>(i,j) = 0.f;
1322 mat.at<double>(i,j) = 0.;
1327 ///////////////// determinant /////////////////////
1329 class Core_DetTest : public Core_MatrixTest
1332 typedef Core_MatrixTest Base;
1335 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
1336 double get_success_error_level( int test_case_idx, int i, int j );
1337 void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
1338 int prepare_test_case( int test_case_idx );
1340 void prepare_to_validation( int test_case_idx );
1344 Core_DetTest::Core_DetTest() : Core_MatrixTest( 1, 1, false, true, 1 )
1346 test_case_count = 100;
1347 max_log_array_size = 7;
1348 test_array[TEMP].push_back(NULL);
1352 void Core_DetTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
1354 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
1356 sizes[INPUT][0].width = sizes[INPUT][0].height = sizes[INPUT][0].height;
1357 sizes[TEMP][0] = sizes[INPUT][0];
1358 types[TEMP][0] = CV_64FC1;
1362 void Core_DetTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
1364 low = cvScalarAll(-2.);
1365 high = cvScalarAll(2.);
1369 double Core_DetTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
1371 return CV_MAT_DEPTH(cvGetElemType(test_array[INPUT][0])) == CV_32F ? 1e-2 : 1e-5;
1375 int Core_DetTest::prepare_test_case( int test_case_idx )
1377 int code = Core_MatrixTest::prepare_test_case( test_case_idx );
1379 cvTsFloodWithZeros( test_mat[INPUT][0], ts->get_rng() );
1385 void Core_DetTest::run_func()
1387 test_mat[OUTPUT][0].at<Scalar>(0,0) = cvRealScalar(cvDet(test_array[INPUT][0]));
1391 // LU method that chooses the optimal in a column pivot element
1392 static double cvTsLU( CvMat* a, CvMat* b=NULL, CvMat* x=NULL, int* rank=0 )
1394 int i, j, k, N = a->rows, N1 = a->cols, Nm = MIN(N, N1), step = a->step/sizeof(double);
1395 int M = b ? b->cols : 0, b_step = b ? b->step/sizeof(double) : 0;
1396 int x_step = x ? x->step/sizeof(double) : 0;
1397 double *a0 = a->data.db, *b0 = b ? b->data.db : 0;
1398 double *x0 = x ? x->data.db : 0;
1400 assert( CV_MAT_TYPE(a->type) == CV_64FC1 &&
1401 (!b || CV_ARE_TYPES_EQ(a,b)) && (!x || CV_ARE_TYPES_EQ(a,x)));
1403 for( i = 0; i < Nm; i++ )
1405 double max_val = fabs(a0[i*step + i]);
1406 double *a1, *a2, *b1 = 0, *b2 = 0;
1409 for( j = i+1; j < N; j++ )
1411 t = fabs(a0[j*step + i]);
1421 for( j = i; j < N1; j++ )
1422 CV_SWAP( a0[i*step + j], a0[k*step + j], t );
1424 for( j = 0; j < M; j++ )
1425 CV_SWAP( b0[i*b_step + j], b0[k*b_step + j], t );
1441 for( j = i+1; j < N; j++, a2 += step, b2 += b_step )
1444 for( k = i+1; k < N1; k++ )
1447 for( k = 0; k < M; k++ )
1458 for( i = N-1; i >= 0; i-- )
1460 double* a1 = a0 + i*step;
1461 double* b1 = b0 + i*b_step;
1462 for( j = 0; j < M; j++ )
1465 for( k = i+1; k < N1; k++ )
1466 t -= a1[k]*x0[k*x_step + j];
1467 x0[i*x_step + j] = t/a1[i];
1478 void Core_DetTest::prepare_to_validation( int )
1480 test_mat[INPUT][0].convertTo(test_mat[TEMP][0], test_mat[TEMP][0].type());
1481 CvMat temp0 = test_mat[TEMP][0];
1482 test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = cvRealScalar(cvTsLU(&temp0, 0, 0));
1486 ///////////////// invert /////////////////////
1488 class Core_InvertTest : public Core_MatrixTest
1491 typedef Core_MatrixTest Base;
1494 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
1495 void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
1496 double get_success_error_level( int test_case_idx, int i, int j );
1497 int prepare_test_case( int test_case_idx );
1499 void prepare_to_validation( int test_case_idx );
1505 Core_InvertTest::Core_InvertTest()
1506 : Core_MatrixTest( 1, 1, false, false, 1 ), method(0), rank(0), result(0.)
1508 test_case_count = 100;
1509 max_log_array_size = 7;
1510 test_array[TEMP].push_back(NULL);
1511 test_array[TEMP].push_back(NULL);
1515 void Core_InvertTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
1517 RNG& rng = ts->get_rng();
1518 int bits = cvtest::randInt(rng);
1519 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
1520 int min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height );
1522 if( (bits & 3) == 0 )
1527 sizes[INPUT][0] = Size(min_size, min_size);
1529 method = CV_CHOLESKY;
1535 sizes[INPUT][0] = Size(min_size, min_size);
1538 sizes[TEMP][0].width = sizes[INPUT][0].height;
1539 sizes[TEMP][0].height = sizes[INPUT][0].width;
1540 sizes[TEMP][1] = sizes[INPUT][0];
1541 types[TEMP][0] = types[INPUT][0];
1542 types[TEMP][1] = CV_64FC1;
1543 sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size(min_size, min_size);
1547 double Core_InvertTest::get_success_error_level( int /*test_case_idx*/, int, int )
1549 return CV_MAT_DEPTH(cvGetElemType(test_array[OUTPUT][0])) == CV_32F ? 1e-2 : 1e-6;
1552 int Core_InvertTest::prepare_test_case( int test_case_idx )
1554 int code = Core_MatrixTest::prepare_test_case( test_case_idx );
1557 cvTsFloodWithZeros( test_mat[INPUT][0], ts->get_rng() );
1559 if( method == CV_CHOLESKY )
1561 cvtest::gemm( test_mat[INPUT][0], test_mat[INPUT][0], 1.,
1562 Mat(), 0., test_mat[TEMP][0], CV_GEMM_B_T );
1563 cvtest::copy( test_mat[TEMP][0], test_mat[INPUT][0] );
1572 void Core_InvertTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
1574 low = cvScalarAll(-1.);
1575 high = cvScalarAll(1.);
1579 void Core_InvertTest::run_func()
1581 result = cvInvert(test_array[INPUT][0], test_array[TEMP][0], method);
1585 static double cvTsSVDet( CvMat* mat, double* ratio )
1587 int type = CV_MAT_TYPE(mat->type);
1588 int i, nm = MIN( mat->rows, mat->cols );
1589 CvMat* w = cvCreateMat( nm, 1, type );
1592 cvSVD( mat, w, 0, 0, 0 );
1594 if( type == CV_32FC1 )
1596 for( i = 0; i < nm; i++ )
1597 det *= w->data.fl[i];
1598 *ratio = w->data.fl[nm-1] < FLT_EPSILON ? 0 : w->data.fl[nm-1]/w->data.fl[0];
1602 for( i = 0; i < nm; i++ )
1603 det *= w->data.db[i];
1604 *ratio = w->data.db[nm-1] < FLT_EPSILON ? 0 : w->data.db[nm-1]/w->data.db[0];
1611 void Core_InvertTest::prepare_to_validation( int )
1613 Mat& input = test_mat[INPUT][0];
1614 Mat& temp0 = test_mat[TEMP][0];
1615 Mat& temp1 = test_mat[TEMP][1];
1616 Mat& dst0 = test_mat[REF_OUTPUT][0];
1617 Mat& dst = test_mat[OUTPUT][0];
1618 CvMat _input = input;
1619 double ratio = 0, det = cvTsSVDet( &_input, &ratio );
1620 double threshold = (input.depth() == CV_32F ? FLT_EPSILON : DBL_EPSILON)*1000;
1622 cvtest::convert( input, temp1, temp1.type() );
1624 if( det < threshold ||
1625 ((method == CV_LU || method == CV_CHOLESKY) && (result == 0 || ratio < threshold)) ||
1626 ((method == CV_SVD || method == CV_SVD_SYM) && result < threshold) )
1628 dst = Scalar::all(0);
1629 dst0 = Scalar::all(0);
1633 if( input.rows >= input.cols )
1634 cvtest::gemm( temp0, input, 1., Mat(), 0., dst, 0 );
1636 cvtest::gemm( input, temp0, 1., Mat(), 0., dst, 0 );
1638 cv::setIdentity( dst0, Scalar::all(1) );
1642 ///////////////// solve /////////////////////
1644 class Core_SolveTest : public Core_MatrixTest
1647 typedef Core_MatrixTest Base;
1650 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
1651 void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
1652 double get_success_error_level( int test_case_idx, int i, int j );
1653 int prepare_test_case( int test_case_idx );
1655 void prepare_to_validation( int test_case_idx );
1661 Core_SolveTest::Core_SolveTest() : Core_MatrixTest( 2, 1, false, false, 1 ), method(0), rank(0), result(0.)
1663 test_case_count = 100;
1664 max_log_array_size = 7;
1665 test_array[TEMP].push_back(NULL);
1666 test_array[TEMP].push_back(NULL);
1670 void Core_SolveTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
1672 RNG& rng = ts->get_rng();
1673 int bits = cvtest::randInt(rng);
1674 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
1675 CvSize in_sz = sizes[INPUT][0];
1676 if( in_sz.width > in_sz.height )
1677 in_sz = cvSize(in_sz.height, in_sz.width);
1678 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
1679 sizes[INPUT][0] = in_sz;
1680 int min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height );
1682 if( (bits & 3) == 0 )
1687 sizes[INPUT][0] = Size(min_size, min_size);
1689 method = CV_SVD_SYM;*/
1695 sizes[INPUT][0] = Size(min_size, min_size);
1698 sizes[INPUT][1].height = sizes[INPUT][0].height;
1699 sizes[TEMP][0].width = sizes[INPUT][1].width;
1700 sizes[TEMP][0].height = sizes[INPUT][0].width;
1701 sizes[TEMP][1] = sizes[INPUT][0];
1702 types[TEMP][0] = types[INPUT][0];
1703 types[TEMP][1] = CV_64FC1;
1704 sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size(sizes[INPUT][1].width, min_size);
1708 int Core_SolveTest::prepare_test_case( int test_case_idx )
1710 int code = Core_MatrixTest::prepare_test_case( test_case_idx );
1712 /*if( method == CV_SVD_SYM )
1714 cvTsGEMM( test_array[INPUT][0], test_array[INPUT][0], 1.,
1715 0, 0., test_array[TEMP][0], CV_GEMM_B_T );
1716 cvTsCopy( test_array[TEMP][0], test_array[INPUT][0] );
1723 void Core_SolveTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
1725 low = cvScalarAll(-1.);
1726 high = cvScalarAll(1.);
1730 double Core_SolveTest::get_success_error_level( int /*test_case_idx*/, int, int )
1732 return CV_MAT_DEPTH(cvGetElemType(test_array[OUTPUT][0])) == CV_32F ? 5e-2 : 1e-8;
1736 void Core_SolveTest::run_func()
1738 result = cvSolve(test_array[INPUT][0], test_array[INPUT][1], test_array[TEMP][0], method);
1741 void Core_SolveTest::prepare_to_validation( int )
1743 //int rank = test_mat[REF_OUTPUT][0].rows;
1744 Mat& input = test_mat[INPUT][0];
1745 Mat& dst = test_mat[OUTPUT][0];
1746 Mat& dst0 = test_mat[REF_OUTPUT][0];
1748 if( method == CV_LU )
1752 Mat& temp1 = test_mat[TEMP][1];
1753 cvtest::convert(input, temp1, temp1.type());
1754 dst = Scalar::all(0);
1755 CvMat _temp1 = temp1;
1756 double det = cvTsLU( &_temp1, 0, 0 );
1757 dst0 = Scalar::all(det != 0);
1761 double threshold = (input.type() == CV_32F ? FLT_EPSILON : DBL_EPSILON)*1000;
1762 CvMat _input = input;
1763 double ratio = 0, det = cvTsSVDet( &_input, &ratio );
1764 if( det < threshold || ratio < threshold )
1766 dst = Scalar::all(0);
1767 dst0 = Scalar::all(0);
1772 Mat* pdst = input.rows <= input.cols ? &test_mat[OUTPUT][0] : &test_mat[INPUT][1];
1774 cvtest::gemm( input, test_mat[TEMP][0], 1., test_mat[INPUT][1], -1., *pdst, 0 );
1776 cvtest::gemm( input, *pdst, 1., Mat(), 0., dst, CV_GEMM_A_T );
1777 dst0 = Scalar::all(0);
1781 ///////////////// SVD /////////////////////
1783 class Core_SVDTest : public Core_MatrixTest
1786 typedef Core_MatrixTest Base;
1789 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
1790 double get_success_error_level( int test_case_idx, int i, int j );
1791 void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
1792 int prepare_test_case( int test_case_idx );
1794 void prepare_to_validation( int test_case_idx );
1796 bool have_u, have_v, symmetric, compact, vector_w;
1800 Core_SVDTest::Core_SVDTest() :
1801 Core_MatrixTest( 1, 4, false, false, 1 ),
1802 flags(0), have_u(false), have_v(false), symmetric(false), compact(false), vector_w(false)
1804 test_case_count = 100;
1805 test_array[TEMP].push_back(NULL);
1806 test_array[TEMP].push_back(NULL);
1807 test_array[TEMP].push_back(NULL);
1808 test_array[TEMP].push_back(NULL);
1812 void Core_SVDTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
1814 RNG& rng = ts->get_rng();
1815 int bits = cvtest::randInt(rng);
1816 Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
1817 int min_size, i, m, n;
1819 min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height );
1821 flags = bits & (CV_SVD_MODIFY_A+CV_SVD_U_T+CV_SVD_V_T);
1822 have_u = (bits & 8) != 0;
1823 have_v = (bits & 16) != 0;
1824 symmetric = (bits & 32) != 0;
1825 compact = (bits & 64) != 0;
1826 vector_w = (bits & 128) != 0;
1829 sizes[INPUT][0] = Size(min_size, min_size);
1831 m = sizes[INPUT][0].height;
1832 n = sizes[INPUT][0].width;
1835 sizes[TEMP][0] = Size(min_size, min_size);
1837 sizes[TEMP][0] = sizes[INPUT][0];
1838 sizes[TEMP][3] = Size(0,0);
1842 sizes[TEMP][3] = sizes[TEMP][0];
1844 sizes[TEMP][0] = Size(1, min_size);
1846 sizes[TEMP][0] = Size(min_size, 1);
1851 sizes[TEMP][1] = compact ? Size(min_size, m) : Size(m, m);
1853 if( flags & CV_SVD_U_T )
1854 CV_SWAP( sizes[TEMP][1].width, sizes[TEMP][1].height, i );
1857 sizes[TEMP][1] = Size(0,0);
1861 sizes[TEMP][2] = compact ? Size(n, min_size) : Size(n, n);
1863 if( !(flags & CV_SVD_V_T) )
1864 CV_SWAP( sizes[TEMP][2].width, sizes[TEMP][2].height, i );
1867 sizes[TEMP][2] = Size(0,0);
1869 types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[TEMP][3] = types[INPUT][0];
1870 types[OUTPUT][0] = types[OUTPUT][1] = types[OUTPUT][2] = types[INPUT][0];
1871 types[OUTPUT][3] = CV_8UC1;
1872 sizes[OUTPUT][0] = !have_u || !have_v ? Size(0,0) : sizes[INPUT][0];
1873 sizes[OUTPUT][1] = !have_u ? Size(0,0) : compact ? Size(min_size,min_size) : Size(m,m);
1874 sizes[OUTPUT][2] = !have_v ? Size(0,0) : compact ? Size(min_size,min_size) : Size(n,n);
1875 sizes[OUTPUT][3] = Size(min_size,1);
1877 for( i = 0; i < 4; i++ )
1879 sizes[REF_OUTPUT][i] = sizes[OUTPUT][i];
1880 types[REF_OUTPUT][i] = types[OUTPUT][i];
1885 int Core_SVDTest::prepare_test_case( int test_case_idx )
1887 int code = Core_MatrixTest::prepare_test_case( test_case_idx );
1890 Mat& input = test_mat[INPUT][0];
1891 cvTsFloodWithZeros( input, ts->get_rng() );
1893 if( symmetric && (have_u || have_v) )
1895 Mat& temp = test_mat[TEMP][have_u ? 1 : 2];
1896 cvtest::gemm( input, input, 1., Mat(), 0., temp, CV_GEMM_B_T );
1897 cvtest::copy( temp, input );
1900 if( (flags & CV_SVD_MODIFY_A) && test_array[OUTPUT][0] )
1901 cvtest::copy( input, test_mat[OUTPUT][0] );
1908 void Core_SVDTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
1910 low = cvScalarAll(-2.);
1911 high = cvScalarAll(2.);
1914 double Core_SVDTest::get_success_error_level( int test_case_idx, int i, int j )
1916 int input_depth = CV_MAT_DEPTH(cvGetElemType( test_array[INPUT][0] ));
1917 double input_precision = input_depth < CV_32F ? 0 : input_depth == CV_32F ? 1e-5 : 5e-11;
1918 double output_precision = Base::get_success_error_level( test_case_idx, i, j );
1919 return MAX(input_precision, output_precision);
1922 void Core_SVDTest::run_func()
1924 CvArr* src = test_array[!(flags & CV_SVD_MODIFY_A) ? INPUT : OUTPUT][0];
1926 src = test_array[INPUT][0];
1927 cvSVD( src, test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2], flags );
1931 void Core_SVDTest::prepare_to_validation( int /*test_case_idx*/ )
1933 Mat& input = test_mat[INPUT][0];
1934 int depth = input.depth();
1935 int i, m = input.rows, n = input.cols, min_size = MIN(m, n);
1937 double prev = 0, threshold = depth == CV_32F ? FLT_EPSILON : DBL_EPSILON;
1941 src = &test_mat[TEMP][1];
1942 dst = &test_mat[OUTPUT][1];
1943 cvtest::gemm( *src, *src, 1., Mat(), 0., *dst, src->rows == dst->rows ? CV_GEMM_B_T : CV_GEMM_A_T );
1944 cv::setIdentity( test_mat[REF_OUTPUT][1], Scalar::all(1.) );
1949 src = &test_mat[TEMP][2];
1950 dst = &test_mat[OUTPUT][2];
1951 cvtest::gemm( *src, *src, 1., Mat(), 0., *dst, src->rows == dst->rows ? CV_GEMM_B_T : CV_GEMM_A_T );
1952 cv::setIdentity( test_mat[REF_OUTPUT][2], Scalar::all(1.) );
1955 w = &test_mat[TEMP][0];
1956 for( i = 0; i < min_size; i++ )
1958 double normval = 0, aii;
1959 if( w->rows > 1 && w->cols > 1 )
1961 normval = cvtest::norm( w->row(i), NORM_L1 );
1962 aii = depth == CV_32F ? w->at<float>(i,i) : w->at<double>(i,i);
1966 normval = aii = depth == CV_32F ? w->at<float>(i) : w->at<double>(i);
1969 normval = fabs(normval - aii);
1970 test_mat[OUTPUT][3].at<uchar>(i) = aii >= 0 && normval < threshold && (i == 0 || aii <= prev);
1974 test_mat[REF_OUTPUT][3] = Scalar::all(1);
1976 if( have_u && have_v )
1980 test_mat[TEMP][3] = Scalar::all(0);
1981 for( i = 0; i < min_size; i++ )
1983 double val = depth == CV_32F ? w->at<float>(i) : w->at<double>(i);
1984 cvSetReal2D( test_array[TEMP][3], i, i, val );
1986 w = &test_mat[TEMP][3];
1991 cvtest::gemm( test_mat[TEMP][1], *w, 1., Mat(), 0., test_mat[REF_OUTPUT][0],
1992 flags & CV_SVD_U_T ? CV_GEMM_A_T : 0 );
1993 cvtest::gemm( test_mat[REF_OUTPUT][0], test_mat[TEMP][2], 1., Mat(), 0.,
1994 test_mat[OUTPUT][0], flags & CV_SVD_V_T ? 0 : CV_GEMM_B_T );
1998 cvtest::gemm( *w, test_mat[TEMP][2], 1., Mat(), 0., test_mat[REF_OUTPUT][0],
1999 flags & CV_SVD_V_T ? 0 : CV_GEMM_B_T );
2000 cvtest::gemm( test_mat[TEMP][1], test_mat[REF_OUTPUT][0], 1., Mat(), 0.,
2001 test_mat[OUTPUT][0], flags & CV_SVD_U_T ? CV_GEMM_A_T : 0 );
2004 cvtest::copy( test_mat[INPUT][0], test_mat[REF_OUTPUT][0] );
2010 ///////////////// SVBkSb /////////////////////
2012 class Core_SVBkSbTest : public Core_MatrixTest
2015 typedef Core_MatrixTest Base;
2018 void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
2019 double get_success_error_level( int test_case_idx, int i, int j );
2020 void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
2021 int prepare_test_case( int test_case_idx );
2023 void prepare_to_validation( int test_case_idx );
2025 bool have_b, symmetric, compact, vector_w;
2029 Core_SVBkSbTest::Core_SVBkSbTest() : Core_MatrixTest( 2, 1, false, false, 1 ),
2030 flags(0), have_b(false), symmetric(false), compact(false), vector_w(false)
2032 test_case_count = 100;
2033 test_array[TEMP].push_back(NULL);
2034 test_array[TEMP].push_back(NULL);
2035 test_array[TEMP].push_back(NULL);
2039 void Core_SVBkSbTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes,
2040 vector<vector<int> >& types )
2042 RNG& rng = ts->get_rng();
2043 int bits = cvtest::randInt(rng);
2044 Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
2045 int min_size, i, m, n;
2048 min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height );
2050 flags = bits & (CV_SVD_MODIFY_A+CV_SVD_U_T+CV_SVD_V_T);
2051 have_b = (bits & 16) != 0;
2052 symmetric = (bits & 32) != 0;
2053 compact = (bits & 64) != 0;
2054 vector_w = (bits & 128) != 0;
2057 sizes[INPUT][0] = Size(min_size, min_size);
2059 m = sizes[INPUT][0].height;
2060 n = sizes[INPUT][0].width;
2062 sizes[INPUT][1] = Size(0,0);
2066 sizes[INPUT][1].height = sizes[INPUT][0].height;
2067 sizes[INPUT][1].width = cvtest::randInt(rng) % 100 + 1;
2068 b_size = sizes[INPUT][1];
2072 sizes[TEMP][0] = Size(min_size, min_size);
2074 sizes[TEMP][0] = sizes[INPUT][0];
2079 sizes[TEMP][0] = Size(1, min_size);
2081 sizes[TEMP][0] = Size(min_size, 1);
2084 sizes[TEMP][1] = compact ? Size(min_size, m) : Size(m, m);
2086 if( flags & CV_SVD_U_T )
2087 CV_SWAP( sizes[TEMP][1].width, sizes[TEMP][1].height, i );
2089 sizes[TEMP][2] = compact ? Size(n, min_size) : Size(n, n);
2091 if( !(flags & CV_SVD_V_T) )
2092 CV_SWAP( sizes[TEMP][2].width, sizes[TEMP][2].height, i );
2094 types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[INPUT][0];
2095 types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][0];
2096 sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size( b_size.width, n );
2100 int Core_SVBkSbTest::prepare_test_case( int test_case_idx )
2102 int code = Base::prepare_test_case( test_case_idx );
2105 Mat& input = test_mat[INPUT][0];
2106 cvTsFloodWithZeros( input, ts->get_rng() );
2110 Mat& temp = test_mat[TEMP][1];
2111 cvtest::gemm( input, input, 1., Mat(), 0., temp, CV_GEMM_B_T );
2112 cvtest::copy( temp, input );
2115 CvMat _input = input;
2116 cvSVD( &_input, test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2], flags );
2123 void Core_SVBkSbTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
2125 low = cvScalarAll(-2.);
2126 high = cvScalarAll(2.);
2130 double Core_SVBkSbTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
2132 return CV_MAT_DEPTH(cvGetElemType(test_array[INPUT][0])) == CV_32F ? 1e-3 : 1e-7;
2136 void Core_SVBkSbTest::run_func()
2138 cvSVBkSb( test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2],
2139 test_array[INPUT][1], test_array[OUTPUT][0], flags );
2143 void Core_SVBkSbTest::prepare_to_validation( int )
2145 Mat& input = test_mat[INPUT][0];
2146 int i, m = input.rows, n = input.cols, min_size = MIN(m, n);
2147 bool is_float = input.type() == CV_32F;
2148 Size w_size = compact ? Size(min_size,min_size) : Size(m,n);
2149 Mat& w = test_mat[TEMP][0];
2150 Mat wdb( w_size.height, w_size.width, CV_64FC1 );
2151 CvMat _w = w, _wdb = wdb;
2152 // use exactly the same threshold as in icvSVD... ,
2153 // so the changes in the library and here should be synchronized.
2154 double threshold = cv::sum(w)[0]*(DBL_EPSILON*2);//(is_float ? FLT_EPSILON*10 : DBL_EPSILON*2);
2156 wdb = Scalar::all(0);
2157 for( i = 0; i < min_size; i++ )
2159 double wii = vector_w ? cvGetReal1D(&_w,i) : cvGetReal2D(&_w,i,i);
2160 cvSetReal2D( &_wdb, i, i, wii > threshold ? 1./wii : 0. );
2163 Mat u = test_mat[TEMP][1];
2164 Mat v = test_mat[TEMP][2];
2165 Mat b = test_mat[INPUT][1];
2169 test_mat[TEMP][1].convertTo(u, CV_64F);
2170 test_mat[TEMP][2].convertTo(v, CV_64F);
2172 test_mat[INPUT][1].convertTo(b, CV_64F);
2178 cvtest::gemm( u, b, 1., Mat(), 0., t0, !(flags & CV_SVD_U_T) ? CV_GEMM_A_T : 0 );
2179 else if( flags & CV_SVD_U_T )
2180 cvtest::copy( u, t0 );
2182 cvtest::transpose( u, t0 );
2184 cvtest::gemm( wdb, t0, 1, Mat(), 0, t1, 0 );
2186 cvtest::gemm( v, t1, 1, Mat(), 0, t0, flags & CV_SVD_V_T ? CV_GEMM_A_T : 0 );
2187 Mat& dst0 = test_mat[REF_OUTPUT][0];
2188 t0.convertTo(dst0, dst0.type() );
2192 typedef std::complex<double> complex_type;
2196 bool operator() (const complex_type& lhs, const complex_type& rhs) const
2198 return fabs(lhs.real() - rhs.real()) > fabs(rhs.real())*FLT_EPSILON ? lhs.real() < rhs.real() : lhs.imag() < rhs.imag();
2204 bool operator() (const double& lhs, const double& rhs) const
2210 class Core_SolvePolyTest : public cvtest::BaseTest
2213 Core_SolvePolyTest();
2214 ~Core_SolvePolyTest();
2216 virtual void run( int start_from );
2219 Core_SolvePolyTest::Core_SolvePolyTest() {}
2221 Core_SolvePolyTest::~Core_SolvePolyTest() {}
2223 void Core_SolvePolyTest::run( int )
2225 RNG& rng = ts->get_rng();
2228 double err_eps = 1e-4;
2230 for (int idx = 0, max_idx = 1000, progress = 0; idx < max_idx; ++idx)
2232 progress = update_progress(progress, idx-1, max_idx, 0);
2233 int n = cvtest::randInt(rng) % 13 + 1;
2234 std::vector<complex_type> r(n), ar(n), c(n + 1, 0);
2235 std::vector<double> a(n + 1), u(n * 2), ar1(n), ar2(n);
2237 int rr_odds = 3; // odds that we get a real root
2238 for (int j = 0; j < n;)
2240 if (cvtest::randInt(rng) % rr_odds == 0 || j == n - 1)
2241 r[j++] = cvtest::randReal(rng) * range;
2244 r[j] = complex_type(cvtest::randReal(rng) * range,
2245 cvtest::randReal(rng) * range + 1);
2246 r[j + 1] = std::conj(r[j]);
2251 for (int j = 0, k = 1 << n, jj, kk; j < k; ++j)
2255 for (jj = 0, kk = 1; jj < n && !(j & kk); ++jj, ++p, kk <<= 1)
2257 for (; jj < n; ++jj, kk <<= 1)
2268 double div = 0, s = 0;
2269 int cubic_case = idx & 1;
2270 for (int maxiter = 100; !pass && maxiter < 10000; maxiter *= 2, cubic_case = (cubic_case + 1) % 2)
2272 for (int j = 0; j < n + 1; ++j)
2276 cvInitMatHeader(&amat, n + 1, 1, CV_64FC1, &a[0]);
2277 cvInitMatHeader(&umat, n, 1, CV_64FC2, &u[0]);
2278 cvSolvePoly(&amat, &umat, maxiter, fig);
2280 for (int j = 0; j < n; ++j)
2281 ar[j] = complex_type(u[j * 2], u[j * 2 + 1]);
2283 std::sort(r.begin(), r.end(), pred_complex());
2284 std::sort(ar.begin(), ar.end(), pred_complex());
2290 cv::Mat _umat2(3, 1, CV_64F, &ar2[0]), umat2 = _umat2;
2291 cvFlip(&amat, &amat, 0);
2293 if( cubic_case == 0 )
2294 nr2 = cv::solveCubic(cv::Mat(&amat),umat2);
2296 nr2 = cv::solveCubic(cv::Mat_<float>(cv::Mat(&amat)), umat2);
2297 cvFlip(&amat, &amat, 0);
2299 std::sort(ar2.begin(), ar2.begin()+nr2, pred_double());
2303 for(int j = 0; j < n; j++)
2304 if( fabs(r[j].imag()) < DBL_EPSILON )
2305 ar1[nr1++] = r[j].real();
2307 pass = pass && nr1 == nr2;
2311 for(int j = 0; j < nr1; j++)
2314 div += fabs(ar1[j] - ar2[j]);
2317 pass = pass && div < err_eps;
2322 for (int j = 0; j < n; ++j)
2324 s += fabs(r[j].real()) + fabs(r[j].imag());
2325 div += sqrt(pow(r[j].real() - ar[j].real(), 2) + pow(r[j].imag() - ar[j].imag(), 2));
2328 pass = pass && div < err_eps;
2333 ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
2334 ts->printf( cvtest::TS::LOG, "too big diff = %g\n", div );
2336 for (size_t j=0;j<ar2.size();++j)
2337 ts->printf( cvtest::TS::LOG, "ar2[%d]=%g\n", j, ar2[j]);
2338 ts->printf(cvtest::TS::LOG, "\n");
2340 for (size_t j=0;j<r.size();++j)
2341 ts->printf( cvtest::TS::LOG, "r[%d]=(%g, %g)\n", j, r[j].real(), r[j].imag());
2342 ts->printf( cvtest::TS::LOG, "\n" );
2343 for (size_t j=0;j<ar.size();++j)
2344 ts->printf( cvtest::TS::LOG, "ar[%d]=(%g, %g)\n", j, ar[j].real(), ar[j].imag());
2351 /////////////////////////////////////////////////////////////////////////////////////////////////////
2353 TEST(Core_CovarMatrix, accuracy) { Core_CovarMatrixTest test; test.safe_run(); }
2354 TEST(Core_CrossProduct, accuracy) { Core_CrossProductTest test; test.safe_run(); }
2355 TEST(Core_Determinant, accuracy) { Core_DetTest test; test.safe_run(); }
2356 TEST(Core_DotProduct, accuracy) { Core_DotProductTest test; test.safe_run(); }
2357 TEST(Core_GEMM, accuracy) { Core_GEMMTest test; test.safe_run(); }
2358 TEST(Core_Invert, accuracy) { Core_InvertTest test; test.safe_run(); }
2359 TEST(Core_Mahalanobis, accuracy) { Core_MahalanobisTest test; test.safe_run(); }
2360 TEST(Core_MulTransposed, accuracy) { Core_MulTransposedTest test; test.safe_run(); }
2361 TEST(Core_Transform, accuracy) { Core_TransformTest test; test.safe_run(); }
2362 TEST(Core_PerspectiveTransform, accuracy) { Core_PerspectiveTransformTest test; test.safe_run(); }
2363 TEST(Core_Pow, accuracy) { Core_PowTest test; test.safe_run(); }
2364 TEST(Core_SolveLinearSystem, accuracy) { Core_SolveTest test; test.safe_run(); }
2365 TEST(Core_SVD, accuracy) { Core_SVDTest test; test.safe_run(); }
2366 TEST(Core_SVBkSb, accuracy) { Core_SVBkSbTest test; test.safe_run(); }
2367 TEST(Core_Trace, accuracy) { Core_TraceTest test; test.safe_run(); }
2368 TEST(Core_SolvePoly, accuracy) { Core_SolvePolyTest test; test.safe_run(); }
2370 // TODO: eigenvv, invsqrt, cbrt, fastarctan, (round, floor, ceil(?)),