basic/geometry/geo_rangesensor/MgcEigen.cpp

Go to the documentation of this file.
00001 // Magic Software, Inc.
00002 // http://www.magic-software.com
00003 // Copyright (c) 2000, All Rights Reserved
00004 //
00005 // Source code from Magic Software is supplied under the terms of a license
00006 // agreement and may not be copied or disclosed except in accordance with the
00007 // terms of that agreement.  The various license agreements may be found at
00008 // the Magic Software web site.  This file is subject to the license
00009 //
00010 // FREE SOURCE CODE
00011 // http://www.magic-software.com/License.html/free.pdf
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     // matrix is already tridiagonal
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     // save matrix M
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         // build column Q1
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         // compute S*Q1
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         // build column Q3 = Q1x(S*Q1)
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             // build column Q2 = Q3xQ1
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             // S*Q1 parallel to Q1, choose any valid Q2 and Q3
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                 // Q1 = (+-1,0,0)
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     // re-ordering if MgcEigen::QLAlgorithm is used subsequently
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     // sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1]
00429     for (int i0 = 0, i1; i0 <= iSize-2; i0++)
00430     {
00431         // locate maximum eigenvalue
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             // swap eigenvalues
00447             afEigval[i1] = afEigval[i0];
00448             afEigval[i0] = fMax;
00449 
00450             // swap eigenvectors
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     // sort eigenvalues in increasing order, e[0] <= ... <= e[iSize-1]
00465     for (int i0 = 0, i1; i0 <= iSize-2; i0++)
00466     {
00467         // locate minimum eigenvalue
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             // swap eigenvalues
00483             afEigval[i1] = afEigval[i0];
00484             afEigval[i0] = fMin;
00485 
00486             // swap eigenvectors
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     // eigenvalues =
00678     //    1.000000 1.000000 4.000000
00679     // eigenvectors =
00680     //    0.411953  0.704955 0.577350
00681     //    0.404533 -0.709239 0.577350
00682     //   -0.816485  0.004284 0.577350
00683 
00684     return 0;
00685 }
00686 
00687 #endif

Generated on Sat Apr 1 21:30:31 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO