📄 matrix.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Matrix.cpp : Implementation of the class Matrix
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Matrix.h"
#include <math.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMatrix::CMatrix()
{
m_nRow = 0;
m_nCol = 0;
m_pTMatrix.resize (m_nRow);
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
m_pTMatrix[i].resize (m_nCol);
m_pTMatrix[i][j] = (double) 0;
}
}
}
CMatrix::~CMatrix()
{
}
CMatrix::CMatrix(unsigned int nRow,unsigned int nCol)
{
// 动态分配二维数组
TMatrix tMatrix;
tMatrix.resize (nRow);
for(unsigned int i=0; i < nRow; i++)
{
for(unsigned int j=0; j < nCol; j++)
{
tMatrix[i].resize(nCol);
tMatrix[i][j] = (double) 0;
}
}
// 对对象变量赋值
m_nRow = nRow;
m_nCol = nCol;
m_pTMatrix = tMatrix;
}
CMatrix::CMatrix(CMatrix& cMatrixB)
{
// Initialize the variable
m_nRow = cMatrixB.m_nRow ;
m_nCol = cMatrixB.m_nCol ;
m_pTMatrix = cMatrixB.m_pTMatrix ;
// Copy Data
for(unsigned int i=0; i< cMatrixB.m_nRow; i++)
{
for(unsigned int j=0; j < cMatrixB.m_nCol; j++)
{
m_pTMatrix [i][j] = cMatrixB.m_pTMatrix [i][j];
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CMatrix member functions
//
CMatrix CMatrix::operator +(CMatrix& cMatrixB)
{
// 要满足矩阵相加的条件: 行列数目相等!
if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol )
{
::AfxMessageBox (TEXT("执行相加的两个矩阵维数不相等!"),MB_OK | MB_ICONERROR);
}
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = m_pTMatrix [i][j] + cMatrixB.m_pTMatrix [i][j];
}
}
return cMatrix;
}
CMatrix CMatrix::operator -(CMatrix& cMatrixB)
{
// 要满足矩阵相加的条件: 行列数数目相等!
if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol )
{
::AfxMessageBox (TEXT("执行相减的两个矩阵维数不相等!"),MB_OK | MB_ICONERROR);
}
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = m_pTMatrix [i][j] - cMatrixB.m_pTMatrix [i][j];
}
}
return cMatrix;
}
CMatrix CMatrix::operator *(CMatrix& cMatrixB)
{
if( m_nCol != cMatrixB.m_nRow )
{
::AfxMessageBox (TEXT("执行相乘的两个矩阵维数不满足相乘的条件!"),MB_OK | MB_ICONERROR);
}
CMatrix cResultMatrix(m_nRow,cMatrixB.m_nCol);
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < cMatrixB.m_nCol; j++)
{
for(unsigned int m=0; m < m_nCol; m++)
{
cResultMatrix.m_pTMatrix [i][j] += m_pTMatrix [i][m] * cMatrixB.m_pTMatrix [m][j];
}
}
}
return cResultMatrix;
}
CMatrix CMatrix::operator * (double nValue)
{
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] =m_pTMatrix [i][j] * nValue;
}
}
return cMatrix;
}
CMatrix& CMatrix::operator =(CMatrix& cMatrixB)
{
if( (m_nRow != cMatrixB.m_nRow) || (m_nCol != cMatrixB.m_nCol) )
{
::AfxMessageBox(TEXT("等号左右两边的矩阵的维数不相等!"),MB_OK | MB_ICONERROR);
return *this; // return invalid value
}
// 给变量赋值
m_nRow = cMatrixB.m_nRow ;
m_nCol = cMatrixB.m_nCol ;
m_pTMatrix = cMatrixB.m_pTMatrix ;
// 赋值操作
for(unsigned int i=0; i < cMatrixB.m_nRow; i++)
{
for(unsigned int j=0; j< cMatrixB.m_nCol; j++)
{
m_pTMatrix [i][j] = cMatrixB.m_pTMatrix [i][j];
}
}
return *this;
}
CMatrix& CMatrix::operator += (CMatrix& cMatrixB)
{
if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol )
{
//printf("错误!执行相加的两个矩阵维数不相等!\n");
::AfxMessageBox (TEXT("运算符的两边矩阵的维数不相等!"),MB_OK | MB_ICONERROR);
return *this; // return invalid value
}
// 赋值操作
for(unsigned int i=0; i < cMatrixB.m_nRow; i++)
{
for(unsigned int j=0; j< cMatrixB.m_nCol; j++)
{
m_pTMatrix [i][j] += cMatrixB.m_pTMatrix [i][j];
}
}
return *this;
}
CMatrix CMatrix::Transpose()
{
CMatrix cMatrix(m_nCol,m_nRow);
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [j][i] = m_pTMatrix [i][j];
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// 将矩阵的所有的元素按列合成一列
// 例如:
// matrix = [
// 1 2 3
// 4 5 6
// 7 8 9
// ]
// CMatrix cMatrix = matrix.MergeColumnsToColumnVector();
// cMatrix =
// [ 1
// 4
// 7
// 2
// 5
// 8
// 3
// 6
// 9 ]
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::MergeColumnsToColumnVector()
{
CMatrix cMatrix(m_nRow * m_nCol,(unsigned int)1);
// 对矩阵赋值
for(unsigned int j=0; j < m_nCol; j++)
{
for(unsigned int i=0; i < m_nRow; i++)
{
cMatrix.m_pTMatrix [i + j * m_nRow][(unsigned int)0] = m_pTMatrix [i][j];
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// Get the total value of the matrix
/////////////////////////////////////////////////////////////////////////////
double CMatrix::GetTotalElementValue()
{
double nTotalValue = 0;
for(unsigned int i=0; i < m_nRow; i++)
{
for( unsigned int j=0; j < m_nCol; j++)
{
nTotalValue += m_pTMatrix [i][j];
}
}
return nTotalValue;
}
/////////////////////////////////////////////////////////////////////////////
// Get System Error
/////////////////////////////////////////////////////////////////////////////
double CMatrix::GetSystemError() const
{
double nSystemError = 0;
for(unsigned int i=0; i < m_nRow; i++)
{
for( unsigned int j=0; j < m_nCol; j++)
{
nSystemError += m_pTMatrix [i][j] * m_pTMatrix [i][j];
}
}
return nSystemError;
}
/////////////////////////////////////////////////////////////////////////////
// Make all the matrix elements to be changed into absolute value
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::AbsoluteValue ()
{
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = fabs( m_pTMatrix [i][j]);
}
}
return cMatrix;
}
CMatrix CMatrix::Inverse()
{
/////////////////////////////////////////////////////////////////////////
// Using Gauss - Jordan Method
// 参考书目: 计算机数值方法 --->施吉林 陈桂枝
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// 判断是否是可逆阵:
// 可逆阵一定是方阵!!!
if ( m_nRow != m_nCol)
{
//printf("错误!矩阵的行列数不相等,是非可逆阵!\n");
::AfxMessageBox (TEXT("矩阵的行列数不相等,是非可逆阵!"),MB_OK | MB_ICONERROR);
}
CMatrix cMatrix = *this;
//***********************************************************************
// 思路:(非常规思维!)
// 动态分配整型数组(2*m_nCol)来存储每次交换的行坐标的值
// 不论有没有行交换都记录在数组中,
// 1.没进行行交换的两个数据相等,在SwapMatrixRow()函数中
// 检测到两个值相等立即返回,在SwapMatrixCol()函数中也一样,
// 检测到两个值相等立即返回,不占用系统资源;
// 2.不相等的就交换
//***********************************************************************
// 分配内存
int *pIntArray = new int [2*m_nCol];
// nSetp --- 约化步数,按列展开
for(unsigned int k=0; k < cMatrix.m_nCol; k++)
{
/////////////////////////////////////////////////////////////////////
// 进行行交换 ---> 游戏规则:
// 为保证计算过程的数值稳定性,在第k步约化时,先在{a(ik)}|i=k->n中选按
// 模最大者作为约化主元素,并交换矩阵相应的行
// 标记主元素
double nMaxElement = cMatrix.m_pTMatrix [k][k];
// 标记主元素所在的行数
unsigned int nMainRow = k;
for(unsigned int nCount = k+1; nCount < cMatrix.m_nCol; nCount++)
{
if( fabs(nMaxElement) < fabs(cMatrix.m_pTMatrix [nCount][k]) )
{
nMaxElement = cMatrix.m_pTMatrix [nCount][k];
nMainRow = nCount;
}
}
// 将欲交换的行数存在数组中
pIntArray [2*k] = k;
pIntArray [2*k+1] = nMainRow;
// 交换行
cMatrix.SwapMatrixRow(k,nMainRow);
//Display();
// 判断是否是可逆阵
if(cMatrix.m_pTMatrix [k][k] == 0)
{
//printf("错误!此矩阵为非可逆阵!\n");
::AfxMessageBox (TEXT("此矩阵为非可逆阵,没有逆矩阵!"),MB_OK | MB_ICONERROR);
}
cMatrix.m_pTMatrix [k][k] = 1/(cMatrix.m_pTMatrix [k][k]);
// 算主列
for(unsigned int i=0; i < cMatrix.m_nRow; i++)
{
if( i != k)
cMatrix.m_pTMatrix [i][k] = -(cMatrix.m_pTMatrix [k][k]) * (cMatrix.m_pTMatrix [i][k]);
//int nTempValue = m_pTMatrix [i][k];
}
//printf("\n");
// 约化非主行
for(unsigned int m=0; m < cMatrix.m_nRow; m++)
{
if ( m == k)
continue;
for(unsigned int n=0; n < cMatrix.m_nCol; n++)
{
if ( n == k)
continue;
cMatrix.m_pTMatrix [m][n] += cMatrix.m_pTMatrix [m][k] * cMatrix.m_pTMatrix [k][n];
//printf("%10f ",m_pTMatrix [m][n]);
}
//printf("\n");
}
// 算主行
for(unsigned int j=0; j < cMatrix.m_nCol; j++)
{
if( j != k)
cMatrix.m_pTMatrix [k][j] = (cMatrix.m_pTMatrix [k][k]) * (cMatrix.m_pTMatrix [k][j]);
}
}
/////////////////////////////////////////////////////////////////////////
// 进行列交换 ---> 对交换行后的矩阵进行列交换 ---> 还原矩阵
// 游戏规则:
// 将开始矩阵中进行的行交换 ---> 现用相对应的列交换进行还原,即可得到所求的
// 逆矩阵
for(int i=2*m_nCol-1; i > 0; i--)
{
cMatrix.SwapMatrixCol(pIntArray[i],pIntArray[i-1]);
i--;
}
delete []pIntArray;
return cMatrix;
}
void CMatrix::SwapMatrixRow(unsigned int nRow1,unsigned int nRow2)
{
if( nRow1 == nRow2)
return;
double *pArray = new double;
for(unsigned int i=0; i < m_nCol; i++)
{
// Swap the datum of the two rows
pArray[0] = m_pTMatrix [nRow1][i];
m_pTMatrix [nRow1][i] = m_pTMatrix [nRow2][i];
m_pTMatrix [nRow2][i] = pArray[0];
}
delete pArray;
}
void CMatrix::SwapMatrixCol(unsigned int nCol1,unsigned int nCol2)
{
if( nCol1 == nCol2)
return;
double *pArray = new double;
for(unsigned int i=0; i < m_nRow; i++)
{
// Swap the datum of the two columns
pArray[0] = m_pTMatrix [i][nCol1];
m_pTMatrix [i][nCol1] = m_pTMatrix [i][nCol2];
m_pTMatrix [i][nCol2] = pArray[0];
}
delete pArray;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -