⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mat.cpp

📁 随机搜索法,用于大型复杂优化问题.该方法只支持变量的范围约束,不支持其它类型的约束.
💻 CPP
字号:
// Mat.cpp: implementation of the Mat class.
// 矩阵运算 2006年1月由本人编制,如有任何问题,请联系xiaofc4395@sina.com
// 所有涉及矩阵运算的首先必须初始化,即要调用 zero函数
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RanMethod.h"
#include "mat.h"
#include "math.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

mat::mat()
{
	row=1;
	col=1;
	p=NULL;
}

mat::~mat()
{
	Freethis();
}

void mat::Freethis()
{
	if (p)
	{
		delete[] p;
		p = NULL;
	}
}

mat::mat(const mat& other)
{
	p=NULL;
	row = other.row;
	col = other.col;
	zero(row,col);
	memcpy(p, other.p, sizeof(double)*row*col);
}

mat::mat(int m,int n,double a[])
{
	Freethis();
	row=int(fabs(m));	col=int(fabs(n));
	int nSize = row*col;
	ASSERT(nSize!=0);
	p = new double[nSize];
	ASSERT(p != NULL);				        	  // 内存分配失败
	BOOL bad=true;
	if (IsBadReadPtr(p, sizeof(double) * nSize)) bad=false;
	ASSERT(bad);
	for (int i=0;i<nSize;i++)
	{
		p[i]=a[i];
	}
}

void mat::zero(int m, int n)
{
	Freethis();
	row=int(fabs(m));	col=int(fabs(n));
	int nSize = row*col;
	ASSERT(nSize!=0);	
	p = new double[nSize];	
	ASSERT(p != NULL);
	BOOL bad=true;
	if (IsBadReadPtr(p, sizeof(double) * nSize)) bad=false;
	ASSERT(bad);
	memset(p,0, sizeof(double) * nSize);   // 将各元素值置0
}

//------------显示某个元素-------------
double mat::r(int nRow, int nCol) const
{
	if (nCol <=0 || nCol > col || nRow <= 0 || nRow > row)
		return 0.0;
	if (p != NULL)
		return p[ (nCol-1) +(nRow-1)* col];
	else
		return 0.0;
}

//------------设置某个元素-------------
void mat::set(int nRow, int nCol, double value)
{
	BOOL a1=true;
	if (nCol <= 0 || nCol > col || nRow <= 0 || nRow > row) 
		a1=false;
	ASSERT(a1);
	if (p == NULL) 
		ASSERT(false);	
	p[(nCol-1) +(nRow-1)* col] = value;
}

//------------设置某个元素-------------
void mat::set(int nRow, int nCol, int value1)
{
	double value=double(value1);
	set(nRow, nCol,value);
}

//------------显示某一行-------------
mat mat::cpr(int m)  const
{
	BOOL a1=true;
	if( (m <= 0) || (m > row) ) a1=false;
	ASSERT(a1);
	if (p == NULL) ASSERT(false);
	mat out;out.zero(1,col);
	for (int i=1;i<=col;i++)
	{
		out.set(1,i,this->r(m,i));
	}
	return out;
}

//------------显示某一列-------------
mat mat::cpc(int n) const
{
	BOOL a1=true;
	if( (n <= 0) && ( n> col) )  a1=false;
	ASSERT(a1);
	if (p == NULL) 
		ASSERT(false);
	mat out;out.zero(row,1);
	for (int i=1;i<=row;i++)
	{
		out.set(i,1,this->r(i,n));
	}
	return out;
}

//------从第m列开始,显示从m-n列之间的数据---
mat mat::cpc(int m,int n) const
{
	ASSERT( (m>0 ) && ( m <=n) );
	ASSERT( (n>=m) && ( n <=col) );
	mat out;out.zero(row,n-m+1);
	for (int i=1;i<=(n-m+1);i++)
	{
		mat temp=cpc(i+m-1);
		out.setc(i,temp);
	}
	return out;
}

