old_lin_algebra.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2006                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 /****************************************************************************
00024 History
00025 
00026 $Log: not supported by cvs2svn $
00027 Revision 1.16  2007/01/29 00:18:20  pietroni
00028 -added some explicit CASTs in order to avoid warning if one use float instead of double as ScalarType
00029 
00030 Revision 1.15  2006/09/29 08:36:10  cignoni
00031 Added missing typedef for gcc compiing
00032 
00033 Revision 1.14  2006/09/28 22:49:49  fiorin
00034 Removed some warnings
00035 
00036 Revision 1.13  2006/07/28 12:39:05  zifnab1974
00037 added some typename directives
00038 
00039 Revision 1.12  2006/07/24 07:26:47  fiorin
00040 Changed the template argument in JacobiRotate and added method for sorting eigenvalues and eigenvectors (SortEigenvaluesAndEigenvectors)
00041 
00042 Revision 1.11  2006/05/25 09:35:55  cignoni
00043 added missing internal prototype to Sort function
00044 
00045 Revision 1.10  2006/05/17 09:26:35  cignoni
00046 Added initial disclaimer
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                 //assert(w.IsSymmetric());
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)                    //Initialize b and d to the diagonal of a.
00097                 {
00098                         b[ip]=d[ip]=w[ip][ip];
00099                         z[ip]=ScalarType(0.0);                                                  //This vector will accumulate terms of the form tapq as in equation (11.1.14).
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)          // Sum off diagonal elements
00106                         {
00107                                 for (iq=ip+1;iq<dimension;++iq)
00108                                         sm += math::Abs(w[ip][iq]);
00109                         }
00110                         if (sm == ScalarType(0.0))                                      //The normal return, which relies on quadratic convergence to machine underflow.
00111                         {
00112                                 return;
00113                         }
00114                         if (i < 4)
00115                                 tresh=ScalarType(0.2)*sm/(dimension*dimension); //...on the first three sweeps.
00116                         else
00117                                 tresh=ScalarType(0.0);                          //...thereafter.
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                                         //After four sweeps, skip the rotation if the off-diagonal element is small.
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; //t =1/(2#)
00131                                                 else
00132                                                 {
00133                                                         theta=ScalarType(0.5)*h/(w[ip][iq]); //Equation (11.1.10).
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++) { //Case of rotations 1 <= j < p.
00147                                                         JacobiRotate<MATRIX_TYPE>(w,s,tau,j,ip,j,iq) ;
00148                                                 }
00149                                                 for (j=ip+1;j<=iq-1;j++) { //Case of rotations p < j < q.
00150                                                         JacobiRotate<MATRIX_TYPE>(w,s,tau,ip,j,j,iq);
00151                                                 }
00152                                                 for (j=iq+1;j<dimension;j++) { //Case of rotations q< j <= n.
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]; //Update d with the sum of ta_pq ,
00166                                 z[ip]=0.0; //and reinitialize z.
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];  // i.e.
00210                                 eigenvalues[i] = p;                                                             // swaps the value of the elements i-th and k-th
00211 
00212                                 for (j=0; j<dimension; j++)
00213                                 {
00214                                         p = eigenvectors[j][i];                                                                         // i.e.
00215                                         eigenvectors[j][i] = eigenvectors[j][k];        // swaps the eigenvectors stored in the
00216                                         eigenvectors[j][k] = p;                                                                         // i-th and the k-th column
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         // Computes (a^2 + b^2)^(1/2) without destructive underflow or overflow.
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                 // Householder reduction to bidiagonal form.
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                 // Accumulation of right-hand transformations.
00344                 for (i=(n-1); i>=0; i--)
00345                 {
00346                         //Accumulation of right-hand transformations.
00347                         if (i < (n-1))
00348                         {
00349                                 if (g)
00350                                 {
00351                                         for (j=l; j<n;j++) //Double division to avoid possible underflow.
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                 // Accumulation of left-hand transformations.
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                 // Diagonalization of the bidiagonal form: Loop over
00395                 // singular values, and over allowed iterations.
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                                         // Test for splitting.
00404                                         nm=l-1;
00405                                         // Note that rv1[1] is always zero.
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;  //Cancellation of rv1[l], if l > 1.
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)  //Convergence.
00441                                 {
00442                                         if (z < 0.0) { // Singular value is made nonnegative.
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]; // Shift from bottom 2-by-2 minor.
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                                 //Next QR transformation:
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                                         // Rotation can be arbitrary if z = 0.
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         // TODO modify the last parameter type
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                 //ScalarType* u = &U[0][0];
00535                 //ScalarType* v = &V[0][0];
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; // nothing to do.
00568       }
00569                         if (k != i)
00570                         {
00571                                 W[k] = W[i];  // i.e.
00572                                 W[i] = p;                       // swaps the i-th and the k-th elements
00573 
00574                                 int j = mu;
00575                                 //ScalarType* uji = u + i; // uji = &U[0][i]
00576                                 //ScalarType* ujk = u + k; // ujk = &U[0][k]
00577                                 //ScalarType* vji = v + i; // vji = &V[0][i]
00578                                 //ScalarType* vjk = v + k; // vjk = &V[0][k]
00579                                 //if (j)
00580                                 //{
00581                                 //      for(;;)                                                                 for( ; j!=0; --j, uji+=n, ujk+=n)
00582                                 //      {                                                                                               {
00583                                 //              p = *uji;                                                               p = *uji;                       // i.e.
00584                                 //              *uji = *ujk;                                            *uji = *ujk;    // swap( U[s][i], U[s][k] )
00585                                 //              *ujk = p;                                                               *ujk = p;                       //
00586                                 //              if (!(--j))                                             }
00587                                 //                      break;
00588                                 //              uji += n;
00589                                 //              ujk += n;
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                                 //if (j!=0)
00597                                 //{
00598                                 //      for(;;)                                                                 for ( ; j!=0; --j, vji+=n, ujk+=n)
00599                                 //      {                                                                                               {
00600                                 //              p    = *vji;                                            p    = *vji;    // i.e.
00601                                 //              *vji = *vjk;                                            *vji = *vjk;    // swap( V[s][i], V[s][k] )
00602                                 //              *vjk = p;                                                               *vjk = p;                       //
00603                                 //              if (!(--j))                                             }
00604                                 //                      break;
00605                                 //              vji += n;
00606                                 //              vjk += n;
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++) //Calculate U^T * B.
00637                 {
00638                         s = 0;
00639                         if (W[j]!=0)                                                    //Nonzero result only if wj is nonzero.
00640                         {
00641                                 for (i=0; i<rows_number; i++)
00642                                         s += U[i][j]*b[i];
00643                                 s /= W[j];                                                      //This is the divide by wj .
00644                         }
00645                         tmp[j]=s;
00646                 }
00647                 for (j=0;j<columns_number;j++)  //Matrix multiply by V to get answer.
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 }; // end of namespace
00659 
00660 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:33:33