?? matrix.h
字號:
/*! @file
********************************************************************************
<PRE>
模塊名 : 實現復數矩陣的基本運算
文件名 : matrix.h
文件實現功能 : 實現復數矩陣的基本運算,并能實現復數矩陣的求逆、快速傅里葉變換和奇異值分解。
作者 : 陳鵬飛
版本 : V1.0
--------------------------------------------------------------------------------
多線程安全性 : <是/否>[,說明]
異常時安全性 : <是/否>[,說明]
--------------------------------------------------------------------------------
備注 : 該復數矩陣模板只適用于float和double型復數矩陣。不能用于實數矩陣。
--------------------------------------------------------------------------------
修改記錄 :
日 期 版本 修改人 修改內容
2009/04/16 V1.01 <陳鵬飛> <模板的規范化>
</PRE>
*******************************************************************************/
#pragma once //避免頭文件重復定義
#include <cassert>
#include <valarray>
#include <complex>
#include <cmath>
#include <cstdlib>
#include <float.h>
using namespace std;
// RTTI
#include <typeinfo>
typedef complex<float> COMPLEX_FLOAT;
typedef complex<double> COMPLEX_DOUBLE;
const float FLOATERROR = 1.0e-6F;
const double DOUBLEERROR = 1.0e-15;
const long double LONGDOUBLEERROR = 1.0e-30;
const double GOLDENSECTION = 0.618033399; //黃金分割常數(1.0-0.381966)
#define DBL_MIN 2.2250738585072014e-308 /* min positive value */
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */
//取x符號,+-或0
template <class T>
T Sgn(const T& x)
{
return x < T(0) ? T(-1) : (x > T(0) ? T(1) : T(0));
}
//絕對值
template <class T>
long double Abs(const T& x)
{
complex<long double> cld(x);
long double ldAbs = abs(x);
return(ldAbs);
}
//比較兩float浮點數相等
bool FloatEqual(float lhs, float rhs)
{
if (Abs(lhs - rhs) < FLOATERROR)
return true;
else
return false;
}
//比較兩float浮點數不相等
bool FloatNotEqual(float lhs, float rhs)
{
if (Abs(lhs - rhs) >= FLOATERROR)
return true;
else
return false;
}
//比較兩double浮點數相等
bool FloatEqual(double lhs, double rhs)
{
if (Abs(lhs - rhs) < DOUBLEERROR)
return true;
else
return false;
}
//比較兩double浮點數不相等
bool FloatNotEqual(double lhs, double rhs)
{
if (Abs(lhs - rhs) >= DOUBLEERROR)
return true;
else
return false;
}
//比較兩long double浮點數相等
bool FloatEqual(long double lhs, long double rhs)
{
if (Abs(lhs - rhs) < LONGDOUBLEERROR)
return true;
else
return false;
}
//比較兩long double浮點數不相等
bool FloatNotEqual(long double lhs, long double rhs)
{
if (Abs(lhs - rhs) >= LONGDOUBLEERROR)
return true;
else
return false;
}
//求x與y的最小值,返回小者
template <class T>
T Min(const T& x, const T& y)
{
if(x < y)
return x;
else
return y;
}
//求x與y的最大值,返回大者
template <class T>
T Max(const T& x, const T& y)
{
if(x > y)
return x;
else
return y;
}
/*! @class
********************************************************************************
<PRE>
類名稱 : 復數矩陣模板類
功能 : 實現復數矩陣的基本運算
--------------------------------------------------------------------------------
備注 : <該類只能用來實現float和double型復數矩陣的基本運算>
--------------------------------------------------------------------------------
作者 : 陳鵬飛
</PRE>
*******************************************************************************/
template <class _Ty>
class CMatrix
{
typedef CMatrix<_Ty> _MatTy;
typedef _Ty _vTy;
public:
//構造函數一(參數1, 2分別為矩陣的行與列數)
/******
矩陣類matrix的構造函數一
構造函數中出現的m_Datas為valarray類的對象,申請stRow * stCol個單元,
單元內沒賦值。對數組對象m_Datas使用了valarray類的構造函數:
explicit valarray(size_t n)
對私有變量m_stRow和m_stCol分別賦初值stRow, stCol。
******/
CMatrix(size_t stRow, size_t stCol)
: m_Datas(stRow * stCol),
m_stRow(stRow), m_stCol(stCol)
{
m_Datas.resize(GetRowNum() * GetColNum(), _vTy(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行數*列數
******/
CMatrix(const _vTy* 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
******/
CMatrix(const _MatTy& 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;
}
////////////////////////////////////////////////
// 重載運算符
// 索引行列(寫入)
_vTy* operator [] (size_t stRow)
{
assert(stRow != 0);
assert(stRow < GetRowNum() + 1); //斷定stRow不超實際矩陣行值
_vTy *p = &m_Datas[(stRow-1) * GetColNum()];
return p;
}
// 索引行列(只讀)
const _vTy* operator [] (size_t stRow) const
{
assert(stRow != 0);
assert(stRow < GetRowNum()); //斷定stRow不超實際矩陣行值
_vTy *p = &m_Datas[(stRow-1) * GetColNum()];
return p;
}
// 索引行列(寫入)
_vTy& operator () (size_t stRow, size_t stCol)
{
assert(stRow < GetRowNum()); //斷定stRow不超實際矩陣行值
assert(stCol < GetColNum()); //斷定stCol不超實際矩陣列值
return m_Datas[stRow * GetColNum() + stCol];
}
// 索引行列(只讀)
const _vTy operator () (size_t stRow, size_t stCol) const
{
assert(stRow < GetRowNum()); //斷定stRow不超實際矩陣行值
assert(stCol < GetColNum()); //斷定stCol不超實際矩陣列值
return m_Datas[stRow * GetColNum() + stCol];
}
// 賦值操作符
//矩陣與矩陣的自反*, +, -運算符
// 矩陣與矩陣的自反+
_MatTy& operator += (const _MatTy& rhs)
{
assert(GetRowNum() == rhs.GetRowNum());
assert(GetColNum() == rhs.GetColNum());
m_Datas += rhs.m_Datas;
return *this;
}
// 矩陣與矩陣的自反-
_MatTy& operator -= (const _MatTy& rhs)
{
assert(GetRowNum() == rhs.GetRowNum());
assert(GetColNum() == rhs.GetColNum());
m_Datas -= rhs.m_Datas;
return *this;
}
// 矩陣與矩陣的自反*
_MatTy& operator *= (const _MatTy& rhs)
{
Multiply(*this, *this, rhs);
return *this;
}
//矩陣自反加、減、乘以、除以數
_MatTy& operator += (const _Ty& rhs) //矩陣自加數
{
m_Datas += rhs; //利用數組對象對每個元素加數
return *this; //結果放在原矩陣(數組m_Datas)中
}
_MatTy& operator -= (const _Ty& rhs) //矩陣自減數
{
m_Datas -= rhs;
return *this;
}
_MatTy& operator *= (const _Ty& rhs) //矩陣自乘數
{
m_Datas *= rhs;
return *this;
}
_MatTy& operator /= (const _Ty& rhs) //矩陣自除以數
{
m_Datas /= rhs;
return *this;
}
// 矩陣取反
_MatTy operator - () const
{
_MatTy mat(*this);
mat.m_Datas = -mat.m_Datas;
return mat;
}
//矩陣乘數 mat = lhs * rhs
friend _MatTy operator * (const _MatTy& lhs, const _Ty& rhs)
{
_MatTy mat(lhs); //新生成一新矩陣對象mat
mat.m_Datas *= rhs; //對新矩陣對象每個元素乘以數
return mat;
}
//數加矩陣 mat = lhs + rhs
friend _MatTy operator + (const _Ty& lhs, const _MatTy& rhs)
{
_MatTy mat(rhs); //新生成一新矩陣對象mat
mat.m_Datas += lhs; //數加上新矩陣對象的每個元素
return mat;
}
//矩陣加數 mat = lhs + rhs
friend _MatTy operator + (const _MatTy& lhs, const _Ty& rhs)
{
_MatTy mat(lhs); //新生成一新矩陣對象mat
mat.m_Datas += rhs; //數加上新矩陣對象的每個元素
return mat;
}
//數減矩陣 mat = lhs - rhs
friend _MatTy operator - (const _Ty& lhs, const _MatTy& rhs)
{
_MatTy mat(rhs); //新生成一新矩陣對象mat
mat.m_Datas -= lhs; //數減新矩陣對象的每個元素
return mat;
}
//數乘矩陣 mat = lhs * rhs
friend _MatTy operator * (const _Ty& lhs, const _MatTy& rhs)
{
_MatTy mat(rhs);
mat.m_Datas *= lhs;
return mat;
}
//矩陣加法 mat = lhs + rhs
friend _MatTy operator + (const _MatTy& lhs, const _MatTy& rhs)
{
_MatTy mat(lhs);
mat.m_Datas += rhs.m_Datas;
return mat;
}
//矩陣減法 mat = lhs - rhs
friend _MatTy operator - (const _MatTy& lhs, const _MatTy& rhs)
{
_MatTy mat(lhs);
mat.m_Datas -= rhs.m_Datas;
return mat;
}
//矩陣乘法 mTmp = lhs * rhs
friend _MatTy operator * (const _MatTy& lhs, const _MatTy& rhs)
{ //生成一個矩陣新對象mTmp
_MatTy mTmp(lhs.GetRowNum(), rhs.GetColNum()); //沒初始化
return Multiply(mTmp, lhs, rhs);
}
//矩陣點乘
friend _MatTy PM(_MatTy& lhs, _MatTy& rhs)
{
int Row, Col;
Row = lhs.GetRowNum();
Col = lhs.GetColNum();
_MatTy Temp(Row, Col);
for ( int i = 0; i < Row; i++)
for ( int j = 0; j < Col; j++)
Temp(i, j) = lhs(i, j) * rhs(i, j);
return Temp;
}
//矩陣點除
friend _MatTy PD(_MatTy& lhs, _MatTy& rhs)
{
int Row, Col;
Row = lhs.GetRowNum();
Col = rhs.GetColNum();
_MatTy Temp(Row, Col);
for ( int i = 0; i < Row; i++)
for ( int j = 0; j < Col; j++)
{
if(rhs(i, j) == _Ty(0, 0))
{
//cout << "input is error" << endl;
exit(1);
}
Temp(i, j) = lhs(i, j) / rhs(i, j);
}
return Temp;
}
//矩陣余弦函數
friend _MatTy COS(_MatTy& lhs)
{
int Row, Col;
Row = lhs.GetRowNum();
Col = lhs.GetColNum();
_MatTy tmp(Row, Col);
for ( int i = 0; i < Row; i++)
for ( int j = 0; j < Col; j++)
tmp(i, j) = cos(lhs(i, j));
return tmp;
}
//矩陣正弦函數
friend _MatTy SIN(_MatTy& lhs)
{
int Row, Col;
Row = lhs.GetRowNum();
Col = lhs.GetColNum();
_MatTy tmp(Row, Col);
for ( int i = 0; i < Row; i++)
for ( int j = 0; j < Col; j++)
tmp(i, j) = sin(lhs(i, j));
return tmp;
}
friend void lstSprsFit(_MatTy& x, _MatTy& y, int n, _MatTy& yFit, _MatTy& coef)
{
int mCol = x.GetColNum();
int yCol = y.GetColNum();
_MatTy X1(1, 2*n);
_MatTy X2(1, n+1);
_MatTy X3(n, n+1);
_MatTy XSUM(n+1, n+1);
_MatTy YSUM(1, n+1);
_Ty SumNum = (0, 0);
for ( int i = 0; i < yCol; i++)
{
SumNum = SumNum + y(0, i);
}
for ( int i = 0; i < 2*n; i++)
{
_Ty sum = (0, 0);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -