一个简单的Matrix实现
来源:互联网 发布:网状数据库的特点 编辑:程序博客网 时间:2024/05/17 06:16
我们直接来看代码吧:
- /* Matrix.h */
- #pragma once
- #include <iostream>
- using namespace std;
- //矩阵类
- class Matrix
- {
- public:
- double * p;
- //矩阵宽度
- long width;
- //矩阵高度
- long height;
- public:
- long getHeight();
- long getWidth();
- bool isVector();//如果是false,那就是一个数
- double Arg();//求行列式
- bool isPtv();//是否正定
- Matrix T();//转置
- Matrix subMatrix(long offset);
- void Test();//测试函数
- /***********重载部分-Overloaded Part*****************/
- Matrix operator+(Matrix &);
- Matrix operator-(Matrix &);
- Matrix operator*(Matrix &);
- friend Matrix operator*(double alpha,Matrix &);//实数与矩阵相乘
- Matrix operator*(double alpha);//矩阵与实数相乘
- Matrix operator/(Matrix &);//实际是实数相除或矩阵和实数相除
- Matrix operator/(double sub);
- Matrix operator+=(Matrix &);
- Matrix operator-=(Matrix &);
- Matrix operator*=(double alpha);//矩阵与实数相乘
- friend Matrix sqrt(Matrix m);//开方
- friend double abs(Matrix &);//取绝对值
- Matrix &operator=(Matrix &);
- double * operator[](long heightPos);//用于实现用[][]操作矩阵元素
- friend ostream & operator<<(ostream &,Matrix &) ;
- Matrix(void);//default constructor
- Matrix(long n);//单位矩阵
- Matrix(double * arrAddress,long arrWidth);//构造一维矩阵
- Matrix(double * arrAddress,long arrWidth,long arrHeight);
- Matrix(const Matrix &);//copy constructor
- ~Matrix(void);//default destructor
- /***********重载部分-Overloaded Part*****************/
- };
下面是实现和测试的代码:
- /* Matrix.cpp */
- #include "Matrix.h"
- #include <math.h>
- #include <assert.h>
- Matrix::Matrix(void)
- {
- p=new double[1];
- width=0;
- height=0;
- }
- Matrix::Matrix(long n)
- {
- height=width=n;
- p=new double[n*n];
- for(long i=0;i<n;i++){
- for(long j=0;j<n;j++){
- if(i==j) *(p+n*i+j)=1;
- else *(p+n*i+j)=0;
- }
- }
- }
- Matrix::Matrix(double * arrAddress,long arrWidth)
- {
- long arrHeight=1;
- p=new double[arrWidth*arrHeight];
- for(long i=0;i<arrHeight;i++){
- for(long j=0;j<arrWidth;j++){
- *(p+arrWidth*i+j)=*(arrAddress+arrWidth*i+j);
- }
- }
- width=arrWidth;
- height=arrHeight;
- }
- Matrix::Matrix(double * arrAddress,long arrWidth,long arrHeight)
- {
- p=new double[arrWidth*arrHeight];
- for(long i=0;i<arrHeight;i++){
- for(long j=0;j<arrWidth;j++){
- *(p+arrWidth*i+j)=*(arrAddress+arrWidth*i+j);
- }
- }
- width=arrWidth;
- height=arrHeight;
- }
- Matrix::Matrix(const Matrix & m)//copy constructor
- {
- height=m.height;
- width=m.width;
- p=new double[height*width];
- for(long i=0;i<height;i++){
- for(long j=0;j<width;j++){
- *(p+width*i+j)=*(m.p+width*i+j);
- }
- }
- }
- long Matrix::getWidth(){
- return width;
- }
- long Matrix::getHeight(){
- return height;
- }
- bool Matrix::isVector()
- {
- return !(width==1 && height==1);
- }
- Matrix Matrix::subMatrix(long offset)
- {
- assert(height==width && offset<=width && offset>=0);
- double * t=new double[offset*offset];
- for(long i=0;i<offset;i++){
- for(long j=0;j<offset;j++){
- *(t+offset*i+j)=*(p+width*i+j);
- }
- }
- Matrix m(t,offset,offset);
- delete [] t;
- return m;
- }
- double Matrix::Arg()//矩阵的行列式
- {
- assert(width==height);
- double result=1;
- double k;
- Matrix m=*this;
- for(long i=0;i<height-1;i++){//Gauss消去法,变换成上三角矩阵
- for(long j=i+1;j<height;j++){
- k=m[j][i]/m[i][i];
- m[j][i]=0;
- for(long n=i+1;n<width;n++){
- m[j][n]=m[j][n]-k*m[i][n];
- }
- }
- }
- for(i=0;i<height;i++){
- for(long j=0;j<width;j++){
- if(i==j) result*=m[i][j];
- }
- }
- return result;
- }
- bool Matrix::isPtv()
- {
- assert(width==height);//是方阵才可以计算
- bool result=true;
- Matrix m;
- for(long i=1;i<=height;i++){
- m=this->subMatrix(i);
- if(m.Arg()<=0){
- result=false;
- break;
- }
- }
- return result;
- }
- Matrix Matrix::T()
- {
- double * t=new double[width*height];
- for(long i=0;i<height;i++){
- for(long j=0;j<width;j++){
- *(t+height*j+i)=*(p+width*i+j);
- }
- }
- Matrix m(t,height,width);
- delete [] t;
- return m;
- }
- Matrix Matrix::operator +(Matrix &m1)
- {
- assert(m1.height==height && m1.width==width);
- long tmpHeight=m1.height;
- long tmpWidth=m1.width;
- double * t=new double[tmpWidth*tmpHeight];
- for(long i=0;i<tmpHeight;i++){
- for(long j=0;j<tmpWidth;j++){
- *(t+tmpWidth*i+j)=*(m1.p+tmpWidth*i+j)+*(p+tmpWidth*i+j);
- }
- }
- Matrix m(t,tmpWidth,tmpHeight);
- delete [] t;
- return m;
- }
- Matrix Matrix::operator -(Matrix &m1)
- {
- assert(m1.height==height && m1.width==width);
- long tmpHeight=m1.height;
- long tmpWidth=m1.width;
- double * t=new double[tmpWidth*tmpHeight];
- for(long i=0;i<tmpHeight;i++){
- for(long j=0;j<tmpWidth;j++){
- *(t+tmpWidth*i+j)=*(p+tmpWidth*i+j)-*(m1.p+tmpWidth*i+j);
- }
- }
- Matrix m(t,tmpWidth,tmpHeight);
- delete [] t;
- return m;
- }
- Matrix Matrix::operator *(Matrix &m1)
- {
- if(!this->isVector() && m1.isVector()){//左为数,右为矩阵
- Matrix m;
- m=p[0]*m1;
- return m;
- }else if(this->isVector() && !m1.isVector()){//左为矩阵,右为数
- Matrix m;
- m=*this*m1[0][0];
- return m;
- }else if(!this->isVector() && m1.isVector()){//左右都为数
- double * t=new double[1];
- t[0]=p[0]*m1[0][0];
- Matrix m(t,1,1);
- delete [] t;
- return m;
- }else if(this->isVector() && m1.isVector() && width==m1.height){//左为矩阵,右为矩阵
- double sum;
- double * t=new double[height*m1.width];
- for(long i=0;i<height;i++){
- for(long j=0;j<m1.width;j++){
- sum=0;
- for(long k=0;k<width;k++){
- sum+=(*(p+width*i+k))*(m1[k][j]);
- }
- *(t+m1.width*i+j)=sum;
- }
- }
- Matrix m(t,m1.width,height);
- delete [] t;
- return m;
- }else{
- assert(0);//未知运算
- return *this;
- }
- }
- Matrix operator*(double alpha,Matrix & m1)
- {
- Matrix m=m1;
- for(long i=0;i<m.height;i++){
- for(long j=0;j<m.width;j++){
- m[i][j]=alpha*m1[i][j];
- }
- }
- return m;
- }
- Matrix Matrix::operator*(double alpha)
- {
- return alpha*(*this);
- }
- Matrix Matrix::operator+=(Matrix & m)
- {
- return *this+m;
- }
- Matrix Matrix::operator-=(Matrix & m)
- {
- return *this-m;
- }
- Matrix Matrix::operator *=(double alpha)
- {
- return *this*alpha;
- }
- Matrix sqrt(Matrix m)
- {
- m[0][0]=sqrt(m[0][0]);
- return m;
- }
- double abs(Matrix & m)
- {
- double sum=0;
- for(long i=0;i<m.height;i++){
- for(long j=0;j<m.width;j++){
- sum+=m[i][j]*m[i][j];
- }
- }
- return sqrt(sum);
- }
- Matrix Matrix::operator /(Matrix &m1)
- {
- assert(m1.width==1 && m1.height==1);
- return *this/m1[0][0];
- }
- Matrix Matrix::operator /(double sub)
- {
- Matrix m=*this;
- for(long i=0;i<height;i++){
- for(long j=0;j<width;j++){
- m[i][j]=*(p+width*i+j)/sub;
- }
- }
- return m;
- }
- Matrix & Matrix::operator =(Matrix & m)
- {
- if(&m==this) return *this;
- height=m.height;
- width=m.width;
- delete [] p;
- p=new double[height*width];
- for(long i=0;i<height;i++){
- for(long j=0;j<width;j++){
- *(p+width*i+j)=*(m.p+width*i+j);
- }
- }
- return *this;
- }
- double * Matrix::operator [](long heightPos)
- {
- assert(heightPos>=0 && heightPos<height);
- return p+width*heightPos;
- }
- ostream & operator<<(ostream & os,Matrix & m)
- {
- os<<"Matrix:height="<<m.height<<endl;
- os<<"Matrix:width="<<m.width<<endl;
- for(long i=0;i<m.height;i++){
- for(long j=0;j<m.width;j++){
- os<<m[i][j]<<" ";
- }
- os<<endl;
- }
- return os;
- }
- Matrix::~Matrix(void)
- {
- delete [] p;
- }
- void Matrix::Test(){
- double arr[4][4]={{1,1,1,1},{1,2,3,4},{1,3,6,10},{1,4,10,20}};
- Matrix m1,m(&arr[0][0],4,4),m2(&arr[0][0],4,4);
- m.isPtv();
- /*
- cout<<"arranger="<<m.Arg()<<endl;
- cout<<m;*/
- }
- void main()
- {
- Matrix obj;
- obj.Test();
- }
我们可以从文件中发现Matrix常用的功能,比如SubMatrix()、乘法等等。另外,将Matrix的测试过程,包含在Matrix类本身——我觉得这种方式类似于“白盒”测试;如果包装成对象再测试,那就是“黑盒”:)
- 一个简单的Matrix实现
- Matrix的基本使用与倒影效果的简单实现
- matrix 重载操作,firend 函数实现 简单的例子
- 一个简单singleton的实现
- 一个简单的SOA实现
- 一个HUD的简单实现
- 哈希表一个简单的实现
- 一个四叉树的简单实现
- 一个简单文件系统的实现
- 一个简单的信号量实现
- 一个简单的RTTI实现
- 一个简单的队列实现
- 实现一个简单的shell
- 一个简单扫描器的实现
- 一个简单嗅探器的实现
- PageRank的一个简单实现
- 一个简单文件系统的实现
- 一个简单的nodeJS实现
- vc 运行exe时生成dll的方法
- 瑞星误杀 技术缺失还是道德缺失?
- 创业从这里开始
- PC市场需求下滑 分析师调降英特尔业绩预期
- 吴敬琏:中国经济突围需更多“淘宝”
- 一个简单的Matrix实现
- 李力刚:职场上如何成功推销自己
- 细算软件外包两本账 西安再拼政策优势
- 我们的未来在哪里?!
- 马云:改变商业生态社会设计师
- Linux 下几个特别有用的设备文件
- 谷歌周二推出Gmail视频和语音聊天插件
- LCD三巨头承认操纵价格 认罚5.85亿美元
- 几个 Linux 命令行的小技巧