矩阵运算  :实现一个二维矩阵类,完成矩阵的运算
要求:1 能象两个整数一样通过 表达式A*B完成矩阵运算。
2 要有想应的输入和输出界面,建立自己的类

解决方案 »

  1.   

    别人的模版,做一个参考吧!
    #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 );
      

  2.   

    #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;
    }
      

  3.   


    //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;
    }