?? matrix.h
字號:
/**
\file Matrix.h
\brief The Zenautics Matrix Class
\author Glenn D. MacGougan (GDM)
\date 2008-09-22
\version 0.06 Beta
\b Version \b Information \n
This is the open source version (BSD license). The Professional Version
is avaiable via http://www.zenautics.com. The Professional Version
is highly optimized using SIMD and includes optimization for multi-core
processors.
\b License \b Information \n
Copyright (c) 2008, Glenn D. MacGougan, Zenautics Technologies Inc. \n
Redistribution and use in source and binary forms, with or without
modification, of the specified files is permitted provided the following
conditions are met: \n
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. \n
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. \n
- The name(s) of the contributor(s) may not be used to endorse or promote
products derived from this software without specific prior written
permission. \n
THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
\b NOTES: \n
This code was developed using rigourous unit testing for every function
and operation. Despite any rigorous development process, bugs are
inevitable. Please report bugs and suggested fixes to glenn @ zenautics.com.\n
\b Preprocessor Defines \n
#define _MATRIX_NO_EXCEPTION // removes exception handling support. \n
*/
#ifndef _ZENAUTICS_MATRIX_H_
#define _ZENAUTICS_MATRIX_H_
#include <complex> // For std::complex<double> (Standard Template Library)
#include <string> // For std::string (Standard Template Library)
#include "cmatrix.h" // The core matrix engine is written in 'c'.
//#define _MATRIX_NO_EXCEPTION // removes exception handling support if required.
namespace Zenautics
{
#ifndef _MATRIX_NO_EXCEPTION
/**
\class MatrixException
\brief A class for exceptions thrown by the Matrix class.
The MATRIX_USE_EXCEPTION_HANDLING define enables the use of exception
handling using try{} catch{}. A MatrixException is thrown. The use of
exception handling is very highly recommended. When it is turned off,
the matrix will try to output a message and then call 'exit(1)'.
\code
int main()
{
try
{
Matrix A(2,2);
double d = A(3,1).real(); // causes an out of bounds exception
}
catch( MatrixException& matrix_exception )
{
cout << matrix_exception << endl;
}
catch ( ... )
{
cout << "Caught unknown exception" << endl;
}
return 0;
}
\endcode
*/
class MatrixException
{
public:
/// \brief The constructor.
MatrixException( const char* msg );
/// \brief The copy constructor.
MatrixException(const MatrixException& matrix_exception);
/// \brief The destuctor.
virtual ~MatrixException() { /* nothing needed yet */ };
/// \brief Return a copy of the exception message.
std::string GetExceptionMessage();
/// \brief Overload the casting operator to a string.
operator const char*();
public:
/// \brief The matrix exception string.
std::string m_ExceptionString;
private:
/// \brief The matrix exception character string.
char m_msg[256];
};
#endif
/**
\class Matrix
\brief The matrix/vector class.
Both real and complex data are inherently supported.
One and two dimensional data.
The matrix class supports advanced real and complex functionality. It is
optimized for columnwise operations. Refer to example_main.cpp for a
complete example program using the Matrix.
*/
class Matrix
{
public: // Constructors / Destructor
/// \brief This function enables or disables a global flag
/// that forces single element matrices to be treated
/// as scalars. This is enabled by default.
static void Treat1x1MatricesAsScalar( bool enable = true );
/// \brief The default constructor (no data allocated yet).
Matrix();
/// \brief A vector style constructor.
///
/// Matrix A(nrows); creates an nrowsx1 real 'vector'.
/// A complex vector must be created using Matrix A(nrows,ncols,false);
explicit Matrix(const unsigned nrows);
/// \brief A matrix style constructor.
///
/// Matrix A(nrows,ncols); creates an nrowsxncols real 'matrix'. A real matrix is assumed.
/// Matrix A(nrows,ncols,false); creates an nrowsxncols complex 'matrix'. A real matrix is assumed.
Matrix(const unsigned nrows, const unsigned ncols, const bool isReal=true);
/// \brief The copy constructor.
Matrix(const Matrix& mat);
/// \brief A constructor reading data from a file.
Matrix(const char* path, bool& itWorked);
/** \brief A constructor initialized the matrix from a string.
There are two general possible interpretations of the string input. \n
(1) Square bracket delimited matrix. e.g. \n
\code
Matrix A = "[1 2 3; 4 5 6]"; // or
Matrix A = "[1, 2, 3; 4, 5, 6]";
\endcode
In this case '[' donates the start of a matrix and ']' denotes the end. \n
Row vectors [1 2 3] and [4 5 6] are separated by ';'. \n
Commas can delimit row vector data but are not needed. \n
Complex input: e.g.
\code
Matrix A = "[1+1i 2+3j 1-2i; 4 5 6]"; // or
Matrix A = "[1+1i, 2+3j, 1-2i; 4, 5, 6]";
\endcode
(2) Free form delimited matrix. e.g. \n
\code
Matrix A = "1 2 3 \\n 4 5 6 \\n";
\endcode
In this case, the newline delimits different rows of the matrix. (\\r\\n also works). \n
Row vectors can still be delimited by ';' as well. \n
\code
Matrix B = "1 2 3; 4 5 6; \\n 7 8 9";
\endcode
will set a 3x3 matrix == [1 2 3; 4 5 6; 7 8 9]. \n
Commas can delimit row vector data but are not needed. \n
Complex input: e.g.
\code
Matrix A = "[1+1i 2+3j 1-2i\\n 4 5 6]"; // or
Matrix A = "1+1i, 2+3j, 1-2i\\n 4, 5, 6"; // or
Matrix A = "1+1i 2+3j 1-2i; 4, 5, 6";
\endcode
All result in A = [1+1i 2+3i 1-2i; 4 5 6]; \n
*/
Matrix(const char* strMatrix);
/// \brief The constructor as a copy from a static matrix.
Matrix(const double mat[], const unsigned nrows, const unsigned ncols=1 );
/// \brief The destructor.
virtual ~Matrix();
/// \brief The assignment operator from another matrix.
///
/// 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)
Matrix& operator=(const Matrix& mat);
/// \brief The assignment operator from a scalar double value.
///
/// e.g. Matrix A; A = 2.0; // A is (1x1).
Matrix& operator=(const double value);
/// \brief The assignment operator from a std::complex<double> value.
///
/// e.g. Matrix A; A = 2.0; // A is (1x1).
Matrix& operator=(const std::complex<double> value);
/**
\brief The assignement operator from a string matrix.
There are two general possible interpretations of the string input. \n
(1) Square bracket delimited matrix. e.g. \n
\code
Matrix A;
A = "[1 2 3; 4 5 6]"; // or
A = "[1, 2, 3; 4, 5, 6]";
\endcode
In this case '[' donates the start of a matrix and ']' denotes the end. \n
Row vectors [1 2 3] and [4 5 6] are separated by ';'. \n
Commas can delimit row vector data but are not needed. \n
Complex input: e.g.
\code
Matrix A;
A = "[1+1i 2+3j 1-2i; 4 5 6]"; // or
A = "[1+1i, 2+3j, 1-2i; 4, 5, 6]";
\endcode
(2) Free form delimited matrix. e.g. \n
\code
Matrix A;
A = "1 2 3 \\n 4 5 6 \\n";
\endcode
In this case, the newline delimits different rows of the matrix. (\\r\\n also works). \n
Row vectors can still be delimited by ';' as well. \n
\code
B = "1 2 3; 4 5 6; \\n 7 8 9";
\endcode
will set a 3x3 matrix == [1 2 3; 4 5 6; 7 8 9]. \n
Commas can delimit row vector data but are not needed. \n
Complex input: e.g.
\code
Matrix A;
A = "[1+1i 2+3j 1-2i\\n 4 5 6]"; // or
A = "1+1i, 2+3j, 1-2i\\n 4, 5, 6"; // or
A = "1+1i 2+3j 1-2i; 4, 5, 6";
\endcode
All result in A = [1+1i 2+3i 1-2i; 4 5 6]; \n
*/
Matrix& operator=(const char* strMatrix);
public:
/**
\brief Clear the matrix memory. Set the matrix to size 0x0.
\code
Matrix A(10,10); // A 10 x 10 matrix
if( !A.Clear() )
return false;
// A is now 0x0
\endcode
\return true if successul, false if error.
*/
bool Clear();
public: // Matrix Qualifiers
/// \brief Is this matrix empty?
bool isEmpty() const;
/// \brief Is the matrix mat conformal for multiplication (*this * mat)?
bool isConformal(const Matrix& mat) const;
/// \brief Is this matrix the same size as mat?
bool isSameSize(const Matrix& mat) const;
/// \brief Is this a square matrix?
bool isSquare() const;
/// Check if this matrix is stored as a complex matrix.
bool isStoredAsComplex();
/// Check if this a real matrix.
bool isReal();
/// Check if this a complex matrix.
bool isComplex();
/// Check if this is a vector. Is the matrix either nx1 or 1xn.
bool isVector();
unsigned GetNrCols() const; //!< return no. of cols
unsigned ncols() const; //!< return no. of cols
unsigned GetNrElems() const; //!< return total no. of elements
unsigned nelems() const; //!< return total no. of elements
unsigned GetNrRows() const; //!< return no. of rows
unsigned nrows() const; //!< return no. of rows
unsigned GetLength() const; //!< return the maximum dimension either nrows or ncols whichever is greater.
/**
\brief Return the real part of the matrix at this row and column.
\code
Matrix A = "2+4i";
double a = A.real(0,0); // a is 2.0
\endcode
*/
double real(const unsigned row, const unsigned col);
/**
\brief Return the real part of the matrix at this vector index.
\code
Matrix A = "[2+4i, 10-1i]";
double a = A.real(1); // a is 10.0
\endcode
*/
double real(const unsigned index);
/**
\brief Return the imaginary part of the matrix at this row and column.
\code
Matrix B = "2+4i";
double b = B.imag(0); // b is 4.0
\endcode
*/
double imag(const unsigned row, const unsigned col);
/**
\brief Return the imaginary part of the matrix at this vector index.
\code
Matrix B = "[2+4i, 1-10i]";
double b = B.imag(1); // b is -10.0
\endcode
*/
double imag(const unsigned index);
public: // Input Operations
/**
\brief Read the matrix from an ASCII file with the path given by the 'c' style string
(with automatric support for many delimiters, whitespace, or ',', or ';', or many others)
or a compressed BINARY matrix file used in the Save function.
Complex and real data input are supported.
A non-numeric header line can be present which will be skipped.
\code
Matrix A;
Matrix B;
Matrix C;
bool result;
result = A.ReadFromFile("data.txt"); // Read an ASCII numeric data file.
result = B.ReadFromFile("data.csv"); // Read a comma delimited numeric data file. e.g. saved from EXCEL.
result = C.ReadFromFile("data.mtx"); // Read a compressed binary matrix (MTX format).
\endcode
\return true if successful, false otherwise
*/
bool ReadFromFile( const char *path );
/**
\brief Read the matrix from a file given the file path as a standard string.
\code
Matrix A;
std::string str = "data.txt";
if( !A.ReadFromFile(str) )
return false;
\endcode
\return true if successful, false otherwise.
*/
bool ReadFromFile( std::string path );
/**
\brief A safe function for performing a copy of another matrix.
\code
Matrix A(2,2);
A[0][0] = 1.0;
A[0][1] = 2.0;
A[1][0] = 3.0;
A[1][1] = 4.0;
Matrix B;
if( !B.Copy(A) )
return false;
\endcode
\return true if successful, false otherwise
*/
bool Copy( Matrix& src );
/**
\brief A safe function for setting the matrix from a double.
\code
double d = 10.0;
Matrix A;
if( !A.Copy(d) )
return false;
\endcode
\return true if successful, false otherwise
*/
bool Copy( const double& value );
/**
\brief A safe function for setting the matrix from a std::complex<double>.
\code
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -