Home | History | Annotate | Download | only in src
      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) 2000-2008, Intel Corporation, all rights reserved.
     14 // Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
     15 // Third party copyrights are property of their respective owners.
     16 //
     17 // Redistribution and use in source and binary forms, with or without modification,
     18 // are permitted provided that the following conditions are met:
     19 //
     20 //   * Redistribution's of source code must retain the above copyright notice,
     21 //     this list of conditions and the following disclaimer.
     22 //
     23 //   * Redistribution's in binary form must reproduce the above copyright notice,
     24 //     this list of conditions and the following disclaimer in the documentation
     25 //     and/or other materials provided with the distribution.
     26 //
     27 //   * The name of the copyright holders may not be used to endorse or promote products
     28 //     derived from this software without specific prior written permission.
     29 //
     30 // This software is provided by the copyright holders and contributors "as is" and
     31 // any express or implied warranties, including, but not limited to, the implied
     32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     33 // In no event shall the Intel Corporation or contributors be liable for any direct,
     34 // indirect, incidental, special, exemplary, or consequential damages
     35 // (including, but not limited to, procurement of substitute goods or services;
     36 // loss of use, data, or profits; or business interruption) however caused
     37 // and on any theory of liability, whether in contract, strict liability,
     38 // or tort (including negligence or otherwise) arising in any way out of
     39 // the use of this software, even if advised of the possibility of such damage.
     40 //
     41 //M*/
     42 
     43 #include "precomp.hpp"
     44 
     45 namespace cv { namespace hal {
     46 
     47 /****************************************************************************************\
     48 *                     LU & Cholesky implementation for small matrices                    *
     49 \****************************************************************************************/
     50 
     51 template<typename _Tp> static inline int
     52 LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n, _Tp eps)
     53 {
     54     int i, j, k, p = 1;
     55     astep /= sizeof(A[0]);
     56     bstep /= sizeof(b[0]);
     57 
     58     for( i = 0; i < m; i++ )
     59     {
     60         k = i;
     61 
     62         for( j = i+1; j < m; j++ )
     63             if( std::abs(A[j*astep + i]) > std::abs(A[k*astep + i]) )
     64                 k = j;
     65 
     66         if( std::abs(A[k*astep + i]) < eps )
     67             return 0;
     68 
     69         if( k != i )
     70         {
     71             for( j = i; j < m; j++ )
     72                 std::swap(A[i*astep + j], A[k*astep + j]);
     73             if( b )
     74                 for( j = 0; j < n; j++ )
     75                     std::swap(b[i*bstep + j], b[k*bstep + j]);
     76             p = -p;
     77         }
     78 
     79         _Tp d = -1/A[i*astep + i];
     80 
     81         for( j = i+1; j < m; j++ )
     82         {
     83             _Tp alpha = A[j*astep + i]*d;
     84 
     85             for( k = i+1; k < m; k++ )
     86                 A[j*astep + k] += alpha*A[i*astep + k];
     87 
     88             if( b )
     89                 for( k = 0; k < n; k++ )
     90                     b[j*bstep + k] += alpha*b[i*bstep + k];
     91         }
     92 
     93         A[i*astep + i] = -d;
     94     }
     95 
     96     if( b )
     97     {
     98         for( i = m-1; i >= 0; i-- )
     99             for( j = 0; j < n; j++ )
    100             {
    101                 _Tp s = b[i*bstep + j];
    102                 for( k = i+1; k < m; k++ )
    103                     s -= A[i*astep + k]*b[k*bstep + j];
    104                 b[i*bstep + j] = s*A[i*astep + i];
    105             }
    106     }
    107 
    108     return p;
    109 }
    110 
    111 
    112 int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n)
    113 {
    114     return LUImpl(A, astep, m, b, bstep, n, FLT_EPSILON*10);
    115 }
    116 
    117 
    118 int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n)
    119 {
    120     return LUImpl(A, astep, m, b, bstep, n, DBL_EPSILON*100);
    121 }
    122 
    123 
    124 template<typename _Tp> static inline bool
    125 CholImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n)
    126 {
    127     _Tp* L = A;
    128     int i, j, k;
    129     double s;
    130     astep /= sizeof(A[0]);
    131     bstep /= sizeof(b[0]);
    132 
    133     for( i = 0; i < m; i++ )
    134     {
    135         for( j = 0; j < i; j++ )
    136         {
    137             s = A[i*astep + j];
    138             for( k = 0; k < j; k++ )
    139                 s -= L[i*astep + k]*L[j*astep + k];
    140             L[i*astep + j] = (_Tp)(s*L[j*astep + j]);
    141         }
    142         s = A[i*astep + i];
    143         for( k = 0; k < j; k++ )
    144         {
    145             double t = L[i*astep + k];
    146             s -= t*t;
    147         }
    148         if( s < std::numeric_limits<_Tp>::epsilon() )
    149             return false;
    150         L[i*astep + i] = (_Tp)(1./std::sqrt(s));
    151     }
    152 
    153     if( !b )
    154         return true;
    155 
    156     // LLt x = b
    157     // 1: L y = b
    158     // 2. Lt x = y
    159 
    160     /*
    161      [ L00             ]  y0   b0
    162      [ L10 L11         ]  y1 = b1
    163      [ L20 L21 L22     ]  y2   b2
    164      [ L30 L31 L32 L33 ]  y3   b3
    165 
    166      [ L00 L10 L20 L30 ]  x0   y0
    167      [     L11 L21 L31 ]  x1 = y1
    168      [         L22 L32 ]  x2   y2
    169      [             L33 ]  x3   y3
    170      */
    171 
    172     for( i = 0; i < m; i++ )
    173     {
    174         for( j = 0; j < n; j++ )
    175         {
    176             s = b[i*bstep + j];
    177             for( k = 0; k < i; k++ )
    178                 s -= L[i*astep + k]*b[k*bstep + j];
    179             b[i*bstep + j] = (_Tp)(s*L[i*astep + i]);
    180         }
    181     }
    182 
    183     for( i = m-1; i >= 0; i-- )
    184     {
    185         for( j = 0; j < n; j++ )
    186         {
    187             s = b[i*bstep + j];
    188             for( k = m-1; k > i; k-- )
    189                 s -= L[k*astep + i]*b[k*bstep + j];
    190             b[i*bstep + j] = (_Tp)(s*L[i*astep + i]);
    191         }
    192     }
    193 
    194     return true;
    195 }
    196 
    197 
    198 bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n)
    199 {
    200     return CholImpl(A, astep, m, b, bstep, n);
    201 }
    202 
    203 bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n)
    204 {
    205     return CholImpl(A, astep, m, b, bstep, n);
    206 }
    207 
    208 }}
    209