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