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;
		 }
	 }
}


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