Home | History | Annotate | Download | only in test
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                           License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of the copyright holders may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the OpenCV Foundation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 
     42 #include "test_precomp.hpp"
     43 #include "opencv2/hal.hpp"
     44 
     45 using namespace cv;
     46 
     47 enum
     48 {
     49     HAL_EXP = 0,
     50     HAL_LOG = 1,
     51     HAL_SQRT = 2
     52 };
     53 
     54 TEST(Core_HAL, mathfuncs)
     55 {
     56     for( int hcase = 0; hcase < 6; hcase++ )
     57     {
     58         int depth = hcase % 2 == 0 ? CV_32F : CV_64F;
     59         double eps = depth == CV_32F ? 1e-5 : 1e-10;
     60         int nfunc = hcase / 2;
     61         int n = 100;
     62 
     63         Mat src(1, n, depth), dst(1, n, depth), dst0(1, n, depth);
     64         randu(src, 1, 10);
     65 
     66         double min_hal_t = DBL_MAX, min_ocv_t = DBL_MAX;
     67 
     68         for( int iter = 0; iter < 10; iter++ )
     69         {
     70             double t = (double)getTickCount();
     71             switch (nfunc)
     72             {
     73             case HAL_EXP:
     74                 if( depth == CV_32F )
     75                     hal::exp(src.ptr<float>(), dst.ptr<float>(), n);
     76                 else
     77                     hal::exp(src.ptr<double>(), dst.ptr<double>(), n);
     78                 break;
     79             case HAL_LOG:
     80                 if( depth == CV_32F )
     81                     hal::log(src.ptr<float>(), dst.ptr<float>(), n);
     82                 else
     83                     hal::log(src.ptr<double>(), dst.ptr<double>(), n);
     84                 break;
     85             case HAL_SQRT:
     86                 if( depth == CV_32F )
     87                     hal::sqrt(src.ptr<float>(), dst.ptr<float>(), n);
     88                 else
     89                     hal::sqrt(src.ptr<double>(), dst.ptr<double>(), n);
     90                 break;
     91             default:
     92                 CV_Error(Error::StsBadArg, "unknown function");
     93             }
     94             t = (double)getTickCount() - t;
     95             min_hal_t = std::min(min_hal_t, t);
     96 
     97             t = (double)getTickCount();
     98             switch (nfunc)
     99             {
    100             case HAL_EXP:
    101                 exp(src, dst0);
    102                 break;
    103             case HAL_LOG:
    104                 log(src, dst0);
    105                 break;
    106             case HAL_SQRT:
    107                 pow(src, 0.5, dst0);
    108                 break;
    109             default:
    110                 CV_Error(Error::StsBadArg, "unknown function");
    111             }
    112             t = (double)getTickCount() - t;
    113             min_ocv_t = std::min(min_ocv_t, t);
    114         }
    115         EXPECT_LE(norm(dst, dst0, NORM_INF | NORM_RELATIVE), eps);
    116 
    117         double freq = getTickFrequency();
    118         printf("%s (N=%d, %s): hal time=%.2fusec, ocv time=%.2fusec\n",
    119                (nfunc == HAL_EXP ? "exp" : nfunc == HAL_LOG ? "log" : nfunc == HAL_SQRT ? "sqrt" : "???"),
    120                n, (depth == CV_32F ? "f32" : "f64"), min_hal_t*1e6/freq, min_ocv_t*1e6/freq);
    121     }
    122 }
    123 
    124 enum
    125 {
    126     HAL_LU = 0,
    127     HAL_CHOL = 1
    128 };
    129 
    130 TEST(Core_HAL, mat_decomp)
    131 {
    132     for( int hcase = 0; hcase < 16; hcase++ )
    133     {
    134         int depth = hcase % 2 == 0 ? CV_32F : CV_64F;
    135         int size = (hcase / 2) % 4;
    136         size = size == 0 ? 3 : size == 1 ? 4  : size == 2 ? 6 : 15;
    137         int nfunc = (hcase / 8);
    138         double eps = depth == CV_32F ? 1e-5 : 1e-10;
    139 
    140         if( size == 3 )
    141             continue;
    142 
    143         Mat a0(size, size, depth), a(size, size, depth), b(size, 1, depth), x(size, 1, depth), x0(size, 1, depth);
    144         randu(a0, -1, 1);
    145         a0 = a0*a0.t();
    146         randu(b, -1, 1);
    147 
    148         double min_hal_t = DBL_MAX, min_ocv_t = DBL_MAX;
    149         size_t asize = size*size*a.elemSize();
    150         size_t bsize = size*b.elemSize();
    151 
    152         for( int iter = 0; iter < 10; iter++ )
    153         {
    154             memcpy(x.ptr(), b.ptr(), bsize);
    155             memcpy(a.ptr(), a0.ptr(), asize);
    156 
    157             double t = (double)getTickCount();
    158             switch (nfunc)
    159             {
    160             case HAL_LU:
    161                 if( depth == CV_32F )
    162                     hal::LU(a.ptr<float>(), a.step, size, x.ptr<float>(), x.step, 1);
    163                 else
    164                     hal::LU(a.ptr<double>(), a.step, size, x.ptr<double>(), x.step, 1);
    165                 break;
    166             case HAL_CHOL:
    167                 if( depth == CV_32F )
    168                     hal::Cholesky(a.ptr<float>(), a.step, size, x.ptr<float>(), x.step, 1);
    169                 else
    170                     hal::Cholesky(a.ptr<double>(), a.step, size, x.ptr<double>(), x.step, 1);
    171                 break;
    172             default:
    173                 CV_Error(Error::StsBadArg, "unknown function");
    174             }
    175             t = (double)getTickCount() - t;
    176             min_hal_t = std::min(min_hal_t, t);
    177 
    178             t = (double)getTickCount();
    179             solve(a0, b, x0, (nfunc == HAL_LU ? DECOMP_LU : DECOMP_CHOLESKY));
    180             t = (double)getTickCount() - t;
    181             min_ocv_t = std::min(min_ocv_t, t);
    182         }
    183         //std::cout << "x: " << Mat(x.t()) << std::endl;
    184         //std::cout << "x0: " << Mat(x0.t()) << std::endl;
    185 
    186         EXPECT_LE(norm(x, x0, NORM_INF | NORM_RELATIVE), eps);
    187 
    188         double freq = getTickFrequency();
    189         printf("%s (%d x %d, %s): hal time=%.2fusec, ocv time=%.2fusec\n",
    190                (nfunc == HAL_LU ? "LU" : nfunc == HAL_CHOL ? "Cholesky" : "???"),
    191                size, size,
    192                (depth == CV_32F ? "f32" : "f64"),
    193                min_hal_t*1e6/freq, min_ocv_t*1e6/freq);
    194     }
    195 }
    196