<手搓有限元 干翻Ansys> 【1】C++實現(xiàn)矩陣Matrix類 實現(xiàn)基本運算
本系列文章致力于實現(xiàn)“手搓有限元,干翻Ansys的目標(biāo)”,基本框架為前端顯示使用QT實現(xiàn)交互,后端計算采用Visual Studio C++。
Matrix類
矩陣基本類,用于有限元矩陣計算。
1、public function
1.1、構(gòu)造函數(shù)與析構(gòu)函數(shù)
構(gòu)造函數(shù)用來初始化矩陣,析構(gòu)函數(shù)用來釋放內(nèi)存。
Matrix.h聲明文件:
//******************************構(gòu)造函數(shù)與析構(gòu)函數(shù)********************************// /* 函數(shù)名稱: 無參構(gòu)造函數(shù) */ Matrix(); /* 函數(shù)名稱: 矩陣有參構(gòu)造函數(shù),初始化為row行、col列的0矩陣 row: 矩陣行數(shù) col: 矩陣列數(shù) */ Matrix(int row, int col); /* 函數(shù)名稱: 矩陣有參構(gòu)造函數(shù),初始化為row行、col列、數(shù)值為mat的矩陣 row: 矩陣行數(shù) col: 矩陣列數(shù) *mat: 矩陣數(shù)值一維數(shù)組 */ Matrix(int row, int col, double* mat); /* 函數(shù)名稱: 深拷貝構(gòu)造函數(shù) mat: 需要復(fù)制的矩陣 */ Matrix(const Matrix& mat); /* 函數(shù)名稱: 析構(gòu)函數(shù) */ ~Matrix();
Matrix.cpp函數(shù)實現(xiàn)文件:
Matrix::Matrix()
{
}
//初始化矩陣 默認值為0
Matrix::Matrix(int row, int col)
{
this->m_Row = row;
this->m_Col = col;
//開辟內(nèi)存
this->m_Matrix = new double* [row];
for (int i = 0; i < row; i++)
{
this->m_Matrix[i] = new double[col] {0.0};
}
}
//初始化矩陣 設(shè)定數(shù)值
Matrix::Matrix(int row, int col, double *mat)
{
this->m_Row = row;
this->m_Col = col;
//開辟內(nèi)存
this->m_Matrix = new double* [row];
for (int i = 0; i < row; i++)
{
this->m_Matrix[i] = new double[col] {0.0};
}
//矩陣賦值
for(int i = 0; i<row; i++)
{
for (int j = 0; j < col; j++)
{
this->m_Matrix[i][j] = mat[i * col + j];
}
}
}
//深拷貝
Matrix::Matrix(const Matrix& mat)
{
//行列傳遞
this->m_Row = mat.m_Row;
this->m_Col = mat.m_Col;
//矩陣深拷貝
this->m_Matrix = new double* [this->m_Row];
for (int i = 0; i < this->m_Row; i++)
{
this->m_Matrix[i] = new double[this->m_Col];
memcpy(this->m_Matrix[i], mat.m_Matrix[i], sizeof(double) * this->m_Col);
}
}
//析構(gòu)函數(shù)
Matrix::~Matrix()
{
//釋放矩陣每一行
for (int i = 0; i < this->m_Row; i++)
{
if (this->m_Matrix[i] != NULL)
{
delete[]this->m_Matrix[i];
this->m_Matrix[i] = NULL;
}
}
//釋放矩陣頂點
if (this->m_Matrix != NULL)
{
delete[]this->m_Matrix;
this->m_Matrix = NULL;
}
}
1.2、獲取矩陣數(shù)值
可以獲取矩陣指定位置數(shù)值、打印矩陣。
Matrix.h聲明文件:
//*******************獲取矩陣*****************// /* 函數(shù)名稱: 獲取矩陣的第row行、第col列元素數(shù)值 row: 矩陣行數(shù) col: 矩陣列數(shù) */ double GetMatrixEle(int row, int col);
Matrix.cpp函數(shù)實現(xiàn)文件:
//獲取矩陣某個元素 某行某列
double Matrix::GetMatrixEle(int row, int col)
{
if (row >= this->m_Row)
{
std::cout << "Error: <GetMatrixEle> Input row >= m_Row" << std::endl;
return 0.0;
}
else if (col >= this->m_Col)
{
std::cout << "Error: <GetMatrixEle> Input col >= m_Col" << std::endl;
return 0.0;
}
else
{
return this->m_Matrix[row][col];
}
}
//矩陣輸出
void Matrix::PrintMat()
{
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
std::cout.setf(std::ios::scientific); //科學(xué)計數(shù)法表示
std::cout << this->m_Matrix[i][j] << "\t";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
1.3、設(shè)置矩陣
可進行設(shè)置矩陣指定位置數(shù)值,以及深拷貝矩陣。
Matrix.h聲明文件:
//*******************設(shè)置矩陣*****************// /* 函數(shù)名稱: 設(shè)置矩陣第row行、第col列數(shù)值 row: 矩陣行數(shù) col: 矩陣列數(shù) value: 設(shè)置的矩陣數(shù)值 */ void SetMatrixEle(int row, int col, double value); /* 函數(shù)名稱: 深拷貝矩陣 mat: 需要復(fù)制的矩陣 */ Matrix CopyMat(const Matrix mat);
Matrix.cpp函數(shù)實現(xiàn)文件:
//*******************設(shè)置矩陣*****************//
void Matrix::SetMatrixEle(int row, int col, double value)
{
if (row >= this->m_Row)
{
std::cout << "Error: <SetMatrixEle> Input row >= m_Row" << std::endl;
return;
}
else if (col >= this->m_Col)
{
std::cout << "Error: <SetMatrixEle> Input col >= m_Col" << std::endl;
return;
}
else
{
this->m_Matrix[row][col] = value;
return;
}
}
//深拷貝矩陣
Matrix Matrix::CopyMat(const Matrix mat)
{
//行列傳遞
this->m_Row = mat.m_Row;
this->m_Col = mat.m_Col;
//矩陣深拷貝
this->m_Matrix = new double* [this->m_Row];
for (int i = 0; i < this->m_Row; i++)
{
this->m_Matrix[i] = new double[this->m_Col];
memcpy(this->m_Matrix[i], mat.m_Matrix[i], sizeof(double) * this->m_Col);
}
return *this;
}
1.4、矩陣轉(zhuǎn)置、單位化
可進行矩陣轉(zhuǎn)置,單位化,注意返回值類型為自身的引用,可實現(xiàn)鏈?zhǔn)骄幊獭?/p>
Matrix.h聲明文件:
//*****************矩陣基本操作***************//
/*
函數(shù)名稱: 矩陣轉(zhuǎn)置,返回的是自身引用,可鏈?zhǔn)秸{(diào)用
*/
Matrix& Transpose();
/*
函數(shù)名稱: 等維度的單位矩陣,前提是方陣
*/
Matrix& Uint();
Matrix.cpp函數(shù)實現(xiàn)文件:
//矩陣轉(zhuǎn)置
Matrix& Matrix::Transpose()
{
Matrix* resMat = new Matrix(this->m_Col, this->m_Row);
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
resMat->m_Matrix[j][i] = this->m_Matrix[i][j];
}
}
return *resMat;
}
//求等長度單位矩陣
Matrix& Matrix::Uint()
{
//矩陣是否為方陣
if (this->m_Col != this->m_Row)
{
std::cout << "Error: <Uint> Row != Col" << std::endl;
Matrix* resMat = new Matrix(this->m_Row, this->m_Row);
return *resMat;
}
else
{
//單位矩陣初始化
Matrix* resMat = new Matrix(this->m_Row, this->m_Col);
//單位矩陣生成
for (int i = 0; i < this->m_Row; i++)
{
resMat->m_Matrix[i][i] = 1.0;
}
return *resMat;
}
}
1.5、矩陣的刪除與替換
可進行矩陣指定行、列的刪除與替換,注意返回值類型為自身的引用,可實現(xiàn)鏈?zhǔn)骄幊獭?/p>
Matrix.h聲明文件:
//****************矩陣保留與剔除**************// /* 函數(shù)名稱: 剔除矩陣中以index為行標(biāo)和列標(biāo)的行和列,num代表index的大小 *index: 矩陣中的行號與列號一維數(shù)組 num: index動態(tài)數(shù)組長度 */ Matrix& DeleteMat(int *index, int num); /* 函數(shù)名稱: 剔除矩陣中以index為行標(biāo)和列標(biāo)的行和列,num代表index的大小 *index: 矩陣中的行號與列號一維動態(tài)數(shù)組 num: index動態(tài)數(shù)組長度 */ Matrix& DeleteMat(std::vector<int> index, int num); /* 函數(shù)名稱: 剔除矩陣中以index為行標(biāo)的行,num代表index的大小 *index: 矩陣中的行號一維數(shù)組 num: index動態(tài)數(shù)組長度 */ Matrix& DeleteRow(int* index, int num); /* 函數(shù)名稱: 剔除矩陣中以index為行標(biāo)的行,num代表index的大小 *index: 矩陣中的行號一維動態(tài)數(shù)組 num: index動態(tài)數(shù)組長度 */ Matrix& DeleteRow(std::vector<int> index, int num); /* 函數(shù)名稱: 剔除矩陣中以index為列標(biāo)的列,num代表index的大小 *index: 矩陣中的列號一維數(shù)組 num: index動態(tài)數(shù)組長度 */ Matrix& DeleteCol(int* index, int num); /* 函數(shù)名稱: 剔除矩陣中以index為列標(biāo)的列,num代表index的大小 *index: 矩陣中的列號一維動態(tài)數(shù)組 num: index動態(tài)數(shù)組長度 */ Matrix& DeleteCol(std::vector<int> index, int num); //******************矩陣的替換****************// /* 函數(shù)名稱: 替換矩陣中行標(biāo)和列標(biāo)為 index中的行與列,num代表index的大小, mat是需要替換 *index: 矩陣中的行標(biāo)和列標(biāo)的一維數(shù)組 num: index動態(tài)數(shù)組長度 mat: 需要替換的矩陣 */ Matrix& ReplaceMat(int* index, int num, Matrix& mat); /* 函數(shù)名稱: 替換矩陣中行標(biāo)和列標(biāo)為 index中的行與列,num代表index的大小, mat是需要替換 *index: 矩陣中的行標(biāo)和列標(biāo)的一維動態(tài)數(shù)組 num: index動態(tài)數(shù)組長度 mat: 需要替換的矩陣 */ Matrix& ReplaceMat(std::vector<int> index, int num, Matrix& mat); /* 函數(shù)名稱: 替換矩陣中行標(biāo)為 index中的行,num代表index的大小, mat是需要替換的矩陣 *index: 矩陣中的行標(biāo)的一維數(shù)組 num: index動態(tài)數(shù)組長度 mat: 需要替換的矩陣 */ Matrix& ReplaceRow(int* index, int num, Matrix& mat); /* 函數(shù)名稱: 替換矩陣中行標(biāo)為 index中的行,num代表index的大小, mat是需要替換的矩陣 *index: 矩陣中的行標(biāo)的一動態(tài)維數(shù)組 num: index動態(tài)數(shù)組長度 mat: 需要替換的矩陣 */ Matrix& ReplaceRow(std::vector<int> index, int num, Matrix& mat); /* 函數(shù)名稱: 替換矩陣中列標(biāo)為 index中的列,num代表index的大小, mat是需要替換的矩陣 *index: 矩陣中的列標(biāo)的一維數(shù)組 num: index動態(tài)數(shù)組長度 mat: 需要替換的矩陣 */ Matrix& ReplaceCol(int* index, int num, Matrix& mat); /* 函數(shù)名稱: 替換矩陣中列標(biāo)為 index中的列,num代表index的大小, mat是需要替換的矩陣 *index: 矩陣中的列標(biāo)的一維動態(tài)數(shù)組 num: index動態(tài)數(shù)組長度 mat: 需要替換的矩陣 */ Matrix& ReplaceCol(std::vector<int> index, int num, Matrix& mat);
Matrix.cpp函數(shù)實現(xiàn)文件:
//****************矩陣保留與剔除**************//
//剔除矩陣的 index中的行與列,num代表index的大小
Matrix& Matrix::DeleteMat(int* index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row - num, this->m_Col - num);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
else if (index[i] >= this->m_Col)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num-1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[recIndex[iRow]][recIndex[iCol]];
}
}
return *resMat;
}
Matrix& Matrix::DeleteMat(std::vector<int> index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row - num, this->m_Col - num);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
else if (index[i] >= this->m_Col)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[recIndex[iRow]][recIndex[iCol]];
}
}
return *resMat;
}
//剔除矩陣的 index中的行,num代表index的大小
Matrix& Matrix::DeleteRow(int* index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row - num, this->m_Col);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[recIndex[iRow]][iCol];
}
}
return *resMat;
}
Matrix& Matrix::DeleteRow(std::vector<int> index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row - num, this->m_Col);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[recIndex[iRow]][iCol];
}
}
return *resMat;
}
Matrix& Matrix::DeleteCol(int* index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row, this->m_Col - num);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[iRow][recIndex[iCol]];
}
}
return *resMat;
}
Matrix& Matrix::DeleteCol(std::vector<int> index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row, this->m_Col - num);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[iRow][recIndex[iCol]];
}
}
return *resMat;
}
//******************矩陣的替換****************//
//替換矩陣中的行和列 index中的行與列,num代表index的大小
Matrix& Matrix::ReplaceMat(int* index, int num, Matrix& mat)
{
//錯誤判定 方陣
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <ReplaceMat> this m_Col != m_Row" << std::endl;
return *this;
}
//檢驗插入矩陣為方陣
if (mat.m_Row != mat.m_Col)
{
std::cout << "Error: <ReplaceMat> mat m_Col != m_Row" << std::endl;
return *this;
}
//檢驗插入矩陣大小與num保持一致
if (mat.m_Col != num)
{
std::cout << "Error: <ReplaceMat> num != mat.m_Col" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <ReplaceMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
else if (index[i] >= this->m_Col)
{
std::cout << "Error: <ReplaceMat> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < num; iRow++)
{
for (int iCol = 0; iCol < num; iCol++)
{
resMat->m_Matrix[index[iRow]][index[iCol]] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
Matrix& Matrix::ReplaceMat(std::vector<int> index, int num, Matrix& mat)
{
//錯誤判定 方陣
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <ReplaceMat> this m_Col != m_Row" << std::endl;
return *this;
}
//檢驗插入矩陣為方陣
if (mat.m_Row != mat.m_Col)
{
std::cout << "Error: <ReplaceMat> mat m_Col != m_Row" << std::endl;
return *this;
}
//檢驗插入矩陣大小與num保持一致
if (mat.m_Col != num)
{
std::cout << "Error: <ReplaceMat> num != mat.m_Col" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <ReplaceMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
else if (index[i] >= this->m_Col)
{
std::cout << "Error: <ReplaceMat> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < num; iRow++)
{
for (int iCol = 0; iCol < num; iCol++)
{
resMat->m_Matrix[index[iRow]][index[iCol]] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
//替換矩陣中的行 index中的行,num代表index的大小, mat是需要替換的矩陣
Matrix& Matrix::ReplaceRow(int* index, int num, Matrix& mat)
{
//檢驗插入矩陣大小與num保持一致
if (mat.m_Row != num)
{
std::cout << "Error: <ReplaceRow> num != mat.m_Row" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <ReplaceRow> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//當(dāng)前矩陣列數(shù)應(yīng)與mat列數(shù)一致
if (this->m_Col != mat.m_Col)
{
std::cout << "Error: <ReplaceRow> this->m_Col != mat.m_Col" << std::endl;
return *this;
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < num; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[index[iRow]][iCol] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
Matrix& Matrix::ReplaceRow(std::vector<int> index, int num, Matrix& mat)
{
//檢驗插入矩陣大小與num保持一致
if (mat.m_Row != num)
{
std::cout << "Error: <ReplaceRow> num != mat.m_Row" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <ReplaceRow> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//當(dāng)前矩陣列數(shù)應(yīng)與mat列數(shù)一致
if (this->m_Col != mat.m_Col)
{
std::cout << "Error: <ReplaceRow> this->m_Col != mat.m_Col" << std::endl;
return *this;
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < num; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[index[iRow]][iCol] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
//替換矩陣中的列 index中的列,num代表index的大小, mat是需要替換的矩陣
Matrix& Matrix::ReplaceCol(int* index, int num, Matrix& mat)
{
//檢驗插入矩陣大小與num保持一致
if (mat.m_Col != num)
{
std::cout << "Error: <ReplaceCol> mat.m_Col != num" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Col)
{
std::cout << "Error: <ReplaceCol> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//當(dāng)前矩陣行數(shù)應(yīng)與mat行數(shù)一致
if (this->m_Row != mat.m_Row)
{
std::cout << "Error: <ReplaceCol> this->m_Row != mat.m_Row" << std::endl;
return *this;
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < num; iCol++)
{
resMat->m_Matrix[iRow][index[iCol]] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
Matrix& Matrix::ReplaceCol(std::vector<int> index, int num, Matrix& mat)
{
//檢驗插入矩陣大小與num保持一致
if (mat.m_Col != num)
{
std::cout << "Error: <ReplaceCol> mat.m_Col != num" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Col)
{
std::cout << "Error: <ReplaceCol> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//當(dāng)前矩陣行數(shù)應(yīng)與mat行數(shù)一致
if (this->m_Row != mat.m_Row)
{
std::cout << "Error: <ReplaceCol> this->m_Row != mat.m_Row" << std::endl;
return *this;
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < num; iCol++)
{
resMat->m_Matrix[iRow][index[iCol]] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
1.6、矩陣初等變換
可實現(xiàn)矩陣的初等變化,注意返回值類型為自身的引用,可實現(xiàn)鏈?zhǔn)骄幊獭?/p>
Matrix.h聲明文件:
//*****************矩陣初等變化***************// /* 函數(shù)名稱: 交換矩陣中行標(biāo)為row0與row1的元素 row0: 矩陣行標(biāo)0 row1: 矩陣行標(biāo)1 */ Matrix& SwapRow(int row0, int row1); /* 函數(shù)名稱: 交換矩陣中列標(biāo)為col0與col1的元素 col0: 矩陣列標(biāo)0 col1: 矩陣列標(biāo)1 */ Matrix& SwapCol(int col0, int col1); /* 函數(shù)名稱: 矩陣行加法 rowLocal = rowLocal + rate *rowAdd rowLocal: 矩陣行標(biāo),被加數(shù) rowAdd: 矩陣行標(biāo),加數(shù) rate: 加數(shù)前倍數(shù) */ Matrix& AddRow(int rowLocal, int rowAdd, double rate = 1.0); //矩陣加法 某列 + 倍數(shù)*某列 /* 函數(shù)名稱: 矩陣列加法 colLocal = colLocal + rate * colAdd colLocal: 矩陣列標(biāo),被加數(shù) colAdd: 矩陣列標(biāo),加數(shù) rate: 加數(shù)前倍數(shù) */ Matrix& AddCol(int colLocal, int colAdd, double rate = 1.0);
Matrix.cpp函數(shù)實現(xiàn)文件:
//*****************矩陣初等變化***************//
Matrix& Matrix::SwapRow(int row0, int row1)
{
//錯誤判定 越界
if ((this->m_Row <= row0) || (this->m_Col <= row1))
{
std::cout << "Error: <SwapRow> Input row0 Or row1 More Than m_Row" << std::endl;
return *this;
}
else if ((0 > row0) || (0 > row1))
{
std::cout << "Error: <SwapRow> Input row0 Or row1 Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//中轉(zhuǎn)臨時變量
double temp = 0.0;
for (int j = 0; j < resMat->m_Col; j++)
{
temp = resMat->m_Matrix[row0][j];
resMat->m_Matrix[row0][j] = resMat->m_Matrix[row1][j];
resMat->m_Matrix[row1][j] = temp;
}
return*resMat;
}
}
Matrix& Matrix::SwapCol(int col0, int col1)
{
//錯誤判定 越界
if ((this->m_Col <= col0) || (this->m_Col <= col1))
{
std::cout << "Error: <SwapCol> Input col0 Or col1 More Than m_Col" << std::endl;
return *this;
}
else if ((0 > col0) || (0 > col1))
{
std::cout << "Error: <SwapCol> Input col0 Or col1 Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//中轉(zhuǎn)臨時變量
double temp = 0.0;
for (int i = 0; i < resMat->m_Row; i++)
{
temp = resMat->m_Matrix[i][col0];
resMat->m_Matrix[i][col0] = resMat->m_Matrix[i][col1];
resMat->m_Matrix[i][col1] = temp;
}
return*resMat;
}
}
//矩陣加法 某行 + 倍數(shù)*某行
Matrix& Matrix::AddRow(int rowLocal, int rowAdd, double rate)
{
if ((this->m_Row <= rowLocal) || (this->m_Row <= rowAdd))
{
std::cout << "Error: <AddRow> Input rowLocal Or rowAdd More Than m_Row" << std::endl;
return *this;
}
else if ((0 > rowLocal) || (0 > rowAdd))
{
std::cout << "Error: <AddRow> Input rowLocal Or rowAdd Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//指定行相加
for (int j = 0; j < resMat->m_Col; j++)
{
resMat->m_Matrix[rowLocal][j] += rate * resMat->m_Matrix[rowAdd][j];
}
return *resMat;
}
}
//矩陣加法 某列 + 倍數(shù)*某列
Matrix& Matrix::AddCol(int colLocal, int colAdd, double rate)
{
if ((this->m_Col <= colLocal) || (this->m_Col <= colAdd))
{
std::cout << "Error: <AddCol> Input colLocal Or colAdd More Than m_Col" << std::endl;
return *this;
}
else if ((0 > colLocal) || (0 > colAdd))
{
std::cout << "Error: <AddCol> Input colLocal Or colAdd Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//指定列相加
for (int i = 0; i < resMat->m_Row; i++)
{
resMat->m_Matrix[i][colLocal] += rate * resMat->m_Matrix[i][colAdd];
}
return *resMat;
}
}
1.7、矩陣加法
實現(xiàn)矩陣基本加法,注意返回值類型為自身的引用,可實現(xiàn)鏈?zhǔn)骄幊獭?/p>
Matrix.h聲明文件:
//*******************矩陣加法*****************// /* 函數(shù)名稱: 矩陣加法 本矩陣 = 本矩陣 + mat 前提是兩個矩陣維度一致 mat: 加數(shù)矩陣 */ Matrix& AddMat(Matrix& mat);
Matrix.cpp函數(shù)實現(xiàn)文件:
//*******************矩陣加法*****************//
Matrix& Matrix::AddMat(Matrix& mat)
{
Matrix* ResMat = new Matrix(*this);
for (int i = 0; i < ResMat->m_Row; i++)
{
for (int j = 0; j < ResMat->m_Col; j++)
{
ResMat->m_Matrix[i][j] += mat.m_Matrix[i][j];
}
}
return *ResMat;
}
1.8、矩陣乘法
實現(xiàn)矩陣基本乘法,注意返回值類型為自身的引用,可實現(xiàn)鏈?zhǔn)骄幊獭?/p>
Matrix.h聲明文件:
//*******************矩陣乘法*****************// /* 函數(shù)名稱: 矩陣乘法 本矩陣 = 本矩陣*num num: 矩陣乘數(shù) */ Matrix& MultNum(double num); /* 函數(shù)名稱: 矩陣乘法(運算符重載) 本矩陣 = 本矩陣*num num: 矩陣乘數(shù) */ Matrix& operator * (double num); /* 函數(shù)名稱: 矩陣某行乘數(shù)值row = row*num num: 矩陣某列乘數(shù) row: 矩陣行標(biāo) */ Matrix& MultRow(double num, int row); /* 函數(shù)名稱: 矩陣某列乘數(shù)值col = col *num num: 矩陣某列乘數(shù) col: 矩陣列標(biāo) */ Matrix& MultCol(double num, int col); /* 函數(shù)名稱: 矩陣乘法,按照矩陣相乘規(guī)則 inputMat: 乘數(shù)矩陣 */ Matrix& MultMat(Matrix& inputMat);
Matrix.cpp函數(shù)實現(xiàn)文件:
//*******************矩陣乘法*****************//
//矩陣數(shù)乘
Matrix& Matrix::MultNum(double num)
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(this->m_Row, this->m_Col);
//乘后矩陣生成
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
resMat->m_Matrix[i][j] = num * this->m_Matrix[i][j];
}
}
return *resMat;
}
//運算符重載 矩陣數(shù)乘
Matrix& Matrix::operator*(double num)
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(this->m_Row, this->m_Col);
//乘后矩陣生成
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
resMat->m_Matrix[i][j] = num * this->m_Matrix[i][j];
}
}
return *resMat;
}
//矩陣某行乘數(shù)值 行標(biāo)從0開始計數(shù)
Matrix& Matrix::MultRow(double num, int row)
{
if (this->m_Row <= row)
{
std::cout << "Error: <MultRow> Input row More Than m_Row" << std::endl;
return *this;
}
else if (0 > row)
{
std::cout << "Error: <MultRow> Input row Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//乘后矩陣生成
for (int j = 0; j < this->m_Col; j++)
{
resMat->m_Matrix[row][j] = num * this->m_Matrix[row][j];
}
return *resMat;
}
}
//矩陣某列乘數(shù)值 列標(biāo)從0開始計數(shù)
Matrix& Matrix::MultCol(double num, int col)
{
if (this->m_Col <= col)
{
std::cout << "Error: <MultCol> Input col More Than m_Row" << std::endl;
return *this;
}
else if (0 > col)
{
std::cout << "Error: <MultCol> Input col Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//乘后矩陣生成
for (int i = 0; i < this->m_Row; i++)
{
resMat->m_Matrix[i][col] = num * this->m_Matrix[i][col];
}
return *resMat;
}
}
//矩陣相乘
Matrix& Matrix::MultMat(Matrix& inputMat)
{
Matrix *resMat = new Matrix(this->m_Row, inputMat.m_Col);
if (this->m_Col != inputMat.m_Row)
{
std::cout << "Matrix Mult Error!" << std::endl;
return *resMat;
}
else
{
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < inputMat.m_Col; j++)
{
for (int k = 0; k < this->m_Col; k++)
{
resMat->m_Matrix[i][j] += this->m_Matrix[i][k] * inputMat.m_Matrix[k][j];
}
}
}
return *resMat;
}
}
1.9、行列式相關(guān)操作
實現(xiàn)行列式計算相關(guān)操作。
Matrix.h聲明文件:
//******************行列式相關(guān)操作***********************// /* 函數(shù)名稱: 求解矩陣對應(yīng)行列式數(shù)值,前提為方陣,按照定義求解,時間復(fù)雜度為O(n!*n),一般不用此方法求解 */ double Det(); /* 函數(shù)名稱: 求解矩陣對應(yīng)行列式的順序主子式,前提為方陣,按照定義求解,時間復(fù)雜度為O(n!*n),一般不用此方法求解 order: 階數(shù) */ double Det(int order); /* 函數(shù)名稱: 矩陣行標(biāo)為row、列標(biāo)為col的余子式 row: 矩陣行標(biāo) col: 矩陣列標(biāo) */ Matrix& ChildMatrix(int row, int col); /* 函數(shù)名稱: 通過高斯列主消元求解矩陣行列式數(shù)值,最為常用 */ double DetRow();
Matrix.cpp函數(shù)實現(xiàn)文件:
//矩陣的行列式數(shù)值
double Matrix::Det()
{
double res = 0.0;
int sign = 1;
if (this->m_Row != this->m_Col)
{
//錯誤判定
std::cout << "Error: <Det> Matrix Col != Row" << std::endl;
return 0;
}
else if (this->m_Row <= 1)
{
//程序終止出口
return this->m_Matrix[0][0];
}
else
{
for (int i = 0; i < this->m_Col; i++)
{
Matrix* temp = &(this->ChildMatrix(0, i));
res += sign * this->m_Matrix[0][i] * (temp->Det());
sign = -1*sign;
delete temp;
}
}
}
//矩陣行列式順序主子式 order階數(shù)
double Matrix::Det(int order)
{
if (this->m_Row != this->m_Col)
{
//錯誤判定
std::cout << "Error: <Det> Matrix Col != Row" << std::endl;
return 0;
}
else if (order < 0)
{
std::cout << "Error: <Det> Input Order Less 0" << std::endl;
return 0;
}
else if (order >= this->m_Row)
{
std::cout << "Error: <Det> Input Order More Than Row" << std::endl;
return 0;
}
else
{
Matrix tempMat(order + 1, order + 1);
for (int i = 0; i < tempMat.m_Col; i++)
{
for (int j = 0; j < tempMat.m_Row; j++)
{
tempMat.m_Matrix[i][j] = this->m_Matrix[i][j];
}
}
return tempMat.Det();
}
}
//求解余子式
Matrix& Matrix::ChildMatrix(int row, int col)
{
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <ChildMatrix> Matrix row != col" << std::endl;
return *this;
}
else if (this->m_Row <= 1)
{
std::cout << "Error: <ChildMatrix> Matrix Row Less 1 " << std::endl;
return *this;
}
else if ((row > this->m_Row) || (col > this->m_Col))
{
std::cout << "Error: <ChildMatrix> Input Row Or Col More Than Matix Max Row Or Col" << std::endl;
return* this;
}
else
{
Matrix* resMat = new Matrix(this->m_Row-1, this->m_Col-1);
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
if ((i < row) && (j < col))
resMat->m_Matrix[i][j] = this->m_Matrix[i][j];
else if((i > row) && (j < col))
resMat->m_Matrix[i-1][j] = this->m_Matrix[i][j];
else if((i < row) && (j > col))
resMat->m_Matrix[i][j - 1] = this->m_Matrix[i][j];
else if((i > row) && (j > col))
resMat->m_Matrix[i - 1][j - 1] = this->m_Matrix[i][j];
}
}
return *resMat;
}
}
//列主消元處理為上三角矩陣
double Matrix::DetRow()
{
//交換標(biāo)志位 1代表偶數(shù)次交換 -1代表奇數(shù)次交換
int flagShift = 1;
//本矩陣
Matrix *localMat = new Matrix(*this);
//行列式數(shù)值
double resDet = 1.0;
//*******************通過交換 num1*i + num2*j 實現(xiàn)下三角為0***************//
for (int i = 0; i < localMat->m_Row - 1; i++)
{
//記錄最大行所在行標(biāo)
int tempMaxRow = i;
for (int i1 = i + 1; i1 < localMat->m_Row; i1++)
{
if (abs(localMat->m_Matrix[i1][i]) > abs(localMat->m_Matrix[tempMaxRow][i]))
{
tempMaxRow = i1;
}
}
if (tempMaxRow != i)
{
//std::cout << i << " 行交換" << tempMaxRow << " 行" << std::endl;
//進行交換 將當(dāng)前第i行與第tempMaxRow行進行互換 初等行變換
*localMat = localMat->SwapRow(i, tempMaxRow);
//記錄交換次數(shù)
flagShift = -flagShift;
//localMat->PrintMat();
}
//此對角線以下的元素通過初等變化為0
for (int i2 = i + 1; i2 < localMat->m_Row; i2++)
{
if (localMat->m_Matrix[i2][i] != 0)
{
//std::cout << "<" << localMat->m_Matrix[i][i] << "> *" << i2 << " 行 + <" << -1.0 * (localMat->m_Matrix[i2][i]) << "> *" << i << " 行" << std::endl;
*localMat = localMat->AddRow(i2, i, -1.0 * (localMat->m_Matrix[i2][i]) / localMat->m_Matrix[i][i]);
//localMat->PrintMat();
}
}
}
//計算行列式數(shù)值 對角線相乘
for (int i = 0; i < localMat->m_Row; i++)
{
resDet = resDet * localMat->m_Matrix[i][i];
}
//矩陣交換一次就會變號
resDet = flagShift * resDet;
//清理localMatrix
delete localMat;
return resDet;
}
1.10、矩陣求逆
實現(xiàn)矩陣求逆相關(guān)操作
Matrix.h聲明文件:
//*********************矩陣求逆********************// /* 函數(shù)名稱: 矩陣求逆,按照定義求解,1/|A|*(A*),時間復(fù)雜度為O(n!*n),一般不用此方法 */ Matrix& Inverse(); /* 函數(shù)名稱: 矩陣求逆,通過行初等變化,高斯列主消元法求解 */ Matrix& InverseRow(); /* 函數(shù)名稱: 矩陣求逆,只針對于下三角矩陣進行求解 */ Matrix& InverseDownTriangle(); /* 函數(shù)名稱: 矩陣求逆,只針對于上三角矩陣進行求解 */ Matrix& InverseUpTriangle(); //矩陣LU分解 /* 函數(shù)名稱: 矩陣LU分解 LMat: 矩陣分解后的L矩陣 UMat: 矩陣分解后的U矩陣 */ void ResolveLU(Matrix& LMat, Matrix& UMat); /* 函數(shù)名稱: 矩陣的LUP分解 P*A = L*U 添加了列主消元功能 LMat: 矩陣分解后的L矩陣 UMat: 矩陣分解后的U矩陣 PMat: 矩陣分解后的P矩陣 */ void ResolveLUP(Matrix& LMat, Matrix& UMat, Matrix& PMat);
Matrix.cpp函數(shù)實現(xiàn)文件:
//矩陣求逆
Matrix& Matrix::Inverse()
{
if (abs(this->DetRow()) < MIN_DET)
{
std::cout << "Error: <Inverse> Matrix Det Near 0" << std::endl;
return *this;
}
else
{
Matrix* resMat = new Matrix(this->m_Row, this->m_Col);
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
Matrix* temp = &(this->ChildMatrix(j, i));
resMat->m_Matrix[i][j] = pow(-1.0, (i + j)) / this->DetRow() * (temp->DetRow());
delete temp;
}
}
return *resMat;
}
}
//矩陣求逆 行初等變化
Matrix& Matrix::InverseRow()
{
//錯誤判斷
if (abs(this->DetRow()) < MIN_DET)
{
std::cout << "Error: <InverseRow> Matrix Det Near 0" << std::endl;
return *this;
}
else if (this->m_Row <= 1)
{
std::cout << "Error: <InverseRow> Size Less 2" << std::endl;
return *this;
}
else
{
//單位矩陣 與帶轉(zhuǎn)換矩陣維度相同的
Matrix uint = this->Uint();
//結(jié)果矩陣 逆矩陣 初始狀態(tài)與本矩陣相同 為不使本矩陣發(fā)生改變
Matrix temp(this->m_Row, this->m_Col);
Matrix* resMat = new Matrix(temp.Uint());
//本矩陣
Matrix localMat(*this);
//*******************通過交換 num1*i + num2*j 實現(xiàn)下三角為0***************//
for (int i = 0; i < localMat.m_Row - 1; i++)
{
//記錄最大行所在行標(biāo)
int tempMaxRow = i;
for (int i1 = i + 1; i1 < localMat.m_Row; i1++)
{
if (abs(localMat.m_Matrix[i1][i]) > abs(localMat.m_Matrix[tempMaxRow][i]))
{
tempMaxRow = i1;
}
}
if (tempMaxRow != i)
{
//std::cout << i << " 行交換" << tempMaxRow << " 行" << std::endl;
//進行交換 將當(dāng)前第i行與第tempMaxRow行進行互換 初等行變換
localMat = localMat.SwapRow(i, tempMaxRow);
*resMat = resMat->SwapRow(i, tempMaxRow);
//localMat.PrintMat();
}
//此對角線以下的元素通過初等變化為0
for (int i2 = i + 1; i2 < localMat.m_Row; i2++)
{
if (localMat.m_Matrix[i2][i] != 0)
{
//std::cout << "<" << localMat.m_Matrix[i][i] << "> *" << i2 << " 行 + <" << -1.0 * (localMat.m_Matrix[i2][i]) << "> *" << i << " 行" << std::endl;
*resMat = resMat->AddRow(i2, i, -1.0 * (localMat.m_Matrix[i2][i]) / localMat.m_Matrix[i][i]);
localMat = localMat.AddRow(i2, i, -1.0 * (localMat.m_Matrix[i2][i]) / localMat.m_Matrix[i][i]);
//localMat.PrintMat();
}
}
}
//錯誤判斷
if (localMat.m_Matrix[localMat.m_Row - 1][localMat.m_Col - 1] == 0)
{
std::cout << "Error: <InverseRow> marix[" << localMat.m_Row - 1 << "][" << localMat.m_Col - 1 <<"] == 0" << std::endl;
return *this;
}
//*******************通過 num1*i + num2*j 實現(xiàn)上三角為0***************//
for (int i = localMat.m_Row - 1; i > 0; i--)
{
for (int i2 = i - 1; i2 >= 0; i2--)
{
if (localMat.m_Matrix[i2][i] != 0)
{
//std::cout << "<" << localMat.m_Matrix[i][i] << "> *" << i2 << " 行 + <" << -1.0 * (localMat.m_Matrix[i2][i]) << "> *" << i << " 行" << std::endl;
*resMat = resMat->AddRow(i2, i, -1.0 * (localMat.m_Matrix[i2][i]) / localMat.m_Matrix[i][i]);
localMat = localMat.AddRow(i2, i, -1.0 * (localMat.m_Matrix[i2][i]) / localMat.m_Matrix[i][i]);
//localMat.PrintMat();
}
}
}
//*******************通過 i*num 實現(xiàn)矩陣為單位矩陣***************//
for (int i = 0; i < localMat.m_Row; i++)
{
if (localMat.m_Matrix[i][i] == 0)
{
std::cout << "Error: <InverseRow> matrix[" << i << "]" << "[" << i << "] == 0" << std::endl;
return *this;
}
else
{
//std::cout << "<" << 1 / localMat.m_Matrix[i][i] << "> *" << i << " 行" << std::endl;
*resMat = resMat->MultRow(1 / localMat.m_Matrix[i][i], i);
localMat = localMat.MultRow(1 / localMat.m_Matrix[i][i], i);
//localMat.PrintMat();
}
}
return *resMat;
}
}
//矩陣求逆 下三角矩陣
Matrix& Matrix::InverseDownTriangle()
{
//錯誤判斷 方陣檢測
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <InverseDownTriangle> Matrix Col != Row" << std::endl;
return *this;
}
//下三角求逆
Matrix* resMat = new Matrix(*this);
for (int i = 0; i < resMat->m_Row; i++)
{
for (int j = 0; j <= i; j++)
{
//分段求解 對角線為倒數(shù)
if (i == j)
{
resMat->m_Matrix[i][j] = 1 / resMat->m_Matrix[i][j];
}
else
{
//分段求解 非對角線元素
double tempSum = 0.0;
for (int k = j; k <= i - 1; k++)
{
tempSum += resMat->m_Matrix[i][k] * resMat->m_Matrix[k][j];
}
resMat->m_Matrix[i][j] = -1.0*tempSum / resMat->m_Matrix[i][i];
}
}
}
return *resMat;
}
//矩陣求逆 上三角矩陣
Matrix& Matrix::InverseUpTriangle()
{
//錯誤判斷 方陣檢測
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <InverseUpTriangle> Matrix Col != Row" << std::endl;
return *this;
}
//上三角求逆
Matrix* resMat = new Matrix(*this);
for (int j = resMat->m_Col-1; j >=0; j--)
{
for (int i = j; i >=0; i--)
{
//分段求解 對角線為倒數(shù)
if (i == j)
{
resMat->m_Matrix[i][j] = 1 / resMat->m_Matrix[i][j];
}
else
{
//分段求解 非對角線元素
double tempSum = 0.0;
for (int k = j; k >= i+1; k--)
{
tempSum += resMat->m_Matrix[i][k] * resMat->m_Matrix[k][j];
}
resMat->m_Matrix[i][j] = -1.0 * tempSum / resMat->m_Matrix[i][i];
}
}
}
return *resMat;
}
//矩陣LU分解 順序分解 對于病態(tài)矩陣可能存在精度問題
void Matrix::ResolveLU(Matrix& LMat, Matrix& UMat)
{
if (this->m_Col != this->m_Row)
{
std::cout << "Error: <ResolveLU> Is Not Square Matrix" << std::endl;
return;
}
//存在性判定 順序主子式不為0
for (int i = 0; i < this->m_Row; i++)
{
if (this->Det(i) == 0)
{
std::cout << "Error: <ResolveLU> order Det = 0" << std::endl;
return;
}
}
//LU 分解
//L矩陣為單位矩陣
LMat = this->Uint();
//U矩陣初始化為空矩陣
Matrix temp(this->m_Row, this->m_Col);
UMat = temp;
for (int i = 0; i < this->m_Row; i++)
{
//計算U
for (int j1 = i; j1 < this->m_Col; j1++)
{
double tempSum1 = 0.0;
if (i != 0)
{
for (int j2 = 0; j2 <= i - 1; j2++)
{
tempSum1 += LMat.m_Matrix[i][j2] * UMat.m_Matrix[j2][j1];
}
}
UMat.m_Matrix[i][j1] = this->m_Matrix[i][j1] - tempSum1;
}
//計算L
for (int i1 = i; i1 < this->m_Row; i1++)
{
double tempSum2 = 0.0;
if (i != 0)
{
for (int j2 = 0; j2 <= i - 1; j2++)
{
tempSum2 += LMat.m_Matrix[i1][j2] * UMat.m_Matrix[j2][i];
}
}
LMat.m_Matrix[i1][i] = (this->m_Matrix[i1][i] - tempSum2)/UMat.m_Matrix[i][i];
}
}
}
//矩陣的LUP分解 P*A = L*U 添加了列主消元功能
//L為主對角線元素為1的下三角矩陣 U為上二角矩陣 P為行交換矩陣 P*A=L*U
void Matrix::ResolveLUP(Matrix& LMat, Matrix& UMat, Matrix& PMat)
{
//條件判斷 矩陣行列式不為0
if (this->Det() == 0)
{
std::cout << "Error: <ResolveLUP> Can't Resolve Matrix To L U P" << std::endl;
return;
}
//初始化 L U P
LMat = this->Uint();
PMat = this->Uint();
UMat = *this;
//進行分解計算
for (int i = 0; i < UMat.m_Row - 1; i++)
{
//記錄最大行所在行標(biāo)
int tempMaxRow = i;
for (int i1 = i + 1; i1 < UMat.m_Row; i1++)
{
if (abs(UMat.m_Matrix[i1][i]) > abs(UMat.m_Matrix[tempMaxRow][i]))
{
tempMaxRow = i1;
}
}
//進行交換 將當(dāng)前第i行與第tempMaxRow行進行互換 初等行變換
UMat = UMat.SwapRow(i, tempMaxRow);
//L矩陣做出對應(yīng)交換 先交換<itempMaxRow>列再交換<itempMaxRow>行
LMat = LMat.SwapCol(i, tempMaxRow);
LMat = LMat.SwapRow(i, tempMaxRow);
//P矩陣做出對應(yīng)變換 交換<itempMaxRow>行
PMat = PMat.SwapRow(i, tempMaxRow);
//高斯消元 V矩陣消除下三角區(qū)域,L矩陣添加下三角區(qū)域
for (int i1 = i + 1; i1 < UMat.m_Row; i1++)
{
//記錄消元系數(shù)
double deleteVar = UMat.m_Matrix[i1][i] / UMat.m_Matrix[i][i];
//L矩陣列填充
LMat.m_Matrix[i1][i] = deleteVar;
//U矩陣列消除
UMat = UMat.MultRow(UMat.m_Matrix[i][i], i1).AddRow(i1, i, -1.0 * UMat.m_Matrix[i1][i]).MultRow(1 / UMat.m_Matrix[i][i], i1);
}
}
return;
}
2、private variable
double** m_Matrix; //矩陣 int m_Row; //矩陣行數(shù) int m_Col; //矩陣列數(shù)
3、全部源碼
為了方便大家復(fù)制應(yīng)用,這里直接貼出源碼。
Matrix.h聲明文件:
#ifndef _MATRIX_H_
#define _MATRIX_H_
#include <iostream>
#include <math.h>
#include <vector>
//矩陣最大容量
#define MAX_COUNT 500
#define MIN_DET 1e-12 //行列式最小數(shù)值
class Matrix
{
public:
//******************************構(gòu)造函數(shù)與析構(gòu)函數(shù)********************************//
/*
函數(shù)名稱: 無參構(gòu)造函數(shù)
*/
Matrix();
/*
函數(shù)名稱: 矩陣有參構(gòu)造函數(shù),初始化為row行、col列的0矩陣
row: 矩陣行數(shù)
col: 矩陣列數(shù)
*/
Matrix(int row, int col);
/*
函數(shù)名稱: 矩陣有參構(gòu)造函數(shù),初始化為row行、col列、數(shù)值為mat的矩陣
row: 矩陣行數(shù)
col: 矩陣列數(shù)
*mat: 矩陣數(shù)值一維數(shù)組
*/
Matrix(int row, int col, double* mat);
/*
函數(shù)名稱: 深拷貝構(gòu)造函數(shù)
mat: 需要復(fù)制的矩陣
*/
Matrix(const Matrix& mat);
/*
函數(shù)名稱: 析構(gòu)函數(shù)
*/
~Matrix();
//*******************獲取矩陣*****************//
/*
函數(shù)名稱: 獲取矩陣的第row行、第col列元素數(shù)值
row: 矩陣行數(shù)
col: 矩陣列數(shù)
*/
double GetMatrixEle(int row, int col);
//*******************設(shè)置矩陣*****************//
/*
函數(shù)名稱: 設(shè)置矩陣第row行、第col列數(shù)值
row: 矩陣行數(shù)
col: 矩陣列數(shù)
value: 設(shè)置的矩陣數(shù)值
*/
void SetMatrixEle(int row, int col, double value);
/*
函數(shù)名稱: 深拷貝矩陣
mat: 需要復(fù)制的矩陣
*/
Matrix CopyMat(const Matrix mat);
//********************************矩陣的相關(guān)計算**********************************//
//*******************打印矩陣*****************//
/*
函數(shù)名稱: 打印矩陣
*/
void PrintMat();
//*****************矩陣基本操作***************//
/*
函數(shù)名稱: 矩陣轉(zhuǎn)置,返回的是自身引用,可鏈?zhǔn)秸{(diào)用
*/
Matrix& Transpose();
/*
函數(shù)名稱: 等維度的單位矩陣,前提是方陣
*/
Matrix& Uint();
//****************矩陣保留與剔除**************//
/*
函數(shù)名稱: 剔除矩陣中以index為行標(biāo)和列標(biāo)的行和列,num代表index的大小
*index: 矩陣中的行號與列號一維數(shù)組
num: index動態(tài)數(shù)組長度
*/
Matrix& DeleteMat(int *index, int num);
/*
函數(shù)名稱: 剔除矩陣中以index為行標(biāo)和列標(biāo)的行和列,num代表index的大小
*index: 矩陣中的行號與列號一維動態(tài)數(shù)組
num: index動態(tài)數(shù)組長度
*/
Matrix& DeleteMat(std::vector<int> index, int num);
/*
函數(shù)名稱: 剔除矩陣中以index為行標(biāo)的行,num代表index的大小
*index: 矩陣中的行號一維數(shù)組
num: index動態(tài)數(shù)組長度
*/
Matrix& DeleteRow(int* index, int num);
/*
函數(shù)名稱: 剔除矩陣中以index為行標(biāo)的行,num代表index的大小
*index: 矩陣中的行號一維動態(tài)數(shù)組
num: index動態(tài)數(shù)組長度
*/
Matrix& DeleteRow(std::vector<int> index, int num);
/*
函數(shù)名稱: 剔除矩陣中以index為列標(biāo)的列,num代表index的大小
*index: 矩陣中的列號一維數(shù)組
num: index動態(tài)數(shù)組長度
*/
Matrix& DeleteCol(int* index, int num);
/*
函數(shù)名稱: 剔除矩陣中以index為列標(biāo)的列,num代表index的大小
*index: 矩陣中的列號一維動態(tài)數(shù)組
num: index動態(tài)數(shù)組長度
*/
Matrix& DeleteCol(std::vector<int> index, int num);
//******************矩陣的替換****************//
/*
函數(shù)名稱: 替換矩陣中行標(biāo)和列標(biāo)為 index中的行與列,num代表index的大小, mat是需要替換的矩陣
*index: 矩陣中的行標(biāo)和列標(biāo)的一維數(shù)組
num: index動態(tài)數(shù)組長度
mat: 需要替換的矩陣
*/
Matrix& ReplaceMat(int* index, int num, Matrix& mat);
/*
函數(shù)名稱: 替換矩陣中行標(biāo)和列標(biāo)為 index中的行與列,num代表index的大小, mat是需要替換的矩陣
*index: 矩陣中的行標(biāo)和列標(biāo)的一維動態(tài)數(shù)組
num: index動態(tài)數(shù)組長度
mat: 需要替換的矩陣
*/
Matrix& ReplaceMat(std::vector<int> index, int num, Matrix& mat);
/*
函數(shù)名稱: 替換矩陣中行標(biāo)為 index中的行,num代表index的大小, mat是需要替換的矩陣
*index: 矩陣中的行標(biāo)的一維數(shù)組
num: index動態(tài)數(shù)組長度
mat: 需要替換的矩陣
*/
Matrix& ReplaceRow(int* index, int num, Matrix& mat);
/*
函數(shù)名稱: 替換矩陣中行標(biāo)為 index中的行,num代表index的大小, mat是需要替換的矩陣
*index: 矩陣中的行標(biāo)的一動態(tài)維數(shù)組
num: index動態(tài)數(shù)組長度
mat: 需要替換的矩陣
*/
Matrix& ReplaceRow(std::vector<int> index, int num, Matrix& mat);
/*
函數(shù)名稱: 替換矩陣中列標(biāo)為 index中的列,num代表index的大小, mat是需要替換的矩陣
*index: 矩陣中的列標(biāo)的一維數(shù)組
num: index動態(tài)數(shù)組長度
mat: 需要替換的矩陣
*/
Matrix& ReplaceCol(int* index, int num, Matrix& mat);
/*
函數(shù)名稱: 替換矩陣中列標(biāo)為 index中的列,num代表index的大小, mat是需要替換的矩陣
*index: 矩陣中的列標(biāo)的一維動態(tài)數(shù)組
num: index動態(tài)數(shù)組長度
mat: 需要替換的矩陣
*/
Matrix& ReplaceCol(std::vector<int> index, int num, Matrix& mat);
//*****************矩陣初等變化***************//
/*
函數(shù)名稱: 交換矩陣中行標(biāo)為row0與row1的元素
row0: 矩陣行標(biāo)0
row1: 矩陣行標(biāo)1
*/
Matrix& SwapRow(int row0, int row1);
/*
函數(shù)名稱: 交換矩陣中列標(biāo)為col0與col1的元素
col0: 矩陣列標(biāo)0
col1: 矩陣列標(biāo)1
*/
Matrix& SwapCol(int col0, int col1);
/*
函數(shù)名稱: 矩陣行加法 rowLocal = rowLocal + rate *rowAdd
rowLocal: 矩陣行標(biāo),被加數(shù)
rowAdd: 矩陣行標(biāo),加數(shù)
rate: 加數(shù)前倍數(shù)
*/
Matrix& AddRow(int rowLocal, int rowAdd, double rate = 1.0);
//矩陣加法 某列 + 倍數(shù)*某列
/*
函數(shù)名稱: 矩陣列加法 colLocal = colLocal + rate * colAdd
colLocal: 矩陣列標(biāo),被加數(shù)
colAdd: 矩陣列標(biāo),加數(shù)
rate: 加數(shù)前倍數(shù)
*/
Matrix& AddCol(int colLocal, int colAdd, double rate = 1.0);
//*******************矩陣加法*****************//
/*
函數(shù)名稱: 矩陣加法 本矩陣 = 本矩陣 + mat 前提是兩個矩陣維度一致
mat: 加數(shù)矩陣
*/
Matrix& AddMat(Matrix& mat);
//*******************矩陣乘法*****************//
/*
函數(shù)名稱: 矩陣乘法 本矩陣 = 本矩陣*num
num: 矩陣乘數(shù)
*/
Matrix& MultNum(double num);
/*
函數(shù)名稱: 矩陣乘法(運算符重載) 本矩陣 = 本矩陣*num
num: 矩陣乘數(shù)
*/
Matrix& operator * (double num);
/*
函數(shù)名稱: 矩陣某行乘數(shù)值row = row*num
num: 矩陣某列乘數(shù)
row: 矩陣行標(biāo)
*/
Matrix& MultRow(double num, int row);
/*
函數(shù)名稱: 矩陣某列乘數(shù)值col = col *num
num: 矩陣某列乘數(shù)
col: 矩陣列標(biāo)
*/
Matrix& MultCol(double num, int col);
/*
函數(shù)名稱: 矩陣乘法,按照矩陣相乘規(guī)則
inputMat: 乘數(shù)矩陣
*/
Matrix& MultMat(Matrix& inputMat);
//******************行列式相關(guān)操作***********************//
/*
函數(shù)名稱: 求解矩陣對應(yīng)行列式數(shù)值,前提為方陣,按照定義求解,時間復(fù)雜度為O(n!*n),一般不用此方法求解
*/
double Det();
/*
函數(shù)名稱: 求解矩陣對應(yīng)行列式的順序主子式,前提為方陣,按照定義求解,時間復(fù)雜度為O(n!*n),一般不用此方法求解
order: 階數(shù)
*/
double Det(int order);
/*
函數(shù)名稱: 矩陣行標(biāo)為row、列標(biāo)為col的余子式
row: 矩陣行標(biāo)
col: 矩陣列標(biāo)
*/
Matrix& ChildMatrix(int row, int col);
/*
函數(shù)名稱: 通過高斯列主消元求解矩陣行列式數(shù)值,最為常用
*/
double DetRow();
//*********************矩陣求逆********************//
/*
函數(shù)名稱: 矩陣求逆,按照定義求解,1/|A|*(A*),時間復(fù)雜度為O(n!*n),一般不用此方法
*/
Matrix& Inverse();
/*
函數(shù)名稱: 矩陣求逆,通過行初等變化,高斯列主消元法求解
*/
Matrix& InverseRow();
/*
函數(shù)名稱: 矩陣求逆,只針對于下三角矩陣進行求解
*/
Matrix& InverseDownTriangle();
/*
函數(shù)名稱: 矩陣求逆,只針對于上三角矩陣進行求解
*/
Matrix& InverseUpTriangle();
//矩陣LU分解
/*
函數(shù)名稱: 矩陣LU分解
LMat: 矩陣分解后的L矩陣
UMat: 矩陣分解后的U矩陣
*/
void ResolveLU(Matrix& LMat, Matrix& UMat);
/*
函數(shù)名稱: 矩陣的LUP分解 P*A = L*U 添加了列主消元功能
LMat: 矩陣分解后的L矩陣
UMat: 矩陣分解后的U矩陣
PMat: 矩陣分解后的P矩陣
*/
void ResolveLUP(Matrix& LMat, Matrix& UMat, Matrix& PMat);
private:
double** m_Matrix; //矩陣
int m_Row; //矩陣行數(shù)
int m_Col; //矩陣列數(shù)
};
#endif
Matrix.cpp函數(shù)實現(xiàn)文件:
#include "Matrix.h"
//******************************構(gòu)造函數(shù)與析構(gòu)函數(shù)********************************//
Matrix::Matrix()
{
}
//初始化矩陣 默認值為0
Matrix::Matrix(int row, int col)
{
this->m_Row = row;
this->m_Col = col;
//開辟內(nèi)存
this->m_Matrix = new double* [row];
for (int i = 0; i < row; i++)
{
this->m_Matrix[i] = new double[col] {0.0};
}
}
//初始化矩陣 設(shè)定數(shù)值
Matrix::Matrix(int row, int col, double *mat)
{
this->m_Row = row;
this->m_Col = col;
//開辟內(nèi)存
this->m_Matrix = new double* [row];
for (int i = 0; i < row; i++)
{
this->m_Matrix[i] = new double[col] {0.0};
}
//矩陣賦值
for(int i = 0; i<row; i++)
{
for (int j = 0; j < col; j++)
{
this->m_Matrix[i][j] = mat[i * col + j];
}
}
}
//深拷貝
Matrix::Matrix(const Matrix& mat)
{
//行列傳遞
this->m_Row = mat.m_Row;
this->m_Col = mat.m_Col;
//矩陣深拷貝
this->m_Matrix = new double* [this->m_Row];
for (int i = 0; i < this->m_Row; i++)
{
this->m_Matrix[i] = new double[this->m_Col];
memcpy(this->m_Matrix[i], mat.m_Matrix[i], sizeof(double) * this->m_Col);
}
}
Matrix::~Matrix()
{
//釋放矩陣每一行
for (int i = 0; i < this->m_Row; i++)
{
if (this->m_Matrix[i] != NULL)
{
delete[]this->m_Matrix[i];
this->m_Matrix[i] = NULL;
}
}
//釋放矩陣頂點
if (this->m_Matrix != NULL)
{
delete[]this->m_Matrix;
this->m_Matrix = NULL;
}
}
//獲取矩陣某個元素 某行某列
double Matrix::GetMatrixEle(int row, int col)
{
if (row >= this->m_Row)
{
std::cout << "Error: <GetMatrixEle> Input row >= m_Row" << std::endl;
return 0.0;
}
else if (col >= this->m_Col)
{
std::cout << "Error: <GetMatrixEle> Input col >= m_Col" << std::endl;
return 0.0;
}
else
{
return this->m_Matrix[row][col];
}
}
//*******************設(shè)置矩陣*****************//
void Matrix::SetMatrixEle(int row, int col, double value)
{
if (row >= this->m_Row)
{
std::cout << "Error: <SetMatrixEle> Input row >= m_Row" << std::endl;
return;
}
else if (col >= this->m_Col)
{
std::cout << "Error: <SetMatrixEle> Input col >= m_Col" << std::endl;
return;
}
else
{
this->m_Matrix[row][col] = value;
return;
}
}
Matrix Matrix::CopyMat(const Matrix mat)
{
//行列傳遞
this->m_Row = mat.m_Row;
this->m_Col = mat.m_Col;
//矩陣深拷貝
this->m_Matrix = new double* [this->m_Row];
for (int i = 0; i < this->m_Row; i++)
{
this->m_Matrix[i] = new double[this->m_Col];
memcpy(this->m_Matrix[i], mat.m_Matrix[i], sizeof(double) * this->m_Col);
}
return *this;
}
//*******************打印矩陣*****************//
//矩陣輸出
void Matrix::PrintMat()
{
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
std::cout.setf(std::ios::scientific); //科學(xué)計數(shù)法表示
std::cout << this->m_Matrix[i][j] << "\t";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
//*****************矩陣基本操作***************//
//矩陣轉(zhuǎn)置
Matrix& Matrix::Transpose()
{
Matrix* resMat = new Matrix(this->m_Col, this->m_Row);
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
resMat->m_Matrix[j][i] = this->m_Matrix[i][j];
}
}
return *resMat;
}
//求等長度單位矩陣
Matrix& Matrix::Uint()
{
//矩陣是否為方陣
if (this->m_Col != this->m_Row)
{
std::cout << "Error: <Uint> Row != Col" << std::endl;
Matrix* resMat = new Matrix(this->m_Row, this->m_Row);
return *resMat;
}
else
{
//單位矩陣初始化
Matrix* resMat = new Matrix(this->m_Row, this->m_Col);
//單位矩陣生成
for (int i = 0; i < this->m_Row; i++)
{
resMat->m_Matrix[i][i] = 1.0;
}
return *resMat;
}
}
//****************矩陣保留與剔除**************//
//剔除矩陣的 index中的行與列,num代表index的大小
Matrix& Matrix::DeleteMat(int* index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row - num, this->m_Col - num);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
else if (index[i] >= this->m_Col)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num-1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[recIndex[iRow]][recIndex[iCol]];
}
}
return *resMat;
}
Matrix& Matrix::DeleteMat(std::vector<int> index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row - num, this->m_Col - num);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
else if (index[i] >= this->m_Col)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[recIndex[iRow]][recIndex[iCol]];
}
}
return *resMat;
}
//剔除矩陣的 index中的行,num代表index的大小
Matrix& Matrix::DeleteRow(int* index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row - num, this->m_Col);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[recIndex[iRow]][iCol];
}
}
return *resMat;
}
Matrix& Matrix::DeleteRow(std::vector<int> index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row - num, this->m_Col);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[recIndex[iRow]][iCol];
}
}
return *resMat;
}
Matrix& Matrix::DeleteCol(int* index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row, this->m_Col - num);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[iRow][recIndex[iCol]];
}
}
return *resMat;
}
Matrix& Matrix::DeleteCol(std::vector<int> index, int num)
{
//結(jié)果矩陣
Matrix* resMat = new Matrix(this->m_Row, this->m_Col - num);
int recIndex[MAX_COUNT];
int currIndex = 0;
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <DeleteMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//篩選出剔除后行數(shù)
for (int iRow = 0; iRow < this->m_Row; iRow++)
{
for (int iNum = 0; iNum < num; iNum++)
{
if (iRow == index[iNum])
{
break;
}
if (iNum == num - 1)
{
recIndex[currIndex++] = iRow;
}
}
}
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[iRow][iCol] = this->m_Matrix[iRow][recIndex[iCol]];
}
}
return *resMat;
}
//******************矩陣的替換****************//
//替換矩陣中的行和列 index中的行與列,num代表index的大小
Matrix& Matrix::ReplaceMat(int* index, int num, Matrix& mat)
{
//錯誤判定 方陣
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <ReplaceMat> this m_Col != m_Row" << std::endl;
return *this;
}
//檢驗插入矩陣為方陣
if (mat.m_Row != mat.m_Col)
{
std::cout << "Error: <ReplaceMat> mat m_Col != m_Row" << std::endl;
return *this;
}
//檢驗插入矩陣大小與num保持一致
if (mat.m_Col != num)
{
std::cout << "Error: <ReplaceMat> num != mat.m_Col" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <ReplaceMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
else if (index[i] >= this->m_Col)
{
std::cout << "Error: <ReplaceMat> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < num; iRow++)
{
for (int iCol = 0; iCol < num; iCol++)
{
resMat->m_Matrix[index[iRow]][index[iCol]] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
Matrix& Matrix::ReplaceMat(std::vector<int> index, int num, Matrix& mat)
{
//錯誤判定 方陣
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <ReplaceMat> this m_Col != m_Row" << std::endl;
return *this;
}
//檢驗插入矩陣為方陣
if (mat.m_Row != mat.m_Col)
{
std::cout << "Error: <ReplaceMat> mat m_Col != m_Row" << std::endl;
return *this;
}
//檢驗插入矩陣大小與num保持一致
if (mat.m_Col != num)
{
std::cout << "Error: <ReplaceMat> num != mat.m_Col" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <ReplaceMat> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
else if (index[i] >= this->m_Col)
{
std::cout << "Error: <ReplaceMat> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < num; iRow++)
{
for (int iCol = 0; iCol < num; iCol++)
{
resMat->m_Matrix[index[iRow]][index[iCol]] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
//替換矩陣中的行 index中的行,num代表index的大小, mat是需要替換的矩陣
Matrix& Matrix::ReplaceRow(int* index, int num, Matrix& mat)
{
//檢驗插入矩陣大小與num保持一致
if (mat.m_Row != num)
{
std::cout << "Error: <ReplaceRow> num != mat.m_Row" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <ReplaceRow> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//當(dāng)前矩陣列數(shù)應(yīng)與mat列數(shù)一致
if (this->m_Col != mat.m_Col)
{
std::cout << "Error: <ReplaceRow> this->m_Col != mat.m_Col" << std::endl;
return *this;
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < num; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[index[iRow]][iCol] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
Matrix& Matrix::ReplaceRow(std::vector<int> index, int num, Matrix& mat)
{
//檢驗插入矩陣大小與num保持一致
if (mat.m_Row != num)
{
std::cout << "Error: <ReplaceRow> num != mat.m_Row" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Row)
{
std::cout << "Error: <ReplaceRow> Input index[" << i << "] = " << index[i] << " >= m_Row" << std::endl;
return *this;
}
}
//當(dāng)前矩陣列數(shù)應(yīng)與mat列數(shù)一致
if (this->m_Col != mat.m_Col)
{
std::cout << "Error: <ReplaceRow> this->m_Col != mat.m_Col" << std::endl;
return *this;
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < num; iRow++)
{
for (int iCol = 0; iCol < resMat->m_Col; iCol++)
{
resMat->m_Matrix[index[iRow]][iCol] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
//替換矩陣中的列 index中的列,num代表index的大小, mat是需要替換的矩陣
Matrix& Matrix::ReplaceCol(int* index, int num, Matrix& mat)
{
//檢驗插入矩陣大小與num保持一致
if (mat.m_Col != num)
{
std::cout << "Error: <ReplaceCol> mat.m_Col != num" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Col)
{
std::cout << "Error: <ReplaceCol> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//當(dāng)前矩陣行數(shù)應(yīng)與mat行數(shù)一致
if (this->m_Row != mat.m_Row)
{
std::cout << "Error: <ReplaceCol> this->m_Row != mat.m_Row" << std::endl;
return *this;
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < num; iCol++)
{
resMat->m_Matrix[iRow][index[iCol]] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
Matrix& Matrix::ReplaceCol(std::vector<int> index, int num, Matrix& mat)
{
//檢驗插入矩陣大小與num保持一致
if (mat.m_Col != num)
{
std::cout << "Error: <ReplaceCol> mat.m_Col != num" << std::endl;
return *this;
}
//檢驗數(shù)據(jù)有效性
for (int i = 0; i < num; i++)
{
//越界判定
if (index[i] >= this->m_Col)
{
std::cout << "Error: <ReplaceCol> Input index[" << i << "] = " << index[i] << " >= m_Col" << std::endl;
return *this;
}
}
//當(dāng)前矩陣行數(shù)應(yīng)與mat行數(shù)一致
if (this->m_Row != mat.m_Row)
{
std::cout << "Error: <ReplaceCol> this->m_Row != mat.m_Row" << std::endl;
return *this;
}
//結(jié)果矩陣
Matrix* resMat = new Matrix(*this);
//加入元素
for (int iRow = 0; iRow < resMat->m_Row; iRow++)
{
for (int iCol = 0; iCol < num; iCol++)
{
resMat->m_Matrix[iRow][index[iCol]] = mat.m_Matrix[iRow][iCol];
}
}
return *resMat;
}
//*****************矩陣初等變化***************//
Matrix& Matrix::SwapRow(int row0, int row1)
{
//錯誤判定 越界
if ((this->m_Row <= row0) || (this->m_Col <= row1))
{
std::cout << "Error: <SwapRow> Input row0 Or row1 More Than m_Row" << std::endl;
return *this;
}
else if ((0 > row0) || (0 > row1))
{
std::cout << "Error: <SwapRow> Input row0 Or row1 Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//中轉(zhuǎn)臨時變量
double temp = 0.0;
for (int j = 0; j < resMat->m_Col; j++)
{
temp = resMat->m_Matrix[row0][j];
resMat->m_Matrix[row0][j] = resMat->m_Matrix[row1][j];
resMat->m_Matrix[row1][j] = temp;
}
return*resMat;
}
}
Matrix& Matrix::SwapCol(int col0, int col1)
{
//錯誤判定 越界
if ((this->m_Col <= col0) || (this->m_Col <= col1))
{
std::cout << "Error: <SwapCol> Input col0 Or col1 More Than m_Col" << std::endl;
return *this;
}
else if ((0 > col0) || (0 > col1))
{
std::cout << "Error: <SwapCol> Input col0 Or col1 Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//中轉(zhuǎn)臨時變量
double temp = 0.0;
for (int i = 0; i < resMat->m_Row; i++)
{
temp = resMat->m_Matrix[i][col0];
resMat->m_Matrix[i][col0] = resMat->m_Matrix[i][col1];
resMat->m_Matrix[i][col1] = temp;
}
return*resMat;
}
}
//矩陣加法 某行 + 倍數(shù)*某行
Matrix& Matrix::AddRow(int rowLocal, int rowAdd, double rate)
{
if ((this->m_Row <= rowLocal) || (this->m_Row <= rowAdd))
{
std::cout << "Error: <AddRow> Input rowLocal Or rowAdd More Than m_Row" << std::endl;
return *this;
}
else if ((0 > rowLocal) || (0 > rowAdd))
{
std::cout << "Error: <AddRow> Input rowLocal Or rowAdd Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//指定行相加
for (int j = 0; j < resMat->m_Col; j++)
{
resMat->m_Matrix[rowLocal][j] += rate * resMat->m_Matrix[rowAdd][j];
}
return *resMat;
}
}
//矩陣加法 某列 + 倍數(shù)*某列
Matrix& Matrix::AddCol(int colLocal, int colAdd, double rate)
{
if ((this->m_Col <= colLocal) || (this->m_Col <= colAdd))
{
std::cout << "Error: <AddCol> Input colLocal Or colAdd More Than m_Col" << std::endl;
return *this;
}
else if ((0 > colLocal) || (0 > colAdd))
{
std::cout << "Error: <AddCol> Input colLocal Or colAdd Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//指定列相加
for (int i = 0; i < resMat->m_Row; i++)
{
resMat->m_Matrix[i][colLocal] += rate * resMat->m_Matrix[i][colAdd];
}
return *resMat;
}
}
//*******************矩陣加法*****************//
Matrix& Matrix::AddMat(Matrix& mat)
{
Matrix* ResMat = new Matrix(*this);
for (int i = 0; i < ResMat->m_Row; i++)
{
for (int j = 0; j < ResMat->m_Col; j++)
{
ResMat->m_Matrix[i][j] += mat.m_Matrix[i][j];
}
}
return *ResMat;
}
//*******************矩陣乘法*****************//
//矩陣數(shù)乘
Matrix& Matrix::MultNum(double num)
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(this->m_Row, this->m_Col);
//乘后矩陣生成
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
resMat->m_Matrix[i][j] = num * this->m_Matrix[i][j];
}
}
return *resMat;
}
//運算符重載 矩陣數(shù)乘
Matrix& Matrix::operator*(double num)
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(this->m_Row, this->m_Col);
//乘后矩陣生成
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
resMat->m_Matrix[i][j] = num * this->m_Matrix[i][j];
}
}
return *resMat;
}
//矩陣某行乘數(shù)值 行標(biāo)從0開始計數(shù)
Matrix& Matrix::MultRow(double num, int row)
{
if (this->m_Row <= row)
{
std::cout << "Error: <MultRow> Input row More Than m_Row" << std::endl;
return *this;
}
else if (0 > row)
{
std::cout << "Error: <MultRow> Input row Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//乘后矩陣生成
for (int j = 0; j < this->m_Col; j++)
{
resMat->m_Matrix[row][j] = num * this->m_Matrix[row][j];
}
return *resMat;
}
}
//矩陣某列乘數(shù)值 列標(biāo)從0開始計數(shù)
Matrix& Matrix::MultCol(double num, int col)
{
if (this->m_Col <= col)
{
std::cout << "Error: <MultCol> Input col More Than m_Row" << std::endl;
return *this;
}
else if (0 > col)
{
std::cout << "Error: <MultCol> Input col Less 0" << std::endl;
return *this;
}
else
{
//結(jié)果矩陣初始化
Matrix* resMat = new Matrix(*this);
//乘后矩陣生成
for (int i = 0; i < this->m_Row; i++)
{
resMat->m_Matrix[i][col] = num * this->m_Matrix[i][col];
}
return *resMat;
}
}
//矩陣相乘
Matrix& Matrix::MultMat(Matrix& inputMat)
{
Matrix *resMat = new Matrix(this->m_Row, inputMat.m_Col);
if (this->m_Col != inputMat.m_Row)
{
std::cout << "Matrix Mult Error!" << std::endl;
return *resMat;
}
else
{
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < inputMat.m_Col; j++)
{
for (int k = 0; k < this->m_Col; k++)
{
resMat->m_Matrix[i][j] += this->m_Matrix[i][k] * inputMat.m_Matrix[k][j];
}
}
}
return *resMat;
}
}
//矩陣的行列式數(shù)值
double Matrix::Det()
{
double res = 0.0;
int sign = 1;
if (this->m_Row != this->m_Col)
{
//錯誤判定
std::cout << "Error: <Det> Matrix Col != Row" << std::endl;
return 0;
}
else if (this->m_Row <= 1)
{
//程序終止出口
return this->m_Matrix[0][0];
}
else
{
for (int i = 0; i < this->m_Col; i++)
{
Matrix* temp = &(this->ChildMatrix(0, i));
res += sign * this->m_Matrix[0][i] * (temp->Det());
sign = -1*sign;
delete temp;
}
}
}
//矩陣行列式順序主子式 order階數(shù)
double Matrix::Det(int order)
{
if (this->m_Row != this->m_Col)
{
//錯誤判定
std::cout << "Error: <Det> Matrix Col != Row" << std::endl;
return 0;
}
else if (order < 0)
{
std::cout << "Error: <Det> Input Order Less 0" << std::endl;
return 0;
}
else if (order >= this->m_Row)
{
std::cout << "Error: <Det> Input Order More Than Row" << std::endl;
return 0;
}
else
{
Matrix tempMat(order + 1, order + 1);
for (int i = 0; i < tempMat.m_Col; i++)
{
for (int j = 0; j < tempMat.m_Row; j++)
{
tempMat.m_Matrix[i][j] = this->m_Matrix[i][j];
}
}
return tempMat.Det();
}
}
//求解余子式
Matrix& Matrix::ChildMatrix(int row, int col)
{
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <ChildMatrix> Matrix row != col" << std::endl;
return *this;
}
else if (this->m_Row <= 1)
{
std::cout << "Error: <ChildMatrix> Matrix Row Less 1 " << std::endl;
return *this;
}
else if ((row > this->m_Row) || (col > this->m_Col))
{
std::cout << "Error: <ChildMatrix> Input Row Or Col More Than Matix Max Row Or Col" << std::endl;
return* this;
}
else
{
Matrix* resMat = new Matrix(this->m_Row-1, this->m_Col-1);
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
if ((i < row) && (j < col))
resMat->m_Matrix[i][j] = this->m_Matrix[i][j];
else if((i > row) && (j < col))
resMat->m_Matrix[i-1][j] = this->m_Matrix[i][j];
else if((i < row) && (j > col))
resMat->m_Matrix[i][j - 1] = this->m_Matrix[i][j];
else if((i > row) && (j > col))
resMat->m_Matrix[i - 1][j - 1] = this->m_Matrix[i][j];
}
}
return *resMat;
}
}
//列主消元處理為上三角矩陣
double Matrix::DetRow()
{
//交換標(biāo)志位 1代表偶數(shù)次交換 -1代表奇數(shù)次交換
int flagShift = 1;
//本矩陣
Matrix *localMat = new Matrix(*this);
//行列式數(shù)值
double resDet = 1.0;
//*******************通過交換 num1*i + num2*j 實現(xiàn)下三角為0***************//
for (int i = 0; i < localMat->m_Row - 1; i++)
{
//記錄最大行所在行標(biāo)
int tempMaxRow = i;
for (int i1 = i + 1; i1 < localMat->m_Row; i1++)
{
if (abs(localMat->m_Matrix[i1][i]) > abs(localMat->m_Matrix[tempMaxRow][i]))
{
tempMaxRow = i1;
}
}
if (tempMaxRow != i)
{
//std::cout << i << " 行交換" << tempMaxRow << " 行" << std::endl;
//進行交換 將當(dāng)前第i行與第tempMaxRow行進行互換 初等行變換
*localMat = localMat->SwapRow(i, tempMaxRow);
//記錄交換次數(shù)
flagShift = -flagShift;
//localMat->PrintMat();
}
//此對角線以下的元素通過初等變化為0
for (int i2 = i + 1; i2 < localMat->m_Row; i2++)
{
if (localMat->m_Matrix[i2][i] != 0)
{
//std::cout << "<" << localMat->m_Matrix[i][i] << "> *" << i2 << " 行 + <" << -1.0 * (localMat->m_Matrix[i2][i]) << "> *" << i << " 行" << std::endl;
*localMat = localMat->AddRow(i2, i, -1.0 * (localMat->m_Matrix[i2][i]) / localMat->m_Matrix[i][i]);
//localMat->PrintMat();
}
}
}
//計算行列式數(shù)值 對角線相乘
for (int i = 0; i < localMat->m_Row; i++)
{
resDet = resDet * localMat->m_Matrix[i][i];
}
//矩陣交換一次就會變號
resDet = flagShift * resDet;
//清理localMatrix
delete localMat;
return resDet;
}
//矩陣求逆
Matrix& Matrix::Inverse()
{
if (abs(this->DetRow()) < MIN_DET)
{
std::cout << "Error: <Inverse> Matrix Det Near 0" << std::endl;
return *this;
}
else
{
Matrix* resMat = new Matrix(this->m_Row, this->m_Col);
for (int i = 0; i < this->m_Row; i++)
{
for (int j = 0; j < this->m_Col; j++)
{
Matrix* temp = &(this->ChildMatrix(j, i));
resMat->m_Matrix[i][j] = pow(-1.0, (i + j)) / this->DetRow() * (temp->DetRow());
delete temp;
}
}
return *resMat;
}
}
//矩陣求逆 行初等變化
Matrix& Matrix::InverseRow()
{
//錯誤判斷
if (abs(this->DetRow()) < MIN_DET)
{
std::cout << "Error: <InverseRow> Matrix Det Near 0" << std::endl;
return *this;
}
else if (this->m_Row <= 1)
{
std::cout << "Error: <InverseRow> Size Less 2" << std::endl;
return *this;
}
else
{
//單位矩陣 與帶轉(zhuǎn)換矩陣維度相同的
Matrix uint = this->Uint();
//結(jié)果矩陣 逆矩陣 初始狀態(tài)與本矩陣相同 為不使本矩陣發(fā)生改變
Matrix temp(this->m_Row, this->m_Col);
Matrix* resMat = new Matrix(temp.Uint());
//本矩陣
Matrix localMat(*this);
//*******************通過交換 num1*i + num2*j 實現(xiàn)下三角為0***************//
for (int i = 0; i < localMat.m_Row - 1; i++)
{
//記錄最大行所在行標(biāo)
int tempMaxRow = i;
for (int i1 = i + 1; i1 < localMat.m_Row; i1++)
{
if (abs(localMat.m_Matrix[i1][i]) > abs(localMat.m_Matrix[tempMaxRow][i]))
{
tempMaxRow = i1;
}
}
if (tempMaxRow != i)
{
//std::cout << i << " 行交換" << tempMaxRow << " 行" << std::endl;
//進行交換 將當(dāng)前第i行與第tempMaxRow行進行互換 初等行變換
localMat = localMat.SwapRow(i, tempMaxRow);
*resMat = resMat->SwapRow(i, tempMaxRow);
//localMat.PrintMat();
}
//此對角線以下的元素通過初等變化為0
for (int i2 = i + 1; i2 < localMat.m_Row; i2++)
{
if (localMat.m_Matrix[i2][i] != 0)
{
//std::cout << "<" << localMat.m_Matrix[i][i] << "> *" << i2 << " 行 + <" << -1.0 * (localMat.m_Matrix[i2][i]) << "> *" << i << " 行" << std::endl;
*resMat = resMat->AddRow(i2, i, -1.0 * (localMat.m_Matrix[i2][i]) / localMat.m_Matrix[i][i]);
localMat = localMat.AddRow(i2, i, -1.0 * (localMat.m_Matrix[i2][i]) / localMat.m_Matrix[i][i]);
//localMat.PrintMat();
}
}
}
//錯誤判斷
if (localMat.m_Matrix[localMat.m_Row - 1][localMat.m_Col - 1] == 0)
{
std::cout << "Error: <InverseRow> marix[" << localMat.m_Row - 1 << "][" << localMat.m_Col - 1 <<"] == 0" << std::endl;
return *this;
}
//*******************通過 num1*i + num2*j 實現(xiàn)上三角為0***************//
for (int i = localMat.m_Row - 1; i > 0; i--)
{
for (int i2 = i - 1; i2 >= 0; i2--)
{
if (localMat.m_Matrix[i2][i] != 0)
{
//std::cout << "<" << localMat.m_Matrix[i][i] << "> *" << i2 << " 行 + <" << -1.0 * (localMat.m_Matrix[i2][i]) << "> *" << i << " 行" << std::endl;
*resMat = resMat->AddRow(i2, i, -1.0 * (localMat.m_Matrix[i2][i]) / localMat.m_Matrix[i][i]);
localMat = localMat.AddRow(i2, i, -1.0 * (localMat.m_Matrix[i2][i]) / localMat.m_Matrix[i][i]);
//localMat.PrintMat();
}
}
}
//*******************通過 i*num 實現(xiàn)矩陣為單位矩陣***************//
for (int i = 0; i < localMat.m_Row; i++)
{
if (localMat.m_Matrix[i][i] == 0)
{
std::cout << "Error: <InverseRow> matrix[" << i << "]" << "[" << i << "] == 0" << std::endl;
return *this;
}
else
{
//std::cout << "<" << 1 / localMat.m_Matrix[i][i] << "> *" << i << " 行" << std::endl;
*resMat = resMat->MultRow(1 / localMat.m_Matrix[i][i], i);
localMat = localMat.MultRow(1 / localMat.m_Matrix[i][i], i);
//localMat.PrintMat();
}
}
return *resMat;
}
}
//矩陣求逆 下三角矩陣
Matrix& Matrix::InverseDownTriangle()
{
//錯誤判斷 方陣檢測
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <InverseDownTriangle> Matrix Col != Row" << std::endl;
return *this;
}
//下三角求逆
Matrix* resMat = new Matrix(*this);
for (int i = 0; i < resMat->m_Row; i++)
{
for (int j = 0; j <= i; j++)
{
//分段求解 對角線為倒數(shù)
if (i == j)
{
resMat->m_Matrix[i][j] = 1 / resMat->m_Matrix[i][j];
}
else
{
//分段求解 非對角線元素
double tempSum = 0.0;
for (int k = j; k <= i - 1; k++)
{
tempSum += resMat->m_Matrix[i][k] * resMat->m_Matrix[k][j];
}
resMat->m_Matrix[i][j] = -1.0*tempSum / resMat->m_Matrix[i][i];
}
}
}
return *resMat;
}
//矩陣求逆 上三角矩陣
Matrix& Matrix::InverseUpTriangle()
{
//錯誤判斷 方陣檢測
if (this->m_Row != this->m_Col)
{
std::cout << "Error: <InverseUpTriangle> Matrix Col != Row" << std::endl;
return *this;
}
//上三角求逆
Matrix* resMat = new Matrix(*this);
for (int j = resMat->m_Col-1; j >=0; j--)
{
for (int i = j; i >=0; i--)
{
//分段求解 對角線為倒數(shù)
if (i == j)
{
resMat->m_Matrix[i][j] = 1 / resMat->m_Matrix[i][j];
}
else
{
//分段求解 非對角線元素
double tempSum = 0.0;
for (int k = j; k >= i+1; k--)
{
tempSum += resMat->m_Matrix[i][k] * resMat->m_Matrix[k][j];
}
resMat->m_Matrix[i][j] = -1.0 * tempSum / resMat->m_Matrix[i][i];
}
}
}
return *resMat;
}
//矩陣LU分解 順序分解 對于病態(tài)矩陣可能存在精度問題
void Matrix::ResolveLU(Matrix& LMat, Matrix& UMat)
{
if (this->m_Col != this->m_Row)
{
std::cout << "Error: <ResolveLU> Is Not Square Matrix" << std::endl;
return;
}
//存在性判定 順序主子式不為0
for (int i = 0; i < this->m_Row; i++)
{
if (this->Det(i) == 0)
{
std::cout << "Error: <ResolveLU> order Det = 0" << std::endl;
return;
}
}
//LU 分解
//L矩陣為單位矩陣
LMat = this->Uint();
//U矩陣初始化為空矩陣
Matrix temp(this->m_Row, this->m_Col);
UMat = temp;
for (int i = 0; i < this->m_Row; i++)
{
//計算U
for (int j1 = i; j1 < this->m_Col; j1++)
{
double tempSum1 = 0.0;
if (i != 0)
{
for (int j2 = 0; j2 <= i - 1; j2++)
{
tempSum1 += LMat.m_Matrix[i][j2] * UMat.m_Matrix[j2][j1];
}
}
UMat.m_Matrix[i][j1] = this->m_Matrix[i][j1] - tempSum1;
}
//計算L
for (int i1 = i; i1 < this->m_Row; i1++)
{
double tempSum2 = 0.0;
if (i != 0)
{
for (int j2 = 0; j2 <= i - 1; j2++)
{
tempSum2 += LMat.m_Matrix[i1][j2] * UMat.m_Matrix[j2][i];
}
}
LMat.m_Matrix[i1][i] = (this->m_Matrix[i1][i] - tempSum2)/UMat.m_Matrix[i][i];
}
}
}
//矩陣的LUP分解 P*A = L*U 添加了列主消元功能
//L為主對角線元素為1的下三角矩陣 U為上二角矩陣 P為行交換矩陣 P*A=L*U
void Matrix::ResolveLUP(Matrix& LMat, Matrix& UMat, Matrix& PMat)
{
//條件判斷 矩陣行列式不為0
if (this->Det() == 0)
{
std::cout << "Error: <ResolveLUP> Can't Resolve Matrix To L U P" << std::endl;
return;
}
//初始化 L U P
LMat = this->Uint();
PMat = this->Uint();
UMat = *this;
//進行分解計算
for (int i = 0; i < UMat.m_Row - 1; i++)
{
//記錄最大行所在行標(biāo)
int tempMaxRow = i;
for (int i1 = i + 1; i1 < UMat.m_Row; i1++)
{
if (abs(UMat.m_Matrix[i1][i]) > abs(UMat.m_Matrix[tempMaxRow][i]))
{
tempMaxRow = i1;
}
}
//進行交換 將當(dāng)前第i行與第tempMaxRow行進行互換 初等行變換
UMat = UMat.SwapRow(i, tempMaxRow);
//L矩陣做出對應(yīng)交換 先交換<itempMaxRow>列再交換<itempMaxRow>行
LMat = LMat.SwapCol(i, tempMaxRow);
LMat = LMat.SwapRow(i, tempMaxRow);
//P矩陣做出對應(yīng)變換 交換<itempMaxRow>行
PMat = PMat.SwapRow(i, tempMaxRow);
//高斯消元 V矩陣消除下三角區(qū)域,L矩陣添加下三角區(qū)域
for (int i1 = i + 1; i1 < UMat.m_Row; i1++)
{
//記錄消元系數(shù)
double deleteVar = UMat.m_Matrix[i1][i] / UMat.m_Matrix[i][i];
//L矩陣列填充
LMat.m_Matrix[i1][i] = deleteVar;
//U矩陣列消除
UMat = UMat.MultRow(UMat.m_Matrix[i][i], i1).AddRow(i1, i, -1.0 * UMat.m_Matrix[i1][i]).MultRow(1 / UMat.m_Matrix[i][i], i1);
}
}
return;
}
工程師必備
- 項目客服
- 培訓(xùn)客服
- 平臺客服
TOP




















