C++マトリクスクラスの実装


マトリックスクラスは,コピーコンストラクタ,演算子リロードなど,C++のクラスを学習するのに大きな助けとなる.以下は設計マトリクスクラスです.
class MyMatrix
{
public:
    int  m_nRows; //      
    int  m_nColumns; //      
    double* m_lpBuf; //              
public:
    MyMatrix();
    MyMatrix(MyMatrix& A);
     ~MyMatrix();
}

マトリクスの行と列は固定されていないため、メモリを動的に割り当てる方法として設定する必要があります.割り当て関数は次のとおりです.
MyMatrix::MyMatrix(int m, int n)//declare an mxn MyMatrix
{
    m_nRows = m;
    m_nColumns = n;
    //        ,     
    this->m_lpBuf = new double[m*n];
    memset(m_lpBuf,0,m*n*sizeof(double));
}

解析関数は次のとおりです.
~MyMatrix(){   
        m_nRows = 0;    
        m_nColumns =0;  
        if(m_lpBuf != NULL)     
            delete[] this->m_lpBuf;
    };

一般的に、動的に割り当てられたメモリを持つクラスでは、深いコピー関数と割り当て関数として次の関数を書き換える(深い)コピー構造関数が必要です.
MyMatrix::MyMatrix(const MyMatrix& A) //copy ructor
{ 
    this->m_nRows = A.m_nRows;
    this->m_nColumns = A.m_nColumns;
    if(m_nRows * m_nColumns != 0)
    {
        this->m_lpBuf = new double[m_nRows*m_nColumns];

        for(int i = 0;i < (m_nRows*m_nColumns);++i)
            this->m_lpBuf[i] = A.m_lpBuf[i];
    }
    else
        m_lpBuf = NULL;
}  
MyMatrix& MyMatrix::operator = ( const MyMatrix& A) //overloading =
{
    if(this==&A) 
        return *this;
    this->resize(A.m_nRows,A.m_nColumns);

    for(int i=0;ireturn *this;
}

Matlabをよく使う人には、a(1,2)、C++クラスについても、同じように表現するのが好きです.
double& MyMatrix::operator ()(int i, int j)
{
    // Unsafe
    return *(m_lpBuf + (i-1)*m_nColumns+(j-1)); 
}

リロードオペレータの場合は、次のように書くことができます.
MyMatrix& MyMatrix::operator += ( MyMatrix& A) 
{
    if(!A.m_lpBuf) return *this;
    if ( (this->m_nRows != A.m_nRows) || (this->m_nColumns != A.m_nColumns))
    {
        throw logic_error ("Size mismatch in MyMatrix addition");
    }
    for(int i=0;ithis->m_lpBuf[i]+=A.m_lpBuf[i];

    return *this;
}
MyMatrix operator + (MyMatrix& A, MyMatrix& B) 
{
    MyMatrix tmp = A;
    tmp+=B;
    return tmp;
}

その他の乗算操作は、これに従って書くことができます.マトリクス内のデータをtxtファイルとして保存し、txtファイルを読み込むには、以下のように記述できます.
bool MyMatrix::SaveToTxt(const char *filename)
{
    ofstream file(filename,ios_base::out);
    if(!file)
        return false;
    for(int i=1;i<=m_nColumns;++i)
    {
        for(int j=1;j<=m_nRows;++j)
            file<20)<7)<1)*m_nColumns + (j-1));
        file<<"
"
<return true; } bool MyMatrix::LoadFromTxt(const char *filename) { FILE *fp = NULL; if(fopen_s(&fp,filename,"r")!=0) return false; int i = 0; while(!feof(fp)) { fscanf_s(fp,"%lf",(m_lpBuf+i)); if(++i>m_nRows*m_nColumns) break; } fclose(fp); return true; }

以下のプログラムは行列に対して逆を求めて、その方法は算術の中の計算方法です
MyMatrix inv(MyMatrix& A) 
{
    int rows = A.m_nRows;
    MyMatrix C(rows,rows);

    if(A.m_nRows != A.m_nColumns)
        return C; 

    //      A       B = |A : E|
    MyMatrix B(rows, rows*2, 0);
    for(int i = 1;i<=rows;++i)
        for(int j=1;j<=rows;++j)
            B(i,j) = A(i,j);
    for(int i = 1;i<=rows;++i)
        B(i,i+rows) = 1;

    double tempa = 0;
    //    A  B.row     ,     K          
    for(int k=1; k<=B.m_nRows; k++)
    { 
        //------------------     -------------------------------- 
        double max = fabs(B(k,k)); //                  
        int ind = k; //                
        //    ind       
        for(int n=k+1; n<=B.m_nRows; ++n)
        { 
            if(fabs(B(n,k)) > max)
            {
                //            
                max = fabs(B(n,k)); //       
                ind = n; //       
            }
        }
        //-------------------       ------------------------- 
        if(ind != k)
        { //              
            for(int m=k; m<=rows*2; ++m)
            { //                
                tempa = B(k,m); 
                B(k,m) = B(ind, m);
                B(ind,m) = tempa;
            }           
        } 

        //---------------------    -------------------------------- 
        //  k     ,  k      ,        k       
        //          B       ,     B  A       
        tempa = 1.0/B(k,k);
        for(int i=k; i<=rows*2; ++i)
        {
            B(k,i) *= tempa;
        }

        for(int i=1; i<=rows; i++)
        { 
            if(i != k)
            { 
                tempa = -B(i,k);
                for(int j=k; j<=B.m_nColumns; ++j) 
                    B(i,j) += tempa*B(k,j);
            }//end if 
        }//loop i 

    }//loop k 

    for(int i = 1;i<=rows;++i)
        for(int j = 1;j<=rows;++j)
            C(i,j) = B(i,j+rows);

    return C;
}//inv()