1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
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.
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.
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.
46 #include <vecLib/clapack.h>
48 typedef __CLPK_integer integer;
49 typedef __CLPK_real real;
61 /****************************************************************************************\
62 * Determinant of the matrix *
63 \****************************************************************************************/
65 #define det2(m) (m(0,0)*m(1,1) - m(0,1)*m(1,0))
66 #define det3(m) (m(0,0)*(m(1,1)*m(2,2) - m(1,2)*m(2,1)) - \
67 m(0,1)*(m(1,0)*m(2,2) - m(1,2)*m(2,0)) + \
68 m(0,2)*(m(1,0)*m(2,1) - m(1,1)*m(2,0)))
70 double determinant( const Mat& mat )
73 int type = mat.type(), rows = mat.rows;
74 size_t step = mat.step;
75 const uchar* m = mat.data;
77 CV_Assert( mat.rows == mat.cols );
79 #define Mf(y, x) ((float*)(m + y*step))[x]
80 #define Md(y, x) ((double*)(m + y*step))[x]
92 integer i, n = rows, *ipiv, info=0;
93 int bufSize = n*n*sizeof(float) + (n+1)*sizeof(ipiv[0]), sign=0;
94 AutoBuffer<uchar> buffer(bufSize);
96 Mat a(n, n, CV_32F, (uchar*)buffer);
99 ipiv = (integer*)cvAlignPtr(a.data + a.step*a.rows, sizeof(integer));
100 sgetrf_(&n, &n, (float*)a.data, &n, ipiv, &info);
106 for( i = 0; i < n; i++ )
108 result *= ((float*)a.data)[i*(n+1)];
109 sign ^= ipiv[i] != i+1;
111 result *= sign ? -1 : 1;
115 else if( type == CV_64F )
125 integer i, n = rows, *ipiv, info=0;
126 int bufSize = n*n*sizeof(double) + (n+1)*sizeof(ipiv[0]), sign=0;
127 AutoBuffer<uchar> buffer(bufSize);
129 Mat a(n, n, CV_64F, (uchar*)buffer);
131 ipiv = (integer*)cvAlignPtr(a.data + a.step*a.rows, sizeof(integer));
133 dgetrf_(&n, &n, (double*)a.data, &n, ipiv, &info);
139 for( i = 0; i < n; i++ )
141 result *= ((double*)a.data)[i*(n+1)];
142 sign ^= ipiv[i] != i+1;
144 result *= sign ? -1 : 1;
149 CV_Error( CV_StsUnsupportedFormat, "" );
157 /****************************************************************************************\
158 * Inverse (or pseudo-inverse) of a matrix *
159 \****************************************************************************************/
161 #define Sf( y, x ) ((float*)(srcdata + y*srcstep))[x]
162 #define Sd( y, x ) ((double*)(srcdata + y*srcstep))[x]
163 #define Df( y, x ) ((float*)(dstdata + y*dststep))[x]
164 #define Dd( y, x ) ((double*)(dstdata + y*dststep))[x]
166 double invert( const Mat& src, Mat& dst, int method )
169 int type = src.type();
171 CV_Assert( method == DECOMP_LU || method == DECOMP_CHOLESKY || method == DECOMP_SVD );
173 if( method == DECOMP_SVD )
175 int n = std::min(src.rows, src.cols);
177 svd.backSubst(Mat(), dst);
179 return type == CV_32F ?
180 (((float*)svd.w.data)[0] >= FLT_EPSILON ?
181 ((float*)svd.w.data)[n-1]/((float*)svd.w.data)[0] : 0) :
182 (((double*)svd.w.data)[0] >= DBL_EPSILON ?
183 ((double*)svd.w.data)[n-1]/((double*)svd.w.data)[0] : 0);
186 CV_Assert( src.rows == src.cols && (type == CV_32F || type == CV_64F));
187 dst.create( src.rows, src.cols, type );
189 if( method == DECOMP_LU || method == DECOMP_CHOLESKY )
193 uchar* srcdata = src.data;
194 uchar* dstdata = dst.data;
195 size_t srcstep = src.step;
196 size_t dststep = dst.step;
200 if( type == CV_32FC1 )
237 else if( src.rows == 3 )
239 if( type == CV_32FC1 )
248 t[0] = (float)((Sf(1,1) * Sf(2,2) - Sf(1,2) * Sf(2,1)) * d);
249 t[1] = (float)((Sf(0,2) * Sf(2,1) - Sf(0,1) * Sf(2,2)) * d);
250 t[2] = (float)((Sf(0,1) * Sf(1,2) - Sf(0,2) * Sf(1,1)) * d);
252 t[3] = (float)((Sf(1,2) * Sf(2,0) - Sf(1,0) * Sf(2,2)) * d);
253 t[4] = (float)((Sf(0,0) * Sf(2,2) - Sf(0,2) * Sf(2,0)) * d);
254 t[5] = (float)((Sf(0,2) * Sf(1,0) - Sf(0,0) * Sf(1,2)) * d);
256 t[6] = (float)((Sf(1,0) * Sf(2,1) - Sf(1,1) * Sf(2,0)) * d);
257 t[7] = (float)((Sf(0,1) * Sf(2,0) - Sf(0,0) * Sf(2,1)) * d);
258 t[8] = (float)((Sf(0,0) * Sf(1,1) - Sf(0,1) * Sf(1,0)) * d);
260 Df(0,0) = t[0]; Df(0,1) = t[1]; Df(0,2) = t[2];
261 Df(1,0) = t[3]; Df(1,1) = t[4]; Df(1,2) = t[5];
262 Df(2,0) = t[6]; Df(2,1) = t[7]; Df(2,2) = t[8];
274 t[0] = (Sd(1,1) * Sd(2,2) - Sd(1,2) * Sd(2,1)) * d;
275 t[1] = (Sd(0,2) * Sd(2,1) - Sd(0,1) * Sd(2,2)) * d;
276 t[2] = (Sd(0,1) * Sd(1,2) - Sd(0,2) * Sd(1,1)) * d;
278 t[3] = (Sd(1,2) * Sd(2,0) - Sd(1,0) * Sd(2,2)) * d;
279 t[4] = (Sd(0,0) * Sd(2,2) - Sd(0,2) * Sd(2,0)) * d;
280 t[5] = (Sd(0,2) * Sd(1,0) - Sd(0,0) * Sd(1,2)) * d;
282 t[6] = (Sd(1,0) * Sd(2,1) - Sd(1,1) * Sd(2,0)) * d;
283 t[7] = (Sd(0,1) * Sd(2,0) - Sd(0,0) * Sd(2,1)) * d;
284 t[8] = (Sd(0,0) * Sd(1,1) - Sd(0,1) * Sd(1,0)) * d;
286 Dd(0,0) = t[0]; Dd(0,1) = t[1]; Dd(0,2) = t[2];
287 Dd(1,0) = t[3]; Dd(1,1) = t[4]; Dd(1,2) = t[5];
288 Dd(2,0) = t[6]; Dd(2,1) = t[7]; Dd(2,2) = t[8];
294 assert( src.rows == 1 );
296 if( type == CV_32FC1 )
302 Df(0,0) = (float)(1./d);
319 integer n = dst.cols, lwork=-1, elem_size = CV_ELEM_SIZE(type),
320 lda = (int)(dst.step/elem_size), piv1=0, info=0;
322 if( dst.data == src.data )
325 dst.create( src.rows, src.cols, type );
328 if( method == DECOMP_LU )
330 int buf_size = (int)(n*sizeof(integer));
331 AutoBuffer<uchar> buf;
337 sgetri_(&n, (float*)dst.data, &lda, &piv1, &work1, &lwork, &info);
338 lwork = cvRound(work1);
343 dgetri_(&n, (double*)dst.data, &lda, &piv1, &work1, &lwork, &info);
344 lwork = cvRound(work1);
347 buf_size += (int)((lwork + 1)*elem_size);
348 buf.allocate(buf_size);
349 buffer = (uchar*)buf;
353 sgetrf_(&n, &n, (float*)dst.data, &lda, (integer*)buffer, &info);
355 sgetri_(&n, (float*)dst.data, &lda, (integer*)buffer,
356 (float*)(buffer + n*sizeof(integer)), &lwork, &info);
360 dgetrf_(&n, &n, (double*)dst.data, &lda, (integer*)buffer, &info);
362 dgetri_(&n, (double*)dst.data, &lda, (integer*)buffer,
363 (double*)cvAlignPtr(buffer + n*sizeof(integer), elem_size), &lwork, &info);
366 else if( method == CV_CHOLESKY )
368 char L[] = {'L', '\0'};
371 spotrf_(L, &n, (float*)dst.data, &lda, &info);
373 spotri_(L, &n, (float*)dst.data, &lda, &info);
377 dpotrf_(L, &n, (double*)dst.data, &lda, &info);
379 dpotri_(L, &n, (double*)dst.data, &lda, &info);
393 /****************************************************************************************\
394 * Solving a linear system *
395 \****************************************************************************************/
397 bool solve( const Mat& src, const Mat& src2, Mat& dst, int method )
400 int type = src.type();
401 bool is_normal = (method & DECOMP_NORMAL) != 0;
403 CV_Assert( type == src2.type() && (type == CV_32F || type == CV_64F) );
405 method &= ~DECOMP_NORMAL;
406 CV_Assert( (method != DECOMP_LU && method != DECOMP_CHOLESKY) ||
407 is_normal || src.rows == src.cols );
409 dst.create( src.cols, src2.cols, src.type() );
411 // check case of a single equation and small matrix
412 if( (method == DECOMP_LU || method == DECOMP_CHOLESKY) &&
413 src.rows <= 3 && src.rows == src.cols && src2.cols == 1 )
415 #define bf(y) ((float*)(bdata + y*src2step))[0]
416 #define bd(y) ((double*)(bdata + y*src2step))[0]
418 uchar* srcdata = src.data;
419 uchar* bdata = src2.data;
420 uchar* dstdata = dst.data;
421 size_t srcstep = src.step;
422 size_t src2step = src2.step;
423 size_t dststep = dst.step;
427 if( type == CV_32FC1 )
434 t = (float)((bf(0)*Sf(1,1) - bf(1)*Sf(0,1))*d);
435 Df(1,0) = (float)((bf(1)*Sf(0,0) - bf(0)*Sf(1,0))*d);
448 t = (bd(0)*Sd(1,1) - bd(1)*Sd(0,1))*d;
449 Dd(1,0) = (bd(1)*Sd(0,0) - bd(0)*Sd(1,0))*d;
456 else if( src.rows == 3 )
458 if( type == CV_32FC1 )
467 (bf(0)*(Sf(1,1)*Sf(2,2) - Sf(1,2)*Sf(2,1)) -
468 Sf(0,1)*(bf(1)*Sf(2,2) - Sf(1,2)*bf(2)) +
469 Sf(0,2)*(bf(1)*Sf(2,1) - Sf(1,1)*bf(2))));
472 (Sf(0,0)*(bf(1)*Sf(2,2) - Sf(1,2)*bf(2)) -
473 bf(0)*(Sf(1,0)*Sf(2,2) - Sf(1,2)*Sf(2,0)) +
474 Sf(0,2)*(Sf(1,0)*bf(2) - bf(1)*Sf(2,0))));
477 (Sf(0,0)*(Sf(1,1)*bf(2) - bf(1)*Sf(2,1)) -
478 Sf(0,1)*(Sf(1,0)*bf(2) - bf(1)*Sf(2,0)) +
479 bf(0)*(Sf(1,0)*Sf(2,1) - Sf(1,1)*Sf(2,0))));
497 t[0] = ((Sd(1,1) * Sd(2,2) - Sd(1,2) * Sd(2,1))*bd(0) +
498 (Sd(0,2) * Sd(2,1) - Sd(0,1) * Sd(2,2))*bd(1) +
499 (Sd(0,1) * Sd(1,2) - Sd(0,2) * Sd(1,1))*bd(2))*d;
501 t[1] = ((Sd(1,2) * Sd(2,0) - Sd(1,0) * Sd(2,2))*bd(0) +
502 (Sd(0,0) * Sd(2,2) - Sd(0,2) * Sd(2,0))*bd(1) +
503 (Sd(0,2) * Sd(1,0) - Sd(0,0) * Sd(1,2))*bd(2))*d;
505 t[2] = ((Sd(1,0) * Sd(2,1) - Sd(1,1) * Sd(2,0))*bd(0) +
506 (Sd(0,1) * Sd(2,0) - Sd(0,0) * Sd(2,1))*bd(1) +
507 (Sd(0,0) * Sd(1,1) - Sd(0,1) * Sd(1,0))*bd(2))*d;
519 assert( src.rows == 1 );
521 if( type == CV_32FC1 )
525 Df(0,0) = (float)(bf(0)/d);
541 double rcond=-1, s1=0, work1=0, *work=0, *s=0;
542 float frcond=-1, fs1=0, fwork1=0, *fwork=0, *fs=0;
543 integer m = src.rows, m_ = m, n = src.cols, mn = std::max(m,n),
544 nm = std::min(m, n), nb = src2.cols, lwork=-1, liwork=0, iwork1=0,
545 lda = m, ldx = mn, info=0, rank=0, *iwork=0;
546 int elem_size = CV_ELEM_SIZE(type);
549 AutoBuffer<uchar> buffer;
551 char N[] = {'N', '\0'}, L[] = {'L', '\0'};
558 buf_size += (is_normal ? n*n : m*n)*elem_size;
560 if( m_ != n || nb > 1 || !dst.isContinuous() )
564 buf_size += n*nb*elem_size;
566 buf_size += mn*nb*elem_size;
569 if( method == DECOMP_SVD || method == DECOMP_EIG )
571 integer nlvl = cvRound(std::log(std::max(std::min(m_,n)/25., 1.))/CV_LOG2) + 1;
572 liwork = std::min(m_,n)*(3*std::max(nlvl,(integer)0) + 11);
575 sgelsd_(&m_, &n, &nb, (float*)src.data, &lda, (float*)dst.data, &ldx,
576 &fs1, &frcond, &rank, &fwork1, &lwork, &iwork1, &info);
578 dgelsd_(&m_, &n, &nb, (double*)src.data, &lda, (double*)dst.data, &ldx,
579 &s1, &rcond, &rank, &work1, &lwork, &iwork1, &info );
580 buf_size += nm*elem_size + (liwork + 1)*sizeof(integer);
582 else if( method == DECOMP_QR )
585 sgels_(N, &m_, &n, &nb, (float*)src.data, &lda,
586 (float*)dst.data, &ldx, &fwork1, &lwork, &info );
588 dgels_(N, &m_, &n, &nb, (double*)src.data, &lda,
589 (double*)dst.data, &ldx, &work1, &lwork, &info );
591 else if( method == DECOMP_LU )
593 buf_size += (n+1)*sizeof(integer);
595 else if( method == DECOMP_CHOLESKY )
598 CV_Error( CV_StsBadArg, "Unknown method" );
601 lwork = cvRound(type == CV_32F ? (double)fwork1 : work1);
602 buf_size += lwork*elem_size;
603 buffer.allocate(buf_size);
604 ptr = (uchar*)buffer;
606 Mat at(n, m_, type, ptr);
607 ptr += n*m_*elem_size;
609 if( method == DECOMP_CHOLESKY || method == DECOMP_EIG )
611 else if( !is_normal )
614 mulTransposed(src, at, true);
621 Mat temp(nb, mn, type, ptr);
622 ptr += nb*mn*elem_size;
623 Mat bt = temp.colRange(0, m);
624 xt = temp.colRange(0, n);
630 xt = Mat(1, n, type, dst.data);
637 xt = Mat(nb, n, type, ptr);
638 ptr += nb*n*elem_size;
641 xt = Mat(1, n, type, dst.data);
643 gemm( src2, src, 1, Mat(), 0, xt, GEMM_1_T );
646 lda = (int)(at.step ? at.step/elem_size : at.cols);
647 ldx = (int)(xt.step ? xt.step/elem_size : (!is_normal && copy_rhs ? mn : n));
649 if( method == DECOMP_SVD || method == DECOMP_EIG )
656 ptr += lwork*elem_size;
657 iwork = (integer*)cvAlignPtr(ptr, sizeof(integer));
659 sgelsd_(&m_, &n, &nb, (float*)at.data, &lda, (float*)xt.data, &ldx,
660 fs, &frcond, &rank, fwork, &lwork, iwork, &info);
667 ptr += lwork*elem_size;
668 iwork = (integer*)cvAlignPtr(ptr, sizeof(integer));
670 dgelsd_(&m_, &n, &nb, (double*)at.data, &lda, (double*)xt.data, &ldx,
671 s, &rcond, &rank, work, &lwork, iwork, &info);
674 else if( method == CV_QR )
679 sgels_(N, &m_, &n, &nb, (float*)at.data, &lda,
680 (float*)xt.data, &ldx, fwork, &lwork, &info);
685 dgels_(N, &m_, &n, &nb, (double*)at.data, &lda,
686 (double*)xt.data, &ldx, work, &lwork, &info);
689 else if( method == CV_CHOLESKY || (method == CV_LU && is_normal) )
693 spotrf_(L, &n, (float*)at.data, &lda, &info);
695 spotrs_(L, &n, &nb, (float*)at.data, &lda, (float*)xt.data, &ldx, &info);
699 dpotrf_(L, &n, (double*)at.data, &lda, &info);
701 dpotrs_(L, &n, &nb, (double*)at.data, &lda, (double*)xt.data, &ldx, &info);
704 else if( method == CV_LU )
706 iwork = (integer*)cvAlignPtr(ptr, sizeof(integer));
708 sgesv_(&n, &nb, (float*)at.data, &lda, iwork, (float*)xt.data, &ldx, &info );
710 dgesv_(&n, &nb, (double*)at.data, &lda, iwork, (double*)xt.data, &ldx, &info );
718 else if( xt.data != dst.data )
719 transpose( xt, dst );
726 /////////////////// finding eigenvalues and eigenvectors of a symmetric matrix ///////////////
728 template<typename Real> static inline Real hypot(Real a, Real b)
736 return a*std::sqrt(1 + f*f);
739 return b*std::sqrt(1 + f*f);
743 template<typename Real> bool jacobi(const Mat& _S0, Mat& _e, Mat& _E, bool computeEvects, Real eps)
745 int n = _S0.cols, i, j, k, m;
748 _E = Mat::eye(n, n, _S0.type());
750 int iters, maxIters = n*n*30;
752 AutoBuffer<uchar> buf(n*2*sizeof(int) + (n*n+n*2+1)*sizeof(Real));
753 Real* S = alignPtr((Real*)(uchar*)buf, sizeof(Real));
754 Real* maxSR = S + n*n;
755 Real* maxSC = maxSR + n;
756 int* indR = (int*)(maxSC + n);
757 int* indC = indR + n;
759 Mat _S(_S0.size(), _S0.type(), S);
763 Real* E = (Real*)_E.data;
764 Real* e = (Real*)_e.data;
765 int Sstep = _S.step/sizeof(Real);
766 int estep = _e.cols == 1 ? 1 : _e.step/sizeof(Real);
767 int Estep = _E.step/sizeof(Real);
769 for( k = 0; k < n; k++ )
771 e[k*estep] = S[(Sstep + 1)*k];
774 for( m = k+1, mv = std::abs(S[Sstep*k + m]), i = k+2; i < n; i++ )
776 Real v = std::abs(S[Sstep*k+i]);
785 for( m = 0, mv = std::abs(S[k]), i = 1; i < k; i++ )
787 Real v = std::abs(S[Sstep*i+k]);
796 for( iters = 0; iters < maxIters; iters++ )
798 // find index (k,l) of pivot p
799 for( k = 0, mv = maxSR[0], i = 1; i < n-1; i++ )
806 for( i = 1; i < n; i++ )
810 mv = v, k = indC[i], l = i;
813 Real p = S[Sstep*k + l];
814 if( std::abs(p) <= eps )
816 Real y = Real((e[estep*l] - e[estep*k])*0.5);
817 Real t = std::abs(y) + hypot(p, y);
818 Real s = hypot(p, t);
820 s = p/s; t = (p/t)*p;
831 #define rotate(v0, v1) a0 = v0, b0 = v1, v0 = a0*c - b0*s, v1 = a0*s + b0*c
833 // rotate rows and columns k and l
834 for( i = 0; i < k; i++ )
835 rotate(S[Sstep*i+k], S[Sstep*i+l]);
836 for( i = k+1; i < l; i++ )
837 rotate(S[Sstep*k+i], S[Sstep*i+l]);
838 for( i = l+1; i < n; i++ )
839 rotate(S[Sstep*k+i], S[Sstep*l+i]);
841 // rotate eigenvectors
843 for( i = 0; i < n; i++ )
844 rotate(E[Estep*k+i], E[Estep*l+i]);
848 for( j = 0; j < 2; j++ )
850 int idx = j == 0 ? k : l;
853 for( m = idx+1, mv = std::abs(S[Sstep*idx + m]), i = idx+2; i < n; i++ )
855 Real v = std::abs(S[Sstep*idx+i]);
864 for( m = 0, mv = std::abs(S[idx]), i = 1; i < idx; i++ )
866 Real v = std::abs(S[Sstep*i+idx]);
876 // sort eigenvalues & eigenvectors
877 for( k = 0; k < n-1; k++ )
880 for( i = k+1; i < n; i++ )
882 if( e[estep*m] < e[estep*i] )
887 std::swap(e[estep*m], e[estep*k]);
889 for( i = 0; i < n; i++ )
890 std::swap(E[Estep*m + i], E[Estep*k + i]);
898 static bool eigen( const Mat& src, Mat& evals, Mat& evects, bool computeEvects,
899 int lowindex, int highindex )
901 int type = src.type();
902 integer n = src.rows;
904 // If a range is selected both limits are needed.
905 CV_Assert( ( lowindex >= 0 && highindex >= 0 ) ||
906 ( lowindex < 0 && highindex < 0 ) );
908 // lapack sorts from lowest to highest so we flip
909 integer il = n - highindex;
910 integer iu = n - lowindex;
912 CV_Assert( src.rows == src.cols );
913 CV_Assert (type == CV_32F || type == CV_64F);
915 // allow for 1xn eigenvalue matrix too
916 if( !(evals.rows == 1 && evals.cols == n && evals.type() == type) )
917 evals.create(n, 1, type);
922 return jacobi<float>(src, evals, evects, computeEvects, FLT_EPSILON);
924 return jacobi<double>(src, evals, evects, computeEvects, DBL_EPSILON);
928 integer m=0, lda, ldv=n, lwork=-1, iwork1=0, liwork=-1, idummy=0, info=0;
929 integer *isupport, *iwork;
930 char job[] = { computeEvects ? 'V' : 'N', '\0' };
932 range[0] = (il < n + 1) ? 'I' : 'A';
934 char L[] = {'L', '\0'};
937 AutoBuffer<uchar> buf;
939 int elem_size = (int)src.elemSize();
940 lda = (int)(src.step/elem_size);
944 evects.create(n, n, type);
945 ldv = (int)(evects.step/elem_size);
948 bool copy_evals = !evals.isContinuous();
950 if( type == CV_32FC1 )
952 float work1 = 0, dummy = 0, abstol = 0, *s;
954 ssyevr_(job, range, L, &n, (float*)src.data, &lda, &dummy, &dummy, &il, &iu,
955 &abstol, &m, (float*)evals.data, (float*)evects.data, &ldv,
956 &idummy, &work1, &lwork, &iwork1, &liwork, &info );
959 lwork = cvRound(work1);
961 buf.allocate((lwork + n*n + (copy_evals ? n : 0))*elem_size +
962 (liwork+2*n+1)*sizeof(integer));
963 Mat a(n, n, type, (uchar*)buf);
964 work = a.data + n*n*elem_size;
966 s = (float*)(work + lwork*elem_size);
968 s = (float*)evals.data;
970 iwork = (integer*)cvAlignPtr(work + (lwork + (copy_evals ? n : 0))*elem_size, sizeof(integer));
971 isupport = iwork + liwork;
973 ssyevr_(job, range, L, &n, (float*)src.data, &lda, &dummy, &dummy,
974 &il, &iu, &abstol, &m, s, (float*)evects.data,
975 &ldv, isupport, (float*)work, &lwork, iwork, &liwork, &info );
980 double work1 = 0, dummy = 0, abstol = 0, *s;
982 dsyevr_(job, range, L, &n, (double*)src.data, &lda, &dummy, &dummy, &il, &iu,
983 &abstol, &m, (double*)evals.data, (double*)evects.data, &ldv,
984 &idummy, &work1, &lwork, &iwork1, &liwork, &info );
987 lwork = cvRound(work1);
989 buf.allocate((lwork + n*n + (copy_evals ? n : 0))*elem_size +
990 (liwork+2*n+1)*sizeof(integer));
991 Mat a(n, n, type, (uchar*)buf);
992 work = a.data + n*n*elem_size;
995 s = (double*)(work + lwork*elem_size);
997 s = (double*)evals.data;
999 iwork = (integer*)cvAlignPtr(work + (lwork + (copy_evals ? n : 0))*elem_size, sizeof(integer));
1000 isupport = iwork + liwork;
1002 dsyevr_(job, range, L, &n, (double*)src.data, &lda, &dummy, &dummy,
1003 &il, &iu, &abstol, &m, s, (double*)evects.data,
1004 &ldv, isupport, (double*)work, &lwork, iwork, &liwork, &info );
1009 Mat(evals.rows, evals.cols, type, work + lwork*elem_size).copyTo(evals);
1011 if( il < n + 1 && n > 20 ) {
1012 int nVV = iu - il + 1;
1013 if( computeEvects ) {
1014 Mat flipme = evects.rowRange(0, nVV);
1015 flip(flipme, flipme, 0);
1016 flipme = evals.rowRange(0, nVV);
1017 flip(flipme, flipme, 0);
1020 flip(evals, evals, 0);
1022 flip(evects, evects, 0);
1028 bool eigen( const Mat& src, Mat& evals, int lowindex, int highindex )
1031 return eigen(src, evals, evects, false, lowindex, highindex);
1034 bool eigen( const Mat& src, Mat& evals, Mat& evects, int lowindex,
1037 return eigen(src, evals, evects, true, lowindex, highindex);
1042 /* y[0:m,0:n] += diag(a[0:1,0:m]) * x[0:m,0:n] */
1043 template<typename T1, typename T2, typename T3> static void
1044 MatrAXPY( int m, int n, const T1* x, int dx,
1045 const T2* a, int inca, T3* y, int dy )
1048 for( i = 0; i < m; i++, x += dx, y += dy )
1051 for( j = 0; j <= n - 4; j += 4 )
1053 T3 t0 = (T3)(y[j] + s*x[j]);
1054 T3 t1 = (T3)(y[j+1] + s*x[j+1]);
1057 t0 = (T3)(y[j+2] + s*x[j+2]);
1058 t1 = (T3)(y[j+3] + s*x[j+3]);
1064 y[j] = (T3)(y[j] + s*x[j]);
1068 template<typename T> static void
1069 SVBkSb( int m, int n, const T* w, int incw,
1070 const T* u, int ldu, int uT,
1071 const T* v, int ldv, int vT,
1072 const T* b, int ldb, int nb,
1073 T* x, int ldx, double* buffer, T eps )
1075 double threshold = 0;
1076 int udelta0 = uT ? ldu : 1, udelta1 = uT ? 1 : ldu;
1077 int vdelta0 = vT ? ldv : 1, vdelta1 = vT ? 1 : ldv;
1078 int i, j, nm = std::min(m, n);
1083 for( i = 0; i < n; i++ )
1084 for( j = 0; j < nb; j++ )
1087 for( i = 0; i < nm; i++ )
1088 threshold += w[i*incw];
1091 // v * inv(w) * uT * b
1092 for( i = 0; i < nm; i++, u += udelta0, v += vdelta0 )
1094 double wi = w[i*incw];
1095 if( wi <= threshold )
1103 for( j = 0; j < m; j++ )
1104 s += u[j*udelta1]*b[j*ldb];
1109 for( j = 0; j < n; j++ )
1110 x[j*ldx] = (T)(x[j*ldx] + s*v[j*vdelta1]);
1116 for( j = 0; j < nb; j++ )
1118 MatrAXPY( m, nb, b, ldb, u, udelta1, buffer, 0 );
1119 for( j = 0; j < nb; j++ )
1124 for( j = 0; j < nb; j++ )
1125 buffer[j] = u[j*udelta1]*wi;
1127 MatrAXPY( n, nb, buffer, 0, v, vdelta1, x, ldx );
1133 SVD& SVD::operator ()(const Mat& a, int flags)
1135 integer m = a.rows, n = a.cols, mn = std::max(m, n), nm = std::min(m, n);
1136 int type = a.type(), elem_size = (int)a.elemSize();
1145 u.create( (int)m, (int)((flags & FULL_UV) ? m : nm), type );
1146 vt.create( (int)((flags & FULL_UV) ? n : nm), n, type );
1149 w.create(nm, 1, type);
1152 int a_ofs = 0, work_ofs=0, iwork_ofs=0, buf_size = 0;
1153 bool temp_a = false;
1154 double u1=0, v1=0, work1=0;
1155 float uf1=0, vf1=0, workf1=0;
1156 integer lda, ldu, ldv, lwork=-1, iwork1=0, info=0, *iwork=0;
1157 char mode[] = {u.data || vt.data ? 'S' : 'N', '\0'};
1159 if( m != n && !(flags & NO_UV) && (flags & FULL_UV) )
1162 if( !(flags & MODIFY_A) )
1164 if( mode[0] == 'N' || mode[0] == 'A' )
1166 else if( ((vt.data && a.size() == vt.size()) || (u.data && a.size() == u.size())) &&
1174 if( type == CV_32F )
1176 sgesdd_(mode, &n, &m, (float*)a.data, &lda, (float*)w.data,
1177 &vf1, &ldv, &uf1, &ldu, &workf1, &lwork, &iwork1, &info );
1178 lwork = cvRound(workf1);
1182 dgesdd_(mode, &n, &m, (double*)a.data, &lda, (double*)w.data,
1183 &v1, &ldv, &u1, &ldu, &work1, &lwork, &iwork1, &info );
1184 lwork = cvRound(work1);
1191 buf_size += n*m*elem_size;
1193 work_ofs = buf_size;
1194 buf_size += lwork*elem_size;
1195 buf_size = cvAlign(buf_size, sizeof(iwork[0]));
1196 iwork_ofs = buf_size;
1197 buf_size += 8*nm*sizeof(integer);
1199 AutoBuffer<uchar> buf(buf_size);
1200 uchar* buffer = (uchar*)buf;
1204 _a = Mat(a.rows, a.cols, type, buffer );
1208 if( !(flags & MODIFY_A) && !temp_a )
1210 if( vt.data && a.size() == vt.size() )
1215 else if( u.data && a.size() == u.size() )
1222 if( mode[0] != 'N' )
1224 ldv = (int)(vt.step ? vt.step/elem_size : vt.cols);
1225 ldu = (int)(u.step ? u.step/elem_size : u.cols);
1228 lda = (int)(_a.step ? _a.step/elem_size : _a.cols);
1229 if( type == CV_32F )
1231 sgesdd_(mode, &n, &m, (float*)_a.data, &lda, (float*)w.data,
1232 (float*)vt.data, &ldv, (float*)u.data, &ldu,
1233 (float*)(buffer + work_ofs), &lwork, (integer*)(buffer + iwork_ofs), &info );
1237 dgesdd_(mode, &n, &m, (double*)_a.data, &lda, (double*)w.data,
1238 (double*)vt.data, &ldv, (double*)u.data, &ldu,
1239 (double*)(buffer + work_ofs), &lwork, (integer*)(buffer + iwork_ofs), &info );
1241 CV_Assert(info >= 0);
1252 void SVD::backSubst( const Mat& rhs, Mat& dst ) const
1254 int type = w.type(), esz = (int)w.elemSize();
1255 int m = u.rows, n = vt.cols, nb = rhs.data ? rhs.cols : m;
1256 AutoBuffer<double> buffer(nb);
1257 CV_Assert( u.data && vt.data && w.data );
1260 CV_Assert( rhs.type() == type && rhs.rows == m );
1262 dst.create( n, nb, type );
1263 if( type == CV_32F )
1264 SVBkSb(m, n, (float*)w.data, 1, (float*)u.data, (int)(u.step/esz), false,
1265 (float*)vt.data, (int)(vt.step/esz), true, (float*)rhs.data, (int)(rhs.step/esz),
1266 nb, (float*)dst.data, (int)(dst.step/esz), buffer, 10*FLT_EPSILON );
1267 else if( type == CV_64F )
1268 SVBkSb(m, n, (double*)w.data, 1, (double*)u.data, (int)(u.step/esz), false,
1269 (double*)vt.data, (int)(vt.step/esz), true, (double*)rhs.data, (int)(rhs.step/esz),
1270 nb, (double*)dst.data, (int)(dst.step/esz), buffer, 2*DBL_EPSILON );
1272 CV_Error( CV_StsUnsupportedFormat, "" );
1279 cvDet( const CvArr* arr )
1281 return determinant(cv::cvarrToMat(arr));
1286 cvInvert( const CvArr* srcarr, CvArr* dstarr, int method )
1288 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
1290 CV_Assert( src.type() == dst.type() && src.rows == dst.cols && src.cols == dst.rows );
1291 return cv::invert( src, dst, method == CV_CHOLESKY ? cv::DECOMP_CHOLESKY :
1292 method == CV_SVD || method == CV_SVD_SYM ? cv::DECOMP_SVD : cv::DECOMP_LU );
1297 cvSolve( const CvArr* Aarr, const CvArr* barr, CvArr* xarr, int method )
1299 cv::Mat A = cv::cvarrToMat(Aarr), b = cv::cvarrToMat(barr), x = cv::cvarrToMat(xarr);
1301 CV_Assert( A.type() == x.type() && A.cols == x.rows && x.cols == b.cols );
1302 return cv::solve( A, b, x, method == CV_CHOLESKY ? cv::DECOMP_CHOLESKY :
1303 method == CV_SVD || method == CV_SVD_SYM ? cv::DECOMP_SVD :
1304 A.rows > A.cols ? cv::DECOMP_QR : cv::DECOMP_LU );
1309 cvEigenVV( CvArr* srcarr, CvArr* evectsarr, CvArr* evalsarr, double,
1310 int lowindex, int highindex)
1312 cv::Mat src = cv::cvarrToMat(srcarr), evals = cv::cvarrToMat(evalsarr);
1315 cv::Mat evects = cv::cvarrToMat(evectsarr);
1316 eigen(src, evals, evects, lowindex, highindex);
1319 eigen(src, evals, lowindex, highindex);
1324 cvSVD( CvArr* aarr, CvArr* warr, CvArr* uarr, CvArr* varr, int flags )
1326 cv::Mat a = cv::cvarrToMat(aarr), w = cv::cvarrToMat(warr), u, v;
1327 int m = a.rows, n = a.cols, type = a.type(), mn = std::max(m, n), nm = std::min(m, n);
1329 CV_Assert( w.type() == type &&
1330 (w.size() == cv::Size(nm,1) || w.size() == cv::Size(1, nm) ||
1331 w.size() == cv::Size(nm, nm) || w.size() == cv::Size(n, m)) );
1335 if( w.size() == cv::Size(nm, 1) )
1336 svd.w = cv::Mat(nm, 1, type, w.data );
1337 else if( w.isContinuous() )
1342 u = cv::cvarrToMat(uarr);
1343 CV_Assert( u.type() == type );
1349 v = cv::cvarrToMat(varr);
1350 CV_Assert( v.type() == type );
1354 svd(a, ((flags & CV_SVD_MODIFY_A) ? cv::SVD::MODIFY_A : 0) |
1355 ((!svd.u.data && !svd.vt.data) ? cv::SVD::NO_UV : 0) |
1356 ((m != n && (svd.u.size() == cv::Size(mn, mn) ||
1357 svd.vt.size() == cv::Size(mn, mn))) ? cv::SVD::FULL_UV : 0));
1361 if( flags & CV_SVD_U_T )
1362 cv::transpose( svd.u, u );
1363 else if( u.data != svd.u.data )
1365 CV_Assert( u.size() == svd.u.size() );
1372 if( !(flags & CV_SVD_V_T) )
1373 cv::transpose( svd.vt, v );
1374 else if( v.data != svd.vt.data )
1376 CV_Assert( v.size() == svd.vt.size() );
1381 if( w.data != svd.w.data )
1383 if( w.size() == svd.w.size() )
1388 cv::Mat wd = w.diag();
1396 cvSVBkSb( const CvArr* warr, const CvArr* uarr,
1397 const CvArr* varr, const CvArr* rhsarr,
1398 CvArr* dstarr, int flags )
1400 cv::Mat w = cv::cvarrToMat(warr), u = cv::cvarrToMat(uarr),
1401 v = cv::cvarrToMat(varr), rhs, dst = cv::cvarrToMat(dstarr);
1402 int type = w.type();
1403 bool uT = (flags & CV_SVD_U_T) != 0, vT = (flags & CV_SVD_V_T) != 0;
1404 int m = !uT ? u.rows : u.cols;
1405 int n = vT ? v.cols : v.rows;
1406 int nm = std::min(n, m), nb;
1407 int esz = (int)w.elemSize();
1408 int incw = w.size() == cv::Size(nm, 1) ? 1 : (int)(w.step/esz) + (w.cols > 1 && w.rows > 1);
1410 CV_Assert( type == u.type() && type == v.type() &&
1411 type == dst.type() && dst.rows == n &&
1412 (!uT ? u.cols : u.rows) >= nm && (vT ? v.rows : v.cols) >= nm &&
1413 (w.size() == cv::Size(nm, 1) || w.size() == cv::Size(1, nm) ||
1414 w.size() == cv::Size(nm, nm) || w.size() == cv::Size(n, m)));
1418 rhs = cv::cvarrToMat(rhsarr);
1420 CV_Assert( type == rhs.type() );
1425 CV_Assert( dst.cols == nb );
1426 cv::AutoBuffer<double> buffer(nb);
1428 if( type == CV_32F )
1429 cv::SVBkSb(m, n, (float*)w.data, incw, (float*)u.data, (int)(u.step/esz), uT,
1430 (float*)v.data, (int)(v.step/esz), vT, (float*)rhs.data, (int)(rhs.step/esz),
1431 nb, (float*)dst.data, (int)(dst.step/esz), buffer, 2*FLT_EPSILON );
1433 cv::SVBkSb(m, n, (double*)w.data, incw, (double*)u.data, (int)(u.step/esz), uT,
1434 (double*)v.data, (int)(v.step/esz), vT, (double*)rhs.data, (int)(rhs.step/esz),
1435 nb, (double*)dst.data, (int)(dst.step/esz), buffer, 2*DBL_EPSILON );