矩阵运算,用mfc

hyjuaun 2005-07-07 05:15:22
矩阵运算 :实现一个二维矩阵类,完成矩阵的运算
要求:1 能象两个整数一样通过 表达式A*B完成矩阵运算。
2 要有想应的输入和输出界面,建立自己的类
...全文
697 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
dawndu 2005-09-09
  • 打赏
  • 举报
回复
楼上的楼上,自己写出来的?
赞一个
ohfox 2005-09-09
  • 打赏
  • 举报
回复
可以引用matlab的库函数阿
guangyou 2005-09-09
  • 打赏
  • 举报
回复

//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;
}
guangyou 2005-09-09
  • 打赏
  • 举报
回复
#include "stdafx.h"
#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;
}
guangyou 2005-09-09
  • 打赏
  • 举报
回复
别人的模版,做一个参考吧!
#pragma once
#define MATINLINE __forceinline

template<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 );

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