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     2008-09-22
00006 \version  0.06 Beta
00007 
00008 \b Version \b Information \n
00009 This is the open source version (BSD license). The Professional Version
00010 is avaiable via http://www.zenautics.com. The Professional Version
00011 is highly optimized using SIMD and includes optimization for multi-core 
00012 processors.
00013 
00014 \b License \b Information \n
00015 Copyright (c) 2008, Glenn D. MacGougan, Zenautics Technologies Inc. \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 \b Preprocessor Defines \n
00048 #define _MATRIX_NO_EXCEPTION // removes exception handling support. \n
00049 */
00050 
00051 #ifndef _ZENAUTICS_MATRIX_H_
00052 #define _ZENAUTICS_MATRIX_H_
00053 
00054 #include <complex> // For std::complex<double> (Standard Template Library)
00055 #include <string>  // For std::string (Standard Template Library)
00056 #include "cmatrix.h" // The core matrix engine is written in 'c'.
00057 
00058 //#define _MATRIX_NO_EXCEPTION // removes exception handling support if required.
00059 
00060 
00061 namespace Zenautics
00062 {
00063 
00064 #ifndef _MATRIX_NO_EXCEPTION
00065   /**
00066   \class   MatrixException
00067   \brief   A class for exceptions thrown by the Matrix class.  
00068   
00069   The MATRIX_USE_EXCEPTION_HANDLING define enables the use of exception 
00070   handling using try{} catch{}. A MatrixException is thrown. The use of 
00071   exception handling is very highly recommended. When it is turned off, 
00072   the matrix will try to output a message and then call 'exit(1)'.
00073   
00074   \code
00075   int main()
00076   { 
00077     try
00078     {
00079       Matrix A(2,2);
00080       double d = A(3,1).real(); // causes an out of bounds exception
00081     }
00082     catch( MatrixException& matrix_exception )
00083     {
00084       cout << matrix_exception << endl;
00085     }
00086     catch ( ... )
00087     {
00088       cout << "Caught unknown exception" << endl;
00089     }
00090     return 0;
00091   }
00092   \endcode
00093   */
00094   class MatrixException
00095   {  
00096   public: 
00097     /// \brief  The constructor.
00098     MatrixException( const char* msg );
00099 
00100     /// \brief  The copy constructor.
00101     MatrixException(const MatrixException& matrix_exception);
00102 
00103     /// \brief  The destuctor.
00104     virtual ~MatrixException() { /* nothing needed yet */ };
00105 
00106     /// \brief  Return a copy of the exception message.
00107     std::string GetExceptionMessage();
00108 
00109     /// \brief  Overload the casting operator to a string.
00110     operator const char*();
00111 
00112   public:
00113     /// \brief  The matrix exception string.  
00114     std::string m_ExceptionString;
00115 
00116   private:
00117     /// \brief  The matrix exception character string.  
00118     char m_msg[256];    
00119   };
00120 #endif
00121 
00122 
00123   /**
00124   \class   Matrix
00125   \brief   The matrix/vector class. 
00126            Both real and complex data are inherently supported.
00127            One and two dimensional data.
00128   
00129   The matrix class supports advanced real and complex functionality. It is
00130   optimized for columnwise operations. Refer to example_main.cpp for a 
00131   complete example program using the Matrix.
00132   */
00133   class Matrix
00134   {  
00135   public: // Constructors / Destructor
00136 
00137     /// \brief  This function enables or disables a global flag
00138     ///         that forces single element matrices to be treated
00139     ///         as scalars. This is enabled by default. 
00140     static void Treat1x1MatricesAsScalar( bool enable = true );
00141 
00142     /// \brief  The default constructor (no data allocated yet).
00143     Matrix();                                             
00144 
00145     /// \brief  A vector style constructor.
00146     ///
00147     /// Matrix A(nrows);  creates an nrowsx1 real 'vector'.
00148     /// A complex vector must be created using Matrix A(nrows,ncols,false);
00149     explicit Matrix(const unsigned nrows);
00150 
00151     /// \brief  A matrix style constructor.
00152     ///
00153     /// Matrix A(nrows,ncols); creates an nrowsxncols real 'matrix'. A real matrix is assumed.
00154     /// Matrix A(nrows,ncols,false); creates an nrowsxncols complex 'matrix'. A real matrix is assumed.
00155     Matrix(const unsigned nrows, const unsigned ncols, const bool isReal=true);
00156 
00157     /// \brief  The copy constructor.
00158     Matrix(const Matrix& mat);                          
00159 
00160     /// \brief  A constructor reading data from a file.
00161     Matrix(const char* path, bool& itWorked);
00162 
00163     /** \brief  A constructor initialized the matrix from a string.
00164 
00165     There are two general possible interpretations of the string input. \n
00166     
00167     (1) Square bracket delimited matrix. e.g. \n
00168     
00169     \code
00170     Matrix A = "[1 2 3; 4 5 6]"; // or 
00171     Matrix A = "[1, 2, 3; 4, 5, 6]";
00172     \endcode
00173 
00174     In this case '[' donates the start of a matrix and ']' denotes the end. \n
00175     Row vectors [1 2 3] and [4 5 6] are separated by ';'.  \n
00176     Commas can delimit row vector data but are not needed. \n
00177     Complex input: e.g. 
00178     
00179     \code
00180     Matrix A = "[1+1i 2+3j 1-2i; 4 5 6]"; // or
00181     Matrix A = "[1+1i, 2+3j, 1-2i; 4, 5, 6]";
00182     \endcode
00183     
00184     (2) Free form delimited matrix. e.g. \n
00185 
00186     \code
00187     Matrix A = "1 2 3 \\n 4 5 6 \\n";
00188     \endcode
00189 
00190     In this case, the newline delimits different rows of the matrix. (\\r\\n also works). \n
00191     Row vectors can still be delimited by ';' as well. \n
00192     
00193     \code
00194     Matrix B = "1 2 3; 4 5 6; \\n 7 8 9";
00195     \endcode 
00196     
00197     will set a 3x3 matrix == [1 2 3; 4 5 6; 7 8 9]. \n
00198 
00199     Commas can delimit row vector data but are not needed. \n
00200     Complex input: e.g. 
00201     
00202     \code
00203     Matrix A = "[1+1i 2+3j 1-2i\\n 4 5 6]";   // or
00204     Matrix A = "1+1i, 2+3j, 1-2i\\n 4, 5, 6"; // or
00205     Matrix A = "1+1i 2+3j 1-2i; 4, 5, 6";   
00206     \endcode 
00207 
00208     All result in A = [1+1i 2+3i 1-2i; 4 5 6]; \n
00209     */
00210     Matrix(const char* strMatrix);
00211 
00212     /// \brief  The constructor as a copy from a static matrix.
00213     Matrix(const double mat[], const unsigned nrows, const unsigned ncols=1 ); 
00214 
00215     /// \brief  The destructor.
00216     virtual ~Matrix();
00217 
00218     /// \brief  The assignment operator from another matrix.
00219     ///
00220     /// 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)
00221     Matrix& operator=(const Matrix& mat);
00222 
00223     /// \brief  The assignment operator from a scalar double value.
00224     ///
00225     /// e.g. Matrix A; A = 2.0; // A is (1x1).
00226     Matrix& operator=(const double value);
00227 
00228     
00229     /// \brief  The assignment operator from a std::complex<double> value.
00230     ///
00231     /// e.g. Matrix A; A = 2.0; // A is (1x1).
00232     Matrix& operator=(const std::complex<double> value);
00233 
00234     /**
00235     \brief  The assignement operator from a string matrix.   
00236     
00237     There are two general possible interpretations of the string input. \n
00238     
00239     (1) Square bracket delimited matrix. e.g. \n
00240     
00241     \code
00242     Matrix A;
00243     A = "[1 2 3; 4 5 6]"; // or 
00244     A = "[1, 2, 3; 4, 5, 6]";
00245     \endcode
00246 
00247     In this case '[' donates the start of a matrix and ']' denotes the end. \n
00248     Row vectors [1 2 3] and [4 5 6] are separated by ';'.  \n
00249     Commas can delimit row vector data but are not needed. \n
00250     Complex input: e.g. 
00251     
00252     \code
00253     Matrix A;
00254     A = "[1+1i 2+3j 1-2i; 4 5 6]"; // or
00255     A = "[1+1i, 2+3j, 1-2i; 4, 5, 6]";
00256     \endcode
00257     
00258     (2) Free form delimited matrix. e.g. \n
00259 
00260     \code
00261     Matrix A; 
00262     A = "1 2 3 \\n 4 5 6 \\n";
00263     \endcode
00264 
00265     In this case, the newline delimits different rows of the matrix. (\\r\\n also works). \n
00266     Row vectors can still be delimited by ';' as well. \n
00267     
00268     \code
00269     B = "1 2 3; 4 5 6; \\n 7 8 9";
00270     \endcode 
00271     
00272     will set a 3x3 matrix == [1 2 3; 4 5 6; 7 8 9]. \n
00273 
00274     Commas can delimit row vector data but are not needed. \n
00275     Complex input: e.g. 
00276     
00277     \code
00278     Matrix A;
00279     A = "[1+1i 2+3j 1-2i\\n 4 5 6]";   // or
00280     A = "1+1i, 2+3j, 1-2i\\n 4, 5, 6"; // or
00281     A = "1+1i 2+3j 1-2i; 4, 5, 6";   
00282     \endcode 
00283 
00284     All result in A = [1+1i 2+3i 1-2i; 4 5 6]; \n
00285     */
00286     Matrix& operator=(const char* strMatrix);
00287 
00288   public:
00289 
00290     /**
00291     \brief  Clear the matrix memory. Set the matrix to size 0x0.
00292     
00293     \code 
00294     Matrix A(10,10); // A 10 x 10 matrix
00295     if( !A.Clear() )
00296       return false;
00297     // A is now 0x0 
00298     \endcode
00299 
00300     \return true if successul, false if error.
00301     */
00302     bool Clear();
00303 
00304   public: // Matrix Qualifiers
00305 
00306     /// \brief  Is this matrix empty?
00307     bool isEmpty() const;
00308 
00309     /// \brief  Is the matrix mat conformal for multiplication (*this * mat)?
00310     bool isConformal(const Matrix& mat) const;
00311 
00312     /// \brief  Is this matrix the same size as mat?
00313     bool isSameSize(const Matrix& mat) const;  
00314 
00315     /// \brief  Is this a square matrix?
00316     bool isSquare() const;
00317 
00318     /// Check if this matrix is stored as a complex matrix.
00319     bool isStoredAsComplex();
00320 
00321     /// Check if this a real matrix.
00322     bool isReal();
00323 
00324     /// Check if this a complex matrix.
00325     bool isComplex(); 
00326 
00327     /// Check if this is a vector. Is the matrix either nx1 or 1xn.
00328     bool isVector();
00329 
00330     unsigned GetNrCols() const;   //!< return no. of cols
00331     unsigned ncols() const;       //!< return no. of cols
00332     unsigned GetNrElems() const;  //!< return total no. of elements
00333     unsigned nelems() const;      //!< return total no. of elements
00334     unsigned GetNrRows() const;   //!< return no. of rows         
00335     unsigned nrows() const;       //!< return no. of rows         
00336     unsigned GetLength() const;   //!< return the maximum dimension either nrows or ncols whichever is greater.
00337 
00338 
00339     /**
00340     \brief  Return the real part of the matrix at this row and column.
00341 
00342     \code 
00343     Matrix A = "2+4i";
00344     double a = A.real(0,0); // a is 2.0
00345     \endcode
00346     */
00347     double real(const unsigned row, const unsigned col);
00348 
00349     /**
00350     \brief  Return the real part of the matrix at this vector index.
00351 
00352     \code 
00353     Matrix A = "[2+4i, 10-1i]";
00354     double a = A.real(1); // a is 10.0
00355     \endcode
00356     */
00357     double real(const unsigned index);
00358 
00359     /**
00360     \brief  Return the imaginary part of the matrix at this row and column.
00361 
00362     \code 
00363     Matrix B = "2+4i";
00364     double b = B.imag(0); // b is 4.0
00365     \endcode
00366     */    
00367     double imag(const unsigned row, const unsigned col);
00368 
00369     /**
00370     \brief  Return the imaginary part of the matrix at this vector index.
00371     
00372     \code 
00373     Matrix B = "[2+4i, 1-10i]";
00374     double b = B.imag(1); // b is -10.0
00375     \endcode
00376     */    
00377     double imag(const unsigned index);
00378 
00379 
00380   public: // Input Operations
00381 
00382     /**
00383     \brief  Read the matrix from an ASCII file with the path given by the 'c' style string
00384     (with automatric support for many delimiters, whitespace, or ',', or ';', or many others) 
00385     or a compressed BINARY matrix file used in the Save function.
00386     Complex and real data input are supported.
00387     A non-numeric header line can be present which will be skipped.
00388 
00389     \code
00390     Matrix A;
00391     Matrix B;
00392     Matrix C;
00393     bool result;
00394 
00395     result = A.ReadFromFile("data.txt"); // Read an ASCII numeric data file.
00396     result = B.ReadFromFile("data.csv"); // Read a comma delimited numeric data file. e.g. saved from EXCEL.
00397     result = C.ReadFromFile("data.mtx"); // Read a compressed binary matrix (MTX format).
00398     \endcode
00399     
00400     \return true if successful, false otherwise
00401     */
00402     bool ReadFromFile( const char *path );
00403     
00404     /**
00405     \brief  Read the matrix from a file given the file path as a standard string.
00406     
00407     \code
00408     Matrix A;
00409     std::string str = "data.txt";
00410     if( !A.ReadFromFile(str) )
00411       return false;
00412     \endcode
00413 
00414     \return true if successful, false otherwise.
00415     */
00416     bool ReadFromFile( std::string path );
00417 
00418 
00419     /**  
00420     \brief  A safe function for performing a copy of another matrix.
00421     
00422     \code
00423     Matrix A(2,2);
00424     A[0][0] = 1.0;
00425     A[0][1] = 2.0;
00426     A[1][0] = 3.0;
00427     A[1][1] = 4.0;
00428     Matrix B;
00429     if( !B.Copy(A) )
00430       return false;
00431     \endcode
00432     
00433     \return true if successful, false otherwise
00434     */
00435     bool Copy( Matrix& src );
00436 
00437 
00438     /**      
00439     \brief  A safe function for setting the matrix from a double.
00440     
00441     \code
00442     double d = 10.0;
00443     Matrix A;
00444     if( !A.Copy(d) )
00445       return false;
00446     \endcode
00447     
00448     \return true if successful, false otherwise
00449     */
00450     bool Copy( const double& value );
00451 
00452 
00453     /**      
00454     \brief  A safe function for setting the matrix from a std::complex<double>.
00455     
00456     \code
00457     std::complex<double> cplx(1.0,2.0);
00458     Matrix A;
00459     if( !A.Copy(cplx) )
00460       return false;
00461     \endcode
00462     
00463     \return true if successful, false otherwise
00464     */
00465     bool Copy( const std::complex<double>& cplx );
00466 
00467 
00468   public: // Output Operations
00469 
00470     /**
00471     \brief  Saves a matrix to the specified file path (a 'c' style string)
00472             using a proprietary compressed format.
00473     \code
00474     Matrix A;
00475     A = "[1,2,3; 4,5,6; 7,8,9]";
00476     if( !A.Save("data.mtx" ) )
00477       return false;
00478     \endcode 
00479 
00480     \return true if successful, false otherwise
00481     */
00482     bool Save( const char* path );
00483 
00484     /**
00485     \brief  Saves a matrix to the specified file path (a std::string)
00486             using a proprietary compressed format.
00487             
00488     \code
00489     Matrix A;
00490     std::string str = "data.mtx";
00491     A = "[1,2,3; 4,5,6; 7,8,9]";
00492     if( !A.Save(str) )
00493       return false;
00494     \endcode 
00495 
00496     \return true if successful, false otherwise
00497     */
00498     bool Save( std::string path );
00499     
00500     /**
00501     \brief  Print the matrix to a file with automatically determined column width 
00502             and the specified precision, uses "%'blank''-'autowidth.precision'g'", to 
00503             the 'c' style path string provided.
00504     \code
00505     A = "[1,2,3; 4,5,6; 7,8,9]";
00506     if( !A.Print( "data.txt", 14 ) ) // Print the matrix to data.txt
00507       return false;
00508     \endcode   
00509 
00510     \return true if successful, false otherwise
00511     */
00512     bool Print( const char *path, const unsigned precision=9, bool append = false );
00513 
00514     /**
00515     \brief  Print the matrix to a file with automatically determined column width 
00516             and the specified precision, uses "%'blank''-'autowidth.precision'g'", to 
00517             the std:string path provided.
00518     \code
00519     A = "[1,2,3; 4,5,6; 7,8,9]";
00520     std::string str = "data.txt";
00521     if( !A.Print( str, 14 ) ) // Print the matrix to data.txt
00522       return false;
00523     \endcode   
00524 
00525     \return true if successful, false otherwise
00526     */
00527     bool Print( std::string path, const unsigned precision, bool append = false );
00528 
00529     /**
00530     \brief  Print the matrix to the standard output (stdout) with automatically 
00531             determined column width and the specified precision, 
00532             uses "%'blank''-'autowidth.precision'g'".
00533     \code
00534     Matrix A;
00535     A = "[1.123 0 2.123 -1; 3.123 0 4.123 -1]";  // Set A using string notation.
00536     bool result = A.PrintStdout(6); // Print to stdout with automatic width determination.
00537     // results in:
00538     // 0123456789012345678901234567890
00539     //  1.123  0  2.123 -1
00540     //  3.123  0  4.123 -1
00541     \endcode
00542         
00543     \return true if successful, false otherwise
00544     */
00545     bool PrintStdout( const unsigned precision = 6 );
00546 
00547     /**
00548     \brief  Print the matrix to a buffer of maxlength with automatically determined column width 
00549     and the specified precision, uses "%'blank''-'autowidth.precision'g'"
00550 
00551     \code
00552     Matrix A;
00553     A = "[1.123 0 2.123 -1; 3.123 0 4.123 -1]";  // Set A using string notation.
00554     char buffer[256]; 
00555     bool result = A.PrintToBuffer( buffer, 256, 6); // Print to a buffer with automatic width determination.
00556     cout << buffer << endl;
00557     // results in:
00558     // 0123456789012345678901234567890
00559     //  1.123  0  2.123 -1
00560     //  3.123  0  4.123 -1
00561     \endcode
00562      
00563     \return true if successful, false otherwise
00564     */
00565     bool PrintToBuffer( char* buffer, const unsigned maxlength, const unsigned precision );
00566 
00567 
00568     /**
00569     \brief  Print the matrix to a file with specifed width and precision
00570             PrintAutoWidth is recommended over this function, "%'blank''-'width.precision'g'"
00571             to file specified with the 'c' style path string provided.
00572     \code
00573     Matrix A;
00574     A = "[1.123 0 2.123 -1; 3.123 0 4.123 -1]";  // Set A using string notation.
00575     if( !A.PrintFixedWidth( "data.txt", 6, 3 ) )
00576       return false;
00577     // results in: data.txt with
00578     // 0123456789012345678901234567890
00579     //  1.123     0 2.123    -1
00580     //  3.123     0 4.123    -1
00581     \endcode
00582 
00583     \return true if successful, false otherwise
00584     */
00585     bool PrintFixedWidth( const char* path, const unsigned width, const unsigned precision, bool append = false );
00586 
00587 
00588     /**
00589     \brief  Print the matrix to a file with specifed width and precision
00590             PrintAutoWidth is recommended over this function, "%'blank''-'width.precision'g'"
00591             to file specified with the std::string path string provided.
00592     \code
00593     Matrix A;
00594     A = "[1.123 0 2.123 -1; 3.123 0 4.123 -1]";  // Set A using string notation.
00595     std::string str = "data.txt";
00596     if( !A.PrintFixedWidth( str, 6, 3 ) )
00597       return false;
00598     // results in: data.txt with
00599     // 0123456789012345678901234567890
00600     //  1.123     0 2.123    -1
00601     //  3.123     0 4.123    -1
00602     \endcode
00603 
00604     \return true if successful, false otherwise
00605     */   
00606     bool PrintFixedWidth( std::string path, const unsigned width, const unsigned precision, bool append = false );
00607 
00608     /**
00609     \brief  Print the matrix to a buffer of maxlength with specifed width and precision
00610             PrintAutoWidth is recommended over this function, "%'blank''-'width.precision'g'"
00611     \code
00612     Matrix A;
00613     A = "[1.123 2.123 -1; 3.123 4.123 -1]";  // Set A using string notation.
00614     char buffer[256]; 
00615     bool result = A.PrintFixedWidthToBuffer( buffer, 256, 10, 6 ); // Print to a buffer with fixed width.
00616     cout << buffer << endl;
00617     // results in:
00618     // 0123456789012345678901234567890    
00619     //  1.123     2.123    -1
00620     //  3.123     4.123    -1
00621     \endcode
00622       
00623     \return true if successful, false otherwise
00624     */
00625     bool PrintFixedWidthToBuffer( char* buffer, const unsigned maxlength, const unsigned width, const unsigned precision );
00626 
00627     /**
00628     \brief  Print the matrix to a file path specified by the 'c' style string 
00629             with specifed precision and delimiter.
00630     \code
00631     Matrix A;
00632     A = "[1.123 2.123 -1; 3.123 4.123 -1]";  // Set A using string notation.
00633     if( !A.PrintDelimited( "data.csv", 5, ',' ) )
00634       return false;
00635     // results in: data.csv with
00636     // 0123456789012345678901234567890    
00637     // 1.123,2.123,-1
00638     // 3.123,4.123,-1
00639     \endcode
00640 
00641     \return true if successful, false otherwise
00642     */
00643     bool PrintDelimited( const char *path, const unsigned precision, const char delimiter, bool append = false );
00644 
00645     /**
00646     \brief  Print the matrix to a file path specified by the std::string 
00647             with specifed precision and delimiter.
00648     \code
00649     Matrix A;
00650     A = "[1.123 2.123 -1; 3.123 4.123 -1]";  // Set A using string notation.
00651     std::string str = "data.csv";
00652     if( !A.PrintDelimited( str, 5, ',' ) )
00653       return false;
00654     // results in: data.csv with
00655     // 0123456789012345678901234567890    
00656     // 1.123,2.123,-1
00657     // 3.123,4.123,-1
00658     \endcode
00659 
00660     \return true if successful, false otherwise
00661     */
00662     bool PrintDelimited( std::string path, const unsigned precision, const char delimiter, bool append = false );
00663     
00664     /**
00665     \brief  Print the matrix to a 'c' style string buffer of maxlength with specifed precision and delimiter.
00666     
00667     \code
00668     Matrix A;
00669     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00670     char buffer[256]; 
00671     if( !A.PrintDelimitedToBuffer( buffer, 256, 6, ',' ) ) // Print to a buffer using comma delimiters.
00672       return false;
00673     cout << buffer << endl;
00674     // results in:
00675     // 1.123,2.123
00676     // 3.123,4.123
00677     \endcode
00678       
00679     \return true if successful, false otherwise
00680     */
00681     bool PrintDelimitedToBuffer( char *buffer, const unsigned maxlength, const unsigned precision, const char delimiter );
00682 
00683     /**
00684     \brief  Print a row to a 'c' style string buffer.
00685     
00686     \code
00687     Matrix A;
00688     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00689     char buffer[256]; 
00690     if( !A.PrintRowToString( 1, buffer, 256, 4, 6 ) ) // Print the second row to the char buffer.
00691       return false;
00692     cout << buffer << endl;
00693     // results in:
00694     // 3.123   4.123
00695     \endcode
00696     
00697     \return true if successful, false otherwise
00698     */
00699     bool PrintRowToString( const unsigned row, char *buffer, const unsigned maxlength, const int width, const int precision );
00700 
00701 
00702   public: // Change the dimensions of the matrix
00703 
00704     /**  
00705     \brief  Remove a single column from the matrix.
00706 
00707     \code
00708     Matrix A;
00709     A = "[1.123 0 2.123; 3.123 0 4.123]";  // Set A using string notation.
00710     if( !A.RemoveColumn(1) ) // Remove the column with the zeros
00711       return false;
00712     // results in 
00713     // A
00714     // 1.123 2.123
00715     // 3.123 4.123
00716     \endcode
00717         
00718     \return true if successful, false otherwise.  
00719     */
00720     bool RemoveColumn( const unsigned col );
00721 
00722     /**
00723     \brief  Remove all the columns 'after' the column index given.
00724 
00725     \code
00726     Matrix A;
00727     A = "[1.123 0 2.123; 3.123 0 4.123]";  // Set A using string notation.
00728     if( !A.RemoveColumnsAfterIndex(0) ) // Remove the 2nd and 3rd columns, i.e. after the 0th column.
00729       return false;
00730     // results in 
00731     // A
00732     // 1.123
00733     // 3.123
00734     \endcode
00735     
00736     \return true if successful, false otherwise.  
00737     */
00738     bool RemoveColumnsAfterIndex( const unsigned col );
00739 
00740     /** 
00741     \brief  Remove the rows and columns specified by the indices in the rows[] and cols[] arrays.
00742     
00743     \code
00744     Matrix A(4,4);
00745     unsigned rows[2];
00746     unsigned cols[2];
00747     rows[0] = 0; // remove row 0
00748     rows[1] = 2; // remove row 2
00749     cols[0] = 0; // remove column 0
00750     cols[1] = 2; // romve column 2
00751     A.RemoveRowsAndColumns( 2, (unsigned int *)rows, 2, (unsigned int *)cols );
00752     // A is now a 2x2 matrix
00753     \endcode
00754     
00755     \return true if successful, false otherwise.  
00756     */
00757     bool RemoveRowsAndColumns( const unsigned nrows, const unsigned rows[], const unsigned ncols, const unsigned cols[] );
00758 
00759     /**
00760     \brief  Insert a column matrix into the matrix.
00761     
00762     \code
00763     Matrix A;
00764     Matrix B(2,2);
00765     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00766     if( !A.InsertColumn( B, 1, 1 ) ) // Insert second column of B into the second column a A.
00767       return false;
00768     // results in:
00769     // A (2x3)
00770     // 1.123  0   2.123
00771     // 3.123  0   4.123
00772     \endcode
00773     
00774     \return true if successful, false otherwise.  
00775     */
00776     bool InsertColumn( const Matrix &src, const unsigned dst_col, const unsigned src_col );
00777 
00778     /** 
00779     \brief  Add a column to the end of the matrix.
00780 
00781     \code
00782     Matrix A;
00783     atrix B(2,2);
00784     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00785     if( !A.AddColumn( B, 1 ) ) // Add second column of B to A.
00786       return false;
00787     // results in:
00788     // A (2x3)
00789     // 1.123  2.123 0
00790     // 3.123  4.123 0
00791     \endcode
00792     
00793     \return true if successful, false otherwise.  
00794     */
00795     bool AddColumn( const Matrix &src, const unsigned src_col );
00796 
00797     /**
00798     \brief  Combine two matrices with the same nrows, A becomes A|B.
00799 
00800     \code
00801     Matrix A;
00802     atrix B(2,2);
00803     A = "[1.123 2.123; 3.123 4.123]";  // Set A using string notation.
00804     if( !A.Concatonate( B ) ) // make A = A | B
00805       return false;
00806     // results in:
00807     // A (2x4)
00808     // 1.123  2.123 0 0
00809     // 3.123  4.123 0 0
00810     \endcode
00811 
00812     \return true if successful, false otherwise.  
00813     */
00814     bool Concatonate( const Matrix &src );
00815 
00816     /**
00817     \brief  Redimension the matrix, original data is saved in place, new 
00818             data is set to zero. The default value for ncols allows 
00819             redimensioning as a vector.
00820     \code
00821     Matrix A(4,4);       // A is 4x4
00822     A[0][0] = 1;
00823     A[1][1] = -1;
00824     if( !A.Redim(2,2) )  // A is 2x2 but data values are retained.
00825       return false;
00826     // results in:
00827     // A (2x2)
00828     // 1  0
00829     // 0 -1
00830 
00831     Matrix B(10);     // B is a vector with length 10.
00832     B[0] = -1;
00833     B[1] = 1;
00834     if( !B.Redim(2) ) // B is a vector with length 2 but data values are retained
00835       return false;
00836     // results in:
00837     // B 
00838     // -1
00839     // 1
00840     \endcode
00841     
00842     \return true if successful, false otherwise.  
00843     */
00844     bool Redim( const unsigned nrows, const unsigned ncols=1 );
00845 
00846     /**
00847     \brief  Resize the matrix, original data is lost, new data is set to zero.
00848             The default value for ncols allows resizing as a vector.
00849 
00850     \code
00851     Matrix A(4,4);       // A is 4x4
00852     A[0][0] = 1;
00853     A[1][1] = -1;
00854     if( !A.Resize(2,2) )  // A is 2x2 and zero.
00855       return false;
00856     // results in:
00857     // A (2x2)
00858     // 0 0
00859     // 0 0
00860 
00861     Matrix B(10);     // B is a vector with length 10.
00862     B[0] = -1;
00863     B[1] = 1;
00864     if( !B.Resize(2) ) // B is a vector with length 2 and is zero.
00865       return false;
00866     // results in:
00867     // B 
00868     // 0
00869     // 0
00870     \endcode
00871             
00872     \return true if successful, false otherwise.  
00873     */
00874     bool Resize( const unsigned nrows, const unsigned ncols=1 );
00875 
00876 
00877   public: // Setting matrix values
00878 
00879     /**
00880     \brief  Set the matrix from the static 'c' style matrix indexed by mat[i*ncols + j].
00881 
00882     \code
00883     Matrix A;
00884     double data[4] = {1.0,2.0,3.0,4.0};
00885     if( !A.SetFromStaticMatrix( data, 1, 4 ) )
00886       return false;
00887     \\ results in 
00888     \\ A
00889     \\ 1.0 2.0 3.0 4.0
00890     if( !A.SetFromStaticMatrix( data, 2, 2 ) )
00891       return false;    
00892     \\ results in 
00893     \\ A
00894     \\ 1.0 2.0 
00895     \\ 3.0 4.0    
00896     \endcode
00897     
00898     \return true if successful, false otherwise.    
00899     */
00900     bool SetFromStaticMatrix( const double mat[], const unsigned nrows, const unsigned ncols );
00901 
00902     /**
00903     \brief  Setting the matrix values from a string matrix.
00904     
00905     There are two general possible interpretations of the string input. \n
00906     
00907     (1) Square bracket delimited matrix. e.g. \n
00908     
00909     \code
00910     Matrix A;
00911     A.SetFromMatrixString( "[1 2 3; 4 5 6]" ); // or 
00912     A.SetFromMatrixString( "[1, 2, 3; 4, 5, 6]" );
00913     \endcode
00914 
00915     In this case '[' donates the start of a matrix and ']' denotes the end. \n
00916     Row vectors [1 2 3] and [4 5 6] are separated by ';'.  \n
00917     Commas can delimit row vector data but are not needed. \n
00918     Complex input: e.g. 
00919     
00920     \code
00921     Matrix A;
00922     A.SetFromMatrixString( "[1+1i 2+3j 1-2i; 4 5 6]" ); // or
00923     A.SetFromMatrixString( "[1+1i, 2+3j, 1-2i; 4, 5, 6]" );
00924     \endcode
00925     
00926     (2) Free form delimited matrix. e.g. \n
00927 
00928     \code
00929     Matrix A; 
00930     A.SetFromMatrixString( "1 2 3 \\n 4 5 6 \\n" );
00931     \endcode
00932 
00933     In this case, the newline delimits different rows of the matrix. (\\r\\n also works). \n
00934     Row vectors can still be delimited by ';' as well. \n
00935     
00936     \code
00937     A.SetFromMatrixString( "1 2 3; 4 5 6; \\n 7 8 9" );
00938     \endcode 
00939     
00940     will set a 3x3 matrix == [1 2 3; 4 5 6; 7 8 9]. \n
00941 
00942     Commas can delimit row vector data but are not needed. \n
00943     Complex input: e.g. 
00944     
00945     \code
00946     Matrix A;
00947     A.SetFromMatrixString( "[1+1i 2+3j 1-2i\\n 4 5 6]" );   // or
00948     A.SetFromMatrixString( "1+1i, 2+3j, 1-2i\\n 4, 5, 6" ); // or
00949     A.SetFromMatrixString( "1+1i 2+3j 1-2i; 4, 5, 6" );   
00950     \endcode 
00951 
00952     All result in A = [1+1i 2+3i 1-2i; 4 5 6]; \n
00953    
00954     \return true if successful, false otherwise.
00955     */
00956     bool SetFromMatrixString(const char* strMatrix);
00957 
00958 
00959     /**    
00960     \brief  Copy the src data in column col to dst matrix, resize dst if possible and necessary.
00961     
00962     \code
00963     Matrix A;
00964     A = "[1 -1; 2 -2; 3 -3]".
00965     Matrix B;
00966     bool result;
00967     result = A.PrintStdout();   // Print Matrix A.
00968     result = A.CopyColumn(0,B); // Copy the first column of A into B.
00969     result = B.PrintStdout();   // Print Matrix B. B = [1;2;3];
00970     \endcode
00971     
00972     \return true if successful, false otherwise.    
00973     */
00974     bool CopyColumn( const unsigned src_col, Matrix &dst );
00975 
00976     /**
00977     \brief  Insert a submatrix (src) into dst, starting at indices dst(row,col).
00978     
00979     \code
00980     Matrix A(4,4); // A 4x4 matrix of zeros.
00981     Matrix B(2,2); // A 2x2 matrix that we will fill with sevens.
00982     B.Fill(7.0);
00983     bool result;
00984     result = A.PrintStdout();           // Print Matrix A.
00985     result = A.InsertSubMatrix(B,1,1);  // Put B in the middle of A.
00986     result = A.PrintStdout();           // Print Matrix A. A = [0 0 0 0; 0 7 7 0; 0 7 7 0; 0 0 0 0].
00987     \endcode
00988     
00989     \return true if successful, false otherwise.    
00990     */
00991     bool InsertSubMatrix( const Matrix &src, const unsigned dst_row, const unsigned dst_col );
00992 
00993 
00994     /**
00995     \brief  Extract a submatrix (dst) from this matrix from (inclusive) 
00996             the rows and columns specified.
00997     \code 
00998     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
00999     Matrix B;
01000     bool result = A.ExtractSubMatrix( B, 1, 0, 2, 2 );
01001     // B == [4 5 6; 7 8 9]
01002     \endcode
01003 
01004     \return true if successful, false otherwise.
01005     */
01006     bool ExtractSubMatrix( 
01007       Matrix &dst,             //!< The destination matrix to contain the submatrix.
01008       const unsigned from_row, //!< The zero-based index for the from row.
01009       const unsigned from_col, //!< The zero-based index for the from column.
01010       const unsigned to_row,   //!< The zero-based index for the to row.
01011       const unsigned to_col    //!< The zero-based index for the to column.
01012       );
01013 
01014     /**
01015     \brief  Zero the entire matrix.
01016     
01017     \code
01018     Matrix A;
01019     A = "[1 2 3; 4 5 6; 7 8 9]";
01020     bool result;
01021     result = A.PrintStdout();   // Print Matrix A.
01022     result = A.Zero();          // Set A back to zeros.
01023     result = A.PrintStdout();   // Print Matrix A. A = [0 0 0; 0 0 0; 0 0 0].
01024     \endcode
01025     
01026     \return true if successful, false otherwise.  
01027     */
01028     bool Zero();
01029 
01030     /**
01031     \brief  Zero all elements in a specified column.
01032     
01033     \code
01034     Matrix A;
01035     A = "[1 2 3; 4 5 6; 7 8 9]";
01036     bool result;
01037     result = A.PrintStdout();   // Print Matrix A.
01038     result = A.ZeroColumn(1);   // Set the second column of A back to zeros.
01039     result = A.PrintStdout();   // Print Matrix A. A = [1 0 3; 4 0 6; 7 0 9].
01040     \endcode
01041        
01042     \return true if successful, false otherwise.    
01043     */
01044     bool ZeroColumn( const unsigned col );
01045 
01046     /**
01047     \brief  Zero all elements in a specified row.
01048     
01049     \code
01050     Matrix A;
01051     A = "[1 2 3; 4 5 6; 7 8 9]";
01052     bool result;
01053     result = A.PrintStdout();   // Print Matrix A.
01054     result = A.ZeroRow(1);      // Set the second row of A back to zeros.
01055     result = A.PrintStdout();   // Print Matrix A. A = [1 2 3; 0 0 0; 7 8 9].
01056     \endcode
01057        
01058     \return true if successful, false otherwise.    
01059     */
01060     bool ZeroRow( const unsigned row );
01061 
01062 
01063     /**
01064     \brief  Efficiently swaps the contents of this matrix with matrix M.
01065     The contents are exhanged without the need to copy matrix data.
01066 
01067     \code
01068     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
01069     Matrix B = "[1 2; 3 4]";        
01070     bool result;
01071     result = A.Swap(B);    
01072     result = A.PrintStdout();   // Print Matrix A. A = [1 2; 3 4]
01073     result = B.PrintStdout();   // Print Matrix B. B = [1 2 3; 4 5 6; 7 8 9]
01074     \endcode
01075 
01076     \return true if successful, false otherwise.    
01077     */
01078     bool Swap( Matrix &M );
01079 
01080     /**
01081     \brief  Fill the matrix with the given value.
01082 
01083     \code
01084     Matrix A;
01085     A = "[1 2 3; 4 5 6; 7 8 9]";
01086     bool result;
01087     result = A.PrintStdout();   // Print Matrix A.
01088     result = A.Fill(7);         // Fill the matrix with 7.0.
01089     result = A.PrintStdout();   // Print Matrix A. A = [7 7 7; 7 7 7; 7 7 7].
01090     \endcode
01091 
01092     \return true if successful, false otherwise.    
01093     */
01094     bool Fill( const double value );
01095 
01096     /**
01097     \brief  Fill the matrix column with the given value.
01098     
01099     \code
01100     Matrix A;
01101     A = "[1 2 3; 4 5 6; 7 8 9]";
01102     bool result;
01103     result = A.PrintStdout();   // Print Matrix A.
01104     result = A.FillColumn(1,7); // Fill the second column with 7.0.
01105     cout << endl;
01106     result = A.PrintStdout();   // Print Matrix A. A = [1 7 3; 4 7 6; 7 7 9].
01107     \endcode
01108     
01109     \return true if successful, false otherwise.    
01110     */
01111     bool FillColumn( const unsigned col, const double value );
01112 
01113     /**
01114     \brief  Fills the matrix row with the given value.
01115     
01116     \code
01117     Matrix A;
01118     A = "[1 2 3; 4 5 6; 7 8 9]";
01119     bool result;
01120     result = A.PrintStdout();   // Print Matrix A.
01121     result = A.FillRow(1,7);    // Fill the second row with 7.0.
01122     cout << endl;
01123     result = A.PrintStdout();   // Print Matrix A. A = [1 2 3; 7 7 7; 7 8 9].
01124     \endcode
01125     
01126     \return true if successful, false otherwise.    
01127     */
01128     bool FillRow( const unsigned row, const double value );
01129 
01130     /**
01131     \brief  Reverse the order of elements of a column.
01132     
01133     \code
01134     Matrix A;
01135     A = "[1 2 3; 4 5 6; 7 8 9]";
01136     bool result;
01137     result = A.PrintStdout();   // Print Matrix A.
01138     result = A.FlipColumn(1);   // Flip the second column.
01139     cout << endl;
01140     result = A.PrintStdout();   // Print Matrix A. A = [1 8 3; 4 5 6; 7 2 9].
01141     \endcode
01142        
01143     \return true if successful, false otherwise.    
01144     */
01145     bool FlipColumn( const unsigned col );
01146 
01147     /**
01148     \brief  Reverse the order of elements of a row.
01149     
01150     \code
01151     Matrix A;
01152     A = "[1 2 3; 4 5 6; 7 8 9]";
01153     bool result;
01154     result = A.PrintStdout();   // Print Matrix A.
01155     result = A.FlipRow(1);      // Flip the second row.
01156     cout << endl;
01157     result = A.PrintStdout();   // Print Matrix A. A = [1 2 3; 6 5 4; 7 8 9].
01158     \endcode    
01159     
01160     \return true if successful, false otherwise.    
01161     */
01162     bool FlipRow( const unsigned row );
01163 
01164     /**
01165     \brief  Set the matrix to identity using the current dimensions.
01166     
01167     \code
01168     Matrix A;
01169     A = "[1 2 3; 4 5 6; 7 8 9]";
01170     bool result;
01171     result = A.PrintStdout();   // Print Matrix A.
01172     result = A.Identity();      // Set A to identity.
01173     cout << endl;
01174     result = A.PrintStdout();   // Print Matrix A. A = [1 0 0; 0 1 0; 0 0 1].
01175     \endcode    
01176     
01177     \return true if successful, false otherwise.    
01178     */
01179     bool Identity();
01180 
01181     /**   
01182     \brief  Set the matrix to identity using the specified dimension (nxn).
01183     
01184     \code
01185     Matrix A;
01186     bool result;
01187     result = A.Identity(3);     // Set A to identity, 3x3.
01188     cout << endl;
01189     result = A.PrintStdout();   // Print Matrix A. A = [1 0 0; 0 1 0; 0 0 1].
01190     \endcode    
01191     
01192     \return true if successful, false otherwise.        
01193     */
01194     bool Identity(const unsigned dimension);
01195 
01196 
01197 
01198   public: // Inplace Operations
01199 
01200     /**
01201     \brief  Transpose the matrix as an inplace operation.
01202     
01203     \code
01204     Matrix A;
01205     A = "[1 2 3; 4 5 6; 7 8 9]";
01206     bool result;
01207     result = A.PrintStdout();         // Print Matrix A.
01208     result = A.Inplace_Transpose();   // Make A = transpose(A).
01209     cout << endl;
01210     result = A.PrintStdout();         // Print Matrix A. A = [1 4 7; 2 5 8; 3 6 9].
01211     \endcode    
01212     
01213     \return true if successful, false otherwise.    
01214     */
01215     bool Inplace_Transpose();
01216     bool Inplace_transpose() { return this->Inplace_Transpose(); }
01217 
01218     /**
01219     \brief  Round the matrix elements to the specified presision. \n
01220     e.g. precision = 0    1.8    -> 2     (default)\n
01221     e.g. precision = 1,   1.45   -> 1.5   \n
01222     e.g. precision = 2    1.456  -> 1.46  \n
01223     e.g. precision = 3,   1.4566 -> 1.457 \n
01224     *
01225     \code
01226     Matrix A;
01227     A = "[1.09 2.08 3.07; 4.06 5.05 6.04; 7.03 8.02 9.01]";
01228     bool result;
01229     result = A.PrintStdout();     // Print Matrix A.
01230     result = A.Inplace_Round(1);  // Make A = round(A) to the 1st decimal place.
01231     cout << endl;
01232     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]";
01233     \endcode    
01234     
01235     \return true if successful, false otherwise.    
01236     */
01237     bool Inplace_Round( const unsigned precision = 0 );
01238     bool Inplace_round( const unsigned precision = 0 ) { return this->Inplace_Round( precision ); }
01239 
01240     /**
01241     \brief  Round the matrix elements to the nearest integers towards minus infinity.
01242     
01243     \code
01244     Matrix A;
01245     A = "[1.9 2.8 3.7; -4.6 -5.5 -6.4; 7.3 8.2 9.1]";
01246     bool result;
01247     result = A.PrintStdout();     // Print Matrix A.
01248     result = A.Inplace_Floor();   // Make A = floor(A).
01249     cout << endl;
01250     result = A.PrintStdout();     // Print Matrix A. A = "[1 2 3; -5 -6 -7; 7 8 9]";
01251     \endcode    
01252        
01253     \return true if successful, false otherwise.    
01254     */
01255     bool Inplace_Floor();
01256     bool Inplace_floor() { return this->Inplace_Floor(); }
01257 
01258     /**
01259     \brief  Round the matrix elements to the nearest integers towards infinity.
01260     
01261     \code
01262     Matrix A;
01263     A = "[1.9 2.8 3.7; -4.6 -5.5 -6.4; 7.3 8.2 9.1]";
01264     bool result;
01265     result = A.PrintStdout();     // Print Matrix A.
01266     result = A.Inplace_Ceil();    // Make A = ceil(A).
01267     cout << endl;
01268     result = A.PrintStdout();     // Print Matrix A. A = "[2 3 4; -4 -5 -6; 8 9 10]";
01269     \endcode    
01270            
01271     \return true if successful, false otherwise.    
01272     */
01273     bool Inplace_Ceil();
01274     bool Inplace_ceil() { return this->Inplace_Ceil(); }
01275 
01276 
01277     /**
01278     \brief  Compute the error function (erf) for all values in the matrix inplace. \n
01279     erf(x) = 2/sqrt(pi) * [integral from 0 to x of]( e^(-t^2) )dt.
01280 
01281     \code
01282     Matrix A;
01283     A = "[-1 -0.5 0 0.5 1]";
01284     bool result;
01285     result = A.PrintStdout();     // Print Matrix A. A = "[-1 -0.5 0 0.5 1]";
01286     result = A.Inplace_erf();     // Make A = erf(A).
01287     cout << endl;
01288     result = A.PrintStdout();     // Print Matrix A. A = "[-0.842700792949715 -0.520499877813047  0 0.520499877813047 0.842700792949715]";
01289     \endcode    
01290            
01291     \return true if successful, false otherwise.    
01292     */
01293     bool Inplace_erf();
01294 
01295     /**
01296     \brief  Compute the inverse error function (erfinv) for all values in the matrix inplace. \n
01297     y = erf(x) = 2/sqrt(pi) * [integral from 0 to x of]( e^(-t^2) )dt.
01298     x = erfinv(y);
01299 
01300     \code
01301     Matrix A;
01302     A = "[-0.842700792949715 -0.520499877813047  0 0.520499877813047 0.842700792949715]"; 
01303     bool result;
01304     result = A.PrintStdout();     // Print Matrix A. A = "[-0.842700792949715 -0.520499877813047  0 0.520499877813047 0.842700792949715]"; 
01305     result = A.Inplace_erfinv();  // Make A = erfinv(A).
01306     cout << endl;
01307     result = A.PrintStdout();     // Print Matrix A. A = "[-1 -0.5 0 0.5 1]";
01308     \endcode    
01309            
01310     \return true if successful, false otherwise.    
01311     */
01312     bool Inplace_erfinv();
01313 
01314     /**
01315     \brief  Compute the complementary error function (erfc) for all values in the matrix inplace. \n
01316     erfc(x) = 1 - erf(x) =  2/sqrt(pi) * [integral from x to inf of]( e^(-t^2) )dt.    
01317 
01318     \code
01319     Matrix A;
01320     A = "[-1 -0.5 0 0.5 1]";
01321     bool result;
01322     result = A.PrintStdout();     // Print Matrix A. A = "[-1 -0.5 0 0.5 1]";
01323     result = A.Inplace_erfc();    // Make A = erfc(A).
01324     cout << endl;
01325     result = A.PrintStdout();     // Print Matrix A. A = "[1.84270079294971  1.52049987781305   1 0.479500122186953 0.157299207050285]";
01326     \endcode    
01327            
01328     \return true if successful, false otherwise.    
01329     */
01330     bool Inplace_erfc();
01331 
01332     /**
01333     \brief  Compute the complementary error function (erfc) for all values in the matrix inplace. \n
01334     erfc(x) = 1 - erf(x) =  2/sqrt(pi) * [integral from x to inf of]( e^(-t^2) )dt.    
01335 
01336     \code
01337     Matrix A;
01338     A = "[1.84270079294971  1.52049987781305   1 0.479500122186953 0.157299207050285]";
01339     bool result;
01340     result = A.PrintStdout();     // Print Matrix A. A = "[1.84270079294971  1.52049987781305   1 0.479500122186953 0.157299207050285]";
01341     result = A.Inplace_erfcinv(); // Make A = erfcinv(A).
01342     cout << endl;
01343     result = A.PrintStdout();     // Print Matrix A. A = "[-1 -0.5 0 0.5 1]";
01344     \endcode    
01345            
01346     \return true if successful, false otherwise.    
01347     */
01348     bool Inplace_erfcinv();
01349 
01350 
01351     /**
01352     \brief  Rounds the matrix elements of X to the nearest integers towards zero.
01353     
01354     \code
01355     Matrix A;
01356     A = "[1.9 2.8 3.7; -4.6 -5.5 -6.4; 7.3 8.2 9.1]";
01357     bool result;
01358     result = A.PrintStdout();     // Print Matrix A.
01359     result = A.Inplace_Fix();     // Make A = fix(A).
01360     cout << endl;
01361     result = A.PrintStdout();     // Print Matrix A. A = "[1 2 3; -4 -5 -6; 7 8 9]";
01362     \endcode    
01363     
01364     \return true if successful, false otherwise.    
01365     */
01366     bool Inplace_Fix();
01367 
01368     /** \brief  Add a scaler double (ie: M += 5).
01369     
01370     \code
01371     Matrix A;
01372     A = "[1 2 3; 4 5 6; 7 8 9]";
01373     bool result;
01374     result = A.PrintStdout();        // Print Matrix A.
01375     result = A.Inplace_AddScalar(1); // A += 1.
01376     cout << endl;
01377     result = A.PrintStdout();        // Print Matrix A. A = "[2 3 4; 5 6 7; 8 9 10]";
01378     \endcode    
01379     
01380     \return true if successful, false otherwise.    
01381     */
01382     bool Inplace_AddScalar( const double scalar );
01383 
01384     /**
01385     \brief  Subtract a scaler double (ie: M -= 5).
01386     
01387     \code
01388     Matrix A;
01389     A = "[1 2 3; 4 5 6; 7 8 9]";
01390     bool result;
01391     result = A.PrintStdout();             // Print Matrix A.
01392     result = A.Inplace_SubtractScalar(1); // A -= 1.
01393     cout << endl;
01394     result = A.PrintStdout();             // Print Matrix A. A = "[0 1 2; 3 4 5; 6 7 8]";
01395     \endcode    
01396        
01397     \return true if successful, false otherwise.    
01398     */
01399     bool Inplace_SubtractScalar( const double scalar );
01400 
01401     /**
01402     \brief  Multiply by scaler double (ie: M *= 5).
01403     
01404     \code
01405     Matrix A;
01406     A = "[1 2 3; 4 5 6; 7 8 9]";
01407     bool result;
01408     result = A.PrintStdout();              // Print Matrix A.
01409     result = A.Inplace_MultiplyScalar(5);  // A *= 5.
01410     cout << endl;
01411     result = A.PrintStdout();              // Print Matrix A. A = "[5 10 15; 20 25 30; 35 40 45]";
01412     \endcode    
01413     
01414     \return true if successful, false otherwise.    
01415     */
01416     bool Inplace_MultiplyScalar( const double scalar );
01417 
01418     /**
01419     \brief  Divide by scaler double (ie: M /= 5).
01420     
01421     \code
01422     Matrix A;
01423     A = "[5 10 15; 20 25 30; 35 40 45]";
01424     bool result;
01425     result = A.PrintStdout();           // Print Matrix A.
01426     result = A.Inplace_DivideScalar(5); // A /= 5.
01427     cout << endl;
01428     result = A.PrintStdout();           // Print Matrix A. A = "[1 2 3; 4 5 6; 7 8 9]";
01429     \endcode    
01430        
01431     \return true if successful, false otherwise.    
01432     */
01433     bool Inplace_DivideScalar( const double scalar );
01434 
01435     /**
01436     \brief  Raise the matrix to a power scaler double (ie: M ^= 5).
01437     
01438     \code
01439     Matrix A;
01440     A = "[1 2 3; 4 5 6; 7 8 9]";
01441     bool result;
01442     result = A.PrintStdout();           // Print Matrix A.
01443     result = A.Inplace_PowerScalar(2);  // A = A.^2. Not A*A! Each element is raised.
01444     cout << endl;
01445     result = A.PrintStdout();           // Print Matrix A. A = "[1 4 9; 16 25 36; 49 64 81]";
01446     \endcode    
01447            
01448     \return true if successful, false otherwise.    
01449     */
01450     bool Inplace_PowerScalar( const double scalar );
01451 
01452     /**
01453     \brief  Add a scaler double (ie: M += (4+2i)).
01454     
01455     \code
01456     Matrix A;
01457     A = "[1 2 3; 4 5 6; 7 8 9]";
01458     bool result;
01459     result = A.PrintStdout();           // Print Matrix A.
01460     std::complex<double> cplx(4.0,2.0);
01461     result = A.Inplace_AddScalarComplex(cplx);  // A += (4+2i).
01462     cout << endl;
01463     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]";
01464     cout << "A(0,0) = " << A(0,0).real() << "+" << A(0,0).imag() << "i " << endl;
01465     \endcode    
01466                
01467     * \return true if successful, false otherwise.    
01468     */
01469     bool Inplace_AddScalarComplex( const std::complex<double> cplx );
01470 
01471     /**
01472     \brief  Subtract a scaler double (ie: M -= (5+2i)).
01473     
01474     \code
01475     Matrix A;
01476     A = "[1 2 3; 4 5 6; 7 8 9]";
01477     bool result;
01478     result = A.PrintStdout();           // Print Matrix A.
01479     std::complex<double> cplx(5.0,2.0);
01480     result = A.Inplace_SubtractScalarComplex(cplx);  // A -= (5+2i).
01481     cout << endl;
01482     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]";
01483     cout << "A(0,0) = " << A(0,0).real() << "+" << A(0,0).imag() << "i " << endl;
01484     \endcode    
01485                    
01486     \return true if successful, false otherwise.    
01487     */
01488     bool Inplace_SubtractScalarComplex( const std::complex<double> cplx );
01489 
01490     /**
01491     \brief  Multiply by scaler double (ie: M *= (5+2i)).
01492 
01493     \code
01494     Matrix M;
01495     M = "[10 20]";
01496     std::complex<double> cplx(5,2);
01497     if( !M.Inplace_MultiplyScalarComplex(cplx) )
01498       return false;
01499     // M
01500     // 50+20i  100+40i
01501     \endcode
01502     
01503     \return true if successful, false otherwise.    
01504     */
01505     bool Inplace_MultiplyScalarComplex( const std::complex<double> cplx );
01506 
01507     /**
01508     \brief  Divide by scaler double (ie: M /= (5+1i)).
01509 
01510     \code
01511     Matrix M;
01512     M = "[10+2i 20+4i]";
01513     std::complex<double> cplx(5,1);
01514     if( !M.Inplace_DivideScalarComplex(cplx) )
01515       return false;
01516     // M
01517     // 2  4
01518     \endcode
01519     
01520     \return true if successful, false otherwise.    
01521     */
01522     bool Inplace_DivideScalarComplex( const std::complex<double> cplx );
01523 
01524     /**
01525     \brief  Raise the matrix to a power scaler double (ie: M ^= (5+2i)).
01526 
01527     \code
01528     Matrix M;
01529     M = "[2 3]";
01530     std::complex<double> cplx(5,2);
01531     if( !M.Inplace_PowerScalarComplex(cplx) )
01532       return false;
01533     // M
01534     // 5.87062319178566+31.4568876931598i    -142.459949032798+196.860770397691i
01535     \endcode    
01536     
01537     \return true if successful, false otherwise.    
01538     */
01539     bool Inplace_PowerScalarComplex( const std::complex<double> cplx );
01540 
01541     /**
01542     \brief  Compute the absolute value of each element in the matrix.
01543 
01544     \code
01545     Matrix A;
01546     A = "[-1 -2; -3 -4]";
01547     if( !A.Inplace_Abs() )
01548       return false;
01549     // A
01550     // 1 2
01551     // 3 4
01552     \endcode
01553     
01554     \return true if successful, false otherwise.    
01555     */
01556     bool Inplace_Abs();
01557 
01558     /**
01559     \brief  Compute the value^2 of each element in the matrix.
01560 
01561     \code
01562     Matrix A;
01563     A = "[1 2; -3 -4]";
01564     if( !A.Inplace_Sqr() )
01565       return false;
01566     // A
01567     // 1 4
01568     // 9 16
01569     \endcode    
01570     
01571     \return true if successful, false otherwise.    
01572     */
01573     bool Inplace_Sqr();
01574 
01575     /**
01576     \brief  Computes the sqrt(value) of each element in the matrix.
01577 
01578     \code
01579     Matrix A;
01580     A = "[1 4; 9 16]";
01581     if( !A.Inplace_Sqrt() )
01582       return false;
01583     // A
01584     // 1 2
01585     // 3 4
01586     \endcode        
01587     
01588     \return true if successful, false otherwise.    
01589     */
01590     bool Inplace_Sqrt();
01591 
01592     /**
01593     \brief  Computes the exp(value) of each element in the matrix.
01594 
01595     \code
01596     Matrix A;
01597     A = "[1 2; 3 4]";
01598     if( !A.Inplace_Exp() )
01599       return false;
01600     // A ~
01601     //  2.71828  7.38905
01602     // 20.08553 54.59815
01603     \endcode        
01604     
01605     \return true if successful, false otherwise.    
01606     */
01607     bool Inplace_Exp();
01608 
01609     /**
01610     \brief  Computes the natural logarithm, ln(value) of each element in the matrix.
01611 
01612     \code
01613     Matrix A;
01614     A = "[2.71828  7.38905; 20.08553 54.59815]";    
01615     if( !A.Inplace_Ln() )
01616       return false;
01617     // A ~
01618     // 1 2
01619     // 3 4
01620     \endcode         
01621     
01622     \return true if successful, false otherwise.    
01623     */
01624     bool Inplace_Ln();
01625 
01626     /**
01627     \brief  Add +1.0 to all elements, e.g. M++.
01628 
01629     \code
01630     Matrix A;
01631     A = "[1 2; 3 4]";
01632     if( !A.Inplace_Increment() )
01633       return false;
01634     // A 
01635     // 2 3
01636     // 4 5
01637     \endcode        
01638     
01639     \return true if successful, false otherwise.   
01640     */
01641     bool Inplace_Increment();
01642 
01643     /**
01644     \brief  Subtract 1.0 from all elements, e.g. M--.
01645 
01646     \code
01647     Matrix A;
01648     A = "[1 2; 3 4]";
01649     if( !A.Inplace_Decrement() )
01650       return false;
01651     // A 
01652     // 0 1
01653     // 2 3
01654     \endcode            
01655     
01656     \return true if successful, false otherwise.    
01657     */
01658     bool Inplace_Decrement();
01659 
01660     /**
01661     \brief  Add matrix B to this matrix inplace. A += B, inplace.
01662 
01663     \code
01664     Matrix A;
01665     Matrix B;
01666     A = "[1 2; 3 4]";
01667     B = "[1 2; 3 4]";
01668     if( !A.Inplace_Add(B) )
01669       return false;
01670     // A 
01671     // 2 4
01672     // 6 8
01673     \endcode            
01674     
01675     \return true if successful, false otherwise.
01676     */
01677     bool Inplace_Add( const Matrix &B );
01678 
01679     /**
01680     \brief  Subtract matrix B from this matrix inplace. A -= B, inplace.
01681 
01682     \code
01683     Matrix A;
01684     Matrix B;
01685     A = "[1 2; 3 4]";
01686     B = "[1 2; 3 4]";
01687     if( !A.Inplace_Subtract(B) )
01688       return false;
01689     // A 
01690     // 0 0
01691     // 0 0
01692     \endcode            
01693     
01694     \return true if successful, false otherwise.
01695     */
01696     bool Inplace_Subtract( const Matrix &B );
01697 
01698     /**
01699     \brief  Pre-Multiply this matrix by B. A = B*A, inplace.
01700 
01701     \code
01702     Matrix A;
01703     Matrix B;
01704     A = "[1 2; 3 4]";
01705     B = "[1 2; 2 1]";
01706     if( !A.Inplace_PreMultiply(B) )
01707       return false;
01708     // A 
01709     // 7 10
01710     // 5 8
01711     \endcode  
01712     
01713     \return true if successful, false otherwise.
01714     */
01715     bool Inplace_PreMultiply( const Matrix &B );
01716 
01717     /**
01718     \brief  Pre-Multiply this matrix by tranpose(B). A = tranpose(B)*A, inplace.
01719     No transpose occurs and hence more efficient.
01720 
01721     \code
01722     Matrix A;
01723     Matrix B;
01724     A = "[1 2; 3 4]";
01725     B = "[5 6; 7 8]";
01726     if( !A.Inplace_TranposePreMultiply(B) )
01727       return false;
01728     // A 
01729     // 26 38
01730     // 30 44
01731     \endcode  
01732     
01733     \return true if successful, false otherwise.
01734     */
01735     bool Inplace_TranposePreMultiply( const Matrix &B );
01736 
01737     /**
01738     \brief  Post-Multiply this matrix by B. A = A*B, inplace.
01739 
01740     \code
01741     Matrix A;
01742     Matrix B;
01743     A = "[1 2; 3 4]";
01744     B = "[1 2; 2 1]";
01745     if( !A.Inplace_PostMultiply(B) )
01746       return false;
01747     // A 
01748     // 5 4
01749     // 11 10
01750     \endcode      
01751     
01752     \return true if successful, false otherwise.  
01753     */
01754     bool Inplace_PostMultiply( const Matrix &B );
01755 
01756     /**
01757     \brief  Post-Multiply this matrix by transpose(B). A = A*transpose(B), inplace.
01758 
01759     \code
01760     Matrix A;
01761     Matrix B;
01762     A = "[1 2; 3 4]";
01763     B = "[5 6; 7 8]";
01764     if( !A.Inplace_PostMultiplyTranspose(B) )
01765       return false;
01766     // A 
01767     // 17 23
01768     // 39 53
01769     \endcode      
01770     
01771     \return true if successful, false otherwise.  
01772     */
01773     bool Inplace_PostMultiplyTranspose( const Matrix &B );
01774 
01775     /**
01776     \brief  Dot multiply A .*= B, inplace. A and B must have the same dimensions.
01777 
01778     \code
01779     Matrix A;
01780     Matrix B;
01781     A = "[1 2; 3 4]";
01782     B = "[1 2; 2 1]";
01783     if( !A.Inplace_DotMultiply(B) )
01784       return false;
01785     // A 
01786     // 1 4
01787     // 6 4
01788     \endcode          
01789     
01790     \return true if successful, false otherwise.
01791     */
01792     bool Inplace_DotMultiply( const Matrix &B );
01793 
01794     /**
01795     \brief  Dot divide A ./= B, inplace. A and B must have the same dimensions.
01796 
01797     \code
01798     Matrix A;
01799     Matrix B;
01800     A = "[1 2; 3 4]";
01801     B = "[1 2; 2 1]";
01802     if( !A.Inplace_DotDivide(B) )
01803       return false;
01804     // A 
01805     // 1   1
01806     // 1.5 4
01807     \endcode          
01808     
01809     \return true if successful, false otherwise.
01810     */
01811     bool Inplace_DotDivide( const Matrix &B );
01812 
01813     /**
01814     \brief  Sorts each column of the matrix in ascending order.
01815             If complex, sorts based on magnitude.
01816     \code
01817     Matrix A;
01818     A = "[1;3;2;4;6;5;7]";
01819     if( !A.Inplace_SortAscending() )
01820       return false;
01821     // A
01822     // [1;2;3;4;5;6;7]
01823     \endcode
01824     
01825     \return true if successful, false otherwise.
01826     */
01827     bool Inplace_SortAscending();
01828 
01829     /**
01830     \brief  Sorts each column of M in descending order.
01831             If complex, sorts based on magnitude.
01832     \code
01833     Matrix A;
01834     A = "[1;3;2;4;6;5;7]";
01835     if( !A.Inplace_SortDescending() )
01836       return false;
01837     // A
01838     // [7;6;5;4;3;2;1]
01839     \endcode    
01840     
01841     \return true if successful, false otherwise.
01842     */
01843     bool Inplace_SortDescending();
01844 
01845     /**
01846     \brief  Sorts a specific column in ascending order.
01847             If complex, sorts based on magnitude.
01848     \code
01849     Matrix A;
01850     A = "[0 1;0 3;0 2;0 4;0 6;0 5;0 7]";
01851     if( !A.Inplace_SortColumnAscending(1) )
01852       return false;
01853     // A
01854     // A = "[0 1;0 2;0 3;0 4;0 5;0 6;0 7]";
01855     \endcode
01856        
01857     \return true if successful, false otherwise.
01858     */
01859     bool Inplace_SortColumnAscending( const unsigned col );
01860 
01861     /**
01862     \brief  Sorts a specific column in descending order.
01863             If complex, sorts based on magnitude.
01864     \code
01865     Matrix A;
01866     A = "[0 1;0 3;0 2;0 4;0 6;0 5;0 7]";
01867     if( !A.Inplace_SortColumnDescending(1) )
01868       return false;
01869     // A
01870     // A = "[0 7;0 6;0 5;0 4;0 3;0 2;0 1]";
01871     \endcode       
01872     
01873     \return true if successful, false otherwise.
01874     */
01875     bool Inplace_SortColumnDescending( const unsigned col );
01876 
01877     /**
01878     \brief  Sorts a specific column in ascending order and fills a  
01879             column vector with the sorted index. The index vector will be resized 
01880             if needed. If complex, sorts based on magnitude.
01881     \code
01882     Matrix A;
01883     Matrix I;
01884     A = "[0 1;0 3;0 2;0 4;0 6;0 5;0 7]";
01885     if( !A.Inplace_SortColumnIndexed(1, I) )
01886       return false;
01887     // A = "[0 1;0 2;0 3;0 4;0 5;0 6;0 7]";
01888     // I = "[0;2;1;3;5;4;6]"
01889     \endcode    
01890     
01891     \return true if successful, false otherwise.
01892     */
01893     bool Inplace_SortColumnIndexed( const unsigned col, Matrix &Index );
01894 
01895     /**
01896     \brief  Sorts the entire matrix by a specific column.
01897             If complex, sorts based on magnitude.
01898 
01899     \code
01900     Matrix A;
01901     Matrix I;
01902     A = "[0 1;2 3;1 2;3 4;5 6;4 5;6 7]";
01903     if( !A.Inplace_SortByColumn(0) )
01904       return false;
01905     // A = "[0 1;1 2;2 3;3 4;4 5;5 6;6 7]";
01906     \endcode 
01907     
01908     \return true if successful, false otherwise.
01909     */
01910     bool Inplace_SortByColumn( const unsigned col );
01911 
01912     /**
01913     \brief  Computes the inplace inverse of the matrix.
01914     
01915     Uses fast closed form solutions for:
01916     1x1, 2x2, 3x3
01917     
01918     Otherwise, the matrix is first tested to determine if it is a symmetric 
01919     positive-definite matrix. If so, Cholesky decomposition is used
01920     to facilitate the inversion of a lower triangular matrix. If the
01921     matrix is not symmetric and positive-definite robust inversion
01922     using gaussing elimination is attempted.
01923     
01924     If the matrix is singular, the original matrix is unchanged.
01925 
01926     \code 
01927     Matrix A;
01928     A = "[10 14; 14 20]";
01929     if( !A.Inplace_Invert() )
01930       return false;
01931     // A
01932     //     5  -3.5
01933     //  -3.5   2.5
01934     \endcode
01935     
01936     \return true if successful, false if empty, singular or not square.
01937     */
01938     bool Inplace_Invert();
01939 
01940     /**
01941     \brief  Perfroms an inplace inverse using Gaussian Elimination methods.
01942 
01943     \code 
01944     Matrix A;
01945     A = "[1 2; 3 4]";
01946     if( !A.Inplace_InvertRobust() )
01947       return false;
01948     // A
01949     //   -2     1
01950     //  1.5  -0.5
01951     \endcode
01952     
01953     \return true if successful, false if empty, singular or not square.
01954     */
01955     bool Inplace_InvertRobust();
01956 
01957     /**
01958     \brief  Compute the inplace inverse of a unit lower triangular matrix. 
01959     
01960     \code
01961     Matrix A;
01962     // A
01963     //    1    0    0
01964     //   -2    2    0
01965     //    4   -3   -3    
01966     A = "[1 0 0; -2 2 0; 4 -3 -3]";
01967     if( !A.Inplace_LowerTriangularInverse() )
01968       return false;
01969     // A
01970     //    1    0    0
01971     //    1  1/2    0
01972     // -1/3  1/2  1/3
01973     \endcode
01974     
01975     \return true if successful, false if empty, singular or not square.
01976     */
01977     bool Inplace_LowerTriangularInverse();
01978 
01979     /**
01980     \brief  Compute the inplace Fourier Transform of each column of the matrix.
01981 
01982     \code
01983     Matrix A;
01984     A = "[0; 0; 0; 0; 1; 1; 1; 1;]"; 
01985     if( !A.Inplace_FFT() )
01986      return false;
01987     // A
01988     //  4                         
01989     // -1+2.41421356237309i
01990     //  0                         
01991     // -1+0.414213562373095i
01992     //  0                         
01993     // -1-0.414213562373095i
01994     //  0                         
01995     // -1-2.41421356237309i
01996     \endcode
01997 
01998     endcode
01999 
02000     \return   true if successful, false if unable to perform the FFT.
02001     */
02002     bool Inplace_FFT();
02003 
02004 
02005     /**
02006     \brief  Compute the inplace Two-Dimensional Fourier Transform of the matrix.
02007     FFT2 is equivalent to transpose( FFT( transpose( FFT(each column) ) ) )
02008 
02009     \code
02010     Matrix A;
02011     Matrix B;
02012     bool result;
02013     result = A.Inplace_colon(1.0,1.0,32.0);
02014     B = A*A.Transpose(); // (32x32 square matrix)
02015     result = B.Inplace_FFT2();
02016     \endcode
02017 
02018     endcode
02019 
02020     \return   true if successful, false if unable to perform the 2D FFT.
02021     */
02022     bool Inplace_FFT2();
02023 
02024     /**
02025     \brief  Compute the inplace inverse Fourier Transform of each column of the matrix.
02026 
02027     \code
02028     Matrix A;
02029     A = "[4; -1+2.41421356237309i; 0; -1+0.414213562373095i; 0; -1-0.414213562373095i; 0; -1-2.41421356237309i;]"; 
02030     if( !A.Inplace_IFFT() )
02031      return false;
02032     // A
02033     // 0                         
02034     // 0
02035     // 0                         
02036     // 0
02037     // 1                         
02038     // 1
02039     // 1                         
02040     // 1
02041     \endcode
02042 
02043     \return   true if successful, false if unable to perform the FFT.
02044     */
02045     bool Inplace_IFFT();
02046 
02047 
02048     /**
02049     \brief  Compute the inplace inverse Fourier Transform of the matrix.
02050     IFFT2 is equivalent to transpose( IFFT( transpose( IFFT(each column) ) ) )
02051 
02052     \return   true if successful, false if unable to perform the FFT.
02053     */
02054     bool Inplace_IFFT2();
02055 
02056 
02057   public: // Safe operations that set the matrix. Safe in that they return a boolean.
02058 
02059     /**
02060     \brief  Add A = B+C. The result, A, is stored in this matrix. 
02061 
02062     \code
02063     Matrix A;
02064     Matrix B;
02065     Matrix C;
02066     B = "[1 2; 3 4]";
02067     C = "[-1 2; -3 4]";
02068     if( !A.Add( B, C ) )
02069       return false;
02070     // A
02071     // 0 4
02072     // 0 8
02073     \endcode
02074     
02075     \return true if successful, false otherwise.
02076     */
02077     bool Add( const Matrix &B, const Matrix &C );
02078 
02079     /**
02080     \brief  Subtract A = B-C. The result, A, is stored in this matrix. 
02081     
02082     \code
02083     Matrix A;
02084     Matrix B;
02085     Matrix C;
02086     B = "[1 2; 3 4]";
02087     C = "[-1 2; -3 4]";
02088     if( !A.Subtract( B, C ) )
02089       return false;
02090     // A
02091     // 2 0
02092     // 6 0
02093     \endcode
02094     
02095     \return true if successful, false otherwise.
02096     */
02097     bool Subtract( const Matrix &B, const Matrix &C );
02098 
02099     /**
02100     \brief  Multiply A = B*C. The result, A, is stored in this matrix. 
02101     
02102     \code
02103     Matrix A;
02104     Matrix B;
02105     Matrix C;
02106     B = "[1 2; 3 4]";
02107     C = "[-1 2; -3 4]";
02108     if( !A.Multiply( B, C ) )
02109       return false;
02110     // A
02111     //  -7  10
02112     // -15  22
02113     \endcode
02114     
02115     \return true if successful, false otherwise.
02116     */
02117     bool Multiply( const Matrix &B, const Matrix &C );
02118 
02119 
02120     /**
02121     \brief  Multiply A = transpose(B)*C. The result, A, is stored in this matrix. 
02122     
02123     \code
02124     Matrix A;
02125     Matrix B;
02126     Matrix C;
02127     B = "[1 2; 3 4]";
02128     C = "[-1 2; -3 4]";
02129     if( !A.TransposeMultiply( B, C ) )
02130       return false;
02131     // A
02132     // -10  14
02133     // -14  20
02134     \endcode
02135     
02136     \return true if successful, false otherwise.
02137     */
02138     bool TransposeMultiply( const Matrix &B, const Matrix &C );
02139 
02140 
02141     /**
02142     \brief  Multiply A = B*transpose(C). The result, A, is stored in this matrix. 
02143     
02144     \code
02145     Matrix A;
02146     Matrix B;
02147     Matrix C;
02148     B = "[1 2; 3 4]";
02149     C = "[-1 2; -3 4]";
02150     if( !A.MultiplyTranspose( B, C ) )
02151       return false;
02152     // A
02153     // 3  5
02154     // 5  7
02155     \endcode
02156     
02157     \return true if successful, false otherwise.
02158     */
02159     bool MultiplyTranspose( const Matrix &B, const Matrix &C );
02160     
02161 
02162   public: // Matlab/Octave style functions
02163 
02164     /**
02165     \brief  Compute the absolute value of each element of the matrix inplace.
02166     
02167     \code
02168     Matrix A;
02169     A = "[-1 2 3]";
02170     if( !A.Inplace_abs() )
02171       return false;
02172     // A 
02173     // [1 2 3]
02174     \endcode
02175 
02176     \return true if successful, false otherwise.    
02177     */
02178     bool Inplace_abs();
02179 
02180     /**
02181     \brief  Compute the arc-cosine of each element of the matrix inplace.
02182             Complex results are obtained if elements are greater than abs(1).
02183             Results in radians.
02184     \code
02185     Matrix A;
02186     A = "[0 0.5 1]";
02187     if( !A.Inplace_acos() )
02188       return false;
02189     // A 
02190     // [pi/2 pi/3 0]
02191     \endcode
02192     
02193     \return true if successful, false otherwise.   
02194     */
02195     bool Inplace_acos();
02196 
02197     /**
02198     \brief  Compute the arc-cosine of each element of the matrix inplace.
02199             Complex results are obtained if elements are greater than abs(1).
02200             Results in degrees.
02201     \code
02202     Matrix A;
02203     A = "[0 0.5 1]";
02204     if( !A.Inplace_acosd() )
02205       return false;
02206     // A 
02207     // [90 60 0]
02208     \endcode    
02209     
02210     \return true if successful, false otherwise.    
02211     */
02212     bool Inplace_acosd();
02213 
02214     /**
02215     \brief  Compute the inverse hyperbolic cosine of each element of the matrix inplace.
02216             Results in radians.
02217     \code
02218     Matrix A;
02219     A = "[0  1.0471975511966 1.5707963267949]";
02220     if( !A.Inplace_acosh() )
02221       return false;
02222     // A 
02223     // [0 pi/3 pi/2]
02224     \endcode        
02225     
02226     \return true if successful, false otherwise.   
02227     */
02228     bool Inplace_acosh();
02229 
02230     /**
02231     \brief  Compute the phase angle in radians of the elements of the matrix.
02232 
02233     \code
02234     Matrix A;
02235     A = "[1+1i  1-1i 3+2i]";
02236     if( !A.Inplace_acosh() )
02237       return false;
02238     // A 
02239     // [pi/4 -pi/4 0.588002603547568]
02240     \endcode    
02241     
02242     \return true if successful, false otherwise.    
02243     */
02244     bool Inplace_angle();
02245 
02246     /**
02247     \brief  Compute the arc-sine of each element of the matrix inplace.
02248             Complex results are obtained if elements are greater than abs(1).
02249             Results in radians.
02250     \code
02251     Matrix A;
02252     A = "[0  0.5 1.0]";
02253     if( !A.Inplace_asin() )
02254       return false;
02255     // A 
02256     // [0 pi/6 pi/2]
02257     \endcode   
02258     
02259     \return true if successful, false otherwise.    
02260     */    
02261     bool Inplace_asin();
02262 
02263     /**
02264     \brief  Compute the arc-sine of each element of the matrix inplace.
02265             Complex results are obtained if elements are greater than abs(1).
02266             Results in degrees.
02267     \code
02268     Matrix A;
02269     A = "[0  0.5 1.0]";
02270     if( !A.Inplace_asind() )
02271       return false;
02272     // A 
02273     // [0 30 90]
02274     \endcode   
02275     
02276     \return true if successful, false otherwise.    
02277     */
02278     bool Inplace_asind();
02279 
02280     /**
02281     \brief  Compute the inverse hyperbolic sine of each element of the matrix inplace.
02282             Results in radians.
02283     \code
02284     Matrix A;
02285     A = "[0  0.521095305493747  1.1752011936438]";
02286     if( !A.Inplace_asinh() )
02287       return false;
02288     // A 
02289     // [0 0.5 1]
02290     \endcode   
02291     
02292     \return true if successful, false otherwise.    
02293     */
02294     bool Inplace_asinh();
02295 
02296     /**
02297     \brief  Compute the arc-tangent of each element of the matrix inplace.
02298             Results in radians bounded [-pi/2, pi/2].
02299     \code
02300     Matrix A;
02301     A = "[0  1.73205080756888  1.63312393531954e+016]";
02302     if( !A.Inplace_atan() )
02303       return false;
02304     // A 
02305     // [0 pi/3 pi/2]
02306     \endcode   
02307     
02308     \return true if successful, false otherwise.    
02309     */
02310     bool Inplace_atan();
02311 
02312     /**
02313     \brief  Compute the arc-tangent of each element of the matrix inplace.
02314             Results in degrees bounded [-90, 90].
02315     \code
02316     Matrix A;
02317     A = "[0  1.73205080756888  1.63312393531954e+016]";
02318     if( !A.Inplace_atand() )
02319       return false;
02320     // A 
02321     // [0 60 90]
02322     \endcode   
02323         
02324     \return true if successful, false otherwise.    
02325     */
02326     bool Inplace_atand();
02327 
02328     /**
02329     \brief  Compute the inverse hyperbolic tangent of each element of the matrix inplace.
02330 
02331     \code
02332     Matrix A;
02333     A = "[0  0.46211715726001  0.761594155955765]";
02334     if( !A.Inplace_atanh() )
02335       return false;
02336     // A 
02337     // [0 0.5 1]
02338     \endcode   
02339     
02340     \return true if successful, false otherwise.    
02341     */
02342     bool Inplace_atanh();
02343 
02344     /**
02345     \brief  Create a column vector [start:increment:end) beginning at start
02346     with step size of increment until less than or equal to end. 
02347     Note that arguments must be real scalars. \n
02348 
02349     \code
02350     Matrix A;
02351     if( !A.Inplace_colon( 2, 2, 9 ) )
02352       return false;
02353     // A
02354     // [2; 4; 6; 8]
02355     if( !A.Inplace_colon( 2, -2, -9 ) )
02356       return false;
02357     // A
02358     // [2; 0; -2; -4; -6; -9;]    
02359     if( !A.Inplace_colon( -10, 0.01, 10 ) )
02360       return false;
02361     // A
02362     // [-10 -9.99 -9.98 ... 10]    
02363     \endcode
02364     
02365     \return true if successful, false otherwise.     
02366     */
02367     bool Inplace_colon( double start, double increment, double end );
02368 
02369     /**
02370     \brief  Compute the cosine of each element of the matrix inplace. This 
02371             function assumes radian values in the matrix.
02372     \code
02373     Matrix A;
02374     A = "[0  1.0471975511966  1.5707963267949]"; // [0 pi/3 pi/2]
02375     if( !A.Inplace_cos() )
02376       return false;
02377     // A
02378     // 1 0.5 0
02379     \endcode 
02380 
02381     \return true if successful, false otherwise.        
02382     */
02383     bool Inplace_cos();
02384 
02385     /**
02386     \brief  Compute the hyperbolic cosine of each element of the matrix inplace. This 
02387             function assumes radian values in the matrix.
02388     \code
02389     Matrix A;
02390     A = "[0  0.5 1]";
02391     if( !A.Inplace_cosh() )
02392       return false;
02393     // A
02394     // 1  1.12762596520638  1.54308063481524
02395     \endcode 
02396     
02397     \return true if successful, false otherwise.      
02398     */
02399     bool Inplace_cosh();
02400 
02401     /**
02402     \brief  Compute the cotangent of each element of the matrix inplace. This 
02403             function assumes radian values in the matrix.
02404     \code
02405     Matrix A;
02406     A = "[0  1.0471975511966  1.5707963267949]"; // [0  pi/3 pi/2]
02407     if( !A.Inplace_cot() )
02408       return false;
02409     // A
02410     // Inf  0.577350269189626  0
02411     \endcode 
02412     
02413     \return true if successful, false otherwise.      
02414     */
02415     bool Inplace_cot();
02416 
02417     /**
02418     \brief  Compute the hyperbolic cotangent of each element of the matrix inplace. This 
02419             function assumes radian values in the matrix.
02420     \code
02421     Matrix A;
02422     A = "[0  0.5  1]";
02423     if( !A.Inplace_coth() )
02424       return false;
02425     // A
02426     // Inf   2.16395341373865 1.31303528549933
02427     \endcode 
02428     
02429     \return true if successful, false otherwise.        
02430     */
02431     bool Inplace_coth();
02432 
02433     /**
02434     \brief  Complex conjugate. z = x+yi. conj(z) = x-yi.
02435 
02436     \code
02437     Matrix A;
02438     A = "[2-2i -3+2i]";
02439     if( !A.Inplace_conj() )
02440       return false;
02441     // A
02442     // 2+2i  -3-2i
02443     \endcode
02444 
02445     \return true if successful, false otherwise.        
02446     */
02447     bool Inplace_conj();
02448 
02449 
02450     /**
02451     \brief  Compute the exponential of each element of the matrix inplace. 
02452             If real, computes the exp(value) of each element in the matrix.
02453             If complex, computes exp(M) = exp(real)*(cos(imag)+i*sin(imag)).
02454     \code
02455     Matrix A;
02456     A = "[1 2]";
02457     if( !A.Inplace_exp() )
02458       return false;
02459     // A
02460     //  2.71828182845905  7.38905609893065
02461     \endcode
02462 
02463     \return true if successful, false otherwise.        
02464     */
02465     bool Inplace_exp();
02466 
02467     /**
02468     \brief  Create an indentity matrix with nrows and ncols.
02469     
02470     \code
02471     Matrix A;
02472     if( !A.eye(3,3) )
02473       return false;
02474     // A
02475     // 1 0 0 
02476     // 0 1 0 
02477     // 0 0 1
02478     \endcode
02479 
02480     \return true if successful, false otherwise.        
02481     */
02482     bool Inplace_eye( const unsigned nrows, const unsigned ncols );
02483 
02484 
02485      /**
02486     \brief  Imaginary part of the complex matrix. z = x+yi. real(z) = y.
02487 
02488     \code
02489     Matrix A;
02490     A = "[2-2i -3+2i]";
02491     if( !A.Inplace_imag() )
02492       return false;
02493     // A
02494     // -2  2
02495     \endcode
02496 
02497     \return true if successful, false otherwise.        
02498     */
02499     bool Inplace_imag();
02500 
02501 
02502     /**
02503     \brief  Compute the log base 2 of the elements of the matrix.
02504             Complex results if elements are negative. 
02505     \code
02506     Matrix A;
02507     A = "[2 32]";
02508     if( !A.Inplace_log2() )
02509       return false;
02510     // A
02511     // 1 5
02512     \endcode
02513     
02514     \return true if successful, false otherwise.     
02515     */
02516     bool Inplace_log2();
02517 
02518     /**
02519     \brief  Compute the log base 10 of the elements of the matrix.
02520             Complex results if elements are negative. 
02521     \code
02522     Matrix A;
02523     A = "[10 1000]";
02524     if( !A.Inplace_log10() )
02525       return false;
02526     // A
02527     // 1 3
02528     \endcode
02529     
02530     \return true if successful, false otherwise.   
02531     */
02532     bool Inplace_log10();
02533 
02534     /**
02535     \brief  Create a matrix of nrows by ncols filled with 1.0.
02536 
02537     \code
02538     Matrix A;
02539     if( !A.Inplace_ones(2,3) )
02540       return false;
02541     // A
02542     // 1 1 1
02543     // 1 1 1
02544     \endcode
02545     
02546     \return true if successful, false otherwise.     
02547     */
02548     bool Inplace_ones( const unsigned nrows, const unsigned ncols );
02549 
02550     
02551     /**
02552     \brief  Produce a matrix that is composed of pseudo-random numbers.
02553     Values are elements are uniform distribution [0,1].
02554 
02555     \code
02556     Matrix A;
02557     if( !A.Inplace_rand(1000,1) ) // create a 1000x1 vector with uniform distribution [0,1]
02558       return false;
02559     \endcode
02560     
02561     \return true if successful, false otherwise.      
02562     */
02563     bool Inplace_rand( const unsigned nrows, const unsigned ncols, const unsigned seed = rand() );
02564 
02565     /**
02566     \brief  Produce a matrix that is composed of pseudo-random numbers. 
02567     Values are elements are standard normal distribution with mean zero, 
02568     variance of one and standard of deviation one. N(0,1)
02569 
02570     \code
02571     Matrix A;
02572     if( !A.Inplace_randn(1000,1) ) // create a 1000x1 vector with standard normal distribution N[0,1]
02573       return false;
02574     \endcode
02575     
02576     \return true if successful, false otherwise.      
02577     */
02578     bool Inplace_randn( const unsigned nrows, const unsigned ncols, const unsigned seed = rand() );
02579 
02580     /**
02581     \brief  Real part of the complex matrix. z = x+yi. real(z) = x.
02582 
02583     \code
02584     Matrix A;
02585     A = "[2-2i -3+2i]";
02586     if( !A.Inplace_real() )
02587       return false;
02588     // A
02589     // 2  3
02590     \endcode
02591     
02592     \return true if successful, false otherwise.      
02593     */
02594     bool Inplace_real();
02595 
02596     /**
02597     \brief  Compute the sine of each element of the matrix inplace. This 
02598             function assumes radian values in the matrix.
02599     \code
02600     Matrix A;
02601     A = "[0         0.523598775598299           1.5707963267949]"; //[0 pi/6 pi/2]
02602     if( !A.Inplace_sin() )
02603       return false;
02604     // A
02605     // 0 0.5 1
02606     \endcode
02607     
02608     \return true if successful, false otherwise.      
02609     */
02610     bool Inplace_sin();
02611 
02612     /**
02613     \brief  Compute the sinc of each element*pi of the matrix inplace. 
02614     i.e. y = sin(pi*x)./(pi*x).
02615 
02616     \code
02617     Matrix A;
02618     A = "[0  0.523598775598299  1.5707963267949]"; //[0 pi/6 pi/2]
02619     if( !A.Inplace_sinc() )
02620       return false;
02621     // A
02622     // 1  0.606257160324575  -0.19765087483668
02623     \endcode
02624     
02625     \return true if successful, false otherwise.      
02626     */
02627     bool Inplace_sinc();
02628 
02629     /**
02630     \brief  Compute the hyperbolic sine of each element of the matrix inplace. This 
02631             function assumes radian values in the matrix.
02632     \code
02633     Matrix A;
02634     A = "[0 0.5 1]";
02635     if( !A.Inplace_sinh() )
02636       return false;
02637     // A
02638     // 0  0.521095305493747  1.1752011936438
02639     \endcode
02640     
02641     \return true if successful, false otherwise.     
02642     */
02643     bool Inplace_sinh();
02644 
02645     /**
02646     \brief  Compute the sqrt of each element of the matrix inplace.
02647 
02648     \code
02649     Matrix A;
02650     A = "[0 9 121]";
02651     if( !A.Inplace_sqrt() )
02652       return false;
02653     // A
02654     // 0  3  11
02655     \endcode
02656     
02657     \return true if successful, false otherwise.       
02658     */
02659     bool Inplace_sqrt();
02660 
02661     /**
02662     \brief  Compute the tangent of each element of the matrix inplace. This 
02663             function assumes radian values in the matrix.
02664     \code
02665     Matrix A;
02666     A = "[0  0.785398163397448  1.5707963267949]"; // [0 pi/4 pi/2]
02667     if( !A.Inplace_tan() )
02668       return false;
02669     // A
02670     // 0  1  1.63312393531954e+016
02671     \endcode
02672     
02673     \return true if successful, false otherwise.    
02674     */
02675     bool Inplace_tan();
02676 
02677     /**
02678     \brief  Compute the hyperbolic tangent of each element of the matrix inplace. This 
02679             function assumes radian values in the matrix.
02680     \code
02681     Matrix A;
02682     A = "[0  0.785398163397448  1.5707963267949]"; // [0 pi/4 pi/2]
02683     if( !A.Inplace_tanh() )
02684       return false;
02685     // A
02686     // 0  0.655794202632672  0.917152335667274
02687     \endcode
02688 
02689     \return true if successful, false otherwise.      
02690     */
02691     bool Inplace_tanh();
02692 
02693     /**
02694     \brief  Create a matrix of nrows by ncols filled with 0.0.
02695 
02696     \code
02697     Matrix A;
02698     if( !A.Inplace_zeros(2,3) )
02699       return false;
02700     // A
02701     // 0 0 0
02702     // 0 0 0
02703     \endcode
02704     
02705     \return true if successful, false otherwise.        
02706     */
02707     bool Inplace_zeros( const unsigned nrows, const unsigned ncols );
02708 
02709 
02710   public: // Statistics
02711 
02712     /**
02713     \brief  Computes the value of the largest absolute element and its index.
02714 
02715     \code
02716     Matrix A;
02717     unsigned row;
02718     unsigned col;
02719     double value;
02720     A = "[1 2 3 4 5]";
02721     if( !A.GetStats_MaxAbs( row, col, value ) )
02722       return false;
02723     // row   == 0
02724     // col   == 4
02725     // value == 5
02726     \endcode
02727     
02728     \return true if successful, false otherwise.
02729     */
02730     bool GetStats_MaxAbs(unsigned &row, unsigned &col, double &value );
02731 
02732     /**
02733     \brief  Computes the value (re+im*j) of the maximum element and its index.  
02734             When complex the maximum absolute value is determined.
02735     \code
02736     Matrix A;
02737     unsigned row;
02738     unsigned col;
02739     double re;
02740     double im;
02741     A = "[1 2 3 4 5-22i]";
02742     if( !A.GetStats_Max( row, col, re, im ) )
02743       return false;
02744     // row   == 0
02745     // col   == 4
02746     // re    == 5
02747     // im    == -22
02748     \endcode
02749     
02750     \return true if successful, false otherwise.
02751     */
02752     bool GetStats_Max(unsigned &row, unsigned &col, double &re, double &im );
02753 
02754     /**
02755     \brief  Computes the value (re+im*j) of the maximum element.  
02756             When complex the maximum absolute value is determined.
02757     \code
02758     Matrix A;
02759     double re;
02760     double im;
02761     A = "[1 2 3 4 5-22i]";
02762     if( !A.GetStats_MaxVal( re, im ) )
02763       return false;
02764     // re    == 5
02765     // im    == -22
02766     \endcode
02767 
02768     \return true if successful, false otherwise.
02769     */
02770     bool GetStats_MaxVal(double &re, double &im );
02771 
02772     /**
02773     \brief  Computes the value of the largest absolute column element and its row index.
02774     
02775     \code
02776     Matrix A;
02777     unsigned row;
02778     double value;
02779     A = "[1 2 3; 4 -5 6]";
02780     if( !A.GetStats_MaxAbsCol( 1, value, row ) )
02781       return false;
02782     // value == 5
02783     // row   == 1
02784     \endcode
02785 
02786     \return true if successful, false otherwise.
02787     */
02788     bool GetStats_MaxAbsCol(const unsigned col, double &value, unsigned &row );
02789 
02790     /**
02791     \brief  Computes the value (re+im*j) of the maximum column element and its row index.  
02792     \return true if successful, false otherwise.
02793     */
02794     bool GetStats_MaxCol(const unsigned col, double &re, double &im, unsigned &row );
02795 
02796     /**
02797     \brief  Computes the value (re+im*j) of the maximum column element.  
02798     \return true if successful, false otherwise.
02799     */
02800     bool GetStats_MaxColVal(const unsigned col, double &re, double &im );
02801 
02802     /**
02803     \brief  Computes the value of the largest absolute row element and its column index.
02804     \return true if successful, false otherwise.
02805     */
02806     bool GetStats_MaxAbsRow(const unsigned row, double &value, unsigned &col );
02807 
02808     /**
02809     \brief  Computes the value (re+im*j) of the maximum row element and its column index.  
02810     \return true if successful, false otherwise.
02811     */
02812     bool GetStats_MaxRow(const unsigned row, double &re, double &im, unsigned &col );
02813 
02814     /**
02815     \brief  Computes the value (re+im*j) of the maximum row element.  
02816     \return true if successful, false otherwise.
02817     */
02818     bool GetStats_MaxRowVal(const unsigned row, double &re, double &im );
02819 
02820     /**
02821     \brief  Computes the value of the smallest absolute element and its index.
02822     \return true if successful, false otherwise.
02823     */
02824     bool GetStats_MinAbs(unsigned &row, unsigned &col, double &value );
02825 
02826     /**
02827     \brief  Computes the value (re+im*j) of the minimum element and its index.  
02828     \return true if successful, false otherwise.
02829     */
02830     bool GetStats_Min(unsigned &row, unsigned &col, double &re, double &im );
02831 
02832     /**
02833     \brief  Computes the value (re+im*j) of the minimum element.  
02834     \return true if successful, false otherwise.
02835     */
02836     bool GetStats_MinVal(double &re, double &im );
02837 
02838     /**
02839     \brief  Computes the value of the smallest absolute column element and its row index.
02840     \return true if successful, false otherwise.
02841     */
02842     bool GetStats_MinAbsCol(const unsigned col, double &value, unsigned &row );
02843 
02844     /**
02845     \brief  Computes the value (re+im*j) of the minimum column element and its row index.  
02846     \return true if successful, false otherwise.
02847     */
02848     bool GetStats_MinCol(const unsigned col, double &re, double &im, unsigned &row );
02849 
02850     /**
02851     \brief  Computes the value (re+im*j) of the minimum column element.  
02852     \return true if successful, false otherwise.
02853     */
02854     bool GetStats_MinColVal(const unsigned col, double &re, double &im );
02855 
02856     /**
02857     \brief  Computes the value of the smallest absolute row element and its column index.
02858     \return true if successful, false otherwise.
02859     */
02860     bool GetStats_MinAbsRow(const unsigned row, double &value, unsigned &col );
02861 
02862     /**
02863     \brief  Computes the value (re+im*j) of the minimum row element and its column index.  
02864     \return true if successful, false otherwise.
02865     */
02866     bool GetStats_MinRow(const unsigned row, double &re, double &im, unsigned &col );
02867 
02868     /**
02869     \brief  Computes the value (re+im*j) of the minimum row element.  
02870     \return true if successful, false otherwise.
02871     */
02872     bool GetStats_MinRowVal(const unsigned row, double &re, double &im );
02873 
02874     /**
02875     \brief  Computes the range of the data in the specified column. 
02876     Range = MaxVal - MinVal.
02877     If the matrix is real, only the real value, re is set, im = 0. 
02878     If the matrix is complex, both re and im are set.
02879     \return true if successful, false otherwise.
02880     */
02881     bool GetStats_ColRange( const unsigned col, double &re, double &im );
02882 
02883     /**
02884     \brief  Computes the range of the data in the specified row. 
02885     Range = MaxVal - MinVal.
02886     If the matrix is real, only the real value, re is set, im = 0. 
02887     If the matrix is complex, both re and im are set.
02888     \return true if successful, false otherwise.
02889     */
02890     bool GetStats_RowRange( const unsigned row, double &re, double &im );
02891 
02892     /**
02893     \brief  Computes the range of the data in the matrix. 
02894     Range = MaxVal - MinVal.
02895     If the matrix is real, only the real value, re is set, im = 0. 
02896     If the matrix is complex, both re and im are set.
02897     \return true if successful, false otherwise.
02898     */
02899     bool GetStats_Range( double &re, double &im );
02900 
02901     /**
02902     \brief  Computes the sum for the specified column.
02903     If the matrix is real, only the real value, re is set, im = 0. 
02904     If the matrix is complex, both re and im are set.
02905     \return true if successful, false otherwise.
02906     */
02907     bool GetStats_ColumnSum( const unsigned col,  double &re, double &im );
02908 
02909     /**
02910     \brief  Computes the sum for the specified row.
02911     If the matrix is real, only the real value, re is set, im = 0. 
02912     If the matrix is complex, both re and im are set.
02913     \return true if successful, false otherwise.
02914     */
02915     bool GetStats_RowSum( const unsigned row, double &re, double &im );
02916 
02917     /**
02918     \brief  Computes the sum for the matrix.
02919     If the matrix is real, only the real value, re is set, im = 0. 
02920     If the matrix is complex, both re and im are set.
02921     \return true if successful, false otherwise.
02922     */
02923     bool GetStats_Sum( double &re, double &im );
02924 
02925     /**
02926     \brief  Computes the sample mean for the specified column.
02927     If the matrix is real, only the real value, re is set, im = 0. 
02928     If the matrix is complex, both re and im are set.
02929     \return true if successful, false otherwise.
02930     */
02931     bool GetStats_ColumnMean( const unsigned col, double &re, double &im );
02932 
02933     /**
02934     \brief  Computes the sample mean for the specified row.
02935     If the matrix is real, only the real value, re is set, im = 0. 
02936     If the matrix is complex, both re and im are set.
02937     \return true if successful, false otherwise.
02938     */
02939     bool GetStats_RowMean( const unsigned row, double &re, double &im );
02940 
02941     /**
02942     \brief  Computes the sample mean for the matrix.
02943     If the matrix is real, only the real value, re is set, im = 0. 
02944     If the matrix is complex, both re and im are set.
02945     \return true if successful, false otherwise.
02946     */
02947     bool GetStats_Mean( double &re, double &im );
02948 
02949     /**
02950     \brief  Computes the sample standard deviation for the specified column.
02951     \return true if successful, false otherwise.
02952     */
02953     bool GetStats_ColumnStdev( const unsigned col, double &value );
02954 
02955     /**
02956     \brief  Computes the sample standard deviation for the specified row.
02957     \return true if successful, false otherwise.
02958     */
02959     bool GetStats_RowStdev( const unsigned row, double &value );
02960 
02961     /**
02962     \brief  Computes the sample standard deviation for the matrix.
02963     \return true if successful, false otherwise.
02964     */
02965     bool GetStats_Stdev( double &value );
02966 
02967     /**
02968     \brief  Computes the sample variance for the specified column.
02969     \return true if successful, false otherwise.
02970     */
02971     bool GetStats_ColumnVar( const unsigned col, double &value );
02972 
02973     /**
02974     \brief  Computes the sample variance for the specified row.
02975     \return true if successful, false otherwise.
02976     */
02977     bool GetStats_RowVar( const unsigned row, double &value );
02978 
02979     /**
02980     \brief  Computes the sample variance for the matrix.
02981     \return true if successful, false otherwise.
02982     */
02983     bool GetStats_Var( double &value );
02984 
02985     /**
02986     \brief  Computes the norm of the specified column.
02987     If real, norm = sqrt( sum( val*val ) ).
02988     If complex, norm = sqrt( sum( val*conjugate(val) ) ).
02989     \return true if successful, false otherwise.
02990     */
02991     bool GetStats_ColumnNorm( const unsigned col, double &value );
02992 
02993     /**
02994     \brief  Computes the norm of the specified row.
02995     If real, norm = sqrt( sum( val*val ) ).
02996     If complex, norm = sqrt( sum( val*conjugate(val) ) ).
02997     \return true if successful, false otherwise.
02998     */
02999     bool GetStats_RowNorm( const unsigned row, double &value );
03000 
03001     /**
03002     \brief  Computes the norm of the matrix.
03003     If real, norm = sqrt( sum( val*val ) ).
03004     If complex, norm = sqrt( sum( val*conjugate(val) ) ).
03005     \return true if successful, false otherwise.
03006     */
03007     bool GetStats_Norm( double &value );
03008 
03009     /**
03010     \brief  Computes the sample RMS value for the specified column.
03011     \return true if successful, false otherwise.
03012     */
03013     bool GetStats_ColumnRMS( const unsigned col, double &value );
03014 
03015     /**
03016     \brief  Computes the sample RMS value for the specified row.
03017     \return true if successful, false otherwise.
03018     */
03019     bool GetStats_RowRMS( const unsigned row, double &value );
03020 
03021     /**
03022     \brief  Computes the sample RMS value for the matrix.
03023     \return true if successful, false otherwise.
03024     */
03025     bool GetStats_RMS( double &value );
03026 
03027 
03028     /**
03029     \brief  Computes the sample skewness value for the specified column.
03030     The skewness is the third central moment divided by the cube of the standard deviation.
03031     If the matrix is real, only the real value, re is set, im = 0. 
03032     If the matrix is complex, both re and im are set.
03033     \return true if successful, false otherwise.
03034     */
03035     bool GetStats_ColumnSkewness( const unsigned col, double &re, double &im );
03036 
03037     /**
03038     \brief  Computes the sample skewness value for the specified row.
03039     The skewness is the third central moment divided by the cube of the standard deviation.
03040     If the matrix is real, only the real value, re is set, im = 0. 
03041     If the matrix is complex, both re and im are set.
03042     \return true if successful, false otherwise.
03043     */
03044     bool GetStats_RowSkewness( const unsigned row, double &re, double &im );
03045 
03046     /**
03047     \brief  Computes the sample skewness value for the matrix.
03048     The skewness is the third central moment divided by the cube of the standard deviation.
03049     If the matrix is real, only the real value, re is set, im = 0. 
03050     If the matrix is complex, both re and im are set.
03051     \return true if successful, false otherwise.
03052     */
03053     bool GetStats_Skewness( double &re, double &im );
03054 
03055 
03056 
03057     /**
03058     \brief  Computes the sample kurtosis value for the specified column.
03059     The kurtosis is the fourth central moment divided by fourth power of the standard deviation.
03060     If the matrix is real, only the real value, re is set, im = 0. 
03061     If the matrix is complex, both re and im are set.
03062     To adjust the computed kurtosis value for bias, subtract 3 from the real component.
03063     Reference: http://en.wikipedia.org/wiki/Kurtosis.
03064     Reference: http://mathworld.wolfram.com/Kurtosis.html (kurtosis proper is computed).
03065     
03066     \return true if successful, false otherwise.
03067     */
03068     // 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}
03069     bool GetStats_ColumnKurtosis( const unsigned col, double &re, double &im );
03070 
03071     /**
03072     \brief  Computes the sample kurtosis value for the specified row.
03073     The kurtosis is the fourth central moment divided by fourth power of the standard deviation.
03074     If the matrix is real, only the real value, re is set, im = 0. 
03075     If the matrix is complex, both re and im are set.
03076     To adjust the computed kurtosis value for bias, subtract 3 from the real component.
03077     Reference: http://en.wikipedia.org/wiki/Kurtosis.
03078     Reference: http://mathworld.wolfram.com/Kurtosis.html (kurtosis proper is computed).
03079     
03080     \return true if successful, false otherwise.
03081     */
03082     // 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}
03083     bool GetStats_RowKurtosis( const unsigned row, double &re, double &im );
03084 
03085     /**
03086     \brief  Computes the sample kurtosis value for the matrix.
03087     The kurtosis is the fourth central moment divided by fourth power of the standard deviation.
03088     If the matrix is real, only the real value, re is set, im = 0. 
03089     If the matrix is complex, both re and im are set.
03090     To adjust the computed kurtosis value for bias, subtract 3 from the real component.
03091     Reference: http://en.wikipedia.org/wiki/Kurtosis.
03092     Reference: http://mathworld.wolfram.com/Kurtosis.html (kurtosis proper is computed).
03093     
03094     \return true if successful, false otherwise.
03095     */
03096     // 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}
03097     bool GetStats_Kurtosis( double &re, double &im );
03098 
03099 
03100   public: // Matrix Specific operations
03101 
03102     /**
03103     /// \brief  Computes the trace of M where M is a square matrix.
03104     /// Trace = Sum of diagonal elements.
03105     /// If the matrix is real, only the real value, re is set, im = 0. 
03106     /// If the matrix is complex, both re and im are set.
03107     /// \return true if successful, false otherwise.
03108     */
03109     bool GetTrace( double &re, double &im );
03110 
03111     /**
03112     /// \brief  Computes the determinatnt of the square matrix M.
03113     /// If the matrix is real, only the real value, re is set, im = 0. 
03114     /// If the matrix is complex, both re and im are set.
03115     */
03116     bool GetDeterminant( double &re, double &im );
03117 
03118 
03119 
03120   public: // Safe operations that set a Matrix argument. Rather than Matrix as a return type.
03121 
03122     /**
03123     /// \brief  Sets the diagonal elements of the matrix into DiagonalVector as a column vector.
03124     /// \return true if successful, false otherwise.
03125     */
03126     bool GetDiagonal( Matrix& DiagonalVector );
03127 
03128     /**
03129     /// \brief  Computes a moving average using N lead samples and M lagging samples
03130     /// for the specified column and stores it in MovAvg.
03131     /// \return true if successful, false otherwise.  
03132     */
03133     bool GetColumnMovAvg( const unsigned col, const unsigned lead, const unsigned lag, Matrix &MovAvg );
03134 
03135     /**
03136     /// \brief  Computes a moving average using N lead samples and M lagging samples
03137     /// for the matrix and stores it in MovAvg.
03138     /// \return true if successful, false otherwise.  
03139     */
03140     bool GetMovAvg( const unsigned lead, const unsigned lag, Matrix &MovAvg );
03141 
03142     /**
03143     /// \brief  Computes: InvATA = inverse( transpose(A) * A ). Assumes this matrix is A.
03144     /// e.g. Matrix A; Matrix InvATA; A = ...; bool result = A.GetATAInverse( InvATA );
03145     /// \return true if successful, false otherwise.  
03146     */
03147     bool GetATAInverse( Matrix &InvATA );
03148 
03149     /**
03150     /// \brief  LU factorization.
03151     /// Performs a factorization to produce a unit lower triangular matrix, L, 
03152     /// an upper triangular matrix, U, and permutation matrix P so that
03153     /// P*X = L*U.
03154     /// P, L and U are copmuted correctly if IsFullRank is set to true.
03155     /// e.g. Matrix A; A = ...; bool isFullRank, Matrix L,U,P; bool result = A.GetLUFactorization( isFullRank, P, L, U );
03156     /// \return true if successful, false otherwise.  
03157     */
03158     bool GetLUFactorization( bool &isFullRank, Matrix &P, Matrix &L, Matrix &U );
03159 
03160 
03161     /**
03162     \brief  Lower x Diagonal x transpose(Lower): matrix factorization.
03163     This method avoids using square roots and can be used for any square, full rank, symmetrical matrix .
03164 
03165     \code
03166     Matrix LDLt = "[3 6;6 16]";
03167     Matrix L;
03168     Matrix d;
03169     bool result = LDLt.GetLDLt( L, d );
03170     // L == [1 0;2 1]
03171     // d == [3; 4]; i.e. D == [3 0;0 4]
03172     \endcode
03173 
03174     \return true if successful, false otherwise.  
03175     */
03176     bool GetLDLt( 
03177       Matrix& L,  //!< A unit lower triangular matrix.
03178       Matrix& d,  //!< The diagonal vector from the diagonal of the D matrix.
03179       bool checkSymmetric = true //!< Enforce a symmetry check. Runs faster if disabled.
03180       );
03181 
03182     /**
03183     \brief  Upper x Diagonal x transpose(Upper): matrix factorization.
03184     This method avoids using square roots and can be used for any square, full rank, symmetrical matrix .
03185 
03186     \code
03187     Matrix UDUt = "[19 8;8 4]";
03188     Matrix U;
03189     Matrix d;
03190     bool result = UDUt.GetUDUt( U, d );
03191     // U == [1 0;2 1]
03192     // d == [3; 4]; i.e. D == [3 0;0 4]
03193     \endcode
03194 
03195     \return true if successful, false otherwise.  
03196     */
03197     bool GetUDUt( 
03198       Matrix& U,  //!< A unit upper triangular matrix.
03199       Matrix& d,  //!< The diagonal vector from the diagonal of the D matrix.
03200       bool checkSymmetric = true //!< Enforce a symmetry check. Runs faster if disabled.
03201       );
03202 
03203     /**
03204     /// \brief  Retrieve the elements of the matrix specified by the index vectors. 
03205     /// The index vectors must be nx1 and preferably not complex.
03206     ///
03207     /// \return true if successful, false otherwise.
03208     */
03209     bool GetIndexedValues( Matrix& RowIndex, Matrix& ColIndex, Matrix& Result );
03210 
03211 
03212     /**
03213     \brief  Set the elements of the matrix specified by the index vectors. 
03214             The index vectors must be nx1 and preferably not complex.
03215     
03216     \return true if successful, false otherwise.
03217     */
03218     bool SetIndexedValues( Matrix& RowIndex, Matrix& ColIndex, Matrix& SourceData );
03219 
03220     /*
03221     \brief  Set the index vector so that it contains are the indices of values that are equal
03222             to the real value specified with the given tolerance from the column of this matrix.            
03223 
03224     \return true if successful, false otherwise.
03225     */
03226     bool Find_EqualTo( 
03227       Matrix &IndexVector,            //!< Store the indexed values in this vector (nx1)
03228       const unsigned col,             //!< Search this column (zero-based index).
03229       const double value,             //!< Search for this value.
03230       const double tolerance = 1e-12  //!< Search with this tolerance.
03231       );     
03232 
03233     /*
03234     \brief  Set the index vector so that it contains are the indices of values that are equal
03235             to the complex value specified with the given tolerance from the column of this matrix.
03236 
03237     \return true if successful, false otherwise.
03238     */
03239     bool Find_EqualTo( 
03240       Matrix &IndexVector,    //!< Store the indexed values in this vector (nx1)
03241       const unsigned col,     //!< Search this column (zero-based index).
03242       const double value_re,  //!< Search for this complex value (re+i*im).
03243       const double value_im,  //!< Search for this complex value (re+i*im).
03244       const double tolerance  //!< Search with this tolerance. No default parameter so there is no function overload confusion.
03245       );     
03246 
03247 
03248     /*
03249     \brief  Set the index vector so that it contains are the indices of values that are not equal
03250             to the real value specified with the given tolerance from the column of this matrix.            
03251 
03252     \return true if successful, false otherwise.
03253     */
03254     bool Find_NotEqualTo( 
03255       Matrix &IndexVector,            //!< Store the indexed values in this vector (nx1)
03256       const unsigned col,             //!< Search this column (zero-based index).
03257       const double value,             //!< Search for this value.
03258       const double tolerance = 1e-12  //!< Search with this tolerance.
03259       );     
03260 
03261     /*
03262     \brief  Set the index vector so that it contains are the indices of values that are not equal
03263             to the complex value specified with the given tolerance from the column of this matrix.
03264 
03265     \return true if successful, false otherwise.
03266     */
03267     bool Find_NotEqualTo( 
03268       Matrix &IndexVector,    //!< Store the indexed values in this vector (nx1)
03269       const unsigned col,     //!< Search this column (zero-based index).
03270       const double value_re,  //!< Search for this complex value (re+i*im).
03271       const double value_im,  //!< Search for this complex value (re+i*im).
03272       const double tolerance  //!< Search with this tolerance. No default parameter so there is no function overload confusion.
03273       );
03274 
03275     /**
03276     \brief  Set the index vector so that it contains are the indices of values that are less than
03277             the value specified from the column specified of this matrix. Complex values are compared
03278             in terms of magnitude (i.e. sqrt(re*re + im*im)).
03279 
03280     \return true if successful, false otherwise.    
03281     */
03282     bool Find_LessThan( 
03283       Matrix &IndexVector, //!< Store the indexed values in this vector (nx1)
03284       const unsigned col,  //!< Search this column (zero-based index).
03285       const double value   //!< Search for this value.
03286       );
03287    
03288     /**
03289     \brief  Set the index vector so that it contains are the indices of values that are more than
03290             the value specified from the column specified of this matrix. Complex values are compared
03291             in terms of magnitude (i.e. sqrt(re*re + im*im)).
03292 
03293     \return true if successful, false otherwise.    
03294     */
03295     bool Find_MoreThan( 
03296       Matrix &IndexVector, //!< Store the indexed values in this vector (nx1)
03297       const unsigned col,  //!< Search this column (zero-based index).
03298       const double value   //!< Search for this value.
03299       );
03300     
03301 
03302   public: // Advanced Functionality
03303 
03304     /**
03305     \brief  Plot one series, X vs Y. The i'th column (x-axis) vs 
03306             j'th column (y-axis) of the Matrix directly to a compressed 
03307             (run-length-encoded) bitamp.
03308     \code
03309     bool TryPlot()
03310     {
03311       bool result;
03312       Matrix T; // time
03313       Matrix S; // sin(time)
03314       Matrix TS; // time | sin(time)
03315       double pi = 3.1415926535897;
03316       result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
03317       if( !result )
03318         return false;
03319       S = T;
03320       result = S.Inplace_sin();
03321       if( !result )
03322         return false;
03323       TS = T;
03324       result = TS.Concatonate( S );
03325       if( !result )
03326         return false;
03327       result = TS.Plot( 0, 1 ); // makes plot.bmp
03328       if( !result )
03329         return false;
03330       result = F.Plot( 0, 1, "test1.bmp", "A Sinusoid", "time (s)", "voltage (V)", "sinusoid", "(V)" ); 
03331       if( !result )
03332         return false;
03333       return true;
03334     }
03335     \endcode
03336     \return true if successful, false otherwise.
03337     */
03338     bool Plot( 
03339       const unsigned x_col,                //!< The column index (0toN-1) with the x series data (if this is the same as y_col, then the index is plotted as x).
03340       const unsigned y_col,                //!< The column index (0toN-1) with the y series data.      
03341       const std::string bmpfilename = "plot.bmp", //!< The file name (or full path name) of the output bitmap file.
03342       const std::string title = "",        //!< The plot title.
03343       const std::string xlabel = "",       //!< The x-axis label.
03344       const std::string ylabel = "",       //!< The y-axis label.
03345       const std::string series_label = "", //!< The series label.
03346       const std::string units = "",        //!< The series data units.
03347       const bool isXGridOn = true,         //!< A boolean to indicate if the x grid lines are on.
03348       const bool isYGridOn = true,         //!< A boolean to indicate if the y grid lines are on.  
03349       const bool includeStats = true,      //!< A boolean to indicate if statistics info should be included on the plot.  
03350       const unsigned precisionStats = 5,   //!< The number of significant digits in the statistics.
03351       const unsigned plot_height_cm = 8,   //!< The plot height in cm.
03352       const unsigned plot_width_cm = 10    //!< The plot width in cm.
03353       );
03354 
03355     /**
03356     \brief  Plot two series, X vs Y1, Y2 using columns of the Matrix.
03357             Plots directly to a compressed (run-length-encoded) bitamp.
03358     \code
03359     bool TryPlot2()
03360     {
03361       bool result;
03362       Matrix T; // time
03363       Matrix S; // sin(time)
03364       Matrix C; // sin(time)
03365       Matrix F; // time | sin(time) | cos(time)
03366       double pi = 3.1415926535897;
03367       result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
03368       if( !result )
03369         return false;
03370       S = T;
03371       result = S.Inplace_sin();
03372       if( !result )
03373         return false;
03374       C = T;
03375       result = C.Inplace_cos();
03376       if( !result )
03377         return false;
03378       F = T;
03379       result = F.Concatonate( S );
03380       if( !result )
03381         return false;
03382       result = F.Concatonate( C );
03383       if( !result )
03384         return false;
03385       result = F.Plot( 0, 1, 2 ); // makes plot2.bmp
03386       if( !result )
03387         return false;
03388       result = F.Plot( 0, 1, 2, "test2.bmp", "Two Sinusoids", "time (s)", "voltage (V)", "sine", "(V)", "cosine", "(V)" );   
03389       if( !result )
03390         return false;
03391       return true;
03392     }
03393     \endcode
03394     \return true if successful, false otherwise.
03395     */
03396     bool Plot( 
03397       const unsigned x_col,                //!< The column index (0toN-1) with the x series data.
03398       const unsigned y_col_1,              //!< The column index (0toN-1) with the y_1 series data.
03399       const unsigned y_col_2,              //!< The column index (0toN-1) with the y_2 series data.      
03400       const std::string bmpfilename = "plot2.bmp", //!< The file name (or full path name) of the output bitmap file.
03401       const std::string title = "",           //!< The plot title.
03402       const std::string xlabel = "",          //!< The x-axis label.
03403       const std::string ylabel = "",          //!< The y-axis label.
03404       const std::string series_label_1 = "",  //!< The series label.
03405       const std::string units_1 = "",         //!< The series data units.
03406       const std::string series_label_2 = "",  //!< The series label.
03407       const std::string units_2 = "",         //!< The series data units.
03408       const bool isXGridOn = true,       //!< A boolean to indicate if the x grid lines are on.
03409       const bool isYGridOn = true,       //!< A boolean to indicate if the y grid lines are on.  
03410       const bool includeStats = true,    //!< A boolean to indicate if statistics info should be included on the plot.  
03411       const unsigned precisionStats = 5, //!< The number of significant digits in the statistics.
03412       const unsigned plot_height_cm = 8, //!< The plot height in cm.
03413       const unsigned plot_width_cm = 10  //!< The plot width in cm.
03414       );
03415 
03416     /**
03417     \brief  Plot three series, X vs Y1, Y2, Y3 using columns of the Matrix.
03418             Plots directly to a compressed (run-length-encoded) bitamp.
03419     \code
03420     bool TryPlot3()
03421     {
03422       bool result;
03423       Matrix T; // time
03424       Matrix S; // sin(time)
03425       Matrix C; // sin(time)
03426       Matrix Sinc; // sin(time)
03427       Matrix F; // time | sin(time) | cos(time) | sinc(time)
03428       double pi = 3.1415926535897;
03429       result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
03430       if( !result )
03431         return false;
03432       S = T;
03433       result = S.Inplace_sin();
03434       if( !result )
03435         return false;
03436       C = T;
03437       result = C.Inplace_cos();
03438       if( !result )
03439         return false;
03440       Sinc = T;
03441       result = Sinc.Inplace_sinc();
03442       if( !result )
03443         return false;
03444       F = T;
03445       result = F.Concatonate( S );
03446       if( !result )
03447         return false;
03448       result = F.Concatonate( C );
03449       if( !result )
03450         return false;
03451       result = F.Concatonate( Sinc );
03452       if( !result )
03453         return false;
03454       result = F.Plot( 0, 1, 2, 3 ); // makes plot3.bmp
03455       if( !result )
03456         return false;
03457       result = F.Plot( 0, 1, 2, 3, "plot3test.bmp", "sin cos sinc", "time (s)", "voltage (V)", "sine", "(V)", "cosine", "(V)", "sinc", "(V)" );   
03458       if( !result )
03459         return false;
03460       return true;
03461     }
03462     \endcode
03463     \return true if successful, false otherwise.
03464     */
03465     bool Plot( 
03466       const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
03467       const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
03468       const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.
03469       const unsigned y_col_3,            //!< The column index (0toN-1) with the y_3 series data.      
03470       const std::string bmpfilename = "plot3.bmp",     //!< The file name (or full path name) of the output bitmap file.
03471       const std::string title = "",           //!< The plot title.
03472       const std::string xlabel = "",          //!< The x-axis label.
03473       const std::string ylabel = "",          //!< The y-axis label.
03474       const std::string series_label_1 = "",  //!< The series label.
03475       const std::string units_1 = "",         //!< The series data units.
03476       const std::string series_label_2 = "",  //!< The series label.
03477       const std::string units_2 = "",         //!< The series data units.
03478       const std::string series_label_3 = "",  //!< The series label.
03479       const std::string units_3 = "",         //!< The series data units.      
03480       const bool isXGridOn = true,       //!< A boolean to indicate if the x grid lines are on.
03481       const bool isYGridOn = true,       //!< A boolean to indicate if the y grid lines are on.  
03482       const bool includeStats = true,    //!< A boolean to indicate if statistics info should be included on the plot.  
03483       const unsigned precisionStats = 5, //!< The number of significant digits in the statistics.
03484       const unsigned plot_height_cm = 8, //!< The plot height in cm.
03485       const unsigned plot_width_cm = 10  //!< The plot width in cm.
03486       );
03487 
03488     /**
03489     \brief  Plot four series, X vs Y1, Y2, Y3 using columns of the Matrix.
03490             Plots directly to a compressed (run-length-encoded) bitamp.
03491     \code
03492     bool TryPlot3()
03493     {
03494       bool result;
03495       Matrix T; // time
03496       Matrix S; // sin(time)
03497       Matrix C; // sin(time)
03498       Matrix Sinc; // sin(time)
03499       Matrix F; // time | sin(time) | cos(time) | sinc(time) | sin(time)+1
03500       double pi = 3.1415926535897;
03501       result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
03502       if( !result )
03503         return false;
03504       S = T;
03505       result = S.Inplace_sin();
03506       if( !result )
03507         return false;
03508       C = T;
03509       result = C.Inplace_cos();
03510       if( !result )
03511         return false;
03512       Sinc = T;
03513       result = Sinc.Inplace_sinc();
03514       if( !result )
03515         return false;
03516       F = T;
03517       result = F.Concatonate( S );
03518       if( !result )
03519         return false;
03520       result = F.Concatonate( C );
03521       if( !result )
03522         return false;
03523       result = F.Concatonate( Sinc );
03524       if( !result )
03525         return false;
03526       S += 1.0;
03527       result = F.Concatonate( S );
03528       if( !result )
03529         return false;
03530       result = F.Plot( 0, 1, 2, 3, 4 ); // makes plot4.bmp
03531       if( !result )
03532         return false;
03533       result = F.Plot( 0, 1, 2, 3, 4, "plot4test.bmp", "sin cos sinc sin+1", "time (s)", "voltage (V)", "sine", "(V)", "cosine", "(V)", "sinc", "(V)", "sin+1", "(V)" );   
03534       if( !result )
03535         return false;
03536       return true;
03537     }
03538     \endcode
03539     \return true if successful, false otherwise.
03540     */
03541     bool Plot( 
03542       const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
03543       const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
03544       const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.
03545       const unsigned y_col_3,            //!< The column index (0toN-1) with the y_3 series data.      
03546       const unsigned y_col_4,            //!< The column index (0toN-1) with the y_4 series data.
03547       const std::string bmpfilename = "plot4.bmp",     //!< The file name (or full path name) of the output bitmap file.
03548       const std::string title = "",           //!< The plot title.
03549       const std::string xlabel = "",          //!< The x-axis label.
03550       const std::string ylabel = "",          //!< The y-axis label.
03551       const std::string series_label_1 = "",  //!< The series label.
03552       const std::string units_1 = "",         //!< The series data units.
03553       const std::string series_label_2 = "",  //!< The series label.
03554       const std::string units_2 = "",         //!< The series data units.
03555       const std::string series_label_3 = "",  //!< The series label.
03556       const std::string units_3 = "",         //!< The series data units.      
03557       const std::string series_label_4 = "",  //!< The series label.
03558       const std::string units_4 = "",         //!< The series data units.            
03559       const bool isXGridOn = true,       //!< A boolean to indicate if the x grid lines are on.
03560       const bool isYGridOn = true,       //!< A boolean to indicate if the y grid lines are on.  
03561       const bool includeStats = true,    //!< A boolean to indicate if statistics info should be included on the plot.  
03562       const unsigned precisionStats = 5, //!< The number of significant digits in the statistics.
03563       const unsigned plot_height_cm = 8, //!< The plot height in cm.
03564       const unsigned plot_width_cm = 10  //!< The plot width in cm.
03565       );
03566 
03567     /**
03568     \brief  Plot five series, X vs Y1, Y2, Y3, Y4, Y5 using columns of the Matrix.
03569             Plots directly to a compressed (run-length-encoded) bitamp.
03570     \code
03571     bool TryPlot3()
03572     {
03573       bool result;
03574       Matrix T; // time
03575       Matrix S; // sin(time)
03576       Matrix C; // sin(time)
03577       Matrix Sinc; // sin(time)
03578       Matrix F; // time | sin(time) | cos(time) | sinc(time) | sin(time)+1 | cos(time)-1
03579       double pi = 3.1415926535897;
03580       result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
03581       if( !result )
03582         return false;
03583       S = T;
03584       result = S.Inplace_sin();
03585       if( !result )
03586         return false;
03587       C = T;
03588       result = C.Inplace_cos();
03589       if( !result )
03590         return false;
03591       Sinc = T;
03592       result = Sinc.Inplace_sinc();
03593       if( !result )
03594         return false;
03595       F = T;
03596       result = F.Concatonate( S );
03597       if( !result )
03598         return false;
03599       result = F.Concatonate( C );
03600       if( !result )
03601         return false;
03602       result = F.Concatonate( Sinc );
03603       if( !result )
03604         return false;
03605       S += 1.0;
03606       result = F.Concatonate( S );
03607       if( !result )
03608         return false;
03609       C -= 1.0;
03610       result = F.Concatonate( C );
03611       if( !result )
03612         return false;
03613       result = F.Plot( 0, 1, 2, 3, 4, 5 ); // makes plot5.bmp
03614       if( !result )
03615         return false;
03616       result = F.Plot( 0, 1, 2, 3, 4, 5, "plot5test.bmp", "sin cos sinc sin+1 cos-1", "time (s)", "voltage (V)", "sine", "(V)", "cosine", "(V)", "sinc", "(V)", "sin+1", "(V)", "cos-1", "(V)" );
03617       if( !result )
03618         return false;
03619       return true;
03620     }
03621     \endcode
03622     \return true if successful, false otherwise.
03623     */
03624     bool Plot( 
03625       const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
03626       const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
03627       const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.
03628       const unsigned y_col_3,            //!< The column index (0toN-1) with the y_3 series data.      
03629       const unsigned y_col_4,            //!< The column index (0toN-1) with the y_4 series data.
03630       const unsigned y_col_5,            //!< The column index (0toN-1) with the y_5 series data.
03631       const std::string bmpfilename = "plot5.bmp",     //!< The file name (or full path name) of the output bitmap file.
03632       const std::string title = "",           //!< The plot title.
03633       const std::string xlabel = "",          //!< The x-axis label.
03634       const std::string ylabel = "",          //!< The y-axis label.
03635       const std::string series_label_1 = "",  //!< The series label.
03636       const std::string units_1 = "",         //!< The series data units.
03637       const std::string series_label_2 = "",  //!< The series label.
03638       const std::string units_2 = "",         //!< The series data units.
03639       const std::string series_label_3 = "",  //!< The series label.
03640       const std::string units_3 = "",         //!< The series data units.      
03641       const std::string series_label_4 = "",  //!< The series label.
03642       const std::string units_4 = "",         //!< The series data units.            
03643       const std::string series_label_5 = "",  //!< The series label.
03644       const std::string units_5 = "",         //!< The series data units.                  
03645       const bool isXGridOn = true,       //!< A boolean to indicate if the x grid lines are on.
03646       const bool isYGridOn = true,       //!< A boolean to indicate if the y grid lines are on.  
03647       const bool includeStats = true,    //!< A boolean to indicate if statistics info should be included on the plot.  
03648       const unsigned precisionStats = 5, //!< The number of significant digits in the statistics.
03649       const unsigned plot_height_cm = 8, //!< The plot height in cm.
03650       const unsigned plot_width_cm = 10  //!< The plot width in cm.
03651       );
03652 
03653     /**
03654     \brief  Plot six series, X vs Y1, Y2, Y3, Y4, Y5, Y6 using columns of the Matrix.
03655             Plots directly to a compressed (run-length-encoded) bitamp.
03656     \code
03657     bool TryPlot3()
03658     {
03659       bool result;
03660       Matrix T; // time
03661       Matrix S; // sin(time)
03662       Matrix C; // sin(time)
03663       Matrix Sinc; // sin(time)
03664       Matrix F; // time | sin(time) | cos(time) | sinc(time) | sin(time)+1 | cos(time)-1 | sinc^2(time)
03665       double pi = 3.1415926535897;
03666       result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
03667       if( !result )
03668         return false;
03669       S = T;
03670       result = S.Inplace_sin();
03671       if( !result )
03672         return false;
03673       C = T;
03674       result = C.Inplace_cos();
03675       if( !result )
03676         return false;
03677       Sinc = T;
03678       result = Sinc.Inplace_sinc();
03679       if( !result )
03680         return false;
03681       F = T;
03682       result = F.Concatonate( S );
03683       if( !result )
03684         return false;
03685       result = F.Concatonate( C );
03686       if( !result )
03687         return false;
03688       result = F.Concatonate( Sinc );
03689       if( !result )
03690         return false;
03691       S += 1.0;
03692       result = F.Concatonate( S );
03693       if( !result )
03694         return false;
03695       C -= 1.0;
03696       result = F.Concatonate( C );
03697       if( !result )
03698         return false;
03699       result = Sinc.Inplace_Sqr();
03700       if( !result )
03701         return false;
03702       result = F.Concatonate( Sinc );
03703       if( !result )
03704         return false;
03705       result = F.Plot( 0, 1, 2, 3, 4, 5, 6 ); // makes plot6.bmp
03706       if( !result )
03707         return false;
03708       result = F.Plot( 0, 1, 2, 3, 4, 5, 6, "plot6test.bmp", "sin cos sinc sin+1 cos-1 sinc^2", "time (s)", "voltage (V)", "sine", "(V)", "cosine", "(V)", "sinc", "(V)", "sin+1", "(V)", "cos-1", "(V)", "sinc^2", "(V)" );
03709       if( !result )
03710         return false;
03711       return true;
03712     }
03713     \endcode
03714     \return true if successful, false otherwise.
03715     */
03716     bool Plot( 
03717       const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
03718       const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
03719       const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.
03720       const unsigned y_col_3,            //!< The column index (0toN-1) with the y_3 series data.      
03721       const unsigned y_col_4,            //!< The column index (0toN-1) with the y_4 series data.
03722       const unsigned y_col_5,            //!< The column index (0toN-1) with the y_5 series data.
03723       const unsigned y_col_6,            //!< The column index (0toN-1) with the y_5 series data.
03724       const std::string bmpfilename = "plot6.bmp",     //!< The file name (or full path name) of the output bitmap file.
03725       const std::string title = "",           //!< The plot title.
03726       const std::string xlabel = "",          //!< The x-axis label.
03727       const std::string ylabel = "",          //!< The y-axis label.
03728       const std::string series_label_1 = "",  //!< The series label.
03729       const std::string units_1 = "",         //!< The series data units.
03730       const std::string series_label_2 = "",  //!< The series label.
03731       const std::string units_2 = "",         //!< The series data units.
03732       const std::string series_label_3 = "",  //!< The series label.
03733       const std::string units_3 = "",         //!< The series data units.      
03734       const std::string series_label_4 = "",  //!< The series label.
03735       const std::string units_4 = "",         //!< The series data units.            
03736       const std::string series_label_5 = "",  //!< The series label.
03737       const std::string units_5 = "",         //!< The series data units.                  
03738       const std::string series_label_6 = "",  //!< The series label.
03739       const std::string units_6 = "",         //!< The series data units.                        
03740       const bool isXGridOn = true,       //!< A boolean to indicate if the x grid lines are on.
03741       const bool isYGridOn = true,       //!< A boolean to indicate if the y grid lines are on.  
03742       const bool includeStats = true,    //!< A boolean to indicate if statistics info should be included on the plot.  
03743       const unsigned precisionStats = 5, //!< The number of significant digits in the statistics.
03744       const unsigned plot_height_cm = 8, //!< The plot height in cm.
03745       const unsigned plot_width_cm = 10  //!< The plot width in cm.
03746       );
03747 
03748 
03749     friend bool Plot(
03750       const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
03751       const std::string title,           //!< The plot title.
03752       const std::string xlabel,          //!< The x-axis label.
03753       const std::string ylabel,          //!< The y-axis label.
03754       Matrix &X,                         //!< The series must be [Nx1] or [1xN].
03755       Matrix &Y,                         //!< The series must be [Nx1] or [1xN].
03756       const std::string series_label,    //!< The series label.
03757       const std::string units,           //!< The series units.
03758       const bool isConnected,     //!< Are the data points connected.
03759       const MTX_enumColor color,  //!< The color of the data points/line.
03760       const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
03761       const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
03762       const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
03763       const unsigned precisionStats, //!< The number of significant digits in the statistics.
03764       const unsigned plot_height_cm, //!< The plot height in cm.
03765       const unsigned plot_width_cm   //!< The plot width in cm.
03766       );  
03767 
03768     friend bool Plot(
03769       const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
03770       const std::string title,           //!< The plot title.
03771       const std::string xlabel,          //!< The x-axis label.
03772       const std::string ylabel,          //!< The y-axis label.
03773       Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
03774       Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
03775       const std::string series_label_1,    //!< The series label.
03776       const std::string units_1,           //!< The series units.
03777       Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
03778       Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
03779       const std::string series_label_2,    //!< The series label.
03780       const std::string units_2,           //!< The series units.
03781       const bool isConnected_1,     //!< Are the data points connected.
03782       const MTX_enumColor color_1,  //!< The color of the data points/line.
03783       const bool isConnected_2,     //!< Are the data points connected.
03784       const MTX_enumColor color_2,  //!< The color of the data points/line.    
03785       const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
03786       const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
03787       const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
03788       const unsigned precisionStats, //!< The number of significant digits in the statistics.
03789       const unsigned plot_height_cm, //!< The plot height in cm.
03790       const unsigned plot_width_cm  //!< The plot width in cm.
03791       );  
03792 
03793     friend bool Plot(
03794       const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
03795       const std::string title,           //!< The plot title.
03796       const std::string xlabel,          //!< The x-axis label.
03797       const std::string ylabel,          //!< The y-axis label.
03798       Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
03799       Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
03800       const std::string series_label_1,    //!< The series label.
03801       const std::string units_1,           //!< The series units.
03802       Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
03803       Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
03804       const std::string series_label_2,    //!< The series label.
03805       const std::string units_2,           //!< The series units.
03806       Matrix &X_3,                         //!< The series must be [Nx1] or [1xN].
03807       Matrix &Y_3,                         //!< The series must be [Nx1] or [1xN].
03808       const std::string series_label_3,    //!< The series label.
03809       const std::string units_3,           //!< The series units.
03810       const bool isConnected_1,     //!< Are the data points connected.
03811       const MTX_enumColor color_1,  //!< The color of the data points/line.
03812       const bool isConnected_2,     //!< Are the data points connected.
03813       const MTX_enumColor color_2,  //!< The color of the data points/line.    
03814       const bool isConnected_3,     //!< Are the data points connected.
03815       const MTX_enumColor color_3,  //!< The color of the data points/line.        
03816       const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
03817       const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
03818       const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
03819       const unsigned precisionStats, //!< The number of significant digits in the statistics.
03820       const unsigned plot_height_cm, //!< The plot height in cm.
03821       const unsigned plot_width_cm   //!< The plot width in cm.
03822       );
03823 
03824     friend bool Plot(
03825       const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
03826       const std::string title,           //!< The plot title.
03827       const std::string xlabel,          //!< The x-axis label.
03828       const std::string ylabel,          //!< The y-axis label.
03829       Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
03830       Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
03831       const std::string series_label_1,    //!< The series label.
03832       const std::string units_1,           //!< The series units.
03833       Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
03834       Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
03835       const std::string series_label_2,    //!< The series label.
03836       const std::string units_2,           //!< The series units.
03837       Matrix &X_3,                         //!< The series must be [Nx1] or [1xN].
03838       Matrix &Y_3,                         //!< The series must be [Nx1] or [1xN].
03839       const std::string series_label_3,    //!< The series label.
03840       const std::string units_3,           //!< The series units.
03841       Matrix &X_4,                         //!< The series must be [Nx1] or [1xN].
03842       Matrix &Y_4,                         //!< The series must be [Nx1] or [1xN].
03843       const std::string series_label_4,    //!< The series label.
03844       const std::string units_4,           //!< The series units.
03845       const bool isConnected_1,     //!< Are the data points connected.
03846       const MTX_enumColor color_1,  //!< The color of the data points/line.
03847       const bool isConnected_2,     //!< Are the data points connected.
03848       const MTX_enumColor color_2,  //!< The color of the data points/line.    
03849       const bool isConnected_3,     //!< Are the data points connected.
03850       const MTX_enumColor color_3,  //!< The color of the data points/line.        
03851       const bool isConnected_4,     //!< Are the data points connected.
03852       const MTX_enumColor color_4,  //!< The color of the data points/line.        
03853       const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
03854       const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
03855       const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
03856       const unsigned precisionStats, //!< The number of significant digits in the statistics.
03857       const unsigned plot_height_cm, //!< The plot height in cm.
03858       const unsigned plot_width_cm   //!< The plot width in cm.
03859       );
03860 
03861     friend bool Plot(
03862       const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
03863       const std::string title,           //!< The plot title.
03864       const std::string xlabel,          //!< The x-axis label.
03865       const std::string ylabel,          //!< The y-axis label.
03866       Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
03867       Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
03868       const std::string series_label_1,    //!< The series label.
03869       const std::string units_1,           //!< The series units.
03870       Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
03871       Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
03872       const std::string series_label_2,    //!< The series label.
03873       const std::string units_2,           //!< The series units.
03874       Matrix &X_3,                         //!< The series must be [Nx1] or [1xN].
03875       Matrix &Y_3,                         //!< The series must be [Nx1] or [1xN].
03876       const std::string series_label_3,    //!< The series label.
03877       const std::string units_3,           //!< The series units.
03878       Matrix &X_4,                         //!< The series must be [Nx1] or [1xN].
03879       Matrix &Y_4,                         //!< The series must be [Nx1] or [1xN].
03880       const std::string series_label_4,    //!< The series label.
03881       const std::string units_4,           //!< The series units.
03882       Matrix &X_5,                         //!< The series must be [Nx1] or [1xN].
03883       Matrix &Y_5,                         //!< The series must be [Nx1] or [1xN].
03884       const std::string series_label_5,    //!< The series label.
03885       const std::string units_5,           //!< The series units.
03886       const bool isConnected_1,     //!< Are the data points connected.
03887       const MTX_enumColor color_1,  //!< The color of the data points/line.
03888       const bool isConnected_2,     //!< Are the data points connected.
03889       const MTX_enumColor color_2,  //!< The color of the data points/line.    
03890       const bool isConnected_3,     //!< Are the data points connected.
03891       const MTX_enumColor color_3,  //!< The color of the data points/line.        
03892       const bool isConnected_4,     //!< Are the data points connected.
03893       const MTX_enumColor color_4,  //!< The color of the data points/line.        
03894       const bool isConnected_5,     //!< Are the data points connected.
03895       const MTX_enumColor color_5,  //!< The color of the data points/line.        
03896       const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
03897       const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
03898       const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
03899       const unsigned precisionStats, //!< The number of significant digits in the statistics.
03900       const unsigned plot_height_cm, //!< The plot height in cm.
03901       const unsigned plot_width_cm   //!< The plot width in cm.
03902       );
03903 
03904     friend bool Plot(
03905       const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
03906       const std::string title,           //!< The plot title.
03907       const std::string xlabel,          //!< The x-axis label.
03908       const std::string ylabel,          //!< The y-axis label.
03909       Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
03910       Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
03911       const std::string series_label_1,    //!< The series label.
03912       const std::string units_1,           //!< The series units.
03913       Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
03914       Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
03915       const std::string series_label_2,    //!< The series label.
03916       const std::string units_2,           //!< The series units.
03917       Matrix &X_3,                         //!< The series must be [Nx1] or [1xN].
03918       Matrix &Y_3,                         //!< The series must be [Nx1] or [1xN].
03919       const std::string series_label_3,    //!< The series label.
03920       const std::string units_3,           //!< The series units.
03921       Matrix &X_4,                         //!< The series must be [Nx1] or [1xN].
03922       Matrix &Y_4,                         //!< The series must be [Nx1] or [1xN].
03923       const std::string series_label_4,    //!< The series label.
03924       const std::string units_4,           //!< The series units.
03925       Matrix &X_5,                         //!< The series must be [Nx1] or [1xN].
03926       Matrix &Y_5,                         //!< The series must be [Nx1] or [1xN].
03927       const std::string series_label_5,    //!< The series label.
03928       const std::string units_5,           //!< The series units.
03929       Matrix &X_6,                         //!< The series must be [Nx1] or [1xN].
03930       Matrix &Y_6,                         //!< The series must be [Nx1] or [1xN].
03931       const std::string series_label_6,    //!< The series label.
03932       const std::string units_6,           //!< The series units.
03933       const bool isConnected_1,     //!< Are the data points connected.
03934       const MTX_enumColor color_1,  //!< The color of the data points/line.
03935       const bool isConnected_2,     //!< Are the data points connected.
03936       const MTX_enumColor color_2,  //!< The color of the data points/line.    
03937       const bool isConnected_3,     //!< Are the data points connected.
03938       const MTX_enumColor color_3,  //!< The color of the data points/line.        
03939       const bool isConnected_4,     //!< Are the data points connected.
03940       const MTX_enumColor color_4,  //!< The color of the data points/line.        
03941       const bool isConnected_5,     //!< Are the data points connected.
03942       const MTX_enumColor color_5,  //!< The color of the data points/line.        
03943       const bool isConnected_6,     //!< Are the data points connected.
03944       const MTX_enumColor color_6,  //!< The color of the data points/line.        
03945       const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
03946       const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
03947       const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
03948       const unsigned precisionStats, //!< The number of significant digits in the statistics.
03949       const unsigned plot_height_cm, //!< The plot height in cm.
03950       const unsigned plot_width_cm   //!< The plot width in cm.
03951       );
03952 
03953 
03954 
03955     /**
03956     \brief  Retrieve the matrix comment string. The string
03957     will be empty if none is available. The matrix comment string
03958     is often the header line read when using ReadFromFile(). \n
03959     e.g. file.txt has:
03960     time(s)   x(m)   y(m)
03961     1.0       20.0   30.0
03962     
03963     \code
03964     bool result;
03965     Matrix A;
03966     result = A.ReadFromFile("file.txt");
03967     // A == [1.0 20.0 30.0]
03968     std::string comment = A.GetMatrixComment();
03969     // comment == "time(s)   x(m)   y(m)"
03970     \endcode
03971     
03972     \return The matrix comment string.
03973     */
03974     std::string GetMatrixComment();
03975 
03976 
03977     /**
03978     \brief  Alter the matrix so that its data is within the startTime to the startTime+duration
03979             and compensate for any rollovers in the time system (e.g. GPS time in seconds rolls over
03980             at 604800.0 s). This function assumes that time is one of the matrix columns and requires
03981             this index, the timeColumn.
03982 
03983     \return true if successful, false otherwise.
03984     */
03985     bool TimeWindow( 
03986       const unsigned timeColumn, //!< The column containing time.
03987       const double startTime,    //!< The specified start time (inclusive).
03988       const double duration,     //!< The duration to include.
03989       const double rolloverTime  //!< The potential time at which system time rolls over.
03990       );
03991 
03992     /**
03993     \brief  Alter the matrix so that its data is within [startTime endTime].
03994             This function assumes that time is one of the matrix columns and requires
03995             this index, the timeColumn.
03996 
03997     \return true if successful, false otherwise.
03998     */
03999     bool TimeLimit( 
04000       const unsigned timeColumn, //!< The column containing time
04001       const double startTime,    //!< The specified start time (inclusive)
04002       const double endTime       //!< The duration to include
04003       );
04004 
04005     /**
04006     \brief  This static function matches matrices in time with specified precision
04007     where time is a column of each matrix. This function also
04008     allows time to rollover at a specified interval.
04009     
04010     precision 0 = match to whole number \n
04011     precision 1 = match to nearest 0.1 \n
04012     precision 2 = match to nearest 0.01 \n
04013     etc. \n
04014 
04015     rolloverTime examples \n
04016     GPS time of week (s): rolloverTime= 604800.0 \n
04017     hours               : rolloverTime = 24.0 \n
04018     minutes             : rolloverTime = 60.0 \n
04019     
04020     The time data must be non-decreasing but the time may rollover
04021     by the specified amount. 
04022     e.g. rolloverTime = 60.0 \n
04023          0,1,2,3,4,...59,60,1,2,5,10,60,1,2,3... \n
04024     
04025     This function may be called by: bool result = Matrix::TimeMatch( ... );
04026 
04027     \return true if successful, false otherwise.
04028     */
04029     static bool TimeMatch( 
04030       Matrix &A,                   //!< The matrix with interpolation times
04031       const unsigned timeColumnA,  //!< The zero based column index for matrix A
04032       Matrix &B,                   //!< The matrix to be interpolated
04033       const unsigned timeColumnB,  //!< The zero based column index for matrix B
04034       const unsigned precision,    //!< The rounding precision used for time matching, 0 = whole, 1 = 0.1, 2 = 0.01, etc
04035       const double rolloverTime    //!< The rollover time, e.g. 60 s for minute based timing, 0.0 means rollovers not allowed
04036       );
04037 
04038     /**
04039     \brief  This static function interpolates Matrix B values by the times defined 
04040             in the column in Matrix A. Time must be increasing but times can 
04041             rollover with the specified rolloverTime.
04042     
04043     This function returns A and B with the same number of rows and 
04044     time aligned time columns.
04045     
04046     This function may be called by: bool result = Matrix::Interpolate( ... );
04047 
04048     \return true if successful, false otherwise.
04049     */
04050     static bool Interpolate( 
04051       Matrix &A,                    //!< The matrix with interpolation times
04052       const unsigned timeColumnA,   //!< The zero based column index for matrix A
04053       Matrix &B,                    //!< The matrix to be interpolated
04054       const unsigned timeColumnB,   //!< The zero based column index for matrix B
04055       const double maxInterpolationInterval, //!< The largest interpolation interval allowed
04056       const double rolloverTime     //!< The rollover time, e.g. 60 s for minute based timing, 0.0 means rollovers not allowed
04057       );
04058 
04059 
04060   public: // Functions that return a Matrix
04061 
04062     /**
04063     \brief  Return the column matrix specified by the column index. Returns (nrows x 1).
04064 
04065     \code
04066     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04067     Matrix B = A.Column(1);
04068     // B == [2; 5; 8]
04069     \endcode
04070     */
04071     Matrix  Column(const unsigned col);
04072 
04073     /**
04074     \brief  Return the row matrix specified by the column index. Returns (ncols x 1).
04075 
04076     \code
04077     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04078     Matrix B = A.Row(1);
04079     // B == [4 5 6]
04080     \endcode    
04081     */
04082     Matrix  Row(const unsigned row);
04083 
04084     /**
04085     \brief  Return the tranpose of the matrix.
04086 
04087     \code
04088     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04089     Matrix B = A.Transpose();
04090     // B == "[1 4 7; 2 5 8; 3 6 9]";
04091     \endcode        
04092     */
04093     Matrix  Transpose();
04094 
04095     /**
04096     \brief  Return the tranpose of the matrix.
04097 
04098     \code
04099     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04100     Matrix B = A.T();
04101     // B == "[1 4 7; 2 5 8; 3 6 9]";
04102     \endcode 
04103     */
04104     Matrix  T(); // short version
04105 
04106     /**
04107     \brief  Return the diagonal of the matrix as a vector.
04108 
04109     \code
04110     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04111     Matrix B = A.Diagonal();
04112     // B == "[1; 5; 9]";
04113     \endcode     
04114     */
04115     Matrix  Diagonal();
04116 
04117     /**
04118     \brief  Return the inverse of the matrix.
04119 
04120     \code
04121     Matrix A = "[1 0 1; -2 1 3; 4 -1 -6]";
04122     Matrix B = A.Inverse();
04123     // B == "[0.6 0.2 0.2; 0 2 1; 0.4 -0.2 -0.2]";
04124     \endcode
04125     */
04126     Matrix  Inverse();
04127     
04128     /**
04129     \brief  Return the inverse of the matrix.
04130 
04131     \code
04132     Matrix A = "[1 0 1; -2 1 3; 4 -1 -6]";
04133     Matrix B = A.Inv();
04134     // B == "[0.6 0.2 0.2; 0 2 1; 0.4 -0.2 -0.2]";
04135     \endcode    
04136     */
04137     Matrix  Inv(); // short version
04138 
04139 
04140     /**
04141     \brief  Return the Fourier Transform of each column of the matrix. 
04142             Power of two uses FFT, otherwise fast DFT.
04143     */
04144     Matrix  FFT();
04145 
04146     /**
04147     \brief  Return the inverse Fourier Transform of each column of the matrix. 
04148             Power of two uses IFFT, otherwise fast IDFT.
04149     */
04150     Matrix  IFFT();
04151 
04152 
04153     /**
04154     \brief  Return the Two Dimensional Fourier Transform of the matrix.
04155     */
04156     Matrix  FFT2();
04157 
04158     /**
04159     \brief  Return the Two Dimensional Inverse Fourier Transform of the matrix.
04160     */
04161     Matrix  IFFT2();
04162 
04163     /**
04164     \brief  Return the real part of the matrix            
04165 
04166     \code
04167     Matrix A = "[1-1i 2-2i 3-3i; 4-4i 5-5i 6-6i; 7-7i 8-8i 9-9i]";
04168     Matrix B = A.Real();
04169     // B == "[1 2 3; 4 5 6; 7 8 9]";
04170     \endcode        
04171     */
04172     Matrix  Real();
04173 
04174     /**
04175     \brief  Return the imag part of the matrix            
04176 
04177     \code
04178     Matrix A = "[1-1i 2-2i 3-3i; 4-4i 5-5i 6-6i; 7-7i 8-8i 9-9i]";
04179     Matrix B = A.Imag();
04180     // B == "[-1 -2 -3; -4 -5 -6; -7 -8 -9]";
04181     \endcode            
04182     */
04183     Matrix  Imag();
04184 
04185     /**
04186     \brief  Return the complex conjugate of the matrix            
04187 
04188     \code
04189     Matrix A = "[1-1i 2-2i 3-3i; 4-4i 5-5i 6-6i; 7-7i 8-8i 9-9i]";
04190     Matrix B = A.conj();
04191     // B == "[1+1i 2+2i 3+3i; 4+4i 5+5i 6+6i; 7+7i 8+8i 9+9i]";
04192     \endcode    
04193     */
04194     Matrix  conj();
04195 
04196 
04197     /** 
04198     \brief  Returns the matrix plus Identity.
04199 
04200     \code
04201     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04202     Matrix B = A.AddIdentity();
04203     // B == "[2 2 3; 4 6 6; 7 8 10]";
04204     \endcode    
04205     */
04206     Matrix AddIdentity();
04207 
04208     /** 
04209     \brief  Returns the matrix minus Identity.
04210 
04211     \code
04212     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04213     Matrix B = A.MinusIdentity();
04214     // B == "[0 2 3; 4 4 6; 7 8 8]";
04215     \endcode    
04216     */
04217     Matrix MinusIdentity();
04218 
04219     /** 
04220     \brief  Returns Identity minus the matrix.
04221 
04222     \code
04223     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04224     Matrix B = A.IdentityMinusMe();
04225     // B == "[0 -2 -3; -4 -4 -6; -7 -8 -8]";
04226     \endcode    
04227     */
04228     Matrix IdentityMinusMe();
04229 
04230     /** 
04231     \brief  Returns the matrix * -1. This is more efficient than A *= -1.
04232 
04233     \code
04234     Matrix A = "[1 2 3; 4 5 6; 7 8 9]";
04235     Matrix B = A.Negate();
04236     // B == "[-1 -2 -3; -4 -5 -6; -7 -8 -9]";
04237     \endcode    
04238     */
04239     Matrix Negate();
04240 
04241     /** 
04242     \brief  Sets the matrix as the NxN hilbert matrix. H_ij = 1.0 / (i+j-1.0) for i=1:N, j=1:N.
04243 
04244     \code
04245     Matrix H;
04246     bool result;
04247     result = H.Hilbert(3);
04248     // H == "[1 1/2 1/3; 1/2 1/3 1/4; 1/3 1/4 1/5]";
04249     \endcode    
04250     */
04251     bool Hilbert( const unsigned N );
04252 
04253     /**
04254     \brief  Return the square root of each element in the matrix.
04255 
04256     \code
04257     Matrix A = "[-1 4 9;16 25 36;49 64 81]";
04258     Matrix B = A.Sqrt();
04259     // B == "[0+1i 2 3;4 5 6; 7 8 9]";
04260     \endcode        
04261     */
04262     Matrix  Sqrt();
04263 
04264     /**
04265     \brief  Return the exponent of each element in the matrix.
04266     */
04267     Matrix  Exp();
04268 
04269     /**
04270     \brief  Return the logarithm of each element in the matrix.
04271     */
04272     Matrix  Ln();
04273 
04274     /**
04275     \brief  Return the cosine of each element in the matrix.
04276     */
04277     Matrix  cos();
04278 
04279     /**
04280     \brief  Return the arc-cosine of each element in the matrix.
04281     */
04282     Matrix  acos();
04283 
04284     /**
04285     \brief  Return the sine of each element in the matrix.
04286     */
04287     Matrix  sin();
04288 
04289     /**
04290     \brief  Return the arc-sine of each element in the matrix.
04291     */
04292     Matrix  asin();
04293 
04294     /**
04295     \brief  Return the tangent of each element in the matrix.
04296     */
04297     Matrix  tan();
04298 
04299     /**
04300     \brief  Return the arc-tangent of each element in the matrix.
04301     */
04302     Matrix  atan();
04303 
04304     /**
04305     \brief  Return the hyperbolic cosine of each element in the matrix.
04306     */
04307     Matrix  cosh();
04308 
04309     /**
04310     \brief  Return the inverse hyperbolic cosine of each element in the matrix.
04311     */
04312     Matrix  acosh();
04313 
04314     /**
04315     \brief  Return the hyperbolic sine of each element in the matrix.
04316     */
04317     Matrix  sinh();
04318 
04319     /**
04320     \brief  Return the inverse hyperbolic sine of each element in the matrix.
04321     */
04322     Matrix  asinh();
04323 
04324     /**
04325     \brief  Return the hyperbolic tangent of each element in the matrix.
04326     */
04327     Matrix  tanh();
04328 
04329     /**
04330     \brief  Return the inverse hyperbolic tangent of each element in the matrix.
04331     */
04332     Matrix  atanh();
04333 
04334     /**
04335     \brief  Return the cotangent of each element in the matrix.
04336     */
04337     Matrix  cot();
04338 
04339     /**
04340     \brief  Return the hyperbolic cotangent of each element in the matrix.
04341     */
04342     Matrix  coth();
04343 
04344     /**
04345     \brief  Return the absolute value (magnitude if complex) of each element in the matrix.
04346     */
04347     Matrix  abs();
04348 
04349     /**
04350     \brief  Return the phase angle in radians of the elements in the matrix.
04351     If M is a real matrix, Phase is a zero matrix.
04352     If M is a complex matrix, Phase is a real matrix = atan2(im,re).
04353     */
04354     Matrix  angle();
04355 
04356     /**
04357     \brief  Return a matrix with all elements in raised to the power X^(power_re + power_im*i).
04358     */
04359     Matrix  pow(const double power_re, const double power_im = 0.0);
04360 
04361     /**
04362     \brief  Return a matrix with elements rounded to the specified precision.\n
04363     e.g. precision = 0    1.8    -> 2     \n
04364     e.g. precision = 1,   1.45   -> 1.5   \n
04365     e.g. precision = 2    1.456  -> 1.46  \n
04366     e.g. precision = 3,   1.4566 -> 1.457 \n
04367     precision has a maximum of 32. After which no rounding occurs.
04368     */
04369     Matrix  round(const unsigned precision);
04370 
04371     /**
04372     \brief  Return a matrix with elements rounded to the nearest integers towards minus infinity.
04373     */
04374     Matrix  floor();
04375 
04376     /**
04377     \brief  Return a matrix with elements rounded to the nearest integers towards infinity.
04378     */
04379     Matrix  ceil();
04380 
04381     /**
04382     \brief  Return a matrix with elements rounded to the nearest integers towards zero.
04383     */
04384     Matrix  fix();
04385 
04386     /**
04387     \brief  Return a matrix with all elements inverted (1/x).
04388     */
04389     Matrix  dotInvert();
04390 
04391     /**
04392     \brief  Return a matrix with each element subtracted from 1.0. i.e. 1-X.
04393     */
04394     Matrix  oneMinusMe();
04395 
04396     /**
04397     \brief  Return the matrix that has each element multiplied by each element of B.
04398     This matrix must be the same dimensions as B unless B is a scalar.
04399     */
04400     Matrix  DotMultiply(const Matrix& B);
04401 
04402 
04403   public:
04404 
04405     /**
04406     \brief  This is a nested class that is an element of the matrix. i.e. Matrix M; M(i,j) is the element. 
04407             It is used for operator(,) access by the Matrix.
04408     */
04409     class Element
04410     {
04411     public:
04412 
04413       /// \brief  The only constructor binds the reference to the deep level matrix.
04414       /// The row and column members are set later.
04415       Element(MTX& mtx);
04416 
04417       /// \brief  The destructor.
04418       virtual ~Element();
04419 
04420     private:
04421       friend class Matrix; //!< The matrix class is a friend.
04422 
04423       MTX& m_mtx;     //!< The reference to the deep level matrix.
04424       unsigned m_row; //!< The corresponding row of this element in the matrix.
04425       unsigned m_col; //!< The corresponding column of this element in the matrix.
04426 
04427     public:
04428 
04429       const double real(); //!< Get the real part.
04430       const double imag(); //!< Get the imaginary part.
04431       
04432       /// \brief  The operator overload for setting the matrix element from a double.
04433       const Element& operator= (double v);
04434 
04435       /// \brief  The operator overload for setting the matrix element from a std::complex.
04436       const Element& operator= (std::complex<double> v);
04437 
04438       /// \brief  The operator overload for setting the matrix element from another the matrix element.
04439       const Element& operator= (Element v);
04440 
04441       /// \brief  This operator allows explict conversion to a std::complex.
04442       operator const std::complex<double>() const;
04443 
04444       void operator+= (const double scalar);            //!< \brief  Add a scalar inplace. 
04445       void operator+= (const std::complex<double>& v);  //!< \brief  Add a complex value inplace. 
04446       void operator+= (const Element& v);               //!< \brief  Add a Element inplace. 
04447       void operator-= (const double scalar);            //!< \brief  Subtract a scalar inplace. 
04448       void operator-= (const std::complex<double>& v);  //!< \brief  Subtract a complex value inplace. 
04449       void operator-= (const Element& v);               //!< \brief  Subtract a Element inplace. 
04450       void operator*= (const double scalar);            //!< \brief  Multiply a scalar inplace. 
04451       void operator*= (const std::complex<double>& v);  //!< \brief  Multiply a complex value inplace. 
04452       void operator*= (const Element& v);               //!< \brief  Multiply a Element inplace. 
04453       void operator/= (const double scalar);            //!< \brief  Divide a scalar inplace. 
04454       void operator/= (const std::complex<double>& v);  //!< \brief  Divide a complex value inplace. 
04455       void operator/= (const Element& v);               //!< \brief  Divide a Element inplace. 
04456       
04457       /// \brief  The operator overload for adding a double to an element.
04458       friend const std::complex<double> operator+ (const Element& m, double scalar);
04459 
04460       /// \brief  The operator overload for adding an element to an element.
04461       friend const std::complex<double> operator+ (const Element& a, const Element& b);
04462 
04463       /// \brief  The operator overload for adding an element to an complex.
04464       friend const std::complex<double> operator+ (const Element& a, const std::complex<double>& b);
04465 
04466       /// \brief  The operator overload for adding an element and a double.
04467       friend const std::complex<double> operator+ (double scalar, const Element& m);
04468 
04469       /// \brief  The operator overload for adding a complex and an element
04470       friend const std::complex<double> operator+ (const std::complex<double>& b, const Element& a);
04471 
04472 
04473       /// \brief  The operator overload for subtracting a double from an element.
04474       friend const std::complex<double> operator- (const Element& m, double scalar);
04475       
04476       /// \brief  The operator overload for subtracting an element from an element.
04477       friend const std::complex<double> operator- (const Element& a, const Element& b);
04478 
04479       /// \brief  The operator overload for subtracting an complex from an element.
04480       friend const std::complex<double> operator- (const Element& a, const std::complex<double>& b);
04481 
04482       /// \brief  The operator overload for subtracting an element from a double.
04483       friend const std::complex<double> operator- (double scalar, const Element& m);
04484 
04485       /// \brief  The operator overload for subtracting an element from a complex.
04486       friend const std::complex<double> operator- (const std::complex<double>& b, const Element& a);
04487 
04488 
04489       /// \brief  The operator overload for multiplying an element and a double.
04490       friend const std::complex<double> operator* (const Element& m, double scalar);
04491       
04492       /// \brief  The operator overload for multiplying an element and an element.
04493       friend const std::complex<double> operator* (const Element& a, const Element& b);
04494 
04495       /// \brief  The operator overload for multiplying an element and a complex.
04496       friend const std::complex<double> operator* (const Element& a, const std::complex<double>& b);
04497 
04498       /// \brief  The operator overload for multiplying a double and an element.
04499       friend const std::complex<double> operator* (double scalar, const Element& m);
04500       
04501       /// \brief  The operator overload for multiplying a complex and an element.
04502       friend const std::complex<double> operator* (const std::complex<double>& b, const Element& a);
04503 
04504 
04505       /// \brief  The operator overload for dividing an element by a double.
04506       friend const std::complex<double> operator/ (const Element& m, double scalar);
04507 
04508       /// \brief  The operator overload for dividing an element by an element.
04509       friend const std::complex<double> operator/ (const Element& a, const Element& b);
04510 
04511       /// \brief  The operator overload for dividing an element by an complex.
04512       friend const std::complex<double> operator/ (const Element& a, const std::complex<double>& b);
04513 
04514       /// \brief  The operator overload for dividing a double by an element.
04515       friend const std::complex<double> operator/ (double scalar, const Element& m);
04516 
04517       /// \brief  The operator overload for dividing a complex by an element.
04518       friend const std::complex<double> operator/ (const std::complex<double>& b, const Element& a);
04519 
04520 
04521       /// \brief  The operator overload for testing equality between an element and a double.
04522       friend const bool operator== (const Element& m, double scalar);
04523       
04524       /// \brief  The operator overload for testing equality between an element and an element.
04525       friend const bool operator== (const Element& a, const Element& b);
04526 
04527       /// \brief  The operator overload for testing equality between an element and a complex.
04528       friend const bool operator== (const Element& a, const std::complex<double>& b);
04529 
04530       /// \brief  The operator overload for testing equality between a double and an element.
04531       friend const bool operator== (double scalar, const Element& m);
04532       
04533       /// \brief  The operator overload for testing equality between a complex and an element.
04534       friend const bool operator== (const std::complex<double>& b, const Element& a);
04535 
04536     };
04537 
04538 
04539   public: // Operator Overloads      
04540 
04541     /// \brief  Get a reference to an element in the matrix to set or get its value.
04542     Element& operator() (unsigned row, unsigned col);
04543 
04544     /// \brief  Get a reference to an element in the matrix as a column or row vector to set or get its value.
04545     /// This can be used to access a matrix of (col,row), col = index/nrows, row = index/ncols. 
04546     /// Matrix A(10); // The matrix is real with dimensions 10x1
04547     /// A(0) = 10.0;  // The matrix is real.
04548     /// stComplex cplx = {1.0,2.0};
04549     /// A(1) = cplx;  // The matrix is now complex with dimensions 10x1.
04550     Element& operator() (unsigned index);
04551 
04552 
04553     bool operator+= (const int    scalar) { return (*this)+=(double)scalar; } //!< add a scaler int     (shorthand notation: A += 5).
04554     bool operator+= (const float  scalar) { return (*this)+=(double)scalar; } //!< add a scaler float   (shorthand notation: A += 5).
04555     bool operator+= (const double scalar);                                    //!< add a scaler double  (shorthand notation: A += 5).
04556     bool operator+= (const std::complex<double> cplx);                        //!< add a scaler complex (shorthand notation: A += (5+2i)).
04557 
04558     bool operator-= (const int    scalar) { return (*this)-=(double)scalar; } //!< subtract a scaler int     (shorthand notation: A -= 5).
04559     bool operator-= (const float  scalar) { return (*this)-=(double)scalar; } //!< subtract a scaler float   (shorthand notation: A -= 5).
04560     bool operator-= (const double scalar);                                    //!< subtract a scaler double  (shorthand notation: A -= 5).
04561     bool operator-= (const std::complex<double> cplx);                        //!< subtract a scaler complex (shorthand notation: A -= (5+2i)).
04562 
04563     bool operator*= (const int    scalar) { return (*this)*=(double)scalar; } //!< multiply a scalar int     (shorthand notation: A *= 5).
04564     bool operator*= (const float  scalar) { return (*this)*=(double)scalar; } //!< multiply a scalar float   (shorthand notation: A *= 5).
04565     bool operator*= (const double scalar);                                    //!< multiply a scalar double  (shorthand notation: A *= 5).
04566     bool operator*= (const std::complex<double> cplx);                        //!< multiply a scaler complex (shorthand notation: A *= (5+2i)).
04567 
04568     bool operator/= (const int    scalar) { return (*this)/=(double)scalar; } //!< divide a scalar int     (shorthand notation: A /= 5).
04569     bool operator/= (const float  scalar) { return (*this)/=(double)scalar; } //!< divide a scalar float   (shorthand notation: A /= 5).
04570     bool operator/= (const double scalar);                                    //!< divide a scalar double  (shorthand notation: A /= 5).
04571     bool operator/= (const std::complex<double> cplx);                        //!< divide a scaler complex (shorthand notation: A /= (5+2i)).
04572 
04573     bool operator+= (const Matrix& mat);  //!< add a matrix      (shorthand notation: A += B).   
04574     bool operator-= (const Matrix& mat);  //!< subtract a matrix (shorthand notation: A -= B).
04575 
04576     /// \brief  The postfix ++ operator overload.
04577     /// Add +1.0 to all elements and returns matrix values after the increment, e.g. Matrix B = A++.
04578     /// Use Inplace_Increment for a boolean return for safer operation.
04579     friend Matrix operator++ (Matrix& mat, int);
04580 
04581     /// \brief  The postfix -- operator overload.
04582     /// Subtract 1.0 to all elements and returns matrix values after the increment, e.g. Matrix B = A--.
04583     /// Use Inplace_Decrement for a boolean return for safer operation.  
04584     friend Matrix operator-- (Matrix& mat, int);
04585 
04586     /// \brief  Multiply two matrices and copy the result. Result = mat1 * mat2.
04587     friend Matrix operator* (const Matrix& mat1, const Matrix& mat2); 
04588 
04589     /// \brief  Multiply two matrices and copy the result. Result = mat1 * mat2.
04590     friend Matrix operator* (Matrix& mat1, Matrix& mat2); 
04591 
04592     /// \brief  Add two matrices and copy the result. Result = mat1 + mat2.
04593     friend Matrix operator+ (Matrix& mat1, Matrix& mat2);
04594     
04595     /// \brief  Add two matrices and copy the result. Result = mat1 + mat2.
04596     friend Matrix operator+ (const Matrix& mat1, const Matrix& mat2);
04597 
04598     /// \brief  Subtract two matrices and copy the result. Result = mat1 - mat2.
04599     friend Matrix operator- (Matrix& mat1, Matrix& mat2); 
04600     
04601     /// \brief  Subtract two matrices and copy the result. Result = mat1 - mat2.
04602     friend Matrix operator- (const Matrix& mat1, const Matrix& mat2); 
04603 
04604 
04605     /// \brief  Raise all matrix elements to the power scalar.
04606     friend Matrix operator^ (Matrix& mat, const int scalar)     { return mat^( (double)scalar ); }
04607 
04608     /// \brief  Raise all matrix elements to the power scalar.
04609     friend Matrix operator^ (Matrix& mat, const float scalar)   { return mat^( (double)scalar ); }
04610 
04611     /// \brief  Raise all matrix elements to the power scalar.
04612     friend Matrix operator^ (Matrix& mat, const double scalar);
04613 
04614     /// \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).
04615     friend Matrix operator+ (const double scalar, Matrix& mat);
04616     friend Matrix operator+ (Matrix& mat, const int    scalar)  { return ((double)scalar) + mat; }
04617     friend Matrix operator+ (Matrix& mat, const float  scalar)  { return ((double)scalar) + mat; }
04618     friend Matrix operator+ (Matrix& mat, const double scalar)  { return scalar + mat;           }
04619     friend Matrix operator+ (const int    scalar, Matrix& mat)  { return ((double)scalar) + mat; }
04620     friend Matrix operator+ (const float  scalar, Matrix& mat)  { return ((double)scalar) + mat; }
04621 
04622     /// \brief  Subtract from a matrix by a scalar variable: ie. A = B - 2.0.
04623     friend Matrix operator- (Matrix& mat, const double scalar)  { return mat + (-1.0*scalar);         }
04624     friend Matrix operator- (Matrix& mat, const int    scalar)  { return mat + (-1.0*(double)scalar); }
04625     friend Matrix operator- (Matrix& mat, const float  scalar)  { return mat + (-1.0*(double)scalar); }
04626 
04627     /// \brief  Subtract a matrix from a scalar variable: ie. A = 2.0 - B == -B + 2.0
04628     friend Matrix operator- (const double scalar, Matrix& mat);
04629     friend Matrix operator- (const int    scalar, Matrix& mat)  { return mat - ((double)scalar); }
04630     friend Matrix operator- (const float  scalar, Matrix& mat)  { return mat - ((double)scalar); }
04631 
04632     /// \brief  Multiply matrix by a scalar variable: A = 2.0 * B and A = B * 2.0.
04633     friend Matrix operator* (const double scalar, Matrix& mat);
04634     friend Matrix operator* (Matrix& mat, const int    scalar)  { return (((double)scalar) * mat); }
04635     friend Matrix operator* (Matrix& mat, const float  scalar)  { return (((double)scalar) * mat); }
04636     friend Matrix operator* (Matrix& mat, const double scalar)  { return (scalar * mat);           }
04637     friend Matrix operator* (const int    scalar, Matrix& mat)  { return (((double)scalar) * mat); }
04638     friend Matrix operator* (const float  scalar, Matrix& mat)  { return (((double)scalar) * mat); }   
04639 
04640     /// \brief  Divide matrix by a scalar variable: A = B / 2.0.
04641     friend Matrix operator/ (Matrix& mat, const double scalar);
04642     friend Matrix operator/ (Matrix& mat, const int    scalar)  { return mat / ((double)scalar); }
04643     friend Matrix operator/ (Matrix& mat, const float  scalar)  { return mat / ((double)scalar); }
04644 
04645     /// \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.
04646     friend Matrix operator/ (const double scalar, Matrix& mat);
04647     friend Matrix operator/ (const int    scalar, Matrix& mat)  { return ((double)scalar) / mat; }
04648     friend Matrix operator/ (const float  scalar, Matrix& mat)  { return ((double)scalar) / mat; }
04649 
04650 
04651     // Accessing matrix data as real only:
04652     // The matrix can be accessed using the square bracket operators.
04653     // e.g. Matrix A(2,2); double b = A[0][0]; A[0][1] = 10.0; A[0][1] = -10.0;
04654   public:
04655 
04656     /// \brief  A nested class for access only to the real part of the matrix. 
04657     /// It is used for operator[] access by the Matrix.    
04658     ///
04659     /// Sequential [][] operators can be used to access the matrix. The
04660     /// first overload of [] is at the Matrix level. This returns a copy of 
04661     /// a RealOnlyAccess and the second overload of [] allows access to the 
04662     /// required element from the matrix.
04663     ///
04664     /// For matrices that are always real. This method of accessing each element
04665     /// is the most efficient.
04666     class RealOnlyAccess
04667     {
04668     public:
04669 
04670       /// \brief  Set or get an element value.
04671       double& operator [] (const unsigned col);
04672 
04673       /// \brief  The matrix is a friend class.
04674       friend class Matrix;
04675 
04676       /// \brief  The only constructor.
04677       RealOnlyAccess( MTX& pMatrix, const unsigned row );
04678 
04679       /// \brief  The destructor.
04680       virtual ~RealOnlyAccess();
04681 
04682       /// \brief  The assignment operator from a double for single index operations. 
04683       RealOnlyAccess& operator=(const double value);
04684 
04685       /// \brief  The assignment operator from another RealOnlyAccess object for single index operations.
04686       RealOnlyAccess& operator=(RealOnlyAccess& rhs);
04687 
04688       /// \brief  The assignment operator from a MatrixElement object for single index operations.
04689       RealOnlyAccess& operator=(Element& rhs);
04690 
04691       /// \brief  The casting operator overload for double.
04692       operator const double();
04693       
04694     public: // operator overloads
04695 
04696       bool operator+= (const int    scalar) { return (*this)+=(double)scalar; } //!< add a scaler int     (shorthand notation: A[0] += 5).
04697       bool operator+= (const float  scalar) { return (*this)+=(double)scalar; } //!< add a scaler float   (shorthand notation: A[0] += 5).
04698       bool operator+= (const double scalar);                                    //!< add a scaler double  (shorthand notation: A[0] += 5).
04699 
04700       bool operator-= (const int    scalar) { return (*this)-=(double)scalar; } //!< subtract a scaler int     (shorthand notation: A[0] -= 5).
04701       bool operator-= (const float  scalar) { return (*this)-=(double)scalar; } //!< subtract a scaler float   (shorthand notation: A[0] -= 5).
04702       bool operator-= (const double scalar);                                    //!< subtract a scaler double  (shorthand notation: A[0] -= 5).
04703 
04704       bool operator*= (const int    scalar) { return (*this)*=(double)scalar; } //!< multiply a scalar int     (shorthand notation: A[0] *= 5).
04705       bool operator*= (const float  scalar) { return (*this)*=(double)scalar; } //!< multiply a scalar float   (shorthand notation: A[0] *= 5).
04706       bool operator*= (const double scalar);                                    //!< multiply a scalar double  (shorthand notation: A[0] *= 5).
04707 
04708       bool operator/= (const int    scalar) { return (*this)/=(double)scalar; } //!< divide a scalar int     (shorthand notation: A[0] /= 5).
04709       bool operator/= (const float  scalar) { return (*this)/=(double)scalar; } //!< divide a scalar float   (shorthand notation: A[0] /= 5).
04710       bool operator/= (const double scalar);                                    //!< divide a scalar double  (shorthand notation: A[0] /= 5).
04711       
04712     private:
04713       /// \brief  Check the specified indices. Throw an exception if they are invalid.
04714       /// \return true if valid, false otherwise. 
04715       bool IndexCheck( const unsigned row, const unsigned col );
04716 
04717       /// \brief  Check the specified index into the Matrix as a vector. 
04718       ///         Throw an exception if the index is invalid.
04719       /// \return true if valid, false otherwise. 
04720       bool IndexCheck( const unsigned index );
04721 
04722       MTX& m_Matrix;   //!< The reference to the source matrix.    
04723       unsigned m_row;  //!< The current row to access.
04724     };
04725 
04726     /// \brief  Retrieve a copy of a RealOnlyAccess object which is then used for the second [] overload.
04727     RealOnlyAccess operator[] (const unsigned row); 
04728 
04729   public: // functions for error handling.
04730 
04731     /// \brief  Clear the matrix from memory and handle the error message.
04732     void MatrixError( const char* error );
04733 
04734     /// \brief  Clear the matrix from memory and handle the error message.
04735     void MatrixError( const char* function, const char* error );
04736 
04737     /// \brief  A static function to handle the error message.
04738     static void StaticMatrixError( const char* error );
04739 
04740     /// \brief  A static function to handle the error message.
04741     static void StaticMatrixError( const char* function, const char* error );
04742 
04743 
04744   protected:
04745 
04746     /// \brief  Check the specified indices. Throw an exception if they are invalid.
04747     /// \return true if valid, false otherwise. return code should not be reached!
04748     bool IndexCheck( const unsigned row, const unsigned col );
04749 
04750     /// \brief  Check the specified index into the Matrix as a vector. 
04751     ///         Throw an exception if the index is invalid.
04752     /// \return true if valid, false otherwise. return code should not be reached!    
04753     bool IndexCheck( const unsigned index );
04754 
04755     /// \brief  A single element from the matrix. This is used for write access with operator().
04756     Element m_MatrixElement;
04757 
04758     /// \brief  The deep level matrix container.
04759     MTX m_Matrix;
04760 
04761     /// \brief  This indicates if the mtx core engine been initialized.
04762     static bool m_IsMTXInitialized; 
04763   };
04764 
04765 
04766 
04767     /**
04768   \brief  Plot a single X vs Y series directly to a compressed (run-length-encoded) bitmap file.  
04769   
04770   \code
04771   bool TryPlot()
04772   {
04773     Matrix T;
04774     Matrix S;
04775     bool result;
04776     double pi = 3.1415926535897;
04777     result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
04778     if( !result )
04779       return false;
04780     S = T;
04781     result = S.Inplace_sin();  
04782     if( !result )
04783       return false;
04784     result = Plot( "sine.bmp", "Testing Plot", "time (s)", "voltage (V)", T, S, "sine", "(V)" );
04785     if( !result )
04786       return false;
04787     return true;
04788   }
04789   \endcode
04790 
04791   \return true if successful, false otherwise.
04792   */
04793   bool Plot(
04794     const std::string bmpfilename,        //!< The file name (or full path name) of the output bitmap file.
04795     const std::string title,              //!< The plot title.
04796     const std::string xlabel,             //!< The x-axis label.
04797     const std::string ylabel,             //!< The y-axis label.
04798     Matrix &X,                            //!< The series must be [Nx1] or [1xN].
04799     Matrix &Y,                            //!< The series must be [Nx1] or [1xN].
04800     const std::string series_label,       //!< The series label.
04801     const std::string units,              //!< The series units.
04802     const bool isConnected = true,        //!< Are the data points connected.
04803     const MTX_enumColor color = MTX_BLUE, //!< The color of the data points/line.
04804     const bool isXGridOn = true,          //!< A boolean to indicate if the x grid lines are on.
04805     const bool isYGridOn = true,          //!< A boolean to indicate if the y grid lines are on.  
04806     const bool includeStats = true,       //!< A boolean to indicate if statistics info should be included on the plot.  
04807     const unsigned precisionStats = 5,    //!< The number of significant digits in the statistics.
04808     const unsigned plot_height_cm = 8,    //!< The plot height in cm.
04809     const unsigned plot_width_cm = 10     //!< The plot width in cm.
04810     );
04811 
04812   /**
04813   \brief  Plot two X vs Y series directly to a compressed (run-length-encoded) bitmap file.  
04814   
04815   \code
04816   bool TryPlot2()
04817   {
04818     Matrix T;
04819     Matrix S;
04820     bool result;
04821     double pi = 3.1415926535897;
04822     result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
04823     if( !result )
04824       return false;
04825     S = T;
04826     result = S.Inplace_sin();  
04827     if( !result )
04828       return false;
04829     result = Plot( "sine.bmp", "Testing Plot", "time (s)", "voltage (V)", T, S, "sine", "(V)", T, S+1.0, "sine+1", "(V)" );
04830     if( !result )
04831       return false;
04832     return true;
04833   }
04834   \endcode
04835 
04836   \return true if successful, false otherwise.
04837   */  
04838   bool Plot(
04839     const std::string bmpfilename,          //!< The file name (or full path name) of the output bitmap file.
04840     const std::string title,                //!< The plot title.
04841     const std::string xlabel,               //!< The x-axis label.
04842     const std::string ylabel,               //!< The y-axis label.
04843     Matrix &X_1,                            //!< The series must be [Nx1] or [1xN].
04844     Matrix &Y_1,                            //!< The series must be [Nx1] or [1xN].
04845     const std::string series_label_1,       //!< The series label.
04846     const std::string units_1,              //!< The series units.
04847     Matrix &X_2,                            //!< The series must be [Nx1] or [1xN].
04848     Matrix &Y_2,                            //!< The series must be [Nx1] or [1xN].
04849     const std::string series_label_2,       //!< The series label.
04850     const std::string units_2,              //!< The series units.
04851     const bool isConnected_1 = true,        //!< Are the data points connected.
04852     const MTX_enumColor color_1 = MTX_BLUE, //!< The color of the data points/line.
04853     const bool isConnected_2 = true,        //!< Are the data points connected.
04854     const MTX_enumColor color_2 = MTX_LIMEGREEN,  //!< The color of the data points/line.    
04855     const bool isXGridOn = true,            //!< A boolean to indicate if the x grid lines are on.
04856     const bool isYGridOn = true,            //!< A boolean to indicate if the y grid lines are on.  
04857     const bool includeStats = true,         //!< A boolean to indicate if statistics info should be included on the plot.  
04858     const unsigned precisionStats = 5,      //!< The number of significant digits in the statistics.
04859     const unsigned plot_height_cm = 8,      //!< The plot height in cm.
04860     const unsigned plot_width_cm = 10       //!< The plot width in cm.
04861     );  
04862 
04863   /**
04864   \brief  Plot three X vs Y series directly to a compressed (run-length-encoded) bitmap file.  
04865   
04866   \code
04867   bool TryPlot3()
04868   {
04869     Matrix T;
04870     Matrix S;
04871     bool result;
04872     double pi = 3.1415926535897;
04873     result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
04874     if( !result )
04875       return false;
04876     S = T;
04877     result = S.Inplace_sin();  
04878     if( !result )
04879       return false;
04880     result = Plot( "sine.bmp", "Testing Plot", "time (s)", "voltage (V)", T, S, "sine", "(V)", T, S+1.0, "sine+1", "(V)", T, S+2.0, "sine+2", "(V)" );
04881     if( !result )
04882       return false;
04883     return true;
04884   }
04885   \endcode
04886 
04887   \return true if successful, false otherwise.
04888   */  
04889   bool Plot(
04890     const std::string bmpfilename,       //!< The file name (or full path name) of the output bitmap file.
04891     const std::string title,             //!< The plot title.
04892     const std::string xlabel,            //!< The x-axis label.
04893     const std::string ylabel,            //!< The y-axis label.
04894     Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
04895     Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
04896     const std::string series_label_1,    //!< The series label.
04897     const std::string units_1,           //!< The series units.
04898     Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
04899     Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
04900     const std::string series_label_2,    //!< The series label.
04901     const std::string units_2,           //!< The series units.
04902     Matrix &X_3,                         //!< The series must be [Nx1] or [1xN].
04903     Matrix &Y_3,                         //!< The series must be [Nx1] or [1xN].
04904     const std::string series_label_3,    //!< The series label.
04905     const std::string units_3,           //!< The series units.
04906     const bool isConnected_1 = true,     //!< Are the data points connected.
04907     const MTX_enumColor color_1 = MTX_BLUE,  //!< The color of the data points/line.
04908     const bool isConnected_2 = true,     //!< Are the data points connected.
04909     const MTX_enumColor color_2 = MTX_LIMEGREEN,  //!< The color of the data points/line.    
04910     const bool isConnected_3 = true,     //!< Are the data points connected.
04911     const MTX_enumColor color_3 = MTX_RED,  //!< The color of the data points/line.        
04912     const bool isXGridOn = true,         //!< A boolean to indicate if the x grid lines are on.
04913     const bool isYGridOn = true,         //!< A boolean to indicate if the y grid lines are on.  
04914     const bool includeStats = true,      //!< A boolean to indicate if statistics info should be included on the plot.  
04915     const unsigned precisionStats = 5,   //!< The number of significant digits in the statistics.
04916     const unsigned plot_height_cm = 8,   //!< The plot height in cm.
04917     const unsigned plot_width_cm = 10    //!< The plot width in cm.
04918     );
04919 
04920   /**
04921   \brief  Plot four X vs Y series directly to a compressed (run-length-encoded) bitmap file.  
04922   
04923   \code
04924   bool TryPlot4()
04925   {
04926     Matrix T;
04927     Matrix S;
04928     bool result;
04929     double pi = 3.1415926535897;
04930     result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
04931     if( !result )
04932       return false;
04933     S = T;
04934     result = S.Inplace_sin();  
04935     if( !result )
04936       return false;
04937     result = Plot( "sine.bmp", "Testing Plot", "time (s)", "voltage (V)", T, S, "sine", "(V)", T, S+1.0, "sine+1", "(V)", T, S+2.0, "sine+2", "(V)", T, S+3.0, "sine+3", "(V)" );
04938     if( !result )
04939       return false;
04940     return true;
04941   }
04942   \endcode
04943 
04944   \return true if successful, false otherwise.
04945   */  
04946   bool Plot(
04947     const std::string bmpfilename,       //!< The file name (or full path name) of the output bitmap file.
04948     const std::string title,             //!< The plot title.
04949     const std::string xlabel,            //!< The x-axis label.
04950     const std::string ylabel,            //!< The y-axis label.
04951     Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
04952     Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
04953     const std::string series_label_1,    //!< The series label.
04954     const std::string units_1,           //!< The series units.
04955     Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
04956     Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
04957     const std::string series_label_2,    //!< The series label.
04958     const std::string units_2,           //!< The series units.
04959     Matrix &X_3,                         //!< The series must be [Nx1] or [1xN].
04960     Matrix &Y_3,                         //!< The series must be [Nx1] or [1xN].
04961     const std::string series_label_3,    //!< The series label.
04962     const std::string units_3,           //!< The series units.
04963     Matrix &X_4,                         //!< The series must be [Nx1] or [1xN].
04964     Matrix &Y_4,                         //!< The series must be [Nx1] or [1xN].
04965     const std::string series_label_4,    //!< The series label.
04966     const std::string units_4,           //!< The series units.
04967     const bool isConnected_1 = true,     //!< Are the data points connected.
04968     const MTX_enumColor color_1 = MTX_BLUE,  //!< The color of the data points/line.
04969     const bool isConnected_2 = true,     //!< Are the data points connected.
04970     const MTX_enumColor color_2 = MTX_LIMEGREEN,  //!< The color of the data points/line.    
04971     const bool isConnected_3 = true,     //!< Are the data points connected.
04972     const MTX_enumColor color_3 = MTX_RED,  //!< The color of the data points/line.        
04973     const bool isConnected_4 = true,     //!< Are the data points connected.
04974     const MTX_enumColor color_4 = MTX_PURPLE,  //!< The color of the data points/line.            
04975     const bool isXGridOn = true,         //!< A boolean to indicate if the x grid lines are on.
04976     const bool isYGridOn = true,         //!< A boolean to indicate if the y grid lines are on.  
04977     const bool includeStats = true,      //!< A boolean to indicate if statistics info should be included on the plot.  
04978     const unsigned precisionStats = 5,   //!< The number of significant digits in the statistics.
04979     const unsigned plot_height_cm = 8,   //!< The plot height in cm.
04980     const unsigned plot_width_cm = 10    //!< The plot width in cm.
04981     );
04982 
04983   /**
04984   \brief  Plot five X vs Y series directly to a compressed (run-length-encoded) bitmap file.  
04985   
04986   \code
04987   bool TryPlot5()
04988   {
04989     Matrix T;
04990     Matrix S;
04991     bool result;
04992     double pi = 3.1415926535897;
04993     result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
04994     if( !result )
04995       return false;
04996     S = T;
04997     result = S.Inplace_sin();  
04998     if( !result )
04999       return false;
05000     result = Plot( "sine.bmp", "Testing Plot", "time (s)", "voltage (V)", T, S, "sine", "(V)", T, S+1.0, "sine+1", "(V)", T, S+2.0, "sine+2", "(V)", T, S+3.0, "sine+3", "(V)", T, S+4.0, "sine+4", "(V)" );
05001     if( !result )
05002       return false;
05003     return true;
05004   }
05005   \endcode
05006 
05007   \return true if successful, false otherwise.
05008   */  
05009   bool Plot(
05010     const std::string bmpfilename,       //!< The file name (or full path name) of the output bitmap file.
05011     const std::string title,             //!< The plot title.
05012     const std::string xlabel,            //!< The x-axis label.
05013     const std::string ylabel,            //!< The y-axis label.
05014     Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
05015     Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
05016     const std::string series_label_1,    //!< The series label.
05017     const std::string units_1,           //!< The series units.
05018     Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
05019     Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
05020     const std::string series_label_2,    //!< The series label.
05021     const std::string units_2,           //!< The series units.
05022     Matrix &X_3,                         //!< The series must be [Nx1] or [1xN].
05023     Matrix &Y_3,                         //!< The series must be [Nx1] or [1xN].
05024     const std::string series_label_3,    //!< The series label.
05025     const std::string units_3,           //!< The series units.
05026     Matrix &X_4,                         //!< The series must be [Nx1] or [1xN].
05027     Matrix &Y_4,                         //!< The series must be [Nx1] or [1xN].
05028     const std::string series_label_4,    //!< The series label.
05029     const std::string units_4,           //!< The series units.
05030     Matrix &X_5,                         //!< The series must be [Nx1] or [1xN].
05031     Matrix &Y_5,                         //!< The series must be [Nx1] or [1xN].
05032     const std::string series_label_5,    //!< The series label.
05033     const std::string units_5,           //!< The series units.
05034     const bool isConnected_1 = true,     //!< Are the data points connected.
05035     const MTX_enumColor color_1 = MTX_BLUE,  //!< The color of the data points/line.
05036     const bool isConnected_2 = true,     //!< Are the data points connected.
05037     const MTX_enumColor color_2 = MTX_LIMEGREEN,  //!< The color of the data points/line.    
05038     const bool isConnected_3 = true,     //!< Are the data points connected.
05039     const MTX_enumColor color_3 = MTX_RED,  //!< The color of the data points/line.        
05040     const bool isConnected_4 = true,     //!< Are the data points connected.
05041     const MTX_enumColor color_4 = MTX_PURPLE,  //!< The color of the data points/line.        
05042     const bool isConnected_5 = true,     //!< Are the data points connected.
05043     const MTX_enumColor color_5 = MTX_ORANGE,  //!< The color of the data points/line.        
05044     const bool isXGridOn = true,         //!< A boolean to indicate if the x grid lines are on.
05045     const bool isYGridOn = true,         //!< A boolean to indicate if the y grid lines are on.  
05046     const bool includeStats = true,      //!< A boolean to indicate if statistics info should be included on the plot.  
05047     const unsigned precisionStats = 5,   //!< The number of significant digits in the statistics.
05048     const unsigned plot_height_cm = 8,   //!< The plot height in cm.
05049     const unsigned plot_width_cm = 10    //!< The plot width in cm.
05050     );
05051 
05052   /**
05053   \brief  Plot six X vs Y series directly to a compressed (run-length-encoded) bitmap file.  
05054   
05055   \code
05056   bool TryPlot6()
05057   {
05058     Matrix T;
05059     Matrix S;
05060     bool result;
05061     double pi = 3.1415926535897;
05062     result = T.Inplace_colon( -2*pi, 0.01, 2*pi );
05063     if( !result )
05064       return false;
05065     S = T;
05066     result = S.Inplace_sin();  
05067     if( !result )
05068       return false;
05069     result = Plot( "sine.bmp", "Testing Plot", "time (s)", "voltage (V)", T, S, "sine", "(V)", T, S+1.0, "sine+1", "(V)", T, S+2.0, "sine+2", "(V)", T, S+3.0, "sine+3", "(V)", T, S+4.0, "sine+4", "(V)", T, S+5.0, "sine+5", "(V)" );
05070     if( !result )
05071       return false;
05072     return true;
05073   }
05074   \endcode
05075 
05076   \return true if successful, false otherwise.
05077   */  
05078   bool Plot(
05079     const std::string bmpfilename,       //!< The file name (or full path name) of the output bitmap file.
05080     const std::string title,             //!< The plot title.
05081     const std::string xlabel,            //!< The x-axis label.
05082     const std::string ylabel,            //!< The y-axis label.
05083     Matrix &X_1,                         //!< The series must be [Nx1] or [1xN].
05084     Matrix &Y_1,                         //!< The series must be [Nx1] or [1xN].
05085     const std::string series_label_1,    //!< The series label.
05086     const std::string units_1,           //!< The series units.
05087     Matrix &X_2,                         //!< The series must be [Nx1] or [1xN].
05088     Matrix &Y_2,                         //!< The series must be [Nx1] or [1xN].
05089     const std::string series_label_2,    //!< The series label.
05090     const std::string units_2,           //!< The series units.
05091     Matrix &X_3,                         //!< The series must be [Nx1] or [1xN].
05092     Matrix &Y_3,                         //!< The series must be [Nx1] or [1xN].
05093     const std::string series_label_3,    //!< The series label.
05094     const std::string units_3,           //!< The series units.
05095     Matrix &X_4,                         //!< The series must be [Nx1] or [1xN].
05096     Matrix &Y_4,                         //!< The series must be [Nx1] or [1xN].
05097     const std::string series_label_4,    //!< The series label.
05098     const std::string units_4,           //!< The series units.
05099     Matrix &X_5,                         //!< The series must be [Nx1] or [1xN].
05100     Matrix &Y_5,                         //!< The series must be [Nx1] or [1xN].
05101     const std::string series_label_5,    //!< The series label.
05102     const std::string units_5,           //!< The series units.
05103     Matrix &X_6,                         //!< The series must be [Nx1] or [1xN].
05104     Matrix &Y_6,                         //!< The series must be [Nx1] or [1xN].
05105     const std::string series_label_6,    //!< The series label.
05106     const std::string units_6,           //!< The series units.
05107     const bool isConnected_1 = true,     //!< Are the data points connected.
05108     const MTX_enumColor color_1 = MTX_BLUE,  //!< The color of the data points/line.
05109     const bool isConnected_2 = true,     //!< Are the data points connected.
05110     const MTX_enumColor color_2 = MTX_LIMEGREEN,  //!< The color of the data points/line.    
05111     const bool isConnected_3 = true,     //!< Are the data points connected.
05112     const MTX_enumColor color_3 = MTX_RED,  //!< The color of the data points/line.        
05113     const bool isConnected_4 = true,     //!< Are the data points connected.
05114     const MTX_enumColor color_4 = MTX_PURPLE,  //!< The color of the data points/line.        
05115     const bool isConnected_5 = true,     //!< Are the data points connected.
05116     const MTX_enumColor color_5 = MTX_ORANGE,  //!< The color of the data points/line.        
05117     const bool isConnected_6 = true,     //!< Are the data points connected.
05118     const MTX_enumColor color_6 = MTX_GREEN,  //!< The color of the data points/line.        
05119     const bool isXGridOn = true,         //!< A boolean to indicate if the x grid lines are on.
05120     const bool isYGridOn = true,         //!< A boolean to indicate if the y grid lines are on.  
05121     const bool includeStats = true,      //!< A boolean to indicate if statistics info should be included on the plot.  
05122     const unsigned precisionStats = 5,   //!< The number of significant digits in the statistics.
05123     const unsigned plot_height_cm = 8,   //!< The plot height in cm.
05124     const unsigned plot_width_cm = 10    //!< The plot width in cm.
05125     );
05126 
05127 } // end namespace Zenautics
05128 
05129 #endif // _ZENAUTICS_MATRIX_H_
05130 

Generated on Sun Feb 8 15:31:10 2009 for The Zenautics Matrix Project by  doxygen 1.5.4