Go to the documentation of this file.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 namespace
00033 cmtk
00034 {
00035
00038
00039 template<class TFloat>
00040 EigenSystemSymmetricMatrix3x3<TFloat>
00041 ::EigenSystemSymmetricMatrix3x3( const Matrix3x3<TFloat>& matrix, const bool sortAbsolute )
00042 {
00043 TFloat e[3];
00044 for (int i = 0; i < 3; i++)
00045 {
00046 for (int j = 0; j < 3; j++)
00047 {
00048 this->m_Eigenvectors[i][j] = matrix[i][j];
00049 }
00050 }
00051 tred2( this->m_Eigenvectors, this->m_Eigenvalues, e);
00052 tql2( this->m_Eigenvectors, this->m_Eigenvalues, e, sortAbsolute );
00053 }
00054
00055 template<class TFloat>
00056 TFloat
00057 EigenSystemSymmetricMatrix3x3<TFloat>
00058 ::hypot2( const TFloat& x, const TFloat& y)
00059 {
00060 return sqrt(x*x+y*y);
00061 }
00062
00063 template<class TFloat>
00064 void
00065 EigenSystemSymmetricMatrix3x3<TFloat>
00066 ::tred2( TFloat V[3][3], TFloat d[3], TFloat e[3] )
00067 {
00068
00069
00070
00071
00072
00073 for (int j = 0; j < 3; j++)
00074 {
00075 d[j] = V[2][j];
00076 }
00077
00078
00079
00080 for (int i = 2; i > 0; i--)
00081 {
00082
00083
00084 TFloat scale = 0.0;
00085 TFloat h = 0.0;
00086 for (int k = 0; k < i; k++)
00087 {
00088 scale = scale + fabs(d[k]);
00089 }
00090 if (scale == 0.0)
00091 {
00092 e[i] = d[i-1];
00093 for (int j = 0; j < i; j++)
00094 {
00095 d[j] = V[i-1][j];
00096 V[i][j] = 0.0;
00097 V[j][i] = 0.0;
00098 }
00099 }
00100 else
00101 {
00102
00103
00104 for (int k = 0; k < i; k++)
00105 {
00106 d[k] /= scale;
00107 h += d[k] * d[k];
00108 }
00109 TFloat f = d[i-1];
00110 TFloat g = sqrt(h);
00111 if (f > 0)
00112 {
00113 g = -g;
00114 }
00115 e[i] = scale * g;
00116 h = h - f * g;
00117 d[i-1] = f - g;
00118 for (int j = 0; j < i; j++)
00119 {
00120 e[j] = 0.0;
00121 }
00122
00123
00124
00125 for (int j = 0; j < i; j++)
00126 {
00127 f = d[j];
00128 V[j][i] = f;
00129 g = e[j] + V[j][j] * f;
00130 for (int k = j+1; k <= i-1; k++)
00131 {
00132 g += V[k][j] * d[k];
00133 e[k] += V[k][j] * f;
00134 }
00135 e[j] = g;
00136 }
00137 f = 0.0;
00138 for (int j = 0; j < i; j++)
00139 {
00140 e[j] /= h;
00141 f += e[j] * d[j];
00142 }
00143 TFloat hh = f / (h + h);
00144 for (int j = 0; j < i; j++)
00145 {
00146 e[j] -= hh * d[j];
00147 }
00148 for (int j = 0; j < i; j++)
00149 {
00150 f = d[j];
00151 g = e[j];
00152 for (int k = j; k <= i-1; k++)
00153 {
00154 V[k][j] -= (f * e[k] + g * d[k]);
00155 }
00156 d[j] = V[i-1][j];
00157 V[i][j] = 0.0;
00158 }
00159 }
00160 d[i] = h;
00161 }
00162
00163
00164
00165 for (int i = 0; i < 2; i++)
00166 {
00167 V[2][i] = V[i][i];
00168 V[i][i] = 1.0;
00169 TFloat h = d[i+1];
00170 if (h != 0.0)
00171 {
00172 for (int k = 0; k <= i; k++)
00173 {
00174 d[k] = V[k][i+1] / h;
00175 }
00176 for (int j = 0; j <= i; j++)
00177 {
00178 TFloat g = 0.0;
00179 for (int k = 0; k <= i; k++)
00180 {
00181 g += V[k][i+1] * V[k][j];
00182 }
00183 for (int k = 0; k <= i; k++)
00184 {
00185 V[k][j] -= g * d[k];
00186 }
00187 }
00188 }
00189 for (int k = 0; k <= i; k++)
00190 {
00191 V[k][i+1] = 0.0;
00192 }
00193 }
00194 for (int j = 0; j < 3; j++)
00195 {
00196 d[j] = V[2][j];
00197 V[2][j] = 0.0;
00198 }
00199 V[2][2] = 1.0;
00200 e[0] = 0.0;
00201 }
00202
00203 template<class TFloat>
00204 void
00205 EigenSystemSymmetricMatrix3x3<TFloat>
00206 ::tql2(TFloat V[3][3], TFloat d[3], TFloat e[3], const bool sortAbsolute)
00207 {
00208
00209
00210
00211
00212
00213 for (int i = 1; i < 3; i++)
00214 {
00215 e[i-1] = e[i];
00216 }
00217 e[2] = 0.0;
00218
00219 TFloat f = 0.0;
00220 TFloat tst1 = 0.0;
00221 TFloat eps = pow(2.0,-52.0);
00222 for (int l = 0; l < 3; l++)
00223 {
00224
00225
00226 tst1 = ( tst1 > fabs( d[l]) + fabs(e[l]) ) ? tst1 : fabs( d[l]) + fabs(e[l]) ;
00227 int m = l;
00228 while (m < 3)
00229 {
00230 if (fabs(e[m]) <= eps*tst1)
00231 {
00232 break;
00233 }
00234 m++;
00235 }
00236
00237
00238
00239
00240 if (m > l)
00241 {
00242 int iter = 0;
00243 do
00244 {
00245 iter = iter + 1;
00246
00247
00248
00249 TFloat g = d[l];
00250 TFloat p = (d[l+1] - g) / (2.0 * e[l]);
00251 TFloat r = hypot2(p,1.0);
00252 if (p < 0)
00253 {
00254 r = -r;
00255 }
00256 d[l] = e[l] / (p + r);
00257 d[l+1] = e[l] * (p + r);
00258 TFloat dl1 = d[l+1];
00259 TFloat h = g - d[l];
00260 for (int i = l+2; i < 3; i++)
00261 {
00262 d[i] -= h;
00263 }
00264 f = f + h;
00265
00266
00267
00268 p = d[m];
00269 TFloat c = 1.0;
00270 TFloat c2 = c;
00271 TFloat c3 = c;
00272 TFloat el1 = e[l+1];
00273 TFloat s = 0.0;
00274 TFloat s2 = 0.0;
00275 for (int i = m-1; i >= l; i--)
00276 {
00277 c3 = c2;
00278 c2 = c;
00279 s2 = s;
00280 g = c * e[i];
00281 h = c * p;
00282 r = hypot2(p,e[i]);
00283 e[i+1] = s * r;
00284 s = e[i] / r;
00285 c = p / r;
00286 p = c * d[i] - s * g;
00287 d[i+1] = h + s * (c * g + s * d[i]);
00288
00289
00290
00291 for (int k = 0; k < 3; k++)
00292 {
00293 h = V[k][i+1];
00294 V[k][i+1] = s * V[k][i] + c * h;
00295 V[k][i] = c * V[k][i] - s * h;
00296 }
00297 }
00298 p = -s * s2 * c3 * el1 * e[l] / dl1;
00299 e[l] = s * p;
00300 d[l] = c * p;
00301
00302
00303
00304 }
00305 while (fabs(e[l]) > eps*tst1);
00306 }
00307 d[l] = d[l] + f;
00308 e[l] = 0.0;
00309 }
00310
00311
00312
00313 for (int i = 0; i < 2; i++)
00314 {
00315 int k = i;
00316 TFloat p = d[i];
00317 for (int j = i+1; j < 3; j++)
00318 {
00319 const bool swap = sortAbsolute ? (fabs(d[j]) < fabs(p)) : (d[j] < p);
00320 if ( swap )
00321 {
00322 k = j;
00323 p = d[j];
00324 }
00325 }
00326 if (k != i)
00327 {
00328 d[k] = d[i];
00329 d[i] = p;
00330 for (int j = 0; j < 3; j++)
00331 {
00332 p = V[j][i];
00333 V[j][i] = V[j][k];
00334 V[j][k] = p;
00335 }
00336 }
00337 }
00338 }
00339
00340 }