Matrix.h

Go to the documentation of this file.
00001 /**
00002 \file     Matrix.h
00003 \brief    The Zenautics Matrix Class
00004 \author   Glenn D. MacGougan (GDM)
00005 \date     2007-12-21
00006 \version  1.11
00007 
00008 \b LICENSE \b INFORMATION \n
00009 Copyright (c) 2007, Glenn D. MacGougan, Zenautics Technologies Inc. \n
00010 
00011 Redistribution pertains only to the following files and their contents. \n
00012 - Matrix.h\n
00013 - Matrix.cpp\n
00014 - cmatrix.h\n
00015 - cmatrix_basic.lib (for windows), cmatrix_basic_lib.a (for linux)\n
00016 
00017 Redistribution and use in source and binary forms, with or without
00018 modification, of the specified files is permitted provided the following 
00019 conditions are met: \n
00020 
00021 - Redistributions of source code must retain the above copyright
00022   notice, this list of conditions and the following disclaimer. \n
00023 - Redistributions in binary form must reproduce the above copyright
00024   notice, this list of conditions and the following disclaimer in the
00025   documentation and/or other materials provided with the distribution. \n
00026 - The name(s) of the contributor(s) may not be used to endorse or promote 
00027   products derived from this software without specific prior written 
00028   permission. \n
00029 
00030 THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00031 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
00032 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00033 DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00034 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00035 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00036 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00037 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00038 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00039 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00040 SUCH DAMAGE.
00041 
00042 \b NOTES: \n
00043 This code was developed using rigourous unit testing for every function 
00044 and operation. Despite any rigorous development process, bugs are
00045 inevitable. Please report bugs and suggested fixes to glenn@zenautics.com.\n
00046 */
00047 
00048 #ifndef _ZENAUTICS_MATRIX_H_
00049 #define _ZENAUTICS_MATRIX_H_
00050 
00051 #include <stdio.h>
00052 #include <complex> // This is needed for the Standard Template Library complex<double> type.
00053 #include <string>
00054 #include "cmatrix.h" // The core matrix engine is written in 'c'.
00055 
00056 namespace Zenautics
00057 {
00058 
00059 #define MATRIX_USE_EXCEPTION_HANDLING
00060 #ifdef MATRIX_USE_EXCEPTION_HANDLING
00061 
00062   /**
00063   \class   MatrixException
00064   \brief   A class for exceptions thrown by the Matrix class.  
00065   
00066   The MATRIX_USE_EXCEPTION_HANDLING define enables the use of exception 
00067   handling using try{} catch{}. A MatrixException is thrown. The use of 
00068   exception handling is very highly recommended. When it is turned off, 
00069   the matrix will try to output a message and then call 'exit(1)'.
00070   
00071   \code
00072   int main()
00073   { 
00074     try
00075     {
00076       Matrix A(2,2);
00077       double d = A(3,1).real(); // causes an out of bounds exception
00078     }
00079     catch( MatrixException& matrix_exception )
00080     {
00081       cout << matrix_exception << endl;
00082     }
00083     catch ( ... )
00084     {
00085       cout << "Caught unknown exception" << endl;
00086     }
00087     return 0;
00088   }
00089   \endcode
00090   */
00091   class MatrixException
00092   {  
00093   public: 
00094     /// \brief  The constructor.
00095     MatrixException( const char* msg );
00096 
00097     /// \brief  The copy constructor.
00098     MatrixException(const MatrixException& matrix_exception);
00099 
00100     /// \brief  The destuctor.
00101     virtual ~MatrixException() { /* nothing needed yet */ };
00102 
00103     /// \brief  Return a copy of the exception message.
00104     std::string GetExceptionMessage();
00105 
00106     /// \brief  Overload the casting operator to a string.
00107     operator const char*();
00108 
00109   public:
00110     /// \brief  The matrix exception string.  
00111     std::string m_ExceptionString;
00112 
00113   private:
00114     /// \brief  The matrix exception character string.  
00115     char m_msg[256];    
00116   };
00117 
00118 #endif
00119 
00120 
00121   /**
00122   \class   Matrix
00123   \brief   The matrix/vector class. 
00124            Both real and complex data are inherently supported.
00125            One and two dimensional data.
00126   
00127   The matrix class supports advanced real and complex functionality. It is
00128   optimized for columnwise operations. Refer to example_main.cpp for a 
00129   complete example program using the Matrix.
00130   */
00131   class Matrix
00132   {  
00133   public: // Constructors / Destructor
00134 
00135     /// \brief  This function enables or disables a global flag
00136     ///         that forces single element matrices to be treated
00137     ///         as scalars. This is enabled by default. 
00138     static void Treat1x1MatricesAsScalar( bool enable = true );
00139 
00140     /// \brief  The default constructor (no data allocated yet).
00141     Matrix();                                             
00142 
00143     /// \brief  A vector style constructor.
00144     ///
00145     /// Matrix A(nrows);  creates an nrowsx1 real 'vector'.
00146     /// A complex vector must be created using Matrix A(nrows,ncols,false);
00147     Matrix(const unsigned nrows);
00148 
00149     /// \brief  A matrix style constructor.
00150     ///
00151     /// Matrix A(nrows,ncols); creates an nrowsxncols real 'matrix'. A real matrix is assumed.
00152     /// Matrix A(nrows,ncols,false); creates an nrowsxncols complex 'matrix'. A real matrix is assumed.
00153     Matrix(const unsigned nrows, const unsigned ncols, const bool isReal=true);
00154 
00155     /// \brief  The copy constructor.
00156     Matrix(const Matrix& mat);                          
00157 
00158     /// \brief  A constructor reading data from a file.
00159     Matrix(const char* path, bool& itWorked);
00160 
00161     /// \brief  The constructor as a copy from a static matrix.
00162     Matrix(const double mat[], const unsigned nrows, const unsigned ncols=1 ); 
00163 
00164     /// \brief  The destructor.
00165     virtual ~Matrix();
00166 
00167     /// \brief  The assignment operator from another matrix.
00168     ///
00169     /// e.g. Matrix B; Matrix A; B = "[1 2 3; 4 5 6]"; A = B; // A == [1 2 3; 4 5 6], A is (2x3)
00170     Matrix& operator=(const Matrix& mat);
00171 
00172     /// \brief  The assignment operator from a scalar double value.
00173     ///
00174     /// e.g. Matrix A; A = 2.0; // A is (1x1).
00175     Matrix& operator=(const double value);
00176 
00177     
00178     /// \brief  The assignment operator from a std::complex<double> value.
00179     ///
00180     /// e.g. Matrix A; A = 2.0; // A is (1x1).
00181     Matrix& operator=(const std::complex<double> value);
00182 
00183     /**
00184     \brief  The assignement operator from a string matrix.   
00185     
00186     There are two general possible interpretations of the string input. \n
00187     
00188     (1) Square bracket delimited matrix. e.g. \n
00189     
00190     \code
00191     Matrix A;
00192     A = "[1 2 3; 4 5 6]"; // or 
00193     A = "[1, 2, 3; 4, 5, 6]";
00194     \endcode
00195 
00196     In this case '[' donates the start of a matrix and ']' denotes the end. \n
00197     Row vectors [1 2 3] and [4 5 6] are separated by ';'.  \n
00198     Commas can delimit row vector data but are not needed. \n
00199     Complex input: e.g. 
00200     
00201     \code
00202     Matrix A;
00203     A = "[1+1i 2+3j 1-2i; 4 5 6]"; // or
00204     A = "[1+1i, 2+3j, 1-2i; 4, 5, 6]";
00205     \endcode
00206     
00207     (2) Free form delimited matrix. e.g. \n
00208 
00209     \code
00210     Matrix A; 
00211     A = "1 2 3 \\n 4 5 6 \\n";
00212     \endcode
00213 
00214     In this case, the newline delimits different rows of the matrix. (\\r\\n also works). \n
00215     Row vectors can still be delimited by ';' as well. \n
00216     
00217     \code
00218     B = "1 2 3; 4 5 6; \\n 7 8 9";
00219     \endcode 
00220     
00221     will set a 3x3 matrix == [1 2 3; 4 5 6; 7 8 9]. \n
00222 
00223     Commas can delimit row vector data but are not needed. \n
00224     Complex input: e.g. 
00225     
00226     \code
00227     Matrix A;
00228     A = "[1+1i 2+3j 1-2i\\n 4 5 6]";   // or
00229     A = "1+1i, 2+3j, 1-2i\\n 4, 5, 6"; // or
00230     A = "1+1i 2+3j 1-2i; 4, 5, 6";   
00231     \endcode 
00232 
00233     All result in A = [1+1i 2+3i 1-2i; 4 5 6]; \n
00234     */
00235     Matrix& operator=(const char* strMatrix);
00236 
00237   public:
00238 
00239     /**
00240     \brief  Clear the matrix memory. Set the matrix to size 0x0.
00241     
00242     \code 
00243     Matrix A(10,10); // A 10 x 10 matrix
00244     if( !A.Clear() )
00245       return false;
00246     // A is now 0x0 
00247     \endcode
00248 
00249     \return true if successul, false if error.
00250     */
00251     bool Clear();
00252 
00253   public: // Matrix Qualifiers
00254 
00255     /// \brief  Is this matrix empty?
00256     bool isEmpty() const;
00257 
00258     /// \brief  Is the matrix mat conformal for multiplication (*this * mat)?
00259     bool isConformal(const Matrix& mat) const;
00260 
00261     /// \brief  Is this matrix the same size as mat?
00262     bool isSameSize(const Matrix& mat) const;  
00263 
00264     /// \brief  Is this a square matrix?
00265     bool isSquare() const;
00266 
00267     /// Check if this matrix is stored as a complex matrix.
00268     bool isStoredAsComplex();
00269 
00270     /// Check if this a real matrix.
00271     bool isReal();
00272 
00273     /// Check if this a complex matrix.
00274     bool isComplex(); 
00275 
00276     /// Check if this is a vector. Is the matrix either nx1 or 1xn.
00277     bool isVector();
00278 
00279     unsigned GetNrCols() const;   //!< return no. of cols
00280     unsigned ncols() const;       //!< return no. of cols
00281     unsigned GetNrElems() const;  //!< return total no. of elements
00282     unsigned nelems() const;      //!< return total no. of elements
00283     unsigned GetNrRows() const;   //!< return no. of rows         
00284     unsigned nrows() const;       //!< return no. of rows         
00285     unsigned GetLength() const;   //!< return the maximum dimension either nrows or ncols whichever is greater.
00286 
00287 
00288     /**
00289     \brief  Return the real part of the matrix at this row and column.
00290 
00291     \code 
00292     Matrix A = "2+4i";
00293     double a = A.real(0,0); // a is 2.0
00294     \endcode
00295     */
00296     double real(const unsigned row, const unsigned col);
00297 
00298     /**
00299     \brief  Return the real part of the matrix at this vector index.
00300 
00301     \code 
00302     Matrix A = "[2+4i, 10-1i]";
00303     double a = A.real(1); // a is 10.0
00304     \endcode
00305     */
00306     double real(const unsigned index);
00307 
00308     /**
00309     \brief  Return the imaginary part of the matrix at this row and column.
00310 
00311     \code 
00312     Matrix B = "2+4i";
00313     double b = B.imag(0); // b is 4.0
00314     \endcode
00315     */    
00316     double imag(const unsigned row, const unsigned col);
00317 
00318     /**
00319     \brief  Return the imaginary part of the matrix at this vector index.
00320     
00321     \code 
00322     Matrix B = "[2+4i, 1-10i]";
00323     double b = B.imag(1); // b is -10.0
00324     \endcode
00325     */    
00326     double imag(const unsigned index);
00327 
00328 
00329   public: // Input Operations
00330 
00331     /**
00332     \brief  Read the matrix from an ASCII file with the path given by the 'c' style string
00333     (with automatric support for many delimiters, whitespace, or ',', or ';', or many others) 
00334     or a compressed BINARY matrix file used in the Save function.
00335     Complex and real data input are supported.
00336     A non-numeric header line can be present which will be skipped.
00337 
00338     \code
00339     Matrix A;
00340     Matrix B;
00341     Matrix C;
00342     bool result;
00343 
00344     result = A.ReadFromFile("data.txt"); // Read an ASCII numeric data file.
00345     result = B.ReadFromFile("data.csv"); // Read a comma delimited numeric data file. e.g. saved from EXCEL.
00346     result = C.ReadFromFile("data.mtx"); // Read a compressed binary matrix (MTX format).
00347     \endcode
00348     
00349     \return true if successful, false otherwise
00350     */
00351     bool ReadFromFile( const char *path );
00352     
00353     /**
00354     \brief  Read the matrix from a file given the file path as a standard string.
00355     
00356     \code
00357     Matrix A;
00358     std::string str = "data.txt";
00359     if( !A.ReadFromFile(str) )
00360       return false;
00361     \endcode
00362 
00363     \return true if successful, false otherwise.
00364     */
00365     bool ReadFromFile( std::string path );
00366 
00367 
00368     /**  
00369     \brief  A safe function for performing a copy of another matrix.
00370     
00371     \code
00372     Matrix A(2,2);
00373     A[0][0] = 1.0;
00374     A[0][1] = 2.0;
00375     A[1][0] = 3.0;
00376     A[1][1] = 4.0;
00377     Matrix B;
00378     if( !B.Copy(A) )
00379       return false;
00380     \endcode
00381     
00382     \return true if successful, false otherwise
00383     */
00384     bool Copy( Matrix& src );
00385 
00386 
00387     /**      
00388     \brief  A safe function for setting the matrix from a double.
00389     
00390     \code
00391     double d = 10.0;
00392     Matrix A;
00393     if( !A.Copy(d) )
00394       return false;
00395     \endcode
00396     
00397     \return true if successful, false otherwise
00398     */
00399     bool Copy( const double& value );
00400 
00401 
00402     /**      
00403     \brief  A safe function for setting the matrix from a std::complex<double>.
00404     
00405     \code
00406     std::complex<double> cplx(1.0,2.0);
00407     Matrix A;
00408     if( !A.Copy(cplx) )
00409       return false;
00410     \endcode
00411     
00412     \return true if successful, false otherwise
00413     */
00414     bool Copy( const std::complex<double>& cplx );
00415 
00416 
00417   public: // Output Operations
00418 
00419     /**
00420     \brief  Saves a matrix to the specified file path (a 'c' style string)
00421             using a proprietary compressed format.
00422             ADVANCED EDITION ONLY. BASIC EDITION will return false.
00423     \code
00424     Matrix A;
00425     A = "[1,2,3; 4,5,6; 7,8,9]";
00426     if( !A.Save("data.mtx" ) )
00427       return false;
00428     \endcode 
00429 
00430     \return true if successful, false otherwise
00431     */
00432     bool Save( const char* path );
00433 
00434     /**
00435     \brief  Saves a matrix to the specified file path (a std::string)
00436             using a proprietary compressed format.
00437             ADVANCED EDITION ONLY. BASIC EDITION will return false.
00438             
00439     \code
00440     Matrix A;
00441     std::string str = "data.mtx";
00442     A = "[1,2,3; 4,5,6; 7,8,9]";
00443     if( !A.Save(str) )
00444       return false;
00445     \endcode 
00446 
00447     \return true if successful, false otherwise
00448     */
00449     bool Save( std::string path );
00450     
00451     /**
00452     \brief  Print the matrix to a file with automatically determined column width 
00453             and the specified precision, uses "%'blank''-'autowidth.precision'g'", to 
00454             the 'c' style path string provided.
00455     \code
00456     A = "[1,2,3; 4,5,6; 7,8,9]";
00457     if( !A.Print( "data.txt", 14 ) ) // Print the matrix to data.txt
00458       return false;
00459     \endcode   
00460 
00461     \return true if successful, false otherwise
00462     */
00463     bool Print( const char *path, const unsigned precision, bool append = false );
00464 
00465     /**
00466     \brief  Print the matrix to a file with automatically determined column width 
00467             and the specified precision, uses "%'blank''-'autowidth.precision'g'", to 
00468             the std:string path provided.
00469     \code
00470     A = "[1,2,3; 4,5,6; 7,8,9]";
00471     std::string str = "data.txt";
00472     if( !A.Print( str, 14 ) ) // Print the matrix to data.txt
00473       return false;
00474     \endcode   
00475 
00476     \return true if successful, false otherwise
00477     */
00478     bool Print( std::string path, const unsigned precision, bool append = false );
00479 
00480     /**
00481     \brief  Print the matrix to the standard output (stdout) with automatically 
00482             determined column width and the specified precision, 
00483             uses "%'blank''-'autowidth.precision'g'".
00484     \code
00485     Matrix A;
00486     A = "[1.123 0 2.123 -1; 3.123 0 4.123 -1]";  // Set A using string notation.
00487     bool result = A.PrintStdout(6); // Print to stdout with automatic width determination.
00488     // results in:
00489     // 0123456789012345678901234567890
00490     //  1.123  0  2.123 -1
00491     //  3.123  0  4.123 -1
00492     \endcode
00493         
00494     \return true if successful, false otherwise
00495     */
00496     bool PrintStdout( const unsigned precision = 6 );
00497 
00498     /**
00499     \brief  Print the matrix to a buffer of maxlength with automatically determined column width 
00500     and the specified precision, uses "%'blank''-'autowidth.precision'g'"
00501 
00502     \code
00503     Matrix A;
00504     A = "[1.123 0 2.123 -1; 3.123 0 4.123 -1]";  // Set A using string notation.
00505     char buffer[256]; 
00506     bool result = A.PrintToBuffer( buffer, 256, 6); // Print to a buffer with automatic width determination.
00507     cout << buffer << endl;
00508     // results in:
00509     // 0123456789012345678901234567890
00510     //  1.123  0  2.123 -1
00511     //  3.123  0  4.123 -1
00512     \endcode
00513      
00514     \return true if successful, false otherwise
00515     */
00516     bool PrintToBuffer( char* buffer, const unsigned maxlength, const unsigned precision );
00517 
00518 
00519     /**
00520     \brief  Print the matrix to a file with specifed width and precision
00521             PrintAutoWidth is recommended over this function, "%'blank''-'width.precision'g'"
00522             to file specified with the 'c' style path string provided.
00523     \code
00524     Matrix A;
00525     A = "[1.123 0 2.123 -1; 3.123 0 4.123 -1]";  // Set A using string notation.
00526     if( !A.PrintFixedWidth( "data.txt", 6, 3 ) )
00527       return false;
00528     // results in: data.txt with
00529     // 0123456789012345678901234567890
00530     //  1.123     0 2.123    -1
00531     //  3.123     0 4.123    -1
00532     \endcode
00533 
00534     \return true if successful, false otherwise
00535     */
00536     bool PrintFixedWidth( const char* path, const unsigned width, const unsigned precision, bool append = false );
00537 
00538 
00539     /**
00540     \brief  Print the matrix to a file with specifed width and precision
00541             PrintAutoWidth is recommended over this function, "%'blank''-'width.precision'g'"
00542             to file specified with the std::string path string provided.
00543     \code
00544     Matrix A;
00545     A = "[1.123 0 2.123 -1; 3.123 0 4.123 -1]";  // Set A using string notation.
00546     std::string str = "data.txt";
00547     if( !A.PrintFixedWidth( str, 6, 3 ) )
00548       return false;
00549     // results in: data.txt with
00550     // 0123456789012345678901234567890
00551     //  1.123     0 2.123    -1
00552     //  3.123     0 4.123    -1
00553     \endcode
00554 
00555     \return true if successful, false otherwise
00556     */   
00557     bool PrintFixedWidth( std::string path, const unsigned width, const unsigned precision, bool append = false );
00558 
00559     /**
00560     \brief  Print the matrix to a buffer of maxlength with specifed width and precision
00561             PrintAutoWidth is recommended over this function, "%'blank''-'width.precision'g'"
00562     \code
00563     Matrix A;
00564     A = "[1.123 2.123 -1; 3.123 4.123 -1]";  // Set A using string notation.
00565     char buffer[256]; 
00566     bool result = A.PrintFixedWidthToBuffer( buffer, 256, 10, 6 ); // Print to a buffer with fixed width.
00567     cout << buffer << endl;
00568     // results in:
00569     // 0123456789012345678901234567890    
00570     //  1.123     2.123    -1
00571     //  3.123     4.123    -1
00572     \endcode
00573       
00574     \return true if successful, false otherwise
00575     */
00576     bool PrintFixedWidthToBuffer( char* buffer, const unsigned maxlength, const unsigned width, const unsigned precision );
00577 
00578     /**
00579     \brief  Print the matrix to a file path specified by the 'c' style string 
00580             with specifed precision and delimiter.
00581     \code
00582     Matrix A;
00583     A = "[1.123 2.123 -1; 3.123 4.123 -1]";  // Set A using string notation.
00584     if( !A.PrintDelimited( "data.csv", 5, ',' ) )
00585       return false;
00586     // results in: data.csv with
00587     // 0123456789012345678901234567890    
00588     // 1.123,2.123,-1
00589     // 3.123,4.123,-1
00590     \endcode
00591 
00592     \return true if successful, false otherwise
00593     */
00594     bool PrintDelimited( const char *path, const unsigned precision, const char delimiter, bool append = false );
00595 
00596     /**
00597     \brief  Print the matrix to a file path specified by the std::string 
00598             with specifed precision and delimiter.
00599     \code
00600     Matrix A;
00601     A = "[1.123 2.123 -1; 3.123 4.123 -1]";  // Set A using string notation.
00602     std::string str = "data.csv";
00603     if( !A.PrintDelimited( str, 5, ',' ) )
00604       return false;
00605     // results in: data.csv with
00606     // 0123456789012345678901234567890    
00607     // 1.123,2.123,-1
00608     // 3.123,4.123,-1
00609     \endcode
00610 
00611     \return true if successful, false otherwise
00612     */
00613     bool PrintDelimited( std::string path, const unsigned precision, const char delimiter, bool append = false );
00614     
00615     /**
00616     \brief  Print the matrix to a 'c' style string buffer of maxlength with specifed precision and delimiter.
00617     
00618     \code
00619     Matrix A;
00620     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00621     char buffer[256]; 
00622     if( !A.PrintDelimitedToBuffer( buffer, 256, 6, ',' ) ) // Print to a buffer using comma delimiters.
00623       return false;
00624     cout << buffer << endl;
00625     // results in:
00626     // 1.123,2.123
00627     // 3.123,4.123
00628     \endcode
00629       
00630     \return true if successful, false otherwise
00631     */
00632     bool PrintDelimitedToBuffer( char *buffer, const unsigned maxlength, const unsigned precision, const char delimiter );
00633 
00634     /**
00635     \brief  Print a row to a 'c' style string buffer.
00636     
00637     \code
00638     Matrix A;
00639     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00640     char buffer[256]; 
00641     if( !A.PrintRowToString( 1, buffer, 256, 4, 6 ) ) // Print the second row to the char buffer.
00642       return false;
00643     cout << buffer << endl;
00644     // results in:
00645     // 3.123   4.123
00646     \endcode
00647     
00648     \return true if successful, false otherwise
00649     */
00650     bool PrintRowToString( const unsigned row, char *buffer, const unsigned maxlength, const int width, const int precision );
00651 
00652 
00653   public: // Change the dimensions of the matrix
00654 
00655     /**  
00656     \brief  Remove a single column from the matrix.
00657 
00658     \code
00659     Matrix A;
00660     A = "[1.123 0 2.123; 3.123 0 4.123]";  // Set A using string notation.
00661     if( !A.RemoveColumn(1) ) // Remove the column with the zeros
00662       return false;
00663     // results in 
00664     // A
00665     // 1.123 2.123
00666     // 3.123 4.123
00667     \endcode
00668         
00669     \return true if successful, false otherwise.  
00670     */
00671     bool RemoveColumn( const unsigned col );
00672 
00673     /**
00674     \brief  Remove all the columns 'after' the column index given.
00675 
00676     \code
00677     Matrix A;
00678     A = "[1.123 0 2.123; 3.123 0 4.123]";  // Set A using string notation.
00679     if( !A.RemoveColumnsAfterIndex(0) ) // Remove the 2nd and 3rd columns, i.e. after the 0th column.
00680       return false;
00681     // results in 
00682     // A
00683     // 1.123
00684     // 3.123
00685     \endcode
00686     
00687     \return true if successful, false otherwise.  
00688     */
00689     bool RemoveColumnsAfterIndex( const unsigned col );
00690 
00691     /** 
00692     \brief  Remove the rows and columns specified by the indices in the rows[] and cols[] arrays.
00693     
00694     \code
00695     Matrix A(4,4);
00696     unsigned rows[2];
00697     unsigned cols[2];
00698     rows[0] = 0; // remove row 0
00699     rows[1] = 2; // remove row 2
00700     cols[0] = 0; // remove column 0
00701     cols[1] = 2; // romve column 2
00702     A.RemoveRowsAndColumns( 2, (unsigned int *)rows, 2, (unsigned int *)cols );
00703     // A is now a 2x2 matrix
00704     \endcode
00705     
00706     \return true if successful, false otherwise.  
00707     */
00708     bool RemoveRowsAndColumns( const unsigned nrows, const unsigned rows[], const unsigned ncols, const unsigned cols[] );
00709 
00710     /**
00711     \brief  Insert a column matrix into the matrix.
00712     
00713     \code
00714     Matrix A;
00715     Matrix B(2,2);
00716     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00717     if( !A.InsertColumn( B, 1, 1 ) ) // Insert second column of B into the second column a A.
00718       return false;
00719     // results in:
00720     // A (2x3)
00721     // 1.123  0   2.123
00722     // 3.123  0   4.123
00723     \endcode
00724     
00725     \return true if successful, false otherwise.  
00726     */
00727     bool InsertColumn( const Matrix &src, const unsigned dst_col, const unsigned src_col );
00728 
00729     /** 
00730     \brief  Add a column to the end of the matrix.
00731 
00732     \code
00733     Matrix A;
00734     atrix B(2,2);
00735     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00736     if( !A.AddColumn( B, 1 ) ) // Add second column of B to A.
00737       return false;
00738     // results in:
00739     // A (2x3)
00740     // 1.123  2.123 0
00741     // 3.123  4.123 0
00742     \endcode
00743     
00744     \return true if successful, false otherwise.  
00745     */
00746     bool AddColumn( const Matrix &src, const unsigned src_col );
00747 
00748     /**
00749     \brief  Combine two matrices with the same nrows, A becomes A|B.
00750 
00751     \code
00752     Matrix A;
00753     atrix B(2,2);
00754     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00755     if( !A.Concatonate( B ) ) // make A = A | B
00756       return false;
00757     // results in:
00758     // A (2x4)
00759     // 1.123  2.123 0 0
00760     // 3.123  4.123 0 0
00761     \endcode
00762 
00763     \return true if successful, false otherwise.  
00764     */
00765     bool Concatonate( const Matrix &src );
00766 
00767     /**
00768     \brief  Redimension the matrix, original data is saved in place, new 
00769             data is set to zero. The default value for ncols allows 
00770             redimensioning as a vector.
00771     \code
00772     Matrix A(4,4);       // A is 4x4
00773     A[0][0] = 1;
00774     A[1][1] = -1;
00775     if( !A.Redim(2,2) )  // A is 2x2 but data values are retained.
00776       return false;
00777     // results in:
00778     // A (2x2)
00779     // 1  0
00780     // 0 -1
00781 
00782     Matrix B(10);     // B is a vector with length 10.
00783     B[0] = -1;
00784     B[1] = 1;
00785     if( !B.Redim(2) ) // B is a vector with length 2 but data values are retained
00786       return false;
00787     // results in:
00788     // B 
00789     // -1
00790     // 1
00791     \endcode
00792     
00793     \return true if successful, false otherwise.  
00794     */
00795     bool Redim( const unsigned nrows, const unsigned ncols=1 );
00796 
00797     /**
00798     \brief  Resize the matrix, original data is lost, new data is set to zero.
00799             The default value for ncols allows resizing as a vector.
00800 
00801     \code
00802     Matrix A(4,4);       // A is 4x4
00803     A[0][0] = 1;
00804     A[1][1] = -1;
00805     if( !A.Resize(2,2) )  // A is 2x2 and zero.
00806       return false;
00807     // results in:
00808     // A (2x2)
00809     // 0 0
00810     // 0 0
00811 
00812     Matrix B(10);     // B is a vector with length 10.
00813     B[0] = -1;
00814     B[1] = 1;
00815     if( !B.Resize(2) ) // B is a vector with length 2 and is zero.
00816       return false;
00817     // results in:
00818     // B 
00819     // 0
00820     // 0
00821     \endcode
00822             
00823     \return true if successful, false otherwise.  
00824     */
00825     bool Resize( const unsigned nrows, const unsigned ncols=1 );
00826 
00827 
00828   public: // Setting matrix values
00829 
00830     /**
00831     \brief  Set the matrix from the static 'c' style matrix indexed by mat[i*ncols + j].
00832 
00833     \code
00834     Matrix A;
00835     double data[4] = {1.0,2.0,3.0,4.0};
00836     if( !A.SetFromStaticMatrix( data, 1, 4 ) )
00837       return false;
00838     \\ results in 
00839     \\ A
00840     \\ 1.0 2.0 3.0 4.0
00841     if( !A.SetFromStaticMatrix( data, 2, 2 ) )
00842       return false;    
00843     \\ results in 
00844     \\ A
00845     \\ 1.0 2.0 
00846     \\ 3.0 4.0    
00847     \endcode
00848     
00849     \return true if successful, false otherwise.    
00850     */
00851     bool SetFromStaticMatrix( const double mat[], const unsigned nrows, const unsigned ncols );
00852 
00853     /**
00854     \brief  Setting the matrix values from a string matrix.
00855     
00856     There are two general possible interpretations of the string input. \n
00857     
00858     (1) Square bracket delimited matrix. e.g. \n
00859     
00860     \code
00861     Matrix A;
00862     A.SetFromMatrixString( "[1 2 3; 4 5 6]" ); // or 
00863     A.SetFromMatrixString( "[1, 2, 3; 4, 5, 6]" );
00864     \endcode
00865 
00866     In this case '[' donates the start of a matrix and ']' denotes the end. \n
00867     Row vectors [1 2 3] and [4 5 6] are separated by ';'.  \n
00868     Commas can delimit row vector data but are not needed. \n
00869     Complex input: e.g. 
00870     
00871     \code
00872     Matrix A;
00873     A.SetFromMatrixString( "[1+1i 2+3j 1-2i; 4 5 6]" ); // or
00874     A.SetFromMatrixString( "[1+1i, 2+3j, 1-2i; 4, 5, 6]" );
00875     \endcode
00876     
00877     (2) Free form delimited matrix. e.g. \n
00878 
00879     \code
00880     Matrix A; 
00881     A.SetFromMatrixString( "1 2 3 \\n 4 5 6 \\n" );
00882     \endcode
00883 
00884     In this case, the newline delimits different rows of the matrix. (\\r\\n also works). \n
00885     Row vectors can still be delimited by ';' as well. \n
00886     
00887     \code
00888     A.SetFromMatrixString( "1 2 3; 4 5 6; \\n 7 8 9" );
00889     \endcode 
00890     
00891     will set a 3x3 matrix == [1 2 3; 4 5 6; 7 8 9]. \n
00892 
00893     Commas can delimit row vector data but are not needed. \n
00894     Complex input: e.g. 
00895     
00896     \code
00897     Matrix A;
00898     A.SetFromMatrixString( "[1+1i 2+3j 1-2i\\n 4 5 6]" );   // or
00899     A.SetFromMatrixString( "1+1i, 2+3j, 1-2i\\n 4, 5, 6" ); // or
00900     A.SetFromMatrixString( "1+1i 2+3j 1-2i; 4, 5, 6" );   
00901     \endcode 
00902 
00903     All result in A = [1+1i 2+3i 1-2i; 4 5 6]; \n
00904    
00905     \return true if successful, false otherwise.
00906     */
00907     bool SetFromMatrixString(const char* strMatrix);
00908 
00909 
00910     /**    
00911     \brief  Copy the src data in column col to dst matrix, resize dst if possible and necessary.
00912     
00913     \code
00914     Matrix A;
00915     A = "[1 -1; 2 -2; 3 -3]".
00916     Matrix B;
00917     bool result;
00918     result = A.PrintStdout();   // Print Matrix A.
00919     result = A.CopyColumn(0,B); // Copy the first column of A into B.
00920     result = B.PrintStdout();   // Print Matrix B. B = [1;2;3];
00921     \endcode
00922     
00923     \return true if successful, false otherwise.    
00924     */
00925     bool CopyColumn( const unsigned src_col, Matrix &dst );
00926 
00927     /**
00928     \brief  Insert a submatrix (src) into dst, starting at indices dst(row,col).
00929     
00930     \code
00931     Matrix A(4,4); // A 4x4 matrix of zeros.
00932     Matrix B(2,2); // A 2x2 matrix that we will fill with sevens.
00933     B.Fill(7.0);
00934     bool result;
00935     result = A.PrintStdout();           // Print Matrix A.
00936     result = A.InsertSubMatrix(B,1,1);  // Put B in the middle of A.
00937     result = A.PrintStdout();           // Print Matrix A. A = [0 0 0 0; 0 7 7 0; 0 7 7 0; 0 0 0 0].
00938     \endcode
00939     
00940     \return true if successful, false otherwise.    
00941     */
00942     bool InsertSubMatrix( const Matrix &src, const unsigned dst_row, const unsigned dst_col );
00943 
00944     /**
00945     \brief  Zero the entire matrix.
00946     
00947     \code
00948     Matrix A;
00949     A = "[1 2 3; 4 5 6; 7 8 9]";
00950     bool result;
00951     result = A.PrintStdout();   // Print Matrix A.
00952     result = A.Zero();          // Set A back to zeros.
00953     result = A.PrintStdout();   // Print Matrix A. A = [0 0 0; 0 0 0; 0 0 0].
00954     \endcode
00955     
00956     \return true if successful, false otherwise.  
00957     */
00958     bool Zero();
00959 
00960     /**
00961     \brief  Zero all elements in a specified column.
00962     
00963     \code
00964     Matrix A;
00965     A = "[1 2 3; 4 5 6; 7 8 9]";
00966     bool result;
00967     result = A.PrintStdout();   // Print Matrix A.
00968     result = A.ZeroColumn(1);   // Set the second column of A back to zeros.
00969     result = A.PrintStdout();   // Print Matrix A. A = [1 0 3; 4 0 6; 7 0 9].
00970     \endcode
00971        
00972     \return true if successful, false otherwise.    
00973     */
00974     bool ZeroColumn( const unsigned col );
00975 
00976     /**
00977     \brief  Zero all elements in a specified row.
00978     
00979     \code
00980     Matrix A;
00981     A = "[1 2 3; 4 5 6; 7 8 9]";
00982     bool result;
00983     result = A.PrintStdout();   // Print Matrix A.
00984     result = A.ZeroRow(1);      // Set the second row of A back to zeros.
00985     result = A.PrintStdout();   // Print Matrix A. A = [1 2 3; 0 0 0; 7 8 9].
00986     \endcode
00987        
00988     \return true if successful, false otherwise.    
00989     */
00990     bool ZeroRow( const unsigned row );
00991 
00992     /**
00993     \brief  Fill the matrix with the given value.
00994 
00995     \code
00996     Matrix A;
00997     A = "[1 2 3; 4 5 6; 7 8 9]";
00998     bool result;
00999     result = A.PrintStdout();   // Print Matrix A.
01000     result = A.Fill(7);         // Fill the matrix with 7.0.
01001     result = A.PrintStdout();   // Print Matrix A. A = [7 7 7; 7 7 7; 7 7 7].
01002     \endcode
01003 
01004     \return true if successful, false otherwise.    
01005     */
01006     bool Fill( const double value );
01007 
01008     /**
01009     \brief  Fill the matrix column with the given value.
01010     
01011     \code
01012     Matrix A;
01013     A = "[1 2 3; 4 5 6; 7 8 9]";
01014     bool result;
01015     result = A.PrintStdout();   // Print Matrix A.
01016     result = A.FillColumn(1,7); // Fill the second column with 7.0.
01017     cout << endl;
01018     result = A.PrintStdout();   // Print Matrix A. A = [1 7 3; 4 7 6; 7 7 9].
01019     \endcode
01020     
01021     \return true if successful, false otherwise.    
01022     */
01023     bool FillColumn( const unsigned col, const double value );
01024 
01025     /**
01026     \brief  Fills the matrix row with the given value.
01027     
01028     \code
01029     Matrix A;
01030     A = "[1 2 3; 4 5 6; 7 8 9]";
01031     bool result;
01032     result = A.PrintStdout();   // Print Matrix A.
01033     result = A.FillRow(1,7);    // Fill the second row with 7.0.
01034     cout << endl;
01035     result = A.PrintStdout();   // Print Matrix A. A = [1 2 3; 7 7 7; 7 8 9].
01036     \endcode
01037     
01038     \return true if successful, false otherwise.    
01039     */
01040     bool FillRow( const unsigned row, const double value );
01041 
01042     /**
01043     \brief  Reverse the order of elements of a column.
01044     
01045     \code
01046     Matrix A;
01047     A = "[1 2 3; 4 5 6; 7 8 9]";
01048     bool result;
01049     result = A.PrintStdout();   // Print Matrix A.
01050     result = A.FlipColumn(1);   // Flip the second column.
01051     cout << endl;
01052     result = A.PrintStdout();   // Print Matrix A. A = [1 8 3; 4 5 6; 7 2 9].
01053     \endcode
01054        
01055     \return true if successful, false otherwise.    
01056     */
01057     bool FlipColumn( const unsigned col );
01058 
01059     /**
01060     \brief  Reverse the order of elements of a row.
01061     
01062     \code
01063     Matrix A;
01064     A = "[1 2 3; 4 5 6; 7 8 9]";
01065     bool result;
01066     result = A.PrintStdout();   // Print Matrix A.
01067     result = A.FlipRow(1);      // Flip the second row.
01068     cout << endl;
01069     result = A.PrintStdout();   // Print Matrix A. A = [1 2 3; 6 5 4; 7 8 9].
01070     \endcode    
01071     
01072     \return true if successful, false otherwise.    
01073     */
01074     bool FlipRow( const unsigned row );
01075 
01076     /**
01077     \brief  Set the matrix to identity using the current dimensions.
01078     
01079     \code
01080     Matrix A;
01081     A = "[1 2 3; 4 5 6; 7 8 9]";
01082     bool result;
01083     result = A.PrintStdout();   // Print Matrix A.
01084     result = A.Identity();      // Set A to identity.
01085     cout << endl;
01086     result = A.PrintStdout();   // Print Matrix A. A = [1 0 0; 0 1 0; 0 0 1].
01087     \endcode    
01088     
01089     \return true if successful, false otherwise.    
01090     */
01091     bool Identity();
01092 
01093     /**   
01094     \brief  Set the matrix to identity using the specified dimension (nxn).
01095     
01096     \code
01097     Matrix A;
01098     bool result;
01099     result = A.Identity(3);     // Set A to identity, 3x3.
01100     cout << endl;
01101     result = A.PrintStdout();   // Print Matrix A. A = [1 0 0; 0 1 0; 0 0 1].
01102     \endcode    
01103     
01104     \return true if successful, false otherwise.        
01105     */
01106     bool Identity(const unsigned dimension);
01107 
01108 
01109 
01110   public: // Inplace Operations
01111 
01112     /**
01113     \brief  Transpose the matrix as an inplace operation.
01114     
01115     \code
01116     Matrix A;
01117     A = "[1 2 3; 4 5 6; 7 8 9]";
01118     bool result;
01119     result = A.PrintStdout();         // Print Matrix A.
01120     result = A.Inplace_Transpose();   // Make A = transpose(A).
01121     cout << endl;
01122     result = A.PrintStdout();         // Print Matrix A. A = [1 4 7; 2 5 8; 3 6 9].
01123     \endcode    
01124     
01125     \return true if successful, false otherwise.    
01126     */
01127     bool Inplace_Transpose();
01128     bool Inplace_transpose() { return this->Inplace_Transpose(); }
01129 
01130     /**
01131     \brief  Round the matrix elements to the specified presision. \n
01132     e.g. precision = 0    1.8    -> 2     (default)\n
01133     e.g. precision = 1,   1.45   -> 1.5   \n
01134     e.g. precision = 2    1.456  -> 1.46  \n
01135     e.g. precision = 3,   1.4566 -> 1.457 \n
01136     *
01137     \code
01138     Matrix A;
01139     A = "[1.09 2.08 3.07; 4.06 5.05 6.04; 7.03 8.02 9.01]";
01140     bool result;
01141     result = A.PrintStdout();     // Print Matrix A.
01142     result = A.Inplace_Round(1);  // Make A = round(A) to the 1st decimal place.
01143     cout << endl;
01144     result = A.PrintStdout();     // Print Matrix A. A = "[1.1 2.1 3.1; 4.1 5.1 6.0; 7.0 8.0 9.0]";
01145     \endcode    
01146     
01147     \return true if successful, false otherwise.    
01148     */
01149     bool Inplace_Round( const unsigned precision = 0 );
01150     bool Inplace_round( const unsigned precision = 0 ) { return this->Inplace_Round( precision ); }
01151 
01152     /**
01153     \brief  Round the matrix elements to the nearest integers towards minus infinity.
01154     
01155     \code
01156     Matrix A;
01157     A = "[1.9 2.8 3.7; -4.6 -5.5 -6.4; 7.3 8.2 9.1]";
01158     bool result;
01159     result = A.PrintStdout();     // Print Matrix A.
01160     result = A.Inplace_Floor();   // Make A = floor(A).
01161     cout << endl;
01162     result = A.PrintStdout();     // Print Matrix A. A = "[1 2 3; -5 -6 -7; 7 8 9]";
01163     \endcode    
01164        
01165     \return true if successful, false otherwise.    
01166     */
01167     bool Inplace_Floor();
01168     bool Inplace_floor() { return this->Inplace_Floor(); }
01169 
01170     /**
01171     \brief  Round the matrix elements to the nearest integers towards infinity.
01172     
01173     \code
01174     Matrix A;
01175     A = "[1.9 2.8 3.7; -4.6 -5.5 -6.4; 7.3 8.2 9.1]";
01176     bool result;
01177     result = A.PrintStdout();     // Print Matrix A.
01178     result = A.Inplace_Ceil();    // Make A = ceil(A).
01179     cout << endl;
01180     result = A.PrintStdout();     // Print Matrix A. A = "[2 3 4; -4 -5 -6; 8 9 10]";
01181     \endcode    
01182            
01183     \return true if successful, false otherwise.    
01184     */
01185     bool Inplace_Ceil();
01186     bool Inplace_ceil() { return this->Inplace_Ceil(); }
01187 
01188     /**
01189     \brief  Rounds the matrix elements of X to the nearest integers towards zero.
01190     
01191     \code
01192     Matrix A;
01193     A = "[1.9 2.8 3.7; -4.6 -5.5 -6.4; 7.3 8.2 9.1]";
01194     bool result;
01195     result = A.PrintStdout();     // Print Matrix A.
01196     result = A.Inplace_Fix();     // Make A = fix(A).
01197     cout << endl;
01198     result = A.PrintStdout();     // Print Matrix A. A = "[1 2 3; -4 -5 -6; 7 8 9]";
01199     \endcode    
01200     
01201     \return true if successful, false otherwise.    
01202     */
01203     bool Inplace_Fix();
01204 
01205     /** \brief  Add a scaler double (ie: M += 5).
01206     
01207     \code
01208     Matrix A;
01209     A = "[1 2 3; 4 5 6; 7 8 9]";
01210     bool result;
01211     result = A.PrintStdout();        // Print Matrix A.
01212     result = A.Inplace_AddScalar(1); // A += 1.
01213     cout << endl;
01214     result = A.PrintStdout();        // Print Matrix A. A = "[2 3 4; 5 6 7; 8 9 10]";
01215     \endcode    
01216     
01217     \return true if successful, false otherwise.    
01218     */
01219     bool Inplace_AddScalar( const double scalar );
01220 
01221     /**
01222     \brief  Subtract a scaler double (ie: M -= 5).
01223     
01224     \code
01225     Matrix A;
01226     A = "[1 2 3; 4 5 6; 7 8 9]";
01227     bool result;
01228     result = A.PrintStdout();             // Print Matrix A.
01229     result = A.Inplace_SubtractScalar(1); // A -= 1.
01230     cout << endl;
01231     result = A.PrintStdout();             // Print Matrix A. A = "[0 1 2; 3 4 5; 6 7 8]";
01232     \endcode    
01233        
01234     \return true if successful, false otherwise.    
01235     */
01236     bool Inplace_SubtractScalar( const double scalar );
01237 
01238     /**
01239     \brief  Multiply by scaler double (ie: M *= 5).
01240     
01241     \code
01242     Matrix A;
01243     A = "[1 2 3; 4 5 6; 7 8 9]";
01244     bool result;
01245     result = A.PrintStdout();              // Print Matrix A.
01246     result = A.Inplace_MultiplyScalar(5);  // A *= 5.
01247     cout << endl;
01248     result = A.PrintStdout();              // Print Matrix A. A = "[5 10 15; 20 25 30; 35 40 45]";
01249     \endcode    
01250     
01251     \return true if successful, false otherwise.    
01252     */
01253     bool Inplace_MultiplyScalar( const double scalar );
01254 
01255     /**
01256     \brief  Divide by scaler double (ie: M /= 5).
01257     
01258     \code
01259     Matrix A;
01260     A = "[5 10 15; 20 25 30; 35 40 45]";
01261     bool result;
01262     result = A.PrintStdout();           // Print Matrix A.
01263     result = A.Inplace_DivideScalar(5); // A /= 5.
01264     cout << endl;
01265     result = A.PrintStdout();           // Print Matrix A. A = "[1 2 3; 4 5 6; 7 8 9]";
01266     \endcode    
01267        
01268     \return true if successful, false otherwise.    
01269     */
01270     bool Inplace_DivideScalar( const double scalar );
01271 
01272     /**
01273     \brief  Raise the matrix to a power scaler double (ie: M ^= 5).
01274     
01275     \code
01276     Matrix A;
01277     A = "[1 2 3; 4 5 6; 7 8 9]";
01278     bool result;
01279     result = A.PrintStdout();           // Print Matrix A.
01280     result = A.Inplace_PowerScalar(2);  // A = A.^2. Not A*A! Each element is raised.
01281     cout << endl;
01282     result = A.PrintStdout();           // Print Matrix A. A = "[1 4 9; 16 25 36; 49 64 81]";
01283     \endcode    
01284            
01285     \return true if successful, false otherwise.    
01286     */
01287     bool Inplace_PowerScalar( const double scalar );
01288 
01289     /**
01290     \brief  Add a scaler double (ie: M += (4+2i)).
01291     
01292     \code
01293     Matrix A;
01294     A = "[1 2 3; 4 5 6; 7 8 9]";
01295     bool result;
01296     result = A.PrintStdout();           // Print Matrix A.
01297     std::complex<double> cplx(4.0,2.0);
01298     result = A.Inplace_AddScalarComplex(cplx);  // A += (4+2i).
01299     cout << endl;
01300     result = A.PrintStdout();           // Print Matrix A. A = "[5+2i 6+2i 7+2i; 8+2i 9+2i 10+2i; 11+2i 12+2i 13+2i]";
01301     cout << "A(0,0) = " << A(0,0).real() << "+" << A(0,0).imag() << "i " << endl;
01302     \endcode    
01303                
01304     * \return true if successful, false otherwise.    
01305     */
01306     bool Inplace_AddScalarComplex( const std::complex<double> cplx );
01307 
01308     /**
01309     \brief  Subtract a scaler double (ie: M -= (5+2i)).
01310     
01311     \code
01312     Matrix A;
01313     A = "[1 2 3; 4 5 6; 7 8 9]";
01314     bool result;
01315     result = A.PrintStdout();           // Print Matrix A.
01316     std::complex<double> cplx(5.0,2.0);
01317     result = A.Inplace_SubtractScalarComplex(cplx);  // A -= (5+2i).
01318     cout << endl;
01319     result = A.PrintStdout();           // Print Matrix A. A = "[-4-2i -3-2i -2-2i; -1-2i 0-2i 1-2i; 2-2i 3-2i 4-2i]";
01320     cout << "A(0,0) = " << A(0,0).real() << "+" << A(0,0).imag() << "i " << endl;
01321     \endcode    
01322                    
01323     \return true if successful, false otherwise.    
01324     */
01325     bool Inplace_SubtractScalarComplex( const std::complex<double> cplx );
01326 
01327     /**
01328     \brief  Multiply by scaler double (ie: M *= (5+2i)).
01329 
01330     \code
01331     Matrix M;
01332     M = "[10 20]";
01333     std::complex<double> cplx(5,2);
01334     if( !M.Inplace_MultiplyScalarComplex(cplx) )
01335       return false;
01336     // M
01337     // 50+20i  100+40i
01338     \endcode
01339     
01340     \return true if successful, false otherwise.    
01341     */
01342     bool Inplace_MultiplyScalarComplex( const std::complex<double> cplx );
01343 
01344     /**
01345     \brief  Divide by scaler double (ie: M /= (5+1i)).
01346 
01347     \code
01348     Matrix M;
01349     M = "[10+2i 20+4i]";
01350     std::complex<double> cplx(5,1);
01351     if( !M.Inplace_DivideScalarComplex(cplx) )
01352       return false;
01353     // M
01354     // 2  4
01355     \endcode
01356     
01357     \return true if successful, false otherwise.    
01358     */
01359     bool Inplace_DivideScalarComplex( const std::complex<double> cplx );
01360 
01361     /**
01362     \brief  Raise the matrix to a power scaler double (ie: M ^= (5+2i)).
01363 
01364     \code
01365     Matrix M;
01366     M = "[2 3]";
01367     std::complex<double> cplx(5,2);
01368     if( !M.Inplace_PowerScalarComplex(cplx) )
01369       return false;
01370     // M
01371     // 5.87062319178566+31.4568876931598i    -142.459949032798+196.860770397691i
01372     \endcode    
01373     
01374     \return true if successful, false otherwise.    
01375     */
01376     bool Inplace_PowerScalarComplex( const std::complex<double> cplx );
01377 
01378     /**
01379     \brief  Compute the absolute value of each element in the matrix.
01380 
01381     \code
01382     Matrix A;
01383     A = "[-1 -2; -3 -4]";
01384     if( !A.Inplace_Abs() )
01385       return false;
01386     // A
01387     // 1 2
01388     // 3 4
01389     \endcode
01390     
01391     \return true if successful, false otherwise.    
01392     */
01393     bool Inplace_Abs();
01394 
01395     /**
01396     \brief  Compute the value^2 of each element in the matrix.
01397 
01398     \code
01399     Matrix A;
01400     A = "[1 2; -3 -4]";
01401     if( !A.Inplace_Sqr() )
01402       return false;
01403     // A
01404     // 1 4
01405     // 9 16
01406     \endcode    
01407     
01408     \return true if successful, false otherwise.    
01409     */
01410     bool Inplace_Sqr();
01411 
01412     /**
01413     \brief  Computes the sqrt(value) of each element in the matrix.
01414 
01415     \code
01416     Matrix A;
01417     A = "[1 4; 9 16]";
01418     if( !A.Inplace_Sqrt() )
01419       return false;
01420     // A
01421     // 1 2
01422     // 3 4
01423     \endcode        
01424     
01425     \return true if successful, false otherwise.    
01426     */
01427     bool Inplace_Sqrt();
01428 
01429     /**
01430     \brief  Computes the exp(value) of each element in the matrix.
01431 
01432     \code
01433     Matrix A;
01434     A = "[1 2; 3 4]";
01435     if( !A.Inplace_Exp() )
01436       return false;
01437     // A ~
01438     //  2.71828  7.38905
01439     // 20.08553 54.59815
01440     \endcode        
01441     
01442     \return true if successful, false otherwise.    
01443     */
01444     bool Inplace_Exp();
01445 
01446     /**
01447     \brief  Computes the natural logarithm, ln(value) of each element in the matrix.
01448 
01449     \code
01450     Matrix A;
01451     A = "[2.71828  7.38905; 20.08553 54.59815]";    
01452     if( !A.Inplace_Ln() )
01453       return false;
01454     // A ~
01455     // 1 2
01456     // 3 4
01457     \endcode         
01458     
01459     \return true if successful, false otherwise.    
01460     */
01461     bool Inplace_Ln();
01462 
01463     /**
01464     \brief  Add +1.0 to all elements, e.g. M++.
01465 
01466     \code
01467     Matrix A;
01468     A = "[1 2; 3 4]";
01469     if( !A.Inplace_Increment() )
01470       return false;
01471     // A 
01472     // 2 3
01473     // 4 5
01474     \endcode        
01475     
01476     \return true if successful, false otherwise.   
01477     */
01478     bool Inplace_Increment();
01479 
01480     /**
01481     \brief  Subtract 1.0 from all elements, e.g. M--.
01482 
01483     \code
01484     Matrix A;
01485     A = "[1 2; 3 4]";
01486     if( !A.Inplace_Decrement() )
01487       return false;
01488     // A 
01489     // 0 1
01490     // 2 3
01491     \endcode            
01492     
01493     \return true if successful, false otherwise.    
01494     */
01495     bool Inplace_Decrement();
01496 
01497     /**
01498     \brief  Add matrix B to this matrix inplace. A += B, inplace.
01499 
01500     \code
01501     Matrix A;
01502     Matrix B;
01503     A = "[1 2; 3 4]";
01504     B = "[1 2; 3 4]";
01505     if( !A.Inplace_Add(B) )
01506       return false;
01507     // A 
01508     // 2 4
01509     // 6 8
01510     \endcode            
01511     
01512     \return true if successful, false otherwise.
01513     */
01514     bool Inplace_Add( const Matrix &B );
01515 
01516     /**
01517     \brief  Subtract matrix B from this matrix inplace. A -= B, inplace.
01518 
01519     \code
01520     Matrix A;
01521     Matrix B;
01522     A = "[1 2; 3 4]";
01523     B = "[1 2; 3 4]";
01524     if( !A.Inplace_Subtract(B) )
01525       return false;
01526     // A 
01527     // 0 0
01528     // 0 0
01529     \endcode            
01530     
01531     \return true if successful, false otherwise.
01532     */
01533     bool Inplace_Subtract( const Matrix &B );
01534 
01535     /**
01536     \brief  Pre-Multiply this matrix by B. A = B*A, inplace.
01537 
01538     \code
01539     Matrix A;
01540     Matrix B;
01541     A = "[1 2; 3 4]";
01542     B = "[1 2; 2 1]";
01543     if( !A.Inplace_PreMultiply(B) )
01544       return false;
01545     // A 
01546     // 7 10
01547     // 5 8
01548     \endcode  
01549     
01550     \return true if successful, false otherwise.
01551     */
01552     bool Inplace_PreMultiply( const Matrix &B );
01553 
01554     /**
01555     \brief  Post-Multiply this matrix by B. A = A*B, inplace.
01556 
01557     \code
01558     Matrix A;
01559     Matrix B;
01560     A = "[1 2; 3 4]";
01561     B = "[1 2; 2 1]";
01562     if( !A.Inplace_PostMultiply(B) )
01563       return false;
01564     // A 
01565     // 5 4
01566     // 11 10
01567     \endcode      
01568     
01569     \return true if successful, false otherwise.  
01570     */
01571     bool Inplace_PostMultiply( const Matrix &B );
01572 
01573     /**
01574     \brief  Dot multiply A .*= B, inplace. A and B must have the same dimensions.
01575 
01576     \code
01577     Matrix A;
01578     Matrix B;
01579     A = "[1 2; 3 4]";
01580     B = "[1 2; 2 1]";
01581     if( !A.Inplace_DotMultiply(B) )
01582       return false;
01583     // A 
01584     // 1 4
01585     // 6 4
01586     \endcode          
01587     
01588     \return true if successful, false otherwise.
01589     */
01590     bool Inplace_DotMultiply( const Matrix &B );
01591 
01592     /**
01593     \brief  Dot divide A ./= B, inplace. A and B must have the same dimensions.
01594 
01595     \code
01596     Matrix A;
01597     Matrix B;
01598     A = "[1 2; 3 4]";
01599     B = "[1 2; 2 1]";
01600     if( !A.Inplace_DotDivide(B) )
01601       return false;
01602     // A 
01603     // 1   1
01604     // 1.5 4
01605     \endcode          
01606     
01607     \return true if successful, false otherwise.
01608     */
01609     bool Inplace_DotDivide( const Matrix &B );
01610 
01611     /**
01612     \brief  Sorts each column of the matrix in ascending order.
01613             If complex, sorts based on magnitude.
01614     \code
01615     Matrix A;
01616     A = "[1;3;2;4;6;5;7]";
01617     if( !A.Inplace_SortAscending() )
01618       return false;
01619     // A
01620     // [1;2;3;4;5;6;7]
01621     \endcode
01622     
01623     \return true if successful, false otherwise.
01624     */
01625     bool Inplace_SortAscending();
01626 
01627     /**
01628     \brief  Sorts each column of M in descending order.
01629             If complex, sorts based on magnitude.
01630     \code
01631     Matrix A;
01632     A = "[1;3;2;4;6;5;7]";
01633     if( !A.Inplace_SortDescending() )
01634       return false;
01635     // A
01636     // [7;6;5;4;3;2;1]
01637     \endcode    
01638     
01639     \return true if successful, false otherwise.
01640     */
01641     bool Inplace_SortDescending();
01642 
01643     /**
01644     \brief  Sorts a specific column in ascending order.
01645             If complex, sorts based on magnitude.
01646     \code
01647     Matrix A;
01648     A = "[0 1;0 3;0 2;0 4;0 6;0 5;0 7]";
01649     if( !A.Inplace_SortColumnAscending(1) )
01650       return false;
01651     // A
01652     // A = "[0 1;0 2;0 3;0 4;0 5;0 6;0 7]";
01653     \endcode
01654        
01655     \return true if successful, false otherwise.
01656     */
01657     bool Inplace_SortColumnAscending( const unsigned col );
01658 
01659     /**
01660     \brief  Sorts a specific column in descending order.
01661             If complex, sorts based on magnitude.
01662     \code
01663     Matrix A;
01664     A = "[0 1;0 3;0 2;0 4;0 6;0 5;0 7]";
01665     if( !A.Inplace_SortColumnDescending(1) )
01666       return false;
01667     // A
01668     // A = "[0 7;0 6;0 5;0 4;0 3;0 2;0 1]";
01669     \endcode       
01670     
01671     \return true if successful, false otherwise.
01672     */
01673     bool Inplace_SortColumnDescending( const unsigned col );
01674 
01675     /**
01676     \brief  Sorts a specific column in ascending order and fills a  
01677             column vector with the sorted index. The index vector will be resized 
01678             if needed. If complex, sorts based on magnitude.
01679     \code
01680     Matrix A;
01681     Matrix I;
01682     A = "[0 1;0 3;0 2;0 4;0 6;0 5;0 7]";
01683     if( !A.Inplace_SortColumnIndexed(1, I) )
01684       return false;
01685     // A = "[0 1;0 2;0 3;0 4;0 5;0 6;0 7]";
01686     // I = "[0;2;1;3;5;4;6]"
01687     \endcode    
01688     
01689     \return true if successful, false otherwise.
01690     */
01691     bool Inplace_SortColumnIndexed( const unsigned col, Matrix &Index );
01692 
01693     /**
01694     \brief  Sorts the entire matrix by a specific column.
01695             If complex, sorts based on magnitude.
01696 
01697     \code
01698     Matrix A;
01699     Matrix I;
01700     A = "[0 1;2 3;1 2;3 4;5 6;4 5;6 7]";
01701     if( !A.Inplace_SortByColumn(0) )
01702       return false;
01703     // A = "[0 1;1 2;2 3;3 4;4 5;5 6;6 7]";
01704     \endcode 
01705     
01706     \return true if successful, false otherwise.
01707     */
01708     bool Inplace_SortByColumn( const unsigned col );
01709 
01710     /**
01711     \brief  Computes the inplace inverse of the matrix.
01712     
01713     Uses fast closed form solutions for:
01714     1x1, 2x2, 3x3
01715     
01716     Otherwise, the matrix is first tested to determine if it is a symmetric 
01717     positive-definite matrix. If so, Cholesky decomposition is used
01718     to facilitate the inversion of a lower triangular matrix. If the
01719     matrix is not symmetric and positive-definite robust inversion
01720     using gaussing elimination is attempted.
01721     
01722     If the matrix is singular, the original matrix is unchanged.
01723 
01724     \code 
01725     Matrix A;
01726     A = "[10 14; 14 20]";
01727     if( !A.Inplace_Invert() )
01728       return false;
01729     // A
01730     //     5  -3.5
01731     //  -3.5   2.5
01732     \endcode
01733     
01734     \return true if successful, false if empty, singular or not square.
01735     */
01736     bool Inplace_Invert();
01737 
01738     /**
01739     \brief  Perfroms an inplace inverse using Gaussian Elimination methods.
01740 
01741     \code 
01742     Matrix A;
01743     A = "[1 2; 3 4]";
01744     if( !A.Inplace_InvertRobust() )
01745       return false;
01746     // A
01747     //   -2     1
01748     //  1.5  -0.5
01749     \endcode
01750     
01751     \return true if successful, false if empty, singular or not square.
01752     */
01753     bool Inplace_InvertRobust();
01754 
01755     /**
01756     \brief  Compute the inplace inverse of a unit lower triangular matrix. 
01757     
01758     \code
01759     Matrix A;
01760     // A
01761     //    1    0    0
01762     //   -2    2    0
01763     //    4   -3   -3    
01764     A = "[1 0 0; -2 2 0; 4 -3 -3]";
01765     if( !A.Inplace_LowerTriangularInverse() )
01766       return false;
01767     // A
01768     //    1    0    0
01769     //    1  1/2    0
01770     // -1/3  1/2  1/3
01771     \endcode
01772     
01773     \return true if successful, false if empty, singular or not square.
01774     */
01775     bool Inplace_LowerTriangularInverse();
01776 
01777     /**
01778     \brief  Compute the inplace Fourier Transform of each column of the matrix.
01779 
01780     \code
01781     Matrix A;
01782     A = "[0; 0; 0; 0; 1; 1; 1; 1;]"; 
01783     if( !A.Inplace_FFT() )
01784      return false;
01785     // A
01786     //  4                         
01787     // -1+2.41421356237309i
01788     //  0                         
01789     // -1+0.414213562373095i
01790     //  0                         
01791     // -1-0.414213562373095i
01792     //  0                         
01793     // -1-2.41421356237309i
01794     \endcode
01795 
01796     endcode
01797 
01798     \return   true if successful, false if unable to perform the FFT.
01799     */
01800     bool Inplace_FFT();
01801 
01802     /**
01803     \brief  Compute the inplace inverse Fourier Transform of each column of the matrix.
01804 
01805     \code
01806     Matrix A;
01807     A = "[4; -1+2.41421356237309i; 0; -1+0.414213562373095i; 0; -1-0.414213562373095i; 0; -1-2.41421356237309i;]"; 
01808     if( !A.Inplace_IFFT() )
01809      return false;
01810     // A
01811     // 0                         
01812     // 0
01813     // 0                         
01814     // 0
01815     // 1                         
01816     // 1
01817     // 1                         
01818     // 1
01819     \endcode
01820 
01821     \return   true if successful, false if unable to perform the FFT.
01822     */
01823     bool Inplace_IFFT();
01824 
01825 
01826   public: // Safe operations that set the matrix. Safe in that they return a boolean.
01827 
01828     /**
01829     \brief  Add A = B+C. The result, A, is stored in this matrix. 
01830 
01831     \code
01832     Matrix A;
01833     Matrix B;
01834     Matrix C;
01835     B = "[1 2; 3 4]";
01836     C = "[-1 2; -3 4]";
01837     if( !A.Add( B, C ) )
01838       return false;
01839     // A
01840     // 0 4
01841     // 0 8
01842     \endcode
01843     
01844     \return true if successful, false otherwise.
01845     */
01846     bool Add( const Matrix &B, const Matrix &C );
01847 
01848     /**
01849     \brief  Subtract A = B-C. The result, A, is stored in this matrix. 
01850     
01851     \code
01852     Matrix A;
01853     Matrix B;
01854     Matrix C;
01855     B = "[1 2; 3 4]";
01856     C = "[-1 2; -3 4]";
01857     if( !A.Subtract( B, C ) )
01858       return false;
01859     // A
01860     // 2 0
01861     // 6 0
01862     \endcode
01863     
01864     \return true if successful, false otherwise.
01865     */
01866     bool Subtract( const Matrix &B, const Matrix &C );
01867 
01868     /**
01869     \brief  Multiply A = B*C. The result, A, is stored in this matrix. 
01870     
01871     \code
01872     Matrix A;
01873     Matrix B;
01874     Matrix C;
01875     B = "[1 2; 3 4]";
01876     C = "[-1 2; -3 4]";
01877     if( !A.Multiply( B, C ) )
01878       return false;
01879     // A
01880     //  -7  10
01881     // -15  22
01882     \endcode
01883     
01884     \return true if successful, false otherwise.
01885     */
01886     bool Multiply( const Matrix &B, const Matrix &C );
01887 
01888     
01889 
01890   public: // Matlab/Octave style functions
01891 
01892     /**
01893     \brief  Compute the absolute value of each element of the matrix inplace.
01894     
01895     \code
01896     Matrix A;
01897     A = "[-1 2 3]";
01898     if( !A.Inplace_abs() )
01899       return false;
01900     // A 
01901     // [1 2 3]
01902     \endcode
01903 
01904     \return true if successful, false otherwise.    
01905     */
01906     bool Inplace_abs();
01907 
01908     /**
01909     \brief  Compute the arc-cosine of each element of the matrix inplace.
01910             Complex results are obtained if elements are greater than abs(1).
01911             Results in radians.
01912     \code
01913     Matrix A;
01914     A = "[0 0.5 1]";
01915     if( !A.Inplace_acos() )
01916       return false;
01917     // A 
01918     // [pi/2 pi/3 0]
01919     \endcode
01920     
01921     \return true if successful, false otherwise.   
01922     */
01923     bool Inplace_acos();
01924 
01925     /**
01926     \brief  Compute the arc-cosine of each element of the matrix inplace.
01927             Complex results are obtained if elements are greater than abs(1).
01928             Results in degrees.
01929     \code
01930     Matrix A;
01931     A = "[0 0.5 1]";
01932     if( !A.Inplace_acosd() )
01933       return false;
01934     // A 
01935     // [90 60 0]
01936     \endcode    
01937     
01938     \return true if successful, false otherwise.    
01939     */
01940     bool Inplace_acosd();
01941 
01942     /**
01943     \brief  Compute the inverse hyperbolic cosine of each element of the matrix inplace.
01944             Results in radians.
01945     \code
01946     Matrix A;
01947     A = "[0  1.0471975511966 1.5707963267949]";
01948     if( !A.Inplace_acosh() )
01949       return false;
01950     // A 
01951     // [0 pi/3 pi/2]
01952     \endcode        
01953     
01954     \return true if successful, false otherwise.   
01955     */
01956     bool Inplace_acosh();
01957 
01958     /**
01959     \brief  Compute the phase angle in radians of the elements of the matrix.
01960 
01961     \code
01962     Matrix A;
01963     A = "[1+1i  1-1i 3+2i]";
01964     if( !A.Inplace_acosh() )
01965       return false;
01966     // A 
01967     // [pi/4 -pi/4 0.588002603547568]
01968     \endcode    
01969     
01970     \return true if successful, false otherwise.    
01971     */
01972     bool Inplace_angle();
01973 
01974     /**
01975     \brief  Compute the arc-sine of each element of the matrix inplace.
01976             Complex results are obtained if elements are greater than abs(1).
01977             Results in radians.
01978     \code
01979     Matrix A;
01980     A = "[0  0.5 1.0]";
01981     if( !A.Inplace_asin() )
01982       return false;
01983     // A 
01984     // [0 pi/6 pi/2]
01985     \endcode   
01986     
01987     \return true if successful, false otherwise.    
01988     */    
01989     bool Inplace_asin();
01990 
01991     /**
01992     \brief  Compute the arc-sine of each element of the matrix inplace.
01993             Complex results are obtained if elements are greater than abs(1).
01994             Results in degrees.
01995     \code
01996     Matrix A;
01997     A = "[0  0.5 1.0]";
01998     if( !A.Inplace_asind() )
01999       return false;
02000     // A 
02001     // [0 30 90]
02002     \endcode   
02003     
02004     \return true if successful, false otherwise.    
02005     */
02006     bool Inplace_asind();
02007 
02008     /**
02009     \brief  Compute the inverse hyperbolic sine of each element of the matrix inplace.
02010             Results in radians.
02011     \code
02012     Matrix A;
02013     A = "[0  0.521095305493747  1.1752011936438]";
02014     if( !A.Inplace_asinh() )
02015       return false;
02016     // A 
02017     // [0 0.5 1]
02018     \endcode   
02019     
02020     \return true if successful, false otherwise.    
02021     */
02022     bool Inplace_asinh();
02023 
02024     /**
02025     \brief  Compute the arc-tangent of each element of the matrix inplace.
02026             Results in radians bounded [-pi/2, pi/2].
02027     \code
02028     Matrix A;
02029     A = "[0  1.73205080756888  1.63312393531954e+016]";
02030     if( !A.Inplace_atan() )
02031       return false;
02032     // A 
02033     // [0 pi/3 pi/2]
02034     \endcode   
02035     
02036     \return true if successful, false otherwise.    
02037     */
02038     bool Inplace_atan();
02039 
02040     /**
02041     \brief  Compute the arc-tangent of each element of the matrix inplace.
02042             Results in degrees bounded [-90, 90].
02043     \code
02044     Matrix A;
02045     A = "[0  1.73205080756888  1.63312393531954e+016]";
02046     if( !A.Inplace_atand() )
02047       return false;
02048     // A 
02049     // [0 60 90]
02050     \endcode   
02051         
02052     \return true if successful, false otherwise.    
02053     */
02054     bool Inplace_atand();
02055 
02056     /**
02057     \brief  Compute the inverse hyperbolic tangent of each element of the matrix inplace.
02058 
02059     \code
02060     Matrix A;
02061     A = "[0  0.46211715726001  0.761594155955765]";
02062     if( !A.Inplace_atanh() )
02063       return false;
02064     // A 
02065     // [0 0.5 1]
02066     \endcode   
02067     
02068     \return true if successful, false otherwise.    
02069     */
02070     bool Inplace_atanh();
02071 
02072     /**
02073     \brief  Create a column vector [start:increment:end) beginning at start
02074     with step size of increment until less than or equal to end. 
02075     Note that arguments must be real scalars. \n
02076 
02077     \code
02078     Matrix A;
02079     if( !A.Inplace_colon( 2, 2, 9 ) )
02080       return false;
02081     // A
02082     // [2; 4; 6; 8]
02083     if( !A.Inplace_colon( 2, -2, -9 ) )
02084       return false;
02085     // A
02086     // [2; 0; -2; -4; -6; -9;]    
02087     if( !A.Inplace_colon( -10, 0.01, 10 ) )
02088       return false;
02089     // A
02090     // [-10 -9.99 -9.98 ... 10]    
02091     \endcode
02092     
02093     \return true if successful, false otherwise.     
02094     */
02095     bool Inplace_colon( double start, double increment, double end );
02096 
02097     /**
02098     \brief  Compute the cosine of each element of the matrix inplace. This 
02099             function assumes radian values in the matrix.
02100     \code
02101     Matrix A;
02102     A = "[0  1.0471975511966  1.5707963267949]"; // [0 pi/3 pi/2]
02103     if( !A.Inplace_cos() )
02104       return false;
02105     // A
02106     // 1 0.5 0
02107     \endcode 
02108 
02109     \return true if successful, false otherwise.        
02110     */
02111     bool Inplace_cos();
02112 
02113     /**
02114     \brief  Compute the hyperbolic cosine of each element of the matrix inplace. This 
02115             function assumes radian values in the matrix.
02116     \code
02117     Matrix A;
02118     A = "[0  0.5 1]";
02119     if( !A.Inplace_cosh() )
02120       return false;
02121     // A
02122     // 1  1.12762596520638  1.54308063481524
02123     \endcode 
02124     
02125     \return true if successful, false otherwise.      
02126     */
02127     bool Inplace_cosh();
02128 
02129     /**
02130     \brief  Compute the cotangent of each element of the matrix inplace. This 
02131             function assumes radian values in the matrix.
02132     \code
02133     Matrix A;
02134     A = "[0  1.0471975511966  1.5707963267949]"; // [0  pi/3 pi/2]
02135     if( !A.Inplace_cot() )
02136       return false;
02137     // A
02138     // Inf  0.577350269189626  0
02139     \endcode 
02140     
02141     \return true if successful, false otherwise.      
02142     */
02143     bool Inplace_cot();
02144 
02145     /**
02146     \brief  Compute the hyperbolic cotangent of each element of the matrix inplace. This 
02147             function assumes radian values in the matrix.
02148     \code
02149     Matrix A;
02150     A = "[0  0.5  1]";
02151     if( !A.Inplace_coth() )
02152       return false;
02153     // A
02154     // Inf   2.16395341373865 1.31303528549933
02155     \endcode 
02156     
02157     \return true if successful, false otherwise.        
02158     */
02159     bool Inplace_coth();
02160 
02161     /**
02162     \brief  Complex conjugate. z = x+yi. conj(z) = x-yi.
02163 
02164     \code
02165     Matrix A;
02166     A = "[2-2i -3+2i]";
02167     if( !A.Inplace_conj() )
02168       return false;
02169     // A
02170     // 2+2i  -3-2i
02171     \endcode
02172 
02173     \return true if successful, false otherwise.        
02174     */
02175     bool Inplace_conj();
02176 
02177 
02178     /**
02179     \brief  Compute the exponential of each element of the matrix inplace. 
02180             If real, computes the exp(value) of each element in the matrix.
02181             If complex, computes exp(M) = exp(real)*(cos(imag)+i*sin(imag)).
02182     \code
02183     Matrix A;
02184     A = "[1 2]";
02185     if( !A.Inplace_exp() )
02186       return false;
02187     // A
02188     //  2.71828182845905  7.38905609893065
02189     \endcode
02190 
02191     \return true if successful, false otherwise.        
02192     */
02193     bool Inplace_exp();
02194 
02195     /**
02196     \brief  Create an indentity matrix with nrows and ncols.
02197     
02198     \code
02199     Matrix A;
02200     if( !A.eye(3,3) )
02201       return false;
02202     // A
02203     // 1 0 0 
02204     // 0 1 0 
02205     // 0 0 1
02206     \endcode
02207 
02208     \return true if successful, false otherwise.        
02209     */
02210     bool Inplace_eye( const unsigned nrows, const unsigned ncols );
02211 
02212 
02213      /**
02214     \brief  Imaginary part of the complex matrix. z = x+yi. real(z) = y.
02215 
02216     \code
02217     Matrix A;
02218     A = "[2-2i -3+2i]";
02219     if( !A.Inplace_imag() )
02220       return false;
02221     // A
02222     // -2  2
02223     \endcode
02224 
02225     \return true if successful, false otherwise.        
02226     */
02227     bool Inplace_imag();
02228 
02229 
02230     /**
02231     \brief  Compute the log base 2 of the elements of the matrix.
02232             Complex results if elements are negative. 
02233     \code
02234     Matrix A;
02235     A = "[2 32]";
02236     if( !A.Inplace_log2() )
02237       return false;
02238     // A
02239     // 1 5
02240     \endcode
02241     
02242     \return true if successful, false otherwise.     
02243     */
02244     bool Inplace_log2();
02245 
02246     /**
02247     \brief  Compute the log base 10 of the elements of the matrix.
02248             Complex results if elements are negative. 
02249     \code
02250     Matrix A;
02251     A = "[10 1000]";
02252     if( !A.Inplace_log10() )
02253       return false;
02254     // A
02255     // 1 3
02256     \endcode
02257     
02258     \return true if successful, false otherwise.   
02259     */
02260     bool Inplace_log10();
02261 
02262     /**
02263     \brief  Create a matrix of nrows by ncols filled with 1.0.
02264 
02265     \code
02266     Matrix A;
02267     if( !A.Inplace_ones(2,3) )
02268       return false;
02269     // A
02270     // 1 1 1
02271     // 1 1 1
02272     \endcode
02273     
02274     \return true if successful, false otherwise.     
02275     */
02276     bool Inplace_ones( const unsigned nrows, const unsigned ncols );
02277 
02278     /**
02279     \brief  Real part of the complex matrix. z = x+yi. real(z) = x.
02280 
02281     \code
02282     Matrix A;
02283     A = "[2-2i -3+2i]";
02284     if( !A.Inplace_real() )
02285       return false;
02286     // A
02287     // 2  3
02288     \endcode
02289     
02290     \return true if successful, false otherwise.      
02291     */
02292     bool Inplace_real();
02293 
02294     /**
02295     \brief  Compute the sine of each element of the matrix inplace. This 
02296             function assumes radian values in the matrix.
02297     \code
02298     Matrix A;
02299     A = "[0         0.523598775598299           1.5707963267949]"; //[0 pi/6 pi/2]
02300     if( !A.Inplace_sin() )
02301       return false;
02302     // A
02303     // 0 0.5 1
02304     \endcode
02305     
02306     \return true if successful, false otherwise.      
02307     */
02308     bool Inplace_sin();
02309 
02310     /**
02311     \brief  Compute the sinc of each element*pi of the matrix inplace. 
02312     i.e. y = sin(pi*x)./(pi*x).
02313 
02314     \code
02315     Matrix A;
02316     A = "[0  0.523598775598299  1.5707963267949]"; //[0 pi/6 pi/2]
02317     if( !A.Inplace_sinc() )
02318       return false;
02319     // A
02320     // 1  0.606257160324575  -0.19765087483668
02321     \endcode
02322     
02323     \return true if successful, false otherwise.      
02324     */
02325     bool Inplace_sinc();
02326 
02327     /**
02328     \brief  Compute the hyperbolic sine of each element of the matrix inplace. This 
02329             function assumes radian values in the matrix.
02330     \code
02331     Matrix A;
02332     A = "[0 0.5 1]";
02333     if( !A.Inplace_sinh() )
02334       return false;
02335     // A
02336     // 0  0.521095305493747  1.1752011936438
02337     \endcode
02338     
02339     \return true if successful, false otherwise.     
02340     */
02341     bool Inplace_sinh();
02342 
02343     /**
02344     \brief  Compute the sqrt of each element of the matrix inplace.
02345 
02346     \code
02347     Matrix A;
02348     A = "[0 9 121]";
02349     if( !A.Inplace_sqrt() )
02350       return false;
02351     // A
02352     // 0  3  11
02353     \endcode
02354     
02355     \return true if successful, false otherwise.       
02356     */
02357     bool Inplace_sqrt();
02358 
02359     /**
02360     \brief  Compute the tangent of each element of the matrix inplace. This 
02361             function assumes radian values in the matrix.
02362     \code
02363     Matrix A;
02364     A = "[0  0.785398163397448  1.5707963267949]"; // [0 pi/4 pi/2]
02365     if( !A.Inplace_tan() )
02366       return false;
02367     // A
02368     // 0  1  1.63312393531954e+016
02369     \endcode
02370     
02371     \return true if successful, false otherwise.    
02372     */
02373     bool Inplace_tan();
02374 
02375     /**
02376     \brief  Compute the hyperbolic tangent of each element of the matrix inplace. This 
02377             function assumes radian values in the matrix.
02378     \code
02379     Matrix A;
02380     A = "[0  0.785398163397448  1.5707963267949]"; // [0 pi/4 pi/2]
02381     if( !A.Inplace_tanh() )
02382       return false;
02383     // A
02384     // 0  0.655794202632672  0.917152335667274
02385     \endcode
02386 
02387     \return true if successful, false otherwise.      
02388     */
02389     bool Inplace_tanh();
02390 
02391     /**
02392     \brief  Create a matrix of nrows by ncols filled with 0.0.
02393 
02394     \code
02395     Matrix A;
02396     if( !A.Inplace_zeros(2,3) )
02397       return false;
02398     // A
02399     // 0 0 0
02400     // 0 0 0
02401     \endcode
02402     
02403     \return true if successful, false otherwise.        
02404     */
02405     bool Inplace_zeros( const unsigned nrows, const unsigned ncols );
02406 
02407 
02408   public: // Statistics
02409 
02410     /**
02411     \brief  Computes the value of the largest absolute element and its index.
02412 
02413     \code
02414     Matrix A;
02415     unsigned row;
02416     unsigned col;
02417     double value;
02418     A = "[1 2 3 4 5]";
02419     if( !A.GetStats_MaxAbs( row, col, value ) )
02420       return false;
02421     // row   == 0
02422     // col   == 4
02423     // value == 5
02424     \endcode
02425     
02426     \return true if successful, false otherwise.
02427     */
02428     bool GetStats_MaxAbs(unsigned &row, unsigned &col, double &value );
02429 
02430     /**
02431     \brief  Computes the value (re+im*j) of the maximum element and its index.  
02432             When complex the maximum absolute value is determined.
02433     \code
02434     Matrix A;
02435     unsigned row;
02436     unsigned col;
02437     double re;
02438     double im;
02439     A = "[1 2 3 4 5-22i]";
02440     if( !A.GetStats_Max( row, col, re, im ) )
02441       return false;
02442     // row   == 0
02443     // col   == 4
02444     // re    == 5
02445     // im    == -22
02446     \endcode
02447     
02448     \return true if successful, false otherwise.
02449     */
02450     bool GetStats_Max(unsigned &row, unsigned &col, double &re, double &im );
02451 
02452     /**
02453     \brief  Computes the value (re+im*j) of the maximum element.  
02454             When complex the maximum absolute value is determined.
02455     \code
02456     Matrix A;
02457     double re;
02458     double im;
02459     A = "[1 2 3 4 5-22i]";
02460     if( !A.GetStats_MaxVal( re, im ) )
02461       return false;
02462     // re    == 5
02463     // im    == -22
02464     \endcode
02465 
02466     \return true if successful, false otherwise.
02467     */
02468     bool GetStats_MaxVal(double &re, double &im );
02469 
02470     /**
02471     \brief  Computes the value of the largest absolute column element and its row index.
02472     
02473     \code
02474     Matrix A;
02475     unsigned row;
02476     double value;
02477     A = "[1 2 3; 4 -5 6]";
02478     if( !A.GetStats_MaxAbsCol( 1, value, row ) )
02479       return false;
02480     // value == 5
02481     // row   == 1
02482     \endcode
02483 
02484     \return true if successful, false otherwise.
02485     */
02486     bool GetStats_MaxAbsCol(const unsigned col, double &value, unsigned &row );
02487 
02488     /**
02489     \brief  Computes the value (re+im*j) of the maximum column element and its row index.  
02490     \return true if successful, false otherwise.
02491     */
02492     bool GetStats_MaxCol(const unsigned col, double &re, double &im, unsigned &row );
02493 
02494     /**
02495     \brief  Computes the value (re+im*j) of the maximum column element.  
02496     \return true if successful, false otherwise.
02497     */
02498     bool GetStats_MaxColVal(const unsigned col, double &re, double &im );
02499 
02500     /**
02501     \brief  Computes the value of the largest absolute row element and its column index.
02502     \return true if successful, false otherwise.
02503     */
02504     bool GetStats_MaxAbsRow(const unsigned row, double &value, unsigned &col );
02505 
02506     /**
02507     \brief  Computes the value (re+im*j) of the maximum row element and its column index.  
02508     \return true if successful, false otherwise.
02509     */
02510     bool GetStats_MaxRow(const unsigned row, double &re, double &im, unsigned &col );
02511 
02512     /**
02513     \brief  Computes the value (re+im*j) of the maximum row element.  
02514     \return true if successful, false otherwise.
02515     */
02516     bool GetStats_MaxRowVal(const unsigned row, double &re, double &im );
02517 
02518     /**
02519     \brief  Computes the value of the smallest absolute element and its index.
02520     \return true if successful, false otherwise.
02521     */
02522     bool GetStats_MinAbs(unsigned &row, unsigned &col, double &value );
02523 
02524     /**
02525     \brief  Computes the value (re+im*j) of the minimum element and its index.  
02526     \return true if successful, false otherwise.
02527     */
02528     bool GetStats_Min(unsigned &row, unsigned &col, double &re, double &im );
02529 
02530     /**
02531     \brief  Computes the value (re+im*j) of the minimum element.  
02532     \return true if successful, false otherwise.
02533     */
02534     bool GetStats_MinVal(double &re, double &im );
02535 
02536     /**
02537     \brief  Computes the value of the smallest absolute column element and its row index.
02538     \return true if successful, false otherwise.
02539     */
02540     bool GetStats_MinAbsCol(const unsigned col, double &value, unsigned &row );
02541 
02542     /**
02543     \brief  Computes the value (re+im*j) of the minimum column element and its row index.  
02544     \return true if successful, false otherwise.
02545     */
02546     bool GetStats_MinCol(const unsigned col, double &re, double &im, unsigned &row );
02547 
02548     /**
02549     \brief  Computes the value (re+im*j) of the minimum column element.  
02550     \return true if successful, false otherwise.
02551     */
02552     bool GetStats_MinColVal(const unsigned col, double &re, double &im );
02553 
02554     /**
02555     \brief  Computes the value of the smallest absolute row element and its column index.
02556     \return true if successful, false otherwise.
02557     */
02558     bool GetStats_MinAbsRow(const unsigned row, double &value, unsigned &col );
02559 
02560     /**
02561     \brief  Computes the value (re+im*j) of the minimum row element and its column index.  
02562     \return true if successful, false otherwise.
02563     */
02564     bool GetStats_MinRow(const unsigned row, double &re, double &im, unsigned &col );
02565 
02566     /**
02567     \brief  Computes the value (re+im*j) of the minimum row element.  
02568     \return true if successful, false otherwise.
02569     */
02570     bool GetStats_MinRowVal(const unsigned row, double &re, double &im );
02571 
02572     /**
02573     \brief  Computes the range of the data in the specified column. 
02574     Range = MaxVal - MinVal.
02575     If the matrix is real, only the real value, re is set, im = 0. 
02576     If the matrix is complex, both re and im are set.
02577     \return true if successful, false otherwise.
02578     */
02579     bool GetStats_ColRange( const unsigned col, double &re, double &im );
02580 
02581     /**
02582     \brief  Computes the range of the data in the specified row. 
02583     Range = MaxVal - MinVal.
02584     If the matrix is real, only the real value, re is set, im = 0. 
02585     If the matrix is complex, both re and im are set.
02586     \return true if successful, false otherwise.
02587     */
02588     bool GetStats_RowRange( const unsigned row, double &re, double &im );
02589 
02590     /**
02591     \brief  Computes the range of the data in the matrix. 
02592     Range = MaxVal - MinVal.
02593     If the matrix is real, only the real value, re is set, im = 0. 
02594     If the matrix is complex, both re and im are set.
02595     \return true if successful, false otherwise.
02596     */
02597     bool GetStats_Range( double &re, double &im );
02598 
02599     /**
02600     \brief  Computes the sum for the specified column.
02601     If the matrix is real, only the real value, re is set, im = 0. 
02602     If the matrix is complex, both re and im are set.
02603     \return true if successful, false otherwise.
02604     */
02605     bool GetStats_ColumnSum( const unsigned col,  double &re, double &im );
02606 
02607     /**
02608     \brief  Computes the sum for the specified row.
02609     If the matrix is real, only the real value, re is set, im = 0. 
02610     If the matrix is complex, both re and im are set.
02611     \return true if successful, false otherwise.
02612     */
02613     bool GetStats_RowSum( const unsigned row, double &re, double &im );
02614 
02615     /**
02616     \brief  Computes the sum for the matrix.
02617     If the matrix is real, only the real value, re is set, im = 0. 
02618     If the matrix is complex, both re and im are set.
02619     \return true if successful, false otherwise.
02620     */
02621     bool GetStats_Sum( double &re, double &im );
02622 
02623     /**
02624     \brief  Computes the sample mean for the specified column.
02625     If the matrix is real, only the real value, re is set, im = 0. 
02626     If the matrix is complex, both re and im are set.
02627     \return true if successful, false otherwise.
02628     */
02629     bool GetStats_ColumnMean( const unsigned col, double &re, double &im );
02630 
02631     /**
02632     \brief  Computes the sample mean for the specified row.
02633     If the matrix is real, only the real value, re is set, im = 0. 
02634     If the matrix is complex, both re and im are set.
02635     \return true if successful, false otherwise.
02636     */
02637     bool GetStats_RowMean( const unsigned row, double &re, double &im );
02638 
02639     /**
02640     \brief  Computes the sample mean for the matrix.
02641     If the matrix is real, only the real value, re is set, im = 0. 
02642     If the matrix is complex, both re and im are set.
02643     \return true if successful, false otherwise.
02644     */
02645     bool GetStats_Mean( double &re, double &im );
02646 
02647     /**
02648     \brief  Computes the sample standard deviation for the specified column.
02649     \return true if successful, false otherwise.
02650     */
02651     bool GetStats_ColumnStdev( const unsigned col, double &value );
02652 
02653     /**
02654     \brief  Computes the sample standard deviation for the specified row.
02655     \return true if successful, false otherwise.
02656     */
02657     bool GetStats_RowStdev( const unsigned row, double &value );
02658 
02659     /**
02660     \brief  Computes the sample standard deviation for the matrix.
02661     \return true if successful, false otherwise.
02662     */
02663     bool GetStats_Stdev( double &value );
02664 
02665     /**
02666     \brief  Computes the sample variance for the specified column.
02667     \return true if successful, false otherwise.
02668     */
02669     bool GetStats_ColumnVar( const unsigned col, double &value );
02670 
02671     /**
02672     \brief  Computes the sample variance for the specified row.
02673     \return true if successful, false otherwise.
02674     */
02675     bool GetStats_RowVar( const unsigned row, double &value );
02676 
02677     /**
02678     \brief  Computes the sample variance for the matrix.
02679     \return true if successful, false otherwise.
02680     */
02681     bool GetStats_Var( double &value );
02682 
02683     /**
02684     \brief  Computes the norm of the specified column.
02685     If real, norm = sqrt( sum( val*val ) ).
02686     If complex, norm = sqrt( sum( val*conjugate(val) ) ).
02687     \return true if successful, false otherwise.
02688     */
02689     bool GetStats_ColumnNorm( const unsigned col, double &value );
02690 
02691     /**
02692     \brief  Computes the norm of the specified row.
02693     If real, norm = sqrt( sum( val*val ) ).
02694     If complex, norm = sqrt( sum( val*conjugate(val) ) ).
02695     \return true if successful, false otherwise.
02696     */
02697     bool GetStats_RowNorm( const unsigned row, double &value );
02698 
02699     /**
02700     \brief  Computes the norm of the matrix.
02701     If real, norm = sqrt( sum( val*val ) ).
02702     If complex, norm = sqrt( sum( val*conjugate(val) ) ).
02703     \return true if successful, false otherwise.
02704     */
02705     bool GetStats_Norm( double &value );
02706 
02707     /**
02708     \brief  Computes the sample RMS value for the specified column.
02709     \return true if successful, false otherwise.
02710     */
02711     bool GetStats_ColumnRMS( const unsigned col, double &value );
02712 
02713     /**
02714     \brief  Computes the sample RMS value for the specified row.
02715     \return true if successful, false otherwise.
02716     */
02717     bool GetStats_RowRMS( const unsigned row, double &value );
02718 
02719     /**
02720     \brief  Computes the sample RMS value for the matrix.
02721     \return true if successful, false otherwise.
02722     */
02723     bool GetStats_RMS( double &value );
02724 
02725 
02726     /**
02727     \brief  Computes the sample skewness value for the specified column.
02728     The skewness is the third central moment divided by the cube of the standard deviation.
02729     If the matrix is real, only the real value, re is set, im = 0. 
02730     If the matrix is complex, both re and im are set.
02731     \return true if successful, false otherwise.
02732     */
02733     bool GetStats_ColumnSkewness( const unsigned col, double &re, double &im );
02734 
02735     /**
02736     \brief  Computes the sample skewness value for the specified row.
02737     The skewness is the third central moment divided by the cube of the standard deviation.
02738     If the matrix is real, only the real value, re is set, im = 0. 
02739     If the matrix is complex, both re and im are set.
02740     \return true if successful, false otherwise.
02741     */
02742     bool GetStats_RowSkewness( const unsigned row, double &re, double &im );
02743 
02744     /**
02745     \brief  Computes the sample skewness value for the matrix.
02746     The skewness is the third central moment divided by the cube of the standard deviation.
02747     If the matrix is real, only the real value, re is set, im = 0. 
02748     If the matrix is complex, both re and im are set.
02749     \return true if successful, false otherwise.
02750     */
02751     bool GetStats_Skewness( double &re, double &im );
02752 
02753 
02754 
02755     /**
02756     \brief  Computes the sample kurtosis value for the specified column.
02757     The kurtosis is the fourth central moment divided by fourth power of the standard deviation.
02758     If the matrix is real, only the real value, re is set, im = 0. 
02759     If the matrix is complex, both re and im are set.
02760     To adjust the computed kurtosis value for bias, subtract 3 from the real component.
02761     Reference: http://en.wikipedia.org/wiki/Kurtosis.
02762     Reference: http://mathworld.wolfram.com/Kurtosis.html (kurtosis proper is computed).
02763     
02764     \return true if successful, false otherwise.
02765     */
02766     // g_2 = \frac{m_4}{m_{2}^2} = \frac{n\,\sum_{i=1}^n (x_i - \overline{x})^4}{\left(\sum_{i=1}^n (x_i - \overline{x})^2\right)^2}
02767     bool GetStats_ColumnKurtosis( const unsigned col, double &re, double &im );
02768 
02769     /**
02770     \brief  Computes the sample kurtosis value for the specified row.
02771     The kurtosis is the fourth central moment divided by fourth power of the standard deviation.
02772     If the matrix is real, only the real value, re is set, im = 0. 
02773     If the matrix is complex, both re and im are set.
02774     To adjust the computed kurtosis value for bias, subtract 3 from the real component.
02775     Reference: http://en.wikipedia.org/wiki/Kurtosis.
02776     Reference: http://mathworld.wolfram.com/Kurtosis.html (kurtosis proper is computed).
02777     
02778     \return true if successful, false otherwise.
02779     */
02780     // g_2 = \frac{m_4}{m_{2}^2} = \frac{n\,\sum_{i=1}^n (x_i - \overline{x})^4}{\left(\sum_{i=1}^n (x_i - \overline{x})^2\right)^2}
02781     bool GetStats_RowKurtosis( const unsigned row, double &re, double &im );
02782 
02783     /**
02784     \brief  Computes the sample kurtosis value for the matrix.
02785     The kurtosis is the fourth central moment divided by fourth power of the standard deviation.
02786     If the matrix is real, only the real value, re is set, im = 0. 
02787     If the matrix is complex, both re and im are set.
02788     To adjust the computed kurtosis value for bias, subtract 3 from the real component.
02789     Reference: http://en.wikipedia.org/wiki/Kurtosis.
02790     Reference: http://mathworld.wolfram.com/Kurtosis.html (kurtosis proper is computed).
02791     
02792     \return true if successful, false otherwise.
02793     */
02794     // g_2 = \frac{m_4}{m_{2}^2} = \frac{n\,\sum_{i=1}^n (x_i - \overline{x})^4}{\left(\sum_{i=1}^n (x_i - \overline{x})^2\right)^2}
02795     bool GetStats_Kurtosis( double &re, double &im );
02796 
02797 
02798   public: // Matrix Specific operations
02799 
02800     /**
02801     /// \brief  Computes the trace of M where M is a square matrix.
02802     /// Trace = Sum of diagonal elements.
02803     /// If the matrix is real, only the real value, re is set, im = 0. 
02804     /// If the matrix is complex, both re and im are set.
02805     /// \return true if successful, false otherwise.
02806     */
02807     bool GetTrace( double &re, double &im );
02808 
02809     /**
02810     /// \brief  Computes the determinatnt of the square matrix M.
02811     /// If the matrix is real, only the real value, re is set, im = 0. 
02812     /// If the matrix is complex, both re and im are set.
02813     */
02814     bool GetDeterminant( double &re, double &im );
02815 
02816 
02817 
02818   public: // Safe operations that set a Matrix argument. Rather than Matrix as a return type.
02819 
02820     /**
02821     /// \brief  Sets the diagonal elements of the matrix into DiagonalVector as a column vector.
02822     /// \return true if successful, false otherwise.
02823     */
02824     bool GetDiagonal( Matrix& DiagonalVector );
02825 
02826     /**
02827     /// \brief  Computes a moving average using N lead samples and M lagging samples
02828     /// for the specified column and stores it in MovAvg.
02829     /// \return true if successful, false otherwise.  
02830     */
02831     bool GetColumnMovAvg( const unsigned col, const unsigned lead, const unsigned lag, Matrix &MovAvg );
02832 
02833     /**
02834     /// \brief  Computes a moving average using N lead samples and M lagging samples
02835     /// for the matrix and stores it in MovAvg.
02836     /// \return true if successful, false otherwise.  
02837     */
02838     bool GetMovAvg( const unsigned lead, const unsigned lag, Matrix &MovAvg );
02839 
02840     /**
02841     /// \brief  Computes: InvATA = inverse( transpose(A) * A ). Assumes this matrix is A.
02842     /// e.g. Matrix A; Matrix InvATA; A = ...; bool result = A.GetATAInverse( InvATA );
02843     /// \return true if successful, false otherwise.  
02844     */
02845     bool GetATAInverse( Matrix &InvATA );
02846 
02847     /**
02848     /// \brief  LU factorization.
02849     /// Performs a factorization to produce a unit lower triangular matrix, L, 
02850     /// an upper triangular matrix, U, and permutation matrix P so that
02851     /// P*X = L*U.
02852     /// P, L and U are copmuted correctly if IsFullRank is set to true.
02853     /// e.g. Matrix A; A = ...; bool isFullRank, Matrix L,U,P; bool result = A.GetLUFactorization( isFullRank, P, L, U );
02854     /// \return true if successful, false otherwise.  
02855     */
02856     bool GetLUFactorization( bool &isFullRank, Matrix &P, Matrix &L, Matrix &U );
02857 
02858 
02859     /**
02860     /// \brief  Retrieve the elements of the matrix specified by the index vectors. 
02861     /// The index vectors must be nx1 and preferably not complex.
02862     ///
02863     /// \return true if successful, false otherwise.
02864     */
02865     bool GetIndexedValues( Matrix& RowIndex, Matrix& ColIndex, Matrix& Result );
02866 
02867 
02868     /**
02869     /// \brief  Set the elements of the matrix specified by the index vectors. 
02870     /// The index vectors must be nx1 and preferably not complex.
02871     ///
02872     /// \return true if successful, false otherwise.
02873     */
02874     bool SetIndexedValues( Matrix& RowIndex, Matrix& ColIndex, Matrix& SourceData );
02875 
02876 
02877     /*
02878     /// \brief  
02879     */
02880     //bool Find_EqualTo( const double value, const double tolerance = 1e-12, Matrix &IndexMatrix );     
02881 
02882     /**
02883     /// get the indices that are not this value
02884     */
02885     //bool Find_NotEqualTo( const double value, const double tolerance = 1e-12 );     
02886    
02887     /**
02888     /// get the indices less than this value
02889     */
02890     //bool Find_LessThan( const double value );     
02891    
02892     /**
02893     /// get the indices less than this value
02894     */
02895     //bool Find_MoreThan( const double value );     
02896     
02897 
02898     
02899 
02900   public: // Advanced Functionality
02901 
02902     /**
02903     \brief  Retrieve the matrix comment string. The string
02904     will be empty if none is available. The matrix comment string
02905     is often the header line read when using ReadFromFile(). \n
02906     e.g. file.txt has:
02907     time(s)   x(m)   y(m)
02908     1.0       20.0   30.0
02909     
02910     \code
02911     bool result;
02912     Matrix A;
02913     result = A.ReadFromFile("file.txt");
02914     // A == [1.0 20.0 30.0]
02915     std::string comment = A.GetMatrixComment();
02916     // comment == "time(s)   x(m)   y(m)"
02917     \endcode
02918     
02919     \return The matrix comment string.
02920     */
02921     std::string GetMatrixComment();
02922 
02923 
02924     /**
02925     \brief  Alter the matrix so that its data is within the startTime to the startTime+duration
02926             and compensate for any rollovers in the time system (e.g. GPS time in seconds rolls over
02927             at 604800.0 s). This function assumes that time is one of the matrix columns and requires
02928             this index, the timeColumn.
02929 
02930     \return true if successful, false otherwise.
02931     */
02932     bool TimeWindow( 
02933       const unsigned timeColumn, //!< The column containing time.
02934       const double startTime,    //!< The specified start time (inclusive).
02935       const double duration,     //!< The duration to include.
02936       const double rolloverTime  //!< The potential time at which system time rolls over.
02937       );
02938 
02939     /**
02940     \brief  Alter the matrix so that its data is within [startTime endTime].
02941             This function assumes that time is one of the matrix columns and requires
02942             this index, the timeColumn.
02943 
02944     \return true if successful, false otherwise.
02945     */
02946     bool TimeLimit( 
02947       const unsigned timeColumn, //!< The column containing time
02948       const double startTime,    //!< The specified start time (inclusive)
02949       const double endTime       //!< The duration to include
02950       );
02951 
02952     /**
02953     \brief  This static function matches matrices in time with specified precision
02954     where time is a column of each matrix. This function also
02955     allows time to rollover at a specified interval.
02956     
02957     precision 0 = match to whole number \n
02958     precision 1 = match to nearest 0.1 \n
02959     precision 2 = match to nearest 0.01 \n
02960     etc. \n
02961 
02962     rolloverTime examples \n
02963     GPS time of week (s): rolloverTime= 604800.0 \n
02964     hours               : rolloverTime = 24.0 \n
02965     minutes             : rolloverTime = 60.0 \n
02966     
02967     The time data must be non-decreasing but the time may rollover
02968     by the specified amount. 
02969     e.g. rolloverTime = 60.0 \n
02970          0,1,2,3,4,...59,60,1,2,5,10,60,1,2,3... \n
02971     
02972     This function may be called by: bool result = Matrix::TimeMatch( ... );
02973 
02974     \return true if successful, false otherwise.
02975     */
02976     static bool TimeMatch( 
02977       Matrix &A,                   //!< The matrix with interpolation times
02978       const unsigned timeColumnA,  //!< The zero based column index for matrix A
02979       Matrix &B,                   //!< The matrix to be interpolated
02980       const unsigned timeColumnB,  //!< The zero based column index for matrix B
02981       const unsigned precision,    //!< The rounding precision used for time matching, 0 = whole, 1 = 0.1, 2 = 0.01, etc
02982       const double rolloverTime    //!< The rollover time, e.g. 60 s for minute based timing, 0.0 means rollovers not allowed
02983       );
02984 
02985     /**
02986     \brief  This static function interpolates Matrix B values by the times defined 
02987             in the column in Matrix A. Time must be increasing but times can 
02988             rollover with the specified rolloverTime.
02989     
02990     This function returns A and B with the same number of rows and 
02991     time aligned time columns.
02992     
02993     This function may be called by: bool result = Matrix::Interpolate( ... );
02994 
02995     \return true if successful, false otherwise.
02996     */
02997     static bool Interpolate( 
02998       Matrix &A,                    //!< The matrix with interpolation times
02999       const unsigned timeColumnA,   //!< The zero based column index for matrix A
03000       Matrix &B,                    //!< The matrix to be interpolated
03001       const unsigned timeColumnB,   //!< The zero based column index for matrix B
03002       const double maxInterpolationInterval, //!< The largest interpolation interval allowed
03003       const double rolloverTime     //!< The rollover time, e.g. 60 s for minute based timing, 0.0 means rollovers not allowed
03004       );
03005 
03006 
03007   public: // Functions that return a Matrix
03008 
03009     /**
03010     \brief  Return the column matrix specified by the column index. Returns (nrows x 1).
03011     */
03012     Matrix  Column(const unsigned col);
03013 
03014     /**
03015     \brief  Return the row matrix specified by the column index. Returns (ncols x 1).
03016     */
03017     Matrix  Row(const unsigned row);
03018 
03019     /**
03020     \brief  Return the tranpose of the matrix.
03021     */
03022     Matrix  Transpose();
03023 
03024     /**
03025     \brief  Return the tranpose of the matrix.
03026     */
03027     Matrix  T(); // short version
03028 
03029     /**
03030     \brief  Return the diagonal of the matrix as a vector.
03031     */
03032     Matrix  Diagonal();
03033 
03034     /**
03035     \brief  Return the inverse of the matrix.
03036     */
03037     Matrix  Inverse();
03038     
03039     /**
03040     \brief  Return the inverse of the matrix.
03041     */
03042     Matrix  Inv(); // short version
03043 
03044 
03045     /**
03046     \brief  Return the Fourier Transform of each column of the matrix. 
03047             Power of two uses FFT, otherwise fast DFT.
03048     */
03049     Matrix  FFT();
03050 
03051     /**
03052     \brief  Return the inverse Fourier Transform of each column of the matrix. 
03053             Power of two uses IFFT, otherwise fast IDFT.
03054     */
03055     Matrix  IFFT();
03056 
03057 
03058   public:
03059 
03060     /**
03061     \brief  This is a nested class that is an element of the matrix. i.e. Matrix M; M(i,j) is the element. 
03062             It is used for operator(,) access by the Matrix.
03063     */
03064     class Element
03065     {
03066     public:
03067 
03068       /// \brief  The only constructor binds the reference to the deep level matrix.
03069       /// The row and column members are set later.
03070       Element(MTX& mtx);
03071 
03072       /// \brief  The destructor.
03073       virtual ~Element();
03074 
03075     private:
03076       friend class Matrix; //!< The matrix class is a friend.
03077 
03078       MTX& m_mtx;     //!< The reference to the deep level matrix.
03079       unsigned m_row; //!< The corresponding row of this element in the matrix.
03080       unsigned m_col; //!< The corresponding column of this element in the matrix.
03081 
03082     public:
03083 
03084       const double real(); //!< Get the real part.
03085       const double imag(); //!< Get the imaginary part.
03086       
03087       /// \brief  The operator overload for setting the matrix element from a double.
03088       const Element& operator= (double v);
03089 
03090       /// \brief  The operator overload for setting the matrix element from a std::complex.
03091       const Element& operator= (std::complex<double> v);
03092 
03093       /// \brief  The operator overload for setting the matrix element from another the matrix element.
03094       const Element& operator= (Element v);
03095 
03096       /// \brief  This operator allows explict conversion to a std::complex.
03097       operator const std::complex<double>() const;
03098 
03099       void operator+= (const double scalar);            //!< \brief  Add a scalar inplace. 
03100       void operator+= (const std::complex<double>& v);  //!< \brief  Add a complex value inplace. 
03101       void operator+= (const Element& v);               //!< \brief  Add a Element inplace. 
03102       void operator-= (const double scalar);            //!< \brief  Subtract a scalar inplace. 
03103       void operator-= (const std::complex<double>& v);  //!< \brief  Subtract a complex value inplace. 
03104       void operator-= (const Element& v);               //!< \brief  Subtract a Element inplace. 
03105       void operator*= (const double scalar);            //!< \brief  Multiply a scalar inplace. 
03106       void operator*= (const std::complex<double>& v);  //!< \brief  Multiply a complex value inplace. 
03107       void operator*= (const Element& v);               //!< \brief  Multiply a Element inplace. 
03108       void operator/= (const double scalar);            //!< \brief  Divide a scalar inplace. 
03109       void operator/= (const std::complex<double>& v);  //!< \brief  Divide a complex value inplace. 
03110       void operator/= (const Element& v);               //!< \brief  Divide a Element inplace. 
03111       
03112       /// \brief  The operator overload for adding a double to an element.
03113       friend const std::complex<double> operator+ (const Element& m, double scalar);
03114 
03115       /// \brief  The operator overload for adding an element to an element.
03116       friend const std::complex<double> operator+ (const Element& a, const Element& b);
03117 
03118       /// \brief  The operator overload for adding an element to an complex.
03119       friend const std::complex<double> operator+ (const Element& a, const std::complex<double>& b);
03120 
03121       /// \brief  The operator overload for adding an element and a double.
03122       friend const std::complex<double> operator+ (double scalar, const Element& m);
03123 
03124       /// \brief  The operator overload for adding a complex and an element
03125       friend const std::complex<double> operator+ (const std::complex<double>& b, const Element& a);
03126 
03127 
03128       /// \brief  The operator overload for subtracting a double from an element.
03129       friend const std::complex<double> operator- (const Element& m, double scalar);
03130       
03131       /// \brief  The operator overload for subtracting an element from an element.
03132       friend const std::complex<double> operator- (const Element& a, const Element& b);
03133 
03134       /// \brief  The operator overload for subtracting an complex from an element.
03135       friend const std::complex<double> operator- (const Element& a, const std::complex<double>& b);
03136 
03137       /// \brief  The operator overload for subtracting an element from a double.
03138       friend const std::complex<double> operator- (double scalar, const Element& m);
03139 
03140       /// \brief  The operator overload for subtracting an element from a complex.
03141       friend const std::complex<double> operator- (const std::complex<double>& b, const Element& a);
03142 
03143 
03144       /// \brief  The operator overload for multiplying an element and a double.
03145       friend const std::complex<double> operator* (const Element& m, double scalar);
03146       
03147       /// \brief  The operator overload for multiplying an element and an element.
03148       friend const std::complex<double> operator* (const Element& a, const Element& b);
03149 
03150       /// \brief  The operator overload for multiplying an element and a complex.
03151       friend const std::complex<double> operator* (const Element& a, const std::complex<double>& b);
03152 
03153       /// \brief  The operator overload for multiplying a double and an element.
03154       friend const std::complex<double> operator* (double scalar, const Element& m);
03155       
03156       /// \brief  The operator overload for multiplying a complex and an element.
03157       friend const std::complex<double> operator* (const std::complex<double>& b, const Element& a);
03158 
03159 
03160       /// \brief  The operator overload for dividing an element by a double.
03161       friend const std::complex<double> operator/ (const Element& m, double scalar);
03162 
03163       /// \brief  The operator overload for dividing an element by an element.
03164       friend const std::complex<double> operator/ (const Element& a, const Element& b);
03165 
03166       /// \brief  The operator overload for dividing an element by an complex.
03167       friend const std::complex<double> operator/ (const Element& a, const std::complex<double>& b);
03168 
03169       /// \brief  The operator overload for dividing a double by an element.
03170       friend const std::complex<double> operator/ (double scalar, const Element& m);
03171 
03172       /// \brief  The operator overload for dividing a complex by an element.
03173       friend const std::complex<double> operator/ (const std::complex<double>& b, const Element& a);
03174 
03175 
03176       /// \brief  The operator overload for testing equality between an element and a double.
03177       friend const bool operator== (const Element& m, double scalar);
03178       
03179       /// \brief  The operator overload for testing equality between an element and an element.
03180       friend const bool operator== (const Element& a, const Element& b);
03181 
03182       /// \brief  The operator overload for testing equality between an element and a complex.
03183       friend const bool operator== (const Element& a, const std::complex<double>& b);
03184 
03185       /// \brief  The operator overload for testing equality between a double and an element.
03186       friend const bool operator== (double scalar, const Element& m);
03187       
03188       /// \brief  The operator overload for testing equality between a complex and an element.
03189       friend const bool operator== (const std::complex<double>& b, const Element& a);
03190 
03191     };
03192 
03193 
03194   public: // Operator Overloads      
03195 
03196     /// \brief  Get a reference to an element in the matrix to set or get its value.
03197     Element& operator() (unsigned row, unsigned col);
03198 
03199     /// \brief  Get a reference to an element in the matrix as a column or row vector to set or get its value.
03200     /// This can be used to access a matrix of (col,row), col = index/nrows, row = index/ncols. 
03201     /// Matrix A(10); // The matrix is real with dimensions 10x1
03202     /// A(0) = 10.0;  // The matrix is real.
03203     /// stComplex cplx = {1.0,2.0};
03204     /// A(1) = cplx;  // The matrix is now complex with dimensions 10x1.
03205     Element& operator() (unsigned index);
03206 
03207 
03208     bool operator+= (const int    scalar) { return (*this)+=(double)scalar; } //!< add a scaler int     (shorthand notation: A += 5).
03209     bool operator+= (const float  scalar) { return (*this)+=(double)scalar; } //!< add a scaler float   (shorthand notation: A += 5).
03210     bool operator+= (const double scalar);                                    //!< add a scaler double  (shorthand notation: A += 5).
03211     bool operator+= (const std::complex<double> cplx);                        //!< add a scaler complex (shorthand notation: A += (5+2i)).
03212 
03213     bool operator-= (const int    scalar) { return (*this)-=(double)scalar; } //!< subtract a scaler int     (shorthand notation: A -= 5).
03214     bool operator-= (const float  scalar) { return (*this)-=(double)scalar; } //!< subtract a scaler float   (shorthand notation: A -= 5).
03215     bool operator-= (const double scalar);                                    //!< subtract a scaler double  (shorthand notation: A -= 5).
03216     bool operator-= (const std::complex<double> cplx);                        //!< subtract a scaler complex (shorthand notation: A -= (5+2i)).
03217 
03218     bool operator*= (const int    scalar) { return (*this)*=(double)scalar; } //!< multiply a scalar int     (shorthand notation: A *= 5).
03219     bool operator*= (const float  scalar) { return (*this)*=(double)scalar; } //!< multiply a scalar float   (shorthand notation: A *= 5).
03220     bool operator*= (const double scalar);                                    //!< multiply a scalar double  (shorthand notation: A *= 5).
03221     bool operator*= (const std::complex<double> cplx);                        //!< multiply a scaler complex (shorthand notation: A *= (5+2i)).
03222 
03223     bool operator/= (const int    scalar) { return (*this)/=(double)scalar; } //!< divide a scalar int     (shorthand notation: A /= 5).
03224     bool operator/= (const float  scalar) { return (*this)/=(double)scalar; } //!< divide a scalar float   (shorthand notation: A /= 5).
03225     bool operator/= (const double scalar);                                    //!< divide a scalar double  (shorthand notation: A /= 5).
03226     bool operator/= (const std::complex<double> cplx);                        //!< divide a scaler complex (shorthand notation: A /= (5+2i)).
03227 
03228     bool operator+= (const Matrix& mat);  //!< add a matrix      (shorthand notation: A += B).   
03229     bool operator-= (const Matrix& mat);  //!< subtract a matrix (shorthand notation: A -= B).
03230 
03231     /// \brief  The postfix ++ operator overload.
03232     /// Add +1.0 to all elements and returns matrix values after the increment, e.g. Matrix B = A++.
03233     /// Use Inplace_Increment for a boolean return for safer operation.
03234     friend Matrix operator++ (Matrix& mat, int);
03235 
03236     /// \brief  The postfix -- operator overload.
03237     /// Subtract 1.0 to all elements and returns matrix values after the increment, e.g. Matrix B = A--.
03238     /// Use Inplace_Decrement for a boolean return for safer operation.  
03239     friend Matrix operator-- (Matrix& mat, int);
03240 
03241     /// \brief  Multiply two matrices and copy the result. Result = mat1 * mat2.
03242     friend Matrix operator* (const Matrix& mat1, const Matrix& mat2); 
03243 
03244     /// \brief  Multiply two matrices and copy the result. Result = mat1 * mat2.
03245     friend Matrix operator* (Matrix& mat1, Matrix& mat2); 
03246 
03247     /// \brief  Add two matrices and copy the result. Result = mat1 + mat2.
03248     friend Matrix operator+ (Matrix& mat1, Matrix& mat2);
03249     
03250     /// \brief  Add two matrices and copy the result. Result = mat1 + mat2.
03251     friend Matrix operator+ (const Matrix& mat1, const Matrix& mat2);
03252 
03253     /// \brief  Subtract two matrices and copy the result. Result = mat1 - mat2.
03254     friend Matrix operator- (Matrix& mat1, Matrix& mat2); 
03255     
03256     /// \brief  Subtract two matrices and copy the result. Result = mat1 - mat2.
03257     friend Matrix operator- (const Matrix& mat1, const Matrix& mat2); 
03258 
03259 
03260     /// \brief  Raise all matrix elements to the power scalar.
03261     friend Matrix operator^ (Matrix& mat, const int scalar)     { return mat^( (double)scalar ); }
03262 
03263     /// \brief  Raise all matrix elements to the power scalar.
03264     friend Matrix operator^ (Matrix& mat, const float scalar)   { return mat^( (double)scalar ); }
03265 
03266     /// \brief  Raise all matrix elements to the power scalar.
03267     friend Matrix operator^ (Matrix& mat, const double scalar);
03268 
03269     /// \brief  Add to a matrix by a scalar variable: ie. A = 2.0 + B and B + 2.0 (adds to 2.0 to all elements).
03270     friend Matrix operator+ (const double scalar, Matrix& mat);
03271     friend Matrix operator+ (Matrix& mat, const int    scalar)  { return ((double)scalar) + mat; }
03272     friend Matrix operator+ (Matrix& mat, const float  scalar)  { return ((double)scalar) + mat; }
03273     friend Matrix operator+ (Matrix& mat, const double scalar)  { return scalar + mat;           }
03274     friend Matrix operator+ (const int    scalar, Matrix& mat)  { return ((double)scalar) + mat; }
03275     friend Matrix operator+ (const float  scalar, Matrix& mat)  { return ((double)scalar) + mat; }
03276 
03277     /// \brief  Subtract from a matrix by a scalar variable: ie. A = B - 2.0.
03278     friend Matrix operator- (Matrix& mat, const double scalar)  { return mat + (-1.0*scalar);         }
03279     friend Matrix operator- (Matrix& mat, const int    scalar)  { return mat + (-1.0*(double)scalar); }
03280     friend Matrix operator- (Matrix& mat, const float  scalar)  { return mat + (-1.0*(double)scalar); }
03281 
03282     /// \brief  Subtract a matrix from a scalar variable: ie. A = 2.0 - B == -B + 2.0
03283     friend Matrix operator- (const double scalar, Matrix& mat);
03284     friend Matrix operator- (const int    scalar, Matrix& mat)  { return mat - ((double)scalar); }
03285     friend Matrix operator- (const float  scalar, Matrix& mat)  { return mat - ((double)scalar); }
03286 
03287     /// \brief  Multiply matrix by a scalar variable: A = 2.0 * B and A = B * 2.0.
03288     friend Matrix operator* (const double scalar, Matrix& mat);
03289     friend Matrix operator* (Matrix& mat, const int    scalar)  { return (((double)scalar) * mat); }
03290     friend Matrix operator* (Matrix& mat, const float  scalar)  { return (((double)scalar) * mat); }
03291     friend Matrix operator* (Matrix& mat, const double scalar)  { return (scalar * mat);           }
03292     friend Matrix operator* (const int    scalar, Matrix& mat)  { return (((double)scalar) * mat); }
03293     friend Matrix operator* (const float  scalar, Matrix& mat)  { return (((double)scalar) * mat); }   
03294 
03295     /// \brief  Divide matrix by a scalar variable: A = B / 2.0.
03296     friend Matrix operator/ (Matrix& mat, const double scalar);
03297     friend Matrix operator/ (Matrix& mat, const int    scalar)  { return mat / ((double)scalar); }
03298     friend Matrix operator/ (Matrix& mat, const float  scalar)  { return mat / ((double)scalar); }
03299 
03300     /// \brief  Divide matrix into a scalar variable: A = 2.0 / B. e.g. A = [2.0 2.0; 2.0 2.0] / B, B is 2x2.
03301     friend Matrix operator/ (const double scalar, Matrix& mat);
03302     friend Matrix operator/ (const int    scalar, Matrix& mat)  { return ((double)scalar) / mat; }
03303     friend Matrix operator/ (const float  scalar, Matrix& mat)  { return ((double)scalar) / mat; }
03304 
03305 
03306     // Accessing matrix data as real only:
03307     // The matrix can be accessed using the square bracket operators.
03308     // e.g. Matrix A(2,2); double b = A[0][0]; A[0][1] = 10.0; A[0][1] = -10.0;
03309   public:
03310 
03311     /// \brief  A nested class for access only to the real part of the matrix. 
03312     /// It is used for operator[] access by the Matrix.    
03313     ///
03314     /// Sequential [][] operators can be used to access the matrix. The
03315     /// first overload of [] is at the Matrix level. This returns a copy of 
03316     /// a RealOnlyAccess and the second overload of [] allows access to the 
03317     /// required element from the matrix.
03318     ///
03319     /// For matrices that are always real. This method of accessing each element
03320     /// is the most efficient.
03321     class RealOnlyAccess
03322     {
03323     public:
03324 
03325       /// \brief  Set or get an element value.
03326       double& operator [] (const unsigned col);
03327 
03328       /// \brief  The matrix is a friend class.
03329       friend class Matrix;
03330 
03331       /// \brief  The only constructor.
03332       RealOnlyAccess( MTX& pMatrix, const unsigned row );
03333 
03334       /// \brief  The destructor.
03335       virtual ~RealOnlyAccess();
03336 
03337       /// \brief  The assignment operator from a double for single index operations. 
03338       RealOnlyAccess& operator=(const double value);
03339 
03340       /// \brief  The assignment operator from another RealOnlyAccess object for single index operations.
03341       RealOnlyAccess& operator=(RealOnlyAccess& rhs);
03342 
03343       /// \brief  The assignment operator from a MatrixElement object for single index operations.
03344       RealOnlyAccess& operator=(Element& rhs);
03345 
03346       /// \brief  The casting operator overload for double.
03347       operator const double();
03348       
03349     public: // operator overloads
03350 
03351       bool operator+= (const int    scalar) { return (*this)+=(double)scalar; } //!< add a scaler int     (shorthand notation: A[0] += 5).
03352       bool operator+= (const float  scalar) { return (*this)+=(double)scalar; } //!< add a scaler float   (shorthand notation: A[0] += 5).
03353       bool operator+= (const double scalar);                                    //!< add a scaler double  (shorthand notation: A[0] += 5).
03354 
03355       bool operator-= (const int    scalar) { return (*this)-=(double)scalar; } //!< subtract a scaler int     (shorthand notation: A[0] -= 5).
03356       bool operator-= (const float  scalar) { return (*this)-=(double)scalar; } //!< subtract a scaler float   (shorthand notation: A[0] -= 5).
03357       bool operator-= (const double scalar);                                    //!< subtract a scaler double  (shorthand notation: A[0] -= 5).
03358 
03359       bool operator*= (const int    scalar) { return (*this)*=(double)scalar; } //!< multiply a scalar int     (shorthand notation: A[0] *= 5).
03360       bool operator*= (const float  scalar) { return (*this)*=(double)scalar; } //!< multiply a scalar float   (shorthand notation: A[0] *= 5).
03361       bool operator*= (const double scalar);                                    //!< multiply a scalar double  (shorthand notation: A[0] *= 5).
03362 
03363       bool operator/= (const int    scalar) { return (*this)/=(double)scalar; } //!< divide a scalar int     (shorthand notation: A[0] /= 5).
03364       bool operator/= (const float  scalar) { return (*this)/=(double)scalar; } //!< divide a scalar float   (shorthand notation: A[0] /= 5).
03365       bool operator/= (const double scalar);                                    //!< divide a scalar double  (shorthand notation: A[0] /= 5).
03366       
03367     private:
03368       /// \brief  Check the specified indices. Throw an exception if they are invalid.
03369       /// \return true if valid, false otherwise. 
03370       bool IndexCheck( const unsigned row, const unsigned col );
03371 
03372       /// \brief  Check the specified index into the Matrix as a vector. 
03373       ///         Throw an exception if the index is invalid.
03374       /// \return true if valid, false otherwise. 
03375       bool IndexCheck( const unsigned index );
03376 
03377       MTX& m_Matrix;   //!< The reference to the source matrix.    
03378       unsigned m_row;  //!< The current row to access.
03379     };
03380 
03381     /// \brief  Retrieve a copy of a RealOnlyAccess object which is then used for the second [] overload.
03382     RealOnlyAccess operator[] (const unsigned row); 
03383 
03384   public: // functions for error handling.
03385 
03386     /// \brief  Clear the matrix from memory and handle the error message.
03387     void MatrixError( const char* error );
03388 
03389     /// \brief  Clear the matrix from memory and handle the error message.
03390     void MatrixError( const char* function, const char* error );
03391 
03392     /// \brief  A static function to handle the error message.
03393     static void StaticMatrixError( const char* error );
03394 
03395     /// \brief  A static function to handle the error message.
03396     static void StaticMatrixError( const char* function, const char* error );
03397 
03398 
03399   protected:
03400 
03401     /// \brief  Check the specified indices. Throw an exception if they are invalid.
03402     /// \return true if valid, false otherwise. return code should not be reached!
03403     bool IndexCheck( const unsigned row, const unsigned col );
03404 
03405     /// \brief  Check the specified index into the Matrix as a vector. 
03406     ///         Throw an exception if the index is invalid.
03407     /// \return true if valid, false otherwise. return code should not be reached!    
03408     bool IndexCheck( const unsigned index );
03409 
03410     /// \brief  A single element from the matrix. This is used for write access with operator().
03411     Element m_MatrixElement;
03412 
03413     /// \brief  The deep level matrix container.
03414     MTX m_Matrix;
03415 
03416     /// \brief  This indicates if the mtx core engine been initialized.
03417     static bool m_IsMTXInitialized; 
03418   };
03419 
03420 } // end namespace Zenautics
03421 
03422 #endif // _ZENAUTICS_MATRIX_H_
03423