//--从k列开始显示一个m*n的矩阵
mat mat::cpc(int k,int m,int n) const
{
	ASSERT( (k>0 ) && ( k<=col));
	ASSERT( (m<=row ) && ((k+n-1)<=col));
	mat out;out.zero(m,n);
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			out.set(i,j,r(i,j+k-1));
		}
	}
	return out;
}

//--从k行开始显示一个m*n的矩阵
mat mat::cpr(int k,int m,int n) const
{
	ASSERT( (k>0 ) && ( k<=row));
	ASSERT( (n>0 ) && ( n<=col));
	ASSERT( (k<=row ) && ((k+m-1)<=row));
	mat out;out.zero(m,n);
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			out.set(i,j,r(i+k-1,j));
		}
	}
	return out;
}

//--从k行,j列开始显示一个m*n的矩阵
mat mat::cprc(int k,int j, int m,int n) const
{
	ASSERT( (k>0 ) && ( k<=row));
	ASSERT( (m>0 ) && ( m<=row));
	ASSERT( (j>0 ) && ( j<=col));
	ASSERT( (n>0 ) && ( n<=col));
	ASSERT( (k<=row ) && ((k+m-1)<=row));
	ASSERT( (j<=row ) && ((j+n-1)<=col));
	mat out;out.zero(m,n);
	for(int i=1;i<=m;i++)
	{
		for(int rrr=1;rrr<=n;rrr++)
		{
			out.set(i,rrr,r(i+k-1,rrr+j-1));
		}
	}
	return out;
}

//------------设置某行元素-------------
void mat::setr(int nRow,const mat& b)
{
	BOOL a1=true;
	if (nRow <= 0 || nRow > row) a1=false;
	ASSERT(a1);
	if (p == NULL) ASSERT(false);
	for (int i=1;i<=col;i++)
	{
		set(nRow,i,b.r(1,i));
	}
}

//------------设置某列元素-------------
void mat::setc(int m,const mat& b)
{
	BOOL a1=true;
	if ((m <=0 || m > col)) a1=false;
	ASSERT(a1);
	if (p == NULL) ASSERT(false);
	for (int i=1;i<=row;i++)
	{
		set(i,m,b.r(i,1));
	}
}

//----从第k列开始,设置一个m*n的矩阵
void mat::setm(int k,const mat& b)
{
	int m=b.row;
	int n=b.col;
	ASSERT( k>0);
	ASSERT( (k+n-1)<=col);
	mat pre,after,out;
	if (k==1)
	{
		after=cpc(n+1,col);
		out=b/=after;
	}
	else
	{
		if (k+n<=col)
		{
			pre=cpc(1,k-1);
			after=cpc(k+n,col);
			out=pre/=b/=after;
		}
		else
		{
			pre=cpc(1,k-1);
			out=pre/=b;
		}
	}
	zero(out.row,out.col);
	memcpy(p, out.p, sizeof(double)*row*col);
}

//-------------转置-------------------
mat mat::T() const
{
	mat out; out.zero(col,row);
	for (int i=1;i<=col;i++)
	{
		for (int j=1;j<=row;j++)
		{
			out.set(i,j,this->r(j,i));			
		}
	}
	return out;
}

//-------------单位阵----------------
void mat::eyemat(int n)
{
	zero(n,n);
	for (int i=1;i<=n;i++)
	{ 
		for (int j=1;j<=n;j++)
		{
			if (i==j)
				set(i,j,1.0);				
			else
				set(i,j,0.0);
		}
	}
}

//-------------付值----------------
mat& mat::operator=(const mat& other)
{
	if(other.p !=NULL)
	{
		if (&other != this)
		{
			zero(other.row,other.col);
			memcpy(p, other.p, sizeof(double)*row*col);
		}
	}
	return *this;
}

