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