C++类写的矩阵计算

类别:编程语言 点击:0 评论:0 推荐:

#pragma once

//矩阵类
class Matrix
{
private:
 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*****************/
};
#include "StdAfx.h"
#include ".\matrix.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(long 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;*/
}

本文地址:http://com.8s8s.com/it/it26320.htm