Home | History | Annotate | Download | only in test
      1 //////////////////////////////////////////////////////////////////////////////////////////
      2 /////////////////// tests for matrix operations and math functions ///////////////////////
      3 //////////////////////////////////////////////////////////////////////////////////////////
      4 
      5 #include "test_precomp.hpp"
      6 #include <float.h>
      7 #include <math.h>
      8 
      9 using namespace cv;
     10 using namespace std;
     11 
     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.
     19 
     20 class Core_MathTest : public cvtest::ArrayTest
     21 {
     22 public:
     23     typedef cvtest::ArrayTest Base;
     24     Core_MathTest();
     25 protected:
     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 );
     29     bool test_nd;
     30 };
     31 
     32 
     33 Core_MathTest::Core_MathTest()
     34 {
     35     optional_mask = false;
     36 
     37     test_array[INPUT].push_back(NULL);
     38     test_array[OUTPUT].push_back(NULL);
     39     test_array[REF_OUTPUT].push_back(NULL);
     40 
     41     test_nd = false;
     42 }
     43 
     44 
     45 double Core_MathTest::get_success_error_level( int /*test_case_idx*/, int i, int j )
     46 {
     47     return test_mat[i][j].depth() == CV_32F ? FLT_EPSILON*128 : DBL_EPSILON*1024;
     48 }
     49 
     50 
     51 void Core_MathTest::get_test_array_types_and_sizes( int test_case_idx,
     52                                                      vector<vector<Size> >& sizes,
     53                                                      vector<vector<int> >& types)
     54 {
     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);
     58     size_t i, j;
     59     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
     60 
     61     for( i = 0; i < test_array.size(); i++ )
     62     {
     63         size_t count = test_array[i].size();
     64         for( j = 0; j < count; j++ )
     65             types[i][j] = type;
     66     }
     67     test_nd = cvtest::randInt(rng)%3 == 0;
     68 }
     69 
     70 
     71 ////////// pow /////////////
     72 
     73 class Core_PowTest : public Core_MathTest
     74 {
     75 public:
     76     typedef Core_MathTest Base;
     77     Core_PowTest();
     78 protected:
     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 );
     83     void run_func();
     84     void prepare_to_validation( int test_case_idx );
     85     double get_success_error_level( int test_case_idx, int i, int j );
     86     double power;
     87 };
     88 
     89 
     90 Core_PowTest::Core_PowTest()
     91 {
     92     power = 0;
     93 }
     94 
     95 
     96 void Core_PowTest::get_test_array_types_and_sizes( int test_case_idx,
     97                                                     vector<vector<Size> >& sizes,
     98                                                     vector<vector<int> >& types )
     99 {
    100     RNG& rng = ts->get_rng();
    101     int depth = cvtest::randInt(rng) % (CV_64F+1);
    102     int cn = cvtest::randInt(rng) % 4 + 1;
    103     size_t i, j;
    104     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    105     depth += depth == CV_8S;
    106 
    107     if( depth < CV_32F || cvtest::randInt(rng)%8 == 0 )
    108         // integer power
    109         power = (int)(cvtest::randInt(rng)%21 - 10);
    110     else
    111     {
    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;
    114     }
    115 
    116     for( i = 0; i < test_array.size(); i++ )
    117     {
    118         size_t count = test_array[i].size();
    119         int type = CV_MAKETYPE(depth, cn);
    120         for( j = 0; j < count; j++ )
    121             types[i][j] = type;
    122     }
    123     test_nd = cvtest::randInt(rng)%3 == 0;
    124 }
    125 
    126 
    127 double Core_PowTest::get_success_error_level( int test_case_idx, int i, int j )
    128 {
    129     int depth = test_mat[i][j].depth();
    130     if( depth < CV_32F )
    131         return power == cvRound(power) && power >= 0 ? 0 : 1;
    132     else
    133         return Base::get_success_error_level( test_case_idx, i, j );
    134 }
    135 
    136 
    137 void Core_PowTest::get_minmax_bounds( int /*i*/, int /*j*/, int type, Scalar& low, Scalar& high )
    138 {
    139     double l, u = cvtest::randInt(ts->get_rng())%1000 + 1;
    140     if( power > 0 )
    141     {
    142         double mval = cvtest::getMaxVal(type);
    143         double u1 = pow(mval,1./power)*2;
    144         u = MIN(u,u1);
    145     }
    146 
    147     l = power == cvRound(power) ? -u : FLT_EPSILON;
    148     low = Scalar::all(l);
    149     high = Scalar::all(u);
    150 }
    151 
    152 
    153 void Core_PowTest::run_func()
    154 {
    155     if(!test_nd)
    156     {
    157         if( fabs(power-1./3) <= DBL_EPSILON && test_mat[INPUT][0].depth() == CV_32F )
    158         {
    159             Mat a = test_mat[INPUT][0], b = test_mat[OUTPUT][0];
    160 
    161             a = a.reshape(1);
    162             b = b.reshape(1);
    163             for( int i = 0; i < a.rows; i++ )
    164             {
    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)));
    168             }
    169         }
    170         else
    171             cvPow( test_array[INPUT][0], test_array[OUTPUT][0], power );
    172     }
    173     else
    174     {
    175         Mat& a = test_mat[INPUT][0];
    176         Mat& b = test_mat[OUTPUT][0];
    177         if(power == 0.5)
    178             cv::sqrt(a, b);
    179         else
    180             cv::pow(a, power, b);
    181     }
    182 }
    183 
    184 
    185 inline static int ipow( int a, int power )
    186 {
    187     int b = 1;
    188     while( power > 0 )
    189     {
    190         if( power&1 )
    191             b *= a, power--;
    192         else
    193             a *= a, power >>= 1;
    194     }
    195     return b;
    196 }
    197 
    198 
    199 inline static double ipow( double a, int power )
    200 {
    201     double b = 1.;
    202     while( power > 0 )
    203     {
    204         if( power&1 )
    205             b *= a, power--;
    206         else
    207             a *= a, power >>= 1;
    208     }
    209     return b;
    210 }
    211 
    212 
    213 void Core_PowTest::prepare_to_validation( int /*test_case_idx*/ )
    214 {
    215     const Mat& a = test_mat[INPUT][0];
    216     Mat& b = test_mat[REF_OUTPUT][0];
    217 
    218     int depth = a.depth();
    219     int ncols = a.cols*a.channels();
    220     int ipower = cvRound(power), apower = abs(ipower);
    221     int i, j;
    222 
    223     for( i = 0; i < a.rows; i++ )
    224     {
    225         const uchar* a_data = a.ptr(i);
    226         uchar* b_data = b.ptr(i);
    227 
    228         switch( depth )
    229         {
    230             case CV_8U:
    231                 if( ipower < 0 )
    232                     for( j = 0; j < ncols; j++ )
    233                     {
    234                         int val = ((uchar*)a_data)[j];
    235                         ((uchar*)b_data)[j] = (uchar)(val == 0 ? 255 : val == 1 ? 1 :
    236                                                       val == 2 && ipower == -1 ? 1 : 0);
    237                     }
    238                 else
    239                     for( j = 0; j < ncols; j++ )
    240                     {
    241                         int val = ((uchar*)a_data)[j];
    242                         val = ipow( val, ipower );
    243                         ((uchar*)b_data)[j] = saturate_cast<uchar>(val);
    244                     }
    245                 break;
    246             case CV_8S:
    247                 if( ipower < 0 )
    248                     for( j = 0; j < ncols; j++ )
    249                     {
    250                         int val = ((schar*)a_data)[j];
    251                         ((schar*)b_data)[j] = (schar)(val == 0 ? 127 : val == 1 ? 1 :
    252                                                     val ==-1 ? 1-2*(ipower&1) :
    253                                                     val == 2 && ipower == -1 ? 1 : 0);
    254                     }
    255                 else
    256                     for( j = 0; j < ncols; j++ )
    257                     {
    258                         int val = ((schar*)a_data)[j];
    259                         val = ipow( val, ipower );
    260                         ((schar*)b_data)[j] = saturate_cast<schar>(val);
    261                     }
    262                 break;
    263             case CV_16U:
    264                 if( ipower < 0 )
    265                     for( j = 0; j < ncols; j++ )
    266                     {
    267                         int val = ((ushort*)a_data)[j];
    268                         ((ushort*)b_data)[j] = (ushort)(val == 0 ? 65535 : val == 1 ? 1 :
    269                                                         val ==-1 ? 1-2*(ipower&1) :
    270                                                         val == 2 && ipower == -1 ? 1 : 0);
    271                     }
    272                 else
    273                     for( j = 0; j < ncols; j++ )
    274                     {
    275                         int val = ((ushort*)a_data)[j];
    276                         val = ipow( val, ipower );
    277                         ((ushort*)b_data)[j] = saturate_cast<ushort>(val);
    278                     }
    279                 break;
    280             case CV_16S:
    281                 if( ipower < 0 )
    282                     for( j = 0; j < ncols; j++ )
    283                     {
    284                         int val = ((short*)a_data)[j];
    285                         ((short*)b_data)[j] = (short)(val == 0 ? 32767 : val == 1 ? 1 :
    286                                                       val ==-1 ? 1-2*(ipower&1) :
    287                                                       val == 2 && ipower == -1 ? 1 : 0);
    288                     }
    289                 else
    290                     for( j = 0; j < ncols; j++ )
    291                     {
    292                         int val = ((short*)a_data)[j];
    293                         val = ipow( val, ipower );
    294                         ((short*)b_data)[j] = saturate_cast<short>(val);
    295                     }
    296                 break;
    297             case CV_32S:
    298                 if( ipower < 0 )
    299                     for( j = 0; j < ncols; j++ )
    300                     {
    301                         int val = ((int*)a_data)[j];
    302                         ((int*)b_data)[j] = val == 0 ? INT_MAX : val == 1 ? 1 :
    303                         val ==-1 ? 1-2*(ipower&1) :
    304                         val == 2 && ipower == -1 ? 1 : 0;
    305                     }
    306                 else
    307                     for( j = 0; j < ncols; j++ )
    308                     {
    309                         int val = ((int*)a_data)[j];
    310                         val = ipow( val, ipower );
    311                         ((int*)b_data)[j] = val;
    312                     }
    313                 break;
    314             case CV_32F:
    315                 if( power != ipower )
    316                     for( j = 0; j < ncols; j++ )
    317                     {
    318                         double val = ((float*)a_data)[j];
    319                         val = pow( fabs(val), power );
    320                         ((float*)b_data)[j] = (float)val;
    321                     }
    322                 else
    323                     for( j = 0; j < ncols; j++ )
    324                     {
    325                         double val = ((float*)a_data)[j];
    326                         if( ipower < 0 )
    327                             val = 1./val;
    328                         val = ipow( val, apower );
    329                         ((float*)b_data)[j] = (float)val;
    330                     }
    331                 break;
    332             case CV_64F:
    333                 if( power != ipower )
    334                     for( j = 0; j < ncols; j++ )
    335                     {
    336                         double val = ((double*)a_data)[j];
    337                         val = pow( fabs(val), power );
    338                         ((double*)b_data)[j] = (double)val;
    339                     }
    340                 else
    341                     for( j = 0; j < ncols; j++ )
    342                     {
    343                         double val = ((double*)a_data)[j];
    344                         if( ipower < 0 )
    345                             val = 1./val;
    346                         val = ipow( val, apower );
    347                         ((double*)b_data)[j] = (double)val;
    348                     }
    349                 break;
    350         }
    351     }
    352 }
    353 
    354 ///////////////////////////////////////// matrix tests ////////////////////////////////////////////
    355 
    356 class Core_MatrixTest : public cvtest::ArrayTest
    357 {
    358 public:
    359     typedef cvtest::ArrayTest Base;
    360     Core_MatrixTest( int in_count, int out_count,
    361                        bool allow_int, bool scalar_output, int max_cn );
    362 protected:
    363     void get_test_array_types_and_sizes( int test_case_idx,
    364                                         vector<vector<Size> >& sizes,
    365                                         vector<vector<int> >& types );
    366     double get_success_error_level( int test_case_idx, int i, int j );
    367     bool allow_int;
    368     bool scalar_output;
    369     int max_cn;
    370 };
    371 
    372 
    373 Core_MatrixTest::Core_MatrixTest( int in_count, int out_count,
    374                                       bool _allow_int, bool _scalar_output, int _max_cn )
    375 : allow_int(_allow_int), scalar_output(_scalar_output), max_cn(_max_cn)
    376 {
    377     int i;
    378     for( i = 0; i < in_count; i++ )
    379         test_array[INPUT].push_back(NULL);
    380 
    381     for( i = 0; i < out_count; i++ )
    382     {
    383         test_array[OUTPUT].push_back(NULL);
    384         test_array[REF_OUTPUT].push_back(NULL);
    385     }
    386 
    387     element_wise_relative_error = false;
    388 }
    389 
    390 
    391 void Core_MatrixTest::get_test_array_types_and_sizes( int test_case_idx,
    392                                                        vector<vector<Size> >& sizes,
    393                                                        vector<vector<int> >& types )
    394 {
    395     RNG& rng = ts->get_rng();
    396     int depth = cvtest::randInt(rng) % (allow_int ? CV_64F+1 : 2);
    397     int cn = cvtest::randInt(rng) % max_cn + 1;
    398     size_t i, j;
    399 
    400     if( allow_int )
    401         depth += depth == CV_8S;
    402     else
    403         depth += CV_32F;
    404 
    405     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    406 
    407     for( i = 0; i < test_array.size(); i++ )
    408     {
    409         size_t count = test_array[i].size();
    410         int flag = (i == OUTPUT || i == REF_OUTPUT) && scalar_output;
    411         int type = !flag ? CV_MAKETYPE(depth, cn) : CV_64FC1;
    412 
    413         for( j = 0; j < count; j++ )
    414         {
    415             types[i][j] = type;
    416             if( flag )
    417                 sizes[i][j] = Size( 4, 1 );
    418         }
    419     }
    420 }
    421 
    422 
    423 double Core_MatrixTest::get_success_error_level( int test_case_idx, int i, int j )
    424 {
    425     int input_depth = test_mat[INPUT][0].depth();
    426     double input_precision = input_depth < CV_32F ? 0 : input_depth == CV_32F ? 5e-5 : 5e-10;
    427     double output_precision = Base::get_success_error_level( test_case_idx, i, j );
    428     return MAX(input_precision, output_precision);
    429 }
    430 
    431 
    432 ///////////////// Trace /////////////////////
    433 
    434 class Core_TraceTest : public Core_MatrixTest
    435 {
    436 public:
    437     Core_TraceTest();
    438 protected:
    439     void run_func();
    440     void prepare_to_validation( int test_case_idx );
    441 };
    442 
    443 
    444 Core_TraceTest::Core_TraceTest() : Core_MatrixTest( 1, 1, true, true, 4 )
    445 {
    446 }
    447 
    448 
    449 void Core_TraceTest::run_func()
    450 {
    451     test_mat[OUTPUT][0].at<Scalar>(0,0) = cvTrace(test_array[INPUT][0]);
    452 }
    453 
    454 
    455 void Core_TraceTest::prepare_to_validation( int )
    456 {
    457     Mat& mat = test_mat[INPUT][0];
    458     int count = MIN( mat.rows, mat.cols );
    459     Mat diag(count, 1, mat.type(), mat.ptr(), mat.step + mat.elemSize());
    460     Scalar r = cvtest::mean(diag);
    461     r *= (double)count;
    462 
    463     test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = r;
    464 }
    465 
    466 
    467 ///////// dotproduct //////////
    468 
    469 class Core_DotProductTest : public Core_MatrixTest
    470 {
    471 public:
    472     Core_DotProductTest();
    473 protected:
    474     void run_func();
    475     void prepare_to_validation( int test_case_idx );
    476 };
    477 
    478 
    479 Core_DotProductTest::Core_DotProductTest() : Core_MatrixTest( 2, 1, true, true, 4 )
    480 {
    481 }
    482 
    483 
    484 void Core_DotProductTest::run_func()
    485 {
    486     test_mat[OUTPUT][0].at<Scalar>(0,0) = Scalar(cvDotProduct( test_array[INPUT][0], test_array[INPUT][1] ));
    487 }
    488 
    489 
    490 void Core_DotProductTest::prepare_to_validation( int )
    491 {
    492     test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = Scalar(cvtest::crossCorr( test_mat[INPUT][0], test_mat[INPUT][1] ));
    493 }
    494 
    495 
    496 ///////// crossproduct //////////
    497 
    498 class Core_CrossProductTest : public Core_MatrixTest
    499 {
    500 public:
    501     Core_CrossProductTest();
    502 protected:
    503     void get_test_array_types_and_sizes( int test_case_idx,
    504                                         vector<vector<Size> >& sizes,
    505                                         vector<vector<int> >& types );
    506     void run_func();
    507     void prepare_to_validation( int test_case_idx );
    508 };
    509 
    510 
    511 Core_CrossProductTest::Core_CrossProductTest() : Core_MatrixTest( 2, 1, false, false, 1 )
    512 {
    513 }
    514 
    515 
    516 void Core_CrossProductTest::get_test_array_types_and_sizes( int,
    517                                                              vector<vector<Size> >& sizes,
    518                                                              vector<vector<int> >& types )
    519 {
    520     RNG& rng = ts->get_rng();
    521     int depth = cvtest::randInt(rng) % 2 + CV_32F;
    522     int cn = cvtest::randInt(rng) & 1 ? 3 : 1, type = CV_MAKETYPE(depth, cn);
    523     CvSize sz;
    524 
    525     types[INPUT][0] = types[INPUT][1] = types[OUTPUT][0] = types[REF_OUTPUT][0] = type;
    526 
    527     if( cn == 3 )
    528         sz = Size(1,1);
    529     else if( cvtest::randInt(rng) & 1 )
    530         sz = Size(3,1);
    531     else
    532         sz = Size(1,3);
    533 
    534     sizes[INPUT][0] = sizes[INPUT][1] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = sz;
    535 }
    536 
    537 
    538 void Core_CrossProductTest::run_func()
    539 {
    540     cvCrossProduct( test_array[INPUT][0], test_array[INPUT][1], test_array[OUTPUT][0] );
    541 }
    542 
    543 
    544 void Core_CrossProductTest::prepare_to_validation( int )
    545 {
    546     CvScalar a(0), b(0), c(0);
    547 
    548     if( test_mat[INPUT][0].rows > 1 )
    549     {
    550         a.val[0] = cvGetReal2D( test_array[INPUT][0], 0, 0 );
    551         a.val[1] = cvGetReal2D( test_array[INPUT][0], 1, 0 );
    552         a.val[2] = cvGetReal2D( test_array[INPUT][0], 2, 0 );
    553 
    554         b.val[0] = cvGetReal2D( test_array[INPUT][1], 0, 0 );
    555         b.val[1] = cvGetReal2D( test_array[INPUT][1], 1, 0 );
    556         b.val[2] = cvGetReal2D( test_array[INPUT][1], 2, 0 );
    557     }
    558     else if( test_mat[INPUT][0].cols > 1 )
    559     {
    560         a.val[0] = cvGetReal1D( test_array[INPUT][0], 0 );
    561         a.val[1] = cvGetReal1D( test_array[INPUT][0], 1 );
    562         a.val[2] = cvGetReal1D( test_array[INPUT][0], 2 );
    563 
    564         b.val[0] = cvGetReal1D( test_array[INPUT][1], 0 );
    565         b.val[1] = cvGetReal1D( test_array[INPUT][1], 1 );
    566         b.val[2] = cvGetReal1D( test_array[INPUT][1], 2 );
    567     }
    568     else
    569     {
    570         a = cvGet1D( test_array[INPUT][0], 0 );
    571         b = cvGet1D( test_array[INPUT][1], 0 );
    572     }
    573 
    574     c.val[2] = a.val[0]*b.val[1] - a.val[1]*b.val[0];
    575     c.val[1] = -a.val[0]*b.val[2] + a.val[2]*b.val[0];
    576     c.val[0] = a.val[1]*b.val[2] - a.val[2]*b.val[1];
    577 
    578     if( test_mat[REF_OUTPUT][0].rows > 1 )
    579     {
    580         cvSetReal2D( test_array[REF_OUTPUT][0], 0, 0, c.val[0] );
    581         cvSetReal2D( test_array[REF_OUTPUT][0], 1, 0, c.val[1] );
    582         cvSetReal2D( test_array[REF_OUTPUT][0], 2, 0, c.val[2] );
    583     }
    584     else if( test_mat[REF_OUTPUT][0].cols > 1 )
    585     {
    586         cvSetReal1D( test_array[REF_OUTPUT][0], 0, c.val[0] );
    587         cvSetReal1D( test_array[REF_OUTPUT][0], 1, c.val[1] );
    588         cvSetReal1D( test_array[REF_OUTPUT][0], 2, c.val[2] );
    589     }
    590     else
    591     {
    592         cvSet1D( test_array[REF_OUTPUT][0], 0, c );
    593     }
    594 }
    595 
    596 
    597 ///////////////// gemm /////////////////////
    598 
    599 class Core_GEMMTest : public Core_MatrixTest
    600 {
    601 public:
    602     typedef Core_MatrixTest Base;
    603     Core_GEMMTest();
    604 protected:
    605     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    606     void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
    607     int prepare_test_case( int test_case_idx );
    608     void run_func();
    609     void prepare_to_validation( int test_case_idx );
    610     int tabc_flag;
    611     double alpha, beta;
    612 };
    613 
    614 Core_GEMMTest::Core_GEMMTest() : Core_MatrixTest( 5, 1, false, false, 2 )
    615 {
    616     test_case_count = 100;
    617     max_log_array_size = 10;
    618     tabc_flag = 0;
    619     alpha = beta = 0;
    620 }
    621 
    622 
    623 void Core_GEMMTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    624 {
    625     RNG& rng = ts->get_rng();
    626     Size sizeA;
    627     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    628     sizeA = sizes[INPUT][0];
    629     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    630     sizes[INPUT][0] = sizeA;
    631     sizes[INPUT][2] = sizes[INPUT][3] = Size(1,1);
    632     types[INPUT][2] = types[INPUT][3] &= ~CV_MAT_CN_MASK;
    633 
    634     tabc_flag = cvtest::randInt(rng) & 7;
    635 
    636     switch( tabc_flag & (CV_GEMM_A_T|CV_GEMM_B_T) )
    637     {
    638         case 0:
    639             sizes[INPUT][1].height = sizes[INPUT][0].width;
    640             sizes[OUTPUT][0].height = sizes[INPUT][0].height;
    641             sizes[OUTPUT][0].width = sizes[INPUT][1].width;
    642             break;
    643         case CV_GEMM_B_T:
    644             sizes[INPUT][1].width = sizes[INPUT][0].width;
    645             sizes[OUTPUT][0].height = sizes[INPUT][0].height;
    646             sizes[OUTPUT][0].width = sizes[INPUT][1].height;
    647             break;
    648         case CV_GEMM_A_T:
    649             sizes[INPUT][1].height = sizes[INPUT][0].height;
    650             sizes[OUTPUT][0].height = sizes[INPUT][0].width;
    651             sizes[OUTPUT][0].width = sizes[INPUT][1].width;
    652             break;
    653         case CV_GEMM_A_T | CV_GEMM_B_T:
    654             sizes[INPUT][1].width = sizes[INPUT][0].height;
    655             sizes[OUTPUT][0].height = sizes[INPUT][0].width;
    656             sizes[OUTPUT][0].width = sizes[INPUT][1].height;
    657             break;
    658     }
    659 
    660     sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
    661 
    662     if( cvtest::randInt(rng) & 1 )
    663         sizes[INPUT][4] = Size(0,0);
    664     else if( !(tabc_flag & CV_GEMM_C_T) )
    665         sizes[INPUT][4] = sizes[OUTPUT][0];
    666     else
    667     {
    668         sizes[INPUT][4].width = sizes[OUTPUT][0].height;
    669         sizes[INPUT][4].height = sizes[OUTPUT][0].width;
    670     }
    671 }
    672 
    673 
    674 int Core_GEMMTest::prepare_test_case( int test_case_idx )
    675 {
    676     int code = Base::prepare_test_case( test_case_idx );
    677     if( code > 0 )
    678     {
    679         alpha = cvGetReal2D( test_array[INPUT][2], 0, 0 );
    680         beta = cvGetReal2D( test_array[INPUT][3], 0, 0 );
    681     }
    682     return code;
    683 }
    684 
    685 
    686 void Core_GEMMTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
    687 {
    688     low = Scalar::all(-10.);
    689     high = Scalar::all(10.);
    690 }
    691 
    692 
    693 void Core_GEMMTest::run_func()
    694 {
    695     cvGEMM( test_array[INPUT][0], test_array[INPUT][1], alpha,
    696            test_array[INPUT][4], beta, test_array[OUTPUT][0], tabc_flag );
    697 }
    698 
    699 
    700 void Core_GEMMTest::prepare_to_validation( int )
    701 {
    702     cvtest::gemm( test_mat[INPUT][0], test_mat[INPUT][1], alpha,
    703              test_array[INPUT][4] ? test_mat[INPUT][4] : Mat(),
    704              beta, test_mat[REF_OUTPUT][0], tabc_flag );
    705 }
    706 
    707 
    708 ///////////////// multransposed /////////////////////
    709 
    710 class Core_MulTransposedTest : public Core_MatrixTest
    711 {
    712 public:
    713     Core_MulTransposedTest();
    714 protected:
    715     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    716     void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
    717     void run_func();
    718     void prepare_to_validation( int test_case_idx );
    719     int order;
    720 };
    721 
    722 
    723 Core_MulTransposedTest::Core_MulTransposedTest() : Core_MatrixTest( 2, 1, false, false, 1 )
    724 {
    725     test_case_count = 100;
    726     order = 0;
    727     test_array[TEMP].push_back(NULL);
    728 }
    729 
    730 
    731 void Core_MulTransposedTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    732 {
    733     RNG& rng = ts->get_rng();
    734     int bits = cvtest::randInt(rng);
    735     int src_type = cvtest::randInt(rng) % 5;
    736     int dst_type = cvtest::randInt(rng) % 2;
    737 
    738     src_type = src_type == 0 ? CV_8U : src_type == 1 ? CV_16U : src_type == 2 ? CV_16S :
    739     src_type == 3 ? CV_32F : CV_64F;
    740     dst_type = dst_type == 0 ? CV_32F : CV_64F;
    741     dst_type = MAX( dst_type, src_type );
    742 
    743     Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    744 
    745     if( bits & 1 )
    746         sizes[INPUT][1] = Size(0,0);
    747     else
    748     {
    749         sizes[INPUT][1] = sizes[INPUT][0];
    750         if( bits & 2 )
    751             sizes[INPUT][1].height = 1;
    752         if( bits & 4 )
    753             sizes[INPUT][1].width = 1;
    754     }
    755 
    756     sizes[TEMP][0] = sizes[INPUT][0];
    757     types[INPUT][0] = src_type;
    758     types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][1] = types[TEMP][0] = dst_type;
    759 
    760     order = (bits & 8) != 0;
    761     sizes[OUTPUT][0].width = sizes[OUTPUT][0].height = order == 0 ?
    762     sizes[INPUT][0].height : sizes[INPUT][0].width;
    763     sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
    764 }
    765 
    766 
    767 void Core_MulTransposedTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
    768 {
    769     low = cvScalarAll(-10.);
    770     high = cvScalarAll(10.);
    771 }
    772 
    773 
    774 void Core_MulTransposedTest::run_func()
    775 {
    776     cvMulTransposed( test_array[INPUT][0], test_array[OUTPUT][0],
    777                     order, test_array[INPUT][1] );
    778 }
    779 
    780 
    781 void Core_MulTransposedTest::prepare_to_validation( int )
    782 {
    783     const Mat& src = test_mat[INPUT][0];
    784     Mat delta = test_mat[INPUT][1];
    785     Mat& temp = test_mat[TEMP][0];
    786     if( !delta.empty() )
    787     {
    788         if( delta.rows < src.rows || delta.cols < src.cols )
    789         {
    790             cv::repeat( delta, src.rows/delta.rows, src.cols/delta.cols, temp);
    791             delta = temp;
    792         }
    793         cvtest::add( src, 1, delta, -1, Scalar::all(0), temp, temp.type());
    794     }
    795     else
    796         src.convertTo(temp, temp.type());
    797 
    798     cvtest::gemm( temp, temp, 1., Mat(), 0, test_mat[REF_OUTPUT][0], order == 0 ? GEMM_2_T : GEMM_1_T );
    799 }
    800 
    801 
    802 ///////////////// Transform /////////////////////
    803 
    804 class Core_TransformTest : public Core_MatrixTest
    805 {
    806 public:
    807     typedef Core_MatrixTest Base;
    808     Core_TransformTest();
    809 protected:
    810     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    811     double get_success_error_level( int test_case_idx, int i, int j );
    812     int prepare_test_case( int test_case_idx );
    813     void run_func();
    814     void prepare_to_validation( int test_case_idx );
    815 
    816     double scale;
    817     bool diagMtx;
    818 };
    819 
    820 
    821 Core_TransformTest::Core_TransformTest() : Core_MatrixTest( 3, 1, true, false, 4 )
    822 {
    823     scale = 1;
    824     diagMtx = false;
    825 }
    826 
    827 
    828 void Core_TransformTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    829 {
    830     RNG& rng = ts->get_rng();
    831     int bits = cvtest::randInt(rng);
    832     int depth, dst_cn, mat_cols, mattype;
    833     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    834 
    835     mat_cols = CV_MAT_CN(types[INPUT][0]);
    836     depth = CV_MAT_DEPTH(types[INPUT][0]);
    837     dst_cn = cvtest::randInt(rng) % 4 + 1;
    838     types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, dst_cn);
    839 
    840     mattype = depth < CV_32S ? CV_32F : depth == CV_64F ? CV_64F : bits & 1 ? CV_32F : CV_64F;
    841     types[INPUT][1] = mattype;
    842     types[INPUT][2] = CV_MAKETYPE(mattype, dst_cn);
    843 
    844     scale = 1./((cvtest::randInt(rng)%4)*50+1);
    845 
    846     if( bits & 2 )
    847     {
    848         sizes[INPUT][2] = Size(0,0);
    849         mat_cols += (bits & 4) != 0;
    850     }
    851     else if( bits & 4 )
    852         sizes[INPUT][2] = Size(1,1);
    853     else
    854     {
    855         if( bits & 8 )
    856             sizes[INPUT][2] = Size(dst_cn,1);
    857         else
    858             sizes[INPUT][2] = Size(1,dst_cn);
    859         types[INPUT][2] &= ~CV_MAT_CN_MASK;
    860     }
    861     diagMtx = (bits & 16) != 0;
    862 
    863     sizes[INPUT][1] = Size(mat_cols,dst_cn);
    864 }
    865 
    866 
    867 int Core_TransformTest::prepare_test_case( int test_case_idx )
    868 {
    869     int code = Base::prepare_test_case( test_case_idx );
    870     if( code > 0 )
    871     {
    872         Mat& m = test_mat[INPUT][1];
    873         cvtest::add(m, scale, m, 0, Scalar::all(0), m, m.type() );
    874         if(diagMtx)
    875         {
    876             Mat mask = Mat::eye(m.rows, m.cols, CV_8U)*255;
    877             mask = ~mask;
    878             m.setTo(Scalar::all(0), mask);
    879         }
    880     }
    881     return code;
    882 }
    883 
    884 
    885 double Core_TransformTest::get_success_error_level( int test_case_idx, int i, int j )
    886 {
    887     int depth = test_mat[INPUT][0].depth();
    888     return depth <= CV_8S ? 1 : depth <= CV_32S ? 9 : Base::get_success_error_level( test_case_idx, i, j );
    889 }
    890 
    891 void Core_TransformTest::run_func()
    892 {
    893     CvMat _m = test_mat[INPUT][1], _shift = test_mat[INPUT][2];
    894     cvTransform( test_array[INPUT][0], test_array[OUTPUT][0], &_m, _shift.data.ptr ? &_shift : 0);
    895 }
    896 
    897 
    898 void Core_TransformTest::prepare_to_validation( int )
    899 {
    900     Mat transmat = test_mat[INPUT][1];
    901     Mat shift = test_mat[INPUT][2];
    902 
    903     cvtest::transform( test_mat[INPUT][0], test_mat[REF_OUTPUT][0], transmat, shift );
    904 }
    905 
    906 
    907 ///////////////// PerspectiveTransform /////////////////////
    908 
    909 class Core_PerspectiveTransformTest : public Core_MatrixTest
    910 {
    911 public:
    912     Core_PerspectiveTransformTest();
    913 protected:
    914     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
    915     double get_success_error_level( int test_case_idx, int i, int j );
    916     void run_func();
    917     void prepare_to_validation( int test_case_idx );
    918 };
    919 
    920 
    921 Core_PerspectiveTransformTest::Core_PerspectiveTransformTest() : Core_MatrixTest( 2, 1, false, false, 2 )
    922 {
    923 }
    924 
    925 
    926 void Core_PerspectiveTransformTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
    927 {
    928     RNG& rng = ts->get_rng();
    929     int bits = cvtest::randInt(rng);
    930     int depth, cn, mattype;
    931     Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
    932 
    933     cn = CV_MAT_CN(types[INPUT][0]) + 1;
    934     depth = CV_MAT_DEPTH(types[INPUT][0]);
    935     types[INPUT][0] = types[OUTPUT][0] = types[REF_OUTPUT][0] = CV_MAKETYPE(depth, cn);
    936 
    937     mattype = depth == CV_64F ? CV_64F : bits & 1 ? CV_32F : CV_64F;
    938     types[INPUT][1] = mattype;
    939     sizes[INPUT][1] = Size(cn + 1, cn + 1);
    940 }
    941 
    942 
    943 double Core_PerspectiveTransformTest::get_success_error_level( int test_case_idx, int i, int j )
    944 {
    945     int depth = test_mat[INPUT][0].depth();
    946     return depth == CV_32F ? 1e-4 : depth == CV_64F ? 1e-8 :
    947     Core_MatrixTest::get_success_error_level(test_case_idx, i, j);
    948 }
    949 
    950 
    951 void Core_PerspectiveTransformTest::run_func()
    952 {
    953     CvMat _m = test_mat[INPUT][1];
    954     cvPerspectiveTransform( test_array[INPUT][0], test_array[OUTPUT][0], &_m );
    955 }
    956 
    957 
    958 static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMat* transmat )
    959 {
    960     int i, j, cols;
    961     int cn, depth, mat_depth;
    962     CvMat astub, bstub, *a, *b;
    963     double mat[16];
    964 
    965     a = cvGetMat( _src, &astub, 0, 0 );
    966     b = cvGetMat( _dst, &bstub, 0, 0 );
    967 
    968     cn = CV_MAT_CN(a->type);
    969     depth = CV_MAT_DEPTH(a->type);
    970     mat_depth = CV_MAT_DEPTH(transmat->type);
    971     cols = transmat->cols;
    972 
    973     // prepare cn x (cn + 1) transform matrix
    974     if( mat_depth == CV_32F )
    975     {
    976         for( i = 0; i < transmat->rows; i++ )
    977             for( j = 0; j < cols; j++ )
    978                 mat[i*cols + j] = ((float*)(transmat->data.ptr + transmat->step*i))[j];
    979     }
    980     else
    981     {
    982         assert( mat_depth == CV_64F );
    983         for( i = 0; i < transmat->rows; i++ )
    984             for( j = 0; j < cols; j++ )
    985                 mat[i*cols + j] = ((double*)(transmat->data.ptr + transmat->step*i))[j];
    986     }
    987 
    988     // transform data
    989     cols = a->cols * cn;
    990     vector<double> buf(cols);
    991 
    992     for( i = 0; i < a->rows; i++ )
    993     {
    994         uchar* src = a->data.ptr + i*a->step;
    995         uchar* dst = b->data.ptr + i*b->step;
    996 
    997         switch( depth )
    998         {
    999             case CV_32F:
   1000                 for( j = 0; j < cols; j++ )
   1001                     buf[j] = ((float*)src)[j];
   1002                 break;
   1003             case CV_64F:
   1004                 for( j = 0; j < cols; j++ )
   1005                     buf[j] = ((double*)src)[j];
   1006                 break;
   1007             default:
   1008                 assert(0);
   1009         }
   1010 
   1011         switch( cn )
   1012         {
   1013             case 2:
   1014                 for( j = 0; j < cols; j += 2 )
   1015                 {
   1016                     double t0 = buf[j]*mat[0] + buf[j+1]*mat[1] + mat[2];
   1017                     double t1 = buf[j]*mat[3] + buf[j+1]*mat[4] + mat[5];
   1018                     double w = buf[j]*mat[6] + buf[j+1]*mat[7] + mat[8];
   1019                     w = w ? 1./w : 0;
   1020                     buf[j] = t0*w;
   1021                     buf[j+1] = t1*w;
   1022                 }
   1023                 break;
   1024             case 3:
   1025                 for( j = 0; j < cols; j += 3 )
   1026                 {
   1027                     double t0 = buf[j]*mat[0] + buf[j+1]*mat[1] + buf[j+2]*mat[2] + mat[3];
   1028                     double t1 = buf[j]*mat[4] + buf[j+1]*mat[5] + buf[j+2]*mat[6] + mat[7];
   1029                     double t2 = buf[j]*mat[8] + buf[j+1]*mat[9] + buf[j+2]*mat[10] + mat[11];
   1030                     double w = buf[j]*mat[12] + buf[j+1]*mat[13] + buf[j+2]*mat[14] + mat[15];
   1031                     w = w ? 1./w : 0;
   1032                     buf[j] = t0*w;
   1033                     buf[j+1] = t1*w;
   1034                     buf[j+2] = t2*w;
   1035                 }
   1036                 break;
   1037             default:
   1038                 assert(0);
   1039         }
   1040 
   1041         switch( depth )
   1042         {
   1043             case CV_32F:
   1044                 for( j = 0; j < cols; j++ )
   1045                     ((float*)dst)[j] = (float)buf[j];
   1046                 break;
   1047             case CV_64F:
   1048                 for( j = 0; j < cols; j++ )
   1049                     ((double*)dst)[j] = buf[j];
   1050                 break;
   1051             default:
   1052                 assert(0);
   1053         }
   1054     }
   1055 }
   1056 
   1057 
   1058 void Core_PerspectiveTransformTest::prepare_to_validation( int )
   1059 {
   1060     CvMat transmat = test_mat[INPUT][1];
   1061     cvTsPerspectiveTransform( test_array[INPUT][0], test_array[REF_OUTPUT][0], &transmat );
   1062 }
   1063 
   1064 ///////////////// Mahalanobis /////////////////////
   1065 
   1066 class Core_MahalanobisTest : public Core_MatrixTest
   1067 {
   1068 public:
   1069     typedef Core_MatrixTest Base;
   1070     Core_MahalanobisTest();
   1071 protected:
   1072     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   1073     int prepare_test_case( int test_case_idx );
   1074     void run_func();
   1075     void prepare_to_validation( int test_case_idx );
   1076 };
   1077 
   1078 
   1079 Core_MahalanobisTest::Core_MahalanobisTest() : Core_MatrixTest( 3, 1, false, true, 1 )
   1080 {
   1081     test_case_count = 100;
   1082     test_array[TEMP].push_back(NULL);
   1083     test_array[TEMP].push_back(NULL);
   1084     test_array[TEMP].push_back(NULL);
   1085 }
   1086 
   1087 
   1088 void Core_MahalanobisTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
   1089 {
   1090     RNG& rng = ts->get_rng();
   1091     Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1092 
   1093     if( cvtest::randInt(rng) & 1 )
   1094         sizes[INPUT][0].width = sizes[INPUT][1].width = 1;
   1095     else
   1096         sizes[INPUT][0].height = sizes[INPUT][1].height = 1;
   1097 
   1098     sizes[TEMP][0] = sizes[TEMP][1] = sizes[INPUT][0];
   1099     sizes[INPUT][2].width = sizes[INPUT][2].height = sizes[INPUT][0].width + sizes[INPUT][0].height - 1;
   1100     sizes[TEMP][2] = sizes[INPUT][2];
   1101     types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[INPUT][0];
   1102 }
   1103 
   1104 int Core_MahalanobisTest::prepare_test_case( int test_case_idx )
   1105 {
   1106     int code = Base::prepare_test_case( test_case_idx );
   1107     if( code > 0 )
   1108     {
   1109         // make sure that the inverted "covariation" matrix is symmetrix and positively defined.
   1110         cvtest::gemm( test_mat[INPUT][2], test_mat[INPUT][2], 1., Mat(), 0., test_mat[TEMP][2], GEMM_2_T );
   1111         cvtest::copy( test_mat[TEMP][2], test_mat[INPUT][2] );
   1112     }
   1113 
   1114     return code;
   1115 }
   1116 
   1117 
   1118 void Core_MahalanobisTest::run_func()
   1119 {
   1120     test_mat[OUTPUT][0].at<Scalar>(0,0) =
   1121     cvRealScalar(cvMahalanobis(test_array[INPUT][0], test_array[INPUT][1], test_array[INPUT][2]));
   1122 }
   1123 
   1124 void Core_MahalanobisTest::prepare_to_validation( int )
   1125 {
   1126     cvtest::add( test_mat[INPUT][0], 1., test_mat[INPUT][1], -1.,
   1127                 Scalar::all(0), test_mat[TEMP][0], test_mat[TEMP][0].type() );
   1128     if( test_mat[INPUT][0].rows == 1 )
   1129         cvtest::gemm( test_mat[TEMP][0], test_mat[INPUT][2], 1.,
   1130                  Mat(), 0., test_mat[TEMP][1], 0 );
   1131     else
   1132         cvtest::gemm( test_mat[INPUT][2], test_mat[TEMP][0], 1.,
   1133                  Mat(), 0., test_mat[TEMP][1], 0 );
   1134 
   1135     test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = cvRealScalar(sqrt(cvtest::crossCorr(test_mat[TEMP][0], test_mat[TEMP][1])));
   1136 }
   1137 
   1138 
   1139 ///////////////// covarmatrix /////////////////////
   1140 
   1141 class Core_CovarMatrixTest : public Core_MatrixTest
   1142 {
   1143 public:
   1144     Core_CovarMatrixTest();
   1145 protected:
   1146     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   1147     int prepare_test_case( int test_case_idx );
   1148     void run_func();
   1149     void prepare_to_validation( int test_case_idx );
   1150     vector<void*> temp_hdrs;
   1151     vector<uchar> hdr_data;
   1152     int flags, t_flag, len, count;
   1153     bool are_images;
   1154 };
   1155 
   1156 
   1157 Core_CovarMatrixTest::Core_CovarMatrixTest() : Core_MatrixTest( 1, 1, true, false, 1 ),
   1158     flags(0), t_flag(0), len(0), count(0), are_images(false)
   1159 {
   1160     test_case_count = 100;
   1161     test_array[INPUT_OUTPUT].push_back(NULL);
   1162     test_array[REF_INPUT_OUTPUT].push_back(NULL);
   1163     test_array[TEMP].push_back(NULL);
   1164     test_array[TEMP].push_back(NULL);
   1165 }
   1166 
   1167 
   1168 void Core_CovarMatrixTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
   1169 {
   1170     RNG& rng = ts->get_rng();
   1171     int bits = cvtest::randInt(rng);
   1172     int i, single_matrix;
   1173     Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1174 
   1175     flags = bits & (CV_COVAR_NORMAL | CV_COVAR_USE_AVG | CV_COVAR_SCALE | CV_COVAR_ROWS );
   1176     single_matrix = flags & CV_COVAR_ROWS;
   1177     t_flag = (bits & 256) != 0;
   1178 
   1179     const int min_count = 2;
   1180 
   1181     if( !t_flag )
   1182     {
   1183         len = sizes[INPUT][0].width;
   1184         count = sizes[INPUT][0].height;
   1185         count = MAX(count, min_count);
   1186         sizes[INPUT][0] = Size(len, count);
   1187     }
   1188     else
   1189     {
   1190         len = sizes[INPUT][0].height;
   1191         count = sizes[INPUT][0].width;
   1192         count = MAX(count, min_count);
   1193         sizes[INPUT][0] = Size(count, len);
   1194     }
   1195 
   1196     if( single_matrix && t_flag )
   1197         flags = (flags & ~CV_COVAR_ROWS) | CV_COVAR_COLS;
   1198 
   1199     if( CV_MAT_DEPTH(types[INPUT][0]) == CV_32S )
   1200         types[INPUT][0] = (types[INPUT][0] & ~CV_MAT_DEPTH_MASK) | CV_32F;
   1201 
   1202     sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = flags & CV_COVAR_NORMAL ? Size(len,len) : Size(count,count);
   1203     sizes[INPUT_OUTPUT][0] = sizes[REF_INPUT_OUTPUT][0] = !t_flag ? Size(len,1) : Size(1,len);
   1204     sizes[TEMP][0] = sizes[INPUT][0];
   1205 
   1206     types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] =
   1207     types[OUTPUT][0] = types[REF_OUTPUT][0] = types[TEMP][0] =
   1208     CV_MAT_DEPTH(types[INPUT][0]) == CV_64F || (bits & 512) ? CV_64F : CV_32F;
   1209 
   1210     are_images = (bits & 1024) != 0;
   1211     for( i = 0; i < (single_matrix ? 1 : count); i++ )
   1212         temp_hdrs.push_back(NULL);
   1213 }
   1214 
   1215 
   1216 int Core_CovarMatrixTest::prepare_test_case( int test_case_idx )
   1217 {
   1218     int code = Core_MatrixTest::prepare_test_case( test_case_idx );
   1219     if( code > 0 )
   1220     {
   1221         int i;
   1222         int single_matrix = flags & (CV_COVAR_ROWS|CV_COVAR_COLS);
   1223         int hdr_size = are_images ? sizeof(IplImage) : sizeof(CvMat);
   1224 
   1225         hdr_data.resize(count*hdr_size);
   1226         uchar* _hdr_data = &hdr_data[0];
   1227         if( single_matrix )
   1228         {
   1229             if( !are_images )
   1230                 *((CvMat*)_hdr_data) = test_mat[INPUT][0];
   1231             else
   1232                 *((IplImage*)_hdr_data) = test_mat[INPUT][0];
   1233             temp_hdrs[0] = _hdr_data;
   1234         }
   1235         else
   1236             for( i = 0; i < count; i++ )
   1237             {
   1238                 Mat part;
   1239                 void* ptr = _hdr_data + i*hdr_size;
   1240 
   1241                 if( !t_flag )
   1242                     part = test_mat[INPUT][0].row(i);
   1243                 else
   1244                     part = test_mat[INPUT][0].col(i);
   1245 
   1246                 if( !are_images )
   1247                     *((CvMat*)ptr) = part;
   1248                 else
   1249                     *((IplImage*)ptr) = part;
   1250 
   1251                 temp_hdrs[i] = ptr;
   1252             }
   1253     }
   1254 
   1255     return code;
   1256 }
   1257 
   1258 
   1259 void Core_CovarMatrixTest::run_func()
   1260 {
   1261     cvCalcCovarMatrix( (const void**)&temp_hdrs[0], count,
   1262                       test_array[OUTPUT][0], test_array[INPUT_OUTPUT][0], flags );
   1263 }
   1264 
   1265 
   1266 void Core_CovarMatrixTest::prepare_to_validation( int )
   1267 {
   1268     Mat& avg = test_mat[REF_INPUT_OUTPUT][0];
   1269     double scale = 1.;
   1270 
   1271     if( !(flags & CV_COVAR_USE_AVG) )
   1272     {
   1273         Mat hdrs0 = cvarrToMat(temp_hdrs[0]);
   1274 
   1275         int i;
   1276         avg = Scalar::all(0);
   1277 
   1278         for( i = 0; i < count; i++ )
   1279         {
   1280             Mat vec;
   1281             if( flags & CV_COVAR_ROWS )
   1282                 vec = hdrs0.row(i);
   1283             else if( flags & CV_COVAR_COLS )
   1284                 vec = hdrs0.col(i);
   1285             else
   1286                 vec = cvarrToMat(temp_hdrs[i]);
   1287 
   1288             cvtest::add(avg, 1, vec, 1, Scalar::all(0), avg, avg.type());
   1289         }
   1290 
   1291         cvtest::add(avg, 1./count, avg, 0., Scalar::all(0), avg, avg.type());
   1292     }
   1293 
   1294     if( flags & CV_COVAR_SCALE )
   1295     {
   1296         scale = 1./count;
   1297     }
   1298 
   1299     Mat& temp0 = test_mat[TEMP][0];
   1300     cv::repeat( avg, temp0.rows/avg.rows, temp0.cols/avg.cols, temp0 );
   1301     cvtest::add( test_mat[INPUT][0], 1, temp0, -1, Scalar::all(0), temp0, temp0.type());
   1302 
   1303     cvtest::gemm( temp0, temp0, scale, Mat(), 0., test_mat[REF_OUTPUT][0],
   1304              t_flag ^ ((flags & CV_COVAR_NORMAL) != 0) ? CV_GEMM_A_T : CV_GEMM_B_T );
   1305     temp_hdrs.clear();
   1306 }
   1307 
   1308 
   1309 static void cvTsFloodWithZeros( Mat& mat, RNG& rng )
   1310 {
   1311     int k, total = mat.rows*mat.cols, type = mat.type();
   1312     int zero_total = cvtest::randInt(rng) % total;
   1313     CV_Assert( type == CV_32FC1 || type == CV_64FC1 );
   1314 
   1315     for( k = 0; k < zero_total; k++ )
   1316     {
   1317         int i = cvtest::randInt(rng) % mat.rows;
   1318         int j = cvtest::randInt(rng) % mat.cols;
   1319 
   1320         if( type == CV_32FC1 )
   1321             mat.at<float>(i,j) = 0.f;
   1322         else
   1323             mat.at<double>(i,j) = 0.;
   1324     }
   1325 }
   1326 
   1327 
   1328 ///////////////// determinant /////////////////////
   1329 
   1330 class Core_DetTest : public Core_MatrixTest
   1331 {
   1332 public:
   1333     typedef Core_MatrixTest Base;
   1334     Core_DetTest();
   1335 protected:
   1336     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   1337     double get_success_error_level( int test_case_idx, int i, int j );
   1338     void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
   1339     int prepare_test_case( int test_case_idx );
   1340     void run_func();
   1341     void prepare_to_validation( int test_case_idx );
   1342 };
   1343 
   1344 
   1345 Core_DetTest::Core_DetTest() : Core_MatrixTest( 1, 1, false, true, 1 )
   1346 {
   1347     test_case_count = 100;
   1348     max_log_array_size = 7;
   1349     test_array[TEMP].push_back(NULL);
   1350 }
   1351 
   1352 
   1353 void Core_DetTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
   1354 {
   1355     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1356 
   1357     sizes[INPUT][0].width = sizes[INPUT][0].height;
   1358     sizes[TEMP][0] = sizes[INPUT][0];
   1359     types[TEMP][0] = CV_64FC1;
   1360 }
   1361 
   1362 
   1363 void Core_DetTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
   1364 {
   1365     low = cvScalarAll(-2.);
   1366     high = cvScalarAll(2.);
   1367 }
   1368 
   1369 
   1370 double Core_DetTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
   1371 {
   1372     return CV_MAT_DEPTH(cvGetElemType(test_array[INPUT][0])) == CV_32F ? 1e-2 : 1e-5;
   1373 }
   1374 
   1375 
   1376 int Core_DetTest::prepare_test_case( int test_case_idx )
   1377 {
   1378     int code = Core_MatrixTest::prepare_test_case( test_case_idx );
   1379     if( code > 0 )
   1380         cvTsFloodWithZeros( test_mat[INPUT][0], ts->get_rng() );
   1381 
   1382     return code;
   1383 }
   1384 
   1385 
   1386 void Core_DetTest::run_func()
   1387 {
   1388     test_mat[OUTPUT][0].at<Scalar>(0,0) = cvRealScalar(cvDet(test_array[INPUT][0]));
   1389 }
   1390 
   1391 
   1392 // LU method that chooses the optimal in a column pivot element
   1393 static double cvTsLU( CvMat* a, CvMat* b=NULL, CvMat* x=NULL, int* rank=0 )
   1394 {
   1395     int i, j, k, N = a->rows, N1 = a->cols, Nm = MIN(N, N1), step = a->step/sizeof(double);
   1396     int M = b ? b->cols : 0, b_step = b ? b->step/sizeof(double) : 0;
   1397     int x_step = x ? x->step/sizeof(double) : 0;
   1398     double *a0 = a->data.db, *b0 = b ? b->data.db : 0;
   1399     double *x0 = x ? x->data.db : 0;
   1400     double t, det = 1.;
   1401     assert( CV_MAT_TYPE(a->type) == CV_64FC1 &&
   1402            (!b || CV_ARE_TYPES_EQ(a,b)) && (!x || CV_ARE_TYPES_EQ(a,x)));
   1403 
   1404     for( i = 0; i < Nm; i++ )
   1405     {
   1406         double max_val = fabs(a0[i*step + i]);
   1407         double *a1, *a2, *b1 = 0, *b2 = 0;
   1408         k = i;
   1409 
   1410         for( j = i+1; j < N; j++ )
   1411         {
   1412             t = fabs(a0[j*step + i]);
   1413             if( max_val < t )
   1414             {
   1415                 max_val = t;
   1416                 k = j;
   1417             }
   1418         }
   1419 
   1420         if( k != i )
   1421         {
   1422             for( j = i; j < N1; j++ )
   1423                 CV_SWAP( a0[i*step + j], a0[k*step + j], t );
   1424 
   1425             for( j = 0; j < M; j++ )
   1426                 CV_SWAP( b0[i*b_step + j], b0[k*b_step + j], t );
   1427             det = -det;
   1428         }
   1429 
   1430         if( max_val == 0 )
   1431         {
   1432             if( rank )
   1433                 *rank = i;
   1434             return 0.;
   1435         }
   1436 
   1437         a1 = a0 + i*step;
   1438         a2 = a1 + step;
   1439         b1 = b0 + i*b_step;
   1440         b2 = b1 + b_step;
   1441 
   1442         for( j = i+1; j < N; j++, a2 += step, b2 += b_step )
   1443         {
   1444             t = a2[i]/a1[i];
   1445             for( k = i+1; k < N1; k++ )
   1446                 a2[k] -= t*a1[k];
   1447 
   1448             for( k = 0; k < M; k++ )
   1449                 b2[k] -= t*b1[k];
   1450         }
   1451 
   1452         det *= a1[i];
   1453     }
   1454 
   1455     if( x )
   1456     {
   1457         assert( b );
   1458 
   1459         for( i = N-1; i >= 0; i-- )
   1460         {
   1461             double* a1 = a0 + i*step;
   1462             double* b1 = b0 + i*b_step;
   1463             for( j = 0; j < M; j++ )
   1464             {
   1465                 t = b1[j];
   1466                 for( k = i+1; k < N1; k++ )
   1467                     t -= a1[k]*x0[k*x_step + j];
   1468                 x0[i*x_step + j] = t/a1[i];
   1469             }
   1470         }
   1471     }
   1472 
   1473     if( rank )
   1474         *rank = i;
   1475     return det;
   1476 }
   1477 
   1478 
   1479 void Core_DetTest::prepare_to_validation( int )
   1480 {
   1481     test_mat[INPUT][0].convertTo(test_mat[TEMP][0], test_mat[TEMP][0].type());
   1482     CvMat temp0 = test_mat[TEMP][0];
   1483     test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = cvRealScalar(cvTsLU(&temp0, 0, 0));
   1484 }
   1485 
   1486 
   1487 ///////////////// invert /////////////////////
   1488 
   1489 class Core_InvertTest : public Core_MatrixTest
   1490 {
   1491 public:
   1492     typedef Core_MatrixTest Base;
   1493     Core_InvertTest();
   1494 protected:
   1495     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   1496     void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
   1497     double get_success_error_level( int test_case_idx, int i, int j );
   1498     int prepare_test_case( int test_case_idx );
   1499     void run_func();
   1500     void prepare_to_validation( int test_case_idx );
   1501     int method, rank;
   1502     double result;
   1503 };
   1504 
   1505 
   1506 Core_InvertTest::Core_InvertTest()
   1507 : Core_MatrixTest( 1, 1, false, false, 1 ), method(0), rank(0), result(0.)
   1508 {
   1509     test_case_count = 100;
   1510     max_log_array_size = 7;
   1511     test_array[TEMP].push_back(NULL);
   1512     test_array[TEMP].push_back(NULL);
   1513 }
   1514 
   1515 
   1516 void Core_InvertTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
   1517 {
   1518     RNG& rng = ts->get_rng();
   1519     int bits = cvtest::randInt(rng);
   1520     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1521     int min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height );
   1522 
   1523     if( (bits & 3) == 0 )
   1524     {
   1525         method = CV_SVD;
   1526         if( bits & 4 )
   1527         {
   1528             sizes[INPUT][0] = Size(min_size, min_size);
   1529             if( bits & 16 )
   1530                 method = CV_CHOLESKY;
   1531         }
   1532     }
   1533     else
   1534     {
   1535         method = CV_LU;
   1536         sizes[INPUT][0] = Size(min_size, min_size);
   1537     }
   1538 
   1539     sizes[TEMP][0].width = sizes[INPUT][0].height;
   1540     sizes[TEMP][0].height = sizes[INPUT][0].width;
   1541     sizes[TEMP][1] = sizes[INPUT][0];
   1542     types[TEMP][0] = types[INPUT][0];
   1543     types[TEMP][1] = CV_64FC1;
   1544     sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size(min_size, min_size);
   1545 }
   1546 
   1547 
   1548 double Core_InvertTest::get_success_error_level( int /*test_case_idx*/, int, int )
   1549 {
   1550     return CV_MAT_DEPTH(cvGetElemType(test_array[OUTPUT][0])) == CV_32F ? 1e-2 : 1e-6;
   1551 }
   1552 
   1553 int Core_InvertTest::prepare_test_case( int test_case_idx )
   1554 {
   1555     int code = Core_MatrixTest::prepare_test_case( test_case_idx );
   1556     if( code > 0 )
   1557     {
   1558         cvTsFloodWithZeros( test_mat[INPUT][0], ts->get_rng() );
   1559 
   1560         if( method == CV_CHOLESKY )
   1561         {
   1562             cvtest::gemm( test_mat[INPUT][0], test_mat[INPUT][0], 1.,
   1563                      Mat(), 0., test_mat[TEMP][0], CV_GEMM_B_T );
   1564             cvtest::copy( test_mat[TEMP][0], test_mat[INPUT][0] );
   1565         }
   1566     }
   1567 
   1568     return code;
   1569 }
   1570 
   1571 
   1572 
   1573 void Core_InvertTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
   1574 {
   1575     low = cvScalarAll(-1.);
   1576     high = cvScalarAll(1.);
   1577 }
   1578 
   1579 
   1580 void Core_InvertTest::run_func()
   1581 {
   1582     result = cvInvert(test_array[INPUT][0], test_array[TEMP][0], method);
   1583 }
   1584 
   1585 
   1586 static double cvTsSVDet( CvMat* mat, double* ratio )
   1587 {
   1588     int type = CV_MAT_TYPE(mat->type);
   1589     int i, nm = MIN( mat->rows, mat->cols );
   1590     CvMat* w = cvCreateMat( nm, 1, type );
   1591     double det = 1.;
   1592 
   1593     cvSVD( mat, w, 0, 0, 0 );
   1594 
   1595     if( type == CV_32FC1 )
   1596     {
   1597         for( i = 0; i < nm; i++ )
   1598             det *= w->data.fl[i];
   1599         *ratio = w->data.fl[nm-1] < FLT_EPSILON ? 0 : w->data.fl[nm-1]/w->data.fl[0];
   1600     }
   1601     else
   1602     {
   1603         for( i = 0; i < nm; i++ )
   1604             det *= w->data.db[i];
   1605         *ratio = w->data.db[nm-1] < FLT_EPSILON ? 0 : w->data.db[nm-1]/w->data.db[0];
   1606     }
   1607 
   1608     cvReleaseMat( &w );
   1609     return det;
   1610 }
   1611 
   1612 void Core_InvertTest::prepare_to_validation( int )
   1613 {
   1614     Mat& input = test_mat[INPUT][0];
   1615     Mat& temp0 = test_mat[TEMP][0];
   1616     Mat& temp1 = test_mat[TEMP][1];
   1617     Mat& dst0 = test_mat[REF_OUTPUT][0];
   1618     Mat& dst = test_mat[OUTPUT][0];
   1619     CvMat _input = input;
   1620     double ratio = 0, det = cvTsSVDet( &_input, &ratio );
   1621     double threshold = (input.depth() == CV_32F ? FLT_EPSILON : DBL_EPSILON)*1000;
   1622 
   1623     cvtest::convert( input, temp1, temp1.type() );
   1624 
   1625     if( det < threshold ||
   1626        ((method == CV_LU || method == CV_CHOLESKY) && (result == 0 || ratio < threshold)) ||
   1627        ((method == CV_SVD || method == CV_SVD_SYM) && result < threshold) )
   1628     {
   1629         dst = Scalar::all(0);
   1630         dst0 = Scalar::all(0);
   1631         return;
   1632     }
   1633 
   1634     if( input.rows >= input.cols )
   1635         cvtest::gemm( temp0, input, 1., Mat(), 0., dst, 0 );
   1636     else
   1637         cvtest::gemm( input, temp0, 1., Mat(), 0., dst, 0 );
   1638 
   1639     cv::setIdentity( dst0, Scalar::all(1) );
   1640 }
   1641 
   1642 
   1643 ///////////////// solve /////////////////////
   1644 
   1645 class Core_SolveTest : public Core_MatrixTest
   1646 {
   1647 public:
   1648     typedef Core_MatrixTest Base;
   1649     Core_SolveTest();
   1650 protected:
   1651     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   1652     void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
   1653     double get_success_error_level( int test_case_idx, int i, int j );
   1654     int prepare_test_case( int test_case_idx );
   1655     void run_func();
   1656     void prepare_to_validation( int test_case_idx );
   1657     int method, rank;
   1658     double result;
   1659 };
   1660 
   1661 
   1662 Core_SolveTest::Core_SolveTest() : Core_MatrixTest( 2, 1, false, false, 1 ), method(0), rank(0), result(0.)
   1663 {
   1664     test_case_count = 100;
   1665     max_log_array_size = 7;
   1666     test_array[TEMP].push_back(NULL);
   1667     test_array[TEMP].push_back(NULL);
   1668 }
   1669 
   1670 
   1671 void Core_SolveTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
   1672 {
   1673     RNG& rng = ts->get_rng();
   1674     int bits = cvtest::randInt(rng);
   1675     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1676     CvSize in_sz = sizes[INPUT][0];
   1677     if( in_sz.width > in_sz.height )
   1678         in_sz = cvSize(in_sz.height, in_sz.width);
   1679     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1680     sizes[INPUT][0] = in_sz;
   1681     int min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height );
   1682 
   1683     if( (bits & 3) == 0 )
   1684     {
   1685         method = CV_SVD;
   1686         if( bits & 4 )
   1687         {
   1688             sizes[INPUT][0] = Size(min_size, min_size);
   1689             /*if( bits & 8 )
   1690              method = CV_SVD_SYM;*/
   1691         }
   1692     }
   1693     else
   1694     {
   1695         method = CV_LU;
   1696         sizes[INPUT][0] = Size(min_size, min_size);
   1697     }
   1698 
   1699     sizes[INPUT][1].height = sizes[INPUT][0].height;
   1700     sizes[TEMP][0].width = sizes[INPUT][1].width;
   1701     sizes[TEMP][0].height = sizes[INPUT][0].width;
   1702     sizes[TEMP][1] = sizes[INPUT][0];
   1703     types[TEMP][0] = types[INPUT][0];
   1704     types[TEMP][1] = CV_64FC1;
   1705     sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size(sizes[INPUT][1].width, min_size);
   1706 }
   1707 
   1708 
   1709 int Core_SolveTest::prepare_test_case( int test_case_idx )
   1710 {
   1711     int code = Core_MatrixTest::prepare_test_case( test_case_idx );
   1712 
   1713     /*if( method == CV_SVD_SYM )
   1714      {
   1715      cvTsGEMM( test_array[INPUT][0], test_array[INPUT][0], 1.,
   1716      0, 0., test_array[TEMP][0], CV_GEMM_B_T );
   1717      cvTsCopy( test_array[TEMP][0], test_array[INPUT][0] );
   1718      }*/
   1719 
   1720     return code;
   1721 }
   1722 
   1723 
   1724 void Core_SolveTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
   1725 {
   1726     low = cvScalarAll(-1.);
   1727     high = cvScalarAll(1.);
   1728 }
   1729 
   1730 
   1731 double Core_SolveTest::get_success_error_level( int /*test_case_idx*/, int, int )
   1732 {
   1733     return CV_MAT_DEPTH(cvGetElemType(test_array[OUTPUT][0])) == CV_32F ? 5e-2 : 1e-8;
   1734 }
   1735 
   1736 
   1737 void Core_SolveTest::run_func()
   1738 {
   1739     result = cvSolve(test_array[INPUT][0], test_array[INPUT][1], test_array[TEMP][0], method);
   1740 }
   1741 
   1742 void Core_SolveTest::prepare_to_validation( int )
   1743 {
   1744     //int rank = test_mat[REF_OUTPUT][0].rows;
   1745     Mat& input = test_mat[INPUT][0];
   1746     Mat& dst = test_mat[OUTPUT][0];
   1747     Mat& dst0 = test_mat[REF_OUTPUT][0];
   1748 
   1749     if( method == CV_LU )
   1750     {
   1751         if( result == 0 )
   1752         {
   1753             Mat& temp1 = test_mat[TEMP][1];
   1754             cvtest::convert(input, temp1, temp1.type());
   1755             dst = Scalar::all(0);
   1756             CvMat _temp1 = temp1;
   1757             double det = cvTsLU( &_temp1, 0, 0 );
   1758             dst0 = Scalar::all(det != 0);
   1759             return;
   1760         }
   1761 
   1762         double threshold = (input.type() == CV_32F ? FLT_EPSILON : DBL_EPSILON)*1000;
   1763         CvMat _input = input;
   1764         double ratio = 0, det = cvTsSVDet( &_input, &ratio );
   1765         if( det < threshold || ratio < threshold )
   1766         {
   1767             dst = Scalar::all(0);
   1768             dst0 = Scalar::all(0);
   1769             return;
   1770         }
   1771     }
   1772 
   1773     Mat* pdst = input.rows <= input.cols ? &test_mat[OUTPUT][0] : &test_mat[INPUT][1];
   1774 
   1775     cvtest::gemm( input, test_mat[TEMP][0], 1., test_mat[INPUT][1], -1., *pdst, 0 );
   1776     if( pdst != &dst )
   1777         cvtest::gemm( input, *pdst, 1., Mat(), 0., dst, CV_GEMM_A_T );
   1778     dst0 = Scalar::all(0);
   1779 }
   1780 
   1781 
   1782 ///////////////// SVD /////////////////////
   1783 
   1784 class Core_SVDTest : public Core_MatrixTest
   1785 {
   1786 public:
   1787     typedef Core_MatrixTest Base;
   1788     Core_SVDTest();
   1789 protected:
   1790     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   1791     double get_success_error_level( int test_case_idx, int i, int j );
   1792     void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
   1793     int prepare_test_case( int test_case_idx );
   1794     void run_func();
   1795     void prepare_to_validation( int test_case_idx );
   1796     int flags;
   1797     bool have_u, have_v, symmetric, compact, vector_w;
   1798 };
   1799 
   1800 
   1801 Core_SVDTest::Core_SVDTest() :
   1802 Core_MatrixTest( 1, 4, false, false, 1 ),
   1803 flags(0), have_u(false), have_v(false), symmetric(false), compact(false), vector_w(false)
   1804 {
   1805     test_case_count = 100;
   1806     max_log_array_size = 8;
   1807     test_array[TEMP].push_back(NULL);
   1808     test_array[TEMP].push_back(NULL);
   1809     test_array[TEMP].push_back(NULL);
   1810     test_array[TEMP].push_back(NULL);
   1811 }
   1812 
   1813 
   1814 void Core_SVDTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
   1815 {
   1816     RNG& rng = ts->get_rng();
   1817     int bits = cvtest::randInt(rng);
   1818     Core_MatrixTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   1819     int min_size, i, m, n;
   1820 
   1821     min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height );
   1822 
   1823     flags = bits & (CV_SVD_MODIFY_A+CV_SVD_U_T+CV_SVD_V_T);
   1824     have_u = (bits & 8) != 0;
   1825     have_v = (bits & 16) != 0;
   1826     symmetric = (bits & 32) != 0;
   1827     compact = (bits & 64) != 0;
   1828     vector_w = (bits & 128) != 0;
   1829 
   1830     if( symmetric )
   1831         sizes[INPUT][0] = Size(min_size, min_size);
   1832 
   1833     m = sizes[INPUT][0].height;
   1834     n = sizes[INPUT][0].width;
   1835 
   1836     if( compact )
   1837         sizes[TEMP][0] = Size(min_size, min_size);
   1838     else
   1839         sizes[TEMP][0] = sizes[INPUT][0];
   1840     sizes[TEMP][3] = Size(0,0);
   1841 
   1842     if( vector_w )
   1843     {
   1844         sizes[TEMP][3] = sizes[TEMP][0];
   1845         if( bits & 256 )
   1846             sizes[TEMP][0] = Size(1, min_size);
   1847         else
   1848             sizes[TEMP][0] = Size(min_size, 1);
   1849     }
   1850 
   1851     if( have_u )
   1852     {
   1853         sizes[TEMP][1] = compact ? Size(min_size, m) : Size(m, m);
   1854 
   1855         if( flags & CV_SVD_U_T )
   1856             CV_SWAP( sizes[TEMP][1].width, sizes[TEMP][1].height, i );
   1857     }
   1858     else
   1859         sizes[TEMP][1] = Size(0,0);
   1860 
   1861     if( have_v )
   1862     {
   1863         sizes[TEMP][2] = compact ? Size(n, min_size) : Size(n, n);
   1864 
   1865         if( !(flags & CV_SVD_V_T) )
   1866             CV_SWAP( sizes[TEMP][2].width, sizes[TEMP][2].height, i );
   1867     }
   1868     else
   1869         sizes[TEMP][2] = Size(0,0);
   1870 
   1871     types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[TEMP][3] = types[INPUT][0];
   1872     types[OUTPUT][0] = types[OUTPUT][1] = types[OUTPUT][2] = types[INPUT][0];
   1873     types[OUTPUT][3] = CV_8UC1;
   1874     sizes[OUTPUT][0] = !have_u || !have_v ? Size(0,0) : sizes[INPUT][0];
   1875     sizes[OUTPUT][1] = !have_u ? Size(0,0) : compact ? Size(min_size,min_size) : Size(m,m);
   1876     sizes[OUTPUT][2] = !have_v ? Size(0,0) : compact ? Size(min_size,min_size) : Size(n,n);
   1877     sizes[OUTPUT][3] = Size(min_size,1);
   1878 
   1879     for( i = 0; i < 4; i++ )
   1880     {
   1881         sizes[REF_OUTPUT][i] = sizes[OUTPUT][i];
   1882         types[REF_OUTPUT][i] = types[OUTPUT][i];
   1883     }
   1884 }
   1885 
   1886 
   1887 int Core_SVDTest::prepare_test_case( int test_case_idx )
   1888 {
   1889     int code = Core_MatrixTest::prepare_test_case( test_case_idx );
   1890     if( code > 0 )
   1891     {
   1892         Mat& input = test_mat[INPUT][0];
   1893         cvTsFloodWithZeros( input, ts->get_rng() );
   1894 
   1895         if( symmetric && (have_u || have_v) )
   1896         {
   1897             Mat& temp = test_mat[TEMP][have_u ? 1 : 2];
   1898             cvtest::gemm( input, input, 1., Mat(), 0., temp, CV_GEMM_B_T );
   1899             cvtest::copy( temp, input );
   1900         }
   1901 
   1902         if( (flags & CV_SVD_MODIFY_A) && test_array[OUTPUT][0] )
   1903             cvtest::copy( input, test_mat[OUTPUT][0] );
   1904     }
   1905 
   1906     return code;
   1907 }
   1908 
   1909 
   1910 void Core_SVDTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
   1911 {
   1912     low = cvScalarAll(-2.);
   1913     high = cvScalarAll(2.);
   1914 }
   1915 
   1916 double Core_SVDTest::get_success_error_level( int test_case_idx, int i, int j )
   1917 {
   1918     int input_depth = CV_MAT_DEPTH(cvGetElemType( test_array[INPUT][0] ));
   1919     double input_precision = input_depth < CV_32F ? 0 : input_depth == CV_32F ? 1e-5 : 5e-11;
   1920     double output_precision = Base::get_success_error_level( test_case_idx, i, j );
   1921     return MAX(input_precision, output_precision);
   1922 }
   1923 
   1924 void Core_SVDTest::run_func()
   1925 {
   1926     CvArr* src = test_array[!(flags & CV_SVD_MODIFY_A) ? INPUT : OUTPUT][0];
   1927     if( !src )
   1928         src = test_array[INPUT][0];
   1929     cvSVD( src, test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2], flags );
   1930 }
   1931 
   1932 
   1933 void Core_SVDTest::prepare_to_validation( int /*test_case_idx*/ )
   1934 {
   1935     Mat& input = test_mat[INPUT][0];
   1936     int depth = input.depth();
   1937     int i, m = input.rows, n = input.cols, min_size = MIN(m, n);
   1938     Mat *src, *dst, *w;
   1939     double prev = 0, threshold = depth == CV_32F ? FLT_EPSILON : DBL_EPSILON;
   1940 
   1941     if( have_u )
   1942     {
   1943         src = &test_mat[TEMP][1];
   1944         dst = &test_mat[OUTPUT][1];
   1945         cvtest::gemm( *src, *src, 1., Mat(), 0., *dst, src->rows == dst->rows ? CV_GEMM_B_T : CV_GEMM_A_T );
   1946         cv::setIdentity( test_mat[REF_OUTPUT][1], Scalar::all(1.) );
   1947     }
   1948 
   1949     if( have_v )
   1950     {
   1951         src = &test_mat[TEMP][2];
   1952         dst = &test_mat[OUTPUT][2];
   1953         cvtest::gemm( *src, *src, 1., Mat(), 0., *dst, src->rows == dst->rows ? CV_GEMM_B_T : CV_GEMM_A_T );
   1954         cv::setIdentity( test_mat[REF_OUTPUT][2], Scalar::all(1.) );
   1955     }
   1956 
   1957     w = &test_mat[TEMP][0];
   1958     for( i = 0; i < min_size; i++ )
   1959     {
   1960         double normval = 0, aii;
   1961         if( w->rows > 1 && w->cols > 1 )
   1962         {
   1963             normval = cvtest::norm( w->row(i), NORM_L1 );
   1964             aii = depth == CV_32F ? w->at<float>(i,i) : w->at<double>(i,i);
   1965         }
   1966         else
   1967         {
   1968             normval = aii = depth == CV_32F ? w->at<float>(i) : w->at<double>(i);
   1969         }
   1970 
   1971         normval = fabs(normval - aii);
   1972         test_mat[OUTPUT][3].at<uchar>(i) = aii >= 0 && normval < threshold && (i == 0 || aii <= prev);
   1973         prev = aii;
   1974     }
   1975 
   1976     test_mat[REF_OUTPUT][3] = Scalar::all(1);
   1977 
   1978     if( have_u && have_v )
   1979     {
   1980         if( vector_w )
   1981         {
   1982             test_mat[TEMP][3] = Scalar::all(0);
   1983             for( i = 0; i < min_size; i++ )
   1984             {
   1985                 double val = depth == CV_32F ? w->at<float>(i) : w->at<double>(i);
   1986                 cvSetReal2D( test_array[TEMP][3], i, i, val );
   1987             }
   1988             w = &test_mat[TEMP][3];
   1989         }
   1990 
   1991         if( m >= n )
   1992         {
   1993             cvtest::gemm( test_mat[TEMP][1], *w, 1., Mat(), 0., test_mat[REF_OUTPUT][0],
   1994                      flags & CV_SVD_U_T ? CV_GEMM_A_T : 0 );
   1995             cvtest::gemm( test_mat[REF_OUTPUT][0], test_mat[TEMP][2], 1., Mat(), 0.,
   1996                      test_mat[OUTPUT][0], flags & CV_SVD_V_T ? 0 : CV_GEMM_B_T );
   1997         }
   1998         else
   1999         {
   2000             cvtest::gemm( *w, test_mat[TEMP][2], 1., Mat(), 0., test_mat[REF_OUTPUT][0],
   2001                      flags & CV_SVD_V_T ? 0 : CV_GEMM_B_T );
   2002             cvtest::gemm( test_mat[TEMP][1], test_mat[REF_OUTPUT][0], 1., Mat(), 0.,
   2003                      test_mat[OUTPUT][0], flags & CV_SVD_U_T ? CV_GEMM_A_T : 0 );
   2004         }
   2005 
   2006         cvtest::copy( test_mat[INPUT][0], test_mat[REF_OUTPUT][0] );
   2007     }
   2008 }
   2009 
   2010 
   2011 
   2012 ///////////////// SVBkSb /////////////////////
   2013 
   2014 class Core_SVBkSbTest : public Core_MatrixTest
   2015 {
   2016 public:
   2017     typedef Core_MatrixTest Base;
   2018     Core_SVBkSbTest();
   2019 protected:
   2020     void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
   2021     double get_success_error_level( int test_case_idx, int i, int j );
   2022     void get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high );
   2023     int prepare_test_case( int test_case_idx );
   2024     void run_func();
   2025     void prepare_to_validation( int test_case_idx );
   2026     int flags;
   2027     bool have_b, symmetric, compact, vector_w;
   2028 };
   2029 
   2030 
   2031 Core_SVBkSbTest::Core_SVBkSbTest() : Core_MatrixTest( 2, 1, false, false, 1 ),
   2032 flags(0), have_b(false), symmetric(false), compact(false), vector_w(false)
   2033 {
   2034     test_case_count = 100;
   2035     test_array[TEMP].push_back(NULL);
   2036     test_array[TEMP].push_back(NULL);
   2037     test_array[TEMP].push_back(NULL);
   2038 }
   2039 
   2040 
   2041 void Core_SVBkSbTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes,
   2042                                                       vector<vector<int> >& types )
   2043 {
   2044     RNG& rng = ts->get_rng();
   2045     int bits = cvtest::randInt(rng);
   2046     Base::get_test_array_types_and_sizes( test_case_idx, sizes, types );
   2047     int min_size, i, m, n;
   2048     CvSize b_size;
   2049 
   2050     min_size = MIN( sizes[INPUT][0].width, sizes[INPUT][0].height );
   2051 
   2052     flags = bits & (CV_SVD_MODIFY_A+CV_SVD_U_T+CV_SVD_V_T);
   2053     have_b = (bits & 16) != 0;
   2054     symmetric = (bits & 32) != 0;
   2055     compact = (bits & 64) != 0;
   2056     vector_w = (bits & 128) != 0;
   2057 
   2058     if( symmetric )
   2059         sizes[INPUT][0] = Size(min_size, min_size);
   2060 
   2061     m = sizes[INPUT][0].height;
   2062     n = sizes[INPUT][0].width;
   2063 
   2064     sizes[INPUT][1] = Size(0,0);
   2065     b_size = Size(m,m);
   2066     if( have_b )
   2067     {
   2068         sizes[INPUT][1].height = sizes[INPUT][0].height;
   2069         sizes[INPUT][1].width = cvtest::randInt(rng) % 100 + 1;
   2070         b_size = sizes[INPUT][1];
   2071     }
   2072 
   2073     if( compact )
   2074         sizes[TEMP][0] = Size(min_size, min_size);
   2075     else
   2076         sizes[TEMP][0] = sizes[INPUT][0];
   2077 
   2078     if( vector_w )
   2079     {
   2080         if( bits & 256 )
   2081             sizes[TEMP][0] = Size(1, min_size);
   2082         else
   2083             sizes[TEMP][0] = Size(min_size, 1);
   2084     }
   2085 
   2086     sizes[TEMP][1] = compact ? Size(min_size, m) : Size(m, m);
   2087 
   2088     if( flags & CV_SVD_U_T )
   2089         CV_SWAP( sizes[TEMP][1].width, sizes[TEMP][1].height, i );
   2090 
   2091     sizes[TEMP][2] = compact ? Size(n, min_size) : Size(n, n);
   2092 
   2093     if( !(flags & CV_SVD_V_T) )
   2094         CV_SWAP( sizes[TEMP][2].width, sizes[TEMP][2].height, i );
   2095 
   2096     types[TEMP][0] = types[TEMP][1] = types[TEMP][2] = types[INPUT][0];
   2097     types[OUTPUT][0] = types[REF_OUTPUT][0] = types[INPUT][0];
   2098     sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = Size( b_size.width, n );
   2099 }
   2100 
   2101 
   2102 int Core_SVBkSbTest::prepare_test_case( int test_case_idx )
   2103 {
   2104     int code = Base::prepare_test_case( test_case_idx );
   2105     if( code > 0 )
   2106     {
   2107         Mat& input = test_mat[INPUT][0];
   2108         cvTsFloodWithZeros( input, ts->get_rng() );
   2109 
   2110         if( symmetric )
   2111         {
   2112             Mat& temp = test_mat[TEMP][1];
   2113             cvtest::gemm( input, input, 1., Mat(), 0., temp, CV_GEMM_B_T );
   2114             cvtest::copy( temp, input );
   2115         }
   2116 
   2117         CvMat _input = input;
   2118         cvSVD( &_input, test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2], flags );
   2119     }
   2120 
   2121     return code;
   2122 }
   2123 
   2124 
   2125 void Core_SVBkSbTest::get_minmax_bounds( int /*i*/, int /*j*/, int /*type*/, Scalar& low, Scalar& high )
   2126 {
   2127     low = cvScalarAll(-2.);
   2128     high = cvScalarAll(2.);
   2129 }
   2130 
   2131 
   2132 double Core_SVBkSbTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
   2133 {
   2134     return CV_MAT_DEPTH(cvGetElemType(test_array[INPUT][0])) == CV_32F ? 1e-3 : 1e-7;
   2135 }
   2136 
   2137 
   2138 void Core_SVBkSbTest::run_func()
   2139 {
   2140     cvSVBkSb( test_array[TEMP][0], test_array[TEMP][1], test_array[TEMP][2],
   2141              test_array[INPUT][1], test_array[OUTPUT][0], flags );
   2142 }
   2143 
   2144 
   2145 void Core_SVBkSbTest::prepare_to_validation( int )
   2146 {
   2147     Mat& input = test_mat[INPUT][0];
   2148     int i, m = input.rows, n = input.cols, min_size = MIN(m, n);
   2149     bool is_float = input.type() == CV_32F;
   2150     Size w_size = compact ? Size(min_size,min_size) : Size(m,n);
   2151     Mat& w = test_mat[TEMP][0];
   2152     Mat wdb( w_size.height, w_size.width, CV_64FC1 );
   2153     CvMat _w = w, _wdb = wdb;
   2154     // use exactly the same threshold as in icvSVD... ,
   2155     // so the changes in the library and here should be synchronized.
   2156     double threshold = cv::sum(w)[0]*(DBL_EPSILON*2);//(is_float ? FLT_EPSILON*10 : DBL_EPSILON*2);
   2157 
   2158     wdb = Scalar::all(0);
   2159     for( i = 0; i < min_size; i++ )
   2160     {
   2161         double wii = vector_w ? cvGetReal1D(&_w,i) : cvGetReal2D(&_w,i,i);
   2162         cvSetReal2D( &_wdb, i, i, wii > threshold ? 1./wii : 0. );
   2163     }
   2164 
   2165     Mat u = test_mat[TEMP][1];
   2166     Mat v = test_mat[TEMP][2];
   2167     Mat b = test_mat[INPUT][1];
   2168 
   2169     if( is_float )
   2170     {
   2171         test_mat[TEMP][1].convertTo(u, CV_64F);
   2172         test_mat[TEMP][2].convertTo(v, CV_64F);
   2173         if( !b.empty() )
   2174             test_mat[INPUT][1].convertTo(b, CV_64F);
   2175     }
   2176 
   2177     Mat t0, t1;
   2178 
   2179     if( !b.empty() )
   2180         cvtest::gemm( u, b, 1., Mat(), 0., t0, !(flags & CV_SVD_U_T) ? CV_GEMM_A_T : 0 );
   2181     else if( flags & CV_SVD_U_T )
   2182         cvtest::copy( u, t0 );
   2183     else
   2184         cvtest::transpose( u, t0 );
   2185 
   2186     cvtest::gemm( wdb, t0, 1, Mat(), 0, t1, 0 );
   2187 
   2188     cvtest::gemm( v, t1, 1, Mat(), 0, t0, flags & CV_SVD_V_T ? CV_GEMM_A_T : 0 );
   2189     Mat& dst0 = test_mat[REF_OUTPUT][0];
   2190     t0.convertTo(dst0, dst0.type() );
   2191 }
   2192 
   2193 
   2194 typedef std::complex<double> complex_type;
   2195 
   2196 struct pred_complex
   2197 {
   2198     bool operator() (const complex_type& lhs, const complex_type& rhs) const
   2199     {
   2200         return fabs(lhs.real() - rhs.real()) > fabs(rhs.real())*FLT_EPSILON ? lhs.real() < rhs.real() : lhs.imag() < rhs.imag();
   2201     }
   2202 };
   2203 
   2204 struct pred_double
   2205 {
   2206     bool operator() (const double& lhs, const double& rhs) const
   2207     {
   2208         return lhs < rhs;
   2209     }
   2210 };
   2211 
   2212 class Core_SolvePolyTest : public cvtest::BaseTest
   2213 {
   2214 public:
   2215     Core_SolvePolyTest();
   2216     ~Core_SolvePolyTest();
   2217 protected:
   2218     virtual void run( int start_from );
   2219 };
   2220 
   2221 Core_SolvePolyTest::Core_SolvePolyTest() {}
   2222 
   2223 Core_SolvePolyTest::~Core_SolvePolyTest() {}
   2224 
   2225 void Core_SolvePolyTest::run( int )
   2226 {
   2227     RNG& rng = ts->get_rng();
   2228     int fig = 100;
   2229     double range = 50;
   2230     double err_eps = 1e-4;
   2231 
   2232     for (int idx = 0, max_idx = 1000, progress = 0; idx < max_idx; ++idx)
   2233     {
   2234         progress = update_progress(progress, idx-1, max_idx, 0);
   2235         int n = cvtest::randInt(rng) % 13 + 1;
   2236         std::vector<complex_type> r(n), ar(n), c(n + 1, 0);
   2237         std::vector<double> a(n + 1), u(n * 2), ar1(n), ar2(n);
   2238 
   2239         int rr_odds = 3; // odds that we get a real root
   2240         for (int j = 0; j < n;)
   2241         {
   2242             if (cvtest::randInt(rng) % rr_odds == 0 || j == n - 1)
   2243                 r[j++] = cvtest::randReal(rng) * range;
   2244             else
   2245             {
   2246                 r[j] = complex_type(cvtest::randReal(rng) * range,
   2247                                     cvtest::randReal(rng) * range + 1);
   2248                 r[j + 1] = std::conj(r[j]);
   2249                 j += 2;
   2250             }
   2251         }
   2252 
   2253         for (int j = 0, k = 1 << n, jj, kk; j < k; ++j)
   2254         {
   2255             int p = 0;
   2256             complex_type v(1);
   2257             for (jj = 0, kk = 1; jj < n && !(j & kk); ++jj, ++p, kk <<= 1)
   2258                 ;
   2259             for (; jj < n; ++jj, kk <<= 1)
   2260             {
   2261                 if (j & kk)
   2262                     v *= -r[jj];
   2263                 else
   2264                     ++p;
   2265             }
   2266             c[p] += v;
   2267         }
   2268 
   2269         bool pass = false;
   2270         double div = 0, s = 0;
   2271         int cubic_case = idx & 1;
   2272         for (int maxiter = 100; !pass && maxiter < 10000; maxiter *= 2, cubic_case = (cubic_case + 1) % 2)
   2273         {
   2274             for (int j = 0; j < n + 1; ++j)
   2275                 a[j] = c[j].real();
   2276 
   2277             CvMat amat, umat;
   2278             cvInitMatHeader(&amat, n + 1, 1, CV_64FC1, &a[0]);
   2279             cvInitMatHeader(&umat, n, 1, CV_64FC2, &u[0]);
   2280             cvSolvePoly(&amat, &umat, maxiter, fig);
   2281 
   2282             for (int j = 0; j < n; ++j)
   2283                 ar[j] = complex_type(u[j * 2], u[j * 2 + 1]);
   2284 
   2285             std::sort(r.begin(), r.end(), pred_complex());
   2286             std::sort(ar.begin(), ar.end(), pred_complex());
   2287 
   2288             pass = true;
   2289             if( n == 3 )
   2290             {
   2291                 ar2.resize(n);
   2292                 cv::Mat _umat2(3, 1, CV_64F, &ar2[0]), umat2 = _umat2;
   2293                 cvFlip(&amat, &amat, 0);
   2294                 int nr2;
   2295                 if( cubic_case == 0 )
   2296                     nr2 = cv::solveCubic(cv::cvarrToMat(&amat),umat2);
   2297                 else
   2298                     nr2 = cv::solveCubic(cv::Mat_<float>(cv::cvarrToMat(&amat)), umat2);
   2299                 cvFlip(&amat, &amat, 0);
   2300                 if(nr2 > 0)
   2301                     std::sort(ar2.begin(), ar2.begin()+nr2, pred_double());
   2302                 ar2.resize(nr2);
   2303 
   2304                 int nr1 = 0;
   2305                 for(int j = 0; j < n; j++)
   2306                     if( fabs(r[j].imag()) < DBL_EPSILON )
   2307                         ar1[nr1++] = r[j].real();
   2308 
   2309                 pass = pass && nr1 == nr2;
   2310                 if( nr2 > 0 )
   2311                 {
   2312                     div = s = 0;
   2313                     for(int j = 0; j < nr1; j++)
   2314                     {
   2315                         s += fabs(ar1[j]);
   2316                         div += fabs(ar1[j] - ar2[j]);
   2317                     }
   2318                     div /= s;
   2319                     pass = pass && div < err_eps;
   2320                 }
   2321             }
   2322 
   2323             div = s = 0;
   2324             for (int j = 0; j < n; ++j)
   2325             {
   2326                 s += fabs(r[j].real()) + fabs(r[j].imag());
   2327                 div += sqrt(pow(r[j].real() - ar[j].real(), 2) + pow(r[j].imag() - ar[j].imag(), 2));
   2328             }
   2329             div /= s;
   2330             pass = pass && div < err_eps;
   2331         }
   2332 
   2333         if (!pass)
   2334         {
   2335             ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
   2336             ts->printf( cvtest::TS::LOG, "too big diff = %g\n", div );
   2337 
   2338             for (size_t j=0;j<ar2.size();++j)
   2339                 ts->printf( cvtest::TS::LOG, "ar2[%d]=%g\n", j, ar2[j]);
   2340             ts->printf(cvtest::TS::LOG, "\n");
   2341 
   2342             for (size_t j=0;j<r.size();++j)
   2343                 ts->printf( cvtest::TS::LOG, "r[%d]=(%g, %g)\n", j, r[j].real(), r[j].imag());
   2344             ts->printf( cvtest::TS::LOG, "\n" );
   2345             for (size_t j=0;j<ar.size();++j)
   2346                 ts->printf( cvtest::TS::LOG, "ar[%d]=(%g, %g)\n", j, ar[j].real(), ar[j].imag());
   2347             break;
   2348         }
   2349     }
   2350 }
   2351 
   2352 class Core_PhaseTest : public cvtest::BaseTest
   2353 {
   2354 public:
   2355     Core_PhaseTest() {}
   2356     ~Core_PhaseTest() {}
   2357 protected:
   2358     virtual void run(int)
   2359     {
   2360         const float maxAngleDiff = 0.5; //in degrees
   2361         const int axisCount = 8;
   2362         const int dim = theRNG().uniform(1,10);
   2363         const float scale = theRNG().uniform(1.f, 100.f);
   2364         Mat x(axisCount + 1, dim, CV_32FC1),
   2365             y(axisCount + 1, dim, CV_32FC1);
   2366         Mat anglesInDegrees(axisCount + 1, dim, CV_32FC1);
   2367 
   2368         // fill the data
   2369         x.row(0).setTo(Scalar(0));
   2370         y.row(0).setTo(Scalar(0));
   2371         anglesInDegrees.row(0).setTo(Scalar(0));
   2372 
   2373         x.row(1).setTo(Scalar(scale));
   2374         y.row(1).setTo(Scalar(0));
   2375         anglesInDegrees.row(1).setTo(Scalar(0));
   2376 
   2377         x.row(2).setTo(Scalar(scale));
   2378         y.row(2).setTo(Scalar(scale));
   2379         anglesInDegrees.row(2).setTo(Scalar(45));
   2380 
   2381         x.row(3).setTo(Scalar(0));
   2382         y.row(3).setTo(Scalar(scale));
   2383         anglesInDegrees.row(3).setTo(Scalar(90));
   2384 
   2385         x.row(4).setTo(Scalar(-scale));
   2386         y.row(4).setTo(Scalar(scale));
   2387         anglesInDegrees.row(4).setTo(Scalar(135));
   2388 
   2389         x.row(5).setTo(Scalar(-scale));
   2390         y.row(5).setTo(Scalar(0));
   2391         anglesInDegrees.row(5).setTo(Scalar(180));
   2392 
   2393         x.row(6).setTo(Scalar(-scale));
   2394         y.row(6).setTo(Scalar(-scale));
   2395         anglesInDegrees.row(6).setTo(Scalar(225));
   2396 
   2397         x.row(7).setTo(Scalar(0));
   2398         y.row(7).setTo(Scalar(-scale));
   2399         anglesInDegrees.row(7).setTo(Scalar(270));
   2400 
   2401         x.row(8).setTo(Scalar(scale));
   2402         y.row(8).setTo(Scalar(-scale));
   2403         anglesInDegrees.row(8).setTo(Scalar(315));
   2404 
   2405         Mat resInRad, resInDeg;
   2406         phase(x, y, resInRad, false);
   2407         phase(x, y, resInDeg, true);
   2408 
   2409         CV_Assert(resInRad.size() == x.size());
   2410         CV_Assert(resInRad.type() == x.type());
   2411 
   2412         CV_Assert(resInDeg.size() == x.size());
   2413         CV_Assert(resInDeg.type() == x.type());
   2414 
   2415         // check the result
   2416         int outOfRangeCount = countNonZero((resInDeg > 360) | (resInDeg < 0));
   2417         if(outOfRangeCount > 0)
   2418         {
   2419             ts->printf(cvtest::TS::LOG, "There are result angles that are out of range [0, 360] (part of them is %f)\n",
   2420                        static_cast<float>(outOfRangeCount)/resInDeg.total());
   2421             ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
   2422         }
   2423 
   2424         Mat diff = abs(anglesInDegrees - resInDeg);
   2425         size_t errDegCount = diff.total() - countNonZero((diff < maxAngleDiff) | ((360 - diff) < maxAngleDiff));
   2426         if(errDegCount > 0)
   2427         {
   2428             ts->printf(cvtest::TS::LOG, "There are incorrect result angles (in degrees) (part of them is %f)\n",
   2429                        static_cast<float>(errDegCount)/resInDeg.total());
   2430             ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
   2431         }
   2432 
   2433         Mat convertedRes = resInRad * 180. / CV_PI;
   2434         double normDiff = cvtest::norm(convertedRes - resInDeg, NORM_INF);
   2435         if(normDiff > FLT_EPSILON * 180.)
   2436         {
   2437             ts->printf(cvtest::TS::LOG, "There are incorrect result angles (in radians)\n");
   2438             ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
   2439         }
   2440 
   2441         ts->set_failed_test_info(cvtest::TS::OK);
   2442     }
   2443 };
   2444 
   2445 class Core_CheckRange_Empty : public cvtest::BaseTest
   2446 {
   2447 public:
   2448     Core_CheckRange_Empty(){}
   2449     ~Core_CheckRange_Empty(){}
   2450 protected:
   2451     virtual void run( int start_from );
   2452 };
   2453 
   2454 void Core_CheckRange_Empty::run( int )
   2455 {
   2456     cv::Mat m;
   2457     ASSERT_TRUE( cv::checkRange(m) );
   2458 }
   2459 
   2460 TEST(Core_CheckRange_Empty, accuracy) { Core_CheckRange_Empty test; test.safe_run(); }
   2461 
   2462 class Core_CheckRange_INT_MAX : public cvtest::BaseTest
   2463 {
   2464 public:
   2465     Core_CheckRange_INT_MAX(){}
   2466     ~Core_CheckRange_INT_MAX(){}
   2467 protected:
   2468     virtual void run( int start_from );
   2469 };
   2470 
   2471 void Core_CheckRange_INT_MAX::run( int )
   2472 {
   2473     cv::Mat m(3, 3, CV_32SC1, cv::Scalar(INT_MAX));
   2474     ASSERT_FALSE( cv::checkRange(m, true, 0, 0, INT_MAX) );
   2475     ASSERT_TRUE( cv::checkRange(m) );
   2476 }
   2477 
   2478 TEST(Core_CheckRange_INT_MAX, accuracy) { Core_CheckRange_INT_MAX test; test.safe_run(); }
   2479 
   2480 template <typename T> class Core_CheckRange : public testing::Test {};
   2481 
   2482 TYPED_TEST_CASE_P(Core_CheckRange);
   2483 
   2484 TYPED_TEST_P(Core_CheckRange, Negative)
   2485 {
   2486     double min_bound = 4.5;
   2487     double max_bound = 16.0;
   2488 
   2489     TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14};
   2490     cv::Mat src = cv::Mat(3,3, cv::DataDepth<TypeParam>::value, data);
   2491 
   2492     cv::Point bad_pt(0, 0);
   2493 
   2494     ASSERT_FALSE(checkRange(src, true, &bad_pt, min_bound, max_bound));
   2495     ASSERT_EQ(bad_pt.x, 0);
   2496     ASSERT_EQ(bad_pt.y, 1);
   2497 }
   2498 
   2499 TYPED_TEST_P(Core_CheckRange, Positive)
   2500 {
   2501     double min_bound = -1;
   2502     double max_bound = 16.0;
   2503 
   2504     TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14};
   2505     cv::Mat src = cv::Mat(3,3, cv::DataDepth<TypeParam>::value, data);
   2506 
   2507     cv::Point bad_pt(0, 0);
   2508 
   2509     ASSERT_TRUE(checkRange(src, true, &bad_pt, min_bound, max_bound));
   2510     ASSERT_EQ(bad_pt.x, 0);
   2511     ASSERT_EQ(bad_pt.y, 0);
   2512 }
   2513 
   2514 TYPED_TEST_P(Core_CheckRange, Bounds)
   2515 {
   2516     double min_bound = 24.5;
   2517     double max_bound = 1.0;
   2518 
   2519     TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14};
   2520     cv::Mat src = cv::Mat(3,3, cv::DataDepth<TypeParam>::value, data);
   2521 
   2522     cv::Point bad_pt(0, 0);
   2523 
   2524     ASSERT_FALSE(checkRange(src, true, &bad_pt, min_bound, max_bound));
   2525     ASSERT_EQ(bad_pt.x, 0);
   2526     ASSERT_EQ(bad_pt.y, 0);
   2527 }
   2528 
   2529 TYPED_TEST_P(Core_CheckRange, Zero)
   2530 {
   2531     double min_bound = 0.0;
   2532     double max_bound = 0.1;
   2533 
   2534     cv::Mat src1 = cv::Mat::zeros(3, 3, cv::DataDepth<TypeParam>::value);
   2535 
   2536     int sizes[] = {5, 6, 7};
   2537     cv::Mat src2 = cv::Mat::zeros(3, sizes, cv::DataDepth<TypeParam>::value);
   2538 
   2539     ASSERT_TRUE( checkRange(src1, true, NULL, min_bound, max_bound) );
   2540     ASSERT_TRUE( checkRange(src2, true, NULL, min_bound, max_bound) );
   2541 }
   2542 
   2543 TYPED_TEST_P(Core_CheckRange, One)
   2544 {
   2545     double min_bound = 1.0;
   2546     double max_bound = 1.1;
   2547 
   2548     cv::Mat src1 = cv::Mat::ones(3, 3, cv::DataDepth<TypeParam>::value);
   2549 
   2550     int sizes[] = {5, 6, 7};
   2551     cv::Mat src2 = cv::Mat::ones(3, sizes, cv::DataDepth<TypeParam>::value);
   2552 
   2553     ASSERT_TRUE( checkRange(src1, true, NULL, min_bound, max_bound) );
   2554     ASSERT_TRUE( checkRange(src2, true, NULL, min_bound, max_bound) );
   2555 }
   2556 
   2557 REGISTER_TYPED_TEST_CASE_P(Core_CheckRange, Negative, Positive, Bounds, Zero, One);
   2558 
   2559 typedef ::testing::Types<signed char,unsigned char, signed short, unsigned short, signed int> mat_data_types;
   2560 INSTANTIATE_TYPED_TEST_CASE_P(Negative_Test, Core_CheckRange, mat_data_types);
   2561 
   2562 TEST(Core_Invert, small)
   2563 {
   2564     cv::Mat a = (cv::Mat_<float>(3,3) << 2.42104644730331, 1.81444796521479, -3.98072565304758, 0, 7.08389214348967e-3, 5.55326770986007e-3, 0,0, 7.44556154284261e-3);
   2565     //cv::randu(a, -1, 1);
   2566 
   2567     cv::Mat b = a.t()*a;
   2568     cv::Mat c, i = Mat_<float>::eye(3, 3);
   2569     cv::invert(b, c, cv::DECOMP_LU); //std::cout << b*c << std::endl;
   2570     ASSERT_LT( cvtest::norm(b*c, i, CV_C), 0.1 );
   2571     cv::invert(b, c, cv::DECOMP_SVD); //std::cout << b*c << std::endl;
   2572     ASSERT_LT( cvtest::norm(b*c, i, CV_C), 0.1 );
   2573     cv::invert(b, c, cv::DECOMP_CHOLESKY); //std::cout << b*c << std::endl;
   2574     ASSERT_LT( cvtest::norm(b*c, i, CV_C), 0.1 );
   2575 }
   2576 
   2577 /////////////////////////////////////////////////////////////////////////////////////////////////////
   2578 
   2579 TEST(Core_CovarMatrix, accuracy) { Core_CovarMatrixTest test; test.safe_run(); }
   2580 TEST(Core_CrossProduct, accuracy) { Core_CrossProductTest test; test.safe_run(); }
   2581 TEST(Core_Determinant, accuracy) { Core_DetTest test; test.safe_run(); }
   2582 TEST(Core_DotProduct, accuracy) { Core_DotProductTest test; test.safe_run(); }
   2583 TEST(Core_GEMM, accuracy) { Core_GEMMTest test; test.safe_run(); }
   2584 TEST(Core_Invert, accuracy) { Core_InvertTest test; test.safe_run(); }
   2585 TEST(Core_Mahalanobis, accuracy) { Core_MahalanobisTest test; test.safe_run(); }
   2586 TEST(Core_MulTransposed, accuracy) { Core_MulTransposedTest test; test.safe_run(); }
   2587 TEST(Core_Transform, accuracy) { Core_TransformTest test; test.safe_run(); }
   2588 TEST(Core_PerspectiveTransform, accuracy) { Core_PerspectiveTransformTest test; test.safe_run(); }
   2589 TEST(Core_Pow, accuracy) { Core_PowTest test; test.safe_run(); }
   2590 TEST(Core_SolveLinearSystem, accuracy) { Core_SolveTest test; test.safe_run(); }
   2591 TEST(Core_SVD, accuracy) { Core_SVDTest test; test.safe_run(); }
   2592 TEST(Core_SVBkSb, accuracy) { Core_SVBkSbTest test; test.safe_run(); }
   2593 TEST(Core_Trace, accuracy) { Core_TraceTest test; test.safe_run(); }
   2594 TEST(Core_SolvePoly, accuracy) { Core_SolvePolyTest test; test.safe_run(); }
   2595 TEST(Core_Phase, accuracy) { Core_PhaseTest test; test.safe_run(); }
   2596 
   2597 
   2598 TEST(Core_SVD, flt)
   2599 {
   2600     float a[] = {
   2601     1.23377746e+011f, -7.05490125e+010f, -4.18380882e+010f, -11693456.f,
   2602     -39091328.f, 77492224.f, -7.05490125e+010f, 2.36211143e+011f,
   2603     -3.51093473e+010f, 70773408.f, -4.83386156e+005f, -129560368.f,
   2604     -4.18380882e+010f, -3.51093473e+010f, 9.25311222e+010f, -49052424.f,
   2605     43922752.f, 12176842.f, -11693456.f, 70773408.f, -49052424.f, 8.40836094e+004f,
   2606     5.17475293e+003f, -1.16122949e+004f, -39091328.f, -4.83386156e+005f,
   2607     43922752.f, 5.17475293e+003f, 5.16047969e+004f, 5.68887842e+003f, 77492224.f,
   2608     -129560368.f, 12176842.f, -1.16122949e+004f, 5.68887842e+003f,
   2609     1.28060578e+005f
   2610     };
   2611 
   2612     float b[] = {
   2613     283751232.f, 2.61604198e+009f, -745033216.f, 2.31125625e+005f,
   2614     -4.52429188e+005f, -1.37596525e+006f
   2615     };
   2616 
   2617     Mat A(6, 6, CV_32F, a);
   2618     Mat B(6, 1, CV_32F, b);
   2619     Mat X, B1;
   2620     solve(A, B, X, DECOMP_SVD);
   2621     B1 = A*X;
   2622     EXPECT_LE(cvtest::norm(B1, B, NORM_L2 + NORM_RELATIVE), FLT_EPSILON*10);
   2623 }
   2624 
   2625 
   2626 // TODO: eigenvv, invsqrt, cbrt, fastarctan, (round, floor, ceil(?)),
   2627 
   2628 enum
   2629 {
   2630     MAT_N_DIM_C1,
   2631     MAT_N_1_CDIM,
   2632     MAT_1_N_CDIM,
   2633     MAT_N_DIM_C1_NONCONT,
   2634     MAT_N_1_CDIM_NONCONT,
   2635     VECTOR
   2636 };
   2637 
   2638 class CV_KMeansSingularTest : public cvtest::BaseTest
   2639 {
   2640 public:
   2641     CV_KMeansSingularTest() {}
   2642     ~CV_KMeansSingularTest() {}
   2643 protected:
   2644     void run(int inVariant)
   2645     {
   2646         int i, iter = 0, N = 0, N0 = 0, K = 0, dims = 0;
   2647         Mat labels;
   2648         try
   2649         {
   2650             RNG& rng = theRNG();
   2651             const int MAX_DIM=5;
   2652             int MAX_POINTS = 100, maxIter = 100;
   2653             for( iter = 0; iter < maxIter; iter++ )
   2654             {
   2655                 ts->update_context(this, iter, true);
   2656                 dims = rng.uniform(inVariant == MAT_1_N_CDIM ? 2 : 1, MAX_DIM+1);
   2657                 N = rng.uniform(1, MAX_POINTS+1);
   2658                 N0 = rng.uniform(1, MAX(N/10, 2));
   2659                 K = rng.uniform(1, N+1);
   2660 
   2661                 if (inVariant == VECTOR)
   2662                 {
   2663                     dims = 2;
   2664 
   2665                     std::vector<cv::Point2f> data0(N0);
   2666                     rng.fill(data0, RNG::UNIFORM, -1, 1);
   2667 
   2668                     std::vector<cv::Point2f> data(N);
   2669                     for( i = 0; i < N; i++ )
   2670                         data[i] = data0[rng.uniform(0, N0)];
   2671 
   2672                     kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
   2673                            5, KMEANS_PP_CENTERS);
   2674                 }
   2675                 else
   2676                 {
   2677                     Mat data0(N0, dims, CV_32F);
   2678                     rng.fill(data0, RNG::UNIFORM, -1, 1);
   2679 
   2680                     Mat data;
   2681 
   2682                     switch (inVariant)
   2683                     {
   2684                     case MAT_N_DIM_C1:
   2685                         data.create(N, dims, CV_32F);
   2686                         for( i = 0; i < N; i++ )
   2687                             data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
   2688                         break;
   2689 
   2690                     case MAT_N_1_CDIM:
   2691                         data.create(N, 1, CV_32FC(dims));
   2692                         for( i = 0; i < N; i++ )
   2693                             memcpy(data.ptr(i), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
   2694                         break;
   2695 
   2696                     case MAT_1_N_CDIM:
   2697                         data.create(1, N, CV_32FC(dims));
   2698                         for( i = 0; i < N; i++ )
   2699                             memcpy(data.ptr() + i * dims * sizeof(float), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
   2700                         break;
   2701 
   2702                     case MAT_N_DIM_C1_NONCONT:
   2703                         data.create(N, dims + 5, CV_32F);
   2704                         data = data(Range(0, N), Range(0, dims));
   2705                         for( i = 0; i < N; i++ )
   2706                             data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
   2707                         break;
   2708 
   2709                     case MAT_N_1_CDIM_NONCONT:
   2710                         data.create(N, 3, CV_32FC(dims));
   2711                         data = data.colRange(0, 1);
   2712                         for( i = 0; i < N; i++ )
   2713                             memcpy(data.ptr(i), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
   2714                         break;
   2715                     }
   2716 
   2717                     kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
   2718                            5, KMEANS_PP_CENTERS);
   2719                 }
   2720 
   2721                 Mat hist(K, 1, CV_32S, Scalar(0));
   2722                 for( i = 0; i < N; i++ )
   2723                 {
   2724                     int l = labels.at<int>(i);
   2725                     CV_Assert(0 <= l && l < K);
   2726                     hist.at<int>(l)++;
   2727                 }
   2728                 for( i = 0; i < K; i++ )
   2729                     CV_Assert( hist.at<int>(i) != 0 );
   2730             }
   2731         }
   2732         catch(...)
   2733         {
   2734             ts->printf(cvtest::TS::LOG,
   2735                        "context: iteration=%d, N=%d, N0=%d, K=%d\n",
   2736                        iter, N, N0, K);
   2737             std::cout << labels << std::endl;
   2738             ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
   2739         }
   2740     }
   2741 };
   2742 
   2743 TEST(Core_KMeans, singular) { CV_KMeansSingularTest test; test.safe_run(MAT_N_DIM_C1); }
   2744 
   2745 CV_ENUM(KMeansInputVariant, MAT_N_DIM_C1, MAT_N_1_CDIM, MAT_1_N_CDIM, MAT_N_DIM_C1_NONCONT, MAT_N_1_CDIM_NONCONT, VECTOR)
   2746 
   2747 typedef testing::TestWithParam<KMeansInputVariant> Core_KMeans_InputVariants;
   2748 
   2749 TEST_P(Core_KMeans_InputVariants, singular)
   2750 {
   2751     CV_KMeansSingularTest test;
   2752     test.safe_run(GetParam());
   2753 }
   2754 
   2755 INSTANTIATE_TEST_CASE_P(AllVariants, Core_KMeans_InputVariants, KMeansInputVariant::all());
   2756 
   2757 TEST(CovariationMatrixVectorOfMat, accuracy)
   2758 {
   2759     unsigned int col_problem_size = 8, row_problem_size = 8, vector_size = 16;
   2760     cv::Mat src(vector_size, col_problem_size * row_problem_size, CV_32F);
   2761     int singleMatFlags = CV_COVAR_ROWS;
   2762 
   2763     cv::Mat gold;
   2764     cv::Mat goldMean;
   2765     cv::randu(src,cv::Scalar(-128), cv::Scalar(128));
   2766     cv::calcCovarMatrix(src,gold,goldMean,singleMatFlags,CV_32F);
   2767     std::vector<cv::Mat> srcVec;
   2768     for(size_t i = 0; i < vector_size; i++)
   2769     {
   2770         srcVec.push_back(src.row(static_cast<int>(i)).reshape(0,col_problem_size));
   2771     }
   2772 
   2773     cv::Mat actual;
   2774     cv::Mat actualMean;
   2775     cv::calcCovarMatrix(srcVec, actual, actualMean,singleMatFlags,CV_32F);
   2776 
   2777     cv::Mat diff;
   2778     cv::absdiff(gold, actual, diff);
   2779     cv::Scalar s = cv::sum(diff);
   2780     ASSERT_EQ(s.dot(s), 0.0);
   2781 
   2782     cv::Mat meanDiff;
   2783     cv::absdiff(goldMean, actualMean.reshape(0,1), meanDiff);
   2784     cv::Scalar sDiff = cv::sum(meanDiff);
   2785     ASSERT_EQ(sDiff.dot(sDiff), 0.0);
   2786 }
   2787 
   2788 TEST(CovariationMatrixVectorOfMatWithMean, accuracy)
   2789 {
   2790     unsigned int col_problem_size = 8, row_problem_size = 8, vector_size = 16;
   2791     cv::Mat src(vector_size, col_problem_size * row_problem_size, CV_32F);
   2792     int singleMatFlags = CV_COVAR_ROWS | CV_COVAR_USE_AVG;
   2793 
   2794     cv::Mat gold;
   2795     cv::randu(src,cv::Scalar(-128), cv::Scalar(128));
   2796     cv::Mat goldMean;
   2797 
   2798     cv::reduce(src,goldMean,0 ,CV_REDUCE_AVG, CV_32F);
   2799 
   2800     cv::calcCovarMatrix(src,gold,goldMean,singleMatFlags,CV_32F);
   2801 
   2802     std::vector<cv::Mat> srcVec;
   2803     for(size_t i = 0; i < vector_size; i++)
   2804     {
   2805         srcVec.push_back(src.row(static_cast<int>(i)).reshape(0,col_problem_size));
   2806     }
   2807 
   2808     cv::Mat actual;
   2809     cv::Mat actualMean = goldMean.reshape(0, row_problem_size);
   2810     cv::calcCovarMatrix(srcVec, actual, actualMean,singleMatFlags,CV_32F);
   2811 
   2812     cv::Mat diff;
   2813     cv::absdiff(gold, actual, diff);
   2814     cv::Scalar s = cv::sum(diff);
   2815     ASSERT_EQ(s.dot(s), 0.0);
   2816 
   2817     cv::Mat meanDiff;
   2818     cv::absdiff(goldMean, actualMean.reshape(0,1), meanDiff);
   2819     cv::Scalar sDiff = cv::sum(meanDiff);
   2820     ASSERT_EQ(sDiff.dot(sDiff), 0.0);
   2821 }
   2822 
   2823 TEST(Core_Pow, special)
   2824 {
   2825     for( int i = 0; i < 100; i++ )
   2826     {
   2827         int n = theRNG().uniform(1, 30);
   2828         Mat mtx0(1, n, CV_8S), mtx, result;
   2829         randu(mtx0, -5, 5);
   2830 
   2831         int type = theRNG().uniform(0, 2) ? CV_64F : CV_32F;
   2832         double eps = type == CV_32F ? 1e-3 : 1e-10;
   2833         mtx0.convertTo(mtx, type);
   2834         // generate power from [-n, n] interval with 1/8 step - enough to check various cases.
   2835         const int max_pf = 3;
   2836         int pf = theRNG().uniform(0, max_pf*2+1);
   2837         double power = ((1 << pf) - (1 << (max_pf*2-1)))/16.;
   2838         int ipower = cvRound(power);
   2839         bool is_ipower = ipower == power;
   2840         cv::pow(mtx, power, result);
   2841         for( int j = 0; j < n; j++ )
   2842         {
   2843             double val = type == CV_32F ? (double)mtx.at<float>(j) : mtx.at<double>(j);
   2844             double r = type == CV_32F ? (double)result.at<float>(j) : result.at<double>(j);
   2845             double r0;
   2846             if( power == 0. )
   2847                 r0 = 1;
   2848             else if( is_ipower )
   2849             {
   2850                 r0 = 1;
   2851                 for( int k = 0; k < std::abs(ipower); k++ )
   2852                     r0 *= val;
   2853                 if( ipower < 0 )
   2854                     r0 = 1./r0;
   2855             }
   2856             else
   2857                 r0 = std::pow(val, power);
   2858             if( cvIsInf(r0) )
   2859             {
   2860                 ASSERT_TRUE(cvIsInf(r) != 0);
   2861             }
   2862             else if( cvIsNaN(r0) )
   2863             {
   2864                 ASSERT_TRUE(cvIsNaN(r) != 0);
   2865             }
   2866             else
   2867             {
   2868                 ASSERT_TRUE(cvIsInf(r) == 0 && cvIsNaN(r) == 0);
   2869                 ASSERT_LT(fabs(r - r0), eps);
   2870             }
   2871         }
   2872     }
   2873 }
   2874 
   2875 /* End of file. */
   2876