MeVisLabToolboxReference
MeVisLab/Standard/Sources/Shared/MLPointCloudUtils/MLMainAxisPCA/MainAxisPCAMatrixRoutines.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 
00006 
00007 #ifndef __MainAxisPCAMatrixRoutines_H
00008 #define __MainAxisPCAMatrixRoutines_H
00009 
00010 
00011 #define JACOBI_ROTATE(a,i,j,k,l) \
00012   g=a[i][j];                   \
00013   h=a[k][l];                   \
00014   a[i][j]=g-s*(h+g*tau);       \
00015   a[k][l]=h+s*(g-h*tau);
00016 
00017 #define NR_END 1
00018 #define FREE_ARG char*
00019 
00020 
00021 //--------------------------------------------------------------------------
00022 // Numerical Recipes standard error handler
00023 //--------------------------------------------------------------------------
00024 void nrerror(char /*error_text*/[])
00025 {        
00026   // do nothing
00027 }
00028 
00029 
00030 //--------------------------------------------------------------------------
00031 // Allocate a variable length float vector with subscript range v[nl..nh]
00032 //--------------------------------------------------------------------------
00033 float *vL_vector(long nl, long nh)
00034 {    
00035   float *v = (float *) malloc((size_t)((nh-nl+1+NR_END)*sizeof(float)));
00036 
00037   if (!v){ nrerror("allocation failure in vector()"); return NULL; }
00038 
00039   return v+NR_END-nl;
00040 }
00041 
00042 
00043 //--------------------------------------------------------------------------
00044 // Free a float vector allocated with vector()
00045 //--------------------------------------------------------------------------
00046 void free_vector(float *v, long nl, long /*nh*/)
00047 {    
00048   free((FREE_ARG) (v+nl-NR_END));
00049 }
00050 
00051 
00052 //--------------------------------------------------------------------------
00053 // Allocate a float matrix with subscript range m[nrl..nrh][ncl..nch]
00054 //--------------------------------------------------------------------------
00055 float **matrix(long nrl, long nrh, long ncl, long nch)
00056 {    
00057   // r -> row: Zeile
00058   // c -> column: Spalte
00059 
00060   long i=0;
00061   long nrow=0, ncol=0;
00062   float **m=NULL;
00063 
00064   nrow = nrh-nrl+1;
00065   ncol = nch-ncl+1;
00066 
00067   // Allocate pointers to rows
00068   m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*)));
00069   if (!m) nrerror("allocation failure 1 in matrix()");
00070   m += NR_END;
00071   m -= nrl;
00072 
00073   // Allocate rows and set pointers to them
00074   m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float)));
00075   if (!m[nrl]) nrerror("allocation failure 2 in matrix()");
00076   m[nrl] += NR_END;
00077   m[nrl] -= ncl;
00078 
00079   for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
00080 
00081   // Return pointer to array of pointers to rows.
00082   return m;
00083 }
00084 
00085 
00086 
00087 //--------------------------------------------------------------------------
00088 // Free a float matrix allocated by matrix()
00089 //--------------------------------------------------------------------------
00090 void free_matrix(float **m, long nrl, long /*nrh*/, long ncl, long /*nch*/)
00091 {    
00092   free((FREE_ARG) (m[nrl]+ncl-NR_END));
00093   free((FREE_ARG) (m+nrl-NR_END));
00094 }
00095 
00096 
00097 
00098 //--------------------------------------------------------------------------
00099 //  Compute the jacobi matrix.
00100 //--------------------------------------------------------------------------
00101 void jacobi(float **a, int n, float d[], float **v, int *nrot)
00102 {    
00103   int j=0,iq=0,ip=0,i=0;
00104   float tresh=0,theta=0,tau=0,t=0,sm=0,s=0,h=0,g=0,c=0,*b=NULL,*z=NULL;
00105 
00106   b = vL_vector(1,n);
00107   z = vL_vector(1,n);
00108 
00109   // Make v be a unit Matrix.
00110   for (ip=1;ip<=n;ip++) 
00111   {
00112     for (iq=1;iq<=n;iq++) {
00113       v[ip][iq]=0.0;
00114     }
00115 
00116     v[ip][ip]=1.0;
00117   }
00118 
00119   for (ip=1;ip<=n;ip++) 
00120   {
00121     b[ip]=d[ip]=a[ip][ip];
00122     z[ip]=0.0;
00123   }
00124 
00125   *nrot=0;
00126 
00127   for (i=1;i<=50;i++) 
00128   {
00129     sm=0.0;
00130     for (ip=1;ip<=n-1;ip++) 
00131     {
00132       for (iq=ip+1;iq<=n;iq++) {
00133         sm += fabs(a[ip][iq]);
00134       }
00135     }
00136 
00137     if (sm == 0.0) 
00138     {
00139       free_vector(z,1,n);
00140       free_vector(b,1,n);
00141       return;
00142     }
00143 
00144     if (i < 4) {
00145       tresh=0.2*sm/(n*n);
00146     } else {
00147       tresh=0.0;
00148     }
00149 
00150     for (ip=1;ip<=n-1;ip++) {
00151 
00152       for (iq=ip+1;iq<=n;iq++) {
00153 
00154         g=100.0*fabs(a[ip][iq]);
00155 
00156         if ((i > 4) && ((float)(fabs(d[ip])+g) == (float)fabs(d[ip]))
00157           && ((float)(fabs(d[iq])+g) == (float)fabs(d[iq]))){
00158 
00159             a[ip][iq]=0.0;
00160         }                
00161         else if (fabs(a[ip][iq]) > tresh) 
00162         {
00163           h=d[iq]-d[ip];
00164           if ((float)(fabs(h)+g) == (float)fabs(h)){
00165             t=(a[ip][iq])/h;
00166           } else {
00167             theta=0.5*h/(a[ip][iq]);
00168             t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
00169             if (theta < 0.0) { t = -t; }
00170           }
00171 
00172           c=1.0/sqrt(1+t*t);
00173           s=t*c;
00174           tau=s/(1.0+c);
00175           h=t*a[ip][iq];
00176           z[ip] -= h;
00177           z[iq] += h;
00178           d[ip] -= h;
00179           d[iq] += h;
00180           a[ip][iq]=0.0;
00181 
00182           for (j=1;j<=ip-1;j++){                   
00183             JACOBI_ROTATE(a,j,ip,j,iq)
00184           }
00185 
00186           for (j=ip+1;j<=iq-1;j++) {
00187             JACOBI_ROTATE(a,ip,j,j,iq)
00188           }
00189 
00190           for (j=iq+1;j<=n;j++) {
00191             JACOBI_ROTATE(a,ip,j,iq,j)
00192           }
00193 
00194           for (j=1;j<=n;j++) {
00195             JACOBI_ROTATE(v,j,ip,j,iq)
00196           }
00197 
00198           ++(*nrot);
00199         }
00200       }
00201     }
00202 
00203     for (ip=1;ip<=n;ip++) 
00204     {
00205       b[ip] += z[ip];
00206       d[ip]=b[ip];
00207       z[ip]=0.0;
00208     }
00209   }
00210   nrerror("Too many iterations in routine jacobi");
00211 } //jacobi
00212 
00213 #undef JACOBI_ROTATE
00214 
00215 
00216 #endif // __MainAxisPCAMatrixRoutines_H