一个简单的Matrix实现

来源:互联网 发布:网状数据库的特点 编辑:程序博客网 时间:2024/05/17 06:16

我们直接来看代码吧:

  1. /*    Matrix.h    */
  2. #pragma once
  3. #include <iostream>
  4. using namespace std;
  5. //矩阵类
  6. class Matrix
  7. {
  8. public:
  9.     double * p;
  10.     //矩阵宽度
  11.     long width;
  12.     //矩阵高度
  13.     long height;
  14. public:
  15.     long getHeight();
  16.     long getWidth();
  17.     bool isVector();//如果是false,那就是一个数
  18.     double Arg();//求行列式
  19.     bool isPtv();//是否正定
  20.     Matrix  T();//转置
  21.     Matrix subMatrix(long offset);
  22.     void Test();//测试函数
  23.     /***********重载部分-Overloaded Part*****************/
  24.     Matrix operator+(Matrix &);
  25.     Matrix operator-(Matrix &);
  26.     Matrix operator*(Matrix &);
  27.     friend Matrix operator*(double alpha,Matrix &);//实数与矩阵相乘
  28.     Matrix operator*(double alpha);//矩阵与实数相乘
  29.     Matrix operator/(Matrix &);//实际是实数相除或矩阵和实数相除
  30.     Matrix operator/(double sub);
  31.     Matrix operator+=(Matrix &);
  32.     Matrix operator-=(Matrix &);
  33.     Matrix operator*=(double alpha);//矩阵与实数相乘
  34.     friend Matrix  sqrt(Matrix m);//开方
  35.     friend double abs(Matrix &);//取绝对值
  36.     Matrix &operator=(Matrix &);
  37.     double * operator[](long heightPos);//用于实现用[][]操作矩阵元素
  38.     friend ostream & operator<<(ostream &,Matrix &) ;
  39.     Matrix(void);//default constructor
  40.     Matrix(long n);//单位矩阵
  41.     Matrix(double * arrAddress,long arrWidth);//构造一维矩阵
  42.     Matrix(double * arrAddress,long arrWidth,long arrHeight);
  43.     Matrix(const Matrix &);//copy constructor
  44.     ~Matrix(void);//default destructor
  45.     /***********重载部分-Overloaded Part*****************/
  46. };

下面是实现和测试的代码:

  1. /*    Matrix.cpp    */
  2. #include "Matrix.h"
  3. #include <math.h>
  4. #include <assert.h>
  5. Matrix::Matrix(void)
  6. {
  7.     p=new double[1];
  8.     width=0;
  9.     height=0;
  10. }
  11. Matrix::Matrix(long n)
  12. {
  13.     height=width=n;
  14.     p=new double[n*n];
  15.     for(long i=0;i<n;i++){
  16.         for(long j=0;j<n;j++){
  17.             if(i==j) *(p+n*i+j)=1;
  18.             else *(p+n*i+j)=0;
  19.         }
  20.     }
  21. }
  22. Matrix::Matrix(double * arrAddress,long arrWidth)
  23. {
  24.     long arrHeight=1;
  25.     p=new double[arrWidth*arrHeight];
  26.     for(long i=0;i<arrHeight;i++){
  27.         for(long j=0;j<arrWidth;j++){
  28.             *(p+arrWidth*i+j)=*(arrAddress+arrWidth*i+j);
  29.         }
  30.     }
  31.     width=arrWidth;
  32.     height=arrHeight;
  33. }
  34. Matrix::Matrix(double * arrAddress,long arrWidth,long arrHeight)
  35. {
  36.     p=new double[arrWidth*arrHeight];
  37.     for(long i=0;i<arrHeight;i++){
  38.         for(long j=0;j<arrWidth;j++){
  39.             *(p+arrWidth*i+j)=*(arrAddress+arrWidth*i+j);
  40.         }
  41.     }
  42.     width=arrWidth;
  43.     height=arrHeight;
  44. }
  45. Matrix::Matrix(const Matrix & m)//copy constructor
  46. {
  47.     height=m.height;
  48.     width=m.width;
  49.     p=new double[height*width];
  50.     for(long i=0;i<height;i++){
  51.         for(long j=0;j<width;j++){
  52.             *(p+width*i+j)=*(m.p+width*i+j);
  53.         }
  54.     }
  55. }
  56. long Matrix::getWidth(){
  57.     return width;
  58. }
  59. long Matrix::getHeight(){
  60.     return height;
  61. }
  62. bool Matrix::isVector()
  63. {
  64.     return !(width==1 && height==1);
  65. }
  66. Matrix Matrix::subMatrix(long offset)
  67. {
  68.     assert(height==width && offset<=width && offset>=0);
  69.     double * t=new double[offset*offset];
  70.     for(long i=0;i<offset;i++){
  71.         for(long j=0;j<offset;j++){
  72.             *(t+offset*i+j)=*(p+width*i+j);
  73.         }
  74.     }
  75.     Matrix m(t,offset,offset);
  76.     delete [] t;
  77.     return m;
  78. }
  79. double Matrix::Arg()//矩阵的行列式
  80. {
  81.     assert(width==height);
  82.     double result=1;
  83.     double k;
  84.     Matrix m=*this;
  85.     for(long i=0;i<height-1;i++){//Gauss消去法,变换成上三角矩阵
  86.         for(long j=i+1;j<height;j++){
  87.             k=m[j][i]/m[i][i];
  88.             m[j][i]=0;
  89.             for(long n=i+1;n<width;n++){
  90.                 m[j][n]=m[j][n]-k*m[i][n];
  91.             }
  92.         }
  93.     }
  94.     for(i=0;i<height;i++){
  95.         for(long j=0;j<width;j++){
  96.             if(i==j) result*=m[i][j];
  97.         }
  98.     }
  99.     return result;
  100. }
  101. bool Matrix::isPtv()
  102. {
  103.     assert(width==height);//是方阵才可以计算
  104.     bool result=true;
  105.     Matrix m;
  106.     for(long i=1;i<=height;i++){
  107.         m=this->subMatrix(i);
  108.         if(m.Arg()<=0){
  109.             result=false;
  110.             break;
  111.         }
  112.     }
  113.     return result;
  114. }
  115. Matrix  Matrix::T()
  116. {
  117.     double * t=new double[width*height];
  118.     for(long i=0;i<height;i++){
  119.         for(long j=0;j<width;j++){
  120.             *(t+height*j+i)=*(p+width*i+j);
  121.         }
  122.     }
  123.     Matrix m(t,height,width);
  124.     delete [] t;
  125.     return m;
  126. }
  127. Matrix Matrix::operator +(Matrix &m1)
  128. {
  129.     assert(m1.height==height && m1.width==width);
  130.     long tmpHeight=m1.height;
  131.     long tmpWidth=m1.width;
  132.     double * t=new double[tmpWidth*tmpHeight];
  133.     for(long i=0;i<tmpHeight;i++){
  134.         for(long j=0;j<tmpWidth;j++){
  135.             *(t+tmpWidth*i+j)=*(m1.p+tmpWidth*i+j)+*(p+tmpWidth*i+j);
  136.         }
  137.     }
  138.     Matrix m(t,tmpWidth,tmpHeight);
  139.     delete [] t;
  140.     return m;
  141. }
  142. Matrix Matrix::operator -(Matrix &m1)
  143. {
  144.     assert(m1.height==height && m1.width==width);
  145.     long tmpHeight=m1.height;
  146.     long tmpWidth=m1.width;
  147.     double * t=new double[tmpWidth*tmpHeight];
  148.     for(long i=0;i<tmpHeight;i++){
  149.         for(long j=0;j<tmpWidth;j++){
  150.             *(t+tmpWidth*i+j)=*(p+tmpWidth*i+j)-*(m1.p+tmpWidth*i+j);
  151.         }
  152.     }
  153.     Matrix m(t,tmpWidth,tmpHeight);
  154.     delete [] t;
  155.     return m;
  156. }
  157. Matrix Matrix::operator *(Matrix &m1)
  158. {
  159.     if(!this->isVector() && m1.isVector()){//左为数,右为矩阵
  160.         Matrix m;
  161.         m=p[0]*m1;
  162.         return m;
  163.     }else if(this->isVector() && !m1.isVector()){//左为矩阵,右为数
  164.         Matrix m;
  165.         m=*this*m1[0][0];
  166.         return m;
  167.     }else if(!this->isVector() && m1.isVector()){//左右都为数
  168.         double * t=new double[1];
  169.         t[0]=p[0]*m1[0][0];
  170.         Matrix m(t,1,1);
  171.         delete [] t;
  172.         return m;
  173.     }else if(this->isVector() && m1.isVector() && width==m1.height){//左为矩阵,右为矩阵
  174.         double sum;
  175.         double * t=new double[height*m1.width];
  176.         for(long i=0;i<height;i++){
  177.             for(long j=0;j<m1.width;j++){
  178.                 sum=0;
  179.                 for(long k=0;k<width;k++){
  180.                     sum+=(*(p+width*i+k))*(m1[k][j]);
  181.                 }
  182.                 *(t+m1.width*i+j)=sum;
  183.             }
  184.         }
  185.         Matrix m(t,m1.width,height);
  186.         delete [] t;
  187.         return m;
  188.     }else{
  189.         assert(0);//未知运算
  190.         return *this;
  191.     }
  192. }
  193. Matrix operator*(double alpha,Matrix & m1)
  194. {
  195.     Matrix m=m1;
  196.     for(long i=0;i<m.height;i++){
  197.         for(long j=0;j<m.width;j++){
  198.             m[i][j]=alpha*m1[i][j];
  199.         }
  200.     }
  201.     return m;
  202. }
  203. Matrix Matrix::operator*(double alpha)
  204. {
  205.     return alpha*(*this);
  206. }
  207. Matrix Matrix::operator+=(Matrix & m)
  208. {
  209.     return *this+m;
  210. }
  211. Matrix Matrix::operator-=(Matrix & m)
  212. {
  213.     return *this-m;
  214. }
  215. Matrix Matrix::operator *=(double alpha)
  216. {
  217.     return *this*alpha;
  218. }
  219. Matrix sqrt(Matrix m)
  220. {
  221.     m[0][0]=sqrt(m[0][0]);
  222.     return m;
  223. }
  224. double abs(Matrix & m)
  225. {
  226.     double sum=0;
  227.     for(long i=0;i<m.height;i++){
  228.         for(long j=0;j<m.width;j++){
  229.             sum+=m[i][j]*m[i][j];
  230.         }
  231.     }
  232.     return sqrt(sum);
  233. }
  234. Matrix Matrix::operator /(Matrix &m1)
  235. {
  236.     assert(m1.width==1 && m1.height==1);
  237.     return *this/m1[0][0];
  238. }
  239. Matrix Matrix::operator /(double sub)
  240. {
  241.     Matrix m=*this;
  242.     for(long i=0;i<height;i++){
  243.         for(long j=0;j<width;j++){
  244.             m[i][j]=*(p+width*i+j)/sub;
  245.         }
  246.     }
  247.     return m;
  248. }
  249. Matrix & Matrix::operator =(Matrix & m)
  250. {
  251.     if(&m==thisreturn *this;
  252.     height=m.height;
  253.     width=m.width;
  254.     delete [] p;
  255.     p=new double[height*width];
  256.     for(long i=0;i<height;i++){
  257.         for(long j=0;j<width;j++){
  258.             *(p+width*i+j)=*(m.p+width*i+j);
  259.         }
  260.     }
  261.     return *this;
  262. }
  263. double * Matrix::operator [](long heightPos)
  264. {
  265.     assert(heightPos>=0 && heightPos<height);
  266.     return p+width*heightPos;
  267. }
  268. ostream & operator<<(ostream & os,Matrix & m)
  269. {
  270.     os<<"Matrix:height="<<m.height<<endl;
  271.     os<<"Matrix:width="<<m.width<<endl;
  272.     for(long i=0;i<m.height;i++){
  273.         for(long j=0;j<m.width;j++){
  274.             os<<m[i][j]<<" "
  275.         } 
  276.         os<<endl;
  277.     }
  278.     return os;
  279. }
  280. Matrix::~Matrix(void)
  281. {
  282.     delete [] p;
  283. }
  284. void Matrix::Test(){
  285.     double arr[4][4]={{1,1,1,1},{1,2,3,4},{1,3,6,10},{1,4,10,20}};
  286.     Matrix m1,m(&arr[0][0],4,4),m2(&arr[0][0],4,4);
  287.     m.isPtv();
  288.     /*            
  289.     cout<<"arranger="<<m.Arg()<<endl;
  290.     cout<<m;*/
  291. }
  292. void main()
  293. {
  294.     Matrix obj;
  295.     obj.Test();
  296. }

我们可以从文件中发现Matrix常用的功能,比如SubMatrix()、乘法等等。另外,将Matrix的测试过程,包含在Matrix类本身——我觉得这种方式类似于“白盒”测试;如果包装成对象再测试,那就是“黑盒”:)