00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00074
00075 #include <new>
00076
00077 #include "Math/FloatMatrix.h"
00078 #include "Math/DoubleMatrix.h"
00079 #include "Math/LinearAlgebra.h"
00080 #include "Image/ImageProcessor.h"
00081 #include "Helpers/helpers.h"
00082
00083 #include <math.h>
00084 #include <float.h>
00085 #include <string.h>
00086 #include <stdlib.h>
00087 #include <stdio.h>
00088 #include <assert.h>
00089 #include <algorithm>
00090
00091
00093
00094 #define icvGivens_64f( n, x, y, c, s ) \
00095 { \
00096 int _i; \
00097 double* _x = (x); \
00098 double* _y = (y); \
00099 \
00100 for( _i = 0; _i < n; _i++ ) \
00101 { \
00102 double t0 = _x[_i]; \
00103 double t1 = _y[_i]; \
00104 _x[_i] = t0*c + t1*s; \
00105 _y[_i] = -t0*s + t1*c; \
00106 } \
00107 }
00108
00109
00110
00111 #define CV_CHECK_NANS( arr )
00112 #define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t))
00113
00114
00115 #define CV_SVD_MODIFY_A (1 << 0)
00116 #define CV_SVD_U_T (1 << 1)
00117 #define CV_SVD_V_T (1 << 2)
00118
00119
00120 #define cvStackAlloc malloc
00121
00122 namespace
00123 {
00124
00125
00126 void
00127 icvMatrAXPY_64f( int m, int n, const double* x, int dx,
00128 const double* a, double* y, int dy )
00129 {
00130 int i, j;
00131
00132 for( i = 0; i < m; i++, x += dx, y += dy )
00133 {
00134 double s = a[i];
00135
00136 for( j = 0; j <= n - 4; j += 4 )
00137 {
00138 double t0 = y[j] + s*x[j];
00139 double t1 = y[j+1] + s*x[j+1];
00140 y[j] = t0;
00141 y[j+1] = t1;
00142 t0 = y[j+2] + s*x[j+2];
00143 t1 = y[j+3] + s*x[j+3];
00144 y[j+2] = t0;
00145 y[j+3] = t1;
00146 }
00147
00148 for( ; j < n; j++ ) y[j] += s*x[j];
00149 }
00150 }
00151
00152
00153
00154
00155 void
00156 icvMatrAXPY3_64f( int m, int n, const double* x, int l, double* y, double h )
00157 {
00158 int i, j;
00159
00160 for( i = 1; i < m; i++ )
00161 {
00162 double s = 0;
00163
00164 y += l;
00165
00166 for( j = 0; j <= n - 4; j += 4 )
00167 s += x[j]*y[j] + x[j+1]*y[j+1] + x[j+2]*y[j+2] + x[j+3]*y[j+3];
00168
00169 for( ; j < n; j++ ) s += x[j]*y[j];
00170
00171 s *= h;
00172 y[-1] = s*x[-1];
00173
00174 for( j = 0; j <= n - 4; j += 4 )
00175 {
00176 double t0 = y[j] + s*x[j];
00177 double t1 = y[j+1] + s*x[j+1];
00178 y[j] = t0;
00179 y[j+1] = t1;
00180 t0 = y[j+2] + s*x[j+2];
00181 t1 = y[j+3] + s*x[j+3];
00182 y[j+2] = t0;
00183 y[j+3] = t1;
00184 }
00185
00186 for( ; j < n; j++ ) y[j] += s*x[j];
00187 }
00188 }
00189
00190
00191 #define icvGivens_32f( n, x, y, c, s ) \
00192 { \
00193 int _i; \
00194 float* _x = (x); \
00195 float* _y = (y); \
00196 \
00197 for( _i = 0; _i < n; _i++ ) \
00198 { \
00199 double t0 = _x[_i]; \
00200 double t1 = _y[_i]; \
00201 _x[_i] = (float)(t0*c + t1*s); \
00202 _y[_i] = (float)(-t0*s + t1*c);\
00203 } \
00204 }
00205
00206 void
00207 icvMatrAXPY_32f( int m, int n, const float* x, int dx,
00208 const float* a, float* y, int dy )
00209 {
00210 int i, j;
00211
00212 for( i = 0; i < m; i++, x += dx, y += dy )
00213 {
00214 double s = a[i];
00215
00216 for( j = 0; j <= n - 4; j += 4 )
00217 {
00218 double t0 = y[j] + s*x[j];
00219 double t1 = y[j+1] + s*x[j+1];
00220 y[j] = (float)t0;
00221 y[j+1] = (float)t1;
00222 t0 = y[j+2] + s*x[j+2];
00223 t1 = y[j+3] + s*x[j+3];
00224 y[j+2] = (float)t0;
00225 y[j+3] = (float)t1;
00226 }
00227
00228 for( ; j < n; j++ )
00229 y[j] = (float)(y[j] + s*x[j]);
00230 }
00231 }
00232
00233
00234 void
00235 icvMatrAXPY3_32f( int m, int n, const float* x, int l, float* y, double h )
00236 {
00237 int i, j;
00238
00239 for( i = 1; i < m; i++ )
00240 {
00241 double s = 0;
00242 y += l;
00243
00244 for( j = 0; j <= n - 4; j += 4 )
00245 s += x[j]*y[j] + x[j+1]*y[j+1] + x[j+2]*y[j+2] + x[j+3]*y[j+3];
00246
00247 for( ; j < n; j++ ) s += x[j]*y[j];
00248
00249 s *= h;
00250 y[-1] = (float)(s*x[-1]);
00251
00252 for( j = 0; j <= n - 4; j += 4 )
00253 {
00254 double t0 = y[j] + s*x[j];
00255 double t1 = y[j+1] + s*x[j+1];
00256 y[j] = (float)t0;
00257 y[j+1] = (float)t1;
00258 t0 = y[j+2] + s*x[j+2];
00259 t1 = y[j+3] + s*x[j+3];
00260 y[j+2] = (float)t0;
00261 y[j+3] = (float)t1;
00262 }
00263
00264 for( ; j < n; j++ ) y[j] = (float)(y[j] + s*x[j]);
00265 }
00266 }
00267
00268
00269 double
00270 pythag( double a, double b )
00271 {
00272 a = fabs( a );
00273 b = fabs( b );
00274 if( a > b )
00275 {
00276 b /= a;
00277 a *= sqrt( 1. + b * b );
00278 }
00279 else if( b != 0 )
00280 {
00281 a /= b;
00282 a = b * sqrt( 1. + a * a );
00283 }
00284
00285 return a;
00286 }
00287
00288
00289
00290
00291 #define MAX_ITERS 30
00292
00293 void
00294 icvSVD_64f( double* a, int lda, int m, int n,
00295 double* w,
00296 double* uT, int lduT, int nu,
00297 double* vT, int ldvT,
00298 double* buffer )
00299 {
00300 double* e;
00301 double* temp;
00302 double *w1, *e1;
00303 double *hv;
00304 double ku0 = 0, kv0 = 0;
00305 double anorm = 0;
00306 double *a1, *u0 = uT, *v0 = vT;
00307 double scale, h;
00308 int i, j, k, l;
00309 int nm, m1, n1;
00310 int nv = n;
00311 int iters = 0;
00312 double* hv0 = (double*)cvStackAlloc( (m+2)*sizeof(hv0[0])) + 1;
00313
00314 e = buffer;
00315 w1 = w;
00316 e1 = e + 1;
00317 nm = n;
00318
00319 temp = buffer + nm;
00320
00321 memset( w, 0, nm * sizeof( w[0] ));
00322 memset( e, 0, nm * sizeof( e[0] ));
00323
00324 m1 = m;
00325 n1 = n;
00326
00327
00328 for( ;; )
00329 {
00330 int update_u;
00331 int update_v;
00332
00333 if( m1 == 0 )
00334 break;
00335
00336 scale = h = 0;
00337 update_u = uT && m1 > m - nu;
00338 hv = update_u ? uT : hv0;
00339
00340 for( j = 0, a1 = a; j < m1; j++, a1 += lda )
00341 {
00342 double t = a1[0];
00343 scale += fabs( hv[j] = t );
00344 }
00345
00346 if( scale != 0 )
00347 {
00348 double f = 1./scale, g, s = 0;
00349
00350 for( j = 0; j < m1; j++ )
00351 {
00352 double t = (hv[j] *= f);
00353 s += t * t;
00354 }
00355
00356 g = sqrt( s );
00357 f = hv[0];
00358 if( f >= 0 )
00359 g = -g;
00360 hv[0] = f - g;
00361 h = 1. / (f * g - s);
00362
00363 memset( temp, 0, n1 * sizeof( temp[0] ));
00364
00365
00366 icvMatrAXPY_64f( m1, n1 - 1, a + 1, lda, hv, temp + 1, 0 );
00367 for( k = 1; k < n1; k++ ) temp[k] *= h;
00368
00369
00370 icvMatrAXPY_64f( m1, n1 - 1, temp + 1, 0, hv, a + 1, lda );
00371 *w1 = g*scale;
00372 }
00373 w1++;
00374
00375
00376 if( update_u )
00377 {
00378 if( m1 == m )
00379 ku0 = h;
00380 else
00381 hv[-1] = h;
00382 }
00383
00384 a++;
00385 n1--;
00386 if( vT )
00387 vT += ldvT + 1;
00388
00389 if( n1 == 0 )
00390 break;
00391
00392 scale = h = 0;
00393 update_v = vT && n1 > n - nv;
00394
00395 hv = update_v ? vT : hv0;
00396
00397 for( j = 0; j < n1; j++ )
00398 {
00399 double t = a[j];
00400 scale += fabs( hv[j] = t );
00401 }
00402
00403 if( scale != 0 )
00404 {
00405 double f = 1./scale, g, s = 0;
00406
00407 for( j = 0; j < n1; j++ )
00408 {
00409 double t = (hv[j] *= f);
00410 s += t * t;
00411 }
00412
00413 g = sqrt( s );
00414 f = hv[0];
00415 if( f >= 0 )
00416 g = -g;
00417 hv[0] = f - g;
00418 h = 1. / (f * g - s);
00419 hv[-1] = 0.;
00420
00421
00422 icvMatrAXPY3_64f( m1, n1, hv, lda, a, h );
00423
00424 *e1 = g*scale;
00425 }
00426 e1++;
00427
00428
00429 if( update_v )
00430 {
00431 if( n1 == n )
00432 kv0 = h;
00433 else
00434 hv[-1] = h;
00435 }
00436
00437 a += lda;
00438 m1--;
00439 if( uT )
00440 uT += lduT + 1;
00441 }
00442
00443 m1 -= m1 != 0;
00444 n1 -= n1 != 0;
00445
00446
00447 if( uT )
00448 {
00449 m1 = m - m1;
00450 uT = u0 + m1 * lduT;
00451 for( i = m1; i < nu; i++, uT += lduT )
00452 {
00453 memset( uT + m1, 0, (m - m1) * sizeof( uT[0] ));
00454 uT[i] = 1.;
00455 }
00456
00457 for( i = m1 - 1; i >= 0; i-- )
00458 {
00459 double s;
00460 int lh = nu - i;
00461
00462 l = m - i;
00463
00464 hv = u0 + (lduT + 1) * i;
00465 h = i == 0 ? ku0 : hv[-1];
00466
00467
00468 if (h > 0) printf("assert: h <= 0 not satisfied, h = %.2f\n", h);
00469
00470 if( h != 0 )
00471 {
00472 uT = hv;
00473 icvMatrAXPY3_64f( lh, l-1, hv+1, lduT, uT+1, h );
00474
00475 s = hv[0] * h;
00476 for( k = 0; k < l; k++ ) hv[k] *= s;
00477 hv[0] += 1;
00478 }
00479 else
00480 {
00481 for( j = 1; j < l; j++ )
00482 hv[j] = 0;
00483 for( j = 1; j < lh; j++ )
00484 hv[j * lduT] = 0;
00485 hv[0] = 1;
00486 }
00487 }
00488 uT = u0;
00489 }
00490
00491
00492 if( vT )
00493 {
00494 n1 = n - n1;
00495 vT = v0 + n1 * ldvT;
00496 for( i = n1; i < nv; i++, vT += ldvT )
00497 {
00498 memset( vT + n1, 0, (n - n1) * sizeof( vT[0] ));
00499 vT[i] = 1.;
00500 }
00501
00502 for( i = n1 - 1; i >= 0; i-- )
00503 {
00504 double s;
00505 int lh = nv - i;
00506
00507 l = n - i;
00508 hv = v0 + (ldvT + 1) * i;
00509 h = i == 0 ? kv0 : hv[-1];
00510
00511
00512 if (h > 0) printf("assert: h <= 0 not satisfied, h = %.2f (2)\n", h);
00513
00514 if( h != 0 )
00515 {
00516 vT = hv;
00517 icvMatrAXPY3_64f( lh, l-1, hv+1, ldvT, vT+1, h );
00518
00519 s = hv[0] * h;
00520 for( k = 0; k < l; k++ ) hv[k] *= s;
00521 hv[0] += 1;
00522 }
00523 else
00524 {
00525 for( j = 1; j < l; j++ )
00526 hv[j] = 0;
00527 for( j = 1; j < lh; j++ )
00528 hv[j * ldvT] = 0;
00529 hv[0] = 1;
00530 }
00531 }
00532 vT = v0;
00533 }
00534
00535 for( i = 0; i < nm; i++ )
00536 {
00537 double tnorm = fabs( w[i] );
00538 tnorm += fabs( e[i] );
00539
00540 if( anorm < tnorm )
00541 anorm = tnorm;
00542 }
00543
00544 anorm *= DBL_EPSILON;
00545
00546
00547 for( k = nm - 1; k >= 0; k-- )
00548 {
00549 double z = 0;
00550 iters = 0;
00551
00552 for( ;; )
00553 {
00554 double c, s, f, g, x, y;
00555 int flag = 0;
00556
00557
00558 for( l = k; l >= 0; l-- )
00559 {
00560 if( fabs(e[l]) <= anorm )
00561 {
00562 flag = 1;
00563 break;
00564 }
00565
00566 if (l <= 0) printf("assert: l > 0 not satisfied, l = %i\n", l);
00567 if( fabs(w[l - 1]) <= anorm )
00568 break;
00569 }
00570
00571 if( !flag )
00572 {
00573 c = 0;
00574 s = 1;
00575
00576 for( i = l; i <= k; i++ )
00577 {
00578 f = s * e[i];
00579
00580 e[i] *= c;
00581
00582 if( anorm + fabs( f ) == anorm )
00583 break;
00584
00585 g = w[i];
00586 h = pythag( f, g );
00587 w[i] = h;
00588 c = g / h;
00589 s = -f / h;
00590
00591 if( uT )
00592 icvGivens_64f( m, uT + lduT * (l - 1), uT + lduT * i, c, s );
00593 }
00594 }
00595
00596 z = w[k];
00597 if( l == k || iters++ == MAX_ITERS )
00598 break;
00599
00600
00601 x = w[l];
00602 y = w[k - 1];
00603 g = e[k - 1];
00604 h = e[k];
00605 f = 0.5 * (((g + z) / h) * ((g - z) / y) + y / h - h / y);
00606 g = pythag( f, 1 );
00607 if( f < 0 )
00608 g = -g;
00609 f = x - (z / x) * z + (h / x) * (y / (f + g) - h);
00610
00611 c = s = 1;
00612
00613 for( i = l + 1; i <= k; i++ )
00614 {
00615 g = e[i];
00616 y = w[i];
00617 h = s * g;
00618 g *= c;
00619 z = pythag( f, h );
00620 e[i - 1] = z;
00621 c = f / z;
00622 s = h / z;
00623 f = x * c + g * s;
00624 g = -x * s + g * c;
00625 h = y * s;
00626 y *= c;
00627
00628 if( vT )
00629 icvGivens_64f( n, vT + ldvT * (i - 1), vT + ldvT * i, c, s );
00630
00631 z = pythag( f, h );
00632 w[i - 1] = z;
00633
00634
00635 if( z != 0 )
00636 {
00637 c = f / z;
00638 s = h / z;
00639 }
00640 f = c * g + s * y;
00641 x = -s * g + c * y;
00642
00643 if( uT )
00644 icvGivens_64f( m, uT + lduT * (i - 1), uT + lduT * i, c, s );
00645 }
00646
00647 e[l] = 0;
00648 e[k] = f;
00649 w[k] = x;
00650 }
00651
00652 if( iters > MAX_ITERS )
00653 break;
00654
00655 if( z < 0 )
00656 {
00657 w[k] = -z;
00658 if( vT )
00659 {
00660 for( j = 0; j < n; j++ )
00661 vT[j + k * ldvT] = -vT[j + k * ldvT];
00662 }
00663 }
00664 }
00665
00666
00667 for( i = 0; i < nm; i++ )
00668 {
00669 k = i;
00670 for( j = i + 1; j < nm; j++ )
00671 if( w[k] < w[j] )
00672 k = j;
00673
00674 if( k != i )
00675 {
00676 double t;
00677 CV_SWAP( w[i], w[k], t );
00678
00679 if( vT )
00680 for( j = 0; j < n; j++ )
00681 CV_SWAP( vT[j + ldvT*k], vT[j + ldvT*i], t );
00682
00683 if( uT )
00684 for( j = 0; j < m; j++ )
00685 CV_SWAP( uT[j + lduT*k], uT[j + lduT*i], t );
00686 }
00687 }
00688
00689 free(hv0 - 1);
00690 }
00691
00692
00693 void
00694 icvSVD_32f( float* a, int lda, int m, int n,
00695 float* w,
00696 float* uT, int lduT, int nu,
00697 float* vT, int ldvT,
00698 float* buffer )
00699 {
00700 float* e;
00701 float* temp;
00702 float *w1, *e1;
00703 float *hv;
00704 double ku0 = 0, kv0 = 0;
00705 double anorm = 0;
00706 float *a1, *u0 = uT, *v0 = vT;
00707 double scale, h;
00708 int i, j, k, l;
00709 int nm, m1, n1;
00710 int nv = n;
00711 int iters = 0;
00712 float* hv0 = (float*)cvStackAlloc( (m+2)*sizeof(hv0[0])) + 1;
00713
00714 e = buffer;
00715
00716 w1 = w;
00717 e1 = e + 1;
00718 nm = n;
00719
00720 temp = buffer + nm;
00721
00722 memset( w, 0, nm * sizeof( w[0] ));
00723 memset( e, 0, nm * sizeof( e[0] ));
00724
00725 m1 = m;
00726 n1 = n;
00727
00728
00729 for( ;; )
00730 {
00731 int update_u;
00732 int update_v;
00733
00734 if( m1 == 0 )
00735 break;
00736
00737 scale = h = 0;
00738
00739 update_u = uT && m1 > m - nu;
00740 hv = update_u ? uT : hv0;
00741
00742 for( j = 0, a1 = a; j < m1; j++, a1 += lda )
00743 {
00744 double t = a1[0];
00745 scale += fabs( hv[j] = (float)t );
00746 }
00747
00748 if( scale != 0 )
00749 {
00750 double f = 1./scale, g, s = 0;
00751
00752 for( j = 0; j < m1; j++ )
00753 {
00754 double t = (hv[j] = (float)(hv[j]*f));
00755 s += t * t;
00756 }
00757
00758 g = sqrt( s );
00759 f = hv[0];
00760 if( f >= 0 )
00761 g = -g;
00762 hv[0] = (float)(f - g);
00763 h = 1. / (f * g - s);
00764
00765 memset( temp, 0, n1 * sizeof( temp[0] ));
00766
00767
00768 icvMatrAXPY_32f( m1, n1 - 1, a + 1, lda, hv, temp + 1, 0 );
00769
00770 for( k = 1; k < n1; k++ ) temp[k] = (float)(temp[k]*h);
00771
00772
00773 icvMatrAXPY_32f( m1, n1 - 1, temp + 1, 0, hv, a + 1, lda );
00774 *w1 = (float)(g*scale);
00775 }
00776 w1++;
00777
00778
00779 if( update_u )
00780 {
00781 if( m1 == m )
00782 ku0 = h;
00783 else
00784 hv[-1] = (float)h;
00785 }
00786
00787 a++;
00788 n1--;
00789 if( vT )
00790 vT += ldvT + 1;
00791
00792 if( n1 == 0 )
00793 break;
00794
00795 scale = h = 0;
00796 update_v = vT && n1 > n - nv;
00797 hv = update_v ? vT : hv0;
00798
00799 for( j = 0; j < n1; j++ )
00800 {
00801 double t = a[j];
00802 scale += fabs( hv[j] = (float)t );
00803 }
00804
00805 if( scale != 0 )
00806 {
00807 double f = 1./scale, g, s = 0;
00808
00809 for( j = 0; j < n1; j++ )
00810 {
00811 double t = (hv[j] = (float)(hv[j]*f));
00812 s += t * t;
00813 }
00814
00815 g = sqrt( s );
00816 f = hv[0];
00817 if( f >= 0 )
00818 g = -g;
00819 hv[0] = (float)(f - g);
00820 h = 1. / (f * g - s);
00821 hv[-1] = 0.f;
00822
00823
00824 icvMatrAXPY3_32f( m1, n1, hv, lda, a, h );
00825
00826 *e1 = (float)(g*scale);
00827 }
00828 e1++;
00829
00830
00831 if( update_v )
00832 {
00833 if( n1 == n )
00834 kv0 = h;
00835 else
00836 hv[-1] = (float)h;
00837 }
00838
00839 a += lda;
00840 m1--;
00841 if( uT )
00842 uT += lduT + 1;
00843 }
00844
00845 m1 -= m1 != 0;
00846 n1 -= n1 != 0;
00847
00848
00849 if( uT )
00850 {
00851 m1 = m - m1;
00852 uT = u0 + m1 * lduT;
00853 for( i = m1; i < nu; i++, uT += lduT )
00854 {
00855 memset( uT + m1, 0, (m - m1) * sizeof( uT[0] ));
00856 uT[i] = 1.;
00857 }
00858
00859 for( i = m1 - 1; i >= 0; i-- )
00860 {
00861 double s;
00862 int lh = nu - i;
00863
00864 l = m - i;
00865
00866 hv = u0 + (lduT + 1) * i;
00867 h = i == 0 ? ku0 : hv[-1];
00868
00869
00870 if (h > 0) printf("assert: h <= 0 not satisfied, h = %.2f (3)\n", h);
00871
00872 if( h != 0 )
00873 {
00874 uT = hv;
00875 icvMatrAXPY3_32f( lh, l-1, hv+1, lduT, uT+1, h );
00876
00877 s = hv[0] * h;
00878 for( k = 0; k < l; k++ ) hv[k] = (float)(hv[k]*s);
00879 hv[0] += 1;
00880 }
00881 else
00882 {
00883 for( j = 1; j < l; j++ )
00884 hv[j] = 0;
00885 for( j = 1; j < lh; j++ )
00886 hv[j * lduT] = 0;
00887 hv[0] = 1;
00888 }
00889 }
00890 uT = u0;
00891 }
00892
00893
00894 if( vT )
00895 {
00896 n1 = n - n1;
00897 vT = v0 + n1 * ldvT;
00898 for( i = n1; i < nv; i++, vT += ldvT )
00899 {
00900 memset( vT + n1, 0, (n - n1) * sizeof( vT[0] ));
00901 vT[i] = 1.;
00902 }
00903
00904 for( i = n1 - 1; i >= 0; i-- )
00905 {
00906 double s;
00907 int lh = nv - i;
00908
00909 l = n - i;
00910 hv = v0 + (ldvT + 1) * i;
00911 h = i == 0 ? kv0 : hv[-1];
00912
00913
00914 if (h > 0) printf("assert: h <= 0 not satisfied, h = %.2f (4)\n", h);
00915
00916 if( h != 0 )
00917 {
00918 vT = hv;
00919 icvMatrAXPY3_32f( lh, l-1, hv+1, ldvT, vT+1, h );
00920
00921 s = hv[0] * h;
00922 for( k = 0; k < l; k++ ) hv[k] = (float)(hv[k]*s);
00923 hv[0] += 1;
00924 }
00925 else
00926 {
00927 for( j = 1; j < l; j++ )
00928 hv[j] = 0;
00929 for( j = 1; j < lh; j++ )
00930 hv[j * ldvT] = 0;
00931 hv[0] = 1;
00932 }
00933 }
00934 vT = v0;
00935 }
00936
00937 for( i = 0; i < nm; i++ )
00938 {
00939 double tnorm = fabs( w[i] );
00940 tnorm += fabs( e[i] );
00941
00942 if( anorm < tnorm )
00943 anorm = tnorm;
00944 }
00945
00946 anorm *= FLT_EPSILON;
00947
00948
00949 for( k = nm - 1; k >= 0; k-- )
00950 {
00951 double z = 0;
00952 iters = 0;
00953
00954 for( ;; )
00955 {
00956 double c, s, f, g, x, y;
00957 int flag = 0;
00958
00959
00960 for( l = k; l >= 0; l-- )
00961 {
00962 if( fabs( e[l] ) <= anorm )
00963 {
00964 flag = 1;
00965 break;
00966 }
00967
00968 if (l <= 0) printf("assert: l > 0 not satisfied, l = %i\n", l);
00969
00970 if( fabs( w[l - 1] ) <= anorm )
00971 break;
00972 }
00973
00974 if( !flag )
00975 {
00976 c = 0;
00977 s = 1;
00978
00979 for( i = l; i <= k; i++ )
00980 {
00981 f = s * e[i];
00982 e[i] = (float)(e[i]*c);
00983
00984 if( anorm + fabs( f ) == anorm )
00985 break;
00986
00987 g = w[i];
00988 h = pythag( f, g );
00989 w[i] = (float)h;
00990 c = g / h;
00991 s = -f / h;
00992
00993 if( uT )
00994 icvGivens_32f( m, uT + lduT * (l - 1), uT + lduT * i, c, s );
00995 }
00996 }
00997
00998 z = w[k];
00999 if( l == k || iters++ == MAX_ITERS )
01000 break;
01001
01002
01003 x = w[l];
01004 y = w[k - 1];
01005 g = e[k - 1];
01006 h = e[k];
01007 f = 0.5 * (((g + z) / h) * ((g - z) / y) + y / h - h / y);
01008 g = pythag( f, 1 );
01009 if( f < 0 )
01010 g = -g;
01011 f = x - (z / x) * z + (h / x) * (y / (f + g) - h);
01012
01013 c = s = 1;
01014
01015 for( i = l + 1; i <= k; i++ )
01016 {
01017 g = e[i];
01018 y = w[i];
01019 h = s * g;
01020 g *= c;
01021 z = pythag( f, h );
01022 e[i - 1] = (float)z;
01023 c = f / z;
01024 s = h / z;
01025 f = x * c + g * s;
01026 g = -x * s + g * c;
01027 h = y * s;
01028 y *= c;
01029
01030 if( vT )
01031 icvGivens_32f( n, vT + ldvT * (i - 1), vT + ldvT * i, c, s );
01032
01033 z = pythag( f, h );
01034 w[i - 1] = (float)z;
01035
01036
01037 if( z != 0 )
01038 {
01039 c = f / z;
01040 s = h / z;
01041 }
01042 f = c * g + s * y;
01043 x = -s * g + c * y;
01044
01045 if( uT )
01046 icvGivens_32f( m, uT + lduT * (i - 1), uT + lduT * i, c, s );
01047 }
01048
01049 e[l] = 0;
01050 e[k] = (float)f;
01051 w[k] = (float)x;
01052 }
01053
01054 if( iters > MAX_ITERS )
01055 break;
01056
01057 if( z < 0 )
01058 {
01059 w[k] = (float)(-z);
01060 if( vT )
01061 {
01062 for( j = 0; j < n; j++ )
01063 vT[j + k * ldvT] = -vT[j + k * ldvT];
01064 }
01065 }
01066 }
01067
01068
01069 for( i = 0; i < nm; i++ )
01070 {
01071 k = i;
01072 for( j = i + 1; j < nm; j++ )
01073 if( w[k] < w[j] )
01074 k = j;
01075
01076 if( k != i )
01077 {
01078 float t;
01079 CV_SWAP( w[i], w[k], t );
01080
01081 if( vT )
01082 for( j = 0; j < n; j++ )
01083 CV_SWAP( vT[j + ldvT*k], vT[j + ldvT*i], t );
01084
01085 if( uT )
01086 for( j = 0; j < m; j++ )
01087 CV_SWAP( uT[j + lduT*k], uT[j + lduT*i], t );
01088 }
01089 }
01090
01091 free(hv0 - 1);
01092 }
01093
01094
01095 void
01096 icvSVBkSb_64f( int m, int n, const double* w,
01097 const double* uT, int lduT,
01098 const double* vT, int ldvT,
01099 const double* b, int ldb, int nb,
01100 double* x, int ldx, double* buffer )
01101 {
01102 double threshold = 0;
01103 int i, j, nm = MY_MIN( m, n );
01104
01105 if( !b )
01106 nb = m;
01107
01108 for( i = 0; i < n; i++ )
01109 memset( x + i*ldx, 0, nb*sizeof(x[0]));
01110
01111 for( i = 0; i < nm; i++ )
01112 threshold += w[i];
01113 threshold *= 2*DBL_EPSILON;
01114
01115
01116 for( i = 0; i < nm; i++, uT += lduT, vT += ldvT )
01117 {
01118 double wi = w[i];
01119
01120 if( wi > threshold )
01121 {
01122 wi = 1./wi;
01123
01124 if( nb == 1 )
01125 {
01126 double s = 0;
01127 if( b )
01128 {
01129 if( ldb == 1 )
01130 {
01131 for( j = 0; j <= m - 4; j += 4 )
01132 s += uT[j]*b[j] + uT[j+1]*b[j+1] + uT[j+2]*b[j+2] + uT[j+3]*b[j+3];
01133 for( ; j < m; j++ )
01134 s += uT[j]*b[j];
01135 }
01136 else
01137 {
01138 for( j = 0; j < m; j++ )
01139 s += uT[j]*b[j*ldb];
01140 }
01141 }
01142 else
01143 s = uT[0];
01144 s *= wi;
01145 if( ldx == 1 )
01146 {
01147 for( j = 0; j <= n - 4; j += 4 )
01148 {
01149 double t0 = x[j] + s*vT[j];
01150 double t1 = x[j+1] + s*vT[j+1];
01151 x[j] = t0;
01152 x[j+1] = t1;
01153 t0 = x[j+2] + s*vT[j+2];
01154 t1 = x[j+3] + s*vT[j+3];
01155 x[j+2] = t0;
01156 x[j+3] = t1;
01157 }
01158
01159 for( ; j < n; j++ )
01160 x[j] += s*vT[j];
01161 }
01162 else
01163 {
01164 for( j = 0; j < n; j++ )
01165 x[j*ldx] += s*vT[j];
01166 }
01167 }
01168 else
01169 {
01170 if( b )
01171 {
01172 memset( buffer, 0, nb*sizeof(buffer[0]));
01173 icvMatrAXPY_64f( m, nb, b, ldb, uT, buffer, 0 );
01174 for( j = 0; j < nb; j++ )
01175 buffer[j] *= wi;
01176 }
01177 else
01178 {
01179 for( j = 0; j < nb; j++ )
01180 buffer[j] = uT[j]*wi;
01181 }
01182 icvMatrAXPY_64f( n, nb, buffer, 0, vT, x, ldx );
01183 }
01184 }
01185 }
01186 }
01187
01188
01189 void
01190 icvSVBkSb_32f( int m, int n, const float* w,
01191 const float* uT, int lduT,
01192 const float* vT, int ldvT,
01193 const float* b, int ldb, int nb,
01194 float* x, int ldx, float* buffer )
01195 {
01196 float threshold = 0.f;
01197 int i, j, nm = MY_MIN( m, n );
01198
01199 if( !b )
01200 nb = m;
01201
01202 for( i = 0; i < n; i++ )
01203 memset( x + i*ldx, 0, nb*sizeof(x[0]));
01204
01205 for( i = 0; i < nm; i++ )
01206 threshold += w[i];
01207 threshold *= 2*FLT_EPSILON;
01208
01209
01210 for( i = 0; i < nm; i++, uT += lduT, vT += ldvT )
01211 {
01212 double wi = w[i];
01213
01214 if( wi > threshold )
01215 {
01216 wi = 1./wi;
01217
01218 if( nb == 1 )
01219 {
01220 double s = 0;
01221 if( b )
01222 {
01223 if( ldb == 1 )
01224 {
01225 for( j = 0; j <= m - 4; j += 4 )
01226 s += uT[j]*b[j] + uT[j+1]*b[j+1] + uT[j+2]*b[j+2] + uT[j+3]*b[j+3];
01227 for( ; j < m; j++ )
01228 s += uT[j]*b[j];
01229 }
01230 else
01231 {
01232 for( j = 0; j < m; j++ )
01233 s += uT[j]*b[j*ldb];
01234 }
01235 }
01236 else
01237 s = uT[0];
01238 s *= wi;
01239
01240 if( ldx == 1 )
01241 {
01242 for( j = 0; j <= n - 4; j += 4 )
01243 {
01244 double t0 = x[j] + s*vT[j];
01245 double t1 = x[j+1] + s*vT[j+1];
01246 x[j] = (float)t0;
01247 x[j+1] = (float)t1;
01248 t0 = x[j+2] + s*vT[j+2];
01249 t1 = x[j+3] + s*vT[j+3];
01250 x[j+2] = (float)t0;
01251 x[j+3] = (float)t1;
01252 }
01253
01254 for( ; j < n; j++ )
01255 x[j] = (float)(x[j] + s*vT[j]);
01256 }
01257 else
01258 {
01259 for( j = 0; j < n; j++ )
01260 x[j*ldx] = (float)(x[j*ldx] + s*vT[j]);
01261 }
01262 }
01263 else
01264 {
01265 if( b )
01266 {
01267 memset( buffer, 0, nb*sizeof(buffer[0]));
01268 icvMatrAXPY_32f( m, nb, b, ldb, uT, buffer, 0 );
01269 for( j = 0; j < nb; j++ )
01270 buffer[j] = (float)(buffer[j]*wi);
01271 }
01272 else
01273 {
01274 for( j = 0; j < nb; j++ )
01275 buffer[j] = (float)(uT[j]*wi);
01276 }
01277 icvMatrAXPY_32f( n, nb, buffer, 0, vT, x, ldx );
01278 }
01279 }
01280 }
01281 }
01282
01283
01284 void
01285 cvSVD( const CFloatMatrix* aarr, CFloatMatrix* warr, CFloatMatrix* uarr, CFloatMatrix* varr, int flags )
01286 {
01287 typedef unsigned char uchar;
01288
01289 uchar* buffer = 0;
01290
01291
01292 CFloatMatrix tmat;
01293 CFloatMatrix ustub, vstub;
01294
01295 const CFloatMatrix *a = aarr;
01296 CFloatMatrix *w = warr;
01297
01298 uchar* tw = 0;
01299 int a_buf_offset = 0, u_buf_offset = 0, buf_size, pix_size;
01300 int temp_u = 0,
01301 t_svd;
01302 int m, n;
01303 int w_rows, w_cols;
01304 int u_rows = 0, u_cols = 0;
01305 int w_is_mat = 0;
01306
01307 if( a->rows >= a->columns )
01308 {
01309 m = a->rows;
01310 n = a->columns;
01311 w_rows = w->rows;
01312 w_cols = w->columns;
01313 t_svd = 0;
01314 }
01315 else
01316 {
01317 CFloatMatrix* t;
01318 CV_SWAP( uarr, varr, t );
01319
01320 flags = (flags & CV_SVD_U_T ? CV_SVD_V_T : 0)|
01321 (flags & CV_SVD_V_T ? CV_SVD_U_T : 0);
01322 m = a->columns;
01323 n = a->rows;
01324 w_rows = w->columns;
01325 w_cols = w->rows;
01326 t_svd = 1;
01327 }
01328
01329 CFloatMatrix *u = uarr;
01330 CFloatMatrix *v = varr;
01331
01332 w_is_mat = w_cols > 1 && w_rows > 1;
01333 if (!w_is_mat && w_cols + w_rows - 1 == n)
01334 tw = (uchar*) w->data;
01335
01336 if( u )
01337 {
01338 if( !(flags & CV_SVD_U_T) )
01339 {
01340 u_rows = u->rows;
01341 u_cols = u->columns;
01342 }
01343 else
01344 {
01345 u_rows = u->columns;
01346 u_cols = u->rows;
01347 }
01348
01349 if( u_rows != m || (u_cols != m && u_cols != n))
01350 !t_svd ? printf( "U matrix has unappropriate size" ) : printf( "V matrix has unappropriate size" );
01351
01352 temp_u = (u_rows != u_cols && !(flags & CV_SVD_U_T)) || u->data == a->data;
01353
01354 if( w_is_mat && u_cols != w_rows )
01355 !t_svd ? printf( "U and W have incompatible sizes" ) : printf( "V and W have incompatible sizes" );
01356 }
01357 else
01358 {
01359 u = &ustub;
01360 u->rows = 0;
01361 u->columns = 0;
01362 u->data = 0;
01363 }
01364
01365 if( v )
01366 {
01367 int v_rows, v_cols;
01368
01369 if( !(flags & CV_SVD_V_T) )
01370 {
01371 v_rows = v->rows;
01372 v_cols = v->columns;
01373 }
01374 else
01375 {
01376 v_rows = v->columns;
01377 v_cols = v->rows;
01378 }
01379
01380 if( v_rows != n || v_cols != n )
01381 t_svd ? printf( "U matrix has unappropriate size") : printf("V matrix has unappropriate size" );
01382
01383 if( w_is_mat && w_cols != v_cols )
01384 t_svd ? printf( "U and W have incompatible sizes") : printf("V and W have incompatible sizes" );
01385 }
01386 else
01387 {
01388 v = &vstub;
01389 v->rows = 0;
01390 v->columns = 0;
01391 v->data = 0;
01392 }
01393
01394 pix_size = sizeof(float);
01395 buf_size = n*2 + m;
01396
01397 if( !(flags & CV_SVD_MODIFY_A) )
01398 {
01399 a_buf_offset = buf_size;
01400 buf_size += a->rows*a->columns;
01401 }
01402
01403 if( temp_u )
01404 {
01405 u_buf_offset = buf_size;
01406 buf_size += u->rows*u->columns;
01407 }
01408
01409 buf_size *= pix_size;
01410
01411 buffer = (uchar*)malloc( buf_size );
01412
01413 if( !(flags & CV_SVD_MODIFY_A) )
01414 {
01415 tmat.rows = m;
01416 tmat.columns = n;
01417 tmat.data = (float *)(buffer + a_buf_offset * pix_size);
01418
01419 if( !t_svd )
01420 ImageProcessor::CopyMatrix(a, &tmat);
01421 else
01422 LinearAlgebra::Transpose(a, &tmat);
01423 a = &tmat;
01424 }
01425
01426 if( temp_u )
01427 {
01428 ustub.rows = u_cols;
01429 ustub.columns = u_rows;
01430 ustub.data = (float *)(buffer + u_buf_offset * pix_size);
01431 u = &ustub;
01432 }
01433
01434 if( !tw )
01435 tw = buffer + (n + m)*pix_size;
01436
01437
01438
01439 icvSVD_32f( a->data, a->columns, a->rows, a->columns,
01440 (float*)tw, u->data, u->columns, u_cols,
01441 v->data, v->columns, (float*)buffer );
01442
01443
01444 if( (void *) tw != (void *) w->data )
01445 {
01446 int shift = w->columns != 1;
01447 ImageProcessor::Zero(w);
01448
01449 for( int i = 0; i < n; i++ )
01450 ((float*)(((unsigned char *) w->data) + i*(w->columns*sizeof(float))))[i*shift] = ((float*)tw)[i];
01451 }
01452
01453 if( uarr )
01454 {
01455 if( !(flags & CV_SVD_U_T))
01456 LinearAlgebra::Transpose(u, uarr);
01457 else if( temp_u )
01458 ImageProcessor::CopyMatrix(u, uarr);
01459 }
01460
01461 if( varr )
01462 {
01463 if( !(flags & CV_SVD_V_T))
01464 LinearAlgebra::Transpose(v, varr);
01465 }
01466
01467 if( buffer )
01468 free( buffer );
01469 }
01470
01471 void
01472 cvSVD( const CDoubleMatrix* aarr, CDoubleMatrix* warr, CDoubleMatrix* uarr, CDoubleMatrix* varr, int flags )
01473 {
01474 typedef unsigned char uchar;
01475
01476 uchar* buffer = 0;
01477
01478
01479 CDoubleMatrix tmat;
01480 CDoubleMatrix ustub, vstub;
01481
01482 const CDoubleMatrix *a = aarr;
01483 CDoubleMatrix *w = warr;
01484
01485 uchar* tw = 0;
01486 int a_buf_offset = 0, u_buf_offset = 0, buf_size, pix_size;
01487 int temp_u = 0,
01488 t_svd;
01489 int m, n;
01490 int w_rows, w_cols;
01491 int u_rows = 0, u_cols = 0;
01492 int w_is_mat = 0;
01493
01494 if( a->rows >= a->columns )
01495 {
01496 m = a->rows;
01497 n = a->columns;
01498 w_rows = w->rows;
01499 w_cols = w->columns;
01500 t_svd = 0;
01501 }
01502 else
01503 {
01504 CDoubleMatrix* t;
01505 CV_SWAP( uarr, varr, t );
01506
01507 flags = (flags & CV_SVD_U_T ? CV_SVD_V_T : 0)|
01508 (flags & CV_SVD_V_T ? CV_SVD_U_T : 0);
01509 m = a->columns;
01510 n = a->rows;
01511 w_rows = w->columns;
01512 w_cols = w->rows;
01513 t_svd = 1;
01514 }
01515
01516 CDoubleMatrix *u = uarr;
01517 CDoubleMatrix *v = varr;
01518
01519 w_is_mat = w_cols > 1 && w_rows > 1;
01520 if (!w_is_mat && w_cols + w_rows - 1 == n)
01521 tw = (uchar*) w->data;
01522
01523 if( u )
01524 {
01525 if( !(flags & CV_SVD_U_T) )
01526 {
01527 u_rows = u->rows;
01528 u_cols = u->columns;
01529 }
01530 else
01531 {
01532 u_rows = u->columns;
01533 u_cols = u->rows;
01534 }
01535
01536 if( u_rows != m || (u_cols != m && u_cols != n))
01537 !t_svd ? printf( "U matrix has unappropriate size" ) : printf( "V matrix has unappropriate size" );
01538
01539 temp_u = (u_rows != u_cols && !(flags & CV_SVD_U_T)) || u->data == a->data;
01540
01541 if( w_is_mat && u_cols != w_rows )
01542 !t_svd ? printf( "U and W have incompatible sizes" ) : printf( "V and W have incompatible sizes" );
01543 }
01544 else
01545 {
01546 u = &ustub;
01547 u->rows = 0;
01548 u->columns = 0;
01549 u->data = 0;
01550 }
01551
01552 if( v )
01553 {
01554 int v_rows, v_cols;
01555
01556 if( !(flags & CV_SVD_V_T) )
01557 {
01558 v_rows = v->rows;
01559 v_cols = v->columns;
01560 }
01561 else
01562 {
01563 v_rows = v->columns;
01564 v_cols = v->rows;
01565 }
01566
01567 if( v_rows != n || v_cols != n )
01568 t_svd ? printf( "U matrix has unappropriate size" ) : printf( "V matrix has unappropriate size" );
01569
01570 if( w_is_mat && w_cols != v_cols )
01571 t_svd ? printf( "U and W have incompatible sizes" ) : printf( "V and W have incompatible sizes" );
01572 }
01573 else
01574 {
01575 v = &vstub;
01576 v->rows = 0;
01577 v->columns = 0;
01578 v->data = 0;
01579 }
01580
01581 pix_size = sizeof(double);
01582 buf_size = n*2 + m;
01583
01584 if( !(flags & CV_SVD_MODIFY_A) )
01585 {
01586 a_buf_offset = buf_size;
01587 buf_size += a->rows*a->columns;
01588 }
01589
01590 if( temp_u )
01591 {
01592 u_buf_offset = buf_size;
01593 buf_size += u->rows*u->columns;
01594 }
01595
01596 buf_size *= pix_size;
01597
01598 buffer = (uchar*)malloc( buf_size );
01599
01600 if( !(flags & CV_SVD_MODIFY_A) )
01601 {
01602 tmat.rows = m;
01603 tmat.columns = n;
01604 tmat.data = (double *)(buffer + a_buf_offset * pix_size);
01605
01606 if( !t_svd )
01607 ImageProcessor::CopyMatrix(a, &tmat);
01608 else
01609 LinearAlgebra::Transpose(a, &tmat);
01610 a = &tmat;
01611 }
01612
01613 if( temp_u )
01614 {
01615 ustub.rows = u_cols;
01616 ustub.columns = u_rows;
01617 ustub.data = (double *)(buffer + u_buf_offset * pix_size);
01618 u = &ustub;
01619 }
01620
01621 if( !tw )
01622 tw = buffer + (n + m)*pix_size;
01623
01624
01625
01626 icvSVD_64f( a->data, a->columns, a->rows, a->columns,
01627 (double*)tw, u->data, u->columns, u_cols,
01628 v->data, v->columns, (double*)buffer );
01629
01630
01631 if( (void *) tw != (void *) w->data )
01632 {
01633 int shift = w->columns != 1;
01634 ImageProcessor::Zero(w);
01635
01636 for( int i = 0; i < n; i++ )
01637 ((double*)(((unsigned char *) w->data) + i*(w->columns*sizeof(double))))[i*shift] = ((double*)tw)[i];
01638 }
01639
01640 if( uarr )
01641 {
01642 if( !(flags & CV_SVD_U_T))
01643 LinearAlgebra::Transpose(u, uarr);
01644 else if( temp_u )
01645 ImageProcessor::CopyMatrix(u, uarr);
01646 }
01647
01648 if( varr )
01649 {
01650 if( !(flags & CV_SVD_V_T))
01651 LinearAlgebra::Transpose(v, varr);
01652 }
01653
01654 if( buffer )
01655 free( buffer );
01656 }
01657 }
01658
01659
01660 void LinearAlgebra::SVD(const CFloatMatrix *A, CFloatMatrix *W, CFloatMatrix *U, CFloatMatrix *V, bool bAllowModifyA, bool bReturnUTransposed, bool bReturnVTransposed)
01661 {
01662 const int columns = A->columns;
01663 const int rows = A->rows;
01664
01665 if (W->columns != columns || W->rows != rows)
01666 {
01667 printf("error: W should have %i columns and %i rows for LinearAlgebra::SVD\n", columns, rows);
01668 return;
01669 }
01670
01671 if (U && (U->columns != rows || U->rows != rows))
01672 {
01673 printf("error: U should have %i columns and %i rows for LinearAlgebra::SVD\n", rows, rows);
01674 return;
01675 }
01676
01677 if (V && (V->columns != columns || V->rows != columns))
01678 {
01679 printf("error: V should have %i columns and %i rows for LinearAlgebra::SVD\n", columns, columns);
01680 return;
01681 }
01682
01683 int flags = 0;
01684
01685 if (bAllowModifyA)
01686 flags |= CV_SVD_MODIFY_A;
01687
01688 if (bReturnUTransposed)
01689 flags |= CV_SVD_U_T;
01690
01691 if (bReturnVTransposed)
01692 flags |= CV_SVD_V_T;
01693
01694 cvSVD(A, W, U, V, flags);
01695 }
01696
01697 void LinearAlgebra::SVD(const CDoubleMatrix *A, CDoubleMatrix *W, CDoubleMatrix *U, CDoubleMatrix *V, bool bAllowModifyA, bool bReturnUTransposed, bool bReturnVTransposed)
01698 {
01699 const int columns = A->columns;
01700 const int rows = A->rows;
01701
01702 if (W->columns != columns || W->rows != rows)
01703 {
01704 printf("error: W should have %i columns and %i rows for LinearAlgebra::SVD\n", columns, rows);
01705 return;
01706 }
01707
01708 if (U && (U->columns != rows || U->rows != rows))
01709 {
01710 printf("error: U should have %i columns and %i rows for LinearAlgebra::SVD\n", rows, rows);
01711 return;
01712 }
01713
01714 if (V && (V->columns != columns || V->rows != columns))
01715 {
01716 printf("error: V should have %i columns and %i rows for LinearAlgebra::SVD\n", columns, columns);
01717 return;
01718 }
01719
01720 int flags = 0;
01721
01722 if (bAllowModifyA)
01723 flags |= CV_SVD_MODIFY_A;
01724
01725 if (bReturnUTransposed)
01726 flags |= CV_SVD_U_T;
01727
01728 if (bReturnVTransposed)
01729 flags |= CV_SVD_V_T;
01730
01731 cvSVD(A, W, U, V, flags);
01732 }