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