00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "MgcRTLib.h"
00014
00015 #include "MgcEigen.h"
00016
00017
00018 MgcEigen::MgcEigen (int iSize)
00019 {
00020 assert( iSize >= 2 );
00021 m_iSize = iSize;
00022
00023 m_aafMat = new MgcReal*[m_iSize];
00024 for (int i = 0; i < m_iSize; i++)
00025 m_aafMat[i] = new MgcReal[m_iSize];
00026
00027 m_afDiag = new MgcReal[m_iSize];
00028 m_afSubd = new MgcReal[m_iSize];
00029 }
00030
00031 MgcEigen::~MgcEigen ()
00032 {
00033 delete[] m_afSubd;
00034 delete[] m_afDiag;
00035 for (int i = 0; i < m_iSize; i++)
00036 delete[] m_aafMat[i];
00037 delete[] m_aafMat;
00038 }
00039
00040 void MgcEigen::Tridiagonal2 (MgcReal** m_aafMat, MgcReal* m_afDiag,
00041 MgcReal* m_afSubd)
00042 {
00043
00044 m_afDiag[0] = m_aafMat[0][0];
00045 m_afDiag[1] = m_aafMat[1][1];
00046 m_afSubd[0] = m_aafMat[0][1];
00047 m_afSubd[1] = 0.0;
00048 m_aafMat[0][0] = 1.0;
00049 m_aafMat[0][1] = 0.0;
00050 m_aafMat[1][0] = 0.0;
00051 m_aafMat[1][1] = 1.0;
00052 }
00053
00054 void MgcEigen::Tridiagonal3 (MgcReal** m_aafMat, MgcReal* m_afDiag,
00055 MgcReal* m_afSubd)
00056 {
00057 MgcReal fM00 = m_aafMat[0][0];
00058 MgcReal fM01 = m_aafMat[0][1];
00059 MgcReal fM02 = m_aafMat[0][2];
00060 MgcReal fM11 = m_aafMat[1][1];
00061 MgcReal fM12 = m_aafMat[1][2];
00062 MgcReal fM22 = m_aafMat[2][2];
00063
00064 m_afDiag[0] = fM00;
00065 m_afSubd[2] = 0.0;
00066 if ( fM02 != 0.0 )
00067 {
00068 MgcReal fLength = MgcMath::Sqrt(fM01*fM01+fM02*fM02);
00069 MgcReal fInvLength = 1.0/fLength;
00070 fM01 *= fInvLength;
00071 fM02 *= fInvLength;
00072 MgcReal fQ = 2.0*fM01*fM12+fM02*(fM22-fM11);
00073 m_afDiag[1] = fM11+fM02*fQ;
00074 m_afDiag[2] = fM22-fM02*fQ;
00075 m_afSubd[0] = fLength;
00076 m_afSubd[1] = fM12-fM01*fQ;
00077 m_aafMat[0][0] = 1.0; m_aafMat[0][1] = 0.0; m_aafMat[0][2] = 0.0;
00078 m_aafMat[1][0] = 0.0; m_aafMat[1][1] = fM01; m_aafMat[1][2] = fM02;
00079 m_aafMat[2][0] = 0.0; m_aafMat[2][1] = fM02; m_aafMat[2][2] = -fM01;
00080 }
00081 else
00082 {
00083 m_afDiag[1] = fM11;
00084 m_afDiag[2] = fM22;
00085 m_afSubd[0] = fM01;
00086 m_afSubd[1] = fM12;
00087 m_aafMat[0][0] = 1.0; m_aafMat[0][1] = 0.0; m_aafMat[0][2] = 0.0;
00088 m_aafMat[1][0] = 0.0; m_aafMat[1][1] = 1.0; m_aafMat[1][2] = 0.0;
00089 m_aafMat[2][0] = 0.0; m_aafMat[2][1] = 0.0; m_aafMat[2][2] = 1.0;
00090 }
00091 }
00092
00093 void MgcEigen::Tridiagonal4 (MgcReal** m_aafMat, MgcReal* m_afDiag,
00094 MgcReal* m_afSubd)
00095 {
00096
00097 MgcReal fM00 = m_aafMat[0][0];
00098 MgcReal fM01 = m_aafMat[0][1];
00099 MgcReal fM02 = m_aafMat[0][2];
00100 MgcReal fM03 = m_aafMat[0][3];
00101 MgcReal fM11 = m_aafMat[1][1];
00102 MgcReal fM12 = m_aafMat[1][2];
00103 MgcReal fM13 = m_aafMat[1][3];
00104 MgcReal fM22 = m_aafMat[2][2];
00105 MgcReal fM23 = m_aafMat[2][3];
00106 MgcReal fM33 = m_aafMat[3][3];
00107
00108 m_afDiag[0] = fM00;
00109 m_afSubd[3] = 0.0;
00110
00111 m_aafMat[0][0] = 1.0;
00112 m_aafMat[0][1] = 0.0;
00113 m_aafMat[0][2] = 0.0;
00114 m_aafMat[0][3] = 0.0;
00115 m_aafMat[1][0] = 0.0;
00116 m_aafMat[2][0] = 0.0;
00117 m_aafMat[3][0] = 0.0;
00118
00119 double fLength, fInvLength;
00120
00121 if ( fM02 != 0.0 || fM03 != 0.0 )
00122 {
00123 MgcReal fQ11, fQ12, fQ13;
00124 MgcReal fQ21, fQ22, fQ23;
00125 MgcReal fQ31, fQ32, fQ33;
00126
00127
00128 fLength = MgcMath::Sqrt(fM01*fM01+fM02*fM02+fM03*fM03);
00129 fInvLength = 1.0/fLength;
00130 fQ11 = fM01*fInvLength;
00131 fQ21 = fM02*fInvLength;
00132 fQ31 = fM03*fInvLength;
00133
00134 m_afSubd[0] = fLength;
00135
00136
00137 MgcReal fV0 = fM11*fQ11+fM12*fQ21+fM13*fQ31;
00138 MgcReal fV1 = fM12*fQ11+fM22*fQ21+fM23*fQ31;
00139 MgcReal fV2 = fM13*fQ11+fM23*fQ21+fM33*fQ31;
00140
00141 m_afDiag[1] = fQ11*fV0+fQ21*fV1+fQ31*fV2;
00142
00143
00144 fQ13 = fQ21*fV2-fQ31*fV1;
00145 fQ23 = fQ31*fV0-fQ11*fV2;
00146 fQ33 = fQ11*fV1-fQ21*fV0;
00147 fLength = MgcMath::Sqrt(fQ13*fQ13+fQ23*fQ23+fQ33*fQ33);
00148 if ( fLength > 0.0 )
00149 {
00150 fInvLength = 1.0/fLength;
00151 fQ13 *= fInvLength;
00152 fQ23 *= fInvLength;
00153 fQ33 *= fInvLength;
00154
00155
00156 fQ12 = fQ23*fQ31-fQ33*fQ21;
00157 fQ22 = fQ33*fQ11-fQ13*fQ31;
00158 fQ32 = fQ13*fQ21-fQ23*fQ11;
00159
00160 fV0 = fQ12*fM11+fQ22*fM12+fQ32*fM13;
00161 fV1 = fQ12*fM12+fQ22*fM22+fQ32*fM23;
00162 fV2 = fQ12*fM13+fQ22*fM23+fQ32*fM33;
00163 m_afSubd[1] = fQ11*fV0+fQ21*fV1+fQ31*fV2;
00164 m_afDiag[2] = fQ12*fV0+fQ22*fV1+fQ32*fV2;
00165 m_afSubd[2] = fQ13*fV0+fQ23*fV1+fQ33*fV2;
00166
00167 fV0 = fQ13*fM11+fQ23*fM12+fQ33*fM13;
00168 fV1 = fQ13*fM12+fQ23*fM22+fQ33*fM23;
00169 fV2 = fQ13*fM13+fQ23*fM23+fQ33*fM33;
00170 m_afDiag[3] = fQ13*fV0+fQ23*fV1+fQ33*fV2;
00171 }
00172 else
00173 {
00174
00175 m_afSubd[1] = 0;
00176
00177 fLength = fQ21*fQ21+fQ31*fQ31;
00178 if ( fLength > 0.0 )
00179 {
00180 fInvLength = 1.0/fLength;
00181 MgcReal fTmp = fQ11-1.0;
00182 fQ12 = -fQ21;
00183 fQ22 = 1.0+fTmp*fQ21*fQ21*fInvLength;
00184 fQ32 = fTmp*fQ21*fQ31*fInvLength;
00185
00186 fQ13 = -fQ31;
00187 fQ23 = fQ32;
00188 fQ33 = 1.0+fTmp*fQ31*fQ31*fInvLength;
00189
00190 fV0 = fQ12*fM11+fQ22*fM12+fQ32*fM13;
00191 fV1 = fQ12*fM12+fQ22*fM22+fQ32*fM23;
00192 fV2 = fQ12*fM13+fQ22*fM23+fQ32*fM33;
00193 m_afDiag[2] = fQ12*fV0+fQ22*fV1+fQ32*fV2;
00194 m_afSubd[2] = fQ13*fV0+fQ23*fV1+fQ33*fV2;
00195
00196 fV0 = fQ13*fM11+fQ23*fM12+fQ33*fM13;
00197 fV1 = fQ13*fM12+fQ23*fM22+fQ33*fM23;
00198 fV2 = fQ13*fM13+fQ23*fM23+fQ33*fM33;
00199 m_afDiag[3] = fQ13*fV0+fQ23*fV1+fQ33*fV2;
00200 }
00201 else
00202 {
00203
00204 fQ12 = 0.0; fQ22 = 1.0; fQ32 = 0.0;
00205 fQ13 = 0.0; fQ23 = 0.0; fQ33 = 1.0;
00206
00207 m_afDiag[2] = fM22;
00208 m_afDiag[3] = fM33;
00209 m_afSubd[2] = fM23;
00210 }
00211 }
00212
00213 m_aafMat[1][1] = fQ11; m_aafMat[1][2] = fQ12; m_aafMat[1][3] = fQ13;
00214 m_aafMat[2][1] = fQ21; m_aafMat[2][2] = fQ22; m_aafMat[2][3] = fQ23;
00215 m_aafMat[3][1] = fQ31; m_aafMat[3][2] = fQ32; m_aafMat[3][3] = fQ33;
00216 }
00217 else
00218 {
00219 m_afDiag[1] = fM11;
00220 m_afSubd[0] = fM01;
00221 m_aafMat[1][1] = 1.0;
00222 m_aafMat[2][1] = 0.0;
00223 m_aafMat[3][1] = 0.0;
00224
00225 if ( fM13 != 0.0 )
00226 {
00227 fLength = MgcMath::Sqrt(fM12*fM12+fM13*fM13);
00228 fInvLength = 1.0/fLength;
00229 fM12 *= fInvLength;
00230 fM13 *= fInvLength;
00231 MgcReal fQ = 2.0*fM12*fM23+fM13*(fM33-fM22);
00232
00233 m_afDiag[2] = fM22+fM13*fQ;
00234 m_afDiag[3] = fM33-fM13*fQ;
00235 m_afSubd[1] = fLength;
00236 m_afSubd[2] = fM23-fM12*fQ;
00237 m_aafMat[1][2] = 0.0;
00238 m_aafMat[1][3] = 0.0;
00239 m_aafMat[2][2] = fM12;
00240 m_aafMat[2][3] = fM13;
00241 m_aafMat[3][2] = fM13;
00242 m_aafMat[3][3] = -fM12;
00243 }
00244 else
00245 {
00246 m_afDiag[2] = fM22;
00247 m_afDiag[3] = fM33;
00248 m_afSubd[1] = fM12;
00249 m_afSubd[2] = fM23;
00250 m_aafMat[1][2] = 0.0;
00251 m_aafMat[1][3] = 0.0;
00252 m_aafMat[2][2] = 1.0;
00253 m_aafMat[2][3] = 0.0;
00254 m_aafMat[3][2] = 0.0;
00255 m_aafMat[3][3] = 1.0;
00256 }
00257 }
00258 }
00259
00260 void MgcEigen::TridiagonalN (int iSize, MgcReal** m_aafMat,
00261 MgcReal* m_afDiag, MgcReal* m_afSubd)
00262 {
00263 int i0, i1, i2, i3;
00264
00265 for (i0 = iSize-1, i3 = iSize-2; i0 >= 1; i0--, i3--)
00266 {
00267 MgcReal fH = 0.0, fScale = 0.0;
00268
00269 if ( i3 > 0 )
00270 {
00271 for (i2 = 0; i2 <= i3; i2++)
00272 fScale += MgcMath::Abs(m_aafMat[i0][i2]);
00273 if ( fScale == 0 )
00274 {
00275 m_afSubd[i0] = m_aafMat[i0][i3];
00276 }
00277 else
00278 {
00279 double fInvScale = 1.0/fScale;
00280 for (i2 = 0; i2 <= i3; i2++)
00281 {
00282 m_aafMat[i0][i2] *= fInvScale;
00283 fH += m_aafMat[i0][i2]*m_aafMat[i0][i2];
00284 }
00285 MgcReal fF = m_aafMat[i0][i3];
00286 MgcReal fG = MgcMath::Sqrt(fH);
00287 if ( fF > 0.0 )
00288 fG = -fG;
00289 m_afSubd[i0] = fScale*fG;
00290 fH -= fF*fG;
00291 m_aafMat[i0][i3] = fF-fG;
00292 fF = 0.0;
00293 double fInvH = 1.0/fH;
00294 for (i1 = 0; i1 <= i3; i1++)
00295 {
00296 m_aafMat[i1][i0] = m_aafMat[i0][i1]*fInvH;
00297 fG = 0.0;
00298 for (i2 = 0; i2 <= i1; i2++)
00299 fG += m_aafMat[i1][i2]*m_aafMat[i0][i2];
00300 for (i2 = i1+1; i2 <= i3; i2++)
00301 fG += m_aafMat[i2][i1]*m_aafMat[i0][i2];
00302 m_afSubd[i1] = fG*fInvH;
00303 fF += m_afSubd[i1]*m_aafMat[i0][i1];
00304 }
00305 MgcReal fHalfFdivH = 0.5*fF*fInvH;
00306 for (i1 = 0; i1 <= i3; i1++)
00307 {
00308 fF = m_aafMat[i0][i1];
00309 fG = m_afSubd[i1] - fHalfFdivH*fF;
00310 m_afSubd[i1] = fG;
00311 for (i2 = 0; i2 <= i1; i2++)
00312 {
00313 m_aafMat[i1][i2] -= fF*m_afSubd[i2] +
00314 fG*m_aafMat[i0][i2];
00315 }
00316 }
00317 }
00318 }
00319 else
00320 {
00321 m_afSubd[i0] = m_aafMat[i0][i3];
00322 }
00323
00324 m_afDiag[i0] = fH;
00325 }
00326
00327 m_afDiag[0] = m_afSubd[0] = 0;
00328 for (i0 = 0, i3 = -1; i0 <= iSize-1; i0++, i3++)
00329 {
00330 if ( m_afDiag[i0] )
00331 {
00332 for (i1 = 0; i1 <= i3; i1++)
00333 {
00334 MgcReal fSum = 0;
00335 for (i2 = 0; i2 <= i3; i2++)
00336 fSum += m_aafMat[i0][i2]*m_aafMat[i2][i1];
00337 for (i2 = 0; i2 <= i3; i2++)
00338 m_aafMat[i2][i1] -= fSum*m_aafMat[i2][i0];
00339 }
00340 }
00341 m_afDiag[i0] = m_aafMat[i0][i0];
00342 m_aafMat[i0][i0] = 1;
00343 for (i1 = 0; i1 <= i3; i1++)
00344 m_aafMat[i1][i0] = m_aafMat[i0][i1] = 0;
00345 }
00346
00347
00348 for (i0 = 1, i3 = 0; i0 < iSize; i0++, i3++)
00349 m_afSubd[i3] = m_afSubd[i0];
00350 m_afSubd[iSize-1] = 0;
00351 }
00352
00353 bool MgcEigen::QLAlgorithm (int iSize, MgcReal* m_afDiag, MgcReal* m_afSubd,
00354 MgcReal** m_aafMat)
00355 {
00356 const int iMaxIter = 32;
00357
00358 for (int i0 = 0; i0 < iSize; i0++)
00359 {
00360 int i1;
00361 for (i1 = 0; i1 < iMaxIter; i1++)
00362 {
00363 int i2;
00364 for (i2 = i0; i2 <= iSize-2; i2++)
00365 {
00366 MgcReal fTmp =
00367 MgcMath::Abs(m_afDiag[i2])+MgcMath::Abs(m_afDiag[i2+1]);
00368 if ( MgcMath::Abs(m_afSubd[i2]) + fTmp == fTmp )
00369 break;
00370 }
00371 if ( i2 == i0 )
00372 break;
00373
00374 MgcReal fG = (m_afDiag[i0+1]-m_afDiag[i0])/(2.0*m_afSubd[i0]);
00375 MgcReal fR = MgcMath::Sqrt(fG*fG+1.0);
00376 if ( fG < 0.0 )
00377 fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG-fR);
00378 else
00379 fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG+fR);
00380 MgcReal fSin = 1.0, fCos = 1.0, fP = 0.0;
00381 for (int i3 = i2-1; i3 >= i0; i3--)
00382 {
00383 MgcReal fF = fSin*m_afSubd[i3];
00384 MgcReal fB = fCos*m_afSubd[i3];
00385 if ( MgcMath::Abs(fF) >= MgcMath::Abs(fG) )
00386 {
00387 fCos = fG/fF;
00388 fR = MgcMath::Sqrt(fCos*fCos+1.0);
00389 m_afSubd[i3+1] = fF*fR;
00390 fSin = 1.0/fR;
00391 fCos *= fSin;
00392 }
00393 else
00394 {
00395 fSin = fF/fG;
00396 fR = MgcMath::Sqrt(fSin*fSin+1.0);
00397 m_afSubd[i3+1] = fG*fR;
00398 fCos = 1.0/fR;
00399 fSin *= fCos;
00400 }
00401 fG = m_afDiag[i3+1]-fP;
00402 fR = (m_afDiag[i3]-fG)*fSin+2.0*fB*fCos;
00403 fP = fSin*fR;
00404 m_afDiag[i3+1] = fG+fP;
00405 fG = fCos*fR-fB;
00406
00407 for (int i4 = 0; i4 < iSize; i4++)
00408 {
00409 fF = m_aafMat[i4][i3+1];
00410 m_aafMat[i4][i3+1] = fSin*m_aafMat[i4][i3]+fCos*fF;
00411 m_aafMat[i4][i3] = fCos*m_aafMat[i4][i3]-fSin*fF;
00412 }
00413 }
00414 m_afDiag[i0] -= fP;
00415 m_afSubd[i0] = fG;
00416 m_afSubd[i2] = 0.0;
00417 }
00418 if ( i1 == iMaxIter )
00419 return false;
00420 }
00421
00422 return true;
00423 }
00424
00425 void MgcEigen::DecreasingSort (int iSize, MgcReal* afEigval,
00426 MgcReal** aafEigvec)
00427 {
00428
00429 for (int i0 = 0, i1; i0 <= iSize-2; i0++)
00430 {
00431
00432 i1 = i0;
00433 MgcReal fMax = afEigval[i1];
00434 int i2;
00435 for (i2 = i0+1; i2 < iSize; i2++)
00436 {
00437 if ( afEigval[i2] > fMax )
00438 {
00439 i1 = i2;
00440 fMax = afEigval[i1];
00441 }
00442 }
00443
00444 if ( i1 != i0 )
00445 {
00446
00447 afEigval[i1] = afEigval[i0];
00448 afEigval[i0] = fMax;
00449
00450
00451 for (i2 = 0; i2 < iSize; i2++)
00452 {
00453 MgcReal fTmp = aafEigvec[i2][i0];
00454 aafEigvec[i2][i0] = aafEigvec[i2][i1];
00455 aafEigvec[i2][i1] = fTmp;
00456 }
00457 }
00458 }
00459 }
00460
00461 void MgcEigen::IncreasingSort (int iSize, MgcReal* afEigval,
00462 MgcReal** aafEigvec)
00463 {
00464
00465 for (int i0 = 0, i1; i0 <= iSize-2; i0++)
00466 {
00467
00468 i1 = i0;
00469 MgcReal fMin = afEigval[i1];
00470 int i2;
00471 for (i2 = i0+1; i2 < iSize; i2++)
00472 {
00473 if ( afEigval[i2] < fMin )
00474 {
00475 i1 = i1;
00476 fMin = afEigval[i1];
00477 }
00478 }
00479
00480 if ( i1 != i0 )
00481 {
00482
00483 afEigval[i1] = afEigval[i0];
00484 afEigval[i0] = fMin;
00485
00486
00487 for (i2 = 0; i2 < iSize; i2++)
00488 {
00489 MgcReal fTmp = aafEigvec[i2][i0];
00490 aafEigvec[i2][i0] = aafEigvec[i2][i1];
00491 aafEigvec[i2][i1] = fTmp;
00492 }
00493 }
00494 }
00495 }
00496
00497 void MgcEigen::SetMatrix (MgcReal** aafMat)
00498 {
00499 for (int iRow = 0; iRow < m_iSize; iRow++)
00500 {
00501 for (int iCol = 0; iCol < m_iSize; iCol++)
00502 m_aafMat[iRow][iCol] = aafMat[iRow][iCol];
00503 }
00504 }
00505
00506 void MgcEigen::EigenStuff2 ()
00507 {
00508 Tridiagonal2(m_aafMat,m_afDiag,m_afSubd);
00509 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00510 }
00511
00512 void MgcEigen::EigenStuff3 ()
00513 {
00514 Tridiagonal3(m_aafMat,m_afDiag,m_afSubd);
00515 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00516 }
00517
00518 void MgcEigen::EigenStuff4 ()
00519 {
00520 Tridiagonal4(m_aafMat,m_afDiag,m_afSubd);
00521 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00522 }
00523
00524 void MgcEigen::EigenStuffN ()
00525 {
00526 TridiagonalN(m_iSize,m_aafMat,m_afDiag,m_afSubd);
00527 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00528 }
00529
00530 void MgcEigen::EigenStuff ()
00531 {
00532 switch ( m_iSize )
00533 {
00534 case 2:
00535 Tridiagonal2(m_aafMat,m_afDiag,m_afSubd);
00536 break;
00537 case 3:
00538 Tridiagonal3(m_aafMat,m_afDiag,m_afSubd);
00539 break;
00540 case 4:
00541 Tridiagonal4(m_aafMat,m_afDiag,m_afSubd);
00542 break;
00543 default:
00544 TridiagonalN(m_iSize,m_aafMat,m_afDiag,m_afSubd);
00545 break;
00546 }
00547 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00548 }
00549
00550 void MgcEigen::DecrSortEigenStuff2 ()
00551 {
00552 Tridiagonal2(m_aafMat,m_afDiag,m_afSubd);
00553 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00554 DecreasingSort(m_iSize,m_afDiag,m_aafMat);
00555 }
00556
00557 void MgcEigen::DecrSortEigenStuff3 ()
00558 {
00559 Tridiagonal3(m_aafMat,m_afDiag,m_afSubd);
00560 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00561 DecreasingSort(m_iSize,m_afDiag,m_aafMat);
00562 }
00563
00564 void MgcEigen::DecrSortEigenStuff4 ()
00565 {
00566 Tridiagonal4(m_aafMat,m_afDiag,m_afSubd);
00567 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00568 DecreasingSort(m_iSize,m_afDiag,m_aafMat);
00569 }
00570
00571 void MgcEigen::DecrSortEigenStuffN ()
00572 {
00573 TridiagonalN(m_iSize,m_aafMat,m_afDiag,m_afSubd);
00574 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00575 DecreasingSort(m_iSize,m_afDiag,m_aafMat);
00576 }
00577
00578 void MgcEigen::DecrSortEigenStuff ()
00579 {
00580 switch ( m_iSize )
00581 {
00582 case 2:
00583 Tridiagonal2(m_aafMat,m_afDiag,m_afSubd);
00584 break;
00585 case 3:
00586 Tridiagonal3(m_aafMat,m_afDiag,m_afSubd);
00587 break;
00588 case 4:
00589 Tridiagonal4(m_aafMat,m_afDiag,m_afSubd);
00590 break;
00591 default:
00592 TridiagonalN(m_iSize,m_aafMat,m_afDiag,m_afSubd);
00593 break;
00594 }
00595 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00596 DecreasingSort(m_iSize,m_afDiag,m_aafMat);
00597 }
00598
00599 void MgcEigen::IncrSortEigenStuff2 ()
00600 {
00601 Tridiagonal2(m_aafMat,m_afDiag,m_afSubd);
00602 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00603 IncreasingSort(m_iSize,m_afDiag,m_aafMat);
00604 }
00605
00606 void MgcEigen::IncrSortEigenStuff3 ()
00607 {
00608 Tridiagonal3(m_aafMat,m_afDiag,m_afSubd);
00609 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00610 IncreasingSort(m_iSize,m_afDiag,m_aafMat);
00611 }
00612
00613 void MgcEigen::IncrSortEigenStuff4 ()
00614 {
00615 Tridiagonal4(m_aafMat,m_afDiag,m_afSubd);
00616 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00617 IncreasingSort(m_iSize,m_afDiag,m_aafMat);
00618 }
00619
00620 void MgcEigen::IncrSortEigenStuffN ()
00621 {
00622 TridiagonalN(m_iSize,m_aafMat,m_afDiag,m_afSubd);
00623 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00624 IncreasingSort(m_iSize,m_afDiag,m_aafMat);
00625 }
00626
00627 void MgcEigen::IncrSortEigenStuff ()
00628 {
00629 switch ( m_iSize )
00630 {
00631 case 2:
00632 Tridiagonal2(m_aafMat,m_afDiag,m_afSubd);
00633 break;
00634 case 3:
00635 Tridiagonal3(m_aafMat,m_afDiag,m_afSubd);
00636 break;
00637 case 4:
00638 Tridiagonal4(m_aafMat,m_afDiag,m_afSubd);
00639 break;
00640 default:
00641 TridiagonalN(m_iSize,m_aafMat,m_afDiag,m_afSubd);
00642 break;
00643 }
00644 QLAlgorithm(m_iSize,m_afDiag,m_afSubd,m_aafMat);
00645 IncreasingSort(m_iSize,m_afDiag,m_aafMat);
00646 }
00647
00648
00649 #ifdef EIGEN_TEST
00650
00651 int main ()
00652 {
00653 MgcEigen kES(3);
00654
00655 kES.Matrix(0,0) = 2.0; kES.Matrix(0,1) = 1.0; kES.Matrix(0,2) = 1.0;
00656 kES.Matrix(1,0) = 1.0; kES.Matrix(1,1) = 2.0; kES.Matrix(1,2) = 1.0;
00657 kES.Matrix(2,0) = 1.0; kES.Matrix(2,1) = 1.0; kES.Matrix(2,2) = 2.0;
00658
00659 kES.IncrSortEigenStuff3();
00660
00661 cout.setf(ios::fixed);
00662
00663 cout << "eigenvalues = " << endl;
00664 int iRow;
00665 for (iRow = 0; iRow < 3; iRow++)
00666 cout << kES.GetEigenvalue(iRow) << ' ';
00667 cout << endl;
00668
00669 cout << "eigenvectors = " << endl;
00670 for (iRow = 0; iRow < 3; iRow++)
00671 {
00672 for (int iCol = 0; iCol < 3; iCol++)
00673 cout << kES.GetEigenvector(iRow,iCol) << ' ';
00674 cout << endl;
00675 }
00676
00677
00678
00679
00680
00681
00682
00683
00684 return 0;
00685 }
00686
00687 #endif