//-------------乘一个实数----------------
mat mat::operator*(double value) const
{
	mat	result(*this) ;	
	for (int i = 1 ; i <= row ; ++i)
	{
		for (int j = 1 ; j <= col; ++j)
			 result.set(i,j,result.r(i,j)*value);
	}
	return result ;
}

//-------------乘一个整数----------------
mat mat::operator*(int value) const
{
	mat	result(*this) ;	
	for (int i = 1 ; i <= row ; i++)
	{
		for (int j = 1 ; j <= col; j++)
			 result.set(i,j,result.r(i,j)*value);
	}
	return result ;
}

//-------------矩阵乘----------------
mat	mat::operator*(const mat& other) const
{
	// 首先检查行列数是否符合要求
	ASSERT (col == other.row);
	mat result;result.zero(row,other.col);
	double	value ;
	for (int i = 1 ; i <=row ; i++)
	{
		for (int j = 1 ; j <= other.col ; j++)
		{
			value = 0.0 ;
			for (int k = 1 ; k <= col ; k++)
			{
				value += this->r(i, k) * other.r(k, j);
			}
			result.set(i,j,value) ;
		}
	}
	return result ;
}

//-------------矩阵+----------------
mat	mat::operator+(const mat& other) const
{
	ASSERT (row == other.row && col == other.col); // 首先检查行列数是否相等
	mat	result;result.zero(row,col);
	for (int i = 1; i <= row ; i++)
	{
		for (int j = 1; j <= col; j++)
		{
			result.set(i,j,r(i,j)+other.r(i,j));
		}
	}
	return result ;
}

//-------------矩阵-  ----------------
mat	mat::operator-(const mat& other) const
{
	ASSERT (row == other.row && col == other.col); // 首先检查行列数是否相等
	mat	result;result.zero(row,col);
	for (int i = 1 ; i <= row ; ++i)
	{
		for (int j = 1 ; j <= col; ++j)
			result.set(i,j,r(i,j)-other.r(i,j));
	}
	return result;
}

//-------------矩阵/----------------
mat mat::operator/(double a) const
{
	mat	result;result.zero(row,col);	
	for (int i = 1 ; i <= row ; ++i)
	{
		for (int j = 1 ; j <= col; ++j)
			 result.set(i,j,this->r(i,j)/a);
	}
	return result ;
}

//-------------矩阵/----------------
mat mat::operator/(int a) const
{
	mat	result;result.zero(row,col);
	for (int i = 1 ; i <= row ; ++i)
	{
		for (int j = 1 ; j <= col; ++j)
			 result.set(i,j,this->r(i,j)/a);
	}
	return result ;
}

//----------------矢量除-----------------
mat mat::operator/(const mat& other) const
{
	mat out;
	int m=other.row;
	int n=other.col;
	BOOL a1=true;
	if (m !=n) 	
	{
		a1=false;
		ASSERT(a1);
	}
	else
	{
		mat thismat;thismat.zero(row,col);
		for (int i=1;i<=row;i++)
		{
			for (int j=1;j<=col;j++)
			{
				thismat.set(i,j,r(i,j));
			}
		}
		mat inva=other.invmat();
		out=thismat*inva;
	}
	return out;
}

//-----------------------矢量差乘------------------
mat mat::operator^(const mat& c) const
{
	mat out;	
	int m=c.row;
	int n=c.col;
	BOOL a1;
	if ( (m == row ) && ( n == col)  && (m*n == 3) )
	{
		a1=true;
		if (m =3)
		{
			out.zero(3,1);
			out.set(1,1,r(2,1)*c.r(3,1)-r(3,1)*c.r(2,1));
			out.set(2,1,r(3,1)*c.r(1,1)-r(1,1)*c.r(3,1));
			out.set(3,1,r(1,1)*c.r(2,1)-r(2,1)*c.r(1,1));
		}
		else
		{
			out.zero(1,3);
			out.set(1,1,r(1,2)*c.r(1,3)-r(1,3)*c.r(1,2));
			out.set(2,1,r(1,3)*c.r(1,1)-r(1,1)*c.r(1,3));
			out.set(3,1,r(1,1)*c.r(1,2)-r(1,2)*c.r(1,1));
		}
	}
	else
	{
		a1=false;
		ASSERT(a1);
	}
	return out;
}

