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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
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 Intel Corporation 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.
45 /////////////////////////////////////////////////////////////////////////////////////////
47 #define icvGivens_64f( n, x, y, c, s ) \
53 for( _i = 0; _i < n; _i++ ) \
57 _x[_i] = t0*c + t1*s; \
58 _y[_i] = -t0*s + t1*c; \
63 /* y[0:m,0:n] += diag(a[0:1,0:m]) * x[0:m,0:n] */
65 icvMatrAXPY_64f( int m, int n, const double* x, int dx,
66 const double* a, double* y, int dy )
70 for( i = 0; i < m; i++, x += dx, y += dy )
74 for( j = 0; j <= n - 4; j += 4 )
76 double t0 = y[j] + s*x[j];
77 double t1 = y[j+1] + s*x[j+1];
80 t0 = y[j+2] + s*x[j+2];
81 t1 = y[j+3] + s*x[j+3];
86 for( ; j < n; j++ ) y[j] += s*x[j];
91 /* y[1:m,-1] = h*y[1:m,0:n]*x[0:1,0:n]'*x[-1] (this is used for U&V reconstruction)
92 y[1:m,0:n] += h*y[1:m,0:n]*x[0:1,0:n]'*x[0:1,0:n] */
94 icvMatrAXPY3_64f( int m, int n, const double* x, int l, double* y, double h )
98 for( i = 1; i < m; i++ )
104 for( j = 0; j <= n - 4; j += 4 )
105 s += x[j]*y[j] + x[j+1]*y[j+1] + x[j+2]*y[j+2] + x[j+3]*y[j+3];
107 for( ; j < n; j++ ) s += x[j]*y[j];
112 for( j = 0; j <= n - 4; j += 4 )
114 double t0 = y[j] + s*x[j];
115 double t1 = y[j+1] + s*x[j+1];
118 t0 = y[j+2] + s*x[j+2];
119 t1 = y[j+3] + s*x[j+3];
124 for( ; j < n; j++ ) y[j] += s*x[j];
129 #define icvGivens_32f( n, x, y, c, s ) \
135 for( _i = 0; _i < n; _i++ ) \
137 double t0 = _x[_i]; \
138 double t1 = _y[_i]; \
139 _x[_i] = (float)(t0*c + t1*s); \
140 _y[_i] = (float)(-t0*s + t1*c);\
145 icvMatrAXPY_32f( int m, int n, const float* x, int dx,
146 const float* a, float* y, int dy )
150 for( i = 0; i < m; i++, x += dx, y += dy )
154 for( j = 0; j <= n - 4; j += 4 )
156 double t0 = y[j] + s*x[j];
157 double t1 = y[j+1] + s*x[j+1];
160 t0 = y[j+2] + s*x[j+2];
161 t1 = y[j+3] + s*x[j+3];
167 y[j] = (float)(y[j] + s*x[j]);
173 icvMatrAXPY3_32f( int m, int n, const float* x, int l, float* y, double h )
177 for( i = 1; i < m; i++ )
182 for( j = 0; j <= n - 4; j += 4 )
183 s += x[j]*y[j] + x[j+1]*y[j+1] + x[j+2]*y[j+2] + x[j+3]*y[j+3];
185 for( ; j < n; j++ ) s += x[j]*y[j];
188 y[-1] = (float)(s*x[-1]);
190 for( j = 0; j <= n - 4; j += 4 )
192 double t0 = y[j] + s*x[j];
193 double t1 = y[j+1] + s*x[j+1];
196 t0 = y[j+2] + s*x[j+2];
197 t1 = y[j+3] + s*x[j+3];
202 for( ; j < n; j++ ) y[j] = (float)(y[j] + s*x[j]);
206 /* accurate hypotenuse calculation */
208 pythag( double a, double b )
215 a *= sqrt( 1. + b * b );
220 a = b * sqrt( 1. + a * a );
226 /****************************************************************************************/
227 /****************************************************************************************/
232 icvSVD_64f( double* a, int lda, int m, int n,
234 double* uT, int lduT, int nu,
235 double* vT, int ldvT,
242 double ku0 = 0, kv0 = 0;
244 double *a1, *u0 = uT, *v0 = vT;
250 double* hv0 = (double*)cvStackAlloc( (m+2)*sizeof(hv0[0])) + 1;
259 memset( w, 0, nm * sizeof( w[0] ));
260 memset( e, 0, nm * sizeof( e[0] ));
265 /* transform a to bi-diagonal form */
275 update_u = uT && m1 > m - nu;
276 hv = update_u ? uT : hv0;
278 for( j = 0, a1 = a; j < m1; j++, a1 += lda )
281 scale += fabs( hv[j] = t );
286 double f = 1./scale, g, s = 0;
288 for( j = 0; j < m1; j++ )
290 double t = (hv[j] *= f);
299 h = 1. / (f * g - s);
301 memset( temp, 0, n1 * sizeof( temp[0] ));
303 /* calc temp[0:n-i] = a[i:m,i:n]'*hv[0:m-i] */
304 icvMatrAXPY_64f( m1, n1 - 1, a + 1, lda, hv, temp + 1, 0 );
305 for( k = 1; k < n1; k++ ) temp[k] *= h;
307 /* modify a: a[i:m,i:n] = a[i:m,i:n] + hv[0:m-i]*temp[0:n-i]' */
308 icvMatrAXPY_64f( m1, n1 - 1, temp + 1, 0, hv, a + 1, lda );
313 /* store -2/(hv'*hv) */
331 update_v = vT && n1 > n - nv;
333 hv = update_v ? vT : hv0;
335 for( j = 0; j < n1; j++ )
338 scale += fabs( hv[j] = t );
343 double f = 1./scale, g, s = 0;
345 for( j = 0; j < n1; j++ )
347 double t = (hv[j] *= f);
356 h = 1. / (f * g - s);
359 /* update a[i:m:i+1:n] = a[i:m,i+1:n] + (a[i:m,i+1:n]*hv[0:m-i])*... */
360 icvMatrAXPY3_64f( m1, n1, hv, lda, a, h );
366 /* store -2/(hv'*hv) */
384 /* accumulate left transformations */
389 for( i = m1; i < nu; i++, uT += lduT )
391 memset( uT + m1, 0, (m - m1) * sizeof( uT[0] ));
395 for( i = m1 - 1; i >= 0; i-- )
402 hv = u0 + (lduT + 1) * i;
403 h = i == 0 ? ku0 : hv[-1];
410 icvMatrAXPY3_64f( lh, l-1, hv+1, lduT, uT+1, h );
413 for( k = 0; k < l; k++ ) hv[k] *= s;
418 for( j = 1; j < l; j++ )
420 for( j = 1; j < lh; j++ )
428 /* accumulate right transformations */
433 for( i = n1; i < nv; i++, vT += ldvT )
435 memset( vT + n1, 0, (n - n1) * sizeof( vT[0] ));
439 for( i = n1 - 1; i >= 0; i-- )
445 hv = v0 + (ldvT + 1) * i;
446 h = i == 0 ? kv0 : hv[-1];
453 icvMatrAXPY3_64f( lh, l-1, hv+1, ldvT, vT+1, h );
456 for( k = 0; k < l; k++ ) hv[k] *= s;
461 for( j = 1; j < l; j++ )
463 for( j = 1; j < lh; j++ )
471 for( i = 0; i < nm; i++ )
473 double tnorm = fabs( w[i] );
474 tnorm += fabs( e[i] );
480 anorm *= DBL_EPSILON;
482 /* diagonalization of the bidiagonal form */
483 for( k = nm - 1; k >= 0; k-- )
488 for( ;; ) /* do iterations */
490 double c, s, f, g, x, y;
493 /* test for splitting */
494 for( l = k; l >= 0; l-- )
496 if( fabs(e[l]) <= anorm )
502 if( fabs(w[l - 1]) <= anorm )
511 for( i = l; i <= k; i++ )
517 if( anorm + fabs( f ) == anorm )
527 icvGivens_64f( m, uT + lduT * (l - 1), uT + lduT * i, c, s );
532 if( l == k || iters++ == MAX_ITERS )
535 /* shift from bottom 2x2 minor */
540 f = 0.5 * (((g + z) / h) * ((g - z) / y) + y / h - h / y);
544 f = x - (z / x) * z + (h / x) * (y / (f + g) - h);
545 /* next QR transformation */
548 for( i = l + 1; i <= k; i++ )
564 icvGivens_64f( n, vT + ldvT * (i - 1), vT + ldvT * i, c, s );
569 /* rotation can be arbitrary if z == 0 */
579 icvGivens_64f( m, uT + lduT * (i - 1), uT + lduT * i, c, s );
585 } /* end of iteration loop */
587 if( iters > MAX_ITERS )
595 for( j = 0; j < n; j++ )
596 vT[j + k * ldvT] = -vT[j + k * ldvT];
599 } /* end of diagonalization loop */
601 /* sort singular values and corresponding values */
602 for( i = 0; i < nm; i++ )
605 for( j = i + 1; j < nm; j++ )
612 CV_SWAP( w[i], w[k], t );
615 for( j = 0; j < n; j++ )
616 CV_SWAP( vT[j + ldvT*k], vT[j + ldvT*i], t );
619 for( j = 0; j < m; j++ )
620 CV_SWAP( uT[j + lduT*k], uT[j + lduT*i], t );
627 icvSVD_32f( float* a, int lda, int m, int n,
629 float* uT, int lduT, int nu,
637 double ku0 = 0, kv0 = 0;
639 float *a1, *u0 = uT, *v0 = vT;
645 float* hv0 = (float*)cvStackAlloc( (m+2)*sizeof(hv0[0])) + 1;
655 memset( w, 0, nm * sizeof( w[0] ));
656 memset( e, 0, nm * sizeof( e[0] ));
661 /* transform a to bi-diagonal form */
672 update_u = uT && m1 > m - nu;
673 hv = update_u ? uT : hv0;
675 for( j = 0, a1 = a; j < m1; j++, a1 += lda )
678 scale += fabs( hv[j] = (float)t );
683 double f = 1./scale, g, s = 0;
685 for( j = 0; j < m1; j++ )
687 double t = (hv[j] = (float)(hv[j]*f));
695 hv[0] = (float)(f - g);
696 h = 1. / (f * g - s);
698 memset( temp, 0, n1 * sizeof( temp[0] ));
700 /* calc temp[0:n-i] = a[i:m,i:n]'*hv[0:m-i] */
701 icvMatrAXPY_32f( m1, n1 - 1, a + 1, lda, hv, temp + 1, 0 );
703 for( k = 1; k < n1; k++ ) temp[k] = (float)(temp[k]*h);
705 /* modify a: a[i:m,i:n] = a[i:m,i:n] + hv[0:m-i]*temp[0:n-i]' */
706 icvMatrAXPY_32f( m1, n1 - 1, temp + 1, 0, hv, a + 1, lda );
707 *w1 = (float)(g*scale);
711 /* store -2/(hv'*hv) */
729 update_v = vT && n1 > n - nv;
730 hv = update_v ? vT : hv0;
732 for( j = 0; j < n1; j++ )
735 scale += fabs( hv[j] = (float)t );
740 double f = 1./scale, g, s = 0;
742 for( j = 0; j < n1; j++ )
744 double t = (hv[j] = (float)(hv[j]*f));
752 hv[0] = (float)(f - g);
753 h = 1. / (f * g - s);
756 /* update a[i:m:i+1:n] = a[i:m,i+1:n] + (a[i:m,i+1:n]*hv[0:m-i])*... */
757 icvMatrAXPY3_32f( m1, n1, hv, lda, a, h );
759 *e1 = (float)(g*scale);
763 /* store -2/(hv'*hv) */
781 /* accumulate left transformations */
786 for( i = m1; i < nu; i++, uT += lduT )
788 memset( uT + m1, 0, (m - m1) * sizeof( uT[0] ));
792 for( i = m1 - 1; i >= 0; i-- )
799 hv = u0 + (lduT + 1) * i;
800 h = i == 0 ? ku0 : hv[-1];
807 icvMatrAXPY3_32f( lh, l-1, hv+1, lduT, uT+1, h );
810 for( k = 0; k < l; k++ ) hv[k] = (float)(hv[k]*s);
815 for( j = 1; j < l; j++ )
817 for( j = 1; j < lh; j++ )
825 /* accumulate right transformations */
830 for( i = n1; i < nv; i++, vT += ldvT )
832 memset( vT + n1, 0, (n - n1) * sizeof( vT[0] ));
836 for( i = n1 - 1; i >= 0; i-- )
842 hv = v0 + (ldvT + 1) * i;
843 h = i == 0 ? kv0 : hv[-1];
850 icvMatrAXPY3_32f( lh, l-1, hv+1, ldvT, vT+1, h );
853 for( k = 0; k < l; k++ ) hv[k] = (float)(hv[k]*s);
858 for( j = 1; j < l; j++ )
860 for( j = 1; j < lh; j++ )
868 for( i = 0; i < nm; i++ )
870 double tnorm = fabs( w[i] );
871 tnorm += fabs( e[i] );
877 anorm *= FLT_EPSILON;
879 /* diagonalization of the bidiagonal form */
880 for( k = nm - 1; k >= 0; k-- )
885 for( ;; ) /* do iterations */
887 double c, s, f, g, x, y;
890 /* test for splitting */
891 for( l = k; l >= 0; l-- )
893 if( fabs( e[l] ) <= anorm )
899 if( fabs( w[l - 1] ) <= anorm )
908 for( i = l; i <= k; i++ )
911 e[i] = (float)(e[i]*c);
913 if( anorm + fabs( f ) == anorm )
923 icvGivens_32f( m, uT + lduT * (l - 1), uT + lduT * i, c, s );
928 if( l == k || iters++ == MAX_ITERS )
931 /* shift from bottom 2x2 minor */
936 f = 0.5 * (((g + z) / h) * ((g - z) / y) + y / h - h / y);
940 f = x - (z / x) * z + (h / x) * (y / (f + g) - h);
941 /* next QR transformation */
944 for( i = l + 1; i <= k; i++ )
960 icvGivens_32f( n, vT + ldvT * (i - 1), vT + ldvT * i, c, s );
965 /* rotation can be arbitrary if z == 0 */
975 icvGivens_32f( m, uT + lduT * (i - 1), uT + lduT * i, c, s );
981 } /* end of iteration loop */
983 if( iters > MAX_ITERS )
991 for( j = 0; j < n; j++ )
992 vT[j + k * ldvT] = -vT[j + k * ldvT];
995 } /* end of diagonalization loop */
997 /* sort singular values and corresponding vectors */
998 for( i = 0; i < nm; i++ )
1001 for( j = i + 1; j < nm; j++ )
1008 CV_SWAP( w[i], w[k], t );
1011 for( j = 0; j < n; j++ )
1012 CV_SWAP( vT[j + ldvT*k], vT[j + ldvT*i], t );
1015 for( j = 0; j < m; j++ )
1016 CV_SWAP( uT[j + lduT*k], uT[j + lduT*i], t );
1023 icvSVBkSb_64f( int m, int n, const double* w,
1024 const double* uT, int lduT,
1025 const double* vT, int ldvT,
1026 const double* b, int ldb, int nb,
1027 double* x, int ldx, double* buffer )
1029 double threshold = 0;
1030 int i, j, nm = MIN( m, n );
1035 for( i = 0; i < n; i++ )
1036 memset( x + i*ldx, 0, nb*sizeof(x[0]));
1038 for( i = 0; i < nm; i++ )
1040 threshold *= 2*DBL_EPSILON;
1042 /* vT * inv(w) * uT * b */
1043 for( i = 0; i < nm; i++, uT += lduT, vT += ldvT )
1047 if( wi > threshold )
1058 for( j = 0; j <= m - 4; j += 4 )
1059 s += uT[j]*b[j] + uT[j+1]*b[j+1] + uT[j+2]*b[j+2] + uT[j+3]*b[j+3];
1065 for( j = 0; j < m; j++ )
1066 s += uT[j]*b[j*ldb];
1074 for( j = 0; j <= n - 4; j += 4 )
1076 double t0 = x[j] + s*vT[j];
1077 double t1 = x[j+1] + s*vT[j+1];
1080 t0 = x[j+2] + s*vT[j+2];
1081 t1 = x[j+3] + s*vT[j+3];
1091 for( j = 0; j < n; j++ )
1092 x[j*ldx] += s*vT[j];
1099 memset( buffer, 0, nb*sizeof(buffer[0]));
1100 icvMatrAXPY_64f( m, nb, b, ldb, uT, buffer, 0 );
1101 for( j = 0; j < nb; j++ )
1106 for( j = 0; j < nb; j++ )
1107 buffer[j] = uT[j]*wi;
1109 icvMatrAXPY_64f( n, nb, buffer, 0, vT, x, ldx );
1117 icvSVBkSb_32f( int m, int n, const float* w,
1118 const float* uT, int lduT,
1119 const float* vT, int ldvT,
1120 const float* b, int ldb, int nb,
1121 float* x, int ldx, float* buffer )
1123 float threshold = 0.f;
1124 int i, j, nm = MIN( m, n );
1129 for( i = 0; i < n; i++ )
1130 memset( x + i*ldx, 0, nb*sizeof(x[0]));
1132 for( i = 0; i < nm; i++ )
1134 threshold *= 2*FLT_EPSILON;
1136 /* vT * inv(w) * uT * b */
1137 for( i = 0; i < nm; i++, uT += lduT, vT += ldvT )
1141 if( wi > threshold )
1152 for( j = 0; j <= m - 4; j += 4 )
1153 s += uT[j]*b[j] + uT[j+1]*b[j+1] + uT[j+2]*b[j+2] + uT[j+3]*b[j+3];
1159 for( j = 0; j < m; j++ )
1160 s += uT[j]*b[j*ldb];
1169 for( j = 0; j <= n - 4; j += 4 )
1171 double t0 = x[j] + s*vT[j];
1172 double t1 = x[j+1] + s*vT[j+1];
1175 t0 = x[j+2] + s*vT[j+2];
1176 t1 = x[j+3] + s*vT[j+3];
1182 x[j] = (float)(x[j] + s*vT[j]);
1186 for( j = 0; j < n; j++ )
1187 x[j*ldx] = (float)(x[j*ldx] + s*vT[j]);
1194 memset( buffer, 0, nb*sizeof(buffer[0]));
1195 icvMatrAXPY_32f( m, nb, b, ldb, uT, buffer, 0 );
1196 for( j = 0; j < nb; j++ )
1197 buffer[j] = (float)(buffer[j]*wi);
1201 for( j = 0; j < nb; j++ )
1202 buffer[j] = (float)(uT[j]*wi);
1204 icvMatrAXPY_32f( n, nb, buffer, 0, vT, x, ldx );
1212 cvSVD( CvArr* aarr, CvArr* warr, CvArr* uarr, CvArr* varr, int flags )
1215 int local_alloc = 0;
1217 CV_FUNCNAME( "cvSVD" );
1221 CvMat astub, *a = (CvMat*)aarr;
1222 CvMat wstub, *w = (CvMat*)warr;
1228 int a_buf_offset = 0, u_buf_offset = 0, buf_size, pix_size;
1229 int temp_u = 0, /* temporary storage for U is needed */
1230 t_svd; /* special case: a->rows < a->cols */
1233 int u_rows = 0, u_cols = 0;
1236 if( !CV_IS_MAT( a ))
1237 CV_CALL( a = cvGetMat( a, &astub ));
1239 if( !CV_IS_MAT( w ))
1240 CV_CALL( w = cvGetMat( w, &wstub ));
1242 if( !CV_ARE_TYPES_EQ( a, w ))
1243 CV_ERROR( CV_StsUnmatchedFormats, "" );
1245 if( a->rows >= a->cols )
1256 CV_SWAP( uarr, varr, t );
1258 flags = (flags & CV_SVD_U_T ? CV_SVD_V_T : 0)|
1259 (flags & CV_SVD_V_T ? CV_SVD_U_T : 0);
1270 w_is_mat = w_cols > 1 && w_rows > 1;
1272 if( !w_is_mat && CV_IS_MAT_CONT(w->type) && w_cols + w_rows - 1 == n )
1277 if( !CV_IS_MAT( u ))
1278 CV_CALL( u = cvGetMat( u, &ustub ));
1280 if( !(flags & CV_SVD_U_T) )
1291 if( !CV_ARE_TYPES_EQ( a, u ))
1292 CV_ERROR( CV_StsUnmatchedFormats, "" );
1294 if( u_rows != m || (u_cols != m && u_cols != n))
1295 CV_ERROR( CV_StsUnmatchedSizes, !t_svd ? "U matrix has unappropriate size" :
1296 "V matrix has unappropriate size" );
1298 temp_u = (u_rows != u_cols && !(flags & CV_SVD_U_T)) || u->data.ptr==a->data.ptr;
1300 if( w_is_mat && u_cols != w_rows )
1301 CV_ERROR( CV_StsUnmatchedSizes, !t_svd ? "U and W have incompatible sizes" :
1302 "V and W have incompatible sizes" );
1315 if( !CV_IS_MAT( v ))
1316 CV_CALL( v = cvGetMat( v, &vstub ));
1318 if( !(flags & CV_SVD_V_T) )
1329 if( !CV_ARE_TYPES_EQ( a, v ))
1330 CV_ERROR( CV_StsUnmatchedFormats, "" );
1332 if( v_rows != n || v_cols != n )
1333 CV_ERROR( CV_StsUnmatchedSizes, t_svd ? "U matrix has unappropriate size" :
1334 "V matrix has unappropriate size" );
1336 if( w_is_mat && w_cols != v_cols )
1337 CV_ERROR( CV_StsUnmatchedSizes, t_svd ? "U and W have incompatible sizes" :
1338 "V and W have incompatible sizes" );
1347 type = CV_MAT_TYPE( a->type );
1348 pix_size = CV_ELEM_SIZE(type);
1351 if( !(flags & CV_SVD_MODIFY_A) )
1353 a_buf_offset = buf_size;
1354 buf_size += a->rows*a->cols;
1359 u_buf_offset = buf_size;
1360 buf_size += u->rows*u->cols;
1363 buf_size *= pix_size;
1365 if( buf_size <= CV_MAX_LOCAL_SIZE )
1367 buffer = (uchar*)cvStackAlloc( buf_size );
1372 CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
1375 if( !(flags & CV_SVD_MODIFY_A) )
1377 cvInitMatHeader( &tmat, m, n, type,
1378 buffer + a_buf_offset*pix_size );
1388 cvInitMatHeader( &ustub, u_cols, u_rows, type, buffer + u_buf_offset*pix_size );
1393 tw = buffer + (n + m)*pix_size;
1395 if( type == CV_32FC1 )
1397 icvSVD_32f( a->data.fl, a->step/sizeof(float), a->rows, a->cols,
1398 (float*)tw, u->data.fl, u->step/sizeof(float), u_cols,
1399 v->data.fl, v->step/sizeof(float), (float*)buffer );
1401 else if( type == CV_64FC1 )
1403 icvSVD_64f( a->data.db, a->step/sizeof(double), a->rows, a->cols,
1404 (double*)tw, u->data.db, u->step/sizeof(double), u_cols,
1405 v->data.db, v->step/sizeof(double), (double*)buffer );
1409 CV_ERROR( CV_StsUnsupportedFormat, "" );
1412 if( tw != w->data.ptr )
1414 int shift = w->cols != 1;
1416 if( type == CV_32FC1 )
1417 for( int i = 0; i < n; i++ )
1418 ((float*)(w->data.ptr + i*w->step))[i*shift] = ((float*)tw)[i];
1420 for( int i = 0; i < n; i++ )
1421 ((double*)(w->data.ptr + i*w->step))[i*shift] = ((double*)tw)[i];
1426 if( !(flags & CV_SVD_U_T))
1430 /*CV_CHECK_NANS( uarr );*/
1435 if( !(flags & CV_SVD_V_T))
1437 /*CV_CHECK_NANS( varr );*/
1444 if( buffer && !local_alloc )
1450 cvSVBkSb( const CvArr* warr, const CvArr* uarr,
1451 const CvArr* varr, const CvArr* barr,
1452 CvArr* xarr, int flags )
1455 int local_alloc = 0;
1457 CV_FUNCNAME( "cvSVBkSb" );
1461 CvMat wstub, *w = (CvMat*)warr;
1462 CvMat bstub, *b = (CvMat*)barr;
1463 CvMat xstub, *x = (CvMat*)xarr;
1464 CvMat ustub, ustub2, *u = (CvMat*)uarr;
1465 CvMat vstub, vstub2, *v = (CvMat*)varr;
1468 int temp_u = 0, temp_v = 0;
1469 int u_buf_offset = 0, v_buf_offset = 0, w_buf_offset = 0, t_buf_offset = 0;
1470 int buf_size = 0, pix_size;
1475 if( !CV_IS_MAT( w ))
1476 CV_CALL( w = cvGetMat( w, &wstub ));
1478 if( !CV_IS_MAT( u ))
1479 CV_CALL( u = cvGetMat( u, &ustub ));
1481 if( !CV_IS_MAT( v ))
1482 CV_CALL( v = cvGetMat( v, &vstub ));
1484 if( !CV_IS_MAT( x ))
1485 CV_CALL( x = cvGetMat( x, &xstub ));
1487 if( !CV_ARE_TYPES_EQ( w, u ) || !CV_ARE_TYPES_EQ( w, v ) || !CV_ARE_TYPES_EQ( w, x ))
1488 CV_ERROR( CV_StsUnmatchedFormats, "All matrices must have the same type" );
1490 type = CV_MAT_TYPE( w->type );
1491 pix_size = CV_ELEM_SIZE(type);
1493 if( !(flags & CV_SVD_U_T) )
1496 u_buf_offset = buf_size;
1497 buf_size += u->cols*u->rows*pix_size;
1507 if( !(flags & CV_SVD_V_T) )
1510 v_buf_offset = buf_size;
1511 buf_size += v->cols*v->rows*pix_size;
1525 if( (u_rows != u_cols && v_rows != v_cols) || x->rows != v_rows )
1526 CV_ERROR( CV_StsBadSize, "V or U matrix must be square" );
1528 if( (w->rows == 1 || w->cols == 1) && w->rows + w->cols - 1 == nm )
1530 if( CV_IS_MAT_CONT(w->type) )
1534 w_buf_offset = buf_size;
1535 buf_size += nm*pix_size;
1540 if( w->cols != v_cols || w->rows != u_cols )
1541 CV_ERROR( CV_StsBadSize, "W must be 1d array of MIN(m,n) elements or "
1542 "matrix which size matches to U and V" );
1543 w_buf_offset = buf_size;
1544 buf_size += nm*pix_size;
1549 if( !CV_IS_MAT( b ))
1550 CV_CALL( b = cvGetMat( b, &bstub ));
1551 if( !CV_ARE_TYPES_EQ( w, b ))
1552 CV_ERROR( CV_StsUnmatchedFormats, "All matrices must have the same type" );
1553 if( b->cols != x->cols || b->rows != m )
1554 CV_ERROR( CV_StsUnmatchedSizes, "b matrix must have (m x x->cols) size" );
1559 memset( b, 0, sizeof(*b));
1562 t_buf_offset = buf_size;
1563 buf_size += (MAX(m,n) + b->cols)*pix_size;
1565 if( buf_size <= CV_MAX_LOCAL_SIZE )
1567 buffer = (uchar*)cvStackAlloc( buf_size );
1571 CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
1575 cvInitMatHeader( &ustub2, u_cols, u_rows, type, buffer + u_buf_offset );
1582 cvInitMatHeader( &vstub2, v_cols, v_rows, type, buffer + v_buf_offset );
1589 int i, shift = w->cols > 1 ? pix_size : 0;
1590 tw = buffer + w_buf_offset;
1591 for( i = 0; i < nm; i++ )
1592 memcpy( tw + i*pix_size, w->data.ptr + i*(w->step + shift), pix_size );
1595 if( type == CV_32FC1 )
1597 icvSVBkSb_32f( m, n, (float*)tw, u->data.fl, u->step/sizeof(float),
1598 v->data.fl, v->step/sizeof(float),
1599 b->data.fl, b->step/sizeof(float), b->cols,
1600 x->data.fl, x->step/sizeof(float),
1601 (float*)(buffer + t_buf_offset) );
1603 else if( type == CV_64FC1 )
1605 icvSVBkSb_64f( m, n, (double*)tw, u->data.db, u->step/sizeof(double),
1606 v->data.db, v->step/sizeof(double),
1607 b->data.db, b->step/sizeof(double), b->cols,
1608 x->data.db, x->step/sizeof(double),
1609 (double*)(buffer + t_buf_offset) );
1613 CV_ERROR( CV_StsUnsupportedFormat, "" );
1618 if( buffer && !local_alloc )