Matrix.cpp

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 The implementation of exception handling and the use of namespace is
00049 not standardized among older compilers, the following deines may be 
00050 necessary. \n
00051 #define _MATRIX_NO_NAMESPACE // removes namespace support. \n
00052 #define _MATRIX_NO_EXCEPTION // removes exception handling support. \n
00053 */
00054 
00055 #include <stdlib.h>
00056 #include <string.h>
00057 
00058 #include "Matrix.h"
00059 #include "cmatrix.h"
00060 
00061 // deal with msvc empty projects
00062 #ifndef WIN32
00063   #ifdef _WIN32
00064     #define WIN32
00065   #endif
00066 #endif
00067 
00068 #ifndef WIN32
00069 #define _CRT_SECURE_NO_DEPRECATE
00070 #endif
00071 
00072 
00073 #ifndef DEG2RAD
00074 #define DEG2RAD   (0.017453292519943295769236907684886)  //!< PI/180.0
00075 #endif
00076 
00077 #ifndef RAD2DEG
00078 #define RAD2DEG   (57.295779513082320876798154814105)    //!< 180.0/PI
00079 #endif
00080 
00081 namespace Zenautics
00082 {
00083   /// A static double  value used for bad referencing. i.e. give me element 10 of 1x9 vector.
00084   static double staticglobal_BadDouble = 0.0;
00085 
00086   // A boolean used to ensure initialization of the mtx engine.
00087   bool Matrix::m_IsMTXInitialized = false;
00088 
00089 
00090 #ifndef _MATRIX_NO_EXCEPTION
00091 
00092   MatrixException::MatrixException( const char* msg )
00093   {
00094     unsigned msgLength = 0;
00095     if( msg == NULL )
00096     {
00097 #ifndef _CRT_SECURE_NO_DEPRECATE
00098       strcpy_s( m_msg, 256, "Unknown Matrix Exception" );
00099 #else
00100       strcpy( m_msg, "Unknown Matrix Exception" );
00101 #endif
00102     }
00103     else
00104     {
00105       msgLength = (unsigned)strlen( msg );
00106       // note 255 here, not 256, 
00107       // just in case msgLength is 255 and we add '\0' to the end of m_msg.
00108 #ifndef _CRT_SECURE_NO_DEPRECATE
00109       if( msgLength < 255 )
00110       {
00111         strncpy_s( m_msg, 256, msg, msgLength );
00112         m_msg[msgLength] = '\0';
00113       }
00114       else
00115       {
00116         strncpy_s( m_msg, 256, msg, 255 );
00117         m_msg[255] = '\0';
00118       }
00119 #else
00120       if( msgLength < 255 )
00121       {
00122         strncpy( m_msg, msg, msgLength );
00123         m_msg[msgLength] = '\0';
00124       }
00125       else
00126       {
00127         strncpy( m_msg, msg, 255 );
00128         m_msg[255] = '\0';
00129       }
00130 #endif
00131     }
00132     m_ExceptionString = m_msg;
00133   }
00134 
00135   MatrixException::MatrixException(const MatrixException& matrix_exception)
00136   {
00137     // This will copy only the matrix exception string.
00138     m_ExceptionString = matrix_exception.m_ExceptionString;
00139   }
00140 
00141   std::string MatrixException::GetExceptionMessage()
00142   {
00143     return m_ExceptionString;
00144   }
00145 
00146   MatrixException::operator const char*()
00147   {
00148     return m_ExceptionString.c_str();
00149   }
00150 #endif
00151 
00152 
00153   // default constructor
00154   Matrix::Matrix()
00155     :m_MatrixElement(m_Matrix)
00156   {
00157     if( !m_IsMTXInitialized )
00158     {
00159       if( !MTX_Initialize_MTXEngine() )
00160       {
00161         m_IsMTXInitialized = false;
00162         MatrixError( "Matrix", "Failed to initialize the MTX Engine." );
00163       }
00164       else
00165       {
00166         m_IsMTXInitialized = true;
00167       }
00168     }
00169 
00170     MTX_Init( &m_Matrix );
00171   }
00172 
00173 
00174   // destructor
00175   Matrix::~Matrix()
00176   { 
00177     if( !MTX_Free( &m_Matrix ) )
00178     {
00179       MatrixError( "~Matrix", "Unable to free memory properly" );
00180     }
00181   }
00182 
00183 
00184   // vector style constructor
00185   Matrix::Matrix( const unsigned nrows )
00186     :m_MatrixElement(m_Matrix)
00187   { 
00188     if( !m_IsMTXInitialized )
00189     {
00190       if( !MTX_Initialize_MTXEngine() )
00191       {
00192         m_IsMTXInitialized = false;
00193         MatrixError( "Matrix", "Failed to initialize the MTX Engine." );
00194       }
00195       else
00196       {
00197         m_IsMTXInitialized = true;
00198       }
00199     }
00200 
00201     MTX_Init( &m_Matrix );
00202     if( !MTX_Calloc( &m_Matrix, nrows, 1, true ) )
00203     {
00204       char msg[128];
00205 #ifndef _CRT_SECURE_NO_DEPRECATE
00206       sprintf_s( msg, 128, "Unable to allocate enough memory for Matrix as vector(%d)", nrows );
00207 #else
00208       sprintf( msg, "Unable to allocate enough memory for Matrix as vector(%d)", nrows );
00209 #endif
00210       MatrixError( "Matrix", msg );
00211     }
00212   }
00213 
00214 
00215   // matrix style constructor
00216   Matrix::Matrix( const unsigned nrows, const unsigned ncols, const bool isReal )
00217     :m_MatrixElement(m_Matrix)
00218   { 
00219     if( !m_IsMTXInitialized )
00220     {
00221       if( !MTX_Initialize_MTXEngine() )
00222       {
00223         m_IsMTXInitialized = false;
00224         MatrixError( "Matrix", "Failed to initialize the MTX Engine." );
00225       }
00226       else
00227       {
00228         m_IsMTXInitialized = true;
00229       }
00230     }
00231 
00232     MTX_Init( &m_Matrix );
00233     if( !MTX_Calloc( &m_Matrix, nrows, ncols, isReal ) )
00234     {
00235       char msg[128];
00236 #ifndef _CRT_SECURE_NO_DEPRECATE
00237       if( isReal )
00238         sprintf_s( msg, 128, "Unable to allocate enough memory for Matrix(%d,%d)", nrows, ncols );
00239       else
00240         sprintf_s( msg, 128, "Unable to allocate enough memory for complex Matrix(%d,%d)", nrows, ncols );
00241 #else
00242       if( isReal )
00243         sprintf( msg, "Unable to allocate enough memory for Matrix(%d,%d)", nrows, ncols );
00244       else
00245         sprintf( msg, "Unable to allocate enough memory for complex Matrix(%d,%d)", nrows, ncols );
00246 #endif
00247 
00248       MatrixError( "Matrix", msg );
00249     }
00250   }
00251 
00252 
00253   // constructor reading data from file   
00254   Matrix::Matrix( const char* path, bool& itWorked )
00255     :m_MatrixElement(m_Matrix)
00256   {
00257     if( !m_IsMTXInitialized )
00258     {
00259       if( !MTX_Initialize_MTXEngine() )
00260       {
00261         m_IsMTXInitialized = false;
00262         MatrixError( "Matrix", "Failed to initialize the MTX Engine." );
00263       }
00264       else
00265       {
00266         m_IsMTXInitialized = true;
00267       }
00268     }
00269 
00270     MTX_Init( &m_Matrix );
00271 
00272     if( MTX_ReadFromFile( &m_Matrix, path ) )
00273       itWorked = true;
00274     else
00275       itWorked = false;  
00276   }
00277 
00278   // copy constructor
00279   Matrix::Matrix( const Matrix& mat )
00280     :m_MatrixElement(m_Matrix)
00281   {
00282     MTX_Init( &m_Matrix );
00283     if( !MTX_Copy( &(mat.m_Matrix), &m_Matrix ) )
00284     {
00285       MatrixError( "Matrix", "Copy constructor failed to copy input matrix." );
00286     }
00287   }
00288 
00289   // copy from a static matrix
00290   Matrix::Matrix(const double mat[], const unsigned nrows, const unsigned ncols )
00291     :m_MatrixElement(m_Matrix)
00292   {
00293     MTX_Init( &m_Matrix );
00294     if( mat == NULL )
00295     {
00296       MatrixError( "Matrix", "Input static double array(matrix) pointer is NULL" );
00297     }
00298     if( !MTX_SetFromStaticMatrix( &m_Matrix, mat, nrows, ncols ) )
00299     {
00300       MatrixError( "Matrix", "Failed to set the matrix from a static double array(matrix)" );
00301     }
00302   }
00303 
00304   // copy from a matrix string 
00305   Matrix::Matrix(const char* strMatrix)
00306     :m_MatrixElement(m_Matrix)
00307   {
00308     MTX_Init( &m_Matrix );
00309     if( !MTX_SetFromMatrixString( &m_Matrix, strMatrix ) )
00310     {
00311       MatrixError( "Matrix = \"string matrix\"", "Unable to set matrix from the string specified." );
00312     }    
00313   }
00314 
00315 
00316   // assignment operator (constructor)
00317   Matrix& Matrix::operator= (const Matrix& mat)
00318   {
00319     // trap assignment to self
00320     if( this == &mat )
00321       return *this;
00322 
00323     if( !MTX_Copy( &mat.m_Matrix, &m_Matrix ) )
00324     {
00325       MatrixError( "operator=", "Failed to copy input matrix" );
00326     }
00327 
00328     return *this;
00329   }
00330 
00331 
00332   Matrix& Matrix::operator= (const double value)
00333   {
00334     if( !MTX_Malloc( &m_Matrix, 1, 1, true ) )
00335     {
00336       MatrixError( "operator=double", "Unable to redimension to 1x1." );
00337     }
00338 
00339     if( !MTX_SetValue( &m_Matrix, 0, 0, value ) )
00340     {
00341       MatrixError( "operator=double", "Unable to set double value." );
00342     }
00343 
00344     return *this;
00345   }
00346 
00347   Matrix& Matrix::operator= (const std::complex<double> value)
00348   {
00349     if( !MTX_Malloc( &m_Matrix, 1, 1, false ) )
00350     {
00351       MatrixError( "operator=std::complex<double>", "Unable to redimension to 1x1." );
00352     }
00353 
00354     if( !MTX_SetComplexValue( &m_Matrix, 0, 0, value.real(), value.imag() ) )
00355     {
00356       MatrixError( "operator=std::complex<double>", "Unable to set the value." );
00357     }
00358 
00359     return *this;
00360   }
00361 
00362   Matrix& Matrix::operator=(const char* strMatrix)
00363   {
00364     if( !MTX_SetFromMatrixString( &m_Matrix, strMatrix ) )
00365     {
00366       MatrixError( "operator=string", "Unable to set matrix from the string specified." );
00367     }
00368     return *this;
00369   }
00370 
00371   bool Matrix::Clear()
00372   {
00373     if( MTX_Free( &m_Matrix ) )
00374     {
00375       return true;
00376     }
00377     else
00378     {
00379       MTX_ERROR_MSG( "MTX_FREE returned false." );
00380       return false;    
00381     }
00382   }
00383 
00384   void Matrix::MatrixError( const char* error )
00385   {
00386     Clear();
00387     StaticMatrixError( error );
00388   }
00389 
00390   void Matrix::MatrixError( const char* function, const char* error )
00391   {
00392     Clear();
00393     StaticMatrixError( function, error );
00394   }
00395 
00396 
00397   // static
00398   void Matrix::StaticMatrixError( const char* error )
00399   {
00400     StaticMatrixError( "", error );
00401   }
00402 
00403   // static
00404   void Matrix::StaticMatrixError( const char* function, const char* error )
00405   {
00406     char msg[256];
00407 #ifndef _CRT_SECURE_NO_DEPRECATE
00408     if( strstr(function,"operator") != NULL )
00409       sprintf_s( msg, 256, "\nMatrix::%s, Error:\n%s\n", function, error );   
00410     else
00411       sprintf_s( msg, 256, "\nMatrix::%s(), Error:\n%s\n", function, error );
00412 #else
00413     if( strstr(function,"operator") != NULL )
00414       sprintf( msg, "\nMatrix::%s, Error:\n%s\n", function, error );   
00415     else
00416       sprintf( msg, "\nMatrix::%s(), Error:\n%s\n", function, error );
00417 #endif
00418 
00419 #ifndef _MATRIX_NO_EXCEPTION
00420 
00421     throw MatrixException(msg);
00422     return;
00423 
00424 #else
00425 
00426     printf( "%s\r\n", msg );   
00427 
00428     // no choice but to call exit!
00429     exit(1);
00430 
00431 #endif    
00432   }
00433 
00434 
00435   bool Matrix::isEmpty() const
00436   {
00437     if( MTX_isNull( &m_Matrix ) )
00438     {
00439       return true;
00440     }
00441     else
00442     {
00443       return false;
00444     }
00445   }
00446 
00447   bool Matrix::isConformal(const Matrix& mat) const
00448   {
00449     if( MTX_isConformalForMultiplication( &m_Matrix, &mat.m_Matrix ) )
00450     {
00451       return true;
00452     }
00453     else
00454     {
00455       MTX_ERROR_MSG( "MTX_isConformalForMultiplication returned false." );
00456       return false;
00457     }
00458   }
00459 
00460   bool Matrix::isSameSize(const Matrix& mat) const
00461   {
00462     if( MTX_isSameSize( &m_Matrix, &mat.m_Matrix ) )
00463     {
00464       return true;
00465     }
00466     else 
00467     {
00468       MTX_ERROR_MSG( "MTX_isSameSize returned false." );
00469       return false;
00470     }
00471   }
00472 
00473   bool Matrix::isSquare() const
00474   {
00475     if( MTX_isSquare( &m_Matrix ) )
00476     {
00477       return true;
00478     }
00479     else 
00480     {
00481       MTX_ERROR_MSG( "MTX_isSquare returned false." );
00482       return false;
00483     }
00484   }
00485 
00486   unsigned  Matrix::GetNrCols() const
00487   {
00488     return m_Matrix.ncols;
00489   }
00490 
00491   unsigned  Matrix::ncols() const
00492   {
00493     return m_Matrix.ncols;
00494   }
00495 
00496   unsigned Matrix::GetNrElems() const
00497   {
00498     return m_Matrix.ncols*m_Matrix.nrows;
00499   }
00500 
00501   unsigned Matrix::nelems() const
00502   {
00503     return m_Matrix.ncols*m_Matrix.nrows;
00504   }
00505 
00506   unsigned Matrix::GetNrRows() const
00507   {
00508     return m_Matrix.nrows;
00509   }
00510 
00511   unsigned Matrix::nrows() const
00512   {
00513     return m_Matrix.nrows;
00514   }
00515 
00516   unsigned Matrix::GetLength() const
00517   {
00518     if( m_Matrix.nrows > m_Matrix.ncols )
00519       return m_Matrix.nrows;
00520     else
00521       return m_Matrix.ncols;
00522   }
00523 
00524   double Matrix::real(const unsigned row, const unsigned col)
00525   {
00526     if( IndexCheck(row,col) )
00527     {
00528       if( m_Matrix.isReal )
00529       {
00530         return m_Matrix.data[col][row];
00531       }
00532       else
00533       {
00534         return m_Matrix.cplx[col][row].re;
00535       }
00536     }
00537     else
00538     {
00539       return 0.0;
00540     }
00541   }
00542 
00543   double Matrix::real(const unsigned index)
00544   {
00545     unsigned row = 0;
00546     unsigned col = 0;
00547 
00548     if( IndexCheck(index) )
00549     {
00550       if( m_Matrix.ncols == 1 )
00551       {
00552         row = index;
00553       }
00554       else if( m_Matrix.nrows == 1 )
00555       {
00556         col = index;
00557       }
00558       else
00559       {
00560         // access the matrix as a singular column array
00561         col = index / m_Matrix.nrows;
00562         row = index - col*m_Matrix.nrows;
00563       }
00564       if( m_Matrix.isReal )
00565       {
00566         return m_Matrix.data[col][row];
00567       }
00568       else
00569       {
00570         return m_Matrix.cplx[col][row].re;
00571       }
00572     }
00573     else
00574     {
00575       return 0.0;
00576     }
00577   }
00578 
00579   double Matrix::imag(const unsigned row, const unsigned col)
00580   {
00581     if( IndexCheck(row,col) )
00582     {
00583       if( m_Matrix.isReal )
00584       {
00585         return 0.0;
00586       }
00587       else
00588       {
00589         return m_Matrix.cplx[col][row].im;
00590       }
00591     }
00592     else
00593     {
00594       return 0.0;
00595     }
00596   }
00597 
00598   double Matrix::imag(const unsigned index)
00599   {
00600     unsigned row = 0;
00601     unsigned col = 0;
00602 
00603     if( IndexCheck(index) )
00604     {
00605       if( m_Matrix.ncols == 1 )
00606       {
00607         row = index;
00608       }
00609       else if( m_Matrix.nrows == 1 )
00610       {
00611         col = index;
00612       }
00613       else
00614       {
00615         // access the matrix as a singular column array
00616         col = index / m_Matrix.nrows;
00617         row = index - col*m_Matrix.nrows;
00618       }
00619       if( m_Matrix.isReal )
00620       {
00621         return 0.0;
00622       }
00623       else
00624       {
00625         return m_Matrix.cplx[col][row].im;
00626       }
00627     }
00628     else
00629     {
00630       return 0.0;
00631     }
00632   }
00633 
00634   bool Matrix::isStoredAsComplex()
00635   {
00636     if( m_Matrix.isReal )
00637       return false;
00638     else
00639       return true;
00640   }
00641 
00642   /// Is this a real matrix for accessing by (row,col) operator? e.g. double d = A(0,4).
00643   bool Matrix::isReal()
00644   {
00645     BOOL isItReal = 0;
00646     
00647     // not checking return value
00648     MTX_isReal(&m_Matrix,&isItReal);
00649 
00650     if( isItReal )
00651       return true;
00652     else
00653       return false;    
00654   }
00655 
00656   /// Is this a complex matrix for accessing by [row][col] operators? e.g. stComplex d = A[0][4].
00657   bool Matrix::isComplex()
00658   {
00659     return !isReal();
00660   }
00661 
00662   bool Matrix::isVector()
00663   {
00664     if( m_Matrix.nrows == 1 )
00665       return true;
00666     if( m_Matrix.ncols == 1 )
00667       return true;
00668 
00669     // otherwise
00670     return false;
00671   }
00672 
00673   bool Matrix::ReadFromFile( const char *path )
00674   {
00675     if( MTX_ReadFromFile( &m_Matrix, path ) )
00676     {
00677       return true;
00678     }
00679     else 
00680     {
00681       MTX_ERROR_MSG( "MTX_ReadFromFile returned false." );
00682       return false;
00683     }
00684   }
00685 
00686 
00687   bool Matrix::ReadFromFile( std::string path )
00688   {
00689     return ReadFromFile( path.c_str() );
00690   }
00691 
00692 
00693   bool Matrix::Copy( Matrix& src )
00694   {
00695     if( MTX_Copy( &src.m_Matrix, &m_Matrix ) )
00696     {
00697       return true;
00698     }
00699     else
00700     {
00701       MTX_ERROR_MSG( "MTX_Copy returned false." );
00702       return false;
00703     }
00704   }
00705 
00706   bool Matrix::Copy( const double& value )
00707   {
00708     if( !MTX_Malloc( &m_Matrix, 1, 1, true ) )
00709     {
00710       MTX_ERROR_MSG( "MTX_Malloc returned false." );
00711       return false;
00712     }
00713 
00714     if( MTX_SetValue( &m_Matrix, 0, 0, value ) )
00715     {
00716       return true;
00717     }
00718     else
00719     {
00720       MTX_ERROR_MSG( "MTX_SetValue returned false." );      
00721       return false;
00722     }
00723   }
00724 
00725   bool Matrix::Copy( const std::complex<double>& cplx )
00726   {
00727     if( !MTX_Malloc( &m_Matrix, 1, 1, false ) )
00728     {
00729       MTX_ERROR_MSG( "MTX_Malloc returned false." );      
00730       return false;
00731     }
00732 
00733     if( MTX_SetComplexValue( &m_Matrix, 0, 0, cplx.real(), cplx.imag() ) )
00734     {
00735       return true;
00736     }
00737     else
00738     {
00739       MTX_ERROR_MSG( "MTX_SetComplexValue returned false." );      
00740       return false;
00741     }
00742   }
00743 
00744   bool Matrix::Save( const char* path )
00745   {
00746     if( MTX_SaveCompressed( &m_Matrix, path ) )
00747     {
00748       return true;
00749     }
00750     else 
00751     {
00752       MTX_ERROR_MSG( "MTX_SaveCompressed returned false." );      
00753       return false;
00754     }
00755   }
00756 
00757   bool Matrix::Save( std::string path )
00758   {
00759     return Save( path.c_str() );
00760   }
00761 
00762   bool Matrix::Print( const char *path, const unsigned precision, bool append )
00763   {
00764     if( MTX_PrintAutoWidth( &m_Matrix, path, precision, append ) )
00765     {
00766       return true;
00767     }
00768     else 
00769     {
00770       MTX_ERROR_MSG( "MTX_PrintAutoWidth returned false." );      
00771       return false;
00772     }
00773   }
00774 
00775   bool Matrix::Print( std::string path, const unsigned precision, bool append ) 
00776   {
00777     return Print( path.c_str(), precision );
00778   }
00779 
00780   bool Matrix::PrintStdout( const unsigned precision )
00781   {
00782     if( m_Matrix.ncols == 0 || m_Matrix.nrows == 0 )
00783     {
00784       printf( "\n" );
00785       return true;
00786     }
00787     if( MTX_PrintStdoutAutoWidth( &m_Matrix, precision ) )
00788     {
00789       return true;
00790     }
00791     else
00792     {
00793       MTX_ERROR_MSG( "MTX_PrintStdoutAutoWidth returned false." );      
00794       return false;
00795     }
00796   }
00797 
00798   bool Matrix::PrintToBuffer( char* buffer, const unsigned maxlength, const unsigned precision )
00799   {
00800     if( MTX_PrintAutoWidth_ToBuffer( &m_Matrix, buffer, maxlength, precision ) )
00801     {
00802       return true;
00803     }
00804     else 
00805     {
00806       MTX_ERROR_MSG( "MTX_PrintAutoWidth_ToBuffer returned false." );      
00807       return false;
00808     }
00809   }
00810 
00811   bool Matrix::PrintFixedWidth( const char* path, const unsigned width, const unsigned precision, bool append )
00812   {
00813     if( MTX_Print( &m_Matrix, path, width, precision, append ) )
00814     {
00815       return true;
00816     }
00817     else 
00818     {
00819       MTX_ERROR_MSG( "MTX_Print returned false." );            
00820       return false;
00821     }
00822   }
00823 
00824   bool Matrix::PrintFixedWidth( std::string path, const unsigned width, const unsigned precision, bool append )
00825   {
00826     return PrintFixedWidth( path.c_str(), width, precision, append );
00827   }
00828 
00829   bool Matrix::PrintFixedWidthToBuffer( char* buffer, const unsigned maxlength, const unsigned width, const unsigned precision )
00830   {
00831     if( MTX_Print_ToBuffer( &m_Matrix, buffer, maxlength, width, precision ) )
00832     {
00833       return true;
00834     }
00835     else 
00836     {
00837       MTX_ERROR_MSG( "MTX_Print_ToBuffer returned false." );            
00838       return false;
00839     }
00840   }
00841 
00842   bool Matrix::PrintDelimited( const char *path, const unsigned precision, const char delimiter, bool append )
00843   {
00844     if( MTX_PrintDelimited( &m_Matrix, path, precision, delimiter, append ) )
00845     {
00846       return true;
00847     }
00848     else 
00849     {
00850       MTX_ERROR_MSG( "MTX_PrintDelimited returned false." );            
00851       return false;
00852     }
00853   }
00854 
00855   bool Matrix::PrintDelimited( std::string path, const unsigned precision, const char delimiter, bool append )
00856   {
00857     return PrintDelimited( path.c_str(), precision, delimiter, append );
00858   }
00859     
00860 
00861   bool Matrix::PrintDelimitedToBuffer( char *buffer, const unsigned maxlength, const unsigned precision, const char delimiter )
00862   {
00863     if( MTX_PrintDelimited_ToBuffer( &m_Matrix, buffer, maxlength, precision, delimiter ) )
00864     {
00865       return true;
00866     }
00867     else 
00868     {
00869       MTX_ERROR_MSG( "MTX_PrintDelimited_ToBuffer returned false." );            
00870       return false;
00871     }
00872   }
00873 
00874   bool Matrix::PrintRowToString( const unsigned row, char *buffer, const unsigned maxlength, const int width, const int precision )
00875   {
00876     if( MTX_PrintRowToString( &m_Matrix, row, buffer, maxlength, width, precision ) )
00877     {
00878       return true;
00879     }
00880     else
00881     {
00882       MTX_ERROR_MSG( "MTX_PrintRowToString returned false." );            
00883       return false;
00884     }
00885   }
00886 
00887 
00888   bool Matrix::RemoveColumn( const unsigned col )
00889   {
00890     if( MTX_RemoveColumn( &m_Matrix, col ) )
00891     {
00892       return true;
00893     }
00894     else 
00895     {
00896       MTX_ERROR_MSG( "MTX_RemoveColumn returned false." );            
00897       return false;
00898     }
00899   }
00900 
00901   bool Matrix::RemoveColumnsAfterIndex( const unsigned col )
00902   {
00903     if( MTX_RemoveColumnsAfterIndex( &m_Matrix, col ) )
00904     {
00905       return true;
00906     }
00907     else 
00908     {
00909       MTX_ERROR_MSG( "MTX_RemoveColumnsAfterIndex returned false." );            
00910       return false;
00911     }
00912   }
00913 
00914   bool Matrix::RemoveRowsAndColumns( const unsigned nrows, const unsigned rows[], const unsigned ncols, const unsigned cols[] )
00915   {
00916     if( MTX_RemoveRowsAndColumns( &m_Matrix, nrows, rows, ncols, cols ) )
00917     {
00918       return true;
00919     }
00920     else
00921     {
00922       MTX_ERROR_MSG( "MTX_RemoveRowsAndColumns returned false." );            
00923       return false;
00924     }
00925   }
00926 
00927   bool Matrix::InsertColumn( const Matrix &src, const unsigned dst_col, const unsigned src_col )
00928   {
00929     if( MTX_InsertColumn( &m_Matrix, &src.m_Matrix, dst_col, src_col ) )
00930     {
00931       return true;
00932     }
00933     else 
00934     {
00935       MTX_ERROR_MSG( "MTX_InsertColumn returned false." );            
00936       return false;
00937     }
00938   }
00939 
00940   bool Matrix::AddColumn( const Matrix &src, const unsigned src_col )
00941   {
00942     if( MTX_AddColumn( &m_Matrix, &src.m_Matrix, src_col ) )
00943     {
00944       return true;
00945     }
00946     else 
00947     {
00948       MTX_ERROR_MSG( "MTX_AddColumn returned false." );            
00949       return false;
00950     }
00951   }
00952 
00953   bool Matrix::Concatonate( const Matrix &src )
00954   {
00955     if( MTX_Concatonate( &m_Matrix, &src.m_Matrix ) )
00956     {
00957       return true;
00958     }
00959     else 
00960     {
00961       MTX_ERROR_MSG( "MTX_Concatonate returned false." );
00962       return false;
00963     }
00964   }
00965 
00966   bool Matrix::Redim( const unsigned nrows, const unsigned ncols )
00967   {
00968     if( MTX_Redim( &m_Matrix, nrows, ncols ) )
00969     {
00970       return true;
00971     }
00972     else 
00973     {
00974       MTX_ERROR_MSG( "MTX_Redim returned false." );
00975       return false;
00976     }
00977   }
00978 
00979   bool Matrix::Resize( const unsigned nrows, const unsigned ncols )
00980   {
00981     if( MTX_Resize( &m_Matrix, nrows, ncols, m_Matrix.isReal ) )
00982     {
00983       return true;
00984     }
00985     else 
00986     {
00987       MTX_ERROR_MSG( "MTX_Resize returned false." );
00988       return false;
00989     }
00990   }
00991 
00992 
00993   bool Matrix::SetFromStaticMatrix( const double mat[], const unsigned nrows, const unsigned ncols )
00994   {
00995     if( MTX_SetFromStaticMatrix( &m_Matrix, mat, nrows, ncols ) )
00996     {
00997       return true;
00998     }
00999     else 
01000     {
01001       MTX_ERROR_MSG( "MTX_SetFromStaticMatrix returned false." );
01002       return false;
01003     }
01004   }
01005 
01006   bool Matrix::SetFromMatrixString(const char* strMatrix)
01007   {
01008     if( MTX_SetFromMatrixString( &m_Matrix, strMatrix ) )
01009     {
01010       return true;
01011     }
01012     else
01013     {
01014       MTX_ERROR_MSG( "MTX_SetFromStaticMatrix returned false." );
01015       return false;
01016     }
01017   }
01018 
01019   bool Matrix::CopyColumn( const unsigned src_col, Matrix &dst )
01020   {
01021     if( MTX_CopyColumn( &m_Matrix, src_col, &dst.m_Matrix ) )
01022     {
01023       return true;
01024     }
01025     else 
01026     {
01027       MTX_ERROR_MSG( "MTX_CopyColumn returned false." );
01028       return false;
01029     }
01030   }
01031 
01032   bool Matrix::InsertSubMatrix( const Matrix &src, const unsigned dst_row, const unsigned dst_col )
01033   {
01034     if( MTX_InsertSubMatrix( &m_Matrix, &src.m_Matrix, dst_row, dst_col ) )
01035     {
01036       return true;
01037     }
01038     else 
01039     {
01040       MTX_ERROR_MSG( "MTX_InsertSubMatrix returned false." );
01041       return false;
01042     }
01043   }
01044 
01045   bool Matrix::ExtractSubMatrix( 
01046     Matrix &dst,             //!< The destination matrix to contain the submatrix.
01047     const unsigned from_row, //!< The zero-based index for the from row.
01048     const unsigned from_col, //!< The zero-based index for the from column.
01049     const unsigned to_row,   //!< The zero-based index for the to row.
01050     const unsigned to_col    //!< The zero-based index for the to column.
01051     )
01052   {
01053     if( MTX_ExtractSubMatrix( &m_Matrix, &dst.m_Matrix, from_row, from_col, to_row, to_col ) )
01054     {
01055       return true;
01056     }
01057     else
01058     {
01059       MTX_ERROR_MSG( "MTX_ExtractSubMatrix returned false." );
01060       return false;
01061     }
01062   }
01063 
01064   bool Matrix::Zero()
01065   {
01066     if( MTX_Zero( &m_Matrix ) )
01067     {
01068       return true;
01069     }
01070     else 
01071     {
01072       MTX_ERROR_MSG( "MTX_Zero returned false." );
01073       return false;
01074     }
01075   }
01076 
01077   bool Matrix::ZeroColumn( const unsigned col )
01078   {
01079     if( MTX_ZeroColumn( &m_Matrix, col ) )
01080     {
01081       return true;
01082     }
01083     else 
01084     {
01085       MTX_ERROR_MSG( "MTX_ZeroColumn returned false." );
01086       return false;
01087     }
01088   }
01089 
01090   bool Matrix::ZeroRow( const unsigned row )
01091   {
01092     if( MTX_ZeroRow( &m_Matrix, row ) )
01093     {
01094       return true;
01095     }
01096     else 
01097     {
01098       MTX_ERROR_MSG( "MTX_ZeroRow returned false." );
01099       return false;
01100     }
01101   }
01102 
01103   bool Matrix::Swap( Matrix &M )
01104   {
01105     if( MTX_Swap( &m_Matrix, &M.m_Matrix ) )
01106     {
01107       return true;
01108     }
01109     else
01110     {
01111       return false;
01112     }
01113   }
01114 
01115   bool Matrix::Fill( const double value )
01116   {
01117     if( MTX_Fill( &m_Matrix, value ) )
01118     {
01119       return true;
01120     }
01121     else 
01122     {
01123       MTX_ERROR_MSG( "MTX_Fill returned false." );
01124       return false;
01125     }
01126   }
01127 
01128   bool Matrix::FillColumn( const unsigned col, const double value )
01129   {
01130     if( MTX_FillColumn( &m_Matrix, col, value ) )
01131     {
01132       return true;
01133     }
01134     else 
01135     {
01136       MTX_ERROR_MSG( "FillColumn returned false." );
01137       return false;
01138     }
01139   }
01140 
01141   bool Matrix::FillRow( const unsigned row, const double value )
01142   {
01143     if( MTX_FillRow( &m_Matrix, row, value ) )
01144     {
01145       return true;
01146     }
01147     else 
01148     {
01149       MTX_ERROR_MSG( "MTX_FillRow returned false." );
01150       return false;
01151     }
01152   }
01153 
01154   bool Matrix::FlipColumn( const unsigned col )
01155   {
01156     if( MTX_FlipColumn( &m_Matrix, col ) )
01157     {
01158       return true;
01159     }
01160     else 
01161     {
01162       MTX_ERROR_MSG( "MTX_FlipColumn returned false." );
01163       return false;
01164     }
01165   }
01166 
01167   bool Matrix::FlipRow( const unsigned row )
01168   {
01169     if( MTX_FlipRow( &m_Matrix, row ) )
01170     {
01171       return true;
01172     }
01173     else 
01174     {
01175       MTX_ERROR_MSG( "MTX_FlipRow returned false." );
01176       return false;
01177     }
01178   }
01179 
01180   bool Matrix::Identity()
01181   {
01182     if( MTX_Identity( &m_Matrix ) )
01183     {
01184       return true;
01185     }
01186     else 
01187     {
01188       MTX_ERROR_MSG( "MTX_Identity returned false." );
01189       return false;
01190     }
01191   }
01192 
01193   bool Matrix::Identity(const unsigned dimension)
01194   {
01195     if( MTX_Malloc( &m_Matrix, dimension, dimension, true ) )
01196     {
01197       if( MTX_Identity( &m_Matrix ) )
01198       {
01199         return true;
01200       }
01201       else
01202       {
01203         MTX_ERROR_MSG( "MTX_Identity returned false." );
01204         return false;
01205       }
01206     }
01207     else
01208     {
01209       MTX_ERROR_MSG( "MTX_Malloc returned false." );
01210       return false;
01211     }
01212   }
01213 
01214   bool Matrix::Inplace_Transpose()
01215   {
01216     if( MTX_TransposeInplace( &m_Matrix ) )
01217     {
01218       return true;
01219     }
01220     else 
01221     {
01222       MTX_ERROR_MSG( "MTX_TransposeInplace returned false." );
01223       return false;
01224     }
01225   }
01226 
01227   bool Matrix::Inplace_Round( const unsigned precision )
01228   {
01229     if( MTX_Round( &m_Matrix, precision ) )
01230     {
01231       return true;
01232     }
01233     else 
01234     {
01235       MTX_ERROR_MSG( "MTX_Round returned false." );
01236       return false;
01237     }
01238   }
01239 
01240   bool Matrix::Inplace_Floor()
01241   {
01242     if( MTX_Floor( &m_Matrix ) )
01243     {
01244       return true;
01245     }
01246     else 
01247     {
01248       MTX_ERROR_MSG( "MTX_Floor returned false." );
01249       return false;
01250     }
01251   }
01252 
01253   bool Matrix::Inplace_Ceil()
01254   {
01255     if( MTX_Ceil( &m_Matrix ) )
01256     {
01257       return true;
01258     }
01259     else 
01260     {
01261       MTX_ERROR_MSG( "MTX_Ceil returned false." );
01262       return false;
01263     }
01264   }
01265 
01266   bool Matrix::Inplace_erf()
01267   {
01268     if( MTX_erf_Inplace( &m_Matrix ) )
01269     {
01270       return true;
01271     }
01272     else 
01273     {
01274       MTX_ERROR_MSG( "MTX_erf_Inplace returned false." );
01275       return false;
01276     }
01277   }
01278 
01279   bool Matrix::Inplace_erfinv()
01280   {
01281     if( MTX_erfinv_Inplace( &m_Matrix ) )
01282     {
01283       return true;
01284     }
01285     else 
01286     {
01287       MTX_ERROR_MSG( "MTX_erfinv_Inplace returned false." );
01288       return false;
01289     }
01290   }
01291 
01292   bool Matrix::Inplace_erfc()
01293   {
01294     if( MTX_erfc_Inplace( &m_Matrix ) )
01295     {
01296       return true;
01297     }
01298     else 
01299     {
01300       MTX_ERROR_MSG( "MTX_erfc_Inplace returned false." );
01301       return false;
01302     }
01303   }
01304 
01305   bool Matrix::Inplace_erfcinv()
01306   {
01307     if( MTX_erfcinv_Inplace( &m_Matrix ) )
01308     {
01309       return true;
01310     }
01311     else 
01312     {
01313       MTX_ERROR_MSG( "MTX_erfcinv_Inplace returned false." );
01314       return false;
01315     }
01316   }
01317 
01318   bool Matrix::Inplace_Fix()
01319   {
01320     if( MTX_Fix( &m_Matrix ) )
01321     {
01322       return true;
01323     }
01324     else 
01325     {
01326       MTX_ERROR_MSG( "MTX_Fix returned false." );
01327       return false;
01328     }
01329   }
01330 
01331   bool Matrix::Inplace_AddScalar( const double scalar )
01332   {
01333     if( MTX_Add_Scalar( &m_Matrix, scalar ) )
01334     {
01335       return true;
01336     }
01337     else 
01338     {
01339       MTX_ERROR_MSG( "MTX_Add_Scalar returned false." );
01340       return false;
01341     }
01342   }
01343 
01344   bool Matrix::Inplace_SubtractScalar( const double scalar )
01345   {
01346     if( MTX_Subtract_Scalar( &m_Matrix, scalar ) )
01347     {
01348       return true;
01349     }
01350     else 
01351     {
01352       MTX_ERROR_MSG( "MTX_Subtract_Scalar returned false." );
01353       return false;
01354     }
01355   }
01356 
01357   bool Matrix::Inplace_MultiplyScalar( const double scalar )
01358   {
01359     if( MTX_Multiply_Scalar( &m_Matrix, scalar ) )
01360     {
01361       return true;
01362     }
01363     else 
01364     {
01365       MTX_ERROR_MSG( "MTX_Multiply_Scalar returned false." );
01366       return false;
01367     }
01368   }
01369 
01370   bool Matrix::Inplace_DivideScalar( const double scalar )
01371   {
01372     if( MTX_Divide_Scalar( &m_Matrix, scalar ) )
01373     {
01374       return true;
01375     }
01376     else 
01377     {
01378       MTX_ERROR_MSG( "MTX_Divide_Scalar returned false." );
01379       return false;
01380     }
01381   }
01382 
01383   bool Matrix::Inplace_PowerScalar( const double scalar )
01384   {
01385     if( MTX_PowInplace( &m_Matrix, scalar, 0.0 ) ) 
01386     {
01387       return true;
01388     }
01389     else
01390     {
01391       MTX_ERROR_MSG( "MTX_PowInplace returned false." );
01392       return false;
01393     }
01394   }
01395 
01396   bool Matrix::Inplace_AddScalarComplex( const std::complex<double> cplx )
01397   {
01398     if( MTX_Add_ScalarComplex( &m_Matrix, cplx.real(), cplx.imag() ) )
01399     {
01400       return true;
01401     }
01402     else 
01403     {
01404       MTX_ERROR_MSG( "MTX_Add_ScalarComplex returned false." );
01405       return false;
01406     }
01407   }
01408 
01409   bool Matrix::Inplace_SubtractScalarComplex( const std::complex<double> cplx )
01410   {
01411     if( MTX_Subtract_ScalarComplex( &m_Matrix, cplx.real(), cplx.imag() ) )
01412     {
01413       return true;
01414     }
01415     else 
01416     {
01417       MTX_ERROR_MSG( "MTX_Subtract_ScalarComplex returned false." );
01418       return false;
01419     }
01420   }
01421 
01422   bool Matrix::Inplace_MultiplyScalarComplex( const std::complex<double> cplx )
01423   {
01424     if( MTX_Multiply_ScalarComplex( &m_Matrix, cplx.real(), cplx.imag() ) )
01425     {
01426       return true;
01427     }
01428     else 
01429     {
01430       MTX_ERROR_MSG( "MTX_Multiply_ScalarComplex returned false." );
01431       return false;
01432     }
01433   }
01434 
01435   bool Matrix::Inplace_DivideScalarComplex( const std::complex<double> cplx )
01436   {
01437     if( MTX_Divide_ScalarComplex( &m_Matrix,  cplx.real(), cplx.imag() ) )
01438     {
01439       return true;
01440     }
01441     else 
01442     {
01443       MTX_ERROR_MSG( "MTX_Divide_ScalarComplex returned false." );
01444       return false;
01445     }
01446   }
01447 
01448   bool Matrix::Inplace_PowerScalarComplex( const std::complex<double> cplx )
01449   {
01450     if( MTX_PowInplace( &m_Matrix, cplx.real(), cplx.imag() ) ) 
01451     {
01452       return true;
01453     }
01454     else
01455     {
01456       MTX_ERROR_MSG( "MTX_PowInplace returned false." );
01457       return false;
01458     }
01459   }
01460 
01461   bool Matrix::Inplace_Abs()
01462   {
01463     if( MTX_Abs( &m_Matrix ) )
01464     {
01465       return true;
01466     }
01467     else 
01468     {
01469       MTX_ERROR_MSG( "MTX_Abs returned false." );
01470       return false;
01471     }
01472   }
01473 
01474   bool Matrix::Inplace_acos()
01475   {
01476     if( MTX_acos( &m_Matrix ) )
01477     {
01478       return true;
01479     }
01480     else 
01481     {
01482       MTX_ERROR_MSG( "MTX_acos returned false." );
01483       return false;
01484     }
01485   }
01486 
01487   bool Matrix::Inplace_acosd()
01488   {
01489     if( MTX_acos( &m_Matrix ) )
01490     {
01491       if( MTX_Multiply_Scalar( &m_Matrix, RAD2DEG ) )
01492       {
01493         return true;
01494       }
01495       else
01496       {
01497         MTX_ERROR_MSG( "MTX_Multiply_Scalar returned false." );
01498         return false;
01499       }
01500     }
01501     else 
01502     {
01503       MTX_ERROR_MSG( "MTX_acos returned false." );
01504       return false;
01505     }
01506   }
01507 
01508   bool Matrix::Inplace_acosh()
01509   {
01510     if( MTX_acosh( &m_Matrix ) )
01511     {
01512       return true;
01513     }
01514     else 
01515     {
01516       MTX_ERROR_MSG( "MTX_acosh returned false." );
01517       return false;
01518     }
01519   }
01520 
01521   bool Matrix::Inplace_angle()
01522   {
01523     if( MTX_angle( &m_Matrix ) )
01524     {
01525       return true;
01526     }
01527     else
01528     {
01529       MTX_ERROR_MSG( "MTX_angle returned false." );
01530       return false;
01531     }
01532   }
01533 
01534   bool Matrix::Inplace_asin()
01535   {
01536     if( MTX_asin( &m_Matrix ) )
01537     {
01538       return true;
01539     }
01540     else 
01541     {
01542       MTX_ERROR_MSG( "MTX_asin returned false." );
01543       return false;
01544     }
01545   }
01546 
01547   bool Matrix::Inplace_asind()
01548   {
01549     if( MTX_asin( &m_Matrix ) )
01550     {
01551       if( MTX_Multiply_Scalar( &m_Matrix, RAD2DEG ) )
01552       {
01553         return true;
01554       }
01555       else
01556       {
01557         MTX_ERROR_MSG( "MTX_Multiply_Scalar returned false." );
01558         return false;
01559       }
01560     }
01561     else 
01562     {
01563       MTX_ERROR_MSG( "MTX_asin returned false." );
01564       return false;
01565     }
01566   }
01567 
01568   bool Matrix::Inplace_asinh()
01569   {
01570     if( MTX_asinh( &m_Matrix ) )
01571     {
01572       return true;
01573     }
01574     else 
01575     {
01576       MTX_ERROR_MSG( "MTX_asinh returned false." );
01577       return false;
01578     }
01579   }
01580 
01581   bool Matrix::Inplace_atan()
01582   {
01583     if( MTX_atan( &m_Matrix ) )
01584     {
01585       return true;
01586     }
01587     else
01588     {
01589       MTX_ERROR_MSG( "MTX_atan returned false." );
01590       return false;
01591     }
01592   }
01593 
01594   bool Matrix::Inplace_atand()
01595   {
01596     if( MTX_atan( &m_Matrix ) )
01597     {
01598       if( MTX_Multiply_Scalar( &m_Matrix, RAD2DEG ) )
01599       {
01600         return true;
01601       }
01602       else
01603       {
01604         MTX_ERROR_MSG( "MTX_Multiply_Scalar returned false." );
01605         return false;
01606       }
01607     }
01608     else 
01609     {
01610       MTX_ERROR_MSG( "MTX_atan returned false." );
01611       return false;
01612     }
01613   }
01614 
01615   bool Matrix::Inplace_atanh()
01616   {
01617     if( MTX_atanh( &m_Matrix ) )
01618     {
01619       return true;
01620     }
01621     else
01622     {
01623       MTX_ERROR_MSG( "MTX_atanh returned false." );
01624       return false;
01625     }
01626   }
01627 
01628   bool Matrix::Inplace_Sqr()
01629   {
01630     if( MTX_Sqr( &m_Matrix ) )
01631     {
01632       return true;
01633     }
01634     else 
01635     {
01636       MTX_ERROR_MSG( "MTX_Sqr returned false." );
01637       return false;
01638     }
01639   }
01640 
01641   bool Matrix::Inplace_Sqrt()
01642   {
01643     if( MTX_Sqrt( &m_Matrix ) )
01644     {
01645       return true;
01646     }
01647     else 
01648     {
01649       MTX_ERROR_MSG( "MTX_Sqrt returned false." );
01650       return false;
01651     }
01652   }
01653 
01654   bool Matrix::Inplace_Exp()
01655   {
01656     if( MTX_Exp( &m_Matrix ) )
01657     {
01658       return true;
01659     }
01660     else 
01661     {
01662       MTX_ERROR_MSG( "MTX_Exp returned false." );
01663       return false;
01664     }
01665   }
01666 
01667   bool Matrix::Inplace_Ln()
01668   {
01669     if( MTX_Ln( &m_Matrix ) )
01670     {
01671       return true;
01672     }
01673     else 
01674     {
01675       MTX_ERROR_MSG( "MTX_Ln returned false." );
01676       return false;
01677     }
01678   }
01679 
01680   bool Matrix::Inplace_Increment()
01681   {
01682     if( MTX_Increment( &m_Matrix ) )
01683     {
01684       return true;
01685     }
01686     else 
01687     {
01688       MTX_ERROR_MSG( "MTX_Increment returned false." );
01689       return false;
01690     }
01691   }
01692 
01693   bool Matrix::Inplace_Decrement()
01694   {
01695     if( MTX_Decrement( &m_Matrix ) )
01696     {
01697       return true;
01698     }
01699     else 
01700     {
01701       MTX_ERROR_MSG( "MTX_Decrement returned false." );
01702       return false;
01703     }
01704   }
01705 
01706   bool Matrix::Inplace_Add( const Matrix &B )
01707   {
01708     if( MTX_Add_Inplace( &m_Matrix, &B.m_Matrix ) )
01709     {
01710       return true;
01711     }
01712     else 
01713     {
01714       MTX_ERROR_MSG( "MTX_Add_Inplace returned false." );
01715       return false;
01716     }
01717   }
01718 
01719   bool Matrix::Inplace_Subtract( const Matrix &B )
01720   {
01721     if( MTX_Subtract_Inplace( &m_Matrix, &B.m_Matrix ) )
01722     {
01723       return true;
01724     }
01725     else 
01726     {
01727       MTX_ERROR_MSG( "MTX_Subtract_Inplace returned false." );
01728       return false;
01729     }
01730   }
01731 
01732   bool Matrix::Inplace_PreMultiply( const Matrix &B )
01733   {
01734     if( MTX_PreMultiply_Inplace( &m_Matrix, &B.m_Matrix ) )
01735     {
01736       return true;
01737     }
01738     else 
01739     {
01740       MTX_ERROR_MSG( "MTX_PreMultiply_Inplace returned false." );
01741       return false;
01742     }
01743   }
01744 
01745   bool Matrix::Inplace_TranposePreMultiply( const Matrix &B )
01746   {
01747     if( MTX_TransposePreMultiply_Inplace( &m_Matrix, &B.m_Matrix ) )
01748     {
01749       return true;
01750     }
01751     else 
01752     {
01753       MTX_ERROR_MSG( "MTX_TransposePreMultiply_Inplace returned false." );
01754       return false;
01755     }
01756   }
01757 
01758   bool Matrix::Inplace_PostMultiply( const Matrix &B )
01759   {
01760     if( MTX_PostMultiply_Inplace( &m_Matrix, &B.m_Matrix ) )
01761     {
01762       return true;
01763     }
01764     else 
01765     {
01766       MTX_ERROR_MSG( "MTX_PostMultiply_Inplace returned false." );
01767       return false;
01768     }
01769   }
01770 
01771   bool Matrix::Inplace_PostMultiplyTranspose( const Matrix &B )
01772   {
01773     if( MTX_PostMultiplyTranspose_Inplace( &m_Matrix, &B.m_Matrix ) )
01774     {
01775       return true;
01776     }
01777     else 
01778     {
01779       MTX_ERROR_MSG( "MTX_PostMultiplyTranspose_Inplace returned false." );
01780       return false;
01781     }
01782   }  
01783 
01784   bool Matrix::Inplace_DotMultiply( const Matrix &B )
01785   {
01786     if( MTX_DotMultiply_Inplace( &m_Matrix, &B.m_Matrix ) )
01787     {
01788       return true;
01789     }
01790     else 
01791     {
01792       MTX_ERROR_MSG( "MTX_DotMultiply_Inplace returned false." );
01793       return false;
01794     }
01795   }
01796 
01797   bool Matrix::Inplace_DotDivide( const Matrix &B )
01798   {
01799     if( MTX_DotDivide_Inplace( &m_Matrix, &B.m_Matrix ) )
01800     {
01801       return true;
01802     }
01803     else 
01804     {
01805       MTX_ERROR_MSG( "MTX_DotDivide_Inplace returned false." );
01806       return false;
01807     }
01808   }
01809 
01810   bool Matrix::Inplace_SortAscending()
01811   {
01812     if( MTX_SortAscending( &m_Matrix ) )
01813     {
01814       return true;
01815     }
01816     else 
01817     {
01818       MTX_ERROR_MSG( "MTX_SortAscending returned false." );
01819       return false;
01820     }
01821   }
01822 
01823   bool Matrix::Inplace_SortDescending()
01824   {
01825     if( MTX_SortDescending( &m_Matrix ) )
01826     {
01827       return true;
01828     }
01829     else 
01830     {
01831       MTX_ERROR_MSG( "MTX_SortDescending returned false." );
01832       return false;
01833     }
01834   }
01835 
01836   bool Matrix::Inplace_SortColumnAscending( const unsigned col )
01837   {
01838     if( MTX_SortColumnAscending( &m_Matrix, col ) )
01839     {
01840       return true;
01841     }
01842     else 
01843     {
01844       MTX_ERROR_MSG( "MTX_SortColumnAscending returned false." );
01845       return false;
01846     }
01847   }
01848 
01849   bool Matrix::Inplace_SortColumnDescending( const unsigned col )
01850   {
01851     if( MTX_SortColumnDescending( &m_Matrix, col ) )
01852     {
01853       return true;
01854     }
01855     else 
01856     {
01857       MTX_ERROR_MSG( "MTX_SortColumnDescending returned false." );
01858       return false;
01859     }
01860   }
01861 
01862   bool Matrix::Inplace_SortColumnIndexed( const unsigned col, Matrix &Index )
01863   {
01864     if( MTX_SortColumnIndexed( &m_Matrix, col, &Index.m_Matrix ) )
01865     {
01866       return true;
01867     }
01868     else 
01869     {
01870       MTX_ERROR_MSG( "MTX_SortColumnIndexed returned false." );
01871       return false;
01872     }
01873   }
01874 
01875   bool Matrix::Inplace_SortByColumn( const unsigned col )
01876   {
01877     if( MTX_SortByColumn( &m_Matrix, col ) )
01878     {
01879       return true;
01880     }
01881     else 
01882     {
01883       MTX_ERROR_MSG( "MTX_SortByColumn returned false." );
01884       return false;
01885     }
01886   }
01887 
01888   bool Matrix::Inplace_Invert()
01889   {
01890     if( MTX_InvertInPlace( &m_Matrix ) )
01891     {
01892       return true;
01893     }
01894     else 
01895     {
01896       MTX_ERROR_MSG( "MTX_InvertInPlace returned false." );
01897       return false;
01898     }
01899   }
01900 
01901   bool Matrix::Inplace_InvertRobust()
01902   {
01903     if( MTX_InvertInPlaceRobust( &m_Matrix ) )
01904     {
01905       return true;
01906     }
01907     else 
01908     {
01909       MTX_ERROR_MSG( "MTX_InvertInPlaceRobust returned false." );
01910       return false;
01911     }
01912   }
01913 
01914   bool Matrix::Inplace_LowerTriangularInverse()
01915   {
01916     if( MTX_LowerTriangularInverseInplace( &m_Matrix ) )
01917     {
01918       return true;
01919     }
01920     else 
01921     {
01922       MTX_ERROR_MSG( "MTX_LowerTriangularInverseInplace returned false." );
01923       return false;
01924     }
01925   }
01926 
01927   bool Matrix::Inplace_FFT()
01928   {
01929     if( MTX_FFT_Inplace( &m_Matrix ) )
01930     {
01931       return true;
01932     }
01933     else
01934     {
01935       MTX_ERROR_MSG( "MTX_FFT_Inplace returned false." );
01936       return false;
01937     }
01938   }
01939 
01940   bool Matrix::Inplace_FFT2()
01941   {
01942     if( MTX_FFT2_Inplace( &m_Matrix ) )
01943     {
01944       return true;
01945     }
01946     else
01947     {
01948       MTX_ERROR_MSG( "MTX_FFT2_Inplace returned false." );
01949       return false;
01950     }
01951   }
01952 
01953   bool Matrix::Inplace_IFFT()
01954   {
01955     if( MTX_IFFT_Inplace( &m_Matrix ) )
01956     {
01957       return true;
01958     }
01959     else
01960     {
01961       MTX_ERROR_MSG( "MTX_IFFT_Inplace returned false." );
01962       return false;
01963     }
01964   }
01965 
01966   bool Matrix::Inplace_IFFT2()
01967   {
01968     if( MTX_IFFT2_Inplace( &m_Matrix ) )
01969     {
01970       return true;
01971     }
01972     else
01973     {
01974       MTX_ERROR_MSG( "MTX_IFFT2_Inplace returned false." );
01975       return false;
01976     }
01977   }
01978   
01979   bool Matrix::Add( const Matrix &B, const Matrix &C )
01980   {
01981     if( MTX_Add( &m_Matrix, &B.m_Matrix, &C.m_Matrix ) )
01982     {
01983       return true;
01984     }
01985     else 
01986     {
01987       MTX_ERROR_MSG( "MTX_Add returned false." );
01988       return false;
01989     }
01990   }
01991 
01992   bool Matrix::Subtract( const Matrix &B, const Matrix &C )
01993   {
01994     if( MTX_Subtract( &m_Matrix, &B.m_Matrix, &C.m_Matrix ) )
01995     {
01996       return true;
01997     }
01998     else 
01999     {
02000       MTX_ERROR_MSG( "MTX_Subtract returned false." );
02001       return false;
02002     }
02003   }
02004 
02005   bool Matrix::Multiply( const Matrix &B, const Matrix &C )
02006   {
02007     if( MTX_Multiply( &m_Matrix, &B.m_Matrix, &C.m_Matrix ) )
02008     {
02009       return true;
02010     }
02011     else 
02012     {
02013       MTX_ERROR_MSG( "MTX_Multiply returned false." );
02014       return false;
02015     }
02016   }
02017 
02018   bool Matrix::TransposeMultiply( const Matrix &B, const Matrix &C )
02019   {
02020     if( MTX_TransposeMultiply( &m_Matrix, &B.m_Matrix, &C.m_Matrix ) )
02021     {
02022       return true;
02023     }
02024     else 
02025     {
02026       MTX_ERROR_MSG( "MTX_TranposeMultiply returned false." );
02027       return false;
02028     }
02029   }
02030 
02031   bool Matrix::MultiplyTranspose( const Matrix &B, const Matrix &C )
02032   {
02033     if( MTX_MultiplyTranspose( &m_Matrix, &B.m_Matrix, &C.m_Matrix ) )
02034     {
02035       return true;
02036     }
02037     else 
02038     {
02039       MTX_ERROR_MSG( "MTX_MultiplyTranspose returned false." );
02040       return false;
02041     }
02042   }
02043 
02044   bool Matrix::Inplace_abs()
02045   {
02046     if( MTX_Abs( &m_Matrix ) )
02047     {
02048       return true;
02049     }
02050     else
02051     {
02052       MTX_ERROR_MSG( "MTX_Abs returned false." );
02053       return false;
02054     }
02055   }
02056 
02057   bool Matrix::Inplace_colon( double start, double increment, double end )
02058   {
02059     if( MTX_Colon( &m_Matrix, start, increment, end) )
02060     {
02061       return true;
02062     }
02063     else
02064     {
02065       MTX_ERROR_MSG( "MTX_Colon returned false." );
02066       return false;
02067     }
02068   }
02069 
02070   bool Matrix::Inplace_conj()
02071   {
02072     if( MTX_Conjugate( &m_Matrix ) )
02073     {
02074       return true;
02075     }
02076     else
02077     {
02078       MTX_ERROR_MSG( "MTX_Conjugate returned false." );
02079       return false;
02080     }
02081   }
02082 
02083   bool Matrix::Inplace_cos()
02084   {
02085     if( MTX_cos( &m_Matrix ) )
02086     {
02087       return true;
02088     }
02089     else
02090     {
02091       MTX_ERROR_MSG( "MTX_cos returned false." );
02092       return false;
02093     }
02094   }
02095 
02096   bool Matrix::Inplace_cosh()
02097   {
02098     if( MTX_cosh( &m_Matrix ) )
02099     {
02100       return true;
02101     }
02102     else
02103     {
02104       MTX_ERROR_MSG( "MTX_cosh returned false." );
02105       return false;
02106     }
02107   }
02108 
02109   bool Matrix::Inplace_cot()
02110   {
02111     if( MTX_cot( &m_Matrix ) )
02112     {
02113       return true;
02114     }
02115     else
02116     {
02117       MTX_ERROR_MSG( "MTX_cot returned false." );
02118       return false;
02119     }
02120   }
02121 
02122   bool Matrix::Inplace_coth()
02123   {
02124     if( MTX_coth( &m_Matrix ) )
02125     {
02126       return true;
02127     }
02128     else
02129     {
02130       MTX_ERROR_MSG( "MTX_coth returned false." );
02131       return false;
02132     }
02133   }
02134   
02135   bool Matrix::Inplace_imag()
02136   {
02137     if( MTX_ConvertComplexToImag( &m_Matrix ) )
02138     {
02139       return true;
02140     }
02141     else
02142     {
02143       MTX_ERROR_MSG( "MTX_ConvertComplexToImag returned false." );
02144       return false;
02145     }
02146   }
02147 
02148   bool Matrix::Inplace_exp()
02149   {
02150     if( MTX_Exp( &m_Matrix ) )
02151     {
02152       return true;
02153     }
02154     else
02155     {
02156       MTX_ERROR_MSG( "MTX_Exp returned false." );
02157       return false;
02158     }
02159   }
02160 
02161   bool Matrix::Inplace_eye( const unsigned nrows, const unsigned ncols )
02162   {
02163     if( MTX_Eye( &m_Matrix, nrows, ncols ) )
02164     {
02165       return true;
02166     }
02167     else
02168     {
02169       MTX_ERROR_MSG( "MTX_Eye returned false." );
02170       return false;
02171     }
02172   }
02173 
02174   bool Matrix::Inplace_log2()
02175   {
02176     if( MTX_Ln( &m_Matrix ) )
02177     {
02178       if( MTX_Divide_Scalar( &m_Matrix, log(2.0) ) )
02179       {
02180         return true;
02181       }
02182       else
02183       {
02184         return false;
02185         MTX_ERROR_MSG( "MTX_Divide_Scalar returned false." );      
02186       }
02187     }
02188     else
02189     {
02190       MTX_ERROR_MSG( "MTX_Ln returned false." );      
02191       return false;
02192     }
02193   }
02194 
02195   bool Matrix::Inplace_log10()
02196   {
02197     if( MTX_Ln( &m_Matrix ) )
02198     {
02199       if( MTX_Divide_Scalar( &m_Matrix, log(10.0) ) )
02200       {
02201         return true;
02202       }
02203       else
02204       {
02205         MTX_ERROR_MSG( "MTX_Divide_Scalar returned false." );
02206         return false;
02207       }
02208     }
02209     else
02210     {
02211       MTX_ERROR_MSG( "MTX_Ln returned false." );
02212       return false;
02213     }
02214   }
02215 
02216 
02217   bool Matrix::Inplace_ones( const unsigned nrows, const unsigned ncols )
02218   {
02219     if( m_Matrix.nrows == nrows && m_Matrix.ncols == ncols && m_Matrix.isReal )
02220     { 
02221       if( !MTX_Fill( &m_Matrix, 1.0 ) )
02222       {
02223         MTX_ERROR_MSG( "MTX_Fill returned false." );
02224         return false;
02225       }
02226     }
02227     else
02228     {
02229       if( !MTX_Malloc( &m_Matrix, nrows, ncols, TRUE ) )
02230       {
02231         MTX_ERROR_MSG( "MTX_Malloc returned false." );
02232         return false;
02233       }
02234       if( !MTX_Fill( &m_Matrix, 1.0 ) )
02235       {
02236         MTX_ERROR_MSG( "MTX_Fill returned false." );
02237         return false;
02238       }
02239     }
02240     return true;
02241   }
02242 
02243   bool Matrix::Inplace_real()
02244   {
02245     if( MTX_ConvertComplexToReal( &m_Matrix ) )
02246     {
02247       return true;
02248     }
02249     else
02250     {
02251       MTX_ERROR_MSG( "MTX_ConvertComplexToReal returned false." );
02252       return false;
02253     }
02254   }
02255 
02256   bool Matrix::Inplace_rand( const unsigned nrows, const unsigned ncols, const unsigned seed )
02257   {
02258     if( MTX_rand( &m_Matrix, nrows, ncols, seed ) )
02259     {
02260       return true;
02261     }
02262     else
02263     {
02264       MTX_ERROR_MSG( "MTX_rand returned false." );
02265       return false;
02266     }
02267   }
02268 
02269   bool Matrix::Inplace_randn( const unsigned nrows, const unsigned ncols, const unsigned seed )
02270   {
02271     if( MTX_randn( &m_Matrix, nrows, ncols, seed ) )
02272     {
02273       return true;
02274     }
02275     else
02276     {
02277       MTX_ERROR_MSG( "MTX_randn returned false." );
02278       return false;
02279     }
02280   }
02281 
02282   bool Matrix::Inplace_sin()
02283   {
02284     if( MTX_sin( &m_Matrix ) )
02285     {
02286       return true;
02287     }
02288     else
02289     {
02290       MTX_ERROR_MSG( "MTX_sin returned false." );
02291       return false;
02292     }
02293   }
02294 
02295   bool Matrix::Inplace_sinc()
02296   {
02297     if( MTX_sinc( &m_Matrix ) )
02298     {
02299       return true;
02300     }
02301     else
02302     {
02303       MTX_ERROR_MSG( "MTX_sinc returned false." );
02304       return false;
02305     }
02306   }
02307 
02308   bool Matrix::Inplace_sinh()
02309   {
02310     if( MTX_sinh( &m_Matrix ) )
02311     {
02312       return true;
02313     }
02314     else
02315     {
02316       MTX_ERROR_MSG( "MTX_sinh returned false." );
02317       return false;
02318     }
02319   }
02320 
02321   bool Matrix::Inplace_sqrt()
02322   {
02323     if( MTX_Sqrt( &m_Matrix ) )
02324     {
02325       return true;
02326     }
02327     else
02328     {
02329       MTX_ERROR_MSG( "MTX_Sqrt returned false." );
02330       return false;
02331     }
02332   }
02333 
02334   bool Matrix::Inplace_tan()
02335   {
02336     if( MTX_tan( &m_Matrix ) )
02337     {
02338       return true;
02339     }
02340     else
02341     {
02342       MTX_ERROR_MSG( "MTX_tan returned false." );
02343       return false;
02344     }
02345   }
02346 
02347   bool Matrix::Inplace_tanh()
02348   {
02349     if( MTX_tanh( &m_Matrix ) )
02350     {
02351       return true;
02352     }
02353     else
02354     {
02355       MTX_ERROR_MSG( "MTX_tanh returned false." );
02356       return false;
02357     }
02358   }
02359 
02360   bool Matrix::Inplace_zeros( const unsigned nrows, const unsigned ncols )
02361   {
02362     if( m_Matrix.nrows == nrows && m_Matrix.ncols == ncols && m_Matrix.isReal )
02363     { 
02364       if( !MTX_Fill( &m_Matrix, 0.0 ) )
02365       {
02366         MTX_ERROR_MSG( "MTX_Fill returned false." );
02367         return false;
02368       }
02369     }
02370     else
02371     {
02372       if( !MTX_Malloc( &m_Matrix, nrows, ncols, TRUE ) )
02373       {
02374         MTX_ERROR_MSG( "MTX_Malloc returned false." );
02375         return false;
02376       }
02377       if( !MTX_Fill( &m_Matrix, 0.0 ) )
02378       {
02379         MTX_ERROR_MSG( "MTX_Fill returned false." );
02380         return false;
02381       }
02382     }
02383     return true;
02384   }
02385   
02386 
02387   bool Matrix::GetStats_MaxAbs(unsigned &row, unsigned &col, double &value )
02388   {
02389     if( MTX_MaxAbsIndex( &m_Matrix, &value, &row, &col ) )
02390     {
02391       return true;
02392     }
02393     else 
02394     {
02395       MTX_ERROR_MSG( "MTX_MaxAbsIndex returned false." );
02396       return false;
02397     }
02398   }
02399 
02400   bool Matrix::GetStats_Max(unsigned &row, unsigned &col, double &re, double &im )
02401   {
02402     if( MTX_MaxIndex( &m_Matrix, &re, &im, &row, &col ) )
02403     {
02404       return true;
02405     }
02406     else 
02407     {
02408       MTX_ERROR_MSG( "MTX_MaxIndex returned false." );
02409       return false;
02410     }
02411   }
02412 
02413   bool Matrix::GetStats_MaxVal(double &re, double &im )
02414   {
02415     if( MTX_Max( &m_Matrix, &re, &im ) )
02416     {
02417       return true;
02418     }
02419     else 
02420     {
02421       MTX_ERROR_MSG( "MTX_Max returned false." );
02422       return false;
02423     }
02424   }
02425 
02426   bool Matrix::GetStats_MaxAbsCol(const unsigned col, double &value, unsigned &row )
02427   {
02428     if( MTX_MaxAbsColIndex( &m_Matrix, col, &value, &row ) )
02429     {
02430       return true;
02431     }
02432     else 
02433     {
02434       MTX_ERROR_MSG( "MTX_MaxAbsColIndex returned false." );
02435       return false;
02436     }
02437   }
02438 
02439   bool Matrix::GetStats_MaxCol(const unsigned col, double &re, double &im, unsigned &row )
02440   {
02441     if( MTX_MaxColIndex( &m_Matrix, col, &re, &im, &row ) )
02442     {
02443       return true;
02444     }
02445     else 
02446     {
02447       MTX_ERROR_MSG( "MTX_MaxColIndex returned false." );
02448       return false;
02449     }
02450   }
02451 
02452   bool Matrix::GetStats_MaxColVal(const unsigned col, double &re, double &im )
02453   {
02454     if( MTX_MaxColumn( &m_Matrix, col, &re, &im ) )
02455     {
02456       return true;
02457     }
02458     else 
02459     {
02460       MTX_ERROR_MSG( "MTX_MaxColumn returned false." );
02461       return false;
02462     }
02463   }
02464 
02465   bool Matrix::GetStats_MaxAbsRow(const unsigned row, double &value, unsigned &col )
02466   {
02467     if( MTX_MaxAbsRowIndex( &m_Matrix, row, &value, &col ) )
02468     {
02469       return true;
02470     }
02471     else 
02472     {
02473       MTX_ERROR_MSG( "MTX_MaxAbsRowIndex returned false." );
02474       return false;
02475     }
02476   }
02477 
02478   bool Matrix::GetStats_MaxRow(const unsigned row, double &re, double &im, unsigned &col )
02479   {
02480     if( MTX_MaxRowIndex( &m_Matrix, row, &re, &im, &col ) )
02481     {
02482       return true;
02483     }
02484     else 
02485     {
02486       MTX_ERROR_MSG( "MTX_MaxRowIndex returned false." );
02487       return false;
02488     }
02489   }
02490 
02491   bool Matrix::GetStats_MaxRowVal(const unsigned row, double &re, double &im )
02492   {
02493     if( MTX_MaxRow( &m_Matrix, row, &re, &im ) )
02494     {
02495       return true;
02496     }
02497     else 
02498     {
02499       MTX_ERROR_MSG( "MTX_MaxRow returned false." );
02500       return false;
02501     }
02502   }
02503 
02504   bool Matrix::GetStats_MinAbs(unsigned &row, unsigned &col, double &value )
02505   {
02506     if( MTX_MinAbsIndex( &m_Matrix, &value, &row, &col ) )
02507     {
02508       return true;
02509     }
02510     else 
02511     {
02512       MTX_ERROR_MSG( "MTX_MinAbsIndex returned false." );
02513       return false;
02514     }
02515   }
02516 
02517   bool Matrix::GetStats_Min(unsigned &row, unsigned &col, double &re, double &im )
02518   {
02519     if( MTX_MinIndex( &m_Matrix, &re, &im, &row, &col ) )
02520     {
02521       return true;
02522     }
02523     else 
02524     {
02525       MTX_ERROR_MSG( "MTX_MinIndex returned false." );
02526       return false;
02527     }
02528   }
02529 
02530   bool Matrix::GetStats_MinVal(double &re, double &im )
02531   {
02532     if( MTX_Min( &m_Matrix, &re, &im ) )
02533     {
02534       return true;
02535     }
02536     else 
02537     {
02538       MTX_ERROR_MSG( "MTX_Min returned false." );
02539       return false;
02540     }
02541   }
02542 
02543   bool Matrix::GetStats_MinAbsCol(const unsigned col, double &value, unsigned &row )
02544   {
02545     if( MTX_MinAbsColIndex( &m_Matrix, col, &value, &row ) )
02546     {
02547       return true;
02548     }
02549     else 
02550     {
02551       MTX_ERROR_MSG( "MTX_MinAbsColIndex returned false." );
02552       return false;
02553     }
02554   }
02555 
02556   bool Matrix::GetStats_MinCol(const unsigned col, double &re, double &im, unsigned &row )
02557   {
02558     if( MTX_MinColIndex( &m_Matrix, col, &re, &im, &row ) )
02559     {
02560       return true;
02561     }
02562     else 
02563     {
02564       MTX_ERROR_MSG( "MTX_MinColIndex returned false." );
02565       return false;
02566     }
02567   }
02568 
02569 
02570   bool Matrix::GetStats_MinColVal(const unsigned col, double &re, double &im )
02571   {
02572     if( MTX_MinColumn( &m_Matrix, col, &re, &im ) )
02573     {
02574       return true;
02575     }
02576     else 
02577     {
02578       MTX_ERROR_MSG( "MTX_MinColumn returned false." );
02579       return false;
02580     }
02581   }
02582 
02583   bool Matrix::GetStats_MinAbsRow(const unsigned row, double &value, unsigned &col )
02584   {
02585     if( MTX_MinAbsRowIndex( &m_Matrix, row, &value, &col ) )
02586     {
02587       return true;
02588     }
02589     else 
02590     {
02591       MTX_ERROR_MSG( "MTX_MinAbsRowIndex returned false." );
02592       return false;
02593     }
02594   }
02595 
02596   bool Matrix::GetStats_MinRow(const unsigned row, double &re, double &im, unsigned &col )
02597   {
02598     if( MTX_MinRowIndex( &m_Matrix, row, &re, &im, &col ) )
02599     {
02600       return true;
02601     }
02602     else 
02603     {
02604       MTX_ERROR_MSG( "MTX_MinRowIndex returned false." );
02605       return false;
02606     }
02607   }
02608 
02609   bool Matrix::GetStats_MinRowVal(const unsigned row, double &re, double &im )
02610   {
02611     if( MTX_MinRow(  &m_Matrix, row, &re, &im ) )
02612     {
02613       return true;
02614     }
02615     else 
02616     {
02617       MTX_ERROR_MSG( "MTX_MinRow returned false." );
02618       return false;
02619     }
02620   }
02621 
02622   bool Matrix::GetStats_ColRange( const unsigned col, double &re, double &im )
02623   {
02624     if( MTX_ColumnRange( &m_Matrix, col, &re, &im ) )
02625     {
02626       return true;
02627     }
02628     else 
02629     {
02630       MTX_ERROR_MSG( "MTX_ColumnRange returned false." );
02631       return false;
02632     }
02633   }
02634 
02635   bool Matrix::GetStats_RowRange( const unsigned row, double &re, double &im )
02636   {
02637     if( MTX_RowRange( &m_Matrix, row, &re, &im ) )
02638     {
02639       return true;
02640     }
02641     else 
02642     {
02643       MTX_ERROR_MSG( "MTX_RowRange returned false." );
02644       return false;
02645     }
02646   }
02647 
02648   bool Matrix::GetStats_Range( double &re, double &im )
02649   {
02650     if( MTX_Range( &m_Matrix, &re, &im ) )
02651     {
02652       return true;
02653     }
02654     else 
02655     {
02656       MTX_ERROR_MSG( "MTX_Range returned false." );
02657       return false;
02658     }
02659   }
02660 
02661   bool Matrix::GetStats_ColumnSum( const unsigned col, double &re, double &im )
02662   {
02663     if( MTX_ColumnSum( &m_Matrix, col, &re, &im ) )
02664     {
02665       return true;
02666     }
02667     else 
02668     {
02669       MTX_ERROR_MSG( "MTX_ColumnSum returned false." );
02670       return false;
02671     }
02672   }
02673 
02674   bool Matrix::GetStats_RowSum( const unsigned row, double &re, double &im )
02675   {
02676     if( MTX_RowSum( &m_Matrix, row, &re, &im ) )
02677     {
02678       return true;
02679     }
02680     else 
02681     {
02682       MTX_ERROR_MSG( "MTX_RowSum returned false." );
02683       return false;
02684     }
02685   }
02686 
02687   bool Matrix::GetStats_Sum( double &re, double &im )
02688   {
02689     if( MTX_Sum( &m_Matrix, &re, &im ) )
02690     {
02691       return true;
02692     }
02693     else 
02694     {
02695       MTX_ERROR_MSG( "MTX_Sum returned false." );
02696       return false;
02697     }
02698   }
02699 
02700   bool Matrix::GetStats_ColumnMean( const unsigned col, double &re, double &im )
02701   {
02702     if( MTX_ColumnMean( &m_Matrix, col, &re, &im ) )
02703     {
02704       return true;
02705     }
02706     else 
02707     {
02708       MTX_ERROR_MSG( "MTX_ColumnMean returned false." );
02709       return false;
02710     }
02711   }
02712 
02713   bool Matrix::GetStats_RowMean( const unsigned row, double &re, double &im )
02714   {
02715     if( MTX_RowMean( &m_Matrix, row, &re, &im ) )
02716     {
02717       return true;
02718     }
02719     else 
02720     {
02721       MTX_ERROR_MSG( "MTX_RowMean returned false." );
02722       return false;
02723     }
02724   }
02725 
02726   bool Matrix::GetStats_Mean( double &re, double &im )
02727   {
02728     if( MTX_Mean( &m_Matrix, &re, &im ) )
02729     {
02730       return true;
02731     }
02732     else 
02733     {
02734       MTX_ERROR_MSG( "MTX_Mean returned false." );
02735       return false;
02736     }
02737   }
02738 
02739   bool Matrix::GetStats_ColumnStdev( const unsigned col, double &value )
02740   {
02741     if( MTX_ColumnStdev( &m_Matrix, col, &value ) )
02742     {
02743       return true;
02744     }
02745     else 
02746     {
02747       MTX_ERROR_MSG( "MTX_ColumnStdev returned false." );
02748       return false;
02749     }
02750   }
02751 
02752   bool Matrix::GetStats_RowStdev( const unsigned row, double &value )
02753   {
02754     if( MTX_RowStdev( &m_Matrix, row, &value ) )
02755     {
02756       return true;
02757     }
02758     else 
02759     {
02760       MTX_ERROR_MSG( "MTX_RowStdev returned false." );
02761       return false;
02762     }
02763   }
02764 
02765   bool Matrix::GetStats_Stdev( double &value )
02766   {
02767     if( MTX_Stdev( &m_Matrix, &value ) )
02768     {
02769       return true;
02770     }
02771     else 
02772     {
02773       MTX_ERROR_MSG( "MTX_Stdev returned false." );
02774       return false;
02775     }
02776   }
02777 
02778   bool Matrix::GetStats_ColumnVar( const unsigned col, double &value )
02779   {
02780     if( MTX_ColumnVar( &m_Matrix, col, &value ) )
02781     {
02782       return true;
02783     }
02784     else 
02785     {
02786       MTX_ERROR_MSG( "MTX_ColumnVar returned false." );
02787       return false;
02788     }
02789   }
02790 
02791   bool Matrix::GetStats_RowVar( const unsigned row, double &value )
02792   {
02793     if( MTX_RowVar( &m_Matrix, row, &value ) )
02794     {
02795       return true;
02796     }
02797     else 
02798     {
02799       MTX_ERROR_MSG( "MTX_RowVar returned false." );
02800       return false;
02801     }
02802   }
02803 
02804   bool Matrix::GetStats_Var( double &value )
02805   {
02806     if( MTX_Var( &m_Matrix, &value ) )
02807     {
02808       return true;
02809     }
02810     else 
02811     {
02812       MTX_ERROR_MSG( "MTX_Var returned false." );
02813       return false;
02814     }
02815   }
02816 
02817   bool Matrix::GetStats_ColumnNorm( const unsigned col, double &value )
02818   {
02819     if( MTX_ColumnNorm( &m_Matrix, col, &value ) )
02820     {
02821       return true;
02822     }
02823     else 
02824     {
02825       MTX_ERROR_MSG( "MTX_ColumnNorm returned false." );
02826       return false;
02827     }
02828   }
02829 
02830   bool Matrix::GetStats_RowNorm( const unsigned row, double &value )
02831   {
02832     if( MTX_RowNorm( &m_Matrix, row, &value ) )
02833     {
02834       return true;
02835     }
02836     else 
02837     {
02838       MTX_ERROR_MSG( "MTX_RowNorm returned false." );
02839       return false;
02840     }
02841   }
02842 
02843   bool Matrix::GetStats_Norm( double &value )
02844   {
02845     if( MTX_Norm( &m_Matrix, &value ) )
02846     {
02847       return true;
02848     }
02849     else 
02850     {
02851       MTX_ERROR_MSG( "MTX_Norm returned false." );
02852       return false;
02853     }
02854   }
02855 
02856   bool Matrix::GetStats_ColumnRMS( const unsigned col, double &value )
02857   {
02858     if( MTX_ColumnRMS( &m_Matrix, col, &value ) )
02859     {
02860       return true;
02861     }
02862     else 
02863     {
02864       MTX_ERROR_MSG( "MTX_ColumnRMS returned false." );
02865       return false;
02866     }
02867   }
02868 
02869   bool Matrix::GetStats_RowRMS( const unsigned row, double &value )
02870   {
02871     if( MTX_RowRMS( &m_Matrix, row, &value ) )
02872     {
02873       return true;
02874     }
02875     else 
02876     {
02877       MTX_ERROR_MSG( "MTX_RowRMS returned false." );
02878       return false;
02879     }
02880   }
02881 
02882   bool Matrix::GetStats_RMS( double &value )
02883   {
02884     if( MTX_RMS( &m_Matrix, &value ) )
02885     {
02886       return true;
02887     }
02888     else 
02889     {
02890       MTX_ERROR_MSG( "MTX_RMS returned false." );
02891       return false;
02892     }
02893   }
02894 
02895   bool Matrix::GetStats_ColumnSkewness( const unsigned col, double &re, double &im )
02896   {
02897     if( MTX_ColumnSkewness( &m_Matrix, col, &re, &im ) )
02898     {
02899       return true;
02900     }
02901     else 
02902     {
02903       MTX_ERROR_MSG( "MTX_ColumnSkewness returned false." );
02904       return false;
02905     }
02906   }
02907 
02908   bool Matrix::GetStats_RowSkewness( const unsigned row, double &re, double &im )
02909   {
02910     if( MTX_RowSkewness( &m_Matrix, row, &re, &im ) )
02911     {
02912       return true;
02913     }
02914     else 
02915     {
02916       MTX_ERROR_MSG( "MTX_RowSkewness returned false." );
02917       return false;
02918     }
02919   }
02920 
02921   bool Matrix::GetStats_Skewness( double &re, double &im )
02922   {
02923     if( MTX_Skewness( &m_Matrix, &re, &im ) )
02924     {
02925       return true;
02926     }
02927     else 
02928     {
02929       MTX_ERROR_MSG( "MTX_Skewness returned false." );
02930       return false;
02931     }
02932   }
02933 
02934   bool Matrix::GetStats_ColumnKurtosis( const unsigned col, double &re, double &im )
02935   {
02936     if( MTX_ColumnKurtosis( &m_Matrix, col, &re, &im ) )
02937     {
02938       return true;
02939     }
02940     else 
02941     {
02942       MTX_ERROR_MSG( "MTX_ColumnKurtosis returned false." );
02943       return false;
02944     }
02945   }
02946 
02947   bool Matrix::GetStats_RowKurtosis( const unsigned row, double &re, double &im )
02948   {
02949     if( MTX_RowKurtosis( &m_Matrix, row, &re, &im ) )
02950     {
02951       return true;
02952     }
02953     else 
02954     {
02955       MTX_ERROR_MSG( "MTX_RowKurtosis returned false." );
02956       return false;
02957     }
02958   }
02959 
02960   bool Matrix::GetStats_Kurtosis( double &re, double &im )
02961   {
02962     if( MTX_Kurtosis( &m_Matrix, &re, &im ) )
02963     {
02964       return true;
02965     }
02966     else 
02967     {
02968       MTX_ERROR_MSG( "MTX_Kurtosis returned false." );
02969       return false;
02970     }
02971   }
02972 
02973   bool Matrix::GetTrace( double &re, double &im )
02974   {
02975     if( MTX_Trace( &m_Matrix, &re, &im ) )
02976     {
02977       return true;
02978     }
02979     else 
02980     {
02981       MTX_ERROR_MSG( "MTX_Trace returned false." );
02982       return false;
02983     }
02984   }
02985 
02986   bool Matrix::GetDeterminant( double &re, double &im )
02987   {
02988     if( MTX_Det( &m_Matrix, &re, &im ) )
02989     {
02990       return true;
02991     }
02992     else 
02993     {
02994       MTX_ERROR_MSG( "MTX_Det returned false." );
02995       return false;
02996     }
02997   }
02998 
02999   bool Matrix::GetDiagonal( Matrix& DiagonalVector )
03000   {
03001     if( MTX_Diagonal( &m_Matrix, &DiagonalVector.m_Matrix ) )
03002     {
03003       return true;
03004     }
03005     else 
03006     {
03007       MTX_ERROR_MSG( "MTX_Diagonal returned false." );
03008       return false;
03009     }
03010   }
03011 
03012   bool Matrix::GetColumnMovAvg( const unsigned col, const unsigned lead, const unsigned lag, Matrix &MovAvg )
03013   {
03014     if( MTX_ColumnMovAvg( &m_Matrix, col, lead, lag, &MovAvg.m_Matrix ) )
03015     {
03016       return true;
03017     }
03018     else 
03019     {
03020       MTX_ERROR_MSG( "MTX_ColumnMovAvg returned false." );
03021       return false;
03022     }
03023   }
03024 
03025   bool Matrix::GetMovAvg( const unsigned lead, const unsigned lag, Matrix &MovAvg )
03026   {
03027     if( MTX_MovAvg( &m_Matrix, lead, lag, &MovAvg.m_Matrix ) )
03028     {
03029       return true;
03030     }
03031     else 
03032     {
03033       MTX_ERROR_MSG( "MTX_MovAvg returned false." );
03034       return false;
03035     }
03036   }
03037 
03038   bool Matrix::GetATAInverse( Matrix &InvATA )
03039   {
03040     if( MTX_ATAInverse( &m_Matrix, &InvATA.m_Matrix ) )
03041     {
03042       return true;
03043     }
03044     else 
03045     {
03046       MTX_ERROR_MSG( "MTX_ATAInverse returned false." );
03047       return false;
03048     }
03049   }
03050 
03051   bool Matrix::GetLUFactorization( bool &isFullRank, Matrix &P, Matrix &L, Matrix &U )
03052   {
03053     BOOL b_isFullRank;
03054     if( MTX_LUFactorization( &m_Matrix, &b_isFullRank, &P.m_Matrix, &L.m_Matrix, &U.m_Matrix ) )
03055     {
03056       if( b_isFullRank )
03057         isFullRank = true;
03058       else
03059         isFullRank = false;
03060 
03061       return true;
03062     }
03063     else 
03064     {
03065       if( b_isFullRank )
03066         isFullRank = true;
03067       else
03068         isFullRank = false;
03069 
03070       MTX_ERROR_MSG( "MTX_LUFactorization returned false." );
03071       return false;
03072     }
03073   }
03074 
03075   bool Matrix::GetLDLt( 
03076     Matrix& L,   //!< A unit lower triangular matrix.
03077     Matrix& d,   //!< The diagonal vector from the diagonal of the D matrix.
03078     bool checkSymmetric //!< Enforce a symmetry check. Runs faster if disabled.
03079     )
03080   {
03081     if( MTX_LDLt( &m_Matrix, &L.m_Matrix, &d.m_Matrix, checkSymmetric ) )
03082     {
03083       return true;
03084     }
03085     else
03086     {
03087       MTX_ERROR_MSG( "MTX_LDLt returned false." );
03088       return false;
03089     }
03090   }
03091 
03092   bool Matrix::GetUDUt( 
03093     Matrix& U,  //!< A unit upper triangular matrix.
03094     Matrix& d,  //!< The diagonal vector from the diagonal of the D matrix.
03095     bool checkSymmetric //!< Enforce a symmetry check. Runs faster if disabled.
03096     )
03097   {
03098     if( MTX_UDUt( &m_Matrix, &U.m_Matrix, &d.m_Matrix, checkSymmetric ) )
03099     {
03100       return true;
03101     }
03102     else
03103     {
03104       MTX_ERROR_MSG( "MTX_UDUt returned false." );
03105       return false;
03106     }
03107   }
03108 
03109   bool Matrix::GetIndexedValues( Matrix& RowIndex, Matrix& ColIndex, Matrix& Result )
03110   {
03111     Matrix _rowIndex; // a copy if needed
03112     Matrix _colIndex; // a copy if needed
03113     if( !RowIndex.m_Matrix.isReal )
03114     {
03115       if( !MTX_Real( &RowIndex.m_Matrix, &_rowIndex.m_Matrix ) )
03116       {
03117         MTX_ERROR_MSG( "MTX_Real returned false." );
03118         return false;
03119       }
03120     }
03121     if( !ColIndex.m_Matrix.isReal )
03122     {
03123       if( !MTX_Real( &ColIndex.m_Matrix, &_colIndex.m_Matrix ) )
03124       {
03125         MTX_ERROR_MSG( "MTX_Real returned false." );
03126         return false;
03127       }
03128     }
03129 
03130     if( !_rowIndex.isEmpty() )
03131     {
03132       if( !_colIndex.isEmpty() )
03133       {
03134         if( MTX_IndexedValues( &m_Matrix, &_rowIndex.m_Matrix, &_colIndex.m_Matrix, &Result.m_Matrix ) )
03135         {
03136           return true;
03137         }
03138         else
03139         {
03140           MTX_ERROR_MSG( "MTX_IndexedValues returned false." );
03141           return false;
03142         }
03143       }
03144       else
03145       {
03146         if( MTX_IndexedValues( &m_Matrix, &_rowIndex.m_Matrix, &ColIndex.m_Matrix, &Result.m_Matrix ) )
03147         {
03148           return true;
03149         }
03150         else
03151         {
03152           MTX_ERROR_MSG( "MTX_IndexedValues returned false." );
03153           return false;
03154         }
03155       }
03156     }
03157     else
03158     {
03159       if( !_colIndex.isEmpty() )
03160       {
03161         if( MTX_IndexedValues( &m_Matrix, &RowIndex.m_Matrix, &_colIndex.m_Matrix, &Result.m_Matrix ) )
03162         {
03163           return true;
03164         }
03165         else
03166         {
03167           MTX_ERROR_MSG( "MTX_IndexedValues returned false." );
03168           return false;
03169         }
03170       }
03171       else
03172       {
03173         if( MTX_IndexedValues( &m_Matrix, &RowIndex.m_Matrix, &ColIndex.m_Matrix, &Result.m_Matrix ) )
03174         {
03175           return true;
03176         }
03177         else
03178         {
03179           MTX_ERROR_MSG( "MTX_IndexedValues returned false." );
03180           return false;
03181         }
03182       }
03183     }    
03184   }
03185 
03186 
03187   bool Matrix::SetIndexedValues( Matrix& RowIndex, Matrix& ColIndex, Matrix& SourceData )
03188   {
03189     Matrix _rowIndex; // a copy if needed
03190     Matrix _colIndex; // a copy if needed
03191     if( !RowIndex.m_Matrix.isReal )
03192     {
03193       if( !MTX_Real( &RowIndex.m_Matrix, &_rowIndex.m_Matrix ) )
03194       {
03195         MTX_ERROR_MSG( "MTX_Real returned false." );
03196         return false;
03197       }
03198     }
03199     if( !ColIndex.m_Matrix.isReal )
03200     {
03201       if( !MTX_Real( &ColIndex.m_Matrix, &_colIndex.m_Matrix ) )
03202       {
03203         MTX_ERROR_MSG( "MTX_Real returned false." );
03204         return false;
03205       }
03206     }
03207 
03208     if( !_rowIndex.isEmpty() )
03209     {
03210       if( !_colIndex.isEmpty() )
03211       {
03212         if( MTX_SetIndexedValues( &m_Matrix, &_rowIndex.m_Matrix, &_colIndex.m_Matrix, &SourceData.m_Matrix ) )
03213         {
03214           return true;
03215         }
03216         else
03217         {
03218           MTX_ERROR_MSG( "MTX_SetIndexedValues returned false." );
03219           return false;
03220         }
03221       }
03222       else
03223       {
03224         if( MTX_SetIndexedValues( &m_Matrix, &_rowIndex.m_Matrix, &ColIndex.m_Matrix, &SourceData.m_Matrix ) )
03225         {
03226           return true;
03227         }
03228         else
03229         {
03230           MTX_ERROR_MSG( "MTX_SetIndexedValues returned false." );
03231           return false;
03232         }
03233       }
03234     }
03235     else
03236     {
03237       if( !_colIndex.isEmpty() )
03238       {
03239         if( MTX_SetIndexedValues( &m_Matrix, &RowIndex.m_Matrix, &_colIndex.m_Matrix, &SourceData.m_Matrix ) )
03240         {
03241           return true;
03242         }
03243         else
03244         {
03245           MTX_ERROR_MSG( "MTX_SetIndexedValues returned false." );
03246           return false;
03247         }
03248       }
03249       else
03250       {
03251         if( MTX_SetIndexedValues( &m_Matrix, &RowIndex.m_Matrix, &ColIndex.m_Matrix, &SourceData.m_Matrix ) )
03252         {
03253           return true;
03254         }
03255         else
03256         {
03257           MTX_ERROR_MSG( "MTX_SetIndexedValues returned false." );
03258           return false;
03259         }
03260       }
03261     }    
03262   }
03263 
03264   bool Matrix::Find_EqualTo( 
03265     Matrix &IndexVector,    //!< Store the indexed values in this vector (nx1)
03266     const unsigned col,     //!< Search this column (zero-based index).
03267     const double value,     //!< Search for this value.
03268     const double tolerance  //!< Search with this tolerance.
03269     )
03270   {
03271     if( MTX_find_column_values_equalto( &m_Matrix, col, &IndexVector.m_Matrix, value, 0.0, tolerance ) )
03272     {
03273       return true;
03274     }
03275     else
03276     {
03277       MTX_ERROR_MSG( "MTX_find_column_values_equalto() returned FALSE." );
03278       return false;
03279     }
03280   }
03281 
03282   bool Matrix::Find_EqualTo( 
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_re,          //!< Search for this complex value (re+i*im).
03286     const double value_im,          //!< Search for this complex value (re+i*im).
03287     const double tolerance          //!< Search with this tolerance.
03288     )
03289   {
03290     if( MTX_find_column_values_equalto( &m_Matrix, col, &IndexVector.m_Matrix, value_re, value_im, tolerance ) )
03291     {
03292       return true;
03293     }
03294     else
03295     {
03296       MTX_ERROR_MSG( "MTX_find_column_values_equalto() returned FALSE." );
03297       return false;
03298     }
03299   }
03300 
03301 
03302   bool Matrix::Find_NotEqualTo( 
03303     Matrix &IndexVector,    //!< Store the indexed values in this vector (nx1)
03304     const unsigned col,     //!< Search this column (zero-based index).
03305     const double value,     //!< Search for this value.
03306     const double tolerance  //!< Search with this tolerance.
03307     )
03308   {
03309     if( MTX_find_column_values_not_equalto( &m_Matrix, col, &IndexVector.m_Matrix, value, 0.0, tolerance ) )
03310     {
03311       return true;
03312     }
03313     else
03314     {
03315       MTX_ERROR_MSG( "MTX_find_column_values_not_equalto() returned FALSE." );
03316       return false;
03317     }
03318   }
03319 
03320   bool Matrix::Find_NotEqualTo( 
03321     Matrix &IndexVector,    //!< Store the indexed values in this vector (nx1)
03322     const unsigned col,     //!< Search this column (zero-based index).
03323     const double value_re,  //!< Search for this complex value (re+i*im).
03324     const double value_im,  //!< Search for this complex value (re+i*im).
03325     const double tolerance  //!< Search with this tolerance. No default parameter so there is no function overload confusion.
03326     )
03327   {
03328     if( MTX_find_column_values_not_equalto( &m_Matrix, col, &IndexVector.m_Matrix, value_re, value_im, tolerance ) )
03329     {
03330       return true;
03331     }
03332     else
03333     {
03334       MTX_ERROR_MSG( "MTX_find_column_values_not_equalto() returned FALSE." );
03335       return false;
03336     }
03337   }
03338 
03339 
03340   bool Matrix::Find_LessThan( 
03341     Matrix &IndexVector, //!< Store the indexed values in this vector (nx1)
03342     const unsigned col,  //!< Search this column (zero-based index).
03343     const double value   //!< Search for this value.
03344     )   
03345   {
03346     if( MTX_find_column_values_less_than( &m_Matrix, col, &IndexVector.m_Matrix, value ) )
03347     {
03348       return true;
03349     }
03350     else
03351     {
03352       MTX_ERROR_MSG( "MTX_find_column_values_less_than() returned FALSE." );
03353       return false;
03354     }
03355   }
03356 
03357 
03358   bool Matrix::Find_MoreThan( 
03359     Matrix &IndexVector, //!< Store the indexed values in this vector (nx1)
03360     const unsigned col,  //!< Search this column (zero-based index).
03361     const double value   //!< Search for this value.
03362     )   
03363   {
03364     if( MTX_find_column_values_more_than( &m_Matrix, col, &IndexVector.m_Matrix, value ) )
03365     {
03366       return true;
03367     }
03368     else
03369     {
03370       MTX_ERROR_MSG( "MTX_find_column_values_more_than() returned FALSE." );
03371       return false;
03372     }
03373   }
03374 
03375 
03376 
03377   std::string Matrix::GetMatrixComment()
03378   {
03379     std::string result;
03380     if( m_Matrix.comment != NULL )
03381       result = m_Matrix.comment;
03382     
03383     return result;
03384   }
03385 
03386 
03387   bool Matrix::TimeWindow( 
03388     const unsigned timeColumn, //!< The column containing time.
03389     const double startTime,    //!< The specified start time (inclusive).
03390     const double duration,     //!< The duration to include.
03391     const double rolloverTime  //!< The potential time at which system time rolls over.
03392     )
03393   {
03394     if( MTX_TimeWindow(
03395       &m_Matrix, 
03396       timeColumn, 
03397       startTime,
03398       duration,
03399       rolloverTime ) )
03400     {
03401       return true;
03402     }
03403     else 
03404     {
03405       MTX_ERROR_MSG( "MTX_TimeWindow returned false." );
03406       return false;
03407     }
03408   }
03409 
03410   bool Matrix::TimeLimit( 
03411     const unsigned timeColumn, //!< The column containing time
03412     const double startTime,    //!< The specified start time (inclusive)
03413     const double endTime       //!< The duration to include
03414     )
03415   {
03416     if( MTX_TimeLimit(
03417       &m_Matrix,
03418       timeColumn,
03419       startTime,
03420       endTime ) )
03421     {
03422       return true;
03423     }
03424     else 
03425     {
03426       MTX_ERROR_MSG( "MTX_TimeLimit returned false." );
03427       return false;
03428     }
03429   }
03430 
03431   bool Matrix::TimeMatch( 
03432     Matrix &A,                   //!< The matrix with interpolation times
03433     const unsigned timeColumnA,  //!< The zero based column index for matrix A
03434     Matrix &B,                   //!< The matrix to be interpolated
03435     const unsigned timeColumnB,  //!< The zero based column index for matrix B
03436     const unsigned precision,    //!< The rounding precision used for time matching, 0 = whole, 1 = 0.1, 2 = 0.01, etc
03437     const double rolloverTime    //!< The rollover time, e.g. 60 s for minute based timing, 0.0 means rollovers not allowed
03438     )
03439   {
03440     // check that the mtx engine is initialized
03441     if( !m_IsMTXInitialized )
03442     {
03443       if( !MTX_Initialize_MTXEngine() )
03444       {
03445         m_IsMTXInitialized = false;
03446         A.Clear();
03447         B.Clear();
03448         StaticMatrixError( "Matrix", "Failed to initialize the MTX Engine." );
03449       }
03450       else
03451       {
03452         m_IsMTXInitialized = true;
03453       }
03454     }
03455 
03456     if( MTX_TimeMatch(
03457       &A.m_Matrix,
03458       timeColumnA,
03459       &B.m_Matrix,
03460       timeColumnB,
03461       precision,
03462       rolloverTime ) )
03463     {
03464       return true;
03465     }
03466     else 
03467     {
03468       MTX_ERROR_MSG( "MTX_TimeMatch returned false." );
03469       return false;
03470     }
03471   }
03472 
03473   bool Matrix::Interpolate( 
03474     Matrix &A,                    //!< The matrix with interpolation times
03475     const unsigned timeColumnA,   //!< The zero based column index for matrix A
03476     Matrix &B,                    //!< The matrix to be interpolated
03477     const unsigned timeColumnB,   //!< The zero based column index for matrix B
03478     const double maxInterpolationInterval, //!< The largest interpolation interval allowed
03479     const double rolloverTime     //!< The rollover time, e.g. 60 s for minute based timing, 0.0 means rollovers not allowed
03480     )
03481   {
03482     // check that the mtx engine is initialized
03483     if( !m_IsMTXInitialized )
03484     {
03485       if( !MTX_Initialize_MTXEngine() )
03486       {
03487         m_IsMTXInitialized = false;
03488         A.Clear();
03489         B.Clear();
03490         StaticMatrixError( "Matrix", "Failed to initialize the MTX Engine." );
03491       }
03492       else
03493       {
03494         m_IsMTXInitialized = true;
03495       }
03496     }
03497 
03498     if( MTX_Interpolate(
03499       &A.m_Matrix,
03500       timeColumnA,
03501       &B.m_Matrix,
03502       timeColumnB,
03503       maxInterpolationInterval,
03504       rolloverTime ) )
03505     {
03506       return true;
03507     }
03508     else 
03509     {
03510       MTX_ERROR_MSG( "MTX_Interpolate returned false." );
03511       return false;
03512     }
03513   }
03514 
03515   // Return the column matrix specified by the column index. Returns (nrows x 1).
03516   Matrix  Matrix::Column(const unsigned col)
03517   {
03518     Matrix A;
03519     if( !MTX_CopyColumn( &m_Matrix, col, &A.m_Matrix ) )
03520     {
03521       MTX_ERROR_MSG( "MTX_CopyColumn returned false." );
03522       MatrixError( "Column", "Unable to copy the source matrix column." );
03523     }
03524     return A;
03525   }
03526 
03527   // Return the row matrix specified by the column index. Returns (ncols x 1).
03528   Matrix  Matrix::Row(const unsigned row)
03529   {
03530     Matrix A;
03531     if( !MTX_CopyRow(&m_Matrix, row, &A.m_Matrix ) )
03532     {
03533       MatrixError( "Column", "Unable to copy the source matrix column." );
03534     }
03535     return A;
03536   }
03537 
03538   // Return the tranpose of the matrix.
03539   Matrix  Matrix::Transpose()
03540   {
03541     Matrix A;
03542     if( !MTX_Transpose( &m_Matrix, &A.m_Matrix ) )
03543     {
03544       MatrixError( "Column", "Unable to transpose the source matrix." );
03545     }
03546     return A;
03547   }
03548 
03549   // Return the tranpose of the matrix.
03550   Matrix  Matrix::T()
03551   {
03552     return Transpose();
03553   }
03554 
03555   // Return the diagonal of the matrix as a vector.
03556   Matrix  Matrix::Diagonal()
03557   {
03558     Matrix A;
03559     if( !MTX_Diagonal( &m_Matrix, &A.m_Matrix ) )
03560     {
03561       MatrixError( "Diagonal", "Unable to get the diagonal of the source matrix." );
03562     }
03563     return A;
03564   }
03565 
03566   // Return the inverse of the matrix.
03567   Matrix  Matrix::Inverse()
03568   {
03569     Matrix A;
03570     if( !MTX_Invert( &m_Matrix, &A.m_Matrix ) )
03571     {
03572       MatrixError( "Inverse", "Unable to invert the matrix." );
03573     }
03574     return A;
03575   }
03576 
03577   // Return the inverse of the matrix.
03578   Matrix  Matrix::Inv()// short version
03579   {
03580     return Inverse();
03581   }
03582 
03583   // Return the Fourier Transform of each column of the matrix. Power of two uses FFT, otherwise fast DFT.
03584   Matrix  Matrix::FFT()
03585   {
03586     Matrix A;
03587     if( !MTX_FFT( &m_Matrix, &A.m_Matrix ) )
03588     {
03589       MatrixError( "FFT", "Unable to perform the FFT." );
03590     }
03591     return A;
03592   }
03593 
03594 
03595   Matrix  Matrix::FFT2()
03596   {
03597     Matrix A;
03598     if( !MTX_FFT2( &m_Matrix, &A.m_Matrix ) )
03599     {
03600       MTX_ERROR_MSG( "MTX_FFT2 returned false." );
03601       return false;
03602     }
03603     return A;
03604   }
03605 
03606   // Return the inverse Fourier Transform of each column of the matrix. Power of two uses IFFT, otherwise fast IDFT.
03607   Matrix  Matrix::IFFT()
03608   {
03609     Matrix A;
03610     if( !MTX_IFFT( &m_Matrix, &A.m_Matrix ) )
03611     {
03612       MatrixError( "IFFT", "Unable to perform the IFFT." );
03613     }
03614     return A;
03615   }
03616 
03617   Matrix  Matrix::IFFT2()
03618   {
03619     Matrix A;
03620     if( !MTX_IFFT2( &m_Matrix, &A.m_Matrix ) )
03621     {
03622       MTX_ERROR_MSG( "MTX_IFFT2 returned false." );
03623       return false;
03624     }
03625     return A;
03626   }
03627 
03628   Matrix  Matrix::DotMultiply(const Matrix& B)
03629   {
03630     Matrix A;
03631     if( !MTX_isConformalForAddition( &m_Matrix, &B.m_Matrix ) )
03632     {
03633       MatrixError( "DotMultiply", "Not conformal for dot multiplication." );
03634     }
03635     else
03636     {
03637       if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03638       {
03639         MatrixError( "DotMultiply", "MTX_Copy returned FALSE." );
03640       }        
03641       else
03642       {
03643         if( !MTX_DotMultiply_Inplace( &A.m_Matrix, &B.m_Matrix ) )
03644         {
03645           MatrixError( "MTX_DotMultiply_Inplace", "MTX_Copy returned FALSE." );
03646         }
03647       }
03648     }
03649     return A;
03650   }
03651 
03652   // Return the real part of the matrix.
03653   Matrix  Matrix::Real()
03654   {
03655     Matrix A;
03656     if( !MTX_Real( &m_Matrix, &A.m_Matrix ) )
03657     {
03658       MatrixError( "Real", "Cannot get real part of the matrix." );
03659     }
03660     return A;
03661   }
03662 
03663   // Return the imaginary part of the matrix.
03664   Matrix  Matrix::Imag()
03665   {
03666     Matrix A;
03667     if( !MTX_Imag( &m_Matrix, &A.m_Matrix ) )
03668     {
03669       MatrixError( "Imag", "Cannot get imaginary part of the matrix." );
03670     }
03671     return A;
03672   }
03673 
03674   // Return the complex conjugate of the matrix            
03675   Matrix  Matrix::conj()
03676   {
03677     Matrix A;
03678     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03679     {
03680       MatrixError( "Conj", "MTX_Copy returned FALSE." );
03681     }    
03682     if( !MTX_Conjugate( &A.m_Matrix ) )
03683     {
03684       MatrixError( "Conj", "MTX_Conj returned FALSE." );
03685     }
03686     return A;
03687   }
03688 
03689   Matrix  Matrix::AddIdentity()
03690   {
03691     Matrix A;
03692     if( !MTX_AddIdentity( &m_Matrix, &A.m_Matrix ) )
03693     {
03694       MatrixError( "AddIdentity", "MTX_AddIdentity returned FALSE." );
03695     }
03696     return A;
03697   }
03698 
03699   Matrix  Matrix::MinusIdentity()
03700   {
03701     Matrix A;
03702     if( !MTX_MinusIdentity( &m_Matrix, &A.m_Matrix ) )
03703     {
03704       MatrixError( "MinusIdentity", "MTX_MinusIdentity returned FALSE." );
03705     }
03706     return A;
03707   }
03708 
03709   Matrix  Matrix::IdentityMinusMe()
03710   {
03711     Matrix A;
03712     if( !MTX_IdentityMinus( &m_Matrix, &A.m_Matrix ) )
03713     {
03714       MatrixError( "IdentityMinusMe", "MTX_IdentityMinus returned FALSE." );
03715     }
03716     return A;
03717   }
03718 
03719   Matrix  Matrix::Negate()
03720   {
03721     Matrix A;
03722     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03723     {
03724       MatrixError( "Negate", "MTX_Copy returned FALSE." );
03725     }        
03726     if( !MTX_Negate( &A.m_Matrix ) )
03727     {
03728       MatrixError( "Negate", "MTX_Negate returned FALSE." );
03729     }
03730     return A;
03731   }
03732     
03733 
03734   // Return the square root of each element in the matrix.
03735   Matrix  Matrix::Sqrt()
03736   {
03737     Matrix A;
03738     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03739     {
03740       MatrixError( "Sqrt", "MTX_Copy returned FALSE." );
03741     }
03742     if( !MTX_Sqrt( &A.m_Matrix ) )
03743     {
03744       MatrixError( "Sqrt", "MTX_Sqrt returned FALSE." );
03745     }
03746     return A;
03747   }
03748 
03749   // Return the exponent of each element in the matrix.
03750   Matrix  Matrix::Exp()
03751   {
03752     Matrix A;
03753     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03754     {
03755       MatrixError( "Exp", "MTX_Copy returned FALSE." );
03756     }
03757     if( !MTX_Exp( &A.m_Matrix ) )
03758     {
03759       MatrixError( "Exp", "MTX_Exp returned FALSE." );
03760     }
03761     return A;
03762   }
03763 
03764   // Return the logarithm of each element in the matrix.
03765   Matrix  Matrix::Ln()
03766   {
03767     Matrix A;
03768     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03769     {
03770       MatrixError( "Ln", "MTX_Copy returned FALSE." );
03771     }
03772     if( !MTX_Ln( &A.m_Matrix ) )
03773     {
03774       MatrixError( "Ln", "MTX_Ln returned FALSE." );
03775     }
03776     return A;
03777   }
03778 
03779 
03780   Matrix  Matrix::cos()
03781   {
03782     Matrix A;
03783     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03784     {
03785       MatrixError( "cos", "MTX_Copy returned FALSE." );
03786     }
03787     if( !MTX_cos( &A.m_Matrix ) )
03788     {
03789       MatrixError( "cos", "MTX_cos returned FALSE." );
03790     }
03791     return A;
03792   }
03793 
03794   Matrix  Matrix::acos()
03795   {
03796     Matrix A;
03797     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03798     {
03799       MatrixError( "acos", "MTX_Copy returned FALSE." );
03800     }
03801     if( !MTX_acos( &A.m_Matrix ) )
03802     {
03803       MatrixError( "acos", "MTX_acos returned FALSE." );
03804     }
03805     return A;
03806   }
03807 
03808   Matrix  Matrix::sin()
03809   {
03810     Matrix A;
03811     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03812     {
03813       MatrixError( "sin", "MTX_Copy returned FALSE." );
03814     }
03815     if( !MTX_sin( &A.m_Matrix ) )
03816     {
03817       MatrixError( "sin", "MTX_sin returned FALSE." );
03818     }
03819     return A;
03820   }
03821 
03822   Matrix  Matrix::asin()
03823   {
03824     Matrix A;
03825     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03826     {
03827       MatrixError( "asin", "MTX_Copy returned FALSE." );
03828     }
03829     if( !MTX_asin( &A.m_Matrix ) )
03830     {
03831       MatrixError( "asin", "MTX_asin returned FALSE." );
03832     }
03833     return A;
03834   }
03835 
03836   Matrix  Matrix::tan()
03837   {
03838     Matrix A;
03839     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03840     {
03841       MatrixError( "tan", "MTX_Copy returned FALSE." );
03842     }
03843     if( !MTX_tan( &A.m_Matrix ) )
03844     {
03845       MatrixError( "tan", "MTX_tan returned FALSE." );
03846     }
03847     return A;
03848   }
03849 
03850   Matrix  Matrix::atan()
03851   {
03852     Matrix A;
03853     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03854     {
03855       MatrixError( "atan", "MTX_Copy returned FALSE." );
03856     }
03857     if( !MTX_atan( &A.m_Matrix ) )
03858     {
03859       MatrixError( "atan", "MTX_atan returned FALSE." );
03860     }
03861     return A;
03862   }
03863 
03864   Matrix  Matrix::cosh()
03865   {
03866     Matrix A;
03867     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03868     {
03869       MatrixError( "cosh", "MTX_Copy returned FALSE." );
03870     }
03871     if( !MTX_cosh( &A.m_Matrix ) )
03872     {
03873       MatrixError( "cosh", "MTX_cosh returned FALSE." );
03874     }
03875     return A;
03876   }
03877 
03878   Matrix  Matrix::sinh()
03879   {
03880     Matrix A;
03881     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03882     {
03883       MatrixError( "sinh", "MTX_Copy returned FALSE." );
03884     }
03885     if( !MTX_sinh( &A.m_Matrix ) )
03886     {
03887       MatrixError( "sinh", "MTX_sinh returned FALSE." );
03888     }
03889     return A;
03890   }
03891 
03892   Matrix  Matrix::tanh()
03893   {
03894     Matrix A;
03895     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03896     {
03897       MatrixError( "tanh", "MTX_Copy returned FALSE." );
03898     }
03899     if( !MTX_tanh( &A.m_Matrix ) )
03900     {
03901       MatrixError( "tanh", "MTX_tanh returned FALSE." );
03902     }
03903     return A;
03904   }
03905 
03906   Matrix  Matrix::cot()
03907   {
03908     Matrix A;
03909     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03910     {
03911       MatrixError( "cot", "MTX_Copy returned FALSE." );
03912     }
03913     if( !MTX_cot( &A.m_Matrix ) )
03914     {
03915       MatrixError( "cot", "MTX_cot returned FALSE." );
03916     }
03917     return A;
03918   }
03919 
03920   Matrix  Matrix::coth()
03921   {
03922     Matrix A;
03923     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03924     {
03925       MatrixError( "coth", "MTX_Copy returned FALSE." );
03926     }
03927     if( !MTX_coth( &A.m_Matrix ) )
03928     {
03929       MatrixError( "coth", "MTX_coth returned FALSE." );
03930     }
03931     return A;
03932   }
03933 
03934   Matrix  Matrix::abs()
03935   {
03936     Matrix A;
03937     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03938     {
03939       MatrixError( "abs", "MTX_Copy returned FALSE." );
03940     }
03941     if( !MTX_Abs( &A.m_Matrix ) )
03942     {
03943       MatrixError( "abs", "MTX_Abs returned FALSE." );
03944     }
03945     return A;
03946   }
03947 
03948   Matrix  Matrix::angle()
03949   {
03950     Matrix A;
03951     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03952     {
03953       MatrixError( "angle", "MTX_Copy returned FALSE." );
03954     }
03955     if( !MTX_angle( &A.m_Matrix ) )
03956     {
03957       MatrixError( "angle", "MTX_angle returned FALSE." );
03958     }
03959     return A;
03960   }
03961 
03962   Matrix  Matrix::pow(const double power_re, const double power_im)
03963   {
03964     Matrix A;
03965     if( !MTX_Pow( &m_Matrix, &A.m_Matrix, power_re, power_im ) )
03966     {
03967       MatrixError( "pow", "MTX_Pow returned FALSE." );
03968     }
03969     return A;
03970   }
03971 
03972   Matrix  Matrix::round(const unsigned precision)
03973   {
03974     Matrix A;
03975     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03976     {
03977       MatrixError( "round", "MTX_Copy returned FALSE." );
03978     }
03979     if( !MTX_Round( &A.m_Matrix, precision ) )
03980     {
03981       MatrixError( "round", "MTX_Round returned FALSE." );
03982     }
03983     return A;
03984   }
03985 
03986   Matrix  Matrix::floor()
03987   {
03988     Matrix A;
03989     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
03990     {
03991       MatrixError( "floor", "MTX_Copy returned FALSE." );
03992     }
03993     if( !MTX_Floor( &A.m_Matrix ) )
03994     {
03995       MatrixError( "floor", "MTX_Floor returned FALSE." );
03996     }
03997     return A;
03998   }
03999 
04000   Matrix  Matrix::ceil()
04001   {
04002     Matrix A;
04003     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
04004     {
04005       MatrixError( "ceil", "MTX_Copy returned FALSE." );
04006     }
04007     if( !MTX_Ceil( &A.m_Matrix ) )
04008     {
04009       MatrixError( "ceil", "MTX_Ceil returned FALSE." );
04010     }
04011     return A;
04012   }
04013 
04014   Matrix  Matrix::fix()
04015   {
04016     Matrix A;
04017     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
04018     {
04019       MatrixError( "fix", "MTX_Copy returned FALSE." );
04020     }
04021     if( !MTX_Fix( &A.m_Matrix ) )
04022     {
04023       MatrixError( "fix", "MTX_Fix returned FALSE." );
04024     }
04025     return A;
04026   }
04027 
04028   Matrix  Matrix::dotInvert()
04029   {
04030     Matrix A;
04031     if( !MTX_Copy( &m_Matrix, &A.m_Matrix ) )
04032     {
04033       MatrixError( "dotInvert", "MTX_Copy returned FALSE." );
04034     }
04035     if( !MTX_Inv( &A.m_Matrix ) )
04036     {
04037       MatrixError( "dotInvert", "MTX_Inv returned FALSE." );
04038     }
04039     return A;
04040   }
04041 
04042   Matrix Matrix::oneMinusMe()
04043   {
04044     Matrix A;
04045     if( !MTX_OneMinus( &m_Matrix, &A.m_Matrix ) )
04046     {
04047       MatrixError( "oneMinusMe", "MTX_OneMinus returned FALSE." );
04048     }
04049     return A;
04050   }
04051 
04052 
04053 
04054 
04055   // Get a reference to an element in the matrix to set its value.
04056   Matrix::Element& Matrix::operator() (unsigned row, unsigned col)
04057   {
04058     if( IndexCheck(row,col) )
04059     {
04060       m_MatrixElement.m_row = row;
04061       m_MatrixElement.m_col = col;
04062     }
04063     else
04064     {
04065       // This code should not be reached!
04066       m_MatrixElement.m_row = 0;
04067       m_MatrixElement.m_col = 0;
04068     }
04069     return m_MatrixElement; 
04070   }
04071 
04072 
04073   // Get a reference to an element in the matrix as a column or row vector to set its value.
04074   Matrix::Element& Matrix::operator() (unsigned index)
04075   {
04076     if( IndexCheck( index ) )
04077     {
04078       if( m_Matrix.ncols == 1 ) // column array
04079       {
04080         m_MatrixElement.m_row = index;
04081         m_MatrixElement.m_col = 0;
04082       }
04083       else if( m_Matrix.nrows == 1 ) // row array
04084       {
04085         m_MatrixElement.m_row = 0;
04086         m_MatrixElement.m_col = index;
04087       }
04088       else
04089       {
04090         // access the matrix as a singular column array
04091         m_MatrixElement.m_col = index / m_Matrix.nrows;
04092         m_MatrixElement.m_row = index - m_MatrixElement.m_col*m_Matrix.nrows;
04093       }
04094     }
04095     else
04096     {
04097       // This code should not be reached!
04098       m_MatrixElement.m_row = 0;
04099       m_MatrixElement.m_col = 0;
04100     }
04101 
04102     return m_MatrixElement;
04103   }
04104 
04105 
04106   Matrix::Element::Element(MTX& mtx)
04107     : m_mtx(mtx), m_row(0), m_col(0)
04108   {
04109     // Note that there is no index checking at this level. The 
04110     // index checking is performed at the Matrix operator() level.
04111   }
04112 
04113   Matrix::Element::~Element()
04114   {}
04115 
04116   const double Matrix::Element::real()
04117   {
04118     if( m_mtx.isReal )
04119     {
04120       return m_mtx.data[m_col][m_row];
04121     }
04122     else
04123     {
04124       return m_mtx.cplx[m_col][m_row].re;
04125     }
04126   }
04127   
04128   const double Matrix::Element::imag()
04129   {
04130     if( m_mtx.isReal )
04131     {
04132       return 0.0;
04133     }
04134     else
04135     {
04136       return m_mtx.cplx[m_col][m_row].im;
04137     }
04138   }
04139 
04140   const Matrix::Element& Matrix::Element::operator= (double v)
04141   {
04142     if( m_mtx.isReal )
04143     {
04144       m_mtx.data[m_col][m_row] = v;
04145     }
04146     else
04147     {
04148       m_mtx.cplx[m_col][m_row].re = v;
04149       m_mtx.cplx[m_col][m_row].im = 0.0;
04150     }
04151     return *this;
04152   }
04153   
04154   const Matrix::Element& Matrix::Element::operator= (std::complex<double> v)
04155   {
04156     if( m_mtx.isReal )
04157     {
04158       if( v.imag() != 0.0 )
04159       {
04160         // This is on the fly conversion to a complex matrix!
04161         if( !MTX_ConvertRealToComplex( &m_mtx ) )
04162         {
04163           MTX_Free( &m_mtx );
04164           Matrix::StaticMatrixError( "Element::operator=", "Unable to convert matrix from real to complex" );
04165           return *this;
04166         }
04167       }
04168       else
04169       {
04170         m_mtx.data[m_col][m_row] = v.real();
04171         return *this;
04172       }
04173     }
04174     m_mtx.cplx[m_col][m_row].re = v.real();
04175     m_mtx.cplx[m_col][m_row].im = v.imag();
04176     return *this;
04177   }
04178 
04179   const Matrix::Element& Matrix::Element::operator= (Element v)
04180   {
04181     if( v.m_mtx.isReal )
04182     {
04183       if( m_mtx.isReal )
04184       {
04185         m_mtx.data[m_col][m_row] = v.m_mtx.data[v.m_col][v.m_row];
04186       }
04187       else
04188       {
04189         m_mtx.cplx[m_col][m_row].re = v.m_mtx.data[v.m_col][v.m_row];
04190         m_mtx.cplx[m_col][m_row].im = 0.0;
04191       }
04192     }
04193     else
04194     {
04195       if( m_mtx.isReal )
04196       {
04197         // This is on the fly conversion to a complex matrix!
04198         if( !MTX_ConvertRealToComplex( &m_mtx ) )
04199         {
04200           MTX_Free( &m_mtx );
04201           Matrix::StaticMatrixError( "Element::operator=", "Unable to convert matrix from real to complex" );
04202           return *this;
04203         }        
04204       }
04205       
04206       m_mtx.cplx[m_col][m_row].re = v.m_mtx.cplx[v.m_col][v.m_row].re;
04207       m_mtx.cplx[m_col][m_row].im = v.m_mtx.cplx[v.m_col][v.m_row].im;      
04208     }
04209     return *this;
04210   }
04211 
04212 
04213   Matrix::Element::operator const std::complex<double>() const
04214   {
04215     if( m_mtx.isReal )
04216     {
04217       std::complex<double> v( m_mtx.data[m_col][m_row], 0.0 );
04218       return v;
04219     }
04220     else
04221     {
04222       std::complex<double> v( m_mtx.cplx[m_col][m_row].re, m_mtx.cplx[m_col][m_row].im );
04223       return v;
04224     }
04225   }
04226 
04227 
04228   void Matrix::Element::operator+= (const double scalar)
04229   {
04230     if( m_mtx.isReal )
04231     {
04232       m_mtx.data[m_col][m_row] += scalar;
04233     }
04234     else
04235     {
04236       m_mtx.cplx[m_col][m_row].re += scalar;
04237     }
04238   }
04239 
04240   void Matrix::Element::operator+= (const std::complex<double>& v)
04241   {
04242     if( m_mtx.isReal )
04243     {
04244       if( v.imag() != 0.0 )
04245       {
04246         // This is on the fly conversion to a complex matrix!
04247         if( !MTX_ConvertRealToComplex( &m_mtx ) )
04248         {
04249           MTX_Free( &m_mtx );
04250           Matrix::StaticMatrixError( "Element::operator=", "Unable to convert matrix from real to complex" );
04251           return;
04252         }
04253       }
04254       else
04255       {
04256         m_mtx.data[m_col][m_row] += v.real();
04257         return;
04258       }
04259     }
04260     
04261     m_mtx.cplx[m_col][m_row].re += v.real();
04262     m_mtx.cplx[m_col][m_row].im += v.imag();    
04263   }
04264   
04265   void Matrix::Element::operator+= (const Element& v)
04266   {
04267     std::complex<double> cplx = (const std::complex<double>)v;
04268     *this += cplx;
04269   }
04270 
04271 
04272   void Matrix::Element::operator-= (const double scalar)
04273   {
04274     if( m_mtx.isReal )
04275     {
04276       m_mtx.data[m_col][m_row] -= scalar;
04277     }
04278     else
04279     {
04280       m_mtx.cplx[m_col][m_row].re -= scalar;
04281     }
04282   }
04283 
04284   void Matrix::Element::operator-= (const std::complex<double>& v)
04285   {
04286     if( m_mtx.isReal )
04287     {
04288       if( v.imag() != 0.0 )
04289       {
04290         // This is on the fly conversion to a complex matrix!
04291         if( !MTX_ConvertRealToComplex( &m_mtx ) )
04292         {
04293           MTX_Free( &m_mtx );
04294           Matrix::StaticMatrixError( "Element::operator=", "Unable to convert matrix from real to complex" );
04295           return;
04296         }
04297       }
04298       else
04299       {
04300         m_mtx.data[m_col][m_row] -= v.real();
04301         return;
04302       }
04303     }
04304     
04305     m_mtx.cplx[m_col][m_row].re -= v.real();
04306     m_mtx.cplx[m_col][m_row].im -= v.imag();    
04307   }
04308   
04309   void Matrix::Element::operator-= (const Element& v)
04310   {
04311     std::complex<double> cplx = (const std::complex<double>)v;
04312     *this -= cplx;
04313   }
04314 
04315 
04316   void Matrix::Element::operator*= (const double scalar)
04317   {
04318     if( m_mtx.isReal )
04319     {
04320       m_mtx.data[m_col][m_row] *= scalar;
04321     }
04322     else
04323     {
04324       m_mtx.cplx[m_col][m_row].re *= scalar;
04325       m_mtx.cplx[m_col][m_row].im *= scalar;
04326     }
04327   }
04328 
04329   void Matrix::Element::operator*= (const std::complex<double>& v)
04330   {
04331     if( m_mtx.isReal )
04332     {
04333       if( v.imag() != 0.0 )
04334       {
04335         // This is on the fly conversion to a complex matrix!
04336         if( !MTX_ConvertRealToComplex( &m_mtx ) )
04337         {
04338           MTX_Free( &m_mtx );
04339           Matrix::StaticMatrixError( "Element::operator=", "Unable to convert matrix from real to complex" );
04340           return;
04341         }
04342       }
04343       else
04344       {
04345         m_mtx.data[m_col][m_row] *= v.real();
04346         return;
04347       }
04348     }
04349 
04350     double re = m_mtx.cplx[m_col][m_row].re;
04351     double im = m_mtx.cplx[m_col][m_row].im;
04352     
04353     m_mtx.cplx[m_col][m_row].re = re*v.real() - im*v.imag();
04354     m_mtx.cplx[m_col][m_row].im = re*v.imag() + im*v.real();    
04355   }
04356   
04357   void Matrix::Element::operator*= (const Element& v)
04358   {
04359     std::complex<double> cplx = (const std::complex<double>)v;
04360     *this *= cplx;
04361   }
04362 
04363 
04364   void Matrix::Element::operator/= (const double scalar)
04365   {
04366     //if( scalar == 0.0 )
04367     //{
04368     //  MTX_Free( &m_mtx );
04369     //  Matrix::StaticMatrixError("Element/=","Divide by zero!");
04370     //}
04371     //else
04372     //{
04373       if( m_mtx.isReal )
04374       {
04375         m_mtx.data[m_col][m_row] /= scalar;
04376       }
04377       else
04378       {
04379         m_mtx.cplx[m_col][m_row].re /= scalar;
04380         m_mtx.cplx[m_col][m_row].im /= scalar;
04381       }
04382     //}
04383   }
04384 
04385   void Matrix::Element::operator/= (const std::complex<double>& v)
04386   {
04387     if( m_mtx.isReal )
04388     {
04389       if( v.imag() == 0.0 )
04390       {
04391       //  if( v.real() == 0.0 )
04392       //  {
04393       //    MTX_Free( &m_mtx );
04394       //    Matrix::StaticMatrixError( "Element/=", "Divide by zero." );
04395       //    return;
04396       //  }
04397       //  else
04398       //  {
04399           m_mtx.data[m_col][m_row] /= v.real();
04400           return;
04401       //  }
04402       }
04403       else
04404       {
04405         // This is on the fly conversion to a complex matrix!
04406         if( !MTX_ConvertRealToComplex( &m_mtx ) )
04407         {
04408           MTX_Free( &m_mtx );
04409           Matrix::StaticMatrixError( "Element/=", "Unable to convert matrix from real to complex" );
04410           return;
04411         }
04412       }
04413     }
04414 
04415     double d = v.real()*v.real() + v.imag()*v.imag(); 
04416     //if( d == 0.0 )
04417     //{ 
04418     //  MTX_Free( &m_mtx );
04419     //  Matrix::StaticMatrixError( "Element/=", "Divide by zero." );
04420     //}
04421     //else
04422     {
04423       double r = m_mtx.cplx[m_col][m_row].re;
04424       double i = m_mtx.cplx[m_col][m_row].im;
04425       m_mtx.cplx[m_col][m_row].re = (r * v.real() + i * v.imag()) / d;
04426       m_mtx.cplx[m_col][m_row].im = (i * v.real() - r * v.imag()) / d;
04427     }
04428   }
04429   
04430   void Matrix::Element::operator/= (const Element& v)
04431   {
04432     std::complex<double> cplx = (const std::complex<double>)v;
04433     *this /= cplx;
04434   }
04435 
04436 
04437 
04438 
04439 
04440 
04441   //friend 
04442   const std::complex<double> operator+ (const Matrix::Element& m, double scalar)
04443   {
04444     std::complex<double> v;
04445     v = (const std::complex<double>)m;
04446     v += scalar;
04447     return v;
04448   }
04449 
04450   //friend 
04451   const std::complex<double> operator+ (const Matrix::Element& a, const Matrix::Element& b)
04452   {
04453     std::complex<double> v1;
04454     std::complex<double> v2;
04455     v1 = (const std::complex<double>)a;
04456     v2 = (const std::complex<double>)b;
04457     v1 += v2;
04458     return v1;
04459   }
04460     
04461   //friend 
04462   const std::complex<double> operator+ (const Matrix::Element& a, const std::complex<double>& b)
04463   {
04464     std::complex<double> v;
04465     v = (const std::complex<double>)a;
04466     v += b;
04467     return v;
04468   }
04469 
04470   //friend 
04471   const std::complex<double> operator+ (double scalar, const Matrix::Element& m)
04472   {
04473     return (m+scalar);
04474 
04475   }
04476 
04477   //friend 
04478   const std::complex<double> operator+ (const std::complex<double>& b, const Matrix::Element& a)
04479   {
04480     return (a+b);
04481   }
04482 
04483 
04484   //friend 
04485   const std::complex<double> operator- (const Matrix::Element& m, double scalar)
04486   {
04487     std::complex<double> v;
04488     v = (const std::complex<double>)m;
04489     v -= scalar;
04490     return v;
04491   }
04492 
04493   //friend 
04494   const std::complex<double> operator- (const Matrix::Element& a, const Matrix::Element& b)
04495   {
04496     std::complex<double> v1;
04497     std::complex<double> v2;
04498     v1 = (const std::complex<double>)a;
04499     v2 = (const std::complex<double>)b;
04500     v1 -= v2;
04501     return v1;
04502   }
04503     
04504   //friend 
04505   const std::complex<double> operator- (const Matrix::Element& a, const std::complex<double>& b)
04506   {
04507     std::complex<double> v;
04508     v = (const std::complex<double>)a;
04509     v -= b;
04510     return v;
04511   }
04512 
04513   //friend 
04514   const std::complex<double> operator- (double scalar, const Matrix::Element& m)
04515   {
04516     return (m+(-1.0*scalar));
04517 
04518   }
04519 
04520   //friend 
04521   const std::complex<double> operator- (const std::complex<double>& b, const Matrix::Element& a)
04522   {
04523     std::complex<double> v = b;
04524     v -= (const std::complex<double>)a;
04525     return v;    
04526   }
04527 
04528 
04529   //friend 
04530   const std::complex<double> operator* (const Matrix::Element& m, double scalar)
04531   {
04532     std::complex<double> v;
04533     v = (const std::complex<double>)m;
04534     v *= scalar;
04535     return v;
04536   }
04537 
04538   //friend 
04539   const std::complex<double> operator* (const Matrix::Element& a, const Matrix::Element& b)
04540   {
04541     std::complex<double> v1;
04542     std::complex<double> v2;
04543     v1 = (const std::complex<double>)a;
04544     v2 = (const std::complex<double>)b;
04545     v1 *= v2;
04546     return v1;
04547   }
04548     
04549   //friend 
04550   const std::complex<double> operator* (const Matrix::Element& a, const std::complex<double>& b)
04551   {
04552     std::complex<double> v;
04553     v = (const std::complex<double>)a;
04554     v *= b;
04555     return v;
04556   }
04557 
04558   //friend 
04559   const std::complex<double> operator* (double scalar, const Matrix::Element& m)
04560   {
04561     return (m*scalar);
04562   }
04563       
04564   //friend 
04565   const std::complex<double> operator* (const std::complex<double>& b, const Matrix::Element& a)
04566   {
04567     return (a*b);
04568   }
04569 
04570 
04571   //friend 
04572   const std::complex<double> operator/ (const Matrix::Element& m, double scalar)
04573   {
04574     std::complex<double> v;
04575     v = (const std::complex<double>)m;
04576     v /= scalar;
04577     return v;
04578   }
04579 
04580   //friend 
04581   const std::complex<double> operator/ (const Matrix::Element& a, const Matrix::Element& b)
04582   {
04583     std::complex<double> v1;
04584     std::complex<double> v2;
04585     v1 = (const std::complex<double>)a;
04586     v2 = (const std::complex<double>)b;
04587     v1 /= v2;
04588     return v1;
04589   }
04590     
04591   //friend 
04592   const std::complex<double> operator/ (const Matrix::Element& a, const std::complex<double>& b)
04593   {
04594     std::complex<double> v;
04595     v = (const std::complex<double>)a;
04596     v /= b; 
04597     return v;
04598   }
04599 
04600   //friend 
04601   const std::complex<double> operator/ (double scalar, const Matrix::Element& m)
04602   {
04603     std::complex<double> v(scalar,0.0);
04604     v /= (const std::complex<double>)m;
04605     return v;
04606   }
04607 
04608   //friend 
04609   const std::complex<double> operator/ (const std::complex<double>& b, const Matrix::Element& a)
04610   {
04611     std::complex<double> v(b);
04612     v /= (const std::complex<double>)a;
04613     return v;
04614   }
04615 
04616 
04617   //friend 
04618   const bool operator== (const Matrix::Element& m, double scalar)
04619   {
04620     if( m.m_mtx.isReal )
04621     {
04622       if( m.m_mtx.data[m.m_col][m.m_row] == scalar )
04623         return true;
04624       else
04625         return false;
04626     }
04627     else
04628     {
04629       if( m.m_mtx.cplx[m.m_col][m.m_row].im != 0.0 )
04630         return false;
04631       if( m.m_mtx.cplx[m.m_col][m.m_row].re == scalar )
04632         return true;
04633       else
04634         return false;
04635     }
04636   }
04637   
04638   //friend 
04639   const bool operator== (const Matrix::Element& a, const Matrix::Element& b)
04640   {
04641     if( a.m_mtx.isReal )
04642     {
04643       if( b.m_mtx.isReal )
04644       {
04645         if( a.m_mtx.data[a.m_col][a.m_row] == b.m_mtx.data[b.m_col][b.m_row] )
04646           return true;
04647         else
04648           return false;
04649       }
04650       else
04651       {
04652         if( b.m_mtx.cplx[a.m_col][a.m_row].im != 0.0 )
04653           return false;
04654         if( a.m_mtx.data[a.m_col][a.m_row] == b.m_mtx.cplx[b.m_col][b.m_row].re )
04655           return true;
04656         else
04657           return false;
04658       }
04659     }
04660     else
04661     {
04662       if( b.m_mtx.isReal )
04663       {
04664         if( a.m_mtx.cplx[a.m_col][a.m_row].im != 0.0 )
04665           return false;
04666         if( a.m_mtx.cplx[a.m_col][a.m_row].re == b.m_mtx.data[b.m_col][b.m_row] )
04667           return true;
04668         else
04669           return false;
04670       }
04671       else
04672       {
04673         if( a.m_mtx.cplx[a.m_col][a.m_row].re == b.m_mtx.cplx[b.m_col][b.m_row].re &&
04674           a.m_mtx.cplx[a.m_col][a.m_row].im == b.m_mtx.cplx[b.m_col][b.m_row].im )
04675           return true;
04676         else
04677           return false;
04678       }
04679     }
04680   }
04681 
04682   //friend 
04683   const bool operator== (const Matrix::Element& a, const std::complex<double>& b)
04684   {
04685     if( a.m_mtx.isReal )
04686     {
04687       if( b.imag() != 0.0 )
04688         return false;
04689       if( a.m_mtx.data[a.m_col][a.m_row] == b.real() )
04690         return true;
04691       else
04692         return false;
04693     }
04694     else
04695     {
04696       if( a.m_mtx.cplx[a.m_col][a.m_row].re == b.real() && a.m_mtx.cplx[a.m_col][a.m_row].im == b.imag() )
04697         return true;
04698       else
04699         return false;
04700     }
04701   }
04702 
04703   //friend 
04704   const bool operator== (double scalar, const Matrix::Element& m)
04705   {
04706     return (m==scalar);
04707   }
04708       
04709   //friend 
04710   const bool operator== (const std::complex<double>& b, const Matrix::Element& a)
04711   {
04712     return (a==b);
04713   }
04714 
04715 
04716 
04717   bool Matrix::operator+= (const double scalar)
04718   {
04719     return Inplace_AddScalar( scalar );
04720   }
04721   
04722   bool Matrix::operator+= (const std::complex<double> cplx)
04723   {
04724     return Inplace_AddScalarComplex( cplx );
04725   }
04726 
04727   bool Matrix::operator-= (const double scalar)
04728   {
04729     return Inplace_SubtractScalar( scalar );
04730   }
04731 
04732   bool Matrix::operator-= (const std::complex<double> cplx)
04733   {
04734     return Inplace_SubtractScalarComplex( cplx );
04735   }
04736 
04737   bool Matrix::operator*= (const double scalar)
04738   {
04739     return Inplace_MultiplyScalar( scalar );
04740   }
04741 
04742   bool Matrix::operator*= (const std::complex<double> cplx)
04743   {
04744     return Inplace_MultiplyScalarComplex( cplx );
04745   }
04746 
04747   bool Matrix::operator/= (double scalar)
04748   {
04749     return Inplace_DivideScalar( scalar );
04750   }
04751 
04752   bool Matrix::operator/= (const std::complex<double> cplx)
04753   {
04754     return Inplace_DivideScalarComplex( cplx );
04755   }
04756 
04757   bool Matrix::operator+= (const Matrix& mat)
04758   {
04759     return Inplace_Add( mat );
04760   }
04761 
04762   bool Matrix::operator-= (const Matrix& mat)
04763   {
04764     return Inplace_Subtract( mat );
04765   }
04766 
04767   /* friend */
04768   Matrix operator++ (Matrix& mat, int)
04769   {
04770     if( !mat.Inplace_Increment() )
04771     {
04772       mat.MatrixError( "operator++", "Inplace_Increment() returned false." );
04773       return mat;
04774     }
04775     return mat;
04776   }
04777 
04778   /* friend */
04779   Matrix operator-- (Matrix& mat, int)
04780   {
04781     if( !mat.Inplace_Decrement() )
04782     {
04783       mat.MatrixError( "operator--", "Inplace_Decrement() returned false." );
04784       return mat;
04785     }
04786     return mat;
04787   }
04788 
04789   // matrix multiplication: A = B * C
04790   /* friend */
04791   Matrix operator* (Matrix& mat1, Matrix& mat2)
04792   {
04793     Matrix A;
04794     if( !MTX_Multiply( &A.m_Matrix, &mat1.m_Matrix, &mat2.m_Matrix ) )
04795     {
04796       mat1.Clear();
04797       A.Clear();
04798       mat2.MatrixError( "operator*", "MTX_Multiply() returned false." );
04799       return A;
04800     }
04801     return A; // return a copy
04802   }
04803   
04804   Matrix operator* (const Matrix& mat1, const Matrix& mat2)
04805   {
04806     Matrix A;
04807     if( !MTX_Multiply( &A.m_Matrix, &mat1.m_Matrix, &mat2.m_Matrix ) )
04808     {
04809       A.Clear();
04810       Matrix::StaticMatrixError( "operator*", "MTX_Multiply() returned false." );
04811       return A;
04812     }
04813     return A; // return a copy
04814   }
04815 
04816 
04817 
04818   // matrix addition: A = B + C
04819   /* friend */ 
04820   Matrix operator+ (Matrix& mat1, Matrix& mat2)
04821   {
04822     Matrix A;
04823     if( !MTX_Add( &A.m_Matrix, &mat1.m_Matrix, &mat2.m_Matrix ) )
04824     {
04825       A.Clear();
04826       mat1.Clear();
04827       mat2.MatrixError( "operator+", "MTX_Add() returned false." );
04828       return A;
04829     }
04830     return A; // return a copy
04831   }
04832   
04833   Matrix operator+ (const Matrix& mat1, const Matrix& mat2)
04834   {
04835     Matrix A;
04836     if( !MTX_Add( &A.m_Matrix, &mat1.m_Matrix, &mat2.m_Matrix ) )
04837     {
04838       A.Clear();
04839       Matrix::StaticMatrixError( "operator+", "MTX_Add() returned false." );
04840       return A;
04841     }
04842     return A; // return a copy
04843   }
04844 
04845 
04846 
04847   // matrix subtraction: A = B - C
04848   /* friend */ 
04849   Matrix operator- (Matrix& mat1, Matrix& mat2)
04850   {
04851     Matrix A;
04852     if( !MTX_Subtract( &A.m_Matrix, &mat1.m_Matrix, &mat2.m_Matrix ) )
04853     {
04854       mat1.Clear();
04855       mat2.MatrixError( "operator-", "MTX_Subtract() returned false." );
04856       return A;
04857     }
04858 
04859     return A; // return a copy
04860   }
04861   
04862   Matrix operator- (const Matrix& mat1, const Matrix& mat2)
04863   {
04864     Matrix A;
04865     if( !MTX_Subtract( &A.m_Matrix, &mat1.m_Matrix, &mat2.m_Matrix ) )
04866     {
04867       A.Clear();
04868       Matrix::StaticMatrixError( "operator-", "MTX_Subtract() returned false." );
04869       return A;
04870     }
04871 
04872     return A; // return a copy
04873   }
04874 
04875 
04876   // raise each element to a power
04877   /* friend */ 
04878   Matrix operator^ (Matrix& mat, const double scalar)
04879   {
04880     Matrix A;
04881     if( !MTX_Pow( &mat.m_Matrix, &A.m_Matrix, scalar, 0.0 ) )
04882     {
04883       mat.MatrixError( "operator^", "MTX_Pow() returned false." );
04884       return A;
04885     }
04886 
04887     return A; // return a copy
04888   }
04889 
04890   /* friend */ 
04891   Matrix operator+ (const double scalar, Matrix& mat)
04892   {
04893     Matrix A;
04894     if( !MTX_Copy( &mat.m_Matrix, &A.m_Matrix ) )
04895     {
04896       mat.MatrixError( "operator+", "MTX_Copy() returned false." );
04897       return A;
04898     }
04899 
04900     if( !A.Inplace_AddScalar( scalar ) )
04901     {
04902       mat.MatrixError( "Matrix operator+", "Inplace_AddScalar() returned false" );
04903       return A;
04904     }
04905 
04906     return A; // return a copy
04907   }
04908 
04909   /* friend */ 
04910   Matrix operator- (const double scalar, Matrix& mat)
04911   {
04912     Matrix A;
04913 
04914     if( !A.Redim( mat.GetNrRows(), mat.GetNrCols() ) )
04915     {
04916       mat.MatrixError( "operator-", "Redim() returned false." );
04917       return A;
04918     }
04919 
04920     if( !A.Fill( scalar ) )
04921     {
04922       mat.MatrixError( "operator-", "Fill() returned false." );
04923       return A;
04924     }
04925 
04926     if( !A.Inplace_Subtract( mat ) )
04927     {
04928       mat.MatrixError( "operator-", "Fill() returned false." );
04929       return A;
04930     }
04931 
04932     return A; // return a copy
04933   }
04934 
04935 
04936   /* friend */ 
04937   Matrix operator* (const double scalar, Matrix& mat)
04938   {
04939     Matrix A;
04940     if( !MTX_Copy( &mat.m_Matrix, &A.m_Matrix ) )
04941     {
04942       mat.MatrixError( "operator*", "MTX_Copy() returned false." );
04943       return A;
04944     }
04945 
04946     if( !A.Inplace_MultiplyScalar( scalar ) )
04947     {
04948       mat.MatrixError( "operator*", "Inplace_MultiplyScalar() returned false." );
04949       return A;
04950     }
04951 
04952     return A;
04953   }
04954 
04955   /* friend */ 
04956   Matrix operator/ (Matrix& mat, const double scalar)
04957   {
04958     Matrix A;
04959     if( !MTX_Copy( &mat.m_Matrix, &A.m_Matrix ) )
04960     {
04961       mat.MatrixError( "operator/", "MTX_Copy() returned false." );
04962       return A;
04963     }
04964 
04965     if( !A.Inplace_DivideScalar( scalar ) )
04966     {
04967       mat.MatrixError( "operator/", "Inplace_DivideScalar() returned false." );
04968       return A;
04969     }
04970 
04971     return A;
04972   }
04973 
04974   /* friend */ 
04975   Matrix operator/ (const double scalar, Matrix& mat)
04976   {
04977     Matrix A;
04978     if( !A.Redim( mat.GetNrRows(), mat.GetNrCols() ) )
04979     {
04980       mat.MatrixError( "operator/", "Redim() returned false." );
04981       return A;
04982     }
04983 
04984     if( !A.Fill( scalar ) )
04985     {
04986       mat.MatrixError( "operator/", "Fill() returned false." );
04987       return A;
04988     }
04989 
04990     if( !A.Inplace_DotDivide( mat ) )
04991     {
04992       mat.MatrixError( "operator/", "Inplace_DotDivide() returned false." );
04993       return A;
04994     }
04995 
04996     return A; // return a copy
04997   }
04998 
04999 
05000 
05001 
05002 
05003   //==========================
05004   //
05005 #ifdef MATRIX_STREAM_SUPPORT
05006 
05007   // output of a matrix: cout << A;
05008   /* friend */ 
05009   ostream& operator<< (ostream& strm, const Matrix& mat)
05010   {
05011     mat.Print( strm, strm.precision(), strm.width() );
05012     return strm;
05013   }
05014 
05015 #endif
05016   //
05017   //==========================
05018 
05019 
05020   bool Matrix::IndexCheck( const unsigned row, const unsigned col )
05021   {
05022     if( MTX_isNull(&m_Matrix) || row >= m_Matrix.nrows || col >= m_Matrix.ncols )
05023     {
05024       char msga[128];
05025 #ifndef _CRT_SECURE_NO_DEPRECATE
05026       sprintf_s( msga, 128, "Matrix access violation (%d,%d) out of bounds (%d,%d).\n", row, col, m_Matrix.nrows, m_Matrix.ncols );
05027 #else
05028       sprintf( msga, "Matrix access violation (%d,%d) out of bounds (%d,%d).\n", row, col, m_Matrix.nrows, m_Matrix.ncols );
05029 #endif
05030       MatrixError( "IndexCheck", msga );
05031       MTX_ERROR_MSG( msga );
05032       return false;
05033     }
05034     return true;
05035   }
05036 
05037   bool Matrix::IndexCheck( const unsigned index )
05038   {
05039     unsigned n = 0; // The number of elements as a vector.
05040     if( MTX_isNull(&m_Matrix) )
05041       n = 0;
05042     else
05043       n = m_Matrix.nrows*m_Matrix.ncols;
05044 
05045     if( index >= n )
05046     {
05047       char msga[128];
05048 #ifndef _CRT_SECURE_NO_DEPRECATE
05049       sprintf_s( msga, 128, "Matrix access violation (%d) out of bounds (%dx%d).\n", index, m_Matrix.nrows, m_Matrix.ncols );
05050 #else
05051       sprintf( msga, "Matrix access violation (%d) out of bounds (%dx%d).\n", index, m_Matrix.nrows, m_Matrix.ncols );
05052 #endif
05053       MatrixError( "IndexCheck", msga );
05054       MTX_ERROR_MSG( msga );
05055       return false;
05056     }
05057     return true;
05058   }
05059 
05060 
05061 
05062 
05063   Matrix::RealOnlyAccess::RealOnlyAccess( MTX& mtx, const unsigned row ) 
05064     : m_Matrix( mtx ), m_row( row ) 
05065   {}
05066 
05067   Matrix::RealOnlyAccess::~RealOnlyAccess()
05068   {}
05069 
05070   bool Matrix::RealOnlyAccess::IndexCheck( const unsigned row, const unsigned col )
05071   {
05072     if( MTX_isNull(&m_Matrix) || row >= m_Matrix.nrows || col >= m_Matrix.ncols )
05073     {
05074       char msga[128];
05075 #ifndef _CRT_SECURE_NO_DEPRECATE
05076       sprintf_s( msga, 128, "Matrix access violation [%d][%d] out of bounds (%d,%d).\n", row, col, m_Matrix.nrows, m_Matrix.ncols );
05077 #else
05078       sprintf( msga, "Matrix access violation (%d,%d) out of bounds (%d,%d).\n", row, col, m_Matrix.nrows, m_Matrix.ncols );
05079 #endif
05080       MTX_Free( &m_Matrix );
05081       StaticMatrixError( "IndexCheck", msga );
05082       MTX_ERROR_MSG( msga );
05083       return false;
05084     }
05085     return true;
05086   }
05087 
05088   bool Matrix::RealOnlyAccess::IndexCheck( const unsigned index )
05089   {
05090     unsigned n = 0; // The number of elements as a vector.
05091     if( MTX_isNull(&m_Matrix) )
05092       n = 0;
05093     else
05094       n = m_Matrix.nrows*m_Matrix.ncols;
05095 
05096     if( index >= n )
05097     {
05098       char msga[128];
05099 #ifndef _CRT_SECURE_NO_DEPRECATE
05100       sprintf_s( msga, 128, "Matrix access violation [%d] out of bounds (%dx%d).\n", index, m_Matrix.nrows, m_Matrix.ncols );
05101 #else
05102       sprintf( msga, "Matrix access violation (%d) out of bounds (%dx%d).\n", index, m_Matrix.nrows, m_Matrix.ncols );
05103 #endif
05104       MTX_Free( &m_Matrix );
05105       StaticMatrixError( "IndexCheck", msga );
05106       MTX_ERROR_MSG( msga );
05107       return false;
05108     }
05109     return true;
05110   }
05111 
05112   double& Matrix::RealOnlyAccess::operator [] (const unsigned col)
05113   { 
05114     if( IndexCheck( m_row, col ) )
05115     {
05116       if( m_Matrix.isReal )
05117       {
05118         return m_Matrix.data[col][m_row];
05119       }
05120       else
05121       {
05122         return m_Matrix.cplx[col][m_row].re;
05123       }
05124     }
05125     else
05126     {
05127       staticglobal_BadDouble = 0.0;
05128       return staticglobal_BadDouble;
05129     }    
05130   }
05131 
05132   Matrix::RealOnlyAccess Matrix::operator[] (const unsigned row)
05133   {
05134     return RealOnlyAccess( m_Matrix, row );
05135   }
05136 
05137   Matrix::RealOnlyAccess& Matrix::RealOnlyAccess::operator=(const double value)
05138   {
05139     // This is indexing the matrix as a vector.
05140     const unsigned index = m_row;
05141     if( IndexCheck(index) )
05142     {
05143       if( m_Matrix.ncols == 1 ) // column array
05144       {
05145         if( m_Matrix.isReal )
05146         {
05147           m_Matrix.data[0][index] = value;
05148         }
05149         else
05150         {
05151           m_Matrix.cplx[0][index].re = value;
05152           m_Matrix.cplx[0][index].im = 0.0;
05153         }
05154       }
05155       else if( m_Matrix.nrows == 1 ) // row array
05156       {
05157         if( m_Matrix.isReal )
05158         {
05159           m_Matrix.data[index][0] = value;
05160         }
05161         else
05162         {
05163           m_Matrix.cplx[index][0].re = value;
05164           m_Matrix.cplx[index][0].im = 0.0;
05165         }
05166       }
05167       else
05168       {
05169         // access the matrix as a singular column array
05170         unsigned col = index / m_Matrix.nrows;
05171         unsigned row = index - col*m_Matrix.nrows;
05172 
05173         if( m_Matrix.isReal )
05174         {
05175           m_Matrix.data[col][row] = value;
05176         }
05177         else
05178         {
05179           m_Matrix.cplx[col][row].re = value;
05180           m_Matrix.cplx[col][row].im = 0.0;
05181         }
05182       }
05183     }
05184     return *this;
05185   }
05186 
05187   Matrix::RealOnlyAccess& Matrix::RealOnlyAccess::operator=(RealOnlyAccess& rhs)
05188   {
05189     // Matrix A(1); Matrix B(1);
05190     // A[0] = B[0];
05191 
05192     // Get the value of the rhs.
05193     double val = (const double)rhs;
05194 
05195     // Use the operator= double overload.
05196     *this = val;
05197     return *this;
05198   }
05199 
05200   Matrix::RealOnlyAccess& Matrix::RealOnlyAccess::operator=(Matrix::Element& rhs)
05201   {
05202     // Matrix A(1); Matrix B(1);
05203     // A[0] = B(0);
05204     *this = rhs.real();
05205     return *this;
05206   }
05207 
05208 
05209   Matrix::RealOnlyAccess::operator const double()
05210   {
05211     // This is indexing the matrix as a vector.
05212     const unsigned index = m_row;
05213     if( IndexCheck(index) )
05214     {
05215       if( m_Matrix.ncols == 1 ) // column array
05216       {
05217         if( m_Matrix.isReal )
05218         {
05219           return m_Matrix.data[0][index];
05220         }
05221         else
05222         {
05223           return m_Matrix.cplx[0][index].re;
05224         }
05225       }
05226       else if( m_Matrix.nrows == 1 ) // row array
05227       {
05228         if( m_Matrix.isReal )
05229         {
05230           return m_Matrix.data[index][0];
05231         }
05232         else
05233         {
05234           return m_Matrix.cplx[index][0].re;
05235         }
05236       }
05237       else
05238       {
05239         // access the matrix as a singular column array
05240         unsigned col = index / m_Matrix.nrows;
05241         unsigned row = index - col*m_Matrix.nrows;
05242 
05243         if( m_Matrix.isReal )
05244         {
05245           return m_Matrix.data[col][row];
05246         }
05247         else
05248         {
05249           return m_Matrix.cplx[col][row].re;
05250         }
05251       }
05252     }
05253     return 0.0; // Should not be reached!
05254   }
05255 
05256   bool Matrix::RealOnlyAccess::operator+= (const double scalar)
05257   {
05258     // This is indexing the matrix as a vector.
05259     const unsigned index = m_row;
05260     if( IndexCheck(index) )
05261     {
05262       if( m_Matrix.ncols == 1 ) // column array
05263       {
05264         if( m_Matrix.isReal )
05265         {
05266           m_Matrix.data[0][index] += scalar;
05267           return true;
05268         }
05269         else
05270         {
05271           m_Matrix.cplx[0][index].re += scalar;
05272           return true;
05273         }
05274       }
05275       else if( m_Matrix.nrows == 1 ) // row array
05276       {
05277         if( m_Matrix.isReal )
05278         {
05279           m_Matrix.data[index][0] += scalar;
05280           return true;
05281         }
05282         else
05283         {
05284           m_Matrix.cplx[index][0].re += scalar;
05285           return true;
05286         }
05287       }
05288       else
05289       {
05290         // access the matrix as a singular column array
05291         unsigned col = index / m_Matrix.nrows;
05292         unsigned row = index - col*m_Matrix.nrows;
05293 
05294         if( m_Matrix.isReal )
05295         {
05296           m_Matrix.data[col][row] += scalar;
05297           return true;
05298         }
05299         else
05300         {
05301           m_Matrix.cplx[col][row].re += scalar;
05302           return true;
05303         }
05304       }
05305     }
05306     MTX_ERROR_MSG( "Unexpected." );
05307     return false; // Should not be reached!
05308   }
05309   
05310   bool Matrix::RealOnlyAccess::operator-= (const double scalar)
05311   {
05312     // This is indexing the matrix as a vector.
05313     const unsigned index = m_row;
05314     if( IndexCheck(index) )
05315     {
05316       if( m_Matrix.ncols == 1 ) // column array
05317       {
05318         if( m_Matrix.isReal )
05319         {
05320           m_Matrix.data[0][index] -= scalar;
05321           return true;
05322         }
05323         else
05324         {
05325           m_Matrix.cplx[0][index].re -= scalar;
05326           return true;
05327         }
05328       }
05329       else if( m_Matrix.nrows == 1 ) // row array
05330       {
05331         if( m_Matrix.isReal )
05332         {
05333           m_Matrix.data[index][0] -= scalar;
05334           return true;
05335         }
05336         else
05337         {
05338           m_Matrix.cplx[index][0].re -= scalar;
05339           return true;
05340         }
05341       }
05342       else
05343       {
05344         // access the matrix as a singular column array
05345         unsigned col = index / m_Matrix.nrows;
05346         unsigned row = index - col*m_Matrix.nrows;
05347 
05348         if( m_Matrix.isReal )
05349         {
05350           m_Matrix.data[col][row] -= scalar;
05351           return true;
05352         }
05353         else
05354         {
05355           m_Matrix.cplx[col][row].re -= scalar;
05356           return true;
05357         }
05358       }
05359     }
05360     MTX_ERROR_MSG( "Unexpected." );
05361     return false; // Should not be reached!
05362   }
05363 
05364   bool Matrix::RealOnlyAccess::operator*= (const double scalar)
05365   {
05366     // This is indexing the matrix as a vector.
05367     const unsigned index = m_row;
05368     if( IndexCheck(index) )
05369     {
05370       if( m_Matrix.ncols == 1 ) // column array
05371       {
05372         if( m_Matrix.isReal )
05373         {
05374           m_Matrix.data[0][index] *= scalar;
05375           return true;
05376         }
05377         else
05378         {
05379           m_Matrix.cplx[0][index].re *= scalar;
05380           return true;
05381         }
05382       }
05383       else if( m_Matrix.nrows == 1 ) // row array
05384       {
05385         if( m_Matrix.isReal )
05386         {
05387           m_Matrix.data[index][0] *= scalar;
05388           return true;
05389         }
05390         else
05391         {
05392           m_Matrix.cplx[index][0].re *= scalar;
05393           return true;
05394         }
05395       }
05396       else
05397       {
05398         // access the matrix as a singular column array
05399         unsigned col = index / m_Matrix.nrows;
05400         unsigned row = index - col*m_Matrix.nrows;
05401 
05402         if( m_Matrix.isReal )
05403         {
05404           m_Matrix.data[col][row] *= scalar;
05405           return true;
05406         }
05407         else
05408         {
05409           m_Matrix.cplx[col][row].re *= scalar;
05410           return true;
05411         }
05412       }
05413     }
05414     MTX_ERROR_MSG( "Unexpected." );
05415     return false; // Should not be reached!
05416   }
05417   
05418   bool Matrix::RealOnlyAccess::operator/= (double scalar)
05419   {
05420     //if( scalar == 0.0 )
05421     //{
05422     //  StaticMatrixError( "Divide by zero not allowed (real vector element division). Matrix X(10); X[0]/0.0!" );
05423     //  return false; // should not reach this code.
05424     //}
05425       
05426     // This is indexing the matrix as a vector.
05427     const unsigned index = m_row;
05428     if( IndexCheck(index) )
05429     {
05430       if( m_Matrix.ncols == 1 ) // column array
05431       {
05432         if( m_Matrix.isReal )
05433         {
05434           m_Matrix.data[0][index] /= scalar;
05435           return true;
05436         }
05437         else
05438         {
05439           m_Matrix.cplx[0][index].re /= scalar;
05440           return true;
05441         }
05442       }
05443       else if( m_Matrix.nrows == 1 ) // row array
05444       {
05445         if( m_Matrix.isReal )
05446         {
05447           m_Matrix.data[index][0] /= scalar;
05448           return true;
05449         }
05450         else
05451         {
05452           m_Matrix.cplx[index][0].re /= scalar;
05453           return true;
05454         }
05455       }
05456       else
05457       {
05458         // access the matrix as a singular column array
05459         unsigned col = index / m_Matrix.nrows;
05460         unsigned row = index - col*m_Matrix.nrows;
05461 
05462         if( m_Matrix.isReal )
05463         {
05464           m_Matrix.data[col][row] /= scalar;
05465           return true;
05466         }
05467         else
05468         {
05469           m_Matrix.cplx[col][row].re /= scalar;
05470           return true;
05471         }
05472       }
05473     }
05474     MTX_ERROR_MSG( "Unexpected." );
05475     return false; // Should not be reached!
05476   }
05477 
05478 
05479   bool Matrix::Hilbert( const unsigned N )
05480   {
05481     if( !MTX_Hilbert( &m_Matrix, N ) )
05482     {
05483       MTX_ERROR_MSG( "MTX_Hilbert returned FALSE." );
05484       return false;
05485     }
05486     else
05487     {
05488       return true;
05489     }
05490   }
05491 
05492   bool Matrix::Plot( 
05493     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).
05494     const unsigned y_col,              //!< The column index (0toN-1) with the y series data.      
05495     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
05496     const std::string title,           //!< The plot title.
05497     const std::string xlabel,          //!< The x-axis label.
05498     const std::string ylabel,          //!< The y-axis label.
05499     const std::string series_label,    //!< The series label.
05500     const std::string units,           //!< The series data units.      
05501     const bool isXGridOn,             //!< A boolean to indicate if the x grid lines are on.
05502     const bool isYGridOn,             //!< A boolean to indicate if the y grid lines are on.  
05503     const bool includeStats,          //!< A boolean to indicate if statistics info should be included on the plot.  
05504     const unsigned precisionStats,    //!< The number of significant digits in the statistics.
05505     const unsigned plot_height_cm,    //!< The plot height in cm.
05506     const unsigned plot_width_cm      //!< The plot width in cm.
05507     )
05508   {
05509     MTX_structAxisOptions x;
05510     MTX_structAxisOptions y;
05511     std::string slabel_1;
05512     MTX_PLOT_structSeries series;
05513     char buffer[256];
05514 
05515     x.lowerlimit.doNotUseDefault = FALSE;
05516     x.ticksize.doNotUseDefault = FALSE;
05517     x.tickend.doNotUseDefault = FALSE;
05518     x.tickstart.doNotUseDefault = FALSE;
05519     x.upperlimit.doNotUseDefault = FALSE;
05520     
05521     y.lowerlimit.doNotUseDefault = FALSE;
05522     y.ticksize.doNotUseDefault = FALSE;
05523     y.tickend.doNotUseDefault = FALSE;
05524     y.tickstart.doNotUseDefault = FALSE;
05525     y.upperlimit.doNotUseDefault = FALSE;
05526     
05527     if( series_label.compare( "" ) == 0 )
05528     {
05529 #ifndef _CRT_SECURE_NO_DEPRECATE
05530       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col );
05531 #else
05532       sprintf( buffer, "Col %d vs %d", x_col, y_col );
05533 #endif
05534       slabel_1 = buffer;
05535     }
05536     else
05537     {
05538       slabel_1 = series_label;
05539     }    
05540 
05541     series.connected = TRUE;
05542     series.markOutlierData = FALSE;
05543     series.precision = precisionStats;
05544     series.x_col = x_col;
05545     series.y_col = y_col;
05546     series.color = MTX_BLUE;
05547     series.M = &m_Matrix;
05548     series.label = (char*)slabel_1.c_str();
05549     series.units = (char*)units.c_str();
05550     
05551     if( !MTX_Plot(
05552       bmpfilename.c_str(), 
05553       title.c_str(), 
05554       plot_height_cm, 
05555       plot_width_cm, 
05556       includeStats, 
05557       isXGridOn, 
05558       isYGridOn, 
05559       xlabel.c_str(), 
05560       ylabel.c_str(),
05561       x,
05562       y,
05563       &series,
05564       1
05565       ) )
05566     {
05567       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
05568       return false;
05569     }
05570 
05571     return true;
05572   }
05573 
05574   bool Matrix::Plot( 
05575     const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
05576     const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
05577     const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.      
05578     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
05579     const std::string title,           //!< The plot title.
05580     const std::string xlabel,          //!< The x-axis label.
05581     const std::string ylabel,          //!< The y-axis label.
05582     const std::string series_label_1,  //!< The series label.
05583     const std::string units_1,         //!< The series data units.
05584     const std::string series_label_2,  //!< The series label.
05585     const std::string units_2,         //!< The series data units.
05586     const bool isXGridOn,           //!< A boolean to indicate if the x grid lines are on.
05587     const bool isYGridOn,           //!< A boolean to indicate if the y grid lines are on.  
05588     const bool includeStats,        //!< A boolean to indicate if statistics info should be included on the plot.  
05589     const unsigned precisionStats,  //!< The number of significant digits in the statistics.
05590     const unsigned plot_height_cm,  //!< The plot height in cm.
05591     const unsigned plot_width_cm    //!< The plot width in cm.
05592     )
05593   {
05594     MTX_structAxisOptions x;
05595     MTX_structAxisOptions y;
05596     std::string slabel_1;
05597     std::string slabel_2;
05598     char buffer[256];
05599 
05600     MTX_PLOT_structSeries series[2];
05601 
05602     x.lowerlimit.doNotUseDefault = FALSE;
05603     x.ticksize.doNotUseDefault = FALSE;
05604     x.tickend.doNotUseDefault = FALSE;
05605     x.tickstart.doNotUseDefault = FALSE;
05606     x.upperlimit.doNotUseDefault = FALSE;
05607     
05608     y.lowerlimit.doNotUseDefault = FALSE;
05609     y.ticksize.doNotUseDefault = FALSE;
05610     y.tickend.doNotUseDefault = FALSE;
05611     y.tickstart.doNotUseDefault = FALSE;
05612     y.upperlimit.doNotUseDefault = FALSE;
05613 
05614     if( series_label_1.compare( "" ) == 0 )
05615     {
05616 #ifndef _CRT_SECURE_NO_DEPRECATE
05617       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_1 );
05618 #else
05619       sprintf( buffer, "Col %d vs %d", x_col, y_col_1 );
05620 #endif
05621       slabel_1 = buffer;
05622     }
05623     else
05624     {
05625       slabel_1 = series_label_1;
05626     }
05627     if( series_label_2.compare( "" ) == 0 )
05628     {
05629 #ifndef _CRT_SECURE_NO_DEPRECATE
05630       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_2 );
05631 #else
05632       sprintf( buffer, "Col %d vs %d", x_col, y_col_2 );
05633 #endif
05634 
05635       slabel_2 = buffer;
05636     }
05637     else
05638     {
05639       slabel_2 = series_label_2;
05640     }
05641     
05642     series[0].connected = TRUE;
05643     series[0].markOutlierData = FALSE;
05644     series[0].precision = precisionStats;
05645     series[0].x_col = x_col;
05646     series[0].y_col = y_col_1;
05647     series[0].color = MTX_BLUE;
05648     series[0].M = &m_Matrix;
05649     series[0].label = (char*)slabel_1.c_str();
05650     series[0].units = (char*)units_1.c_str();
05651 
05652     series[1].connected = TRUE;
05653     series[1].markOutlierData = FALSE;
05654     series[1].precision = precisionStats;
05655     series[1].x_col = x_col;
05656     series[1].y_col = y_col_2;
05657     series[1].color = MTX_LIMEGREEN;
05658     series[1].M = &m_Matrix;
05659     series[1].label = (char*)slabel_2.c_str();
05660     series[1].units = (char*)units_2.c_str();
05661     
05662     if( !MTX_Plot(
05663       bmpfilename.c_str(), 
05664       title.c_str(), 
05665       plot_height_cm, 
05666       plot_width_cm, 
05667       includeStats, 
05668       isXGridOn, 
05669       isYGridOn, 
05670       xlabel.c_str(), 
05671       ylabel.c_str(),
05672       x,
05673       y,
05674       series,
05675       2
05676       ) )
05677     {
05678       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
05679       return false;
05680     }
05681 
05682     return true;
05683   }
05684 
05685   bool Matrix::Plot( 
05686     const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
05687     const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
05688     const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.
05689     const unsigned y_col_3,            //!< The column index (0toN-1) with the y_3 series data.      
05690     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
05691     const std::string title,           //!< The plot title.
05692     const std::string xlabel,          //!< The x-axis label.
05693     const std::string ylabel,          //!< The y-axis label.
05694     const std::string series_label_1,  //!< The series label.
05695     const std::string units_1,         //!< The series data units.
05696     const std::string series_label_2,  //!< The series label.
05697     const std::string units_2,         //!< The series data units.
05698     const std::string series_label_3,  //!< The series label.
05699     const std::string units_3,         //!< The series data units.            
05700     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
05701     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
05702     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
05703     const unsigned precisionStats, //!< The number of significant digits in the statistics.
05704     const unsigned plot_height_cm, //!< The plot height in cm.
05705     const unsigned plot_width_cm  //!< The plot width in cm.
05706     )
05707   {
05708     MTX_structAxisOptions x;
05709     MTX_structAxisOptions y;
05710     std::string slabel_1;
05711     std::string slabel_2;
05712     std::string slabel_3;
05713     char buffer[256];
05714 
05715     MTX_PLOT_structSeries series[3];
05716 
05717     x.lowerlimit.doNotUseDefault = FALSE;
05718     x.ticksize.doNotUseDefault = FALSE;
05719     x.tickend.doNotUseDefault = FALSE;
05720     x.tickstart.doNotUseDefault = FALSE;
05721     x.upperlimit.doNotUseDefault = FALSE;
05722     
05723     y.lowerlimit.doNotUseDefault = FALSE;
05724     y.ticksize.doNotUseDefault = FALSE;
05725     y.tickend.doNotUseDefault = FALSE;
05726     y.tickstart.doNotUseDefault = FALSE;
05727     y.upperlimit.doNotUseDefault = FALSE;
05728 
05729     if( series_label_1.compare( "" ) == 0 )
05730     {
05731 #ifndef _CRT_SECURE_NO_DEPRECATE
05732       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_1 );
05733 #else
05734       sprintf( buffer, "Col %d vs %d", x_col, y_col_1 );
05735 #endif
05736       slabel_1 = buffer;
05737     }
05738     else
05739     {
05740       slabel_1 = series_label_1;
05741     }
05742     if( series_label_2.compare( "" ) == 0 )
05743     {
05744 #ifndef _CRT_SECURE_NO_DEPRECATE
05745       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_2 );
05746 #else
05747       sprintf( buffer, "Col %d vs %d", x_col, y_col_2 );
05748 #endif
05749 
05750       slabel_2 = buffer;
05751     }
05752     else
05753     {
05754       slabel_2 = series_label_2;
05755     }
05756     if( series_label_3.compare( "" ) == 0 )
05757     {
05758 #ifndef _CRT_SECURE_NO_DEPRECATE
05759       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_3 );
05760 #else
05761       sprintf( buffer, "Col %d vs %d", x_col, y_col_3 );
05762 #endif
05763       slabel_3 = buffer;
05764     }
05765     else
05766     {
05767       slabel_3 = series_label_3;
05768     }
05769     
05770     series[0].connected = TRUE;
05771     series[0].markOutlierData = FALSE;
05772     series[0].precision = precisionStats;
05773     series[0].x_col = x_col;
05774     series[0].y_col = y_col_1;
05775     series[0].color = MTX_BLUE;
05776     series[0].M = &m_Matrix;
05777     series[0].label = (char*)slabel_1.c_str();
05778     series[0].units = (char*)units_1.c_str();
05779 
05780     series[1].connected = TRUE;
05781     series[1].markOutlierData = FALSE;
05782     series[1].precision = precisionStats;
05783     series[1].x_col = x_col;
05784     series[1].y_col = y_col_2;
05785     series[1].color = MTX_LIMEGREEN;
05786     series[1].M = &m_Matrix;
05787     series[1].label = (char*)slabel_2.c_str();
05788     series[1].units = (char*)units_2.c_str();
05789 
05790     series[2].connected = TRUE;
05791     series[2].markOutlierData = FALSE;
05792     series[2].precision = precisionStats;
05793     series[2].x_col = x_col;
05794     series[2].y_col = y_col_3;
05795     series[2].color = MTX_RED;
05796     series[2].M = &m_Matrix;
05797     series[2].label = (char*)slabel_3.c_str();
05798     series[2].units = (char*)units_3.c_str();
05799     
05800     if( !MTX_Plot(
05801       bmpfilename.c_str(), 
05802       title.c_str(), 
05803       plot_height_cm, 
05804       plot_width_cm, 
05805       includeStats, 
05806       isXGridOn, 
05807       isYGridOn, 
05808       xlabel.c_str(), 
05809       ylabel.c_str(),
05810       x,
05811       y,
05812       series,
05813       3
05814       ) )
05815     {
05816       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
05817       return false;
05818     }
05819 
05820     return true;
05821   }
05822 
05823   bool Matrix::Plot( 
05824     const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
05825     const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
05826     const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.
05827     const unsigned y_col_3,            //!< The column index (0toN-1) with the y_3 series data.      
05828     const unsigned y_col_4,            //!< The column index (0toN-1) with the y_4 series data.      
05829     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
05830     const std::string title,           //!< The plot title.
05831     const std::string xlabel,          //!< The x-axis label.
05832     const std::string ylabel,          //!< The y-axis label.
05833     const std::string series_label_1,  //!< The series label.
05834     const std::string units_1,         //!< The series data units.
05835     const std::string series_label_2,  //!< The series label.
05836     const std::string units_2,         //!< The series data units.
05837     const std::string series_label_3,  //!< The series label.
05838     const std::string units_3,         //!< The series data units.            
05839     const std::string series_label_4,  //!< The series label.
05840     const std::string units_4,         //!< The series data units.            
05841     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
05842     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
05843     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
05844     const unsigned precisionStats, //!< The number of significant digits in the statistics.
05845     const unsigned plot_height_cm, //!< The plot height in cm.
05846     const unsigned plot_width_cm  //!< The plot width in cm.
05847     )
05848   {
05849     MTX_structAxisOptions x;
05850     MTX_structAxisOptions y;
05851     std::string slabel_1;
05852     std::string slabel_2;
05853     std::string slabel_3;
05854     std::string slabel_4;
05855     char buffer[256];
05856 
05857     MTX_PLOT_structSeries series[4];
05858 
05859     x.lowerlimit.doNotUseDefault = FALSE;
05860     x.ticksize.doNotUseDefault = FALSE;
05861     x.tickend.doNotUseDefault = FALSE;
05862     x.tickstart.doNotUseDefault = FALSE;
05863     x.upperlimit.doNotUseDefault = FALSE;
05864     
05865     y.lowerlimit.doNotUseDefault = FALSE;
05866     y.ticksize.doNotUseDefault = FALSE;
05867     y.tickend.doNotUseDefault = FALSE;
05868     y.tickstart.doNotUseDefault = FALSE;
05869     y.upperlimit.doNotUseDefault = FALSE;
05870 
05871     if( series_label_1.compare( "" ) == 0 )
05872     {
05873 #ifndef _CRT_SECURE_NO_DEPRECATE
05874       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_1 );
05875 #else
05876       sprintf( buffer, "Col %d vs %d", x_col, y_col_1 );
05877 #endif
05878 
05879       slabel_1 = buffer;
05880     }
05881     else
05882     {
05883       slabel_1 = series_label_1;
05884     }
05885     if( series_label_2.compare( "" ) == 0 )
05886     {
05887 #ifndef _CRT_SECURE_NO_DEPRECATE
05888       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_2 );
05889 #else
05890       sprintf( buffer, "Col %d vs %d", x_col, y_col_2 );
05891 #endif
05892       slabel_2 = buffer;
05893     }
05894     else
05895     {
05896       slabel_2 = series_label_2;
05897     }
05898     if( series_label_3.compare( "" ) == 0 )
05899     {
05900 #ifndef _CRT_SECURE_NO_DEPRECATE
05901       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_3 );
05902 #else
05903       sprintf( buffer, "Col %d vs %d", x_col, y_col_3 );
05904 #endif
05905 
05906       slabel_3 = buffer;
05907     }
05908     else
05909     {
05910       slabel_3 = series_label_3;
05911     }
05912     if( series_label_4.compare( "" ) == 0 )
05913     {
05914 #ifndef _CRT_SECURE_NO_DEPRECATE
05915       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_4 );
05916 #else
05917       sprintf( buffer, "Col %d vs %d", x_col, y_col_4 );
05918 #endif
05919       slabel_4 = buffer;
05920     }
05921     else
05922     {
05923       slabel_4 = series_label_4;
05924     }
05925     
05926     series[0].connected = TRUE;
05927     series[0].markOutlierData = FALSE;
05928     series[0].precision = precisionStats;
05929     series[0].x_col = x_col;
05930     series[0].y_col = y_col_1;
05931     series[0].color = MTX_BLUE;
05932     series[0].M = &m_Matrix;
05933     series[0].label = (char*)slabel_1.c_str();
05934     series[0].units = (char*)units_1.c_str();
05935 
05936     series[1].connected = TRUE;
05937     series[1].markOutlierData = FALSE;
05938     series[1].precision = precisionStats;
05939     series[1].x_col = x_col;
05940     series[1].y_col = y_col_2;
05941     series[1].color = MTX_LIMEGREEN;
05942     series[1].M = &m_Matrix;
05943     series[1].label = (char*)slabel_2.c_str();
05944     series[1].units = (char*)units_2.c_str();
05945 
05946     series[2].connected = TRUE;
05947     series[2].markOutlierData = FALSE;
05948     series[2].precision = precisionStats;
05949     series[2].x_col = x_col;
05950     series[2].y_col = y_col_3;
05951     series[2].color = MTX_RED;
05952     series[2].M = &m_Matrix;
05953     series[2].label = (char*)slabel_3.c_str();
05954     series[2].units = (char*)units_3.c_str();
05955 
05956     series[3].connected = TRUE;
05957     series[3].markOutlierData = FALSE;
05958     series[3].precision = precisionStats;
05959     series[3].x_col = x_col;
05960     series[3].y_col = y_col_4;
05961     series[3].color = MTX_PURPLE;
05962     series[3].M = &m_Matrix;
05963     series[3].label = (char*)slabel_4.c_str();
05964     series[3].units = (char*)units_4.c_str();
05965     
05966     if( !MTX_Plot(
05967       bmpfilename.c_str(), 
05968       title.c_str(), 
05969       plot_height_cm, 
05970       plot_width_cm, 
05971       includeStats, 
05972       isXGridOn, 
05973       isYGridOn, 
05974       xlabel.c_str(), 
05975       ylabel.c_str(),
05976       x,
05977       y,
05978       series,
05979       4
05980       ) )
05981     {
05982       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
05983       return false;
05984     }
05985 
05986     return true;
05987   }
05988 
05989   bool Matrix::Plot( 
05990     const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
05991     const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
05992     const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.
05993     const unsigned y_col_3,            //!< The column index (0toN-1) with the y_3 series data.      
05994     const unsigned y_col_4,            //!< The column index (0toN-1) with the y_4 series data.      
05995     const unsigned y_col_5,            //!< The column index (0toN-1) with the y_5 series data.      
05996     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
05997     const std::string title,           //!< The plot title.
05998     const std::string xlabel,          //!< The x-axis label.
05999     const std::string ylabel,          //!< The y-axis label.
06000     const std::string series_label_1,  //!< The series label.
06001     const std::string units_1,         //!< The series data units.
06002     const std::string series_label_2,  //!< The series label.
06003     const std::string units_2,         //!< The series data units.
06004     const std::string series_label_3,  //!< The series label.
06005     const std::string units_3,         //!< The series data units.            
06006     const std::string series_label_4,  //!< The series label.
06007     const std::string units_4,         //!< The series data units.            
06008     const std::string series_label_5,  //!< The series label.
06009     const std::string units_5,         //!< The series data units.                
06010     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
06011     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
06012     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
06013     const unsigned precisionStats, //!< The number of significant digits in the statistics.
06014     const unsigned plot_height_cm, //!< The plot height in cm.
06015     const unsigned plot_width_cm  //!< The plot width in cm.
06016     )
06017   {
06018     MTX_structAxisOptions x;
06019     MTX_structAxisOptions y;
06020     std::string slabel_1;
06021     std::string slabel_2;
06022     std::string slabel_3;
06023     std::string slabel_4;
06024     std::string slabel_5;
06025     char buffer[256];
06026 
06027     MTX_PLOT_structSeries series[5];
06028 
06029     x.lowerlimit.doNotUseDefault = FALSE;
06030     x.ticksize.doNotUseDefault = FALSE;
06031     x.tickend.doNotUseDefault = FALSE;
06032     x.tickstart.doNotUseDefault = FALSE;
06033     x.upperlimit.doNotUseDefault = FALSE;
06034     
06035     y.lowerlimit.doNotUseDefault = FALSE;
06036     y.ticksize.doNotUseDefault = FALSE;
06037     y.tickend.doNotUseDefault = FALSE;
06038     y.tickstart.doNotUseDefault = FALSE;
06039     y.upperlimit.doNotUseDefault = FALSE;
06040 
06041     if( series_label_1.compare( "" ) == 0 )
06042     {
06043 #ifndef _CRT_SECURE_NO_DEPRECATE
06044       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_1 );
06045 #else
06046       sprintf( buffer, "Col %d vs %d", x_col, y_col_1 );
06047 #endif
06048 
06049       slabel_1 = buffer;
06050     }
06051     else
06052     {
06053       slabel_1 = series_label_1;
06054     }
06055     if( series_label_2.compare( "" ) == 0 )
06056     {
06057 #ifndef _CRT_SECURE_NO_DEPRECATE
06058       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_2 );
06059 #else
06060       sprintf( buffer, "Col %d vs %d", x_col, y_col_2 );
06061 #endif
06062 
06063       slabel_2 = buffer;
06064     }
06065     else
06066     {
06067       slabel_2 = series_label_2;
06068     }
06069     if( series_label_3.compare( "" ) == 0 )
06070     {
06071 #ifndef _CRT_SECURE_NO_DEPRECATE
06072       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_3 );
06073 #else
06074       sprintf( buffer, "Col %d vs %d", x_col, y_col_3 );
06075 #endif
06076       slabel_3 = buffer;
06077     }
06078     else
06079     {
06080       slabel_3 = series_label_3;
06081     }
06082     if( series_label_4.compare( "" ) == 0 )
06083     {
06084 #ifndef _CRT_SECURE_NO_DEPRECATE
06085       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_4 );
06086 #else
06087       sprintf( buffer, "Col %d vs %d", x_col, y_col_4 );
06088 #endif
06089 
06090       slabel_4 = buffer;
06091     }
06092     else
06093     {
06094       slabel_4 = series_label_4;
06095     }
06096     if( series_label_5.compare( "" ) == 0 )
06097     {
06098 #ifndef _CRT_SECURE_NO_DEPRECATE
06099       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_5 );
06100 #else
06101       sprintf( buffer, "Col %d vs %d", x_col, y_col_5 );
06102 #endif
06103       slabel_5 = buffer;
06104     }
06105     else
06106     {
06107       slabel_5 = series_label_5;
06108     }
06109     
06110     series[0].connected = TRUE;
06111     series[0].markOutlierData = FALSE;
06112     series[0].precision = precisionStats;
06113     series[0].x_col = x_col;
06114     series[0].y_col = y_col_1;
06115     series[0].color = MTX_BLUE;
06116     series[0].M = &m_Matrix;
06117     series[0].label = (char*)slabel_1.c_str();
06118     series[0].units = (char*)units_1.c_str();
06119 
06120     series[1].connected = TRUE;
06121     series[1].markOutlierData = FALSE;
06122     series[1].precision = precisionStats;
06123     series[1].x_col = x_col;
06124     series[1].y_col = y_col_2;
06125     series[1].color = MTX_LIMEGREEN;
06126     series[1].M = &m_Matrix;
06127     series[1].label = (char*)slabel_2.c_str();
06128     series[1].units = (char*)units_2.c_str();
06129 
06130     series[2].connected = TRUE;
06131     series[2].markOutlierData = FALSE;
06132     series[2].precision = precisionStats;
06133     series[2].x_col = x_col;
06134     series[2].y_col = y_col_3;
06135     series[2].color = MTX_RED;
06136     series[2].M = &m_Matrix;
06137     series[2].label = (char*)slabel_3.c_str();
06138     series[2].units = (char*)units_3.c_str();
06139 
06140     series[3].connected = TRUE;
06141     series[3].markOutlierData = FALSE;
06142     series[3].precision = precisionStats;
06143     series[3].x_col = x_col;
06144     series[3].y_col = y_col_4;
06145     series[3].color = MTX_PURPLE;
06146     series[3].M = &m_Matrix;
06147     series[3].label = (char*)slabel_4.c_str();
06148     series[3].units = (char*)units_4.c_str();
06149 
06150     series[4].connected = TRUE;
06151     series[4].markOutlierData = FALSE;
06152     series[4].precision = precisionStats;
06153     series[4].x_col = x_col;
06154     series[4].y_col = y_col_5;
06155     series[4].color = MTX_ORANGE;
06156     series[4].M = &m_Matrix;
06157     series[4].label = (char*)slabel_5.c_str();
06158     series[4].units = (char*)units_5.c_str();
06159     
06160     if( !MTX_Plot(
06161       bmpfilename.c_str(), 
06162       title.c_str(), 
06163       plot_height_cm, 
06164       plot_width_cm, 
06165       includeStats, 
06166       isXGridOn, 
06167       isYGridOn, 
06168       xlabel.c_str(), 
06169       ylabel.c_str(),
06170       x,
06171       y,
06172       series,
06173       5
06174       ) )
06175     {
06176       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
06177       return false;
06178     }
06179     return true;
06180   }
06181 
06182   bool Matrix::Plot( 
06183     const unsigned x_col,              //!< The column index (0toN-1) with the x series data.
06184     const unsigned y_col_1,            //!< The column index (0toN-1) with the y_1 series data.
06185     const unsigned y_col_2,            //!< The column index (0toN-1) with the y_2 series data.
06186     const unsigned y_col_3,            //!< The column index (0toN-1) with the y_3 series data.      
06187     const unsigned y_col_4,            //!< The column index (0toN-1) with the y_4 series data.      
06188     const unsigned y_col_5,            //!< The column index (0toN-1) with the y_5 series data.      
06189     const unsigned y_col_6,            //!< The column index (0toN-1) with the y_6 series data.      
06190     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
06191     const std::string title,           //!< The plot title.
06192     const std::string xlabel,          //!< The x-axis label.
06193     const std::string ylabel,          //!< The y-axis label.
06194     const std::string series_label_1,  //!< The series label.
06195     const std::string units_1,         //!< The series data units.
06196     const std::string series_label_2,  //!< The series label.
06197     const std::string units_2,         //!< The series data units.
06198     const std::string series_label_3,  //!< The series label.
06199     const std::string units_3,         //!< The series data units.            
06200     const std::string series_label_4,  //!< The series label.
06201     const std::string units_4,         //!< The series data units.            
06202     const std::string series_label_5,  //!< The series label.
06203     const std::string units_5,         //!< The series data units.                
06204     const std::string series_label_6,  //!< The series label.
06205     const std::string units_6,         //!< The series data units.                
06206     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
06207     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
06208     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
06209     const unsigned precisionStats, //!< The number of significant digits in the statistics.
06210     const unsigned plot_height_cm, //!< The plot height in cm.
06211     const unsigned plot_width_cm  //!< The plot width in cm.
06212     )
06213   {
06214     MTX_structAxisOptions x;
06215     MTX_structAxisOptions y;
06216     std::string slabel_1;
06217     std::string slabel_2;
06218     std::string slabel_3;
06219     std::string slabel_4;
06220     std::string slabel_5;
06221     std::string slabel_6;
06222     char buffer[256];
06223 
06224     MTX_PLOT_structSeries series[6];
06225 
06226     x.lowerlimit.doNotUseDefault = FALSE;
06227     x.ticksize.doNotUseDefault = FALSE;
06228     x.tickend.doNotUseDefault = FALSE;
06229     x.tickstart.doNotUseDefault = FALSE;
06230     x.upperlimit.doNotUseDefault = FALSE;
06231     
06232     y.lowerlimit.doNotUseDefault = FALSE;
06233     y.ticksize.doNotUseDefault = FALSE;
06234     y.tickend.doNotUseDefault = FALSE;
06235     y.tickstart.doNotUseDefault = FALSE;
06236     y.upperlimit.doNotUseDefault = FALSE;
06237 
06238     if( series_label_1.compare( "" ) == 0 )
06239     {
06240 #ifndef _CRT_SECURE_NO_DEPRECATE
06241       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_1 );
06242 #else
06243       sprintf( buffer, "Col %d vs %d", x_col, y_col_1 );
06244 #endif
06245       slabel_1 = buffer;
06246     }
06247     else
06248     {
06249       slabel_1 = series_label_1;
06250     }
06251     if( series_label_2.compare( "" ) == 0 )
06252     {
06253 #ifndef _CRT_SECURE_NO_DEPRECATE
06254       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_2 );
06255 #else
06256       sprintf( buffer, "Col %d vs %d", x_col, y_col_2 );
06257 #endif
06258       slabel_2 = buffer;
06259     }
06260     else
06261     {
06262       slabel_2 = series_label_2;
06263     }
06264     if( series_label_3.compare( "" ) == 0 )
06265     {
06266 #ifndef _CRT_SECURE_NO_DEPRECATE
06267       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_3 );
06268 #else
06269       sprintf( buffer, "Col %d vs %d", x_col, y_col_3 );
06270 #endif
06271       slabel_3 = buffer;
06272     }
06273     else
06274     {
06275       slabel_3 = series_label_3;
06276     }
06277     if( series_label_4.compare( "" ) == 0 )
06278     {
06279 #ifndef _CRT_SECURE_NO_DEPRECATE
06280       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_4 );
06281 #else
06282       sprintf( buffer, "Col %d vs %d", x_col, y_col_4 );
06283 #endif
06284       slabel_4 = buffer;
06285     }
06286     else
06287     {
06288       slabel_4 = series_label_4;
06289     }
06290     if( series_label_5.compare( "" ) == 0 )
06291     {
06292 #ifndef _CRT_SECURE_NO_DEPRECATE
06293       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_5 );
06294 #else
06295       sprintf( buffer, "Col %d vs %d", x_col, y_col_5 );
06296 #endif
06297       slabel_5 = buffer;
06298     }
06299     else
06300     {
06301       slabel_5 = series_label_5;
06302     }
06303     if( series_label_6.compare( "" ) == 0 )
06304     {
06305 #ifndef _CRT_SECURE_NO_DEPRECATE
06306       sprintf_s ( buffer, 256, "Col %d vs %d", x_col, y_col_6 );
06307 #else
06308       sprintf( buffer, "Col %d vs %d", x_col, y_col_6 );
06309 #endif
06310       slabel_6 = buffer;
06311     }
06312     else
06313     {
06314       slabel_6 = series_label_6;
06315     }
06316     
06317     series[0].connected = TRUE;
06318     series[0].markOutlierData = FALSE;
06319     series[0].precision = precisionStats;
06320     series[0].x_col = x_col;
06321     series[0].y_col = y_col_1;
06322     series[0].color = MTX_BLUE;
06323     series[0].M = &m_Matrix;
06324     series[0].label = (char*)slabel_1.c_str();
06325     series[0].units = (char*)units_1.c_str();
06326 
06327     series[1].connected = TRUE;
06328     series[1].markOutlierData = FALSE;
06329     series[1].precision = precisionStats;
06330     series[1].x_col = x_col;
06331     series[1].y_col = y_col_2;
06332     series[1].color = MTX_LIMEGREEN;
06333     series[1].M = &m_Matrix;
06334     series[1].label = (char*)slabel_2.c_str();
06335     series[1].units = (char*)units_2.c_str();
06336 
06337     series[2].connected = TRUE;
06338     series[2].markOutlierData = FALSE;
06339     series[2].precision = precisionStats;
06340     series[2].x_col = x_col;
06341     series[2].y_col = y_col_3;
06342     series[2].color = MTX_RED;
06343     series[2].M = &m_Matrix;
06344     series[2].label = (char*)slabel_3.c_str();
06345     series[2].units = (char*)units_3.c_str();
06346 
06347     series[3].connected = TRUE;
06348     series[3].markOutlierData = FALSE;
06349     series[3].precision = precisionStats;
06350     series[3].x_col = x_col;
06351     series[3].y_col = y_col_4;
06352     series[3].color = MTX_PURPLE;
06353     series[3].M = &m_Matrix;
06354     series[3].label = (char*)slabel_4.c_str();
06355     series[3].units = (char*)units_4.c_str();
06356 
06357     series[4].connected = TRUE;
06358     series[4].markOutlierData = FALSE;
06359     series[4].precision = precisionStats;
06360     series[4].x_col = x_col;
06361     series[4].y_col = y_col_5;
06362     series[4].color = MTX_ORANGE;
06363     series[4].M = &m_Matrix;
06364     series[4].label = (char*)slabel_5.c_str();
06365     series[4].units = (char*)units_5.c_str();
06366 
06367     series[5].connected = TRUE;
06368     series[5].markOutlierData = FALSE;
06369     series[5].precision = precisionStats;
06370     series[5].x_col = x_col;
06371     series[5].y_col = y_col_6;
06372     series[5].color = MTX_GREEN;
06373     series[5].M = &m_Matrix;
06374     series[5].label = (char*)slabel_6.c_str();
06375     series[5].units = (char*)units_6.c_str();
06376     
06377     if( !MTX_Plot(
06378       bmpfilename.c_str(), 
06379       title.c_str(), 
06380       plot_height_cm, 
06381       plot_width_cm, 
06382       includeStats, 
06383       isXGridOn, 
06384       isYGridOn, 
06385       xlabel.c_str(), 
06386       ylabel.c_str(),
06387       x,
06388       y,
06389       series,
06390       6
06391       ) )
06392     {
06393       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
06394       return false;
06395     }
06396 
06397     return true;
06398   }
06399 
06400   //friend
06401   bool Plot(
06402     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
06403     const std::string title,           //!< The plot title.
06404     const std::string xlabel,          //!< The x-axis label.
06405     const std::string ylabel,          //!< The y-axis label.
06406     Matrix &X,                         //!< The x series must be [Nx1].
06407     Matrix &Y,                         //!< The x series must be [Nx1].
06408     const std::string series_label,    //!< The series label.
06409     const std::string units,           //!< The series units.
06410     const bool isConnected,     //!< Are the data points connected.
06411     const MTX_enumColor color,  //!< The color of the data points/line.
06412     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
06413     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
06414     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
06415     const unsigned precisionStats, //!< The number of significant digits in the statistics.
06416     const unsigned plot_height_cm, //!< The plot height in cm.
06417     const unsigned plot_width_cm   //!< The plot width in cm.
06418     )
06419   {
06420     MTX_structAxisOptions x;
06421     MTX_structAxisOptions y;
06422 
06423     MTX_PLOT_structSeries series;
06424 
06425     Matrix M;
06426 
06427     x.lowerlimit.doNotUseDefault = FALSE;
06428     x.ticksize.doNotUseDefault = FALSE;
06429     x.tickend.doNotUseDefault = FALSE;
06430     x.tickstart.doNotUseDefault = FALSE;
06431     x.upperlimit.doNotUseDefault = FALSE;
06432     
06433     y.lowerlimit.doNotUseDefault = FALSE;
06434     y.ticksize.doNotUseDefault = FALSE;
06435     y.tickend.doNotUseDefault = FALSE;
06436     y.tickstart.doNotUseDefault = FALSE;
06437     y.upperlimit.doNotUseDefault = FALSE;
06438     
06439     if( X.ncols() > 1 && X.nrows() == 1 )
06440     {
06441       M = X.Transpose();
06442     }
06443     else
06444     {
06445       M = X;
06446     }
06447     if( Y.ncols() > 1 && Y.nrows() == 1 )
06448     {
06449       if( !M.Concatonate( Y.Transpose() ) )
06450         return false;
06451     }
06452     else
06453     {
06454       if( !M.Concatonate( Y ) )
06455         return false;
06456     }
06457 
06458     series.connected = isConnected;
06459     series.markOutlierData = FALSE;
06460     series.precision = precisionStats;
06461     series.x_col = 0;
06462     series.y_col = 1;
06463     series.color = color;
06464     series.M = &(M.m_Matrix);
06465     series.label = (char*)series_label.c_str();
06466     series.units = (char*)units.c_str();
06467     
06468     if( !MTX_Plot(
06469       bmpfilename.c_str(), 
06470       title.c_str(), 
06471       plot_height_cm, 
06472       plot_width_cm, 
06473       includeStats, 
06474       isXGridOn, 
06475       isYGridOn, 
06476       xlabel.c_str(), 
06477       ylabel.c_str(),
06478       x,
06479       y,
06480       &series,
06481       1
06482       ) )
06483     {
06484       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
06485       return false;
06486     }
06487 
06488     return true;
06489   }
06490 
06491 
06492   bool Plot(
06493     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
06494     const std::string title,           //!< The plot title.
06495     const std::string xlabel,          //!< The x-axis label.
06496     const std::string ylabel,          //!< The y-axis label.
06497     Matrix &X_1,                         //!< The x series must be [Nx1].
06498     Matrix &Y_1,                         //!< The x series must be [Nx1].
06499     const std::string series_label_1,    //!< The series label.
06500     const std::string units_1,           //!< The series units.
06501     Matrix &X_2,                         //!< The x series must be [Nx1].
06502     Matrix &Y_2,                         //!< The x series must be [Nx1].
06503     const std::string series_label_2,    //!< The series label.
06504     const std::string units_2,           //!< The series units.
06505     const bool isConnected_1,     //!< Are the data points connected.
06506     const MTX_enumColor color_1,  //!< The color of the data points/line.
06507     const bool isConnected_2,     //!< Are the data points connected.
06508     const MTX_enumColor color_2,  //!< The color of the data points/line.    
06509     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
06510     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
06511     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
06512     const unsigned precisionStats, //!< The number of significant digits in the statistics.
06513     const unsigned plot_height_cm, //!< The plot height in cm.
06514     const unsigned plot_width_cm  //!< The plot width in cm.
06515     )
06516   {
06517     MTX_structAxisOptions x;
06518     MTX_structAxisOptions y;
06519 
06520     MTX_PLOT_structSeries series[2];
06521 
06522     Matrix M1;
06523     Matrix M2;
06524 
06525     x.lowerlimit.doNotUseDefault = FALSE;
06526     x.ticksize.doNotUseDefault = FALSE;
06527     x.tickend.doNotUseDefault = FALSE;
06528     x.tickstart.doNotUseDefault = FALSE;
06529     x.upperlimit.doNotUseDefault = FALSE;
06530     
06531     y.lowerlimit.doNotUseDefault = FALSE;
06532     y.ticksize.doNotUseDefault = FALSE;
06533     y.tickend.doNotUseDefault = FALSE;
06534     y.tickstart.doNotUseDefault = FALSE;
06535     y.upperlimit.doNotUseDefault = FALSE;
06536 
06537     if( X_1.ncols() > 1 && X_1.nrows() == 1 )
06538     {
06539       M1 = X_1.Transpose();
06540     }
06541     else
06542     {
06543       M1 = X_1;
06544     }
06545     if( Y_1.ncols() > 1 && Y_1.nrows() == 1 )
06546     {
06547       if( !M1.Concatonate( Y_1.Transpose() ) )
06548         return false;
06549     }
06550     else
06551     {
06552       if( !M1.Concatonate( Y_1 ) )
06553         return false;
06554     }
06555 
06556     if( X_2.ncols() > 2 && X_2.nrows() == 2 )
06557     {
06558       M2 = X_2.Transpose();
06559     }
06560     else
06561     {
06562       M2 = X_2;
06563     }
06564     if( Y_2.ncols() > 2 && Y_2.nrows() == 2 )
06565     {
06566       if( !M2.Concatonate( Y_2.Transpose() ) )
06567         return false;
06568     }
06569     else
06570     {
06571       if( !M2.Concatonate( Y_2 ) )
06572         return false;
06573     }
06574 
06575     series[0].connected = isConnected_1;
06576     series[0].markOutlierData = FALSE;
06577     series[0].precision = precisionStats;
06578     series[0].x_col = 0;
06579     series[0].y_col = 1;
06580     series[0].color = color_1;
06581     series[0].M = &(M1.m_Matrix);
06582     series[0].label = (char*)series_label_1.c_str();
06583     series[0].units = (char*)units_1.c_str();
06584 
06585     series[1].connected = isConnected_2;
06586     series[1].markOutlierData = FALSE;
06587     series[1].precision = precisionStats;
06588     series[1].x_col = 0;
06589     series[1].y_col = 1;
06590     series[1].color = color_2;
06591     series[1].M = &(M2.m_Matrix);
06592     series[1].label = (char*)series_label_2.c_str();
06593     series[1].units = (char*)units_2.c_str();
06594     
06595     if( !MTX_Plot(
06596       bmpfilename.c_str(), 
06597       title.c_str(), 
06598       plot_height_cm, 
06599       plot_width_cm, 
06600       includeStats, 
06601       isXGridOn, 
06602       isYGridOn, 
06603       xlabel.c_str(), 
06604       ylabel.c_str(),
06605       x,
06606       y,
06607       series,
06608       2
06609       ) )
06610     {
06611       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
06612       return false;
06613     }
06614 
06615     return true;
06616   }
06617 
06618   bool Plot(
06619     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
06620     const std::string title,           //!< The plot title.
06621     const std::string xlabel,          //!< The x-axis label.
06622     const std::string ylabel,          //!< The y-axis label.
06623     Matrix &X_1,                         //!< The x series must be [Nx1].
06624     Matrix &Y_1,                         //!< The x series must be [Nx1].
06625     const std::string series_label_1,    //!< The series label.
06626     const std::string units_1,           //!< The series units.
06627     Matrix &X_2,                         //!< The x series must be [Nx1].
06628     Matrix &Y_2,                         //!< The x series must be [Nx1].
06629     const std::string series_label_2,    //!< The series label.
06630     const std::string units_2,           //!< The series units.
06631     Matrix &X_3,                         //!< The x series must be [Nx1].
06632     Matrix &Y_3,                         //!< The x series must be [Nx1].
06633     const std::string series_label_3,    //!< The series label.
06634     const std::string units_3,           //!< The series units.
06635     const bool isConnected_1,     //!< Are the data points connected.
06636     const MTX_enumColor color_1,  //!< The color of the data points/line.
06637     const bool isConnected_2,     //!< Are the data points connected.
06638     const MTX_enumColor color_2,  //!< The color of the data points/line.    
06639     const bool isConnected_3,     //!< Are the data points connected.
06640     const MTX_enumColor color_3,  //!< The color of the data points/line.        
06641     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
06642     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
06643     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
06644     const unsigned precisionStats, //!< The number of significant digits in the statistics.
06645     const unsigned plot_height_cm, //!< The plot height in cm.
06646     const unsigned plot_width_cm   //!< The plot width in cm.
06647     )
06648   {
06649     MTX_structAxisOptions x;
06650     MTX_structAxisOptions y;
06651 
06652     MTX_PLOT_structSeries series[3];
06653 
06654     Matrix M1;
06655     Matrix M2;
06656     Matrix M3;
06657 
06658     x.lowerlimit.doNotUseDefault = FALSE;
06659     x.ticksize.doNotUseDefault = FALSE;
06660     x.tickend.doNotUseDefault = FALSE;
06661     x.tickstart.doNotUseDefault = FALSE;
06662     x.upperlimit.doNotUseDefault = FALSE;
06663     
06664     y.lowerlimit.doNotUseDefault = FALSE;
06665     y.ticksize.doNotUseDefault = FALSE;
06666     y.tickend.doNotUseDefault = FALSE;
06667     y.tickstart.doNotUseDefault = FALSE;
06668     y.upperlimit.doNotUseDefault = FALSE;
06669     
06670     if( X_1.ncols() > 1 && X_1.nrows() == 1 )
06671     {
06672       M1 = X_1.Transpose();
06673     }
06674     else
06675     {
06676       M1 = X_1;
06677     }
06678     if( Y_1.ncols() > 1 && Y_1.nrows() == 1 )
06679     {
06680       if( !M1.Concatonate( Y_1.Transpose() ) )
06681         return false;
06682     }
06683     else
06684     {
06685       if( !M1.Concatonate( Y_1 ) )
06686         return false;
06687     }
06688 
06689     if( X_2.ncols() > 2 && X_2.nrows() == 2 )
06690     {
06691       M2 = X_2.Transpose();
06692     }
06693     else
06694     {
06695       M2 = X_2;
06696     }
06697     if( Y_2.ncols() > 2 && Y_2.nrows() == 2 )
06698     {
06699       if( !M2.Concatonate( Y_2.Transpose() ) )
06700         return false;
06701     }
06702     else
06703     {
06704       if( !M2.Concatonate( Y_2 ) )
06705         return false;
06706     }
06707 
06708     if( X_3.ncols() > 3 && X_3.nrows() == 3 )
06709     {
06710       M3 = X_3.Transpose();
06711     }
06712     else
06713     {
06714       M3 = X_3;
06715     }
06716     if( Y_3.ncols() > 3 && Y_3.nrows() == 3 )
06717     {
06718       if( !M3.Concatonate( Y_3.Transpose() ) )
06719         return false;
06720     }
06721     else
06722     {
06723       if( !M3.Concatonate( Y_3 ) )
06724         return false;
06725     }
06726 
06727     series[0].connected = isConnected_1;
06728     series[0].markOutlierData = FALSE;
06729     series[0].precision = precisionStats;
06730     series[0].x_col = 0;
06731     series[0].y_col = 1;
06732     series[0].color = color_1;
06733     series[0].M = &(M1.m_Matrix);
06734     series[0].label = (char*)series_label_1.c_str();
06735     series[0].units = (char*)units_1.c_str();
06736 
06737     series[1].connected = isConnected_2;
06738     series[1].markOutlierData = FALSE;
06739     series[1].precision = precisionStats;
06740     series[1].x_col = 0;
06741     series[1].y_col = 1;
06742     series[1].color = color_2;
06743     series[1].M = &(M2.m_Matrix);
06744     series[1].label = (char*)series_label_2.c_str();
06745     series[1].units = (char*)units_2.c_str();
06746 
06747     series[2].connected = isConnected_3;
06748     series[2].markOutlierData = FALSE;
06749     series[2].precision = precisionStats;
06750     series[2].x_col = 0;
06751     series[2].y_col = 1;
06752     series[2].color = color_3;
06753     series[2].M = &(M3.m_Matrix);
06754     series[2].label = (char*)series_label_3.c_str();
06755     series[2].units = (char*)units_3.c_str();
06756     
06757     if( !MTX_Plot(
06758       bmpfilename.c_str(), 
06759       title.c_str(), 
06760       plot_height_cm, 
06761       plot_width_cm, 
06762       includeStats, 
06763       isXGridOn, 
06764       isYGridOn, 
06765       xlabel.c_str(), 
06766       ylabel.c_str(),
06767       x,
06768       y,
06769       series,
06770       3
06771       ) )
06772     {
06773       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
06774       return false;
06775     }
06776 
06777     return true;
06778   }
06779 
06780   bool Plot(
06781     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
06782     const std::string title,           //!< The plot title.
06783     const std::string xlabel,          //!< The x-axis label.
06784     const std::string ylabel,          //!< The y-axis label.
06785     Matrix &X_1,                         //!< The x series must be [Nx1].
06786     Matrix &Y_1,                         //!< The x series must be [Nx1].
06787     const std::string series_label_1,    //!< The series label.
06788     const std::string units_1,           //!< The series units.
06789     Matrix &X_2,                         //!< The x series must be [Nx1].
06790     Matrix &Y_2,                         //!< The x series must be [Nx1].
06791     const std::string series_label_2,    //!< The series label.
06792     const std::string units_2,           //!< The series units.
06793     Matrix &X_3,                         //!< The x series must be [Nx1].
06794     Matrix &Y_3,                         //!< The x series must be [Nx1].
06795     const std::string series_label_3,    //!< The series label.
06796     const std::string units_3,           //!< The series units.
06797     Matrix &X_4,                         //!< The x series must be [Nx1].
06798     Matrix &Y_4,                         //!< The x series must be [Nx1].
06799     const std::string series_label_4,    //!< The series label.
06800     const std::string units_4,           //!< The series units.
06801     const bool isConnected_1,     //!< Are the data points connected.
06802     const MTX_enumColor color_1,  //!< The color of the data points/line.
06803     const bool isConnected_2,     //!< Are the data points connected.
06804     const MTX_enumColor color_2,  //!< The color of the data points/line.    
06805     const bool isConnected_3,     //!< Are the data points connected.
06806     const MTX_enumColor color_3,  //!< The color of the data points/line.        
06807     const bool isConnected_4,     //!< Are the data points connected.
06808     const MTX_enumColor color_4,  //!< The color of the data points/line.        
06809     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
06810     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
06811     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
06812     const unsigned precisionStats, //!< The number of significant digits in the statistics.
06813     const unsigned plot_height_cm, //!< The plot height in cm.
06814     const unsigned plot_width_cm   //!< The plot width in cm.
06815     )
06816   {
06817     MTX_structAxisOptions x;
06818     MTX_structAxisOptions y;
06819 
06820     MTX_PLOT_structSeries series[4];
06821 
06822     Matrix M1;
06823     Matrix M2;
06824     Matrix M3;
06825     Matrix M4;
06826 
06827     x.lowerlimit.doNotUseDefault = FALSE;
06828     x.ticksize.doNotUseDefault = FALSE;
06829     x.tickend.doNotUseDefault = FALSE;
06830     x.tickstart.doNotUseDefault = FALSE;
06831     x.upperlimit.doNotUseDefault = FALSE;
06832     
06833     y.lowerlimit.doNotUseDefault = FALSE;
06834     y.ticksize.doNotUseDefault = FALSE;
06835     y.tickend.doNotUseDefault = FALSE;
06836     y.tickstart.doNotUseDefault = FALSE;
06837     y.upperlimit.doNotUseDefault = FALSE;
06838     
06839     if( X_1.ncols() > 1 && X_1.nrows() == 1 )
06840     {
06841       M1 = X_1.Transpose();
06842     }
06843     else
06844     {
06845       M1 = X_1;
06846     }
06847     if( Y_1.ncols() > 1 && Y_1.nrows() == 1 )
06848     {
06849       if( !M1.Concatonate( Y_1.Transpose() ) )
06850         return false;
06851     }
06852     else
06853     {
06854       if( !M1.Concatonate( Y_1 ) )
06855         return false;
06856     }
06857 
06858     if( X_2.ncols() > 2 && X_2.nrows() == 2 )
06859     {
06860       M2 = X_2.Transpose();
06861     }
06862     else
06863     {
06864       M2 = X_2;
06865     }
06866     if( Y_2.ncols() > 2 && Y_2.nrows() == 2 )
06867     {
06868       if( !M2.Concatonate( Y_2.Transpose() ) )
06869         return false;
06870     }
06871     else
06872     {
06873       if( !M2.Concatonate( Y_2 ) )
06874         return false;
06875     }
06876 
06877     if( X_3.ncols() > 3 && X_3.nrows() == 3 )
06878     {
06879       M3 = X_3.Transpose();
06880     }
06881     else
06882     {
06883       M3 = X_3;
06884     }
06885     if( Y_3.ncols() > 3 && Y_3.nrows() == 3 )
06886     {
06887       if( !M3.Concatonate( Y_3.Transpose() ) )
06888         return false;
06889     }
06890     else
06891     {
06892       if( !M3.Concatonate( Y_3 ) )
06893         return false;
06894     }
06895 
06896     if( X_4.ncols() > 4 && X_4.nrows() == 4 )
06897     {
06898       M4 = X_4.Transpose();
06899     }
06900     else
06901     {
06902       M4 = X_4;
06903     }
06904     if( Y_4.ncols() > 4 && Y_4.nrows() == 4 )
06905     {
06906       if( !M4.Concatonate( Y_4.Transpose() ) )
06907         return false;
06908     }
06909     else
06910     {
06911       if( !M4.Concatonate( Y_4 ) )
06912         return false;
06913     }
06914 
06915     series[0].connected = isConnected_1;
06916     series[0].markOutlierData = FALSE;
06917     series[0].precision = precisionStats;
06918     series[0].x_col = 0;
06919     series[0].y_col = 1;
06920     series[0].color = color_1;
06921     series[0].M = &(M1.m_Matrix);
06922     series[0].label = (char*)series_label_1.c_str();
06923     series[0].units = (char*)units_1.c_str();
06924 
06925     series[1].connected = isConnected_2;
06926     series[1].markOutlierData = FALSE;
06927     series[1].precision = precisionStats;
06928     series[1].x_col = 0;
06929     series[1].y_col = 1;
06930     series[1].color = color_2;
06931     series[1].M = &(M2.m_Matrix);
06932     series[1].label = (char*)series_label_2.c_str();
06933     series[1].units = (char*)units_2.c_str();
06934 
06935     series[2].connected = isConnected_3;
06936     series[2].markOutlierData = FALSE;
06937     series[2].precision = precisionStats;
06938     series[2].x_col = 0;
06939     series[2].y_col = 1;
06940     series[2].color = color_3;
06941     series[2].M = &(M3.m_Matrix);
06942     series[2].label = (char*)series_label_3.c_str();
06943     series[2].units = (char*)units_3.c_str();
06944 
06945     series[3].connected = isConnected_4;
06946     series[3].markOutlierData = FALSE;
06947     series[3].precision = precisionStats;
06948     series[3].x_col = 0;
06949     series[3].y_col = 1;
06950     series[3].color = color_4;
06951     series[3].M = &(M4.m_Matrix);
06952     series[3].label = (char*)series_label_4.c_str();
06953     series[3].units = (char*)units_4.c_str();
06954     
06955     if( !MTX_Plot(
06956       bmpfilename.c_str(), 
06957       title.c_str(), 
06958       plot_height_cm, 
06959       plot_width_cm, 
06960       includeStats, 
06961       isXGridOn, 
06962       isYGridOn, 
06963       xlabel.c_str(), 
06964       ylabel.c_str(),
06965       x,
06966       y,
06967       series,
06968       4
06969       ) )
06970     {
06971       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
06972       return false;
06973     }
06974 
06975     return true;
06976   }
06977 
06978   bool Plot(
06979     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
06980     const std::string title,           //!< The plot title.
06981     const std::string xlabel,          //!< The x-axis label.
06982     const std::string ylabel,          //!< The y-axis label.
06983     Matrix &X_1,                         //!< The x series must be [Nx1].
06984     Matrix &Y_1,                         //!< The x series must be [Nx1].
06985     const std::string series_label_1,    //!< The series label.
06986     const std::string units_1,           //!< The series units.
06987     Matrix &X_2,                         //!< The x series must be [Nx1].
06988     Matrix &Y_2,                         //!< The x series must be [Nx1].
06989     const std::string series_label_2,    //!< The series label.
06990     const std::string units_2,           //!< The series units.
06991     Matrix &X_3,                         //!< The x series must be [Nx1].
06992     Matrix &Y_3,                         //!< The x series must be [Nx1].
06993     const std::string series_label_3,    //!< The series label.
06994     const std::string units_3,           //!< The series units.
06995     Matrix &X_4,                         //!< The x series must be [Nx1].
06996     Matrix &Y_4,                         //!< The x series must be [Nx1].
06997     const std::string series_label_4,    //!< The series label.
06998     const std::string units_4,           //!< The series units.
06999     Matrix &X_5,                         //!< The x series must be [Nx1].
07000     Matrix &Y_5,                         //!< The x series must be [Nx1].
07001     const std::string series_label_5,    //!< The series label.
07002     const std::string units_5,           //!< The series units.
07003     const bool isConnected_1,     //!< Are the data points connected.
07004     const MTX_enumColor color_1,  //!< The color of the data points/line.
07005     const bool isConnected_2,     //!< Are the data points connected.
07006     const MTX_enumColor color_2,  //!< The color of the data points/line.    
07007     const bool isConnected_3,     //!< Are the data points connected.
07008     const MTX_enumColor color_3,  //!< The color of the data points/line.        
07009     const bool isConnected_4,     //!< Are the data points connected.
07010     const MTX_enumColor color_4,  //!< The color of the data points/line.        
07011     const bool isConnected_5,     //!< Are the data points connected.
07012     const MTX_enumColor color_5,  //!< The color of the data points/line.        
07013     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
07014     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
07015     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
07016     const unsigned precisionStats, //!< The number of significant digits in the statistics.
07017     const unsigned plot_height_cm, //!< The plot height in cm.
07018     const unsigned plot_width_cm   //!< The plot width in cm.
07019     )
07020   {
07021     MTX_structAxisOptions x;
07022     MTX_structAxisOptions y;
07023 
07024     MTX_PLOT_structSeries series[5];
07025 
07026     Matrix M1;
07027     Matrix M2;
07028     Matrix M3;
07029     Matrix M4;
07030     Matrix M5;
07031 
07032     x.lowerlimit.doNotUseDefault = FALSE;
07033     x.ticksize.doNotUseDefault = FALSE;
07034     x.tickend.doNotUseDefault = FALSE;
07035     x.tickstart.doNotUseDefault = FALSE;
07036     x.upperlimit.doNotUseDefault = FALSE;
07037     
07038     y.lowerlimit.doNotUseDefault = FALSE;
07039     y.ticksize.doNotUseDefault = FALSE;
07040     y.tickend.doNotUseDefault = FALSE;
07041     y.tickstart.doNotUseDefault = FALSE;
07042     y.upperlimit.doNotUseDefault = FALSE;
07043     
07044     if( X_1.ncols() > 1 && X_1.nrows() == 1 )
07045     {
07046       M1 = X_1.Transpose();
07047     }
07048     else
07049     {
07050       M1 = X_1;
07051     }
07052     if( Y_1.ncols() > 1 && Y_1.nrows() == 1 )
07053     {
07054       if( !M1.Concatonate( Y_1.Transpose() ) )
07055         return false;
07056     }
07057     else
07058     {
07059       if( !M1.Concatonate( Y_1 ) )
07060         return false;
07061     }
07062 
07063     if( X_2.ncols() > 2 && X_2.nrows() == 2 )
07064     {
07065       M2 = X_2.Transpose();
07066     }
07067     else
07068     {
07069       M2 = X_2;
07070     }
07071     if( Y_2.ncols() > 2 && Y_2.nrows() == 2 )
07072     {
07073       if( !M2.Concatonate( Y_2.Transpose() ) )
07074         return false;
07075     }
07076     else
07077     {
07078       if( !M2.Concatonate( Y_2 ) )
07079         return false;
07080     }
07081 
07082     if( X_3.ncols() > 3 && X_3.nrows() == 3 )
07083     {
07084       M3 = X_3.Transpose();
07085     }
07086     else
07087     {
07088       M3 = X_3;
07089     }
07090     if( Y_3.ncols() > 3 && Y_3.nrows() == 3 )
07091     {
07092       if( !M3.Concatonate( Y_3.Transpose() ) )
07093         return false;
07094     }
07095     else
07096     {
07097       if( !M3.Concatonate( Y_3 ) )
07098         return false;
07099     }
07100 
07101     if( X_4.ncols() > 4 && X_4.nrows() == 4 )
07102     {
07103       M4 = X_4.Transpose();
07104     }
07105     else
07106     {
07107       M4 = X_4;
07108     }
07109     if( Y_4.ncols() > 4 && Y_4.nrows() == 4 )
07110     {
07111       if( !M4.Concatonate( Y_4.Transpose() ) )
07112         return false;
07113     }
07114     else
07115     {
07116       if( !M4.Concatonate( Y_4 ) )
07117         return false;
07118     }
07119 
07120     if( X_5.ncols() > 5 && X_5.nrows() == 5 )
07121     {
07122       M5 = X_5.Transpose();
07123     }
07124     else
07125     {
07126       M5 = X_5;
07127     }
07128     if( Y_5.ncols() > 5 && Y_5.nrows() == 5 )
07129     {
07130       if( !M5.Concatonate( Y_5.Transpose() ) )
07131         return false;
07132     }
07133     else
07134     {
07135       if( !M5.Concatonate( Y_5 ) )
07136         return false;
07137     }
07138 
07139     series[0].connected = isConnected_1;
07140     series[0].markOutlierData = FALSE;
07141     series[0].precision = precisionStats;
07142     series[0].x_col = 0;
07143     series[0].y_col = 1;
07144     series[0].color = color_1;
07145     series[0].M = &(M1.m_Matrix);
07146     series[0].label = (char*)series_label_1.c_str();
07147     series[0].units = (char*)units_1.c_str();
07148 
07149     series[1].connected = isConnected_2;
07150     series[1].markOutlierData = FALSE;
07151     series[1].precision = precisionStats;
07152     series[1].x_col = 0;
07153     series[1].y_col = 1;
07154     series[1].color = color_2;
07155     series[1].M = &(M2.m_Matrix);
07156     series[1].label = (char*)series_label_2.c_str();
07157     series[1].units = (char*)units_2.c_str();
07158 
07159     series[2].connected = isConnected_3;
07160     series[2].markOutlierData = FALSE;
07161     series[2].precision = precisionStats;
07162     series[2].x_col = 0;
07163     series[2].y_col = 1;
07164     series[2].color = color_3;
07165     series[2].M = &(M3.m_Matrix);
07166     series[2].label = (char*)series_label_3.c_str();
07167     series[2].units = (char*)units_3.c_str();
07168 
07169     series[3].connected = isConnected_4;
07170     series[3].markOutlierData = FALSE;
07171     series[3].precision = precisionStats;
07172     series[3].x_col = 0;
07173     series[3].y_col = 1;
07174     series[3].color = color_4;
07175     series[3].M = &(M4.m_Matrix);
07176     series[3].label = (char*)series_label_4.c_str();
07177     series[3].units = (char*)units_4.c_str();
07178 
07179     series[4].connected = isConnected_5;
07180     series[4].markOutlierData = FALSE;
07181     series[4].precision = precisionStats;
07182     series[4].x_col = 0;
07183     series[4].y_col = 1;
07184     series[4].color = color_5;
07185     series[4].M = &(M5.m_Matrix);
07186     series[4].label = (char*)series_label_5.c_str();
07187     series[4].units = (char*)units_5.c_str();
07188     
07189     if( !MTX_Plot(
07190       bmpfilename.c_str(), 
07191       title.c_str(), 
07192       plot_height_cm, 
07193       plot_width_cm, 
07194       includeStats, 
07195       isXGridOn, 
07196       isYGridOn, 
07197       xlabel.c_str(), 
07198       ylabel.c_str(),
07199       x,
07200       y,
07201       series,
07202       5
07203       ) )
07204     {
07205       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
07206       return false;
07207     }
07208 
07209     return true;
07210   }
07211 
07212   bool Plot(
07213     const std::string bmpfilename,     //!< The file name (or full path name) of the output bitmap file.
07214     const std::string title,           //!< The plot title.
07215     const std::string xlabel,          //!< The x-axis label.
07216     const std::string ylabel,          //!< The y-axis label.
07217     Matrix &X_1,                         //!< The x series must be [Nx1].
07218     Matrix &Y_1,                         //!< The x series must be [Nx1].
07219     const std::string series_label_1,    //!< The series label.
07220     const std::string units_1,           //!< The series units.
07221     Matrix &X_2,                         //!< The x series must be [Nx1].
07222     Matrix &Y_2,                         //!< The x series must be [Nx1].
07223     const std::string series_label_2,    //!< The series label.
07224     const std::string units_2,           //!< The series units.
07225     Matrix &X_3,                         //!< The x series must be [Nx1].
07226     Matrix &Y_3,                         //!< The x series must be [Nx1].
07227     const std::string series_label_3,    //!< The series label.
07228     const std::string units_3,           //!< The series units.
07229     Matrix &X_4,                         //!< The x series must be [Nx1].
07230     Matrix &Y_4,                         //!< The x series must be [Nx1].
07231     const std::string series_label_4,    //!< The series label.
07232     const std::string units_4,           //!< The series units.
07233     Matrix &X_5,                         //!< The x series must be [Nx1].
07234     Matrix &Y_5,                         //!< The x series must be [Nx1].
07235     const std::string series_label_5,    //!< The series label.
07236     const std::string units_5,           //!< The series units.
07237     Matrix &X_6,                         //!< The x series must be [Nx1].
07238     Matrix &Y_6,                         //!< The x series must be [Nx1].
07239     const std::string series_label_6,    //!< The series label.
07240     const std::string units_6,           //!< The series units.
07241     const bool isConnected_1,     //!< Are the data points connected.
07242     const MTX_enumColor color_1,  //!< The color of the data points/line.
07243     const bool isConnected_2,     //!< Are the data points connected.
07244     const MTX_enumColor color_2,  //!< The color of the data points/line.    
07245     const bool isConnected_3,     //!< Are the data points connected.
07246     const MTX_enumColor color_3,  //!< The color of the data points/line.        
07247     const bool isConnected_4,     //!< Are the data points connected.
07248     const MTX_enumColor color_4,  //!< The color of the data points/line.        
07249     const bool isConnected_5,     //!< Are the data points connected.
07250     const MTX_enumColor color_5,  //!< The color of the data points/line.        
07251     const bool isConnected_6,     //!< Are the data points connected.
07252     const MTX_enumColor color_6,  //!< The color of the data points/line.        
07253     const bool isXGridOn,       //!< A boolean to indicate if the x grid lines are on.
07254     const bool isYGridOn,       //!< A boolean to indicate if the y grid lines are on.  
07255     const bool includeStats,    //!< A boolean to indicate if statistics info should be included on the plot.  
07256     const unsigned precisionStats, //!< The number of significant digits in the statistics.
07257     const unsigned plot_height_cm, //!< The plot height in cm.
07258     const unsigned plot_width_cm   //!< The plot width in cm.
07259     )
07260   {
07261     MTX_structAxisOptions x;
07262     MTX_structAxisOptions y;
07263 
07264     MTX_PLOT_structSeries series[6];
07265 
07266     Matrix M1;
07267     Matrix M2;
07268     Matrix M3;
07269     Matrix M4;
07270     Matrix M5;
07271     Matrix M6;
07272 
07273     x.lowerlimit.doNotUseDefault = FALSE;
07274     x.ticksize.doNotUseDefault = FALSE;
07275     x.tickend.doNotUseDefault = FALSE;
07276     x.tickstart.doNotUseDefault = FALSE;
07277     x.upperlimit.doNotUseDefault = FALSE;
07278     
07279     y.lowerlimit.doNotUseDefault = FALSE;
07280     y.ticksize.doNotUseDefault = FALSE;
07281     y.tickend.doNotUseDefault = FALSE;
07282     y.tickstart.doNotUseDefault = FALSE;
07283     y.upperlimit.doNotUseDefault = FALSE;
07284     
07285     if( X_1.ncols() > 1 && X_1.nrows() == 1 )
07286     {
07287       M1 = X_1.Transpose();
07288     }
07289     else
07290     {
07291       M1 = X_1;
07292     }
07293     if( Y_1.ncols() > 1 && Y_1.nrows() == 1 )
07294     {
07295       if( !M1.Concatonate( Y_1.Transpose() ) )
07296         return false;
07297     }
07298     else
07299     {
07300       if( !M1.Concatonate( Y_1 ) )
07301         return false;
07302     }
07303 
07304     if( X_2.ncols() > 2 && X_2.nrows() == 2 )
07305     {
07306       M2 = X_2.Transpose();
07307     }
07308     else
07309     {
07310       M2 = X_2;
07311     }
07312     if( Y_2.ncols() > 2 && Y_2.nrows() == 2 )
07313     {
07314       if( !M2.Concatonate( Y_2.Transpose() ) )
07315         return false;
07316     }
07317     else
07318     {
07319       if( !M2.Concatonate( Y_2 ) )
07320         return false;
07321     }
07322 
07323     if( X_3.ncols() > 3 && X_3.nrows() == 3 )
07324     {
07325       M3 = X_3.Transpose();
07326     }
07327     else
07328     {
07329       M3 = X_3;
07330     }
07331     if( Y_3.ncols() > 3 && Y_3.nrows() == 3 )
07332     {
07333       if( !M3.Concatonate( Y_3.Transpose() ) )
07334         return false;
07335     }
07336     else
07337     {
07338       if( !M3.Concatonate( Y_3 ) )
07339         return false;
07340     }
07341 
07342     if( X_4.ncols() > 4 && X_4.nrows() == 4 )
07343     {
07344       M4 = X_4.Transpose();
07345     }
07346     else
07347     {
07348       M4 = X_4;
07349     }
07350     if( Y_4.ncols() > 4 && Y_4.nrows() == 4 )
07351     {
07352       if( !M4.Concatonate( Y_4.Transpose() ) )
07353         return false;
07354     }
07355     else
07356     {
07357       if( !M4.Concatonate( Y_4 ) )
07358         return false;
07359     }
07360 
07361     if( X_5.ncols() > 5 && X_5.nrows() == 5 )
07362     {
07363       M5 = X_5.Transpose();
07364     }
07365     else
07366     {
07367       M5 = X_5;
07368     }
07369     if( Y_5.ncols() > 5 && Y_5.nrows() == 5 )
07370     {
07371       if( !M5.Concatonate( Y_5.Transpose() ) )
07372         return false;
07373     }
07374     else
07375     {
07376       if( !M5.Concatonate( Y_5 ) )
07377         return false;
07378     }
07379 
07380     if( X_6.ncols() > 6 && X_6.nrows() == 6 )
07381     {
07382       M6 = X_6.Transpose();
07383     }
07384     else
07385     {
07386       M6 = X_6;
07387     }
07388     if( Y_6.ncols() > 6 && Y_6.nrows() == 6 )
07389     {
07390       if( !M6.Concatonate( Y_6.Transpose() ) )
07391         return false;
07392     }
07393     else
07394     {
07395       if( !M6.Concatonate( Y_6 ) )
07396         return false;
07397     }
07398 
07399     series[0].connected = isConnected_1;
07400     series[0].markOutlierData = FALSE;
07401     series[0].precision = precisionStats;
07402     series[0].x_col = 0;
07403     series[0].y_col = 1;
07404     series[0].color = color_1;
07405     series[0].M = &(M1.m_Matrix);
07406     series[0].label = (char*)series_label_1.c_str();
07407     series[0].units = (char*)units_1.c_str();
07408 
07409     series[1].connected = isConnected_2;
07410     series[1].markOutlierData = FALSE;
07411     series[1].precision = precisionStats;
07412     series[1].x_col = 0;
07413     series[1].y_col = 1;
07414     series[1].color = color_2;
07415     series[1].M = &(M2.m_Matrix);
07416     series[1].label = (char*)series_label_2.c_str();
07417     series[1].units = (char*)units_2.c_str();
07418 
07419     series[2].connected = isConnected_3;
07420     series[2].markOutlierData = FALSE;
07421     series[2].precision = precisionStats;
07422     series[2].x_col = 0;
07423     series[2].y_col = 1;
07424     series[2].color = color_3;
07425     series[2].M = &(M3.m_Matrix);
07426     series[2].label = (char*)series_label_3.c_str();
07427     series[2].units = (char*)units_3.c_str();
07428 
07429     series[3].connected = isConnected_4;
07430     series[3].markOutlierData = FALSE;
07431     series[3].precision = precisionStats;
07432     series[3].x_col = 0;
07433     series[3].y_col = 1;
07434     series[3].color = color_4;
07435     series[3].M = &(M4.m_Matrix);
07436     series[3].label = (char*)series_label_4.c_str();
07437     series[3].units = (char*)units_4.c_str();
07438 
07439     series[4].connected = isConnected_5;
07440     series[4].markOutlierData = FALSE;
07441     series[4].precision = precisionStats;
07442     series[4].x_col = 0;
07443     series[4].y_col = 1;
07444     series[4].color = color_5;
07445     series[4].M = &(M5.m_Matrix);
07446     series[4].label = (char*)series_label_5.c_str();
07447     series[4].units = (char*)units_5.c_str();
07448 
07449     series[5].connected = isConnected_6;
07450     series[5].markOutlierData = FALSE;
07451     series[5].precision = precisionStats;
07452     series[5].x_col = 0;
07453     series[5].y_col = 1;
07454     series[5].color = color_6;
07455     series[5].M = &(M6.m_Matrix);
07456     series[5].label = (char*)series_label_6.c_str();
07457     series[5].units = (char*)units_6.c_str();
07458     
07459     if( !MTX_Plot(
07460       bmpfilename.c_str(), 
07461       title.c_str(), 
07462       plot_height_cm, 
07463       plot_width_cm, 
07464       includeStats, 
07465       isXGridOn, 
07466       isYGridOn, 
07467       xlabel.c_str(), 
07468       ylabel.c_str(),
07469       x,
07470       y,
07471       series,
07472       6
07473       ) )
07474     {
07475       MTX_ERROR_MSG( "MTX_Plot returned FALSE." );
07476       return false;
07477     }
07478 
07479     return true;
07480   }
07481 
07482 }

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