//---------------矢量点乘--------------------
double mat::operator|(const mat& a) const
{
	//无论是矩阵还是向量,只对第一列有效/列
	double out=0.0;
	int m=a.row;
	int n=a.col;
	if (( m==row ) && (n ==col) )
	{
		double temp=0.0;
		if (m==1)
		{
			for (int i=1;i<=n;i++)
			{
				temp+=a.r(1,i)*r(1,i);
			}
			out=temp;
		}
		else
		{
			if (n==1)
			{
				for (int i=1;i<=m;i++)
				{
					temp+=a.r(i,1)*r(i,1);
				}
				out=temp;
			}	
		}
	}
	return out;
}

//--------------- 2范数 -----------------------
double mat::normmat() const
{
	double out=0.0;
	int m=row;
	int n=col;
	BOOL a1=true;
	if ((m !=1) && (n !=1)) a1=false; 
	ASSERT(a1);
	if (m==1)
	{
		double temp=0.0;
		for (int i=1;i<=n;i++)
		{
			temp+=r(1,i)*r(1,i);
		}
		out=sqrt(temp);
	}
	else
	{
		if (n==1)
		{
			double temp=0.0;
			for (int i=1;i<=m;i++)
			{
				temp+=r(i,1)*r(i,1);
			}
			out=sqrt(temp);
		}
	}
	return out;
}


//---------------伴随阵-------------------------
mat mat::adj() const
{
	mat out;out.zero(row,col);
	for(int i=1;i<=row;i++)
	{
		for(int j=1;j<=col;j++)
		{
			if (((i+j)%2)!=0)
			{
				out.set(i,j,(-1.0)*(sub_mat(i,j).detmat()));
			}
			else
			{
				out.set(i,j,       (sub_mat(i,j).detmat()));
			}
		}
	}
	mat reuslt=out.T();
	return reuslt;
}

//---------------行列式的值-----------------------
double mat::detmat() const
{
	double out=0.0;
	BOOL a1=true;
	if ( row !=col) 
		a1=false; 
	ASSERT(a1);

	if ( (col==1) &&(row==1) )
	{
		out=r(1,1);
	}
	else
	{
		if ((col==2)&&(row==2))
		{
			out=r(1,1)*r(2,2)-r(1,2)*r(2,1);
		}
		else
		{
			int i=1;
			for(int j=1;j<=col;j++)
			{
				if ( ((i+j)%2 )!=0)
				{
					out+=(-1.0)*sub_mat(i,j).detmat()*r(i,j);
				}
				else
				{
					out+=       sub_mat(i,j).detmat()*r(i,j);
				}
			}
		}
	}
	return out;
}

//--------------------余子式------------------------
mat mat::sub_mat(int rr,int cc) const
{
	mat out;out.zero(row-1,col-1);
	int m=out.row;
	int n=out.col;
	for (int i=1;i<=m;i++)
	{
		for (int j=1;j<=n;j++)
		{
			if ( i< rr)
			{
				if ( j< cc)
				{
					out.set(i,j,r(i,j));
				}
				else
				{
					out.set(i,j,r(i,j+1));
				}
			}
			else
			{
				if (i>=rr)
				{
					if ( j< cc)
					{
						out.set(i,j,r(i+1,j));
					}
					else
					{
						out.set(i,j,r(i+1,j+1));
					}
				}
			}
		}
	}
	return out;
}

