C++マトリクスクラスの実装
11107 ワード
マトリックスクラスは,コピーコンストラクタ,演算子リロードなど,C++のクラスを学習するのに大きな助けとなる.以下は設計マトリクスクラスです.
マトリクスの行と列は固定されていないため、メモリを動的に割り当てる方法として設定する必要があります.割り当て関数は次のとおりです.
解析関数は次のとおりです.
一般的に、動的に割り当てられたメモリを持つクラスでは、深いコピー関数と割り当て関数として次の関数を書き換える(深い)コピー構造関数が必要です.
Matlabをよく使う人には、a(1,2)、C++クラスについても、同じように表現するのが好きです.
リロードオペレータの場合は、次のように書くことができます.
その他の乗算操作は、これに従って書くことができます.マトリクス内のデータをtxtファイルとして保存し、txtファイルを読み込むには、以下のように記述できます.
以下のプログラムは行列に対して逆を求めて、その方法は算術の中の計算方法です
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()