⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix.h

📁 大地测量专业计算软件
💻 H
📖 第 1 页 / 共 5 页
字号:
/**
\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 + -