//--------------------逆矩阵--------------------------------
mat mat::invmat() const
{
	mat out;out.zero(row,col);

	BOOL a1=true;
	if (col!=row)
	{
		a1=false; 
		ASSERT(a1);
	}
	else
	{
		double d=this->detmat();
		if (d !=0.0)
		{
			double d1=1/d;
			mat rusult=adj();
			int m=rusult.row;
			int n=rusult.col;
			for (int i=1;i<=m;i++)
			{
				for (int j=1;j<=n;j++)
				{
					out.set(i,j,rusult.r(i,j)*d1);			
				}
			}
		}
	}
	return out;
}

//------2个线性空间的结合(return this)----------------
void mat::operator||(mat a)
{	
	int m1=a.row;	int n1=a.col;
	int m=row;      int n=col;
	BOOL a1=true;
	if (m1 != m)
	{
		a1=false;
		ASSERT(a1);
	}
	else
	{
		mat temp;temp.zero(m,n);
		for (int i=1;i<=m;i++)
		{
			for (int j=1;j<=n;j++)
			{
				temp.set(i,j,r(i,j));
			}
		}
		zero(m1,n+n1);		
		for (int ii=1;ii<=row;ii++)
		{
			for (int jj=1;jj<=col;jj++)
			{
				if (jj<=n)
					this->set(ii,jj,temp.r(ii,jj));
				else
					this->set(ii,jj,a.r(ii,jj-n));
			}
		}
	} 
}

//------2个线性空间的结合(return ohers)----------------
mat mat::operator|=(const mat& a) const
{
	mat out;out.zero(row,col);
	memcpy(out.p, p, sizeof(double)*row*col);
	out||a;
	return out;
}

//------2个线性行与列均不相同空间的结合(return ohers)----------------
mat mat::operator /=(const mat& a) const
{
	int m1=a.row,n=a.col;
	int m;
	if (m1> row)
		m=m1;
	else
		m=row;
	mat out;out.zero(m,col+n);
	for (int i=1;i<=out.row;i++)
	{
		for (int j=1;j<=out.col;j++)
		{
			if (j<=col)
				out.set(i,j,r(i,j));
			else
				out.set(i,j,a.r(i,j-col));
		}
	}
	return out;
}

//------行向量与一个实数的结合----------------
void mat::operator||(double a)
{
	int m=row;      int n=col;
	ASSERT(m < 1.5);
	mat temp;temp.zero(1,n);
	for (int j=1;j<=n;j++)
	{
		temp.set(1,j,r(1,j));
	}
	zero(m,n+1);
	for (int jj=1;jj<=col;jj++)
	{
		if (jj<=n)
			this->set(1,jj,temp.r(1,jj));
		else
			this->set(1,jj,a);
	} 
}


int mat::length()
{
	return col*row;
}


mat mat::Delc(int n) const
{
	ASSERT( 1<=n  && n<=col);
	mat out;
	if(col==1)
	{
		out.zero(row,1);
	}
	else
	{
		out.zero(row,col-1);
		for (int i=1;i<=row;i++)
		{
			for (int j=1;j<=col-1;j++)
			{
				if (j < n)
					out.set(i,j,r(i,j));
				else
					out.set(i,j,r(i,j+1));
			}
		}		
	}
	return out;
}

mat mat::Delr(int n) const
{
	mat out;out.zero(row-1,col);
	if ( n <= row)
	{
		for (int j=1;j<=col;j++)
		{
			for (int i=1;i<=row-1;i++)
			{
				if (i < n)
					out.set(i,j,r(i,j));
				else
					out.set(i,j,r(i+1,j));
			}
		}		
	}
	return out;
}

void mat::setmat(int m, int n, double a[])
{
	Freethis();
	row=m;	col=n;
	int nSize = row*col;
	ASSERT (nSize > 0);
	p = new double[nSize];	
	if (p == NULL)
		exit(0);				        	// 内存分配失败
	if (IsBadReadPtr(p, sizeof(double) * nSize))
		exit(0);
	for (int i=0;i<nSize;i++)
	{
		p[i]=a[i];
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -