?? matrix.h
字號:
// Matrix.h 矩陣模板類頭文件
// Ver 1.0.0.0
// 版權所有(C) 何渝, 2002
// 最后修改: 2002.5.31.
#ifndef _MATRIX_H //避免多次編譯
#define _MATRIX_H
#include <valarray> //模板類valarray的標準頭文件
#include <comm.h> //公共頭文件
#include <math.h> //數學頭文件
template <class _Ty>
class matrix //矩陣類matrix
{
typedef matrix<_Ty> _Myt;
private:
std::valarray<_Ty> m_Datas; //定義一維數組對象m_Datas
size_t m_stRow; //矩陣行數變量
size_t m_stCol; //矩陣列數變量
public:
typedef _Ty value_type;
//構造函數一(參數1, 2分別為矩陣的行與列數)
/******
矩陣類matrix的構造函數一
構造函數中出現的m_Datas為valarray類的對象,申請stRow * stCol個單元,
單元內沒賦值。對數組對象m_Datas使用了valarray類的構造函數:
explicit valarray(size_t n)
對私有變量m_stRow和m_stCol分別賦初值stRow, stCol。
******/
matrix(size_t stRow, size_t stCol)
: m_Datas(stRow * stCol),
m_stRow(stRow), m_stCol(stCol)
{
m_Datas.resize(GetRowNum() * GetColNum(), _Ty(0));
/*
構造函數中出現的m_Datas為valarray類的對象,若在函數體內調用的
resize(size_t n, const T& c = T())函數有兩個參數(參閱valarray中的
定義),第一個參數申請有矩陣行*列那么多元素個數的存儲空間,第二個
參數對這些申請的空間賦予具有模式T的初值0。如果不調用該函數,則缺省
情況下m_Datas長度為0;另外,調用該函數但不使用第二個參數,則不會對
m_Datas的任何一個元素賦初值。
*/
}
//構造函數二(參數1為指向矩陣的指針,參數2, 3為矩陣行與列數)
/******
矩陣類matrix的構造函數二
對私有變量m_stRow和m_stCol分別賦初值stRow, stCol。
對數組對象m_Datas使用了valarray類的構造函數:
valarray(const _Ty *p, size_t n)
m_Datas初始化的第一參數為矩陣rhs指針,第二個參數為rhs的元素總個數,
即rhs行數*列數
******/
matrix(const _Ty* rhs, size_t stRow, size_t stCol)
: m_Datas(rhs, stRow * stCol),
m_stRow(stRow), m_stCol(stCol)
{
}
//構造函數三(拷貝構造函數,參數為對矩陣matrix的引用)
/******
矩陣類matrix的構造函數三
用引用矩陣rhs的數組對象m_Datas初始化matrix所定義對象的m_Datas,
用引用矩陣rhs的行數rhs.GetRowNum()和列數rhs.GetColNum()分別初始化私
有變量m_stRow和m_stCol
******/
matrix(const _Myt& rhs)
: m_Datas(rhs.m_Datas),
m_stRow(rhs.GetRowNum()), m_stCol(rhs.GetColNum())
{
}
size_t GetRowNum() const //返回矩陣行數的函數
{
return m_stRow;
}
size_t GetColNum() const //返回矩陣列數的函數
{
return m_stCol;
}
/*****
重載運算符(),獲取二維矩陣某元素在一維數組m_Datas的位置
(matrix類定義的矩陣實際上已經被轉化為一維數組m_Datas)
當數組元素(i, j)在運算符左邊(被寫)時,使用_Ty& operator ()
當數組元素(i, j)在運算符右邊(被讀)時,使用_Ty operator ()
*****/
_Ty& operator () (size_t stRow, size_t stCol)
{
Assert(stRow < GetRowNum()); //斷定stRow不超實際矩陣行值
Assert(stCol < GetColNum()); //斷定stCol不超實際矩陣列值
return m_Datas[stRow * GetColNum() + stCol];
}
/******
重載()運算符,返回二維矩陣中元素(stRow, stCol)在一維數組中的位置
stRow與stCol分別為矩陣某元素行與列的位置數
當矩陣元素在運算符右邊(被讀)時使用
******/
const _Ty operator () (size_t stRow, size_t stCol) const
{
Assert(stRow < GetRowNum()); //斷定stRow不超實際矩陣行值
Assert(stCol < GetColNum()); //斷定stCol不超實際矩陣列值
return m_Datas[stRow * GetColNum() + stCol];
}
// 賦值操作符
//矩陣與矩陣的自反*, +, -運算符
_Myt& operator += (const _Myt& rhs) //矩陣與矩陣的自反+
{
Assert(GetRowNum() == rhs.GetRowNum()); //斷定兩矩陣的行數相等
Assert(GetColNum() == rhs.GetColNum()); //斷定兩矩陣的列數相等
//利用類valarray定義,使其對象m_Datas定義進行兩矩陣相加
m_Datas += rhs.m_Datas;
//結果放在左邊矩陣中,返回指向左邊矩陣的指針
return *this;
}
_Myt& operator -= (const _Myt& rhs) //矩陣與矩陣的自反-
{
Assert(GetRowNum() == rhs.GetRowNum());
Assert(GetColNum() == rhs.GetColNum());
//利用類valarray定義,使其對象m_Datas定義進行兩矩陣相減
m_Datas -= rhs.m_Datas;
//結果放在左邊矩陣中,返回指向左邊矩陣的指針
return *this;
}
_Myt& operator *= (const _Myt& rhs) //矩陣與矩陣的自反*
{
MatrixMultiply(*this, *this, rhs); //調用矩陣乘法函數
return *this; //最后結果放在左邊矩陣中
}
//矩陣自反加、減、乘以、除以數
_Myt& operator += (const _Ty& rhs) //矩陣自加數
{
m_Datas += rhs; //利用數組對象對每個元素加數
return *this; //結果放在原矩陣(數組m_Datas)中
}
_Myt& operator -= (const _Ty& rhs) //矩陣自減數
{
m_Datas -= rhs;
return *this;
}
_Myt& operator *= (const _Ty& rhs) //矩陣自乘數
{
m_Datas *= rhs;
return *this;
}
_Myt& operator /= (const _Ty& rhs) //矩陣自除以數
{
m_Datas /= rhs;
return *this;
}
// 一元操作符 對矩陣(每個元素)賦予+或-號
_Myt operator + () const //賦+號
{
return *this; //不用作任何處理,維持原狀
}
_Myt operator - () const //賦-號
{
_Myt mat(*this);
mat.m_Datas = -mat.m_Datas; //每個元素賦-號
return mat;
}
// 二元操作符
//矩陣加數 mat = lhs + rhs
friend _Myt operator + (const _Myt& lhs, const _Ty& rhs)
{
_Myt mat(lhs); //新生成一新矩陣對象mat
mat.m_Datas += rhs; //對新矩陣對象每個元素加數
return mat; //返回新矩陣對象
}
//矩陣減數 mat = lhs - rhs
friend _Myt operator - (const _Myt& lhs, const _Ty& rhs)
{
_Myt mat(lhs);
mat.m_Datas -= rhs;
return mat;
}
//矩陣乘以數 mat = lhs * rhs
friend _Myt operator * (const _Myt& lhs, const _Ty& rhs)
{
_Myt mat(lhs); //新生成一新矩陣對象mat
mat.m_Datas *= rhs; //對新矩陣對象每個元素乘以數
return mat; //返回新矩陣對象
}
//矩陣除以數 mat = lhs / rhs
friend _Myt operator / (const _Myt& lhs, const _Ty& rhs)
{
_Myt mat(lhs);
mat.m_Datas /= rhs;
return mat;
}
//數加矩陣 mat = lhs + rhs
friend _Myt operator + (const _Ty& lhs, const _Myt& rhs)
{
_Myt mat(rhs); //新生成一新矩陣對象mat
mat.m_Datas += lhs; //數加上新矩陣對象的每個元素
return mat;
}
//數減矩陣 mat = lhs - rhs
friend _Myt operator - (const _Ty& lhs, const _Myt& rhs)
{
_Myt mat(rhs); //新生成一新矩陣對象mat
mat.m_Datas -= lhs; //數減新矩陣對象的每個元素
return mat;
}
//數乘以矩陣 mat = lhs * rhs
friend _Myt operator * (const _Ty& lhs, const _Myt& rhs)
{
_Myt mat(rhs); //新生成一新矩陣對象mat
mat.m_Datas *= lhs; //對新矩陣對象每個元素乘以數
return mat;
}
//矩陣加矩陣 mat = lhs + rhs
friend _Myt operator + (const _Myt& lhs, const _Myt& rhs)
{
_Myt mat(lhs); //新生成一新矩陣對象mat, 用左邊陣初始化
mat.m_Datas += rhs.m_Datas; //加上右邊矩陣對象每個相應元素
return mat; //返回新矩陣對象
}
//矩陣減矩陣 mat = lhs - rhs
friend _Myt operator - (const _Myt& lhs, const _Myt& rhs)
{
_Myt mat(lhs); //新生成一新矩陣對象mat, 用左邊陣初始化
mat.m_Datas -= rhs.m_Datas; //減去右邊矩陣對象每個相應元素
return mat; //返回新矩陣對象
}
//矩陣乘以矩陣 mTmp = lhs * rhs
friend _Myt operator * (const _Myt& lhs, const _Myt& rhs)
{ //生成一個矩陣新對象mTmp
_Myt mTmp(lhs.GetRowNum(), rhs.GetColNum()); //沒初始化
MatrixMultiply(mTmp, lhs, rhs); //調用矩陣乘法函數
return mTmp; //用新矩陣對象返回
}
//矩陣比較
//比較兩矩陣是否不相等,若相等返回true,否則返回false
friend bool operator != (const _Myt& lhs, const _Myt& rhs)
{
if (lhs.GetRowNum() != rhs.GetRowNum())
return true;
if (lhs.GetColNum() != rhs.GetColNum())
return true;
for (size_t i = 0; i < lhs.m_Datas.size(); i ++)
{
if (lhs.m_Datas[i] != rhs.m_Datas[i])
return true;
}
return false;
}
//比較兩矩陣是否相等,若相等返回true,否則返回false
friend bool operator == (const _Myt& lhs, const _Myt& rhs)
{
if (lhs.GetRowNum() != rhs.GetRowNum())
return false;
if (lhs.GetColNum() != rhs.GetColNum())
return false;
for (size_t i = 0; i < lhs.m_Datas.size(); i ++)
{
if (lhs.m_Datas[i] != rhs.m_Datas[i])
return false;
}
return true;
}
};
typedef matrix<float> matrixf;
typedef matrix<double> matrixd;
typedef matrix<long double> matrixld;
//矩陣乘法函數
template <class _Tyout, class _Tylhs, class _Tyrhs> //最后結果在mOut中
matrix<_Tyout>& MatrixMultiply(matrix<_Tyout>& mOut, const matrix<_Tylhs>& lhs, const matrix<_Tyrhs>& rhs);
//輸出矩陣 一行一行輸出全矩陣
template <class _Ty>
void MatrixLinePrint(const matrix<_Ty>& mOut);
//輸出矩陣 輸出指定的某行
template <class _Ty>
void MatrixLinePrint(const matrix<_Ty>& mOut, size_t LineNo);
//矩陣轉置 原陣在mIn,轉置后的矩陣在mOut
template <class _Ty>
void MatrixTranspose(matrix<_Ty>& mIn, matrix<_Ty>& mOut);
//判斷矩陣對稱
template <class _Ty> //對稱返回true,否則返回false
bool MatrixSymmetry(const matrix<_Ty>& rhs);
//判斷矩陣對稱正定
template <class _Ty>
int MatrixSymmetryRegular(const matrix<_Ty>& rhs, int sym);
//全選主元法求矩陣行列式
template <class _Ty> //返回值為行列式值
long double MatrixDeterminant(const matrix<_Ty>& rhs);
//全選主元高斯(Gauss)消去法求一般矩陣的秩
template <class _Ty> //返回值為秩數
size_t MatrixRank(const matrix<_Ty>& rhs);
//用全選主元高斯-約當(Gauss-Jordan)消去法計算實(復)矩陣的逆矩陣
//矩陣類型必須是浮點型
template <class _Ty>
int MatrixInversionGS(matrix<_Ty>& rhs);
//用“變量循環重新編號法”法求對稱正定矩陣逆
//矩陣類型必須是浮點型
template <class _Ty>
int MatrixSymmetryRegularInversion(matrix<_Ty>& rhs);
//特蘭持(Trench)法求托伯利茲(Toeplitz)矩陣逆
//矩陣類型必須是浮點型
template <class _Ty>
int MatrixToeplitzInversionTrench(const valarray<_Ty>& t,
const valarray<_Ty>& tt, matrix<_Ty>& rhs);
//實矩陣LU分解
//矩陣類型必須是浮點型
template <class _Ty>
int MatrixLU(const matrix<_Ty>& rhs, matrix<_Ty>& lhs, matrix<_Ty>& uhs);
//用豪斯荷爾德(Householder)變換對一般m*n階的實矩陣進行QR分解
//矩陣類型必須是浮點型
template <class _Ty>
int MatrixQR(matrix<_Ty>& rhs, matrix<_Ty>& rhq);
//對稱正定陣的喬里斯基(Cholesky)分解及求其行列式值
//矩陣類型必須是浮點型
template <class _Ty>
long double MatrixSymmetryRegularCholesky(const matrix<_Ty>& rhs);
//一般實矩陣的奇異值分解
//矩陣類型必須是浮點型
template <class _Ty>
int MatrixSingularValue(matrix<_Ty>& a, matrix<_Ty>& u,
matrix<_Ty>& v, _Ty eps);
//廣義逆的奇異值分解
//矩陣類型必須是浮點型
template <class _Ty>
int GeneralizedInversionSingularValue(matrix<_Ty>& a, matrix<_Ty>& aa,
_Ty eps, matrix<_Ty>& u, matrix<_Ty>& v);
#include "Matrix.inl" //類及相關函數的定義頭文件
#endif // _MATRIX_H
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -