矩阵运算 :实现一个二维矩阵类,完成矩阵的运算
要求:1 能象两个整数一样通过 表达式A*B完成矩阵运算。
2 要有想应的输入和输出界面,建立自己的类
要求:1 能象两个整数一样通过 表达式A*B完成矩阵运算。
2 要有想应的输入和输出界面,建立自己的类
解决方案 »
- 自建window服务 调用exe 该exe通过odbc连接数据库 不能连接odbc失败
- 简单问题,高手指导~ up也有分!!
- 在VC6中建立的DLL项目,进行什么设置才能输出.LIB,我的只能输出.OBJ文档?
- 简单问题__新手提问__望指教
- 菜鸟求救:(
- 关于DELPHI与VC++的应用问题
- 如果一个文件头部以Microsoft C/C++ MSF 7.00 DS字节开头,那属于哪种类型的文件?
- 怎样在列表框中添加常用热键
- 分不在高、题不在深,大家帮忙拉我一把。
- 我想用WinInet类编一个简单的Web浏览器,可是却无法解决用户权限问题,通过代理服务器上网(要用户名和密码)
- 急: Debug版运行正常,而Release版无法运行,仅仅弹出 Runtime error!对话框
- Pdf417的图象识别
#pragma once
#define MATINLINE __forceinlinetemplate<typename _Ty, typename _F = int>class CMatrix
{
public:
// 初等变换类型
enum ETMETHOD {ET_ROWMUL = 1, ET_ROWADD, ET_ROWEXC
,ET_COLMUL, ET_COLADD, ET_COLEXC};
public:
// 构造空的Matrix
MATINLINE CMatrix( void );
// 构造指定大小的Matrix,并用数组为其赋值
MATINLINE CMatrix( _F nRow, _F nCol, const _Ty *ptAssign = 0 );
// 构造指定大小的Matrix,并将元素置为默认值
MATINLINE CMatrix( _F nRow, _F nCol, const _Ty &tValue );
// 拷贝构造
MATINLINE CMatrix( const CMatrix &mOther );
// 析构
MATINLINE ~CMatrix( void );
// 创建赋值
MATINLINE bool Create( _F nRow, _F nCol, const _Ty *ptAssign = 0 );
// 用数组给元素赋值
MATINLINE bool Assign( const _Ty *ptAssign );
MATINLINE bool Assign( const _Ty &tValue );// 使用默认值给元素赋值
// 清除矩阵
MATINLINE void Clear( void );
// 判断是否空矩阵
MATINLINE bool IsEmpty( void ) const;
// 获得某元素
MATINLINE _Ty& GetElem( _F nRow, _F nCol );
MATINLINE const _Ty& GetElem( _F nRow, _F nCol ) const;
// 获得数据内存
MATINLINE _Ty* GetBuffer( void );
MATINLINE const _Ty* GetBuffer( void ) const;
// 获得行列数
MATINLINE _F GetRowCount( void ) const;
MATINLINE _F GetColCount( void ) const;
// 单位化矩阵
bool Identity( void );
// 初等变换(elementary transformation)
bool ElemTrans( ETMETHOD Method, _F nFirst, _F nSecond, const _Ty &tFalue );
// 赋值
CMatrix& operator =( const CMatrix &mOther );
CMatrix& operator =( const _Ty &tValue );
// 相加
CMatrix operator +( const CMatrix &mOther ) const;
CMatrix& operator +=( const CMatrix &mOther );
// 数乘
CMatrix operator *( const _Ty &tValue ) const;
CMatrix& operator *=( const _Ty &tValue );
// 相乘
CMatrix operator *( const CMatrix &mOther ) const;
CMatrix& operator *=( const CMatrix &mOther );
// 乘方
CMatrix operator ^( _F nPower ) const;
CMatrix& operator ^=( _F nPower );
// 求转置矩阵
bool Transform( void );
// 求余子式矩阵
bool Cofactor( _F nRow, _F nCol );
// 作为行列式求值
bool Determinant( _Ty *ptOut ) const;
// 求伴随矩阵
bool Adjoint( void );
// 求逆阵
bool Inversion( void );
private:
// 使正对角线上的值不为0, concomitance
_F RegularDiagonal( _F nIndex, CMatrix *pConc );
private:
_F m_nRow, m_nCol;
_Ty *m_pElem;
};template< typename _Ty, typename _F >
CMatrix< _Ty, _F > operator *( const _Ty &tValue, const CMatrix< _Ty, _F > &mOther );
#include "REmovenoise.h"
#include "Matrix.h"#include <algorithm>
using namespace std;#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
template< typename _Ty > //初等变换
MATINLINE bool equal( const _Ty &first, const _Ty &second )
{
_Ty temp = first - second;
return temp <= _Ty( 1e-8 ) && temp >= -_Ty( 1e-8 );
}template< typename _Ty, typename _F >
MATINLINE CMatrix< _Ty, _F >::CMatrix( void )
: m_nRow(0)
, m_nCol(0)
, m_pElem(0)
{
}template< typename _Ty, typename _F >
MATINLINE CMatrix< _Ty, _F >::CMatrix( _F nRow, _F nCol, const _Ty *ptAssign )
: m_nRow( nRow )
, m_nCol( nCol )
, m_pElem( new _Ty[ nRow * nCol ] )
{
if ( 0 == m_pElem )
{
m_nRow = 0;
m_nCol = 0;
}
else if ( 0 != ptAssign )
{
Assign( ptAssign );
}
}template< typename _Ty, typename _F >
MATINLINE CMatrix< _Ty, _F >::CMatrix( _F nRow, _F nCol, const _Ty &tValue )
: m_nRow(nRow)
, m_nCol(nCol)
, m_pElem( new _Ty[ nRow * nCol ] )
{
if ( 0 == m_pElem )
{
m_nRow = 0;
m_nCol = 0;
}
else
{
Assign( tValue );
}
}template< typename _Ty, typename _F >
MATINLINE CMatrix< _Ty, _F >::CMatrix( const CMatrix &mOther )
: m_nRow( 0 )
, m_nCol( 0 )
, m_pElem( 0 )
{
if ( mOther.m_nRow > 0 && mOther.m_nCol > 0 )
{
Create( mOther.m_nRow, mOther.m_nCol, mOther.m_pElem );//创建赋值
}
}template< typename _Ty, typename _F >
MATINLINE CMatrix< _Ty, _F >::~CMatrix( void )
{
delete []m_pElem;
}template< typename _Ty, typename _F >
MATINLINE void CMatrix< _Ty, _F >::Clear( void )
{
delete []m_pElem;
m_pElem = 0;
m_nRow = 0;
m_nCol = 0;
}template< typename _Ty, typename _F >
MATINLINE bool CMatrix< _Ty, _F >::IsEmpty( void ) const//判断是否为空
{
return ( mOther.m_nRow > 0 && mOther.m_nCol > 0 );
}template< typename _Ty, typename _F >
MATINLINE bool CMatrix< _Ty, _F >::Create( _F nRow, _F nCol, const _Ty *ptAssign )
{
if ( m_nRow != 0 || m_nCol != 0 )
{
return false;
}
if ( nRow < 1 || nCol < 1 )
{
return false;
}
_F nCount = nRow * nCol;
m_pElem = new _Ty[nCount];
m_nRow = nRow;
m_nCol = nCol;
if ( 0 != ptAssign )
{
Assign( ptAssign );
}
return true;
}template< typename _Ty, typename _F >
MATINLINE bool CMatrix< _Ty, _F >::Assign( const _Ty *ptAssign )
{
if ( 0 == ptAssign || m_nRow < 1 || m_nCol < 1 )
{
return false;
}
copy( ptAssign, ptAssign + m_nCol * m_nRow, m_pElem );
return true;
}template< typename _Ty, typename _F >
MATINLINE bool CMatrix< _Ty, _F >::Assign( const _Ty &tValue )
{
if ( m_nRow < 1 || m_nCol < 1 )
{
return false;
}
fill( m_pElem, m_pElem + m_nRow * m_nCol, tValue );
return true;
}template< typename _Ty, typename _F >
MATINLINE _Ty& CMatrix< _Ty, _F >::GetElem( _F nRow, _F nCol )
{
return m_pElem[ nRow * m_nCol + nCol ];
}template< typename _Ty, typename _F >
MATINLINE const _Ty& CMatrix< _Ty, _F >::GetElem( _F nRow, _F nCol ) const
{
return m_pElem[ nRow * m_nCol + nCol ];
}template< typename _Ty, typename _F >
MATINLINE _Ty* CMatrix< _Ty, _F >::GetBuffer( void )
{
return m_pElem;
}template< typename _Ty, typename _F >
MATINLINE const _Ty* CMatrix< _Ty, _F >::GetBuffer( void ) const
{
return m_pElem;
}template< typename _Ty, typename _F >
MATINLINE _F CMatrix< _Ty, _F >::GetRowCount( void ) const
{
return m_nRow;
}template< typename _Ty, typename _F >
MATINLINE _F CMatrix< _Ty, _F >::GetColCount( void ) const
{
return m_nCol;
}template< typename _Ty, typename _F >
CMatrix< _Ty, _F >& CMatrix< _Ty, _F >::operator =( const CMatrix &mOther )
{
if ( mOther.m_nRow < 1 || mOther.m_nCol < 1 )
{
Clear();
return *this;
}
if ( m_nRow == mOther.m_nRow && m_nCol == mOther.m_nCol )
{
copy( mOther.m_pElem, mOther.m_pElem + m_nCol * m_nRow, m_pElem );
}
else
{
Clear();
Create( mOther.m_nRow, mOther.m_nCol, mOther.m_pElem );
}
return *this;
}template< typename _Ty, typename _F >
CMatrix< _Ty, _F >& CMatrix< _Ty, _F >::operator =( const _Ty &tValue )
{
if ( m_nRow < 1 || m_nCol < 1 )
{
Clear();
return *this;
}
_F nCount = m_nRow * m_nCol;
for ( _F i = 0; i < nCount; i++ )
{
m_pElem[i] = tValue;
}
return *this;
}//addition of array substitution
template< typename _Ty, typename _F >
CMatrix< _Ty, _F > CMatrix< _Ty, _F >::operator+( const CMatrix &mOther ) const
{
CMatrix< _Ty, _F > mTemp = *this;
mTemp += mOther;
return mTemp;
}
//addition random
template< typename _Ty, typename _F >
CMatrix< _Ty, _F >& CMatrix< _Ty, _F >::operator+=( const CMatrix &mOther )
{
if ( m_nRow < 1 || m_nCol < 1 || m_nRow != mOther.m_nRow|| m_nCol != mOther.m_nCol )
{
return *this;
}
_F nCount = m_nRow * m_nCol;
for ( _F i = 0; i < nCount; i++ )
{
m_pElem[i] += mOther.m_pElem[i];
}
return *this;
}// scalar multiplication(数乘) of array substitution
template< typename _Ty, typename _F >
CMatrix< _Ty, _F > CMatrix< _Ty, _F >::operator *( const _Ty &tValue ) const
{
CMatrix< _Ty, _F > mTemp( *this );
mTemp *= tValue;
return mTemp;
}template< typename _Ty, typename _F >
CMatrix< _Ty, _F >& CMatrix< _Ty, _F >::operator *=( const _Ty &tValue )
{
if ( m_nRow < 1 || m_nCol < 1 )
{
return *this;
}
_F nCount = m_nRow * m_nCol;
for ( _F i = 0; i < nCount; i++ )
{
m_pElem[i] *= tValue;
}
return *this;
}//multiply each other
template< typename _Ty, typename _F >
CMatrix< _Ty, _F > CMatrix< _Ty, _F >::operator *( const CMatrix &mOther ) const
{
CMatrix< _Ty, _F > mTemp( *this );
mTemp *= mOther;
return mTemp;
}template< typename _Ty, typename _F >
CMatrix< _Ty, _F >& CMatrix< _Ty, _F >::operator *=( const CMatrix &mOther )
{
if ( m_nRow < 1 || m_nCol < 1 )
{
return *this;
}
if ( m_nCol != mOther.m_nRow )
{
Clear();
return *this;
}
CMatrix< _Ty, _F > mTemp;
mTemp.Create( m_nRow, mOther.m_nCol );
_F nOtherCol = mOther.m_nCol;
for ( _F j = 0; j < m_nRow; j++ )
{
for ( _F i = 0; i < nOtherCol; i++ )
{
_Ty &nElem = mTemp.m_pElem[ j * mTemp.m_nCol + i ];
nElem = 0;
for ( _F k = 0; k < m_nCol; k++ )
{
nElem += m_pElem[ j * m_nCol + k ] *
mOther.m_pElem[ k * nOtherCol + i ];
}
}
}
*this = mTemp;
return *this;
}
//multiply power
template< typename _Ty, typename _F >
CMatrix< _Ty, _F > CMatrix< _Ty, _F >::operator ^( _F nPower ) const
{
CMatrix< _Ty, _F > mTemp = *this;
mTemp ^= nPower;
return mTemp;
}template< typename _Ty, typename _F >
CMatrix< _Ty, _F >& CMatrix< _Ty, _F >::operator ^=( _F nPower )
{
if ( m_nRow < 1 || m_nCol < 1 )
{
return *this;
}
_F nPowFac;
if ( nPower < 0 )
{
if ( m_nCol != m_nRow )
{
Clear();
return *this;
}
nPowFac = -nPower;
}
nPowFac--;
CMatrix< _Ty, _F > mTemp = *this;
for ( _F i = 0; i < nPowFac; i++ )
{
*this *= mTemp;
}
if ( nPower < 0 )
{
Inversion();
}
return *this;
}
//obtain tranform matrix
template< typename _Ty, typename _F >
bool CMatrix< _Ty, _F >::Transform( void )
{
if ( m_nRow < 1 || m_nCol < 1 )
{
return false;
}
if ( m_nRow == 1 || m_nCol == 1 )
{
return true;
}
CMatrix mTemp( *this );
for ( _F j = 0; j < m_nCol; j++ )
{
for ( _F i = 0; i < m_nRow; i++ )
{
m_pElem[ j * m_nRow + i ] = mTemp.m_pElem[ i * m_nCol + j ];
}
}
_F nTemp = m_nRow;
m_nRow = m_nCol;
m_nCol = nTemp;
return true;
}//obtain determinant evaluation
template< typename _Ty, typename _F >
bool CMatrix< _Ty, _F >::Determinant( _Ty *ptOut ) const
{
if ( m_nRow < 1 || m_nCol < 1 || m_nRow != m_nCol )
{
return false;
}
_Ty tTemp;
_F nExcCount = 0;
CMatrix< _Ty, _F > mTemp( *this );
// 以下过程的说明请参考文档
for ( _F i = 0; i < m_nRow; i++ )
{
// 使对角线不为0
_F nCurExc = mTemp.RegularDiagonal( i, 0 );
if ( _F(-1) == nCurExc )
{
*ptOut = _Ty(0);
return false;
}
nExcCount += nCurExc;
for ( _F j = i + 1; j < m_nCol; j++ )
{
tTemp = -mTemp.m_pElem[ j * m_nCol + i ] / mTemp.m_pElem[ i * m_nCol + i ];
mTemp.ElemTrans( ET_ROWADD, j, i, tTemp );
}
}
*ptOut = _Ty( ( nExcCount % 2 ) * -2 + 1 );
for ( _F i = 0; i < m_nRow; i++ )
{
*ptOut *= mTemp.m_pElem[ i * m_nCol + i ];
}
return true;
}template< typename _Ty, typename _F >
bool CMatrix< _Ty, _F >::Cofactor( _F nRow, _F nCol )
{
if ( m_nRow < 2 || m_nCol < 2 || nRow >= m_nRow || nCol >= m_nCol )
{
return false;
}
CMatrix< _Ty, _F > mTemp( *this );
Clear();
Create( mTemp.m_nRow - 1, mTemp.m_nCol - 1 );
_F nDestRow;
for ( _F j = 0; j < m_nRow; j++ )
{
nDestRow = j >= nRow ? j + 1 : j;
copy( mTemp.m_pElem + nDestRow * mTemp.m_nCol,// 源矩阵起始点1
mTemp.m_pElem + nDestRow * mTemp.m_nCol + nCol,// 源矩阵结束点1
m_pElem + j * m_nCol );// 目标阵起始点1
copy( mTemp.m_pElem + nDestRow * mTemp.m_nCol + nCol + 1,// 源矩阵起始点2
mTemp.m_pElem + nDestRow * mTemp.m_nCol + mTemp.m_nCol,// 源矩阵结束点2
m_pElem + j * m_nCol + nCol );// 目标阵起始点2
}
return true;
}//obtain Adjoint evaluation
template< typename _Ty, typename _F >
bool CMatrix< _Ty, _F >::Adjoint( void )
{
if ( m_nRow < 2 || m_nCol < 2 || m_nRow != m_nCol )
{
return false;
}
CMatrix< _Ty, _F > mTemp( *this );
CMatrix< _Ty, _F > CofMat;
for ( _F j = 0; j < m_nRow; j++ )
{
for ( _F i = 0; i < m_nCol; i++ )
{
_Ty &det = m_pElem[ j * m_nCol + i ];
CofMat = mTemp;
CofMat.Cofactor( j, i );
CofMat.Determinant( &det );
det *= ( ( i + j ) % 2 ) * -2 + 1;
}
}
Transform();
return true;
}template< typename _Ty, typename _F >
bool CMatrix< _Ty, _F >::Identity( void )
{
if ( m_nRow < 1 || m_nCol < 1 || m_nRow != m_nCol )
{
return false;
}
fill( m_pElem, m_pElem + m_nRow * m_nCol, _Ty(0) );
for ( _F i = 0; i < m_nRow; i++ )
{
m_pElem[ i * m_nCol + i ] = _Ty(1);
}
return true;
}template< typename _Ty, typename _F >
bool CMatrix< _Ty, _F >::ElemTrans( ETMETHOD Method, _F nFirst,
_F nSecond, const _Ty &tValue )
{
// 检查参数
if ( m_nRow < 1 || m_nCol < 1 || m_nRow != m_nCol )
{
return false;
}
switch ( Method )
{
case ET_ROWADD: case ET_ROWEXC: case ET_COLADD: case ET_COLEXC:
if ( nSecond >= m_nRow ) return false;
case ET_ROWMUL: case ET_COLMUL:
if ( nFirst >= m_nRow ) return false;
break;
default:
return false;
}
switch ( Method )
{
// 行倍乘
case ET_ROWMUL:
for ( _F i = 0; i < m_nCol; i++ )
{
m_pElem[ nFirst * m_nCol + i ] *= tValue;
}
break;
// 行倍加
case ET_ROWADD:
for ( _F i = 0; i < m_nCol; i++ )
{
m_pElem[ nFirst * m_nCol + i ] +=
( m_pElem[ nSecond * m_nCol + i ] * tValue );
}
break;
// 行对换
case ET_ROWEXC:
for ( _F i = 0; i < m_nCol; i++ )
{
swap( m_pElem[ nFirst * m_nCol + i ],
m_pElem[ nSecond * m_nCol + i ] );
}
break;
// 列倍乘
case ET_COLMUL:
for ( _F j = 0; j < m_nRow; j++ )
{
m_pElem[ j * m_nCol + nFirst ] *= tValue;
}
break;
// 列倍加
case ET_COLADD:
for ( _F j = 0; j < m_nRow; j++ )
{
m_pElem[ j * m_nCol + nFirst ] +=
( m_pElem[ j * m_nCol + nSecond ] * tValue );
}
break;
// 列对换
case ET_COLEXC:
for ( _F j = 0; j < m_nRow; j++ )
{
swap( m_pElem[ j * m_nCol + nFirst ],
m_pElem[ j * m_nCol + nSecond ] );
}
break;
}
return true;
}template< typename _Ty, typename _F >
bool CMatrix< _Ty, _F >::Inversion( void )
{
// 检查参数
if ( m_nRow <= 0 || m_nCol <= 0 || m_nRow != m_nCol )
{
return false;
}
_Ty tTemp;
CMatrix< _Ty, _F > mTemp( *this );
Identity();
// 以下过程的说明请参考文档
for ( _F i = 0; i < m_nRow; i++ )
{
// 使对角线不为0
if ( _F(-1) == mTemp.RegularDiagonal( i, this ) )
{
return false;
}
tTemp = _Ty(1) / mTemp.m_pElem[ i * m_nCol + i ];
mTemp.ElemTrans( ET_ROWMUL, i, 0, tTemp );
ElemTrans( ET_ROWMUL, i, 0, tTemp );
for ( _F j = 0; j < m_nCol; j++ )
{
if ( i == j )
{
continue;
}
tTemp = -mTemp.m_pElem[ j * m_nCol + i ];
mTemp.ElemTrans( ET_ROWADD, j, i, tTemp );
ElemTrans( ET_ROWADD, j, i, tTemp );
}
}
return true;
}template< typename _Ty, typename _F >
_F CMatrix< _Ty, _F >::RegularDiagonal( _F nIndex, CMatrix< _Ty, _F > *pConc )
{
_F nTransCount = 0;
if ( equal( m_pElem[ nIndex * m_nCol + nIndex ], _Ty(0) ) )
{
// 如果有零元素,则查找其它该列不为零元素的行
for ( _F j = nIndex + 1; j < m_nRow; j++ )
{
if ( nIndex == j )
{
continue;
}
if ( !equal( m_pElem[ j * m_nCol + nIndex ], _Ty(0) ) )
{
ElemTrans( ET_ROWEXC, nIndex, j, 0 );
if ( pConc != 0 )
{
pConc->ElemTrans( ET_ROWEXC, nIndex, j, 0 );
}
nTransCount++;
break;
}
}
}
if ( equal( m_pElem[ nIndex * m_nCol + nIndex ], _Ty(0) ) )
{
// 如果有零元素,则查找其它该列不为零元素的行
for ( _F j = nIndex + 1; j < m_nCol; j++ )
{
if ( nIndex == j )
{
continue;
}
if ( !equal( m_pElem[ nIndex * m_nCol + j ], _Ty(0) ) )
{
ElemTrans( ET_COLEXC, nIndex, j, 0 );
if ( pConc != 0 )
{
pConc->ElemTrans( ET_COLEXC, nIndex, j, 0 );
}
nTransCount++;
break;
}
}
}
return equal( m_pElem[ nIndex * m_nCol + nIndex ], _Ty(0) ) ? _F(-1) : nTransCount;
}template< typename _Ty, typename _F >
CMatrix< _Ty, _F > operator *( const _Ty &tValue, const CMatrix< _Ty, _F > &mOther )
{
return mOther * tValue;
}