www.pudn.com > 科学与工程数值计算算法配套源码vc++.zip > Matrix.cpp


////////////////////////////////////////////////////////////////////// 
// Matrix.cpp 
// 
// 操作矩阵的类 CMatrix 的实现文件 
// 
// 周长发编制, 2002/8 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Matrix.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
////////////////////////////////////////////////////////////////////// 
// 基本构造函数 
////////////////////////////////////////////////////////////////////// 
CMatrix::CMatrix() 
{ 
	m_nNumColumns = 1; 
	m_nNumRows = 1; 
	m_pData = NULL; 
	BOOL bSuccess = Init(m_nNumRows, m_nNumColumns); 
	ASSERT(bSuccess); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 指定行列构造函数 
// 
// 参数: 
// 1. int nRows - 指定的矩阵行数 
// 2. int nCols - 指定的矩阵列数 
////////////////////////////////////////////////////////////////////// 
CMatrix::CMatrix(int nRows, int nCols) 
{ 
	m_nNumRows = nRows; 
	m_nNumColumns = nCols; 
	m_pData = NULL; 
	BOOL bSuccess = Init(m_nNumRows, m_nNumColumns); 
	ASSERT(bSuccess); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 指定值构造函数 
// 
// 参数: 
// 1. int nRows - 指定的矩阵行数 
// 2. int nCols - 指定的矩阵列数 
// 3. double value[] - 一维数组,长度为nRows*nCols,存储矩阵各元素的值 
////////////////////////////////////////////////////////////////////// 
CMatrix::CMatrix(int nRows, int nCols, double value[]) 
{ 
	m_nNumRows = nRows; 
	m_nNumColumns = nCols; 
	m_pData = NULL; 
	BOOL bSuccess = Init(m_nNumRows, m_nNumColumns); 
	ASSERT(bSuccess); 
 
	SetData(value); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 方阵构造函数 
// 
// 参数: 
// 1. int nSize - 方阵行列数 
////////////////////////////////////////////////////////////////////// 
CMatrix::CMatrix(int nSize) 
{ 
	m_nNumRows = nSize; 
	m_nNumColumns = nSize; 
	m_pData = NULL; 
	BOOL bSuccess = Init(nSize, nSize); 
	ASSERT (bSuccess); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 方阵构造函数 
// 
// 参数: 
// 1. int nSize - 方阵行列数 
// 2. double value[] - 一维数组,长度为nRows*nRows,存储方阵各元素的值 
////////////////////////////////////////////////////////////////////// 
CMatrix::CMatrix(int nSize, double value[]) 
{ 
	m_nNumRows = nSize; 
	m_nNumColumns = nSize; 
	m_pData = NULL; 
	BOOL bSuccess = Init(nSize, nSize); 
	ASSERT (bSuccess); 
 
	SetData(value); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 拷贝构造函数 
// 
// 参数: 
// 1. const CMatrix& other - 源矩阵 
////////////////////////////////////////////////////////////////////// 
CMatrix::CMatrix(const CMatrix& other) 
{ 
	m_nNumColumns = other.GetNumColumns(); 
	m_nNumRows = other.GetNumRows(); 
	m_pData = NULL; 
	BOOL bSuccess = Init(m_nNumRows, m_nNumColumns); 
	ASSERT(bSuccess); 
 
	// copy the pointer 
	memcpy(m_pData, other.m_pData, sizeof(double)*m_nNumColumns*m_nNumRows); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 析构函数 
////////////////////////////////////////////////////////////////////// 
CMatrix::~CMatrix() 
{ 
	if (m_pData) 
	{ 
		delete[] m_pData; 
		m_pData = NULL; 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// 初始化函数 
// 
// 参数: 
// 1. int nRows - 指定的矩阵行数 
// 2. int nCols - 指定的矩阵列数 
// 
// 返回值:BOOL 型,初始化是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::Init(int nRows, int nCols) 
{ 
	if (m_pData) 
	{ 
		delete[] m_pData; 
		m_pData = NULL; 
	} 
 
	m_nNumRows = nRows; 
	m_nNumColumns = nCols; 
	int nSize = nCols*nRows; 
	if (nSize < 0) 
		return FALSE; 
 
	// 分配内存 
	m_pData = new double[nSize]; 
	 
	if (m_pData == NULL) 
		return FALSE;					// 内存分配失败 
	if (IsBadReadPtr(m_pData, sizeof(double) * nSize)) 
		return FALSE; 
 
	// 将各元素值置0 
	memset(m_pData, 0, sizeof(double) * nSize); 
 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 将方阵初始化为单位矩阵 
// 
// 参数: 
// 1. int nSize - 方阵行列数 
// 
// 返回值:BOOL 型,初始化是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::MakeUnitMatrix(int nSize) 
{ 
	if (! Init(nSize, nSize)) 
		return FALSE; 
 
	for (int i=0; i= m_nNumRows) 
		return s; 
 
	for (int j=0; j= m_nNumColumns) 
		return s; 
 
	for (int i=0; i= m_nNumColumns || nRow < 0 || nRow >= m_nNumRows) 
		return FALSE;						// array bounds error 
	if (m_pData == NULL) 
		return FALSE;							// bad pointer error 
	 
	m_pData[nCol + nRow * m_nNumColumns] = value; 
 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 设置指定元素的值 
// 
// 参数: 
// 1. int nRows - 指定的矩阵行数 
// 2. int nCols - 指定的矩阵列数 
// 
// 返回值:double 型,指定元素的值 
////////////////////////////////////////////////////////////////////// 
double CMatrix::GetElement(int nRow, int nCol) const 
{ 
	ASSERT(nCol >= 0 && nCol < m_nNumColumns && nRow >= 0 && nRow < m_nNumRows); // array bounds error 
	ASSERT(m_pData);							// bad pointer error 
	return m_pData[nCol + nRow * m_nNumColumns] ; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 获取矩阵的列数 
// 
// 参数:无 
// 
// 返回值:int 型,矩阵的列数 
////////////////////////////////////////////////////////////////////// 
int	CMatrix::GetNumColumns() const 
{ 
	return m_nNumColumns; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 获取矩阵的行数 
// 
// 参数:无 
// 
// 返回值:int 型,矩阵的行数 
////////////////////////////////////////////////////////////////////// 
int	CMatrix::GetNumRows() const 
{ 
	return m_nNumRows; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 获取矩阵的数据 
// 
// 参数:无 
// 
// 返回值:double型指针,指向矩阵各元素的数据缓冲区 
////////////////////////////////////////////////////////////////////// 
double* CMatrix::GetData() const 
{ 
	return m_pData; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 获取指定行的向量 
// 
// 参数: 
// 1. int nRows - 指定的矩阵行数 
// 2.  double* pVector - 指向向量中各元素的缓冲区 
// 
// 返回值:int 型,向量中元素的个数,即矩阵的列数 
////////////////////////////////////////////////////////////////////// 
int CMatrix::GetRowVector(int nRow, double* pVector) const 
{ 
	if (pVector == NULL) 
		delete pVector; 
 
	pVector = new double[m_nNumColumns]; 
	ASSERT(pVector != NULL); 
 
	for (int j=0; jd)  
				{  
					d=p;  
					pnRow[k]=i;  
					pnCol[k]=j; 
				} 
			} 
		} 
         
		// 失败 
		if (d == 0.0) 
		{ 
			delete[] pnRow; 
			delete[] pnCol; 
			return FALSE; 
		} 
 
        if (pnRow[k] != k) 
		{ 
			for (j=0; j<=m_nNumColumns-1; j++) 
			{  
				u=k*m_nNumColumns+j;  
				v=pnRow[k]*m_nNumColumns+j; 
				p=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=p; 
			} 
		} 
         
		if (pnCol[k] != k) 
		{ 
			for (i=0; i<=m_nNumColumns-1; i++) 
            {  
				u=i*m_nNumColumns+k;  
				v=i*m_nNumColumns+pnCol[k]; 
				p=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=p; 
            } 
		} 
 
        l=k*m_nNumColumns+k; 
        m_pData[l]=1.0/m_pData[l]; 
        for (j=0; j<=m_nNumColumns-1; j++) 
		{ 
			if (j != k) 
            {  
				u=k*m_nNumColumns+j;  
				m_pData[u]=m_pData[u]*m_pData[l]; 
			} 
		} 
 
        for (i=0; i<=m_nNumColumns-1; i++) 
		{ 
			if (i!=k) 
			{ 
				for (j=0; j<=m_nNumColumns-1; j++) 
				{ 
					if (j!=k) 
					{  
						u=i*m_nNumColumns+j; 
						m_pData[u]=m_pData[u]-m_pData[i*m_nNumColumns+k]*m_pData[k*m_nNumColumns+j]; 
					} 
                } 
			} 
		} 
 
        for (i=0; i<=m_nNumColumns-1; i++) 
		{ 
			if (i!=k) 
            {  
				u=i*m_nNumColumns+k;  
				m_pData[u]=-m_pData[u]*m_pData[l]; 
			} 
		} 
    } 
 
    // 调整恢复行列次序 
    for (k=m_nNumColumns-1; k>=0; k--) 
    {  
		if (pnCol[k]!=k) 
		{ 
			for (j=0; j<=m_nNumColumns-1; j++) 
            {  
				u=k*m_nNumColumns+j;  
				v=pnCol[k]*m_nNumColumns+j; 
				p=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=p; 
            } 
		} 
 
        if (pnRow[k]!=k) 
		{ 
			for (i=0; i<=m_nNumColumns-1; i++) 
            {  
				u=i*m_nNumColumns+k;  
				v=i*m_nNumColumns+pnRow[k]; 
				p=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=p; 
            } 
		} 
    } 
 
	// 清理内存 
	delete[] pnRow; 
	delete[] pnCol; 
 
	// 成功返回 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 复矩阵求逆的全选主元高斯-约当法 
// 
// 参数: 
// 1. CMatrix& mtxImag - 复矩阵的虚部矩阵,当前矩阵为复矩阵的实部 
// 
// 返回值:BOOL型,求逆是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::InvertGaussJordan(CMatrix& mtxImag) 
{ 
	int *pnRow,*pnCol,i,j,k,l,u,v,w; 
    double p,q,s,t,d,b; 
 
	// 分配内存 
    pnRow = new int[m_nNumColumns]; 
    pnCol = new int[m_nNumColumns]; 
	if (pnRow == NULL || pnCol == NULL) 
		return FALSE; 
 
	// 消元 
    for (k=0; k<=m_nNumColumns-1; k++) 
    {  
		d=0.0; 
        for (i=k; i<=m_nNumColumns-1; i++) 
		{ 
			for (j=k; j<=m_nNumColumns-1; j++) 
			{  
				u=i*m_nNumColumns+j; 
				p=m_pData[u]*m_pData[u]+mtxImag.m_pData[u]*mtxImag.m_pData[u]; 
				if (p>d)  
				{  
					d=p;  
					pnRow[k]=i;  
					pnCol[k]=j; 
				} 
			} 
		} 
 
		// 失败 
        if (d == 0.0) 
        {  
			delete[] pnRow; 
			delete[] pnCol; 
            return(0); 
        } 
 
        if (pnRow[k]!=k) 
		{ 
			for (j=0; j<=m_nNumColumns-1; j++) 
            {  
				u=k*m_nNumColumns+j;  
				v=pnRow[k]*m_nNumColumns+j; 
				t=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=t; 
				t=mtxImag.m_pData[u];  
				mtxImag.m_pData[u]=mtxImag.m_pData[v];  
				mtxImag.m_pData[v]=t; 
            } 
		} 
 
        if (pnCol[k]!=k) 
		{ 
			for (i=0; i<=m_nNumColumns-1; i++) 
            {  
				u=i*m_nNumColumns+k;  
				v=i*m_nNumColumns+pnCol[k]; 
				t=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=t; 
				t=mtxImag.m_pData[u];  
				mtxImag.m_pData[u]=mtxImag.m_pData[v];  
				mtxImag.m_pData[v]=t; 
            } 
		} 
 
        l=k*m_nNumColumns+k; 
        m_pData[l]=m_pData[l]/d; mtxImag.m_pData[l]=-mtxImag.m_pData[l]/d; 
        for (j=0; j<=m_nNumColumns-1; j++) 
		{ 
			if (j!=k) 
            {  
				u=k*m_nNumColumns+j; 
				p=m_pData[u]*m_pData[l];  
				q=mtxImag.m_pData[u]*mtxImag.m_pData[l]; 
				s=(m_pData[u]+mtxImag.m_pData[u])*(m_pData[l]+mtxImag.m_pData[l]); 
				m_pData[u]=p-q;  
				mtxImag.m_pData[u]=s-p-q; 
            } 
		} 
 
        for (i=0; i<=m_nNumColumns-1; i++) 
		{ 
			if (i!=k) 
            {  
				v=i*m_nNumColumns+k; 
				for (j=0; j<=m_nNumColumns-1; j++) 
				{ 
					if (j!=k) 
					{  
						u=k*m_nNumColumns+j;   
						w=i*m_nNumColumns+j; 
						p=m_pData[u]*m_pData[v];  
						q=mtxImag.m_pData[u]*mtxImag.m_pData[v]; 
						s=(m_pData[u]+mtxImag.m_pData[u])*(m_pData[v]+mtxImag.m_pData[v]); 
						t=p-q;  
						b=s-p-q; 
						m_pData[w]=m_pData[w]-t; 
						mtxImag.m_pData[w]=mtxImag.m_pData[w]-b; 
					} 
				} 
            } 
		} 
 
        for (i=0; i<=m_nNumColumns-1; i++) 
		{ 
			if (i!=k) 
            {  
				u=i*m_nNumColumns+k; 
				p=m_pData[u]*m_pData[l];  
				q=mtxImag.m_pData[u]*mtxImag.m_pData[l]; 
				s=(m_pData[u]+mtxImag.m_pData[u])*(m_pData[l]+mtxImag.m_pData[l]); 
				m_pData[u]=q-p;  
				mtxImag.m_pData[u]=p+q-s; 
            } 
		} 
    } 
 
    // 调整恢复行列次序 
    for (k=m_nNumColumns-1; k>=0; k--) 
    {  
		if (pnCol[k]!=k) 
		{ 
			for (j=0; j<=m_nNumColumns-1; j++) 
            {  
				u=k*m_nNumColumns+j;  
				v=pnCol[k]*m_nNumColumns+j; 
				t=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=t; 
				t=mtxImag.m_pData[u];  
				mtxImag.m_pData[u]=mtxImag.m_pData[v];  
				mtxImag.m_pData[v]=t; 
            } 
		} 
 
        if (pnRow[k]!=k) 
		{ 
			for (i=0; i<=m_nNumColumns-1; i++) 
            {  
				u=i*m_nNumColumns+k;  
				v=i*m_nNumColumns+pnRow[k]; 
				t=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=t; 
				t=mtxImag.m_pData[u];  
				mtxImag.m_pData[u]=mtxImag.m_pData[v];  
				mtxImag.m_pData[v]=t; 
            } 
		} 
    } 
 
	// 清理内存 
	delete[] pnRow; 
	delete[] pnCol; 
 
	// 成功返回 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 对称正定矩阵的求逆 
// 
// 参数:无 
// 
// 返回值:BOOL型,求逆是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::InvertSsgj() 
{  
	int i, j ,k, m; 
    double w, g, *pTmp; 
 
	// 临时内存 
    pTmp = new double[m_nNumColumns]; 
 
	// 逐列处理 
    for (k=0; k<=m_nNumColumns-1; k++) 
    {  
		w=m_pData[0]; 
        if (w == 0.0) 
        {  
			delete[] pTmp; 
			return FALSE; 
		} 
 
        m=m_nNumColumns-k-1; 
        for (i=1; i<=m_nNumColumns-1; i++) 
        {  
			g=m_pData[i*m_nNumColumns];  
			pTmp[i]=g/w; 
            if (i<=m)  
				pTmp[i]=-pTmp[i]; 
            for (j=1; j<=i; j++) 
              m_pData[(i-1)*m_nNumColumns+j-1]=m_pData[i*m_nNumColumns+j]+g*pTmp[j]; 
        } 
 
        m_pData[m_nNumColumns*m_nNumColumns-1]=1.0/w; 
        for (i=1; i<=m_nNumColumns-1; i++) 
			m_pData[(m_nNumColumns-1)*m_nNumColumns+i-1]=pTmp[i]; 
    } 
 
	// 行列调整 
    for (i=0; i<=m_nNumColumns-2; i++) 
		for (j=i+1; j<=m_nNumColumns-1; j++) 
			m_pData[i*m_nNumColumns+j]=m_pData[j*m_nNumColumns+i]; 
 
	// 临时内存清理 
	delete[] pTmp; 
 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 托伯利兹矩阵求逆的埃兰特方法 
// 
// 参数:无 
// 
// 返回值:BOOL型,求逆是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::InvertTrench() 
{  
	int i,j,k; 
    double a,s,*t,*tt,*c,*r,*p; 
 
	// 上三角元素 
	t = new double[m_nNumColumns]; 
	// 下三角元素 
	tt = new double[m_nNumColumns]; 
 
	// 上、下三角元素赋值 
	for (i=0; iq)  
				{  
					q=d;  
					is=i;  
					js=j; 
				} 
			} 
		} 
 
        if (q == 0.0) 
        {  
			det=0.0;  
			return(det); 
		} 
         
		if (is!=k) 
        {  
			f=-f; 
            for (j=k; j<=m_nNumColumns-1; j++) 
            {  
				u=k*m_nNumColumns+j;  
				v=is*m_nNumColumns+j; 
                d=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=d; 
            } 
        } 
         
		if (js!=k) 
        {  
			f=-f; 
            for (i=k; i<=m_nNumColumns-1; i++) 
            { 
				u=i*m_nNumColumns+js;  
				v=i*m_nNumColumns+k; 
                d=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=d; 
            } 
        } 
 
        l=k*m_nNumColumns+k; 
        det=det*m_pData[l]; 
        for (i=k+1; i<=m_nNumColumns-1; i++) 
        {  
			d=m_pData[i*m_nNumColumns+k]/m_pData[l]; 
            for (j=k+1; j<=m_nNumColumns-1; j++) 
            {  
				u=i*m_nNumColumns+j; 
                m_pData[u]=m_pData[u]-d*m_pData[k*m_nNumColumns+j]; 
            } 
        } 
    } 
     
	// 求值 
	det=f*det*m_pData[m_nNumColumns*m_nNumColumns-1]; 
 
    return(det); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 求矩阵秩的全选主元高斯消去法 
// 
// 参数:无 
// 
// 返回值:int型,矩阵的秩 
////////////////////////////////////////////////////////////////////// 
int CMatrix::RankGauss() 
{  
	int i,j,k,nn,is,js,l,ll,u,v; 
    double q,d; 
     
	// 秩小于等于行列数 
	nn = m_nNumRows; 
    if (m_nNumRows >= m_nNumColumns)  
		nn = m_nNumColumns; 
 
    k=0; 
 
	// 消元求解 
    for (l=0; l<=nn-1; l++) 
    {  
		q=0.0; 
        for (i=l; i<=m_nNumRows-1; i++) 
		{ 
			for (j=l; j<=m_nNumColumns-1; j++) 
			{  
				ll=i*m_nNumColumns+j;  
				d=fabs(m_pData[ll]); 
				if (d>q)  
				{  
					q=d;  
					is=i;  
					js=j; 
				} 
			} 
		} 
 
        if (q == 0.0)  
			return(k); 
 
        k=k+1; 
        if (is!=l) 
        {  
			for (j=l; j<=m_nNumColumns-1; j++) 
            {  
				u=l*m_nNumColumns+j;  
				v=is*m_nNumColumns+j; 
                d=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=d; 
            } 
        } 
        if (js!=l) 
        {  
			for (i=l; i<=m_nNumRows-1; i++) 
            {  
				u=i*m_nNumColumns+js;  
				v=i*m_nNumColumns+l; 
                d=m_pData[u];  
				m_pData[u]=m_pData[v];  
				m_pData[v]=d; 
            } 
        } 
         
		ll=l*m_nNumColumns+l; 
        for (i=l+1; i<=m_nNumColumns-1; i++) 
        {  
			d=m_pData[i*m_nNumColumns+l]/m_pData[ll]; 
            for (j=l+1; j<=m_nNumColumns-1; j++) 
            {  
				u=i*m_nNumColumns+j; 
                m_pData[u]=m_pData[u]-d*m_pData[l*m_nNumColumns+j]; 
            } 
        } 
    } 
     
	return(k); 
} 
 
////////////////////////////////////////////////////////////////////// 
// 对称正定矩阵的乔里斯基分解与行列式的求值 
// 
// 参数: 
// 1. double* dblDet - 返回行列式的值 
// 
// 返回值:BOOL型,求解是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::DetCholesky(double* dblDet) 
{  
	int i,j,k,u,l; 
    double d; 
     
	// 不满足求解要求 
	if (m_pData[0] <= 0.0) 
		return FALSE; 
 
	// 乔里斯基分解 
 
    m_pData[0]=sqrt(m_pData[0]); 
    d=m_pData[0]; 
 
    for (i=1; i<=m_nNumColumns-1; i++) 
    {  
		u=i*m_nNumColumns;  
		m_pData[u]=m_pData[u]/m_pData[0]; 
	} 
     
	for (j=1; j<=m_nNumColumns-1; j++) 
    {  
		l=j*m_nNumColumns+j; 
        for (k=0; k<=j-1; k++) 
        {  
			u=j*m_nNumColumns+k;  
			m_pData[l]=m_pData[l]-m_pData[u]*m_pData[u]; 
		} 
         
		if (m_pData[l] <= 0.0) 
			return FALSE; 
 
        m_pData[l]=sqrt(m_pData[l]); 
        d=d*m_pData[l]; 
         
		for (i=j+1; i<=m_nNumColumns-1; i++) 
        {  
			u=i*m_nNumColumns+j; 
            for (k=0; k<=j-1; k++) 
				m_pData[u]=m_pData[u]-m_pData[i*m_nNumColumns+k]*m_pData[j*m_nNumColumns+k]; 
             
			m_pData[u]=m_pData[u]/m_pData[l]; 
        } 
    } 
     
	// 行列式求值 
	*dblDet=d*d; 
     
	// 下三角矩阵 
    for (i=0; i<=m_nNumColumns-2; i++) 
		for (j=i+1; j<=m_nNumColumns-1; j++) 
			m_pData[i*m_nNumColumns+j]=0.0; 
 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 矩阵的三角分解,分解成功后,原矩阵将成为Q矩阵 
// 
// 参数: 
// 1. CMatrix& mtxL - 返回分解后的L矩阵 
// 2. CMatrix& mtxU - 返回分解后的U矩阵 
// 
// 返回值:BOOL型,求解是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::SplitLU(CMatrix& mtxL, CMatrix& mtxU) 
{  
	int i,j,k,w,v,ll; 
     
	// 初始化结果矩阵 
	if (! mtxL.Init(m_nNumColumns, m_nNumColumns) || 
		! mtxU.Init(m_nNumColumns, m_nNumColumns)) 
		return FALSE; 
 
	for (k=0; k<=m_nNumColumns-2; k++) 
    {  
		ll=k*m_nNumColumns+k; 
		if (m_pData[ll] == 0.0) 
			return FALSE; 
 
        for (i=k+1; i<=m_nNumColumns-1; i++) 
		{  
			w=i*m_nNumColumns+k;  
			m_pData[w]=m_pData[w]/m_pData[ll]; 
		} 
 
        for (i=k+1; i<=m_nNumColumns-1; i++) 
        {  
			w=i*m_nNumColumns+k; 
            for (j=k+1; j<=m_nNumColumns-1; j++) 
            {  
				v=i*m_nNumColumns+j; 
                m_pData[v]=m_pData[v]-m_pData[w]*m_pData[k*m_nNumColumns+j]; 
            } 
        } 
    } 
     
	for (i=0; i<=m_nNumColumns-1; i++) 
    { 
		for (j=0; ju)  
				u=w; 
        } 
         
		alpha=0.0; 
        for (i=k; i<=m_nNumRows-1; i++) 
        {  
			t=m_pData[i*m_nNumColumns+k]/u;  
			alpha=alpha+t*t; 
		} 
 
        if (m_pData[l]>0.0)  
			u=-u; 
 
        alpha=u*sqrt(alpha); 
        if (alpha == 0.0) 
			return FALSE; 
 
        u=sqrt(2.0*alpha*(alpha-m_pData[l])); 
        if ((u+1.0)!=1.0) 
        {  
			m_pData[l]=(m_pData[l]-alpha)/u; 
            for (i=k+1; i<=m_nNumRows-1; i++) 
            {  
				p=i*m_nNumColumns+k;  
				m_pData[p]=m_pData[p]/u; 
			} 
             
			for (j=0; j<=m_nNumRows-1; j++) 
            {  
				t=0.0; 
                for (jj=k; jj<=m_nNumRows-1; jj++) 
					t=t+m_pData[jj*m_nNumColumns+k]*mtxQ.m_pData[jj*m_nNumRows+j]; 
 
                for (i=k; i<=m_nNumRows-1; i++) 
                {  
					p=i*m_nNumRows+j;  
					mtxQ.m_pData[p]=mtxQ.m_pData[p]-2.0*t*m_pData[i*m_nNumColumns+k]; 
				} 
            } 
             
			for (j=k+1; j<=m_nNumColumns-1; j++) 
            {  
				t=0.0; 
                 
				for (jj=k; jj<=m_nNumRows-1; jj++) 
					t=t+m_pData[jj*m_nNumColumns+k]*m_pData[jj*m_nNumColumns+j]; 
                 
				for (i=k; i<=m_nNumRows-1; i++) 
                {  
					p=i*m_nNumColumns+j;  
					m_pData[p]=m_pData[p]-2.0*t*m_pData[i*m_nNumColumns+k]; 
				} 
            } 
             
			m_pData[l]=alpha; 
            for (i=k+1; i<=m_nNumRows-1; i++) 
				m_pData[i*m_nNumColumns+k]=0.0; 
        } 
    } 
     
	// 调整元素 
	for (i=0; i<=m_nNumRows-2; i++) 
	{ 
		for (j=i+1; j<=m_nNumRows-1;j++) 
		{  
			p=i*m_nNumRows+j;  
			l=j*m_nNumRows+i; 
			t=mtxQ.m_pData[p];  
			mtxQ.m_pData[p]=mtxQ.m_pData[l];  
			mtxQ.m_pData[l]=t; 
		} 
	} 
 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 一般实矩阵的奇异值分解,分解成功后,原矩阵对角线元素就是矩阵的奇异值 
// 
// 参数: 
// 1. CMatrix& mtxU - 返回分解后的U矩阵 
// 2. CMatrix& mtxV - 返回分解后的V矩阵 
// 3. double eps - 计算精度,默认值为0.000001 
// 
// 返回值:BOOL型,求解是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::SplitUV(CMatrix& mtxU, CMatrix& mtxV, double eps /*= 0.000001*/) 
{  
	int i,j,k,l,it,ll,kk,ix,iy,mm,nn,iz,m1,ks; 
    double d,dd,t,sm,sm1,em1,sk,ek,b,c,shh,fg[2],cs[2]; 
    double *s,*e,*w; 
 
	int m = m_nNumRows; 
	int n = m_nNumColumns; 
 
	// 初始化U, V矩阵 
	if (! mtxU.Init(m, m) || ! mtxV.Init(n, n)) 
		return FALSE; 
 
	// 临时缓冲区 
	int ka = max(m, n) + 1; 
    s = new double[ka]; 
    e = new double[ka]; 
    w = new double[ka]; 
 
	// 指定迭代次数为60 
    it=60;  
	k=n; 
 
    if (m-1k)  
		ll=l; 
    if (ll>=1) 
    {  
		for (kk=1; kk<=ll; kk++) 
        {  
			if (kk<=k) 
            {  
				d=0.0; 
                for (i=kk; i<=m; i++) 
                {  
					ix=(i-1)*n+kk-1;  
					d=d+m_pData[ix]*m_pData[ix]; 
				} 
 
                s[kk-1]=sqrt(d); 
                if (s[kk-1]!=0.0) 
                {  
					ix=(kk-1)*n+kk-1; 
                    if (m_pData[ix]!=0.0) 
                    {  
						s[kk-1]=fabs(s[kk-1]); 
                        if (m_pData[ix]<0.0)  
							s[kk-1]=-s[kk-1]; 
                    } 
                     
					for (i=kk; i<=m; i++) 
                    {  
						iy=(i-1)*n+kk-1; 
                        m_pData[iy]=m_pData[iy]/s[kk-1]; 
                    } 
                     
					m_pData[ix]=1.0+m_pData[ix]; 
                } 
                 
				s[kk-1]=-s[kk-1]; 
            } 
             
			if (n>=kk+1) 
            {  
				for (j=kk+1; j<=n; j++) 
                {  
					if ((kk<=k)&&(s[kk-1]!=0.0)) 
                    {  
						d=0.0; 
                        for (i=kk; i<=m; i++) 
                        {  
							ix=(i-1)*n+kk-1; 
                            iy=(i-1)*n+j-1; 
                            d=d+m_pData[ix]*m_pData[iy]; 
                        } 
                         
						d=-d/m_pData[(kk-1)*n+kk-1]; 
                        for (i=kk; i<=m; i++) 
                        {  
							ix=(i-1)*n+j-1; 
                            iy=(i-1)*n+kk-1; 
                            m_pData[ix]=m_pData[ix]+d*m_pData[iy]; 
                        } 
                    } 
                     
					e[j-1]=m_pData[(kk-1)*n+j-1]; 
                } 
            } 
             
			if (kk<=k) 
            {  
				for (i=kk; i<=m; i++) 
                {  
					ix=(i-1)*m+kk-1;  
					iy=(i-1)*n+kk-1; 
                    mtxU.m_pData[ix]=m_pData[iy]; 
                } 
            } 
             
			if (kk<=l) 
            {  
				d=0.0; 
                for (i=kk+1; i<=n; i++) 
					d=d+e[i-1]*e[i-1]; 
                 
				e[kk-1]=sqrt(d); 
                if (e[kk-1]!=0.0) 
                {  
					if (e[kk]!=0.0) 
                    {  
						e[kk-1]=fabs(e[kk-1]); 
                        if (e[kk]<0.0)  
							e[kk-1]=-e[kk-1]; 
                    } 
 
                    for (i=kk+1; i<=n; i++) 
                      e[i-1]=e[i-1]/e[kk-1]; 
                     
					e[kk]=1.0+e[kk]; 
                } 
                 
				e[kk-1]=-e[kk-1]; 
                if ((kk+1<=m)&&(e[kk-1]!=0.0)) 
                {  
					for (i=kk+1; i<=m; i++)  
						w[i-1]=0.0; 
                     
					for (j=kk+1; j<=n; j++) 
						for (i=kk+1; i<=m; i++) 
							w[i-1]=w[i-1]+e[j-1]*m_pData[(i-1)*n+j-1]; 
                     
					for (j=kk+1; j<=n; j++) 
					{ 
						for (i=kk+1; i<=m; i++) 
                        {  
							ix=(i-1)*n+j-1; 
							m_pData[ix]=m_pData[ix]-w[i-1]*e[j-1]/e[kk]; 
                        } 
					} 
                } 
                 
				for (i=kk+1; i<=n; i++) 
                  mtxV.m_pData[(i-1)*n+kk-1]=e[i-1]; 
            } 
        } 
    } 
     
	mm=n; 
    if (m+1n)  
		nn=n; 
    if (nn>=k+1) 
    {  
		for (j=k+1; j<=nn; j++) 
        {  
			for (i=1; i<=m; i++) 
				mtxU.m_pData[(i-1)*m+j-1]=0.0; 
            mtxU.m_pData[(j-1)*m+j-1]=1.0; 
        } 
    } 
     
	if (k>=1) 
    {  
		for (ll=1; ll<=k; ll++) 
        {  
			kk=k-ll+1;  
			iz=(kk-1)*m+kk-1; 
            if (s[kk-1]!=0.0) 
            {  
				if (nn>=kk+1) 
				{ 
					for (j=kk+1; j<=nn; j++) 
					{  
						d=0.0; 
						for (i=kk; i<=m; i++) 
						{  
							ix=(i-1)*m+kk-1; 
							iy=(i-1)*m+j-1; 
							d=d+mtxU.m_pData[ix]*mtxU.m_pData[iy]/mtxU.m_pData[iz]; 
						} 
 
						d=-d; 
						for (i=kk; i<=m; i++) 
						{  
							ix=(i-1)*m+j-1; 
							iy=(i-1)*m+kk-1; 
							mtxU.m_pData[ix]=mtxU.m_pData[ix]+d*mtxU.m_pData[iy]; 
						} 
					} 
				} 
                   
				for (i=kk; i<=m; i++) 
				{  
					ix=(i-1)*m+kk-1;  
					mtxU.m_pData[ix]=-mtxU.m_pData[ix]; 
				} 
 
				mtxU.m_pData[iz]=1.0+mtxU.m_pData[iz]; 
				if (kk-1>=1) 
				{ 
					for (i=1; i<=kk-1; i++) 
						mtxU.m_pData[(i-1)*m+kk-1]=0.0; 
				} 
			} 
            else 
            {  
				for (i=1; i<=m; i++) 
					mtxU.m_pData[(i-1)*m+kk-1]=0.0; 
                mtxU.m_pData[(kk-1)*m+kk-1]=1.0; 
            } 
		} 
    } 
 
    for (ll=1; ll<=n; ll++) 
    {  
		kk=n-ll+1;  
		iz=kk*n+kk-1; 
         
		if ((kk<=l)&&(e[kk-1]!=0.0)) 
        {  
			for (j=kk+1; j<=n; j++) 
            {  
				d=0.0; 
                for (i=kk+1; i<=n; i++) 
                {  
					ix=(i-1)*n+kk-1;  
					iy=(i-1)*n+j-1; 
                    d=d+mtxV.m_pData[ix]*mtxV.m_pData[iy]/mtxV.m_pData[iz]; 
                } 
                 
				d=-d; 
                for (i=kk+1; i<=n; i++) 
                {  
					ix=(i-1)*n+j-1;  
					iy=(i-1)*n+kk-1; 
                    mtxV.m_pData[ix]=mtxV.m_pData[ix]+d*mtxV.m_pData[iy]; 
                } 
            } 
        } 
         
		for (i=1; i<=n; i++) 
			mtxV.m_pData[(i-1)*n+kk-1]=0.0; 
         
		mtxV.m_pData[iz-n]=1.0; 
    } 
     
	for (i=1; i<=m; i++) 
		for (j=1; j<=n; j++) 
			m_pData[(i-1)*n+j-1]=0.0; 
     
	m1=mm;  
	it=60; 
    while (TRUE) 
    {  
		if (mm==0) 
        {  
			ppp(m_pData,e,s,mtxV.m_pData,m,n); 
            return TRUE; 
        } 
        if (it==0) 
        {  
			ppp(m_pData,e,s,mtxV.m_pData,m,n); 
            return FALSE; 
        } 
         
		kk=mm-1; 
		while ((kk!=0)&&(fabs(e[kk-1])!=0.0)) 
        {  
			d=fabs(s[kk-1])+fabs(s[kk]); 
            dd=fabs(e[kk-1]); 
            if (dd>eps*d)  
				kk=kk-1; 
            else  
				e[kk-1]=0.0; 
        } 
         
		if (kk==mm-1) 
        {  
			kk=kk+1; 
            if (s[kk-1]<0.0) 
            {  
				s[kk-1]=-s[kk-1]; 
                for (i=1; i<=n; i++) 
                {  
					ix=(i-1)*n+kk-1;  
					mtxV.m_pData[ix]=-mtxV.m_pData[ix];} 
				} 
				 
				while ((kk!=m1)&&(s[kk-1]kk)&&(fabs(s[ks-1])!=0.0)) 
            {  
				d=0.0; 
                if (ks!=mm)  
					d=d+fabs(e[ks-1]); 
                if (ks!=kk+1)  
					d=d+fabs(e[ks-2]); 
                 
				dd=fabs(s[ks-1]); 
                if (dd>eps*d)  
					ks=ks-1; 
                else  
					s[ks-1]=0.0; 
            } 
             
			if (ks==kk) 
            {  
				kk=kk+1; 
                d=fabs(s[mm-1]); 
                t=fabs(s[mm-2]); 
                if (t>d)  
					d=t; 
                 
				t=fabs(e[mm-2]); 
                if (t>d)  
					d=t; 
                 
				t=fabs(s[kk-1]); 
                if (t>d)  
					d=t; 
                 
				t=fabs(e[kk-1]); 
                if (t>d)  
					d=t; 
                 
				sm=s[mm-1]/d;  
				sm1=s[mm-2]/d; 
                em1=e[mm-2]/d; 
                sk=s[kk-1]/d;  
				ek=e[kk-1]/d; 
                b=((sm1+sm)*(sm1-sm)+em1*em1)/2.0; 
                c=sm*em1;  
				c=c*c;  
				shh=0.0; 
 
                if ((b!=0.0)||(c!=0.0)) 
                {  
					shh=sqrt(b*b+c); 
                    if (b<0.0)  
						shh=-shh; 
 
                    shh=c/(b+shh); 
                } 
                 
				fg[0]=(sk+sm)*(sk-sm)-shh; 
                fg[1]=sk*ek; 
                for (i=kk; i<=mm-1; i++) 
                {  
					sss(fg,cs); 
                    if (i!=kk)  
						e[i-2]=fg[0]; 
 
                    fg[0]=cs[0]*s[i-1]+cs[1]*e[i-1]; 
                    e[i-1]=cs[0]*e[i-1]-cs[1]*s[i-1]; 
                    fg[1]=cs[1]*s[i]; 
                    s[i]=cs[0]*s[i]; 
 
                    if ((cs[0]!=1.0)||(cs[1]!=0.0)) 
					{ 
						for (j=1; j<=n; j++) 
                        {  
							ix=(j-1)*n+i-1; 
							iy=(j-1)*n+i; 
							d=cs[0]*mtxV.m_pData[ix]+cs[1]*mtxV.m_pData[iy]; 
							mtxV.m_pData[iy]=-cs[1]*mtxV.m_pData[ix]+cs[0]*mtxV.m_pData[iy]; 
							mtxV.m_pData[ix]=d; 
                        } 
					} 
 
                    sss(fg,cs); 
                    s[i-1]=fg[0]; 
                    fg[0]=cs[0]*e[i-1]+cs[1]*s[i]; 
                    s[i]=-cs[1]*e[i-1]+cs[0]*s[i]; 
                    fg[1]=cs[1]*e[i]; 
                    e[i]=cs[0]*e[i]; 
 
                    if (i=n)  
		i=n; 
    else  
		i=m; 
 
    for (j=1; j<=i-1; j++) 
    {  
		a[(j-1)*n+j-1]=s[j-1]; 
        a[(j-1)*n+j]=e[j-1]; 
    } 
     
	a[(i-1)*n+i-1]=s[i-1]; 
    if (mfabs(fg[1])) 
        {  
			d=fabs(d); 
            if (fg[0]<0.0)  
				d=-d; 
        } 
        if (fabs(fg[1])>=fabs(fg[0])) 
        {  
			d=fabs(d); 
            if (fg[1]<0.0)  
				d=-d; 
        } 
         
		cs[0]=fg[0]/d;  
		cs[1]=fg[1]/d; 
    } 
     
	r=1.0; 
    if (fabs(fg[0])>fabs(fg[1]))  
		r=cs[1]; 
    else if (cs[0]!=0.0)  
		r=1.0/cs[0]; 
 
    fg[0]=d;  
	fg[1]=r; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 求广义逆的奇异值分解法,分解成功后,原矩阵对角线元素就是矩阵的奇异值 
// 
// 参数: 
// 1. CMatrix& mtxAP - 返回原矩阵的广义逆矩阵 
// 2. CMatrix& mtxU - 返回分解后的U矩阵 
// 3. CMatrix& mtxV - 返回分解后的V矩阵 
// 4. double eps - 计算精度,默认值为0.000001 
// 
// 返回值:BOOL型,求解是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::GInvertUV(CMatrix& mtxAP, CMatrix& mtxU, CMatrix& mtxV, double eps /*= 0.000001*/) 
{  
	int i,j,k,l,t,p,q,f; 
 
	// 调用奇异值分解 
    if (! SplitUV(mtxU, mtxV, eps)) 
		return FALSE; 
 
	int m = m_nNumRows; 
	int n = m_nNumColumns; 
 
	// 初始化广义逆矩阵 
	if (! mtxAP.Init(n, m)) 
		return FALSE; 
 
	// 计算广义逆矩阵 
 
    j=n; 
    if (m=1; i--) 
    {  
		h=0.0; 
        if (i>1) 
		{ 
			for (k=0; k<=i-1; k++) 
            {  
				u=i*m_nNumColumns+k;  
				h=h+mtxQ.m_pData[u]*mtxQ.m_pData[u]; 
			} 
		} 
 
        if (h == 0.0) 
        {  
			dblC[i]=0.0; 
            if (i==1)  
				dblC[i]=mtxQ.m_pData[i*m_nNumColumns+i-1]; 
            dblB[i]=0.0; 
        } 
        else 
        {  
			dblC[i]=sqrt(h); 
            u=i*m_nNumColumns+i-1; 
            if (mtxQ.m_pData[u]>0.0)  
				dblC[i]=-dblC[i]; 
 
            h=h-mtxQ.m_pData[u]*dblC[i]; 
            mtxQ.m_pData[u]=mtxQ.m_pData[u]-dblC[i]; 
            f=0.0; 
            for (j=0; j<=i-1; j++) 
            {  
				mtxQ.m_pData[j*m_nNumColumns+i]=mtxQ.m_pData[i*m_nNumColumns+j]/h; 
                g=0.0; 
                for (k=0; k<=j; k++) 
					g=g+mtxQ.m_pData[j*m_nNumColumns+k]*mtxQ.m_pData[i*m_nNumColumns+k]; 
 
				if (j+1<=i-1) 
					for (k=j+1; k<=i-1; k++) 
						g=g+mtxQ.m_pData[k*m_nNumColumns+j]*mtxQ.m_pData[i*m_nNumColumns+k]; 
 
                dblC[j]=g/h; 
                f=f+g*mtxQ.m_pData[j*m_nNumColumns+i]; 
            } 
             
			h2=f/(h+h); 
            for (j=0; j<=i-1; j++) 
            {  
				f=mtxQ.m_pData[i*m_nNumColumns+j]; 
                g=dblC[j]-h2*f; 
                dblC[j]=g; 
                for (k=0; k<=j; k++) 
                {  
					u=j*m_nNumColumns+k; 
                    mtxQ.m_pData[u]=mtxQ.m_pData[u]-f*dblC[k]-g*mtxQ.m_pData[i*m_nNumColumns+k]; 
                } 
            } 
             
			dblB[i]=h; 
        } 
    } 
     
	for (i=0; i<=m_nNumColumns-2; i++)  
		dblC[i]=dblC[i+1]; 
     
	dblC[m_nNumColumns-1]=0.0; 
    dblB[0]=0.0; 
    for (i=0; i<=m_nNumColumns-1; i++) 
    {  
		if ((dblB[i]!=0.0)&&(i-1>=0)) 
		{ 
			for (j=0; j<=i-1; j++) 
            {  
				g=0.0; 
				for (k=0; k<=i-1; k++) 
					g=g+mtxQ.m_pData[i*m_nNumColumns+k]*mtxQ.m_pData[k*m_nNumColumns+j]; 
 
				for (k=0; k<=i-1; k++) 
                {  
					u=k*m_nNumColumns+j; 
					mtxQ.m_pData[u]=mtxQ.m_pData[u]-g*mtxQ.m_pData[k*m_nNumColumns+i]; 
                } 
            } 
		} 
 
        u=i*m_nNumColumns+i; 
        dblB[i]=mtxQ.m_pData[u]; mtxQ.m_pData[u]=1.0; 
        if (i-1>=0) 
		{ 
			for (j=0; j<=i-1; j++) 
            {  
				mtxQ.m_pData[i*m_nNumColumns+j]=0.0;  
				mtxQ.m_pData[j*m_nNumColumns+i]=0.0; 
			} 
		} 
    } 
 
    // 构造对称三对角矩阵 
    for (i=0; id)  
			d=h; 
         
		m=j; 
        while ((m<=n-1)&&(fabs(dblC[m])>d))  
			m=m+1; 
         
		if (m!=j) 
        {  
			do 
            {  
				if (it==nMaxIt) 
					return FALSE; 
 
                it=it+1; 
                g=dblB[j]; 
                p=(dblB[j+1]-g)/(2.0*dblC[j]); 
                r=sqrt(p*p+1.0); 
                if (p>=0.0)  
					dblB[j]=dblC[j]/(p+r); 
                else  
					dblB[j]=dblC[j]/(p-r); 
                 
				h=g-dblB[j]; 
                for (i=j+1; i<=n-1; i++) 
					dblB[i]=dblB[i]-h; 
                 
				f=f+h;  
				p=dblB[m];  
				e=1.0;  
				s=0.0; 
                for (i=m-1; i>=j; i--) 
                {  
					g=e*dblC[i];  
					h=e*p; 
                    if (fabs(p)>=fabs(dblC[i])) 
                    {  
						e=dblC[i]/p;  
						r=sqrt(e*e+1.0); 
                        dblC[i+1]=s*p*r;  
						s=e/r;  
						e=1.0/r; 
                    } 
                    else 
					{  
						e=p/dblC[i];  
						r=sqrt(e*e+1.0); 
                        dblC[i+1]=s*dblC[i]*r; 
                        s=1.0/r;  
						e=e/r; 
                    } 
                     
					p=e*dblB[i]-s*g; 
                    dblB[i+1]=h+s*(e*g+s*dblB[i]); 
                    for (k=0; k<=n-1; k++) 
                    {  
						u=k*n+i+1;  
						v=u-1; 
                        h=mtxQ.m_pData[u];  
						mtxQ.m_pData[u]=s*mtxQ.m_pData[v]+e*h; 
                        mtxQ.m_pData[v]=e*mtxQ.m_pData[v]-s*h; 
                    } 
                } 
                 
				dblC[j]=s*p;  
				dblB[j]=e*p; 
             
			} while (fabs(dblC[j])>d); 
        } 
         
		dblB[j]=dblB[j]+f; 
    } 
     
	for (i=0; i<=n-1; i++) 
    {  
		k=i;  
		p=dblB[i]; 
        if (i+1<=n-1) 
        {  
			j=i+1; 
            while ((j<=n-1)&&(dblB[j]<=p)) 
            {  
				k=j;  
				p=dblB[j];  
				j=j+1; 
			} 
        } 
 
        if (k!=i) 
        {  
			dblB[k]=dblB[i];  
			dblB[i]=p; 
            for (j=0; j<=n-1; j++) 
            {  
				u=j*n+i;  
				v=j*n+k; 
                p=mtxQ.m_pData[u];  
				mtxQ.m_pData[u]=mtxQ.m_pData[v];  
				mtxQ.m_pData[v]=p; 
            } 
        } 
    } 
     
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 约化一般实矩阵为赫申伯格矩阵的初等相似变换法 
// 
// 参数:无 
// 
// 返回值:无 
////////////////////////////////////////////////////////////////////// 
void CMatrix::MakeHberg() 
{  
	int i,j,k,u,v; 
    double d,t; 
 
    for (k=1; k<=m_nNumColumns-2; k++) 
    {  
		d=0.0; 
        for (j=k; j<=m_nNumColumns-1; j++) 
        {  
			u=j*m_nNumColumns+k-1;  
			t=m_pData[u]; 
            if (fabs(t)>fabs(d)) 
            {  
				d=t;  
				i=j; 
			} 
        } 
         
		if (d != 0.0) 
        {  
			if (i!=k) 
            {  
				for (j=k-1; j<=m_nNumColumns-1; j++) 
                {  
					u=i*m_nNumColumns+j;  
					v=k*m_nNumColumns+j; 
                    t=m_pData[u];  
					m_pData[u]=m_pData[v];  
					m_pData[v]=t; 
                } 
                 
				for (j=0; j<=m_nNumColumns-1; j++) 
                {  
					u=j*m_nNumColumns+i;  
					v=j*m_nNumColumns+k; 
                    t=m_pData[u];  
					m_pData[u]=m_pData[v];  
					m_pData[v]=t; 
                } 
            } 
             
			for (i=k+1; i<=m_nNumColumns-1; i++) 
            {  
				u=i*m_nNumColumns+k-1;  
				t=m_pData[u]/d;  
				m_pData[u]=0.0; 
                for (j=k; j<=m_nNumColumns-1; j++) 
                {  
					v=i*m_nNumColumns+j; 
                    m_pData[v]=m_pData[v]-t*m_pData[k*m_nNumColumns+j]; 
                } 
                 
				for (j=0; j<=m_nNumColumns-1; j++) 
                {  
					v=j*m_nNumColumns+k; 
                    m_pData[v]=m_pData[v]+t*m_pData[j*m_nNumColumns+i]; 
                } 
            } 
        } 
    } 
} 
 
////////////////////////////////////////////////////////////////////// 
// 求赫申伯格矩阵全部特征值的QR方法 
// 
// 参数: 
// 1. double dblU[] - 一维数组,长度为矩阵的阶数,返回时存放特征值的实部 
// 2. double dblV[] - 一维数组,长度为矩阵的阶数,返回时存放特征值的虚部 
// 3. int nMaxIt - 迭代次数,默认值为60 
// 4. double eps - 计算精度,默认值为0.000001 
// 
// 返回值:BOOL型,求解是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::HBergEigenv(double dblU[], double dblV[], int nMaxIt /*= 60*/, double eps /*= 0.000001*/) 
{  
	int m,it,i,j,k,l,ii,jj,kk,ll; 
    double b,c,w,g,xy,p,q,r,x,s,e,f,z,y; 
     
	int n = m_nNumColumns; 
 
	it=0;  
	m=n; 
    while (m!=0) 
    {  
		l=m-1; 
        while ((l>0)&&(fabs(m_pData[l*n+l-1]) >  
				eps*(fabs(m_pData[(l-1)*n+l-1])+fabs(m_pData[l*n+l]))))  
		  l=l-1; 
 
        ii=(m-1)*n+m-1;  
		jj=(m-1)*n+m-2; 
        kk=(m-2)*n+m-1;  
		ll=(m-2)*n+m-2; 
        if (l==m-1) 
        {  
			dblU[m-1]=m_pData[(m-1)*n+m-1];  
			dblV[m-1]=0.0; 
            m=m-1;  
			it=0; 
        } 
        else if (l==m-2) 
        {  
			b=-(m_pData[ii]+m_pData[ll]); 
            c=m_pData[ii]*m_pData[ll]-m_pData[jj]*m_pData[kk]; 
            w=b*b-4.0*c; 
            y=sqrt(fabs(w)); 
            if (w>0.0) 
            {  
				xy=1.0; 
                if (b<0.0)  
					xy=-1.0; 
                dblU[m-1]=(-b-xy*y)/2.0; 
                dblU[m-2]=c/dblU[m-1]; 
                dblV[m-1]=0.0; dblV[m-2]=0.0; 
            } 
            else 
            {  
				dblU[m-1]=-b/2.0;  
				dblU[m-2]=dblU[m-1]; 
                dblV[m-1]=y/2.0;  
				dblV[m-2]=-dblV[m-1]; 
            } 
             
			m=m-2;  
			it=0; 
        } 
        else 
        {  
			if (it>=nMaxIt) 
				return FALSE; 
 
            it=it+1; 
            for (j=l+2; j<=m-1; j++) 
				m_pData[j*n+j-2]=0.0; 
            for (j=l+3; j<=m-1; j++) 
				m_pData[j*n+j-3]=0.0; 
            for (k=l; k<=m-2; k++) 
            {  
				if (k!=l) 
                {  
					p=m_pData[k*n+k-1];  
					q=m_pData[(k+1)*n+k-1]; 
                    r=0.0; 
                    if (k!=m-2)  
						r=m_pData[(k+2)*n+k-1]; 
                } 
                else 
                {  
					x=m_pData[ii]+m_pData[ll]; 
                    y=m_pData[ll]*m_pData[ii]-m_pData[kk]*m_pData[jj]; 
                    ii=l*n+l;  
					jj=l*n+l+1; 
                    kk=(l+1)*n+l;  
					ll=(l+1)*n+l+1; 
                    p=m_pData[ii]*(m_pData[ii]-x)+m_pData[jj]*m_pData[kk]+y; 
                    q=m_pData[kk]*(m_pData[ii]+m_pData[ll]-x); 
                    r=m_pData[kk]*m_pData[(l+2)*n+l+1]; 
                } 
                 
				if ((fabs(p)+fabs(q)+fabs(r))!=0.0) 
                {  
					xy=1.0; 
                    if (p<0.0)  
						xy=-1.0; 
                    s=xy*sqrt(p*p+q*q+r*r); 
                    if (k!=l)  
						m_pData[k*n+k-1]=-s; 
                    e=-q/s;  
					f=-r/s;  
					x=-p/s; 
                    y=-x-f*r/(p+s); 
                    g=e*r/(p+s); 
                    z=-x-e*q/(p+s); 
                    for (j=k; j<=m-1; j++) 
                    {  
						ii=k*n+j;  
						jj=(k+1)*n+j; 
                        p=x*m_pData[ii]+e*m_pData[jj]; 
                        q=e*m_pData[ii]+y*m_pData[jj]; 
                        r=f*m_pData[ii]+g*m_pData[jj]; 
                        if (k!=m-2) 
                        {  
							kk=(k+2)*n+j; 
                            p=p+f*m_pData[kk]; 
                            q=q+g*m_pData[kk]; 
                            r=r+z*m_pData[kk];  
							m_pData[kk]=r; 
                        } 
                         
						m_pData[jj]=q; m_pData[ii]=p; 
                    } 
                     
					j=k+3; 
                    if (j>=m-1)  
						j=m-1; 
                     
					for (i=l; i<=j; i++) 
                    {  
						ii=i*n+k;  
						jj=i*n+k+1; 
                        p=x*m_pData[ii]+e*m_pData[jj]; 
                        q=e*m_pData[ii]+y*m_pData[jj]; 
                        r=f*m_pData[ii]+g*m_pData[jj]; 
                        if (k!=m-2) 
                        {  
							kk=i*n+k+2; 
                            p=p+f*m_pData[kk]; 
                            q=q+g*m_pData[kk]; 
                            r=r+z*m_pData[kk];  
							m_pData[kk]=r; 
                        } 
                         
						m_pData[jj]=q;  
						m_pData[ii]=p; 
                    } 
                } 
            } 
        } 
    } 
     
	return TRUE; 
} 
 
////////////////////////////////////////////////////////////////////// 
// 求实对称矩阵特征值与特征向量的雅可比法 
// 
// 参数: 
// 1. double dblEigenValue[] - 一维数组,长度为矩阵的阶数,返回时存放特征值 
// 2. CMatrix& mtxEigenVector - 返回时存放特征向量矩阵,其中第i列为与 
//    数组dblEigenValue中第j个特征值对应的特征向量 
// 3. int nMaxIt - 迭代次数,默认值为60 
// 4. double eps - 计算精度,默认值为0.000001 
// 
// 返回值:BOOL型,求解是否成功 
////////////////////////////////////////////////////////////////////// 
BOOL CMatrix::JacobiEigenv(double dblEigenValue[], CMatrix& mtxEigenVector, int nMaxIt /*= 60*/, double eps /*= 0.000001*/) 
{  
	int i,j,p,q,u,w,t,s,l; 
    double fm,cn,sn,omega,x,y,d; 
     
	if (! mtxEigenVector.Init(m_nNumColumns, m_nNumColumns)) 
		return FALSE; 
 
	l=1; 
    for (i=0; i<=m_nNumColumns-1; i++) 
    {  
		mtxEigenVector.m_pData[i*m_nNumColumns+i]=1.0; 
        for (j=0; j<=m_nNumColumns-1; j++) 
			if (i!=j)  
				mtxEigenVector.m_pData[i*m_nNumColumns+j]=0.0; 
    } 
     
	while (TRUE) 
    {  
		fm=0.0; 
        for (i=1; i<=m_nNumColumns-1; i++) 
		{ 
			for (j=0; j<=i-1; j++) 
			{  
				d=fabs(m_pData[i*m_nNumColumns+j]); 
				if ((i!=j)&&(d>fm)) 
				{  
					fm=d;  
					p=i;  
					q=j; 
				} 
			} 
		} 
 
        if (fmnMaxIt)   
			return FALSE; 
         
		l=l+1; 
        u=p*m_nNumColumns+q;  
		w=p*m_nNumColumns+p;  
		t=q*m_nNumColumns+p;  
		s=q*m_nNumColumns+q; 
        x=-m_pData[u];  
		y=(m_pData[s]-m_pData[w])/2.0; 
        omega=x/sqrt(x*x+y*y); 
 
        if (y<0.0)  
			omega=-omega; 
 
        sn=1.0+sqrt(1.0-omega*omega); 
        sn=omega/sqrt(2.0*sn); 
        cn=sqrt(1.0-sn*sn); 
        fm=m_pData[w]; 
        m_pData[w]=fm*cn*cn+m_pData[s]*sn*sn+m_pData[u]*omega; 
        m_pData[s]=fm*sn*sn+m_pData[s]*cn*cn-m_pData[u]*omega; 
        m_pData[u]=0.0;  
		m_pData[t]=0.0; 
        for (j=0; j<=m_nNumColumns-1; j++) 
		{ 
			if ((j!=p)&&(j!=q)) 
			{  
				u=p*m_nNumColumns+j; w=q*m_nNumColumns+j; 
				fm=m_pData[u]; 
				m_pData[u]=fm*cn+m_pData[w]*sn; 
				m_pData[w]=-fm*sn+m_pData[w]*cn; 
			} 
		} 
 
        for (i=0; i<=m_nNumColumns-1; i++) 
		{ 
			if ((i!=p)&&(i!=q)) 
            {  
				u=i*m_nNumColumns+p;  
				w=i*m_nNumColumns+q; 
				fm=m_pData[u]; 
				m_pData[u]=fm*cn+m_pData[w]*sn; 
				m_pData[w]=-fm*sn+m_pData[w]*cn; 
            } 
		} 
 
        for (i=0; i<=m_nNumColumns-1; i++) 
        {  
			u=i*m_nNumColumns+p;  
			w=i*m_nNumColumns+q; 
            fm=mtxEigenVector.m_pData[u]; 
            mtxEigenVector.m_pData[u]=fm*cn+mtxEigenVector.m_pData[w]*sn; 
            mtxEigenVector.m_pData[w]=-fm*sn+mtxEigenVector.m_pData[w]*cn; 
        } 
    } 
     
	for (i=0; iff) 
            {  
				p=i;  
				q=j; 
                goto Loop_2; 
            } 
        } 
	} 
         
	if (ff