?? 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 ]
/////////////////////////////////////////////////////////////////////////////
//DEL CMatrix CMatrix::MergeColumnsToColumnVector()
//DEL {
//DEL CMatrix cMatrix(m_nRow * m_nCol,(unsigned int)1);
//DEL
//DEL // 對矩陣賦值
//DEL for(unsigned int j=0; j < m_nCol; j++)
//DEL {
//DEL for(unsigned int i=0; i < m_nRow; i++)
//DEL {
//DEL cMatrix.m_pTMatrix [i + j * m_nRow][(unsigned int)0] = m_pTMatrix [i][j];
//DEL }
//DEL }
//DEL
//DEL return cMatrix;
//DEL
//DEL }
/////////////////////////////////////////////////////////////////////////////
// Get the total value of the matrix
/////////////////////////////////////////////////////////////////////////////
//DEL double CMatrix::GetTotalElementValue()
//DEL {
//DEL double nTotalValue = 0;
//DEL
//DEL for(unsigned int i=0; i < m_nRow; i++)
//DEL {
//DEL for( unsigned int j=0; j < m_nCol; j++)
//DEL {
//DEL nTotalValue += m_pTMatrix [i][j];
//DEL }
//DEL }
//DEL
//DEL return nTotalValue;
//DEL }
/////////////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////////////
//DEL CMatrix CMatrix::AbsoluteValue ()
//DEL {
//DEL CMatrix cMatrix = *this;
//DEL
//DEL for(unsigned int i=0; i < m_nRow; i++)
//DEL {
//DEL for(unsigned int j=0; j < m_nCol; j++)
//DEL {
//DEL cMatrix.m_pTMatrix [i][j] = fabs( m_pTMatrix [i][j]);
//DEL
//DEL }
//DEL
//DEL }
//DEL
//DEL return cMatrix;
//DEL
//DEL }
//DEL CMatrix CMatrix::Inverse()
//DEL {
//DEL /////////////////////////////////////////////////////////////////////////
//DEL // Using Gauss - Jordan Method
//DEL // 參考書目: 計算機數值方法 --->施吉林 陳桂枝
//DEL /////////////////////////////////////////////////////////////////////////
//DEL
//DEL /////////////////////////////////////////////////////////////////////////
//DEL // 判斷是否是可逆陣:
//DEL // 可逆陣一定是方陣!!!
//DEL
//DEL if ( m_nRow != m_nCol)
//DEL {
//DEL //printf("錯誤!矩陣的行列數不相等,是非可逆陣!\n");
//DEL ::AfxMessageBox (TEXT("矩陣的行列數不相等,是非可逆陣!"),MB_OK | MB_ICONERROR);
//DEL }
//DEL
//DEL CMatrix cMatrix = *this;
//DEL
//DEL //***********************************************************************
//DEL // 思路:(非常規思維!)
//DEL // 動態分配整型數組(2*m_nCol)來存儲每次交換的行坐標的值
//DEL // 不論有沒有行交換都記錄在數組中,
//DEL // 1.沒進行行交換的兩個數據相等,在SwapMatrixRow()函數中
//DEL // 檢測到兩個值相等立即返回,在SwapMatrixCol()函數中也一樣,
//DEL // 檢測到兩個值相等立即返回,不占用系統資源;
//DEL // 2.不相等的就交換
//DEL //***********************************************************************
//DEL
//DEL // 分配內存
//DEL int *pIntArray = new int [2*m_nCol];
//DEL
//DEL // nSetp --- 約化步數,按列展開
//DEL for(unsigned int k=0; k < cMatrix.m_nCol; k++)
//DEL {
//DEL /////////////////////////////////////////////////////////////////////
//DEL // 進行行交換 ---> 游戲規則:
//DEL // 為保證計算過程的數值穩定性,在第k步約化時,先在{a(ik)}|i=k->n中選按
//DEL // 模最大者作為約化主元素,并交換矩陣相應的行
//DEL
//DEL // 標記主元素
//DEL double nMaxElement = cMatrix.m_pTMatrix [k][k];
//DEL // 標記主元素所在的行數
//DEL unsigned int nMainRow = k;
//DEL
//DEL for(unsigned int nCount = k+1; nCount < cMatrix.m_nCol; nCount++)
//DEL {
//DEL if( fabs(nMaxElement) < fabs(cMatrix.m_pTMatrix [nCount][k]) )
//DEL {
//DEL nMaxElement = cMatrix.m_pTMatrix [nCount][k];
//DEL nMainRow = nCount;
//DEL }
//DEL }
//DEL
//DEL // 將欲交換的行數存在數組中
//DEL pIntArray [2*k] = k;
//DEL pIntArray [2*k+1] = nMainRow;
//DEL
//DEL
//DEL // 交換行
//DEL cMatrix.SwapMatrixRow(k,nMainRow);
//DEL
//DEL //Display();
//DEL
//DEL // 判斷是否是可逆陣
//DEL if(cMatrix.m_pTMatrix [k][k] == 0)
//DEL {
//DEL //printf("錯誤!此矩陣為非可逆陣!\n");
//DEL ::AfxMessageBox (TEXT("此矩陣為非可逆陣,沒有逆矩陣!"),MB_OK | MB_ICONERROR);
//DEL }
//DEL
//DEL cMatrix.m_pTMatrix [k][k] = 1/(cMatrix.m_pTMatrix [k][k]);
//DEL
//DEL
//DEL // 算主列
//DEL for(unsigned int i=0; i < cMatrix.m_nRow; i++)
//DEL {
//DEL if( i != k)
//DEL cMatrix.m_pTMatrix [i][k] = -(cMatrix.m_pTMatrix [k][k]) * (cMatrix.m_pTMatrix [i][k]);
//DEL
//DEL //int nTempValue = m_pTMatrix [i][k];
//DEL
//DEL }
//DEL
//DEL //printf("\n");
//DEL
//DEL // 約化非主行
//DEL for(unsigned int m=0; m < cMatrix.m_nRow; m++)
//DEL {
//DEL if ( m == k)
//DEL continue;
//DEL
//DEL for(unsigned int n=0; n < cMatrix.m_nCol; n++)
//DEL {
//DEL if ( n == k)
//DEL continue;
//DEL
//DEL cMatrix.m_pTMatrix [m][n] += cMatrix.m_pTMatrix [m][k] * cMatrix.m_pTMatrix [k][n];
//DEL
//DEL //printf("%10f ",m_pTMatrix [m][n]);
//DEL
//DEL }
//DEL
//DEL //printf("\n");
//DEL
//DEL }
//DEL
//DEL // 算主行
//DEL for(unsigned int j=0; j < cMatrix.m_nCol; j++)
//DEL {
//DEL if( j != k)
//DEL cMatrix.m_pTMatrix [k][j] = (cMatrix.m_pTMatrix [k][k]) * (cMatrix.m_pTMatrix [k][j]);
//DEL
//DEL }
//DEL
//DEL }
//DEL
//DEL
//DEL /////////////////////////////////////////////////////////////////////////
//DEL // 進行列交換 ---> 對交換行后的矩陣進行列交換 ---> 還原矩陣
//DEL // 游戲規則:
//DEL // 將開始矩陣中進行的行交換 ---> 現用相對應的列交換進行還原,即可得到所求的
//DEL // 逆矩陣
//DEL
//DEL for(int i=2*m_nCol-1; i > 0; i--)
//DEL {
//DEL cMatrix.SwapMatrixCol(pIntArray[i],pIntArray[i-1]);
//DEL i--;
//DEL }
//DEL
//DEL delete []pIntArray;
//DEL
//DEL return cMatrix;
//DEL
//DEL }
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;
}
bool CMatrix::LoadDataFromFile(CString& strFileName)
{
CStdioFile dataFile;
LPCTSTR lpszFileName = "";
// CString convert to LPCTSTR
strFileName.TrimLeft ();
strFileName.TrimRight ();
//strFileName.Format (lpszFileName);
lpszFileName = (LPCTSTR)strFileName;
if(!dataFile.Open (lpszFileName,CFile::modeRead | CFile::typeText))
{
::AfxMessageBox (TEXT("文件打開失敗!"),MB_OK | MB_ICONERROR);
dataFile.Close ();
return FALSE;
}
// 用來存儲提取文本文件中一行的數據
CString strData;
// 用來記錄文本文件中一共有多少行數據?
unsigned int nRow = 0;
/////////////////////////////////////////////////////////////////////////
// Step 1: 得到文件的行列數目并根據文本文件的行列數目來設置對象(矩陣)的行
// 列數目
//
while(dataFile.ReadString (strData) != FALSE)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -