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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #ifndef __VCGLIB_LINALGEBRA_H
00050 #define __VCGLIB_LINALGEBRA_H
00051
00052 #include <vcg/math/base.h>
00053 #include <vcg/math/matrix44.h>
00054 #include <algorithm>
00055
00056 namespace vcg
00057 {
00059
00060
00064 template< typename MATRIX_TYPE >
00065 static void JacobiRotate(MATRIX_TYPE &A, typename MATRIX_TYPE::ScalarType s, typename MATRIX_TYPE::ScalarType tau, int i,int j,int k,int l)
00066 {
00067 typename MATRIX_TYPE::ScalarType g=A[i][j];
00068 typename MATRIX_TYPE::ScalarType h=A[k][l];
00069 A[i][j]=g-s*(h+g*tau);
00070 A[k][l]=h+s*(g-h*tau);
00071 };
00072
00080 template <typename MATRIX_TYPE, typename POINT_TYPE>
00081 static void Jacobi(MATRIX_TYPE &w, POINT_TYPE &d, MATRIX_TYPE &v, int &nrot)
00082 {
00083 typedef typename MATRIX_TYPE::ScalarType ScalarType;
00084 assert(w.RowsNumber()==w.ColumnsNumber());
00085 int dimension = w.RowsNumber();
00086
00087 int j,iq,ip,i;
00088
00089 typename MATRIX_TYPE::ScalarType tresh, theta, tau, t, sm, s, h, g, c;
00090 POINT_TYPE b, z;
00091
00092 v.SetIdentity();
00093
00094 for (ip=0;ip<dimension;++ip)
00095 {
00096 b[ip]=d[ip]=w[ip][ip];
00097 z[ip]=ScalarType(0.0);
00098 }
00099 nrot=0;
00100 for (i=0;i<50;i++)
00101 {
00102 sm=ScalarType(0.0);
00103 for (ip=0;ip<dimension-1;++ip)
00104 {
00105 for (iq=ip+1;iq<dimension;++iq)
00106 sm += math::Abs(w[ip][iq]);
00107 }
00108 if (sm == ScalarType(0.0))
00109 {
00110 return;
00111 }
00112 if (i < 4)
00113 tresh=ScalarType(0.2)*sm/(dimension*dimension);
00114 else
00115 tresh=ScalarType(0.0);
00116 for (ip=0;ip<dimension-1;++ip)
00117 {
00118 for (iq=ip+1;iq<dimension;iq++)
00119 {
00120 g=ScalarType(100.0)*fabs(w[ip][iq]);
00121
00122 if(i>4 && (float)(fabs(d[ip])+g) == (float)fabs(d[ip]) && (float)(fabs(d[iq])+g) == (float)fabs(d[iq]))
00123 w[ip][iq]=ScalarType(0.0);
00124 else if (fabs(w[ip][iq]) > tresh)
00125 {
00126 h=d[iq]-d[ip];
00127 if ((float)(fabs(h)+g) == (float)fabs(h))
00128 t=(w[ip][iq])/h;
00129 else
00130 {
00131 theta=ScalarType(0.5)*h/(w[ip][iq]);
00132 t=ScalarType(1.0)/(fabs(theta)+sqrt(ScalarType(1.0)+theta*theta));
00133 if (theta < ScalarType(0.0)) t = -t;
00134 }
00135 c=ScalarType(1.0)/sqrt(ScalarType(1.0)+t*t);
00136 s=t*c;
00137 tau=s/(ScalarType(1.0)+c);
00138 h=t*w[ip][iq];
00139 z[ip] -= h;
00140 z[iq] += h;
00141 d[ip] -= h;
00142 d[iq] += h;
00143 w[ip][iq]=ScalarType(0.0);
00144 for (j=0;j<=ip-1;j++) {
00145 JacobiRotate<MATRIX_TYPE>(w,s,tau,j,ip,j,iq) ;
00146 }
00147 for (j=ip+1;j<=iq-1;j++) {
00148 JacobiRotate<MATRIX_TYPE>(w,s,tau,ip,j,j,iq);
00149 }
00150 for (j=iq+1;j<dimension;j++) {
00151 JacobiRotate<MATRIX_TYPE>(w,s,tau,ip,j,iq,j);
00152 }
00153 for (j=0;j<dimension;j++) {
00154 JacobiRotate<MATRIX_TYPE>(v,s,tau,j,ip,j,iq);
00155 }
00156 ++nrot;
00157 }
00158 }
00159 }
00160 for (ip=0;ip<dimension;ip++)
00161 {
00162 b[ip] += z[ip];
00163 d[ip]=b[ip];
00164 z[ip]=0.0;
00165 }
00166 }
00167 };
00168
00169
00177 template < typename MATRIX_TYPE, typename POINT_TYPE >
00178 void SortEigenvaluesAndEigenvectors(POINT_TYPE &eigenvalues, MATRIX_TYPE &eigenvectors, bool absComparison = false)
00179 {
00180 assert(eigenvectors.ColumnsNumber()==eigenvectors.RowsNumber());
00181 int dimension = eigenvectors.ColumnsNumber();
00182 int i, j, k;
00183 float p,q;
00184 for (i=0; i<dimension-1; i++)
00185 {
00186 if (absComparison)
00187 {
00188 p = fabs(eigenvalues[k=i]);
00189 for (j=i+1; j<dimension; j++)
00190 if ((q=fabs(eigenvalues[j])) >= p)
00191 {
00192 p = q;
00193 k = j;
00194 }
00195 p = eigenvalues[k];
00196 }
00197 else
00198 {
00199 p = eigenvalues[ k=i ];
00200 for (j=i+1; j<dimension; j++)
00201 if (eigenvalues[j] >= p)
00202 p = eigenvalues[ k=j ];
00203 }
00204
00205 if (k != i)
00206 {
00207 eigenvalues[k] = eigenvalues[i];
00208 eigenvalues[i] = p;
00209
00210 for (j=0; j<dimension; j++)
00211 {
00212 p = eigenvectors[j][i];
00213 eigenvectors[j][i] = eigenvectors[j][k];
00214 eigenvectors[j][k] = p;
00215 }
00216 }
00217 }
00218 };
00219
00220
00221
00222 template <typename TYPE>
00223 inline static TYPE pythagora(TYPE a, TYPE b)
00224 {
00225 TYPE abs_a = fabs(a);
00226 TYPE abs_b = fabs(b);
00227 if (abs_a > abs_b)
00228 return abs_a*sqrt((TYPE)1.0+sqr(abs_b/abs_a));
00229 else
00230 return (abs_b == (TYPE)0.0 ? (TYPE)0.0 : abs_b*sqrt((TYPE)1.0+sqr(abs_a/abs_b)));
00231 };
00232
00233 template <typename TYPE>
00234 inline static TYPE sign(TYPE a, TYPE b)
00235 {
00236 return (b >= 0.0 ? fabs(a) : -fabs(a));
00237 };
00238
00239 template <typename TYPE>
00240 inline static TYPE sqr(TYPE a)
00241 {
00242 TYPE sqr_arg = a;
00243 return (sqr_arg == 0 ? 0 : sqr_arg*sqr_arg);
00244 }
00245
00249 enum SortingStrategy {LeaveUnsorted=0, SortAscending=1, SortDescending=2};
00250 template< typename MATRIX_TYPE >
00251 void Sort(MATRIX_TYPE &U, typename MATRIX_TYPE::ScalarType W[], MATRIX_TYPE &V, const SortingStrategy sorting) ;
00252
00253
00264 template <typename MATRIX_TYPE>
00265 static bool SingularValueDecomposition(MATRIX_TYPE &A, typename MATRIX_TYPE::ScalarType *W, MATRIX_TYPE &V, const SortingStrategy sorting=LeaveUnsorted, const int max_iters=30)
00266 {
00267 typedef typename MATRIX_TYPE::ScalarType ScalarType;
00268 int m = (int) A.RowsNumber();
00269 int n = (int) A.ColumnsNumber();
00270 int flag,i,its,j,jj,k,l,nm;
00271 ScalarType anorm, c, f, g, h, s, scale, x, y, z, *rv1;
00272 bool convergence = true;
00273
00274 rv1 = new ScalarType[n];
00275 g = scale = anorm = 0;
00276
00277 for (i=0; i<n; i++)
00278 {
00279 l = i+1;
00280 rv1[i] = scale*g;
00281 g = s = scale = 0.0;
00282 if (i < m)
00283 {
00284 for (k = i; k<m; k++)
00285 scale += fabs(A[k][i]);
00286 if (scale)
00287 {
00288 for (k=i; k<m; k++)
00289 {
00290 A[k][i] /= scale;
00291 s += A[k][i]*A[k][i];
00292 }
00293 f=A[i][i];
00294 g = -sign<ScalarType>( sqrt(s), f );
00295 h = f*g - s;
00296 A[i][i]=f-g;
00297 for (j=l; j<n; j++)
00298 {
00299 for (s=0.0, k=i; k<m; k++)
00300 s += A[k][i]*A[k][j];
00301 f = s/h;
00302 for (k=i; k<m; k++)
00303 A[k][j] += f*A[k][i];
00304 }
00305 for (k=i; k<m; k++)
00306 A[k][i] *= scale;
00307 }
00308 }
00309 W[i] = scale *g;
00310 g = s = scale = 0.0;
00311 if (i < m && i != (n-1))
00312 {
00313 for (k=l; k<n; k++)
00314 scale += fabs(A[i][k]);
00315 if (scale)
00316 {
00317 for (k=l; k<n; k++)
00318 {
00319 A[i][k] /= scale;
00320 s += A[i][k]*A[i][k];
00321 }
00322 f = A[i][l];
00323 g = -sign<ScalarType>(sqrt(s),f);
00324 h = f*g - s;
00325 A[i][l] = f-g;
00326 for (k=l; k<n; k++)
00327 rv1[k] = A[i][k]/h;
00328 for (j=l; j<m; j++)
00329 {
00330 for (s=0.0, k=l; k<n; k++)
00331 s += A[j][k]*A[i][k];
00332 for (k=l; k<n; k++)
00333 A[j][k] += s*rv1[k];
00334 }
00335 for (k=l; k<n; k++)
00336 A[i][k] *= scale;
00337 }
00338 }
00339 anorm=math::Max( anorm, (math::Abs(W[i])+math::Abs(rv1[i])) );
00340 }
00341
00342 for (i=(n-1); i>=0; i--)
00343 {
00344
00345 if (i < (n-1))
00346 {
00347 if (g)
00348 {
00349 for (j=l; j<n;j++)
00350 V[j][i]=(A[i][j]/A[i][l])/g;
00351 for (j=l; j<n; j++)
00352 {
00353 for (s=0.0, k=l; k<n; k++)
00354 s += A[i][k] * V[k][j];
00355 for (k=l; k<n; k++)
00356 V[k][j] += s*V[k][i];
00357 }
00358 }
00359 for (j=l; j<n; j++)
00360 V[i][j] = V[j][i] = 0.0;
00361 }
00362 V[i][i] = 1.0;
00363 g = rv1[i];
00364 l = i;
00365 }
00366
00367 for (i=math::Min(m,n)-1; i>=0; i--)
00368 {
00369 l = i+1;
00370 g = W[i];
00371 for (j=l; j<n; j++)
00372 A[i][j]=0.0;
00373 if (g)
00374 {
00375 g = (ScalarType)1.0/g;
00376 for (j=l; j<n; j++)
00377 {
00378 for (s=0.0, k=l; k<m; k++)
00379 s += A[k][i]*A[k][j];
00380 f = (s/A[i][i])*g;
00381 for (k=i; k<m; k++)
00382 A[k][j] += f*A[k][i];
00383 }
00384 for (j=i; j<m; j++)
00385 A[j][i] *= g;
00386 }
00387 else
00388 for (j=i; j<m; j++)
00389 A[j][i] = 0.0;
00390 ++A[i][i];
00391 }
00392
00393
00394 for (k=(n-1); k>=0; k--)
00395 {
00396 for (its=1; its<=max_iters; its++)
00397 {
00398 flag=1;
00399 for (l=k; l>=0; l--)
00400 {
00401
00402 nm=l-1;
00403
00404 if ((double)(fabs(rv1[l])+anorm) == anorm)
00405 {
00406 flag=0;
00407 break;
00408 }
00409 if ((double)(fabs(W[nm])+anorm) == anorm)
00410 break;
00411 }
00412 if (flag)
00413 {
00414 c=0.0;
00415 s=1.0;
00416 for (i=l ;i<=k; i++)
00417 {
00418 f = s*rv1[i];
00419 rv1[i] = c*rv1[i];
00420 if ((double)(fabs(f)+anorm) == anorm)
00421 break;
00422 g = W[i];
00423 h = pythagora<ScalarType>(f,g);
00424 W[i] = h;
00425 h = (ScalarType)1.0/h;
00426 c = g*h;
00427 s = -f*h;
00428 for (j=0; j<m; j++)
00429 {
00430 y = A[j][nm];
00431 z = A[j][i];
00432 A[j][nm] = y*c + z*s;
00433 A[j][i] = z*c - y*s;
00434 }
00435 }
00436 }
00437 z = W[k];
00438 if (l == k)
00439 {
00440 if (z < 0.0) {
00441 W[k] = -z;
00442 for (j=0; j<n; j++)
00443 V[j][k] = -V[j][k];
00444 }
00445 break;
00446 }
00447 if (its == max_iters)
00448 {
00449 convergence = false;
00450 }
00451 x = W[l];
00452 nm = k-1;
00453 y = W[nm];
00454 g = rv1[nm];
00455 h = rv1[k];
00456 f = ((y-z)*(y+z) + (g-h)*(g+h))/((ScalarType)2.0*h*y);
00457 g = pythagora<ScalarType>(f,1.0);
00458 f=((x-z)*(x+z) + h*((y/(f+sign(g,f)))-h))/x;
00459 c=s=1.0;
00460
00461 for (j=l; j<= nm;j++)
00462 {
00463 i = j+1;
00464 g = rv1[i];
00465 y = W[i];
00466 h = s*g;
00467 g = c*g;
00468 z = pythagora<ScalarType>(f,h);
00469 rv1[j] = z;
00470 c = f/z;
00471 s = h/z;
00472 f = x*c + g*s;
00473 g = g*c - x*s;
00474 h = y*s;
00475 y *= c;
00476 for (jj=0; jj<n; jj++)
00477 {
00478 x = V[jj][j];
00479 z = V[jj][i];
00480 V[jj][j] = x*c + z*s;
00481 V[jj][i] = z*c - x*s;
00482 }
00483 z = pythagora<ScalarType>(f,h);
00484 W[j] = z;
00485
00486 if (z)
00487 {
00488 z = (ScalarType)1.0/z;
00489 c = f*z;
00490 s = h*z;
00491 }
00492 f = c*g + s*y;
00493 x = c*y - s*g;
00494 for (jj=0; jj<m; jj++)
00495 {
00496 y = A[jj][j];
00497 z = A[jj][i];
00498 A[jj][j] = y*c + z*s;
00499 A[jj][i] = z*c - y*s;
00500 }
00501 }
00502 rv1[l] = 0.0;
00503 rv1[k] = f;
00504 W[k] = x;
00505 }
00506 }
00507 delete []rv1;
00508
00509 if (sorting!=LeaveUnsorted)
00510 Sort<MATRIX_TYPE>(A, W, V, sorting);
00511
00512 return convergence;
00513 };
00514
00515
00520
00521 template< typename MATRIX_TYPE >
00522 void Sort(MATRIX_TYPE &U, typename MATRIX_TYPE::ScalarType W[], MATRIX_TYPE &V, const SortingStrategy sorting)
00523 {
00524 typedef typename MATRIX_TYPE::ScalarType ScalarType;
00525
00526 assert(U.ColumnsNumber()==V.ColumnsNumber());
00527
00528 int mu = U.RowsNumber();
00529 int mv = V.RowsNumber();
00530 int n = U.ColumnsNumber();
00531
00532
00533
00534
00535 for (int i=0; i<n; i++)
00536 {
00537 int k = i;
00538 ScalarType p = W[i];
00539 switch (sorting)
00540 {
00541 case SortAscending:
00542 {
00543 for (int j=i+1; j<n; j++)
00544 {
00545 if (W[j] < p)
00546 {
00547 k = j;
00548 p = W[j];
00549 }
00550 }
00551 break;
00552 }
00553 case SortDescending:
00554 {
00555 for (int j=i+1; j<n; j++)
00556 {
00557 if (W[j] > p)
00558 {
00559 k = j;
00560 p = W[j];
00561 }
00562 }
00563 break;
00564 }
00565 case LeaveUnsorted: break;
00566 }
00567 if (k != i)
00568 {
00569 W[k] = W[i];
00570 W[i] = p;
00571
00572 int j = mu;
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 for(int s=0; j!=0; ++s, --j)
00591 std::swap(U[s][i], U[s][k]);
00592
00593 j = mv;
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 for (int s=0; j!=0; ++s, --j)
00608 std::swap(V[s][i], V[s][k]);
00609 }
00610 }
00611 }
00612
00613
00621 template <typename MATRIX_TYPE>
00622 static void SingularValueBacksubstitution(const MATRIX_TYPE &U,
00623 const typename MATRIX_TYPE::ScalarType *W,
00624 const MATRIX_TYPE &V,
00625 typename MATRIX_TYPE::ScalarType *x,
00626 const typename MATRIX_TYPE::ScalarType *b)
00627 {
00628 typedef typename MATRIX_TYPE::ScalarType ScalarType;
00629 unsigned int jj, j, i;
00630 unsigned int columns_number = U.ColumnsNumber();
00631 unsigned int rows_number = U.RowsNumber();
00632 ScalarType s;
00633 ScalarType *tmp = new ScalarType[columns_number];
00634 for (j=0; j<columns_number; j++)
00635 {
00636 s = 0;
00637 if (W[j]!=0)
00638 {
00639 for (i=0; i<rows_number; i++)
00640 s += U[i][j]*b[i];
00641 s /= W[j];
00642 }
00643 tmp[j]=s;
00644 }
00645 for (j=0;j<columns_number;j++)
00646 {
00647 s = 0;
00648 for (jj=0; jj<columns_number; jj++)
00649 s += V[j][jj]*tmp[jj];
00650 x[j]=s;
00651 }
00652 delete []tmp;
00653 };
00654
00656 };
00657
00658 #endif