TAPs 0.7.7.3
SP_MatrixOperations.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 SP_MatrixOperations.cpp
00003 
00004 Operation on Matrix
00005 
00006 SUKITTI PUNAK   (07/14/2007)
00007 UPDATE          (07/14/2007)
00008 ******************************************************************************/
00009 #include "SP_MatrixOperations.h"
00010 // Using Inclusion Model (i.e. definitions are included in declarations)
00011 //                       (this name.cpp is included in name.hpp)
00012 // Each friend is defined directly inside its declaration.
00013 //-----------------------------------------------------------------------------
00014 // Member Fn:   HouseHolderMatrix()     ---------------------------------------
00015 // Desc:    Find a HouseHolder matrix of a real square matrix only.
00016 SPtMatrix< double > MatrixOperations::HouseHolderMatrix( const SPtMatrix< double > &A,  // I/P
00017                                                          SPtMatrix< double > *ptrH,     // O/P
00018                                                          SPtMatrix< double > *ptrR )    // O/P
00019 {
00020     // only for square matrix
00021     if ( A.m_iRows != A.m_iCols )   return NULL;
00022     if ( ptrR != NULL ) {
00023         if ( ptrR->m_iRows != A.m_iRows || ptrR->m_iCols != A.m_iCols ) return false;
00024     }
00025 
00026     SPtMatrix< double > B( A );
00027     SPtMatrix< double > H( A );
00028 
00029     int i, k;
00030     double g, s;
00031     int n = H.m_iRows;
00032     SPtMatrix< double > W( n, 1 );
00033     //SPtMatrix< double > V( n, 1 );
00034     SPtMatrix< double > U( n, 1 );
00035     
00036     // Create Identity matrix
00037     SPtMatrix< double > I( n, n );
00038     I.SetToIdentity();
00039     
00040 
00041     for ( k = 0; k < n-1; k++ ) {
00042         //cout << "\nk = " << k << "\n";
00043 
00044         // Step 1: Set W_i = 0 for i = 0, ... , k-2
00045         for ( i = 0; i < k; i++ ) {
00046             W.m_tElement[i][0] = 0.0;
00047         }
00048 
00049         // Step 2.1: Find g
00050         g = 0;
00051         for ( i = k; i < n; i++ ) {
00052             g += B.m_tElement[i][k] * B.m_tElement[i][k];
00053         }
00054         g = sqrt(g);
00055 
00056         // Step 2.2: Find s
00057         s = sqrt( 2 * g * ( g + fabs(B.m_tElement[k][k]) ) );
00058 
00059         // Step 3.1: Set W_k
00060         W.m_tElement[k][0] = ( B.m_tElement[k][k] + (B.m_tElement[k][k] >= 0.0 ? +1.0 : -1.0)*g ) / s;
00061 
00062         // Step 3.2: Set W_i
00063         for ( i = k+1; i < n; i++ ) {
00064             W.m_tElement[i][0] = B.m_tElement[i][k] / s;
00065         }
00066 
00067         //cout << "W" << endl;
00068         //W.DisplayElements();
00069 
00070         U = 2 * B.GetTranspose() * W;
00071 
00072         //cout << "W*U'" << endl;
00073         //(W*U.GetTranspose()).DisplayElements();
00074 
00075         //H -= W*U.GetTranspose();
00076 
00077         H = I - ( 2 * W * W.GetTranspose() );
00078         if ( ptrH != NULL )     ptrH[k] = H;
00079 
00080         B = H*B;
00081     }
00082 
00083     if ( ptrR != NULL )     *ptrR = B;
00084 
00085     return H;
00086 } // END Member Fn: HouseHolderMatrix()
00087 //-----------------------------------------------------------------------------
00088 // Member Fn:   QRFactorization()       ---------------------------------------
00089 // Desc:    Find a QR Factorization of a real square matrix only.
00090 bool MatrixOperations::QRFactorization( const SPtMatrix< double > &A,                       // I/P
00091                                         SPtMatrix< double > &Q, SPtMatrix< double > &R )    // O/P
00092 {
00093     // only square matrix
00094     if ( A.m_iRows != A.m_iCols )   return false;
00095     if ( Q.m_iRows != A.m_iRows || Q.m_iCols != A.m_iCols ) return false;
00096     if ( R.m_iRows != A.m_iRows || R.m_iCols != A.m_iCols ) return false;
00097 
00098     int n = A.m_iRows;
00099     int k;
00100 
00101     // Define R_(0) = A
00102     //R = A;
00103     SPtMatrix< double > *arrayH = new SPtMatrix< double >[ n-1 ];
00104 
00105     // For k = 1,...,n-1
00106     for ( k = 0; k < n-1; k++ ) {
00107         // Find H_(k) in order to reduce positions k+1,...,n, 
00108         // in the k_th column of R_(k-1) to zero
00109         HouseHolderMatrix( A, arrayH, &R );
00110         //R = ptrH[n-2] * R;
00111     }
00112 
00113     // Define Q = I;
00114     // For k = n-1,...,1
00115     //    Q = H_(k) * Q
00116     Q.SetToIdentity();
00117     for ( k = n-2; k >= 0; k-- ) {
00118         Q = arrayH[k]*Q;
00119     }
00120 
00121     //cout << "R is\n";
00122     //R.DisplayElements();
00123     //cout << "Q is\n";
00124     //Q.DisplayElements();
00125     //cout << "Q'*Q is ";
00126     //(Q.GetTranspose()*Q).DisplayElements();
00127     //cout << "Q*R is\n";
00128     //(Q*R).DisplayElements();
00129 
00130     delete [] arrayH;
00131 
00132     return true;
00133 } // END Member Fn: QRFactorization()
00134 //-----------------------------------------------------------------------------
00135 // Member Fn:   EigenValsByQRFactorization()        ---------------------------
00136 // Desc:    Find all eigen values of a real square matrix only.
00137 // I/P:  A is a real square matrix.
00138 // I/P:  (default = 6), times is the number of iterations.
00139 // O/P:  (default = NULL), ptrO is a pointer to a matrix with will be the same 
00140 //       order as I/P Matrix, A.  Its diagonal are the approximated eigen values.
00141 // Return:  A column vector (n-by-1 matrix) contains all approximated eigenvalues.
00142 SPtMatrix< double > MatrixOperations::EigenValsByQRFactorization( const SPtMatrix< double > &A, // I/P
00143                                                    int times,                       // Number of iterations
00144                                                    SPtMatrix< double > *ptrO )      // O/P
00145 {
00146     // only square matrix
00147     if ( A.m_iRows != A.m_iCols )   return NULL;
00148 
00149     // Given a real n-by-n matrix A:
00150     // Define A_(1) = A
00151     // For k = 1 to times
00152     //      Factor A_(k)   =  Q_(k)R_(k)        (so that Q_(k)'A_(k) = R_(k))
00153     //      Define A_(k+1) =  R_(k)Q_(k)        (so that A_(k+1) = Q_(k)'A_(k)Q_(k))
00154     // end.
00155     double errThreshold = 1.0;
00156     int limit = 10000;
00157     int n = A.m_iRows;
00158     SPtMatrix< double > M( A ), Q( n, n ), R( n, n );
00159     if ( times < 0 ) {
00160         errThreshold = pow( 10.0, times );
00161         times = limit;
00162     }
00163 
00164     for ( int k = 0; k < times; k++ ) {
00165         //cout << k << " ";
00166         
00167         //M.DisplayElements();
00168         
00169         QRFactorization( M, Q, R );
00170         
00171         //cout << "R is \n";
00172         //R.DisplayElements();
00173         //cout << "Q is \n";
00174         //Q.DisplayElements();
00175 
00176         M = R*Q;
00177     
00178         if ( 1.0 > errThreshold ) {
00179             bool isEnough = true;
00180             for ( int r = n/2; r < n; r++ ) {
00181                 for ( int c = 0; c <= n/2; c++ ) {
00182                     if ( r > c ) {
00183                         //cout << "(" << r << ", " << c << ") ";
00184                         if ( fabs(M.m_tElement[r][c]) > errThreshold ) {
00185                             isEnough = false;
00186                             break;
00187                         }
00188                     }
00189                 }
00190             }
00191             if ( isEnough ) {
00192                 cout << "Stopped at Iteration# " << k << "\n";
00193                 break;
00194             }
00195         }
00196     }
00197     //cout << "M_(" << k << ")\n";
00198     //M.DisplayElements();
00199 
00200     if ( ptrO != NULL ) *ptrO = M;
00201 
00202     SPtMatrix< double > outMatrix( n, 1 );
00203     for ( int i = 0; i < n; i++ ) {
00204         outMatrix.m_tElement[i][0] = M.m_tElement[i][i];
00205     }
00206 
00207     return M;
00208     //return outMatrix;
00209 } // END Member Fn: EigenValsByQRFactorization()
00210 //-----------------------------------------------------------------------------
00211 //34567890123456789012345678901234567890123456789012345678901234567890123456789
00212 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines