MeVisLabToolboxReference
|
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