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

📄 matrix.h

📁 矩阵类
💻 H
📖 第 1 页 / 共 5 页
字号:
/**
\file     Matrix.h
\brief    The Zenautics Matrix Class
\author   Glenn D. MacGougan (GDM)
\date     2007-12-13
\version  1.10

\b LICENSE \b INFORMATION \n
Copyright (c) 2007, Glenn D. MacGougan, Zenautics Technologies Inc. \n

Redistribution pertains only to the following files and their contents. \n
- Matrix.h\n
- Matrix.cpp\n
- cmatrix.h\n
- cmatrix_basic.lib (for windows), cmatrix_basic_lib.a (for linux)\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
*/

#ifndef _ZENAUTICS_MATRIX_H_
#define _ZENAUTICS_MATRIX_H_

#include <stdio.h>
#include <complex> // This is needed for the Standard Template Library complex<double> type.
#include <string>
#include "cmatrix.h" // The core matrix engine is written in 'c'.

namespace Zenautics
{

#define MATRIX_USE_EXCEPTION_HANDLING
#ifdef MATRIX_USE_EXCEPTION_HANDLING

  /**
  \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);
    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  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
    std::complex<double> cplx(1.0,2.0);
    Matrix A;
    if( !A.Copy(cplx) )
      return false;
    \endcode
    
    \return true if successful, false otherwise
    */
    bool Copy( const std::complex<double>& cplx );


  public: // Output Operations

    /**
    \brief  Saves a matrix to the specified file path (a 'c' style string)
            using a proprietary compressed format.
            ADVANCED EDITION ONLY. BASIC EDITION will return false.
    \code
    Matrix A;
    A = "[1,2,3; 4,5,6; 7,8,9]";
    if( !A.Save("data.mtx" ) )
      return false;
    \endcode 

    \return true if successful, false otherwise
    */
    bool Save( const char* path );

    /**
    \brief  Saves a matrix to the specified file path (a std::string)
            using a proprietary compressed format.
            ADVANCED EDITION ONLY. BASIC EDITION will return false.
            
    \code
    Matrix A;
    std::string str = "data.mtx";
    A = "[1,2,3; 4,5,6; 7,8,9]";
    if( !A.Save(str) )
      return false;
    \endcode 

    \return true if successful, false otherwise
    */
    bool Save( std::string path );
    
    /**
    \brief  Print the matrix to a file with automatically determined column width 
            and the specified precision, uses "%'blank''-'autowidth.precision'g'", to 
            the 'c' style path string provided.
    \code
    A = "[1,2,3; 4,5,6; 7,8,9]";
    if( !A.Print( "data.txt", 14 ) ) // Print the matrix to data.txt
      return false;
    \endcode   

    \return true if successful, false otherwise
    */
    bool Print( const char *path, const unsigned precision, bool append = false );

    /**
    \brief  Print the matrix to a file with automatically determined column width 
            and the specified precision, uses "%'blank''-'autowidth.precision'g'", to 
            the std:string path provided.
    \code
    A = "[1,2,3; 4,5,6; 7,8,9]";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -