CMatrix類 矩陣類 C++

不是我寫的,僅分享學習!書上配套,如有侵權,速刪

與測繪程序設計配套(C++) 矩陣類 ,這個類魯棒性不好

矩陣運算類我更推薦eigen類,自行百度

代碼:

matrix.h :

#pragma once
class matrix
{
public:
	matrix(int row=3,int col=3);
	// copy constructor

    matrix (const matrix& m);

	~matrix(void);
private:
	double **dMatData;//保存矩陣元素數據的二維數組
	int iRow;//矩陣的行
	int iCol;//矩陣的列
    
public:
	int Row() const {return iRow;}//返回行
	int Col() const {return iCol;}//返回列
    void SetSize (int row, int col);//調整數組的大小,原有數據不變(未測試)

	double& operator () (int row, int col);//獲取矩陣元素
    double  operator () (int row, int col) const;//重載獲取矩陣元素函數,只有const對象能訪問
	matrix& operator = (const matrix& m) ;
    
    //注意:友元函數並不是類自己的成員函數
    friend matrix operator + (const matrix& m1,const matrix& m2);
	friend matrix operator - (const matrix& m1,const matrix& m2);
	friend matrix operator * (const matrix& m1,const matrix& m2);
	friend matrix operator * (const double& num, const matrix& m1);
	friend matrix operator * (const matrix& m1,const double& num);

	friend matrix operator ~ (const matrix& m);//矩陣轉置
	matrix Inv();//矩陣求逆
	void Unit();//生成單位矩陣
};



matix.cpp :


#include "StdAfx.h"
#include "matrix.h"
#include "math.h"

matrix::matrix(int row,int col)
{
	iRow=row;
	iCol=col;
    dMatData = new double*[row];

	for (int i=0; i < row; i++)
	{
		dMatData[i]= new double[col];
		for(int j=0;j<col;j++)
		{
				dMatData[i][j]=0;
		}
	 }
}

// copy constructor,
//拷貝構造函數的作用:
//(1)以類對象作爲函數參數傳值調用時;
//(2)函數返回值爲類對象;
//(3)用一個已定義的對象去初始化一個新對象時;

matrix::matrix (const matrix& m)
{
   	iRow=m.Row();
	iCol=m.Col();
    dMatData = new double*[iRow];

	for (int i=0; i < iRow; i++)
	{
		dMatData[i]= new double[iCol];
	//	for(int j=0;j<iCol;j++)
		{
			memcpy(dMatData[i],m.dMatData[i],sizeof(double)*iCol);
		}
	 }
   
}

matrix::~matrix(void)
{
    for (int i=0; i < iRow; i++)
	{
		delete[] dMatData[i];
	 }
	delete[] dMatData;
}

//返回數組元素(引用返回)
double& matrix::operator () (int row, int col)
{
    if (row >= iRow || col >= iCol)
	{
      throw( "matrix::operator(): Index out of range!");
	}
	
    return dMatData[row][col]; 
}

////返回數組元素(重載)
double matrix::operator () (int row, int col) const
{
    if (row >= iRow || col >= iCol)
	{
      throw( "matrix::operator(): Index out of range!");
	}
	
    return dMatData[row][col]; 
}


//重載預算符+
matrix operator + (const matrix& m1,const matrix& m2)
{

   if((m1.Col()!=m2.Col()) ||(m1.Row()!=m2.Row()) )
   {
       throw( "matrix::operator+: The two matrix have different size!");
   }

   matrix matTmp(m1.Row(),m1.Col());
   for(int i=0;i<m1.Row();i++)
   {
	   for(int j=0;j<m1.Col();j++)
	   {
             matTmp(i,j)=m1(i,j)+m2(i,j);     
	   }
   }
   return matTmp;
}

//重載賦值運算符=,當左右兩邊矩陣的大小不相等時,
//以右邊的大小爲基準,調整左邊矩陣的大小

matrix &matrix::operator = (const matrix& m) 
{
	//revised in 2011-4-1, by Daiwujiao
 //   if(iRow!=m.Row()||iCol!=m.Col())
	//{
 //       throw( "matrix::operator=: The two matrix have different size!");
	//}

	if(iRow!=m.Row()||iCol!=m.Col())
	{
		SetSize(m.Row(),m.Col());
	}
	for (int i=0; i < iRow; i++)
	{
		
		for(int j=0;j<iCol;j++)
		{
				dMatData[i][j]=m(i,j);
		}
	 }
    return *this;
}


//調整矩陣大小,原有值不變
void matrix::SetSize (int row, int col)
{
   if (row == iRow && col == iCol)
   {
      return;
   }

   double **rsData = new double*[row];
   	for (int i=0; i < row; i++)
	{
		rsData[i]= new double[col];
		for(int j=0;j<col;j++)
		{
				rsData[i][j]=0;
		}
	 }

	int minRow=(iRow>row)?row:iRow;
    int minCol= (iCol>col)?col:iCol;
    int  colSize = minCol * sizeof(double);
    

   for (int i=0; i < minRow; i++)
   {
      memcpy( rsData[i], dMatData[i], colSize);
   }

    for (int i=0; i < minRow; i++)
	{
         delete[] dMatData[i];
	}
	delete[] dMatData;
	dMatData=rsData;
    iRow=row;
	iCol=col;
    return;
}
//重載預算符-
matrix operator - (const matrix& m1,const matrix& m2)
{

   if((m1.Col()!=m2.Col()) ||(m1.Row()!=m2.Row()) )
   {
       throw( "matrix::operator-: The two matrix have different size!");
   }

   matrix matTmp(m1.Row(),m1.Col());
   for(int i=0;i<m1.Row();i++)
   {
	   for(int j=0;j<m1.Col();j++)
	   {
             matTmp(i,j)=m1(i,j)-m2(i,j);     
	   }
   }
   return matTmp;
}

//重載預算符*,兩個矩陣相乘,m1的列要等於m2的行
matrix operator * (const matrix& m1,const matrix& m2)
{

   if((m1.Col()!=m2.Row()))
   {
       throw( "matrix::operator*: The col of matrix m1 doesn't equ to row of m2 !");
   }

   matrix matTmp(m1.Row(),m2.Col());
   for(int i=0;i<m1.Row();i++)
   {
	   for(int j=0;j<m2.Col();j++)
	   {
		   for(int k=0;k<m2.Row();k++)
		   {
             matTmp(i,j)+=m1(i,k)*m2(k,j);     
		   }
	   }
   }
   return matTmp;
}

//重載預算符*,矩陣右乘一個數
matrix operator * (const matrix& m1,const double& num)
{
   matrix matTmp(m1.Row(),m1.Col());
   for(int i=0;i<m1.Row();i++)
   {
	   for(int j=0;j<m1.Col();j++)
	   {
             matTmp(i,j)=m1(i,j)*num;     

	   }
   }
   return matTmp;
}

//重載預算符*,矩陣左乘一個數
matrix operator * (const double& num, const matrix& m1)
{
   matrix matTmp(m1.Row(),m1.Col());
   for(int i=0;i<m1.Row();i++)
   {
	   for(int j=0;j<m1.Col();j++)
	   {
             matTmp(i,j)=m1(i,j)*num;     
	   }
   }
   return matTmp;
}

//矩陣轉置
matrix operator ~ (const matrix& m)
{
  matrix matTmp(m.Col(),m.Row());

   for (int i=0; i < m.Row(); i++)
      for (int j=0; j < m.Col(); j++)
      {
         matTmp(j,i) = m(i,j);
      }
   return matTmp;
}


//矩陣求逆
//採用選全主元法
matrix matrix::Inv()
{
    if (iRow!=iCol)
	{
        throw("待求逆的矩陣行列不相等!");
	}
    
    int i, j, k, vv;
 
    matrix InvMat(iRow,iRow);

    //複製矩陣
	InvMat=*this;
   
    int* MainRow=new int[iRow];
	int* MainCol=new int[iRow];//用於記錄主元素的行和列

    double dMainCell;//主元元素的值
    double dTemp;//臨時變量

    for(k = 0;k<iRow;k++)
	{
        dMainCell = 0;
        //選全主元
        for( i = k;i<iRow ;i++)
		{
            for( j = k;j<iRow;j++)
			{
                dTemp = fabs(InvMat(i, j));
                if(dTemp > dMainCell)
				{
                    dMainCell = dTemp;
                    MainRow[k] = i;
                    MainCol[k] = j;
				}
			}
		}

		if( fabs(dMainCell) < 0.0000000000001)//矩陣秩虧,不能求逆
		{
            throw("矩陣秩虧");
		}

        if(MainRow[k] != k)//交換行
		{
            for( j = 0 ;j<iRow;j++)
			{
                vv = MainRow[k];
                dTemp = InvMat(k, j);
                InvMat(k, j) = InvMat(vv, j);
                InvMat(vv, j) = dTemp;
			}
		}

        if(MainCol[k] != k)//交換列
		{
            for(i = 0;i<iRow;i++)
			{
                vv = MainCol[k];
                dTemp = InvMat(i, k);
                InvMat(i, k) = InvMat(i, vv);
                InvMat(i, vv) = dTemp;
			}
		}
        InvMat(k, k) = 1.0 / InvMat(k, k);//計算乘數

        for( j = 0;j< iRow;j++) //計算主行
		{
            if(j != k)
			{
                InvMat(k, j) = InvMat(k, j) * InvMat(k, k);
			}
		}
        for(i = 0;i<iRow;i++)//消元
		{
            if( i !=k)
			{
                for(j = 0;j<iRow;j++)
				{
					if(j != k)
					{
                        InvMat(i, j) -= InvMat(i, k) * InvMat(k, j);
					}
				}
			}
		}
        for( i = 0;i< iRow;i++ )//計算主列
		{
            if( i != k)
			{
				InvMat(i, k) = -InvMat(i, k) * InvMat(k, k);
			}
		}
	}

    for( k = iRow - 1;k>=0;k--)
	{
        if(MainCol[k] != k)// 交換行
		{
            for( j = 0;j<iRow;j++)
			{
                vv = MainCol[k];
                dTemp = InvMat(k, j);
                InvMat(k, j) = InvMat(vv, j);
                InvMat(vv, j) = dTemp;
			}
		}

        if(MainRow[k] != k)//交換列
		{
            for( i = 0;i<iRow;i++)
			{
				vv = MainRow[k];
                dTemp = InvMat(i, k);
                InvMat(i, k) = InvMat(i, vv);
                InvMat(i, vv) = dTemp;
			}
		}
	}
	delete[] MainRow;
	delete[] MainCol;
    return InvMat;
}
//單位化矩陣
void matrix::Unit()
{
     for(int i=0;i<iRow;i++)
	 {
		 for(int j=0;j<iCol;j++)
		 {
			 dMatData[i][j]=(i==j)?1:0;
		 }
	 }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章