此次的矩阵类可以使用双下标,并且带有越界检查能力
用例:
jks::CMatrix<int> m(3,4);
int i,j;
for (i=0;i<m.getHeight();i++)
{
for (j=0;j<m.getWidth();j++)
{
m[i][j] = i*10+j;
}
}
cerr<<m;
=========================================================================
头文件
#if !defined(__JKS_MATRIX_HPP_)
#define __JKS_MATRIX_HPP_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <cassert>
#include <iostream>
namespace jks
{
//////////////////////////////////////////////////////////////////////////
template<typename T>
class CMatrix
{
class CLine
{
T* _pLine;
CMatrix* _pMat;
public:
CLine(T* pLine,CMatrix* pMat):_pLine(pLine),_pMat(pMat) {};
T& operator[] (long nCol)
{assert(nCol>=0 && nCol<_pMat->getWidth());return _pLine[nCol];}
};
long _sLn,_sCol;
T* _pData;
public:
CMatrix();
CMatrix(T * arrAddress,long arrWidth);//构造一维矩阵(一行,arrWidth列)
CMatrix(T * arrAddress,long arrHeight,long arrWidth);//构造二维矩阵
CMatrix(long Height,long Width);//构造空矩阵
CMatrix(const CMatrix<T> &);//复制构造函数
virtual ~CMatrix(void);//默认析构函数
//属性
long getHeight() const {return _sLn;}
long getWidth() const {return _sCol;}
T* getData(long& arrHeight,long& arrWidth,T* p=NULL) const;
T* getData(int& arrHeight,int& arrWidth,T* p=NULL) const
{long t1 = arrHeight;long t2 = arrWidth;
arrHeight = _sLn;arrWidth = _sCol;
return getData(t1,t2,p);}
operator void* () {return isValid()?this:0;}
bool isValid() const
{
if(this!=NULL && _pData!=NULL) return true;
else return false;
}
bool isInDomain(long nLn,long nCol)
{
if (nLn<_sLn && nLn>=0 && nCol<_sCol && nCol>=0)
return true;
else
return false;
}
int isVector();//如果是0,那就是一个数;1,列向量;-1行向量
//运算
CMatrix operator+(CMatrix<T> &);
CMatrix operator-(CMatrix<T> &);
CMatrix operator*(CMatrix<T> &);
friend CMatrix operator*(double alpha,CMatrix<T> &);//实数与矩阵相乘
CMatrix operator*(double alpha);//矩阵与实数相乘
CMatrix operator/(CMatrix<T> &);//实际是实数相除或矩阵和实数相除
CMatrix operator/(double sub);
CMatrix operator+=(CMatrix<T> &);
CMatrix operator-=(CMatrix<T> &);
CMatrix operator*=(CMatrix<T> &);//矩阵与实数相乘
CMatrix operator*=(double alpha);//矩阵与实数相乘
CMatrix & operator = (CMatrix<T> &);//赋值
CLine operator[](long heightPos);//用于实现用[][]操作矩阵元素
friend CMatrix sqrt(CMatrix<T> m);//开方
friend double abs(CMatrix<T> &);//取绝对值(泛数)
friend double sum(CMatrix<T> &);//求和
friend CMatrix multiply(CMatrix<T> &m1,CMatrix<T> & m2);//按元素相乘
friend T operator+(double dbl,CMatrix<T> &);
friend T operator+(CMatrix<T> &,double dbl);
friend T operator-(double dbl,CMatrix<T> &);
friend T operator-(CMatrix<T> &,double dbl);
const T* c_ptr() const;
friend bool operator == (CMatrix<T> &,CMatrix<T> &);
//输出
friend std::ostream& operator<<(std::ostream &,jks::CMatrix<T> &);
public:
//公有属性
static float m_fPrecision;//控制==的精度
static double m_dPrecision;
};
//////////////////////////////////////////////////////////////////////////
//函数实现
template<typename T>
float CMatrix<T>::m_fPrecision = 0.0000001;
template<typename T>
double CMatrix<T>::m_dPrecision = 1e-20;
//////////////////////////////////////////////////////////////////////////
//构造与析构
template<typename T>
CMatrix<T>::CMatrix(void)//:_sCol(1),_sLn(1)
{
_sCol = 0;
_sLn = 0;
_pData=NULL;
}
template<typename T>
CMatrix<T>::CMatrix(T * arrAddress,long arrWidth)
{
long arrHeight=1;
_pData=new T[arrWidth*arrHeight];
memcpy(_pData,arrAddress,arrWidth*arrHeight*sizeof(T));
_sCol=arrWidth;
_sLn=arrHeight;
}
template<typename T>
CMatrix<T>::CMatrix(T * arrAddress,long arrHeight,long arrWidth)
{
_pData=new T[arrWidth*arrHeight];
memcpy(_pData,arrAddress,arrWidth*arrHeight*sizeof(T));
_sCol=arrWidth;
_sLn=arrHeight;
}
template<typename T>
CMatrix<T>::CMatrix(long height,long width)
{
_sCol=width;
_sLn=height;
_pData=new T[height*width];
}
template<typename T>
CMatrix<T>::CMatrix(const CMatrix<T> & m)//copy constructor
{
_sLn=m._sLn;
_sCol=m._sCol;
_pData=new T[_sLn*_sCol];
memcpy(_pData,m._pData,_sLn*_sCol*sizeof(T));
}
template<typename T>
CMatrix<T>::~CMatrix()
{
if (_pData)
{
delete []_pData;
}
_pData = NULL;
_sLn = 0;
_sCol = 0;
}
//////////////////////////////////////////////////////////////////////////
//运算
template<typename T>
CMatrix<T> CMatrix<T>::operator +(CMatrix &m1)
{
assert(m1._sLn==_sLn && m1._sCol==_sCol);
long tmpHeight=m1._sLn;
long tmpWidth=m1._sCol;
T * t=new T[tmpWidth*tmpHeight];
for(long i=0;i<tmpHeight;i++){
for(long j=0;j<tmpWidth;j++){
*(t+tmpWidth*i+j)=*((T*)m1._pData+tmpWidth*i+j)+*((T*)_pData+tmpWidth*i+j);
}
}
CMatrix<T> m(t,tmpHeight,tmpWidth);
delete [] t;
return m;
}
template<typename T>
CMatrix<T> CMatrix<T>::operator -(CMatrix &m1)
{
assert(m1._sLn==_sLn && m1._sCol==_sCol);
long tmpHeight=m1._sLn;
long tmpWidth=m1._sCol;
T * t=new T[tmpWidth*tmpHeight];
for(long i=0;i<tmpHeight;i++){
for(long j=0;j<tmpWidth;j++){
*(t+tmpWidth*i+j)=*((T*)_pData+tmpWidth*i+j)-*((T*)m1._pData+tmpWidth*i+j);
}
}
CMatrix<T> m(t,tmpHeight,tmpWidth);
delete [] t;
return m;
}
template<typename T>
CMatrix<T> CMatrix<T>::operator *(CMatrix &m1)
{
if(!this->isVector() && m1.isVector()){//左为数,右为矩阵
CMatrix<T> m;
m=((T*)_pData)[0]*m1;
return m;
}else if(this->isVector() && !m1.isVector()){//左为矩阵,右为数
CMatrix m;
m=*this*m1[0][0];
return m;
}else if(!this->isVector() && m1.isVector()){//左右都为数
T * t=new T[1];
t[0]=((T*)_pData)[0]*m1[0][0];
CMatrix<T> m(t,1,1);
delete [] t;
return m;
}else if(this->isVector() && m1.isVector() && _sCol==m1._sLn){//左为矩阵,右为矩阵
double sum;
T * t=new T[_sLn*m1._sCol];
for(long i=0;i<_sLn;i++){
for(long j=0;j<m1._sCol;j++){
sum=0;
for(long k=0;k<_sCol;k++){
sum+=(*((T*)_pData+_sCol*i+k))*(m1[k][j]);
}
*(t+m1._sCol*i+j)=sum;
}
}
CMatrix<T> m(t,_sLn,m1._sCol);
delete [] t;
return m;
}else{
assert(0);//未知运算
return *this;
}
}
template<typename T>
CMatrix<T> operator*(double alpha,CMatrix<T> & m1)
{
CMatrix<T> m=m1;
for(long i=0;i<m._sLn;i++){
for(long j=0;j<m._sCol;j++){
m[i][j]=alpha*m1[i][j];
}
}
return m;
}
template<typename T>
CMatrix<T> CMatrix<T>::operator*(double alpha)
{
return alpha*(*this);
}
template<typename T>
CMatrix<T> CMatrix<T>::operator+=(CMatrix<T> & m)
{
return *this+m;
}
template<typename T>
CMatrix<T> CMatrix<T>::operator-=(CMatrix<T> & m)
{
return *this-m;
}
template<typename T>
CMatrix<T> CMatrix<T>::operator *=(double alpha)
{
return *this*alpha;
}
template<typename T>
CMatrix<T> CMatrix<T>::operator *=(CMatrix<T> & m1)
{
return *this*m1;
}
template<typename T>
const T* CMatrix<T>::c_ptr () const
{
return _pData;
}
template<typename T>
CMatrix<T> CMatrix<T>::operator /(CMatrix<T> &m1)
{
assert(m1._sCol==1 && m1._sLn==1);
assert(m1[0][0]!=0);
return *this/m1[0][0];
}
template<typename T>
CMatrix<T> CMatrix<T>::operator /(double sub)
{
assert(sub!=0);
CMatrix<T> m=*this;
for(long i=0;i<_sLn;i++){
for(long j=0;j<_sCol;j++){
m[i][j]=*((T*)_pData+_sCol*i+j)/sub;
}
}
return m;
}
template<typename T>
CMatrix<T> & CMatrix<T>::operator =(CMatrix<T> & m)
{
if(&m==this) return *this;
_sLn=m._sLn;
_sCol=m._sCol;
if(_pData)
{
delete [] _pData;
_pData = NULL;
}
_pData=new T[_sLn*_sCol];
memcpy(_pData,m._pData,_sLn*_sCol*sizeof(T));
return *this;
}
template<typename T>
bool operator == (CMatrix<T>& m1,CMatrix<T>& m2)
{
if (&m1 == &m2)
{
return true;
}
if (m1.getWidth()!=m2.getWidth() || m1.getHeight()!=m2.getHeight())
{
return false;
}
T *p1,*p2;
p1 = m1[0];
p2 = m2[0];
long sum = m1.getHeight()*m1.getWidth();
long i;
if(typeid(T) == typeid(float))
for (i=0;i<sum;i++)
{
if (fabs(*p1++ - *p2++)<CMatrix<T>::m_fPrecision)
{
return false;
}
}
if(typeid(T) == typeid(double))
for (i=0;i<sum;i++)
{
if (fabs(*p1++ - *p2++)<CMatrix<T>::m_dPrecision)
{
return false;
}
}
else
for (i=0;i<sum;i++)
{
if (*p1++ != *p2++)
{
return false;
}
}
return true;
}
template<typename T>
T operator+(double dbl,CMatrix<T> & m)
{
assert(m.getHeight()==1 && m.getWidth()==1);
return dbl+m[0][0];
}
template<typename T>
T operator+(CMatrix<T> & m,double dbl)
{
return dbl+m;
}
template<typename T>
T operator-(double dbl,CMatrix<T> & m)
{
assert(m.getHeight()==1 && m.getWidth()==1);
return dbl-m[0][0];
}
template<typename T>
T operator-(CMatrix<T> & m,double dbl)
{
return -(dbl-m);
}
template<typename T>
CMatrix<T>::CLine CMatrix<T>::operator [](long heightPos)
{
assert(isValid());
assert(heightPos>=0 && heightPos<=_sLn);//报错
CLine rLine(_pData+heightPos*_sCol,this);
return rLine;//取回的是行头指针
}
//////////////////////////////////////////////////////////////////////////
//输出
template<typename T>
std::ostream & operator<<(std::ostream & os,jks::CMatrix<T> & m)
{
os<<"Sum Ln:"<<m._sLn<<" "<<"Sum Col:"<<m._sCol<<std::endl;
long i,j;
if(typeid(T)==typeid(unsigned char))
for (i=0;i<m._sLn;i++)
{
for (j=0;j<m._sCol;j++)
{
os<<(int)m._pData[i*m._sCol+j]<<"/t";
}
os<<std::endl;
}
else
for (i=0;i<m._sLn;i++)
{
for (j=0;j<m._sCol;j++)
{
os<<m._pData[i*m._sCol+j]<<"/t";
}
os<<std::endl;
}
return os;
}
//////////////////////////////////////////////////////////////////////////
template<typename T>
int CMatrix<T>::isVector()
{
//return !(nWidth==1 && nHeight==1);
if (_sCol==1)
if (_sLn==1)
return 0;
else
return 1;
else
return -1;
}
//////////////////////////////////////////////////////////////////////////
}//
#endif // !defined(__JKS_MATRIX_HPP_)
分享到:
相关推荐
类模板实现矩阵类;能够输出矩阵的行数,列数和元素最大值等信息; c++;
CMatrix 实现的矩阵类 使用的时候包含#include "Matrix.h"就行 CMatrix的接口函数都在"Matrix.h"里面 CVector的接口函数在"Vector.h"里,"Matrix.h"里包含了"Vector.h" 具体用法与测试用例Main.cpp里有3个测试用例...
CMatrix 实现的矩阵类 使用的时候包含#include "Matrix.h"就行 CMatrix的接口函数都在"Matrix.h"里面 CVector的接口函数在"Vector.h"里,"Matrix.h"里包含了"Vector.h" 具体用法与测试用例Main.cpp里有3个测试用例...
VS2010下实现的一个double型的矩阵类,重载了+ - * / = 等多种操作符,并且实现了求解矩阵行列式,逆运算,转置等操作
VC++中使用的矩阵类模板,实现了矩阵的存储,转置等问题。
可重用的矩阵类,实现了矩阵的各种运算,包括加、减、转置等等,(说明:转载)
C++课程设计 矩阵类 课程设计报告,包含全部代码和描述
矩阵类的运算符重载,编写一个矩阵类Matrix,并重载运算符“+”、“-”、“*”、“>>”、“”来分别实现矩阵的加法、减法、乘法,以及标准流输入和流输出操作。
用C#写的矩阵类,包含矩阵的四则运算、叉乘、转置、行列式、逆矩阵、卷积等。
C#的矩阵类,包含矩阵的加减乘除,求逆,转置,赋值等
这是利用做的一个矩阵类及其实现,包括矩阵行列式和矩阵求逆的运算,代码通俗易懂,适合学习交流
这个一个老外写的矩阵类,用C++实现,注释详细,把线性代数里用到的加减乘除和转置、求逆等矩阵运算都实现了,小可查到并修改了几个小错误,几近完美了。
矩阵类的功能实现,加减乘逆转置等等……非原创,但特别好……
这是一个关于矩阵操作的C++矩阵类程序,主要包括赋值,取值,分配大小,重新分配等基本操作,整个类的操作接口下,基本功能齐全。
一个老外写的可扩展C++矩阵类(包括实例,VS2010可用)
简单的c++代码实现矩阵类的学习要求,仅供初学者参考,
VC++矩阵类,可以实现矩阵的加,乘,逆矩阵,单位阵,随机阵,重载运算符,并做了简单的界面来实现简单的操作。。。
定义了矩阵类,能实现矩阵赋值,通过重载运算符实现矩阵的加减乘除(求逆),另外还有转置,求模等等
TOEPLITZ矩阵类的快速算法 徐仲 西北工业大学出版社
矩阵类C#实现,效果还蛮好的。适合新手,欢迎参考,可以实现常用的矩阵运算