为了偷懒线性代数作业而写的,功能有矩阵化简(高斯消元法),解方程组(包括齐次和非齐次),求逆矩阵.
解方程的过程是模拟人算(我实在想不出其他方法)
特点是能够保存化简中每个步骤以及该步运算后的结果(方便抄).
本还想再做后续的其他功能(比如求方阵的特征值),但是太难而且线性代数的课程也结束了,做出来也用不上,就弃坑了..= =|||
补充:最近在看《Effective C++》一书,发现我在这个程序里犯了一个重大错误:没有把基类析构函数声明为virtual,原来测试时没找到原因的内存泄漏就出在这里,果然作为初学者,我还得更加努力啊~~~
/Files/takamachi660/矩阵计算器v0.9.3beta.rar
解方程的过程是模拟人算(我实在想不出其他方法)
特点是能够保存化简中每个步骤以及该步运算后的结果(方便抄).
本还想再做后续的其他功能(比如求方阵的特征值),但是太难而且线性代数的课程也结束了,做出来也用不上,就弃坑了..= =|||
补充:最近在看《Effective C++》一书,发现我在这个程序里犯了一个重大错误:没有把基类析构函数声明为virtual,原来测试时没找到原因的内存泄漏就出在这里,果然作为初学者,我还得更加努力啊~~~
//Version 0.9.3
#include"双链表.h"
class CRESULT //结果信息类
{
public:
const int** pArray;
const int** pTArray;
const int** pAArray;
const int iSizeY;
const int iSizeX;
const int iRankA;
const int iRank;
const int iDet;
const int iRoots;
const int** iRootsNum;
const int** iRootsDen;
const bool bHomo;
CRESULT(const int** pArray,const int** pTArray,const int** pAArray,const int iSizeY,const int iSizeX,const int iRankA,const int iRank,const int iDet,const int iRoots,const int** iRootsNum,const int** iRootsDen,const bool bHomo);
};
class CDynamicArray2D //基类
{
protected:
int** pArray; //矩阵
int** pTArray; //转置矩阵
public:
int iSizeY,iSizeX; //行数与列数
CDynamicArray2D(int** p,int iSizeY,int iSizeX);
CDynamicArray2D(int iSizeY,int iSizeX);
CDynamicArray2D();
~CDynamicArray2D();
int fabs(int x); //求绝对值
int** New2D();
void Delete2D(int** Ptr);
void fnTranspose();
void fnTransposeNew();
virtual CRESULT fnRunCalc(); //执行运算并输出结果
static int** New2D(const int iSizeY,const int iSizeX);//创建矩阵,参数为行数与列数
static void Delete2D(int** Ptr,const int iSizeY); //删除矩阵,参数为行数
static void fnArrayCopy(int** const pDst,const int** const pSrc,const int iSizeY,const int iSizeX);//复制矩阵,pDst为目标矩阵,pSrc为源矩阵
static void fnTranspose(int*** ppArr,const int iSizeY,const int iSizeX); //转置矩阵,参数中的行列数为原矩阵的行列数
static int** fnTransposeNew(const int** const pArr,const int iSizeY,const int iSizeX); //转置矩阵但不改变原矩阵,而是输出一个新矩阵
static int fnCommonDivisor(int m,int n); //求m,n的最大公约数
static int fnCommonMultiple(int m,int n); //求m,n的最小公倍数
CDynamicArray2D& operator=(CDynamicArray2D &r);
};
class CDeterminant:public CDynamicArray2D //行列式类
{
private:
int* pValue; //保存行列式的值
public:
int& iSize/*=CMatrix::iSizeX*/; //保存行列式阶数,引用基类的列数
CDeterminant(int** p,int iSize);
CDeterminant(int iSize);
CDeterminant();
~CDeterminant();
int GetValue(); //返回行列式的值
int fnDeterminantCalc();
void fnTranspose();
void fnTransposeNew();
int** New2D();
CRESULT fnRunCalc();
static int** New2D(const int iSize); //重载基类函数,参数表中的两个关于矩阵大小的参数(行列数)改为单个(阶数)
static int fnDeterminantCalc(const int** const pDet,const int iSize); //计算行列式的值
static void fnDeterminantZoom(int** const pDst,const int** const pSrc,const int iPosY,const int iPosX,const int iSize);//求pSrc[iPosY][iPosX]的余子式并保存到pDst中,iSize为原阶数
static void fnTranspose(int** const pDet,const int iSize);
static int** fnTransposeNew(const int** const pDet,const int iSize);
static void fnArrayCopy(int** const pDst,const int** const pSrc,const int iSize);
static int** fnCofactor(const int** const pDet,const int iPosY,const int iPosX,const int iSize);//生成pSrc[iPosY][iPosX]的余子式并返回,iSize为原阶数
static int fnCofactorValue(const int** const pDet,const int iPosY,const int iPosX,const int iSize);//求pSrc[iPosY][iPosX]的代数余子式的值
int operator+(CDeterminant &r); //重载运算符,对行列式值进行四则运算和比较
int operator-(CDeterminant &r);
int operator*(CDeterminant &r);
int operator/(CDeterminant &r);
bool operator==(CDeterminant &r);
bool operator!=(CDeterminant &r);
bool operator>(CDeterminant &r);
bool operator<(CDeterminant &r);
bool operator>=(CDeterminant &r);
bool operator<=(CDeterminant &r);
};
class CStep:public CDynamicArray2D //运算步骤类
{
friend class CMatrix;
public:
CString strOper;
CStep(int** p,int iSizeY,int iSizeX,CString s,int n);
CStep(int n);
CStep();
~CStep();
const int** GetArray();
int nIndex;
bool operator==(const CStep &r);
};
class CMatrix:public CDynamicArray2D //矩阵类
{
protected:
int fnRCommonDivisor(int iR,bool min=0); //求某行元素的最大公约数,当min=1时,-1也作为公约数
bool fnRZeroCheck(int iR); //检查某行元素是否全为0
bool fnRZeroCheck(int iR,int iX); //检查某行前几个元素是否全为0
List<CStep> mylist; //记录化简步骤的链表
public:
int iRank; //秩数
ListItr<CStep> steps; //链表操作器
CMatrix(int** p,int iSizeY,int iSizeX);
CMatrix(int iSizeY,int iSizeX);
CMatrix();
~CMatrix();
//初等行变换函数(Elementary Row Transformation of Matrix)
void fnEleRowTran(int iMod,int iR,bool op=0); //aRi,op=0时为乘,op=1时为除
void fnEleRowTran(int iRa,int iMod,int iRb); //Rj+aRi
void fnEleRowTranEx(int iRa,int iRb); //Ri<-->Rj
void fnEchelon(); //化为梯矩阵
virtual void fnGauss(); //高斯消元法
CRESULT fnRunCalc();
virtual void fnAdjointNew();
CMatrix* operator+(CMatrix &r); //重载运算与,对矩阵进行四则运算和比较
CMatrix* operator-(CMatrix &r);
CMatrix* operator*(int iA);
CMatrix* operator*(CMatrix &r);
bool operator==(CMatrix &r);
};
struct UnknownX //未知数信息
{
int iMod;
int iX;
};
class CEquationGroup:public CMatrix //方程组类
{
public:
UnknownX* xMain; //主变元序列
UnknownX* xFree; //自由变元序列
public:
int iRankA; //系数矩阵的秩数
bool bHomo; //1为齐次方程组,0为非齐次
int** iRootsNum; //解的分子
int** iRootsDen; //解的分母
CEquationGroup(int** p,int iSizeY,int iSizeX);
CEquationGroup(int iSizeY,int iSizeX);
CEquationGroup();
~CEquationGroup();
void fnGauss();
int fnSolve(); //解方程组,返回值表示解的情况,-1:无解,0:只有零解,1:有唯一解,>1:有无穷多个解
CRESULT fnRunCalc();
};
class CSquare:public CMatrix,public CDeterminant //方阵类
{
int** pAArray; //伴随矩阵
public:
CSquare(int** p,int iSize);
CSquare(int iSize);
CSquare();
~CSquare();
void fnAdjointNew();
void fnTranspose();
void fnTransposeNew();
CRESULT fnRunCalc();
static void fnAdjoint(int** const pDet,const int iSize); //将pDet转化为其伴随矩阵
static int** fnAdjointNew(const int** const pDet,const int iSize); //生成pDet的伴随矩阵
};
#include"双链表.h"
class CRESULT //结果信息类
{
public:
const int** pArray;
const int** pTArray;
const int** pAArray;
const int iSizeY;
const int iSizeX;
const int iRankA;
const int iRank;
const int iDet;
const int iRoots;
const int** iRootsNum;
const int** iRootsDen;
const bool bHomo;
CRESULT(const int** pArray,const int** pTArray,const int** pAArray,const int iSizeY,const int iSizeX,const int iRankA,const int iRank,const int iDet,const int iRoots,const int** iRootsNum,const int** iRootsDen,const bool bHomo);
};
class CDynamicArray2D //基类
{
protected:
int** pArray; //矩阵
int** pTArray; //转置矩阵
public:
int iSizeY,iSizeX; //行数与列数
CDynamicArray2D(int** p,int iSizeY,int iSizeX);
CDynamicArray2D(int iSizeY,int iSizeX);
CDynamicArray2D();
~CDynamicArray2D();
int fabs(int x); //求绝对值
int** New2D();
void Delete2D(int** Ptr);
void fnTranspose();
void fnTransposeNew();
virtual CRESULT fnRunCalc(); //执行运算并输出结果
static int** New2D(const int iSizeY,const int iSizeX);//创建矩阵,参数为行数与列数
static void Delete2D(int** Ptr,const int iSizeY); //删除矩阵,参数为行数
static void fnArrayCopy(int** const pDst,const int** const pSrc,const int iSizeY,const int iSizeX);//复制矩阵,pDst为目标矩阵,pSrc为源矩阵
static void fnTranspose(int*** ppArr,const int iSizeY,const int iSizeX); //转置矩阵,参数中的行列数为原矩阵的行列数
static int** fnTransposeNew(const int** const pArr,const int iSizeY,const int iSizeX); //转置矩阵但不改变原矩阵,而是输出一个新矩阵
static int fnCommonDivisor(int m,int n); //求m,n的最大公约数
static int fnCommonMultiple(int m,int n); //求m,n的最小公倍数
CDynamicArray2D& operator=(CDynamicArray2D &r);
};
class CDeterminant:public CDynamicArray2D //行列式类
{
private:
int* pValue; //保存行列式的值
public:
int& iSize/*=CMatrix::iSizeX*/; //保存行列式阶数,引用基类的列数
CDeterminant(int** p,int iSize);
CDeterminant(int iSize);
CDeterminant();
~CDeterminant();
int GetValue(); //返回行列式的值
int fnDeterminantCalc();
void fnTranspose();
void fnTransposeNew();
int** New2D();
CRESULT fnRunCalc();
static int** New2D(const int iSize); //重载基类函数,参数表中的两个关于矩阵大小的参数(行列数)改为单个(阶数)
static int fnDeterminantCalc(const int** const pDet,const int iSize); //计算行列式的值
static void fnDeterminantZoom(int** const pDst,const int** const pSrc,const int iPosY,const int iPosX,const int iSize);//求pSrc[iPosY][iPosX]的余子式并保存到pDst中,iSize为原阶数
static void fnTranspose(int** const pDet,const int iSize);
static int** fnTransposeNew(const int** const pDet,const int iSize);
static void fnArrayCopy(int** const pDst,const int** const pSrc,const int iSize);
static int** fnCofactor(const int** const pDet,const int iPosY,const int iPosX,const int iSize);//生成pSrc[iPosY][iPosX]的余子式并返回,iSize为原阶数
static int fnCofactorValue(const int** const pDet,const int iPosY,const int iPosX,const int iSize);//求pSrc[iPosY][iPosX]的代数余子式的值
int operator+(CDeterminant &r); //重载运算符,对行列式值进行四则运算和比较
int operator-(CDeterminant &r);
int operator*(CDeterminant &r);
int operator/(CDeterminant &r);
bool operator==(CDeterminant &r);
bool operator!=(CDeterminant &r);
bool operator>(CDeterminant &r);
bool operator<(CDeterminant &r);
bool operator>=(CDeterminant &r);
bool operator<=(CDeterminant &r);
};
class CStep:public CDynamicArray2D //运算步骤类
{
friend class CMatrix;
public:
CString strOper;
CStep(int** p,int iSizeY,int iSizeX,CString s,int n);
CStep(int n);
CStep();
~CStep();
const int** GetArray();
int nIndex;
bool operator==(const CStep &r);
};
class CMatrix:public CDynamicArray2D //矩阵类
{
protected:
int fnRCommonDivisor(int iR,bool min=0); //求某行元素的最大公约数,当min=1时,-1也作为公约数
bool fnRZeroCheck(int iR); //检查某行元素是否全为0
bool fnRZeroCheck(int iR,int iX); //检查某行前几个元素是否全为0
List<CStep> mylist; //记录化简步骤的链表
public:
int iRank; //秩数
ListItr<CStep> steps; //链表操作器
CMatrix(int** p,int iSizeY,int iSizeX);
CMatrix(int iSizeY,int iSizeX);
CMatrix();
~CMatrix();
//初等行变换函数(Elementary Row Transformation of Matrix)
void fnEleRowTran(int iMod,int iR,bool op=0); //aRi,op=0时为乘,op=1时为除
void fnEleRowTran(int iRa,int iMod,int iRb); //Rj+aRi
void fnEleRowTranEx(int iRa,int iRb); //Ri<-->Rj
void fnEchelon(); //化为梯矩阵
virtual void fnGauss(); //高斯消元法
CRESULT fnRunCalc();
virtual void fnAdjointNew();
CMatrix* operator+(CMatrix &r); //重载运算与,对矩阵进行四则运算和比较
CMatrix* operator-(CMatrix &r);
CMatrix* operator*(int iA);
CMatrix* operator*(CMatrix &r);
bool operator==(CMatrix &r);
};
struct UnknownX //未知数信息
{
int iMod;
int iX;
};
class CEquationGroup:public CMatrix //方程组类
{
public:
UnknownX* xMain; //主变元序列
UnknownX* xFree; //自由变元序列
public:
int iRankA; //系数矩阵的秩数
bool bHomo; //1为齐次方程组,0为非齐次
int** iRootsNum; //解的分子
int** iRootsDen; //解的分母
CEquationGroup(int** p,int iSizeY,int iSizeX);
CEquationGroup(int iSizeY,int iSizeX);
CEquationGroup();
~CEquationGroup();
void fnGauss();
int fnSolve(); //解方程组,返回值表示解的情况,-1:无解,0:只有零解,1:有唯一解,>1:有无穷多个解
CRESULT fnRunCalc();
};
class CSquare:public CMatrix,public CDeterminant //方阵类
{
int** pAArray; //伴随矩阵
public:
CSquare(int** p,int iSize);
CSquare(int iSize);
CSquare();
~CSquare();
void fnAdjointNew();
void fnTranspose();
void fnTransposeNew();
CRESULT fnRunCalc();
static void fnAdjoint(int** const pDet,const int iSize); //将pDet转化为其伴随矩阵
static int** fnAdjointNew(const int** const pDet,const int iSize); //生成pDet的伴随矩阵
};
//Version 0.9.3
#include"stdafx.h"
#include"DeterminantAndMatrix.h"
CDynamicArray2D::CDynamicArray2D(int** p,int iSizeY,int iSizeX)
: iSizeY(iSizeY)
, iSizeX(iSizeX)
{
pArray=New2D();
pTArray=NULL;
fnArrayCopy(pArray,(const int**const)p,iSizeY,iSizeX);
}
CDynamicArray2D::CDynamicArray2D(int iSizeY,int iSizeX)
: iSizeY(iSizeY)
, iSizeX(iSizeX)
{
pArray=New2D();
pTArray=NULL;
for(int y=0;y<iSizeY;y++)
for(int x=0;x<iSizeX;x++)
pArray[y][x]=0;
}
CDynamicArray2D::CDynamicArray2D()
{
iSizeX=iSizeY=0;
pArray=NULL;
pTArray=NULL;
}
CDynamicArray2D::~CDynamicArray2D()
{
if (pTArray!=NULL)
Delete2D(pTArray,iSizeX);
if (pArray!=NULL)
Delete2D(pArray);
}
int CDynamicArray2D::fabs(int x)
{
return x<0?-x:x;
}
int** CDynamicArray2D::New2D()
{
int** pTemp=new int*[iSizeY];
for(int i=0;i<iSizeY;i++)
{
pTemp[i]=new int[iSizeX];
}
return pTemp;
}
int** CDynamicArray2D::New2D(const int iSizeY,const int iSizeX)
{
int** pTemp=new int*[iSizeY];
for(int i=0;i<iSizeY;i++)
{
pTemp[i]=new int[iSizeX];
}
return pTemp;
}
void CDynamicArray2D::Delete2D(int** Ptr)
{
Delete2D(Ptr,iSizeY);
}
void CDynamicArray2D::Delete2D(int** Ptr,const int iSizeY)
{
for(int i=0;i<iSizeY;i++)
{
delete []Ptr[i];
Ptr[i]=NULL;
}
delete []Ptr;
}
void CDynamicArray2D::fnArrayCopy(int** const pDst,const int** const pSrc,const int iSizeY,const int iSizeX)
{
for(int y=0;y<iSizeY;y++)
{
for(int x=0;x<iSizeX;x++)
{
pDst[y][x]=pSrc[y][x];
}
}
}
void CDynamicArray2D::fnTranspose()
{
if(pTArray==NULL)
pTArray=New2D();
fnArrayCopy(pTArray,(const int**const)pArray,iSizeY,iSizeX);
fnTranspose(&pArray,iSizeY,iSizeX);
int temp=iSizeY;
iSizeY=iSizeX;
iSizeX=temp;
}
void CDynamicArray2D::fnTranspose(int*** const ppArr,const int iSizeY,const int iSizeX)
{
int** pTempArr=fnTransposeNew((const int**const)*ppArr,iSizeY,iSizeX);
Delete2D(*ppArr,iSizeX);
*ppArr=New2D(iSizeX,iSizeY);
fnArrayCopy(*ppArr,(const int**const)pTempArr,iSizeX,iSizeY);
Delete2D(pTempArr,iSizeX);
}
void CDynamicArray2D::fnTransposeNew()
{
if(pTArray!=NULL)
Delete2D(pTArray,iSizeY);
pTArray=fnTransposeNew((const int**const)pArray,iSizeY,iSizeX);
}
int** CDynamicArray2D::fnTransposeNew(const int** const pArr,const int iSizeY,const int iSizeX)
{
int** pNewArr=New2D(iSizeX,iSizeY);
for(int y=0;y<iSizeX;y++)
{
for(int x=0;x<iSizeY;x++)
{
pNewArr[y][x]=pArr[x][y];
}
}
return pNewArr;
}
int CDynamicArray2D::fnCommonDivisor(int m,int n)
{
int p,r,temp;
if (n<m)
{
temp=n;
n=m;
m=temp;
}
p=n*m;
while(m!=0)
{
r=n%m;
n=m;
m=r;
}
return n;
}
int CDynamicArray2D::fnCommonMultiple(int m,int n)
{
m=m==0?1:m;
n=n==0?1:n;
m=m<0?-m:m;
n=n<0?-n:n;
/*int GBS;
for(GBS=m<=n?n:m;GBS%m!=0||GBS%n!=0||GBS<=0;GBS++){} //求最小公倍数,枚举法
return GBS;*/
int p,r,temp; //求最小公倍数,辗转相除法
if (n<m)
{
temp=n;
n=m;
m=temp;
}
p=n*m;
while(m!=0)
{
r=n%m;
n=m;
m=r;
}
return p/n;
}
CRESULT CDynamicArray2D::fnRunCalc()
{
CRESULT dat((const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,0,0,0,0,NULL,NULL,0);
return dat;
}
CDynamicArray2D& CDynamicArray2D::operator=(CDynamicArray2D &r)
{
if(r.iSizeX==0||r.iSizeY==0)
{
pArray=pTArray=NULL;
return *this;
}
if(r.pArray!=NULL)
{
if(pArray==NULL)
pArray=New2D(iSizeY,iSizeX);
fnArrayCopy(pArray,(const int**const)r.pArray,r.iSizeY,r.iSizeX);
}
else
{
if(pArray!=NULL)
Delete2D(pArray);
pArray=NULL;
}
if(r.pTArray!=NULL)
{
if(pTArray==NULL)
pTArray=New2D(r.iSizeX,r.iSizeY);
fnArrayCopy(pTArray,(const int**const)r.pTArray,r.iSizeX,r.iSizeY);
}
else
{
if(pTArray!=NULL)
Delete2D(pTArray,iSizeX);
pTArray=NULL;
}
iSizeY=r.iSizeY;
iSizeX=r.iSizeX;
return *this;
}
CDeterminant::CDeterminant(int** p,int iSize)
: CDynamicArray2D(p,iSize,iSize)
, iSize(CDynamicArray2D::iSizeX)
, pValue(NULL){}
CDeterminant::CDeterminant(int iSize)
: CDynamicArray2D(iSize,iSize)
, iSize(CDynamicArray2D::iSizeX)
, pValue(NULL){}
CDeterminant::CDeterminant()
: iSize(CDynamicArray2D::iSizeX)
, pValue(NULL){}
CDeterminant::~CDeterminant()
{
if (pValue!=NULL)
delete pValue;
}
int** CDeterminant::New2D()
{
return CDynamicArray2D::New2D();
}
int** CDeterminant::New2D(const int iSize)
{
return CDynamicArray2D::New2D(iSize,iSize);
}
int CDeterminant::fnDeterminantCalc()
{
if (pValue==NULL)
pValue=new int;
return *pValue=fnDeterminantCalc((const int**const)pArray,iSize);
}
int CDeterminant::fnDeterminantCalc(const int** const pDet,const int iSize)
{
if(iSize==1)
{
return pDet[0][0];
}
int iX,iResult=0;
for(iX=0;iX<iSize;iX++)
{
iResult+=pDet[0][iX]*fnCofactorValue(pDet,0,iX,iSize);
}
return iResult;
}
void CDeterminant::fnDeterminantZoom(int** const pDst,const int** const pSrc,const int iPosY,const int iPosX,const int iSize)
{
int x,y;
for(y=0;y<iSize-1;y++)
{
for(x=0;x<iSize-1;x++)
{
pDst[y][x]=pSrc[y+(y>=iPosY)][x+(x>=iPosX)];
}
}
}
void CDeterminant::fnArrayCopy(int** const pDst,const int** const pSrc,const int iSize)
{
CDynamicArray2D::fnArrayCopy(pDst,pSrc,iSize,iSize);
}
void CDeterminant::fnTranspose()
{
if(pTArray==NULL)
pTArray=New2D();
fnArrayCopy(pTArray,(const int**const)pArray,iSize);
fnTranspose(pArray,iSize);
}
void CDeterminant::fnTranspose(int** const pDet,const int iSize)
{
int** pTempDet=fnTransposeNew((const int**const)pDet,iSize);
fnArrayCopy(pDet,(const int**const)pTempDet,iSize);
Delete2D(pTempDet,iSize);
}
void CDeterminant::fnTransposeNew()
{
CDynamicArray2D::fnTransposeNew();
}
int** CDeterminant::fnTransposeNew(const int** const pDet,const int iSize)
{
return CDynamicArray2D::fnTransposeNew(pDet,iSize,iSize);
}
int** CDeterminant::fnCofactor(const int** const pDet,const int iPosY,const int iPosX,const int iSize)
{
int** pOutDet=New2D(iSize-1);
fnDeterminantZoom(pOutDet,pDet,iPosY,iPosX,iSize);
return pOutDet;
}
int CDeterminant::fnCofactorValue(const int** const pDet,const int iPosY,const int iPosX,const int iSize)
{
int** pTempDet=fnCofactor(pDet,iPosY,iPosX,iSize);
int iResult=(((iPosY+1+iPosX+1)%2==0)?1:-1)*fnDeterminantCalc((const int**const)pTempDet,iSize-1);
Delete2D(pTempDet,iSize-1);
return iResult;
}
int CDeterminant::GetValue()
{
return *pValue;
}
CRESULT CDeterminant::fnRunCalc()
{
CRESULT dat((const int**)pArray,(const int**)pTArray,NULL,iSize,iSize,0,0,*pValue,0,NULL,NULL,0);
return dat;
}
int CDeterminant::operator+(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue+(*(r.pValue));
}
int CDeterminant::operator-(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue-(*(r.pValue));
}
int CDeterminant::operator*(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue*(*(r.pValue));
}
int CDeterminant::operator/(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue/(*(r.pValue));
}
bool CDeterminant::operator==(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue==(*(r.pValue));
}
bool CDeterminant::operator!=(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue!=(*(r.pValue));
}
bool CDeterminant::operator>(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue>(*(r.pValue));
}
bool CDeterminant::operator<(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue<(*(r.pValue));
}
bool CDeterminant::operator>=(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue>=(*(r.pValue));
}
bool CDeterminant::operator<=(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue<=(*(r.pValue));
}
CStep::CStep(int** p,int iSizeY,int iSizeX,CString s,int n)
: CDynamicArray2D(p,iSizeY,iSizeX)
, strOper(s)
, nIndex(n){}
CStep::CStep(int n)
: strOper("")
, nIndex(n){}
CStep::CStep()
: strOper("")
, nIndex(-1){}
CStep::~CStep(){}
const int** CStep::GetArray()
{
return (const int**)pArray;
}
bool CStep::operator==(const CStep &r)
{
return nIndex==r.nIndex;
}
CMatrix::CMatrix(int** p,int iSizeY,int iSizeX)
: CDynamicArray2D(p,iSizeY,iSizeX)
, iRank(iSizeY)
, steps(mylist){}
CMatrix::CMatrix(int iSizeY,int iSizeX)
:CDynamicArray2D(iSizeY,iSizeX)
, iRank(iSizeY)
, steps(mylist){}
CMatrix::CMatrix()
: iRank(0)
, steps(mylist){}
CMatrix::~CMatrix(){}
int CMatrix::fnRCommonDivisor(int iR,bool min/*=0*/)
{
int GYS=1;
for(int x=0;x<iSizeX;x++)
{
if (pArray[iR][x]!=0)
{
GYS=fabs(pArray[iR][x]);
break;
}
}
for(int x=1;x<iSizeX;x++)
if (GYS>fabs(pArray[iR][x])&&pArray[iR][x]!=0)
GYS=fabs(pArray[iR][x]);
for(int x=0;x<iSizeX;x++)
{
if ((fabs(pArray[iR][x]))%GYS!=0)
{
x=0;
GYS--;
}
}
if(min)
{
int x;
for(x=0;x<iSizeX;x++)
{
if (pArray[iR][x]>0)
break;
}
if (x==iSizeX&&!fnRZeroCheck(iR))
GYS*=-1;
}
return GYS;
}
bool CMatrix::fnRZeroCheck(int iR)
{
for(int x=0;x<iSizeX;x++)
{
if (pArray[iR][x]!=0)
return 0;
}
return 1;
}
bool CMatrix::fnRZeroCheck(int iR,int iX)
{
for(int x=0;x<=iX;x++)
{
if (pArray[iR][x]!=0)
return 0;
}
return 1;
}
void CMatrix::fnEleRowTran(int iMod,int iR,bool op/*=0*/)
{
if (iMod==1||iMod==0)
return;
if (iMod==-1)
op=0;
CString temp;
for(int x=0;x<iSizeX;x++)
{
if(!op)
pArray[iR][x]*=iMod;
else
pArray[iR][x]/=iMod;
}
if(!op)
temp.AppendFormat(_T("%d*R%d"),iMod,iR+1);
else if (iMod<0)
{
iMod*=-1;
temp.AppendFormat(_T("-(1/%d)*R%d"),iMod,iR+1);
}
else
temp.AppendFormat(_T("(1/%d)*R%d"),iMod,iR+1);
CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()+1);
steps+step;
step.pArray=NULL;
}
void CMatrix::fnEleRowTran(int iRa,int iMod,int iRb)
{
if (iMod==0)
return;
for(int x=0;x<iSizeX;x++)
pArray[iRa][x]+=iMod*pArray[iRb][x];
CString temp;
if (iMod>=0)
{
if (iMod==1)
temp.AppendFormat(_T("R%d+R%d"),iRa+1,iRb+1);
else
temp.AppendFormat(_T("R%d+%d*R%d"),iRa+1,iMod,iRb+1);
}
else
{
if (iMod==-1)
temp.AppendFormat(_T("R%d-R%d"),iRa+1,iRb+1);
else
temp.AppendFormat(_T("R%d%d*R%d"),iRa+1,iMod,iRb+1);
}
CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()+1);
steps+step;
step.pArray=NULL;
}
void CMatrix::fnEleRowTranEx(int iRa,int iRb)
{
if (iRa==iRb)
return;
int* temparr=new int[iSizeX];
for(int x=0;x<iSizeX;x++)
temparr[x]=pArray[iRa][x];
for(int x=0;x<iSizeX;x++)
pArray[iRa][x]=pArray[iRb][x];
for(int x=0;x<iSizeX;x++)
pArray[iRb][x]=temparr[x];
delete []temparr;
CString temp;
temp.AppendFormat(_T("R%d<-->R%d"),iRa+1,iRb+1);
CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()+1);
steps+step;
step.pArray=NULL;
}
void CMatrix::fnEchelon()
{
steps.MakeEmpty(mylist);
for(int c=0;c<iSizeX&&c<iRank;c++)
{
for(int y=0;y<iRank;y++)
{
if(fnRZeroCheck(y,c))
{
for(int r=iRank-1;r>y;r--)
{
if (!fnRZeroCheck(r,c))
{
fnEleRowTranEx(y,r);
if (fnRZeroCheck(r))
iRank--;
break;
}
}
}
}
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);
if (pArray[c][c]==0)
continue;
if(pArray[c][c]!=1&&pArray[c][c]!=-1)
{
for(int r=c+1;r<iRank;r++)
{
if (pArray[r][c]==0)
continue;
if ((pArray[c][c]-1)%pArray[r][c]==0)
{
int mod=-(pArray[c][c]-1)/pArray[r][c];
fnEleRowTran(c,mod,r);
break;
}
else if ((pArray[c][c]+1)%pArray[r][c]==0)
{
int mod=-(pArray[c][c]+1)/pArray[r][c];
fnEleRowTran(c,mod,r);
fnEleRowTran(-1,c);
break;
}
}
}
for(int r=c+1;r<iRank;r++)
{
if (pArray[r][c]==0)
continue;
int cm=fnCommonMultiple(pArray[c][c],pArray[r][c]);
if (pArray[r][c]<0)
cm=-cm;
fnEleRowTran(cm/pArray[r][c],r);
fnEleRowTran(r,-pArray[r][c]/pArray[c][c],c);
}
for(int y=iRank-1;y>-1;y--)
{
bool bt=fnRZeroCheck(y);
if(fnRZeroCheck(y))
{
for(int r=iRank-1;r>y;r--)
{
if (!fnRZeroCheck(r))
{
fnEleRowTranEx(y,r);
break;
}
}
iRank--;
}
}
}
for(int y=0;y<iRank-1;y++)
{
int x1,x2;
for(x1=0;x1<iSizeX;x1++)
{
if(pArray[y][x1]!=0)
break;
}
for(x2=0;x2<iSizeX;x2++)
{
if(pArray[y+1][x2]!=0)
break;
}
if(x1==x2)
{
int c=x1;
int cm=fnCommonMultiple(pArray[y][c],pArray[y+1][c]);
if (pArray[y+1][c]<0)
cm=-cm;
fnEleRowTran(cm/pArray[y+1][c],y+1);
fnEleRowTran(y+1,-pArray[y+1][c]/pArray[y][c],y);
}
}
for(int y=0;y<iRank;y++)
{
if(fnRZeroCheck(y))
iRank--;
}
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);
}
void CMatrix::fnGauss()
{
fnEchelon();
for(int x=iSizeX-1;x>-1;x--)
{
int y;
for(y=iRank-1;y>0;y--)
{
if(pArray[y][x]!=0)
break;
}
if(y==0)
continue;
for(int r=y-1;r>-1;r--)
{
if(pArray[r][x]==0)
continue;
int cm=fnCommonMultiple(pArray[y][x],pArray[r][x]);
if (pArray[r][x]<0)
cm=-cm;
fnEleRowTran(cm/pArray[r][x],r);
fnEleRowTran(r,-pArray[r][x]/pArray[y][x],y);
}
for(int y=0;y<iRank-1;y++)
{
int x1,x2;
for(x1=0;x1<iSizeX;x1++)
{
if(pArray[y][x1]!=0)
break;
}
for(x2=0;x2<iSizeX;x2++)
{
if(pArray[y+1][x2]!=0)
break;
}
if(x1>x2)
fnEleRowTranEx(y,y+1);
}
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y,(bool)1),y,(bool)1);
}
/*
for(int r=1;r<iRank;r++)
{
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);
if (pArray[r][r]==0)
continue;
for(int y=r-1;y>-1;y--)
{
if (pArray[y][r]==0)
continue;
int cm=fnCommonMultiple(pArray[r][r],pArray[y][r]);
if (pArray[y][r]<0)
cm=-cm;
fnEleRowTran(cm/pArray[y][r],y);
fnEleRowTran(y,-pArray[y][r]/pArray[r][r],r);
}
for(int y=iRank-1;y>-1;y--)
{
bool bt=fnRZeroCheck(y);
if(fnRZeroCheck(y))
{
for(int r=iRank-1;r>y;r--)
{
if (!fnRZeroCheck(r))
{
fnEleRowTranEx(y,r);
break;
}
}
iRank--;
}
}
for(int y=0;y<iRank-1;y++)
{
int x1,x2;
for(x1=0;x1<iSizeX;x1++)
{
if(pArray[y][x1]!=0)
break;
}
for(x2=0;x2<iSizeX;x2++)
{
if(pArray[y+1][x2]!=0)
break;
}
if(x1>x2)
fnEleRowTranEx(y,y+1);
}
}
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);*/
}
CMatrix* CMatrix::operator+(CMatrix &r)
{
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
return NULL;
CMatrix* pOutMatrix=new CMatrix(iSizeY,iSizeX);
for(int y=0;y<iSizeY;y++)
{
for(int x=0;x<iSizeX;x++)
{
pOutMatrix->pArray[y][x]=pArray[y][x]+r.pArray[y][x];
}
}
return pOutMatrix;
}
CMatrix* CMatrix::operator-(CMatrix &r)
{
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
return NULL;
CMatrix* pOutMatrix=new CMatrix(iSizeY,iSizeX);
for(int y=0;y<iSizeY;y++)
{
for(int x=0;x<iSizeX;x++)
{
pOutMatrix->pArray[y][x]=pArray[y][x]-r.pArray[y][x];
}
}
return pOutMatrix;
}
CMatrix* CMatrix::operator*(int iA)
{
CMatrix* pOutMatrix=new CMatrix(iSizeY,iSizeX);
for(int y=0;y<iSizeY;y++)
for(int x=0;x<iSizeX;x++)
pOutMatrix->pArray[y][x]=iA*pArray[y][x];
return pOutMatrix;
}
CMatrix* CMatrix::operator*(CMatrix &r)
{
if(iSizeX!=r.iSizeY)
return NULL;
CMatrix* pOutMatrix=new CMatrix(iSizeY,r.iSizeX);
for(int y=0;y<pOutMatrix->iSizeY;y++)
{
for(int x=0;x<pOutMatrix->iSizeX;x++)
{
for(int i=0;i<iSizeX;i++)
pOutMatrix->pArray[y][x]+=pArray[y][i]*r.pArray[i][x];
}
}
return pOutMatrix;
}
bool CMatrix::operator==(CMatrix &r)
{
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
return 0;
for(int y=0;y<iSizeY;y++)
for(int x=0;x<iSizeX;x++)
if(pArray[y][x]!=r.pArray[y][x])
return 0;
return 1;
}
CRESULT CMatrix::fnRunCalc()
{
fnGauss();
CRESULT dat((const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,iRank,iRank,0,0,NULL,NULL,0);
return dat;
}
void CMatrix::fnAdjointNew(){};
CEquationGroup::CEquationGroup(int** p,int iSizeY,int iSizeX)
: CMatrix(p,iSizeY,iSizeX)
, iRankA(CMatrix::iRank)
, iRootsNum(NULL)
, iRootsDen(NULL)
, xMain(NULL)
, xFree(NULL){}
CEquationGroup::CEquationGroup(int iSizeY,int iSizeX)
: CMatrix(iSizeY,iSizeX)
, iRankA(CMatrix::iRank)
, iRootsNum(NULL)
, iRootsDen(NULL)
, xMain(NULL)
, xFree(NULL){}
CEquationGroup::CEquationGroup()
: iRankA(0)
, iRootsNum(NULL)
, iRootsDen(NULL)
, xMain(NULL)
, xFree(NULL){}
CEquationGroup::~CEquationGroup()
{
if(iRootsNum!=NULL)
Delete2D(iRootsNum,iSizeX-1);
if(iRootsDen!=NULL)
Delete2D(iRootsDen,iSizeX-1);
if(xMain!=NULL)
delete []xMain;
if(xFree!=NULL)
delete []xFree;
}
void CEquationGroup::fnGauss()
{
CMatrix::fnGauss();
iRankA=iRank;
for(int y=0;y<iRank;y++)
if(fnRZeroCheck(y,iSizeX-2))
iRankA--;
}
int CEquationGroup::fnSolve()
{ //判断是否为齐次方程
int y=0;
for(;y<iRank;y++)
{
if(pArray[y][iSizeX-1]!=0)
break;
}
if(y==iRank)
bHomo=1;
else
bHomo=0;
//非齐次,有唯一解的情况
if(!bHomo&&iRankA==iSizeX-1&&iRank==iSizeX-1)
{
iRootsNum=New2D(iSizeX-1,1);
iRootsDen=New2D(iSizeX-1,1);
for(int root=0;root<iSizeX-1;root++)
{
int iCD=fnCommonDivisor(pArray[root][root],pArray[root][iSizeX-1]);
iRootsDen[root][1]=pArray[root][root]/iCD;
iRootsNum[root][1]=pArray[root][iSizeX-1]/iCD;
if(iRootsDen[root][1]<0)
{
iRootsDen[root][1]*=-1;
iRootsNum[root][1]*=-1;
}
}
return 1;
}
//非齐次,无解的情况
if(!bHomo&&iRankA<iRank)
return -1;
//齐次,只有零解的情况
if(bHomo&&iRankA==iSizeX-1)
return 0;
//统计主变元与自由变元的位置
if(iRankA!=0)
{
xMain=new UnknownX[iRankA];
xFree=new UnknownX[iSizeX-1-iRankA];
int iCountM=-1;
int iCountF=-1;
for(int x=0;x<iSizeX-1;x++)
{
int y=0;
bool logic=0;
for(;y<iRankA;y++)
{
if(y==iCountM+1)
{
if(pArray[y][x]!=0)
logic=1;
continue;
}
if(pArray[y][x]!=0)
break;
}
if(y==iRankA&&logic)
{
++iCountM;
xMain[iCountM].iX=x;
xMain[iCountM].iMod=pArray[iCountM][x];
}
else
{
++iCountF;
xFree[iCountF].iX=x;
xFree[iCountF].iMod=0;
}
}
}
//齐次,有无穷多个解的情况
if(bHomo&&iRankA<iSizeX-1)
{
iRootsNum=New2D(iSizeX-1,iSizeX-1-iRankA);
for(int y=0;y<iSizeX-1;y++)
for(int x=0;x<iSizeX-1-iRankA;x++)
iRootsNum[y][x]=0;
iRootsDen=New2D(iSizeX-1,iSizeX-1-iRankA);
for(int y=0;y<iSizeX-1;y++)
for(int x=0;x<iSizeX-1-iRankA;x++)
iRootsDen[y][x]=1;
for(int xf=0;xf<iSizeX-1-iRankA;xf++)
{
iRootsNum[xFree[xf].iX][xf]=1;
for(int xm=0;xm<iRankA;xm++)
{
iRootsNum[xMain[xm].iX][xf]=-pArray[xm][xFree[xf].iX];
iRootsDen[xMain[xm].iX][xf]=xMain[xm].iMod;
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][xf],iRootsDen[xMain[xm].iX][xf]);
iRootsNum[xMain[xm].iX][xf]/=iCD;
iRootsDen[xMain[xm].iX][xf]/=iCD;
if(iRootsDen[xMain[xm].iX][xf]<0)
{
iRootsDen[xMain[xm].iX][xf]*=-1;
iRootsNum[xMain[xm].iX][xf]*=-1;
}
}
}
return iSizeX-1-iRankA;
}
//非齐次,有无穷多个解的情况
if(!bHomo&&iRank==iRankA&&iRankA<iSizeX-1)
{
//求通解
iRootsNum=New2D(iSizeX-1,iSizeX-iRankA);
for(int y=0;y<iSizeX-1;y++)
for(int x=0;x<iSizeX-iRankA;x++)
iRootsNum[y][x]=0;
iRootsDen=New2D(iSizeX-1,iSizeX-iRankA);
for(int y=0;y<iSizeX-1;y++)
for(int x=0;x<iSizeX-iRankA;x++)
iRootsDen[y][x]=1;
for(int xf=0;xf<iSizeX-1-iRankA;xf++)
{
iRootsNum[xFree[xf].iX][xf]=1;
for(int xm=0;xm<iRankA;xm++)
{
iRootsNum[xMain[xm].iX][xf]=-pArray[xm][xFree[xf].iX];
iRootsDen[xMain[xm].iX][xf]=xMain[xm].iMod;
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][xf],iRootsDen[xMain[xm].iX][xf]);
iRootsNum[xMain[xm].iX][xf]/=iCD;
iRootsDen[xMain[xm].iX][xf]/=iCD;
if(iRootsDen[xMain[xm].iX][xf]<0)
{
iRootsDen[xMain[xm].iX][xf]*=-1;
iRootsNum[xMain[xm].iX][xf]*=-1;
}
}
}
//求一特解
for(int xm=0;xm<iRankA;xm++)
{
iRootsNum[xMain[xm].iX][iSizeX-iRankA-1]=pArray[xm][iSizeX-1];
iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]=xMain[xm].iMod;
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][iSizeX-iRankA-1],iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]);
iRootsNum[xMain[xm].iX][iSizeX-iRankA-1]/=iCD;
iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]/=iCD;
if(iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]<0)
{
iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]*=-1;
iRootsNum[xMain[xm].iX][iSizeX-iRankA-1]*=-1;
}
}
return iSizeX-iRankA;
}
return -1;
}
CRESULT CEquationGroup::fnRunCalc()
{
fnGauss();
int roots=fnSolve();
CRESULT dat((const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,iRankA,iRank,0,roots,(const int**)iRootsNum,(const int**)iRootsDen,bHomo);
return dat;
}
CSquare::CSquare(int** p,int iSize)
: CDeterminant(p,iSize)
, pAArray(NULL)
{
CMatrix::pArray=CDeterminant::pArray;
CMatrix::iSizeX=CMatrix::iSizeY=CMatrix::iRank=iSize;
}
CSquare::CSquare(int iSize)
: CDeterminant(iSize)
, pAArray(NULL)
{
CMatrix::pArray=CDeterminant::pArray;
CMatrix::iSizeX=CMatrix::iSizeY=CMatrix::iRank=iSize;
}
CSquare::CSquare()
: pAArray(NULL){}
CSquare::~CSquare()
{
if (pAArray!=NULL)
CDeterminant::Delete2D(pAArray);
}
void CSquare::fnAdjoint(int** const pDet,const int iSize)
{
if(fnDeterminantCalc((const int**const)pDet,iSize)==0)
return;
int** pTempDet=CDeterminant::New2D(iSize);
CDeterminant::fnArrayCopy(pTempDet,(const int**const)pDet,iSize);
for(int y=0;y<iSize;y++)
{
for(int x=0;x<iSize;x++)
{
pDet[y][x]=fnCofactorValue((const int**const)pTempDet,y,x,iSize);
}
}
CDeterminant::fnTranspose(pDet,iSize);
CDeterminant::Delete2D(pTempDet,iSize);
}
int** CSquare::fnAdjointNew(const int** const pDet,const int iSize)
{
int** pOutDet=CDeterminant::New2D(iSize);
CDeterminant::fnArrayCopy(pOutDet,pDet,iSize);
fnAdjoint(pOutDet,iSize);
return pOutDet;
}
void CSquare::fnAdjointNew()
{
if(pAArray==NULL)
pAArray=CDeterminant::New2D();
CDeterminant::fnArrayCopy(pAArray,(const int**const)CDeterminant::pArray,iSize);
fnAdjoint(pAArray,iSize);
}
void CSquare::fnTranspose()
{
CDeterminant::fnTranspose();
CMatrix::pArray=CDeterminant::pArray;
CMatrix::pTArray=CDeterminant::pTArray;
}
void CSquare::fnTransposeNew()
{
CDeterminant::fnTransposeNew();
CMatrix::pTArray=CDeterminant::pTArray;
}
CRESULT CSquare::fnRunCalc()
{
fnDeterminantCalc();
fnAdjointNew();
fnGauss();
CRESULT dat((const int**)CDeterminant::pArray,(const int**)CDeterminant::pTArray,(const int**)pAArray,iSize,iSize,iRank,iRank,GetValue(),0,NULL,NULL,0);
return dat;
}
CRESULT::CRESULT(const int** pArray,const int** pTArray,const int** pAArray,const int iSizeY,const int iSizeX,const int iRankA,const int iRank,const int iDet,const int iRoots,const int** iRootsNum,const int** iRootsDen,const bool bHomo)
: pArray(pArray)
, pTArray(pTArray)
, pAArray(pAArray)
, iSizeY(iSizeY)
, iSizeX(iSizeX)
, iRankA(iRankA)
, iRank(iRank)
, iDet(iDet)
, iRoots(iRoots)
, iRootsNum(iRootsNum)
, iRootsDen(iRootsDen)
, bHomo(bHomo){}
完整的代码,包括一个MFC窗口程序和那个没贴出来的"双链表.h"#include"stdafx.h"
#include"DeterminantAndMatrix.h"
CDynamicArray2D::CDynamicArray2D(int** p,int iSizeY,int iSizeX)
: iSizeY(iSizeY)
, iSizeX(iSizeX)
{
pArray=New2D();
pTArray=NULL;
fnArrayCopy(pArray,(const int**const)p,iSizeY,iSizeX);
}
CDynamicArray2D::CDynamicArray2D(int iSizeY,int iSizeX)
: iSizeY(iSizeY)
, iSizeX(iSizeX)
{
pArray=New2D();
pTArray=NULL;
for(int y=0;y<iSizeY;y++)
for(int x=0;x<iSizeX;x++)
pArray[y][x]=0;
}
CDynamicArray2D::CDynamicArray2D()
{
iSizeX=iSizeY=0;
pArray=NULL;
pTArray=NULL;
}
CDynamicArray2D::~CDynamicArray2D()
{
if (pTArray!=NULL)
Delete2D(pTArray,iSizeX);
if (pArray!=NULL)
Delete2D(pArray);
}
int CDynamicArray2D::fabs(int x)
{
return x<0?-x:x;
}
int** CDynamicArray2D::New2D()
{
int** pTemp=new int*[iSizeY];
for(int i=0;i<iSizeY;i++)
{
pTemp[i]=new int[iSizeX];
}
return pTemp;
}
int** CDynamicArray2D::New2D(const int iSizeY,const int iSizeX)
{
int** pTemp=new int*[iSizeY];
for(int i=0;i<iSizeY;i++)
{
pTemp[i]=new int[iSizeX];
}
return pTemp;
}
void CDynamicArray2D::Delete2D(int** Ptr)
{
Delete2D(Ptr,iSizeY);
}
void CDynamicArray2D::Delete2D(int** Ptr,const int iSizeY)
{
for(int i=0;i<iSizeY;i++)
{
delete []Ptr[i];
Ptr[i]=NULL;
}
delete []Ptr;
}
void CDynamicArray2D::fnArrayCopy(int** const pDst,const int** const pSrc,const int iSizeY,const int iSizeX)
{
for(int y=0;y<iSizeY;y++)
{
for(int x=0;x<iSizeX;x++)
{
pDst[y][x]=pSrc[y][x];
}
}
}
void CDynamicArray2D::fnTranspose()
{
if(pTArray==NULL)
pTArray=New2D();
fnArrayCopy(pTArray,(const int**const)pArray,iSizeY,iSizeX);
fnTranspose(&pArray,iSizeY,iSizeX);
int temp=iSizeY;
iSizeY=iSizeX;
iSizeX=temp;
}
void CDynamicArray2D::fnTranspose(int*** const ppArr,const int iSizeY,const int iSizeX)
{
int** pTempArr=fnTransposeNew((const int**const)*ppArr,iSizeY,iSizeX);
Delete2D(*ppArr,iSizeX);
*ppArr=New2D(iSizeX,iSizeY);
fnArrayCopy(*ppArr,(const int**const)pTempArr,iSizeX,iSizeY);
Delete2D(pTempArr,iSizeX);
}
void CDynamicArray2D::fnTransposeNew()
{
if(pTArray!=NULL)
Delete2D(pTArray,iSizeY);
pTArray=fnTransposeNew((const int**const)pArray,iSizeY,iSizeX);
}
int** CDynamicArray2D::fnTransposeNew(const int** const pArr,const int iSizeY,const int iSizeX)
{
int** pNewArr=New2D(iSizeX,iSizeY);
for(int y=0;y<iSizeX;y++)
{
for(int x=0;x<iSizeY;x++)
{
pNewArr[y][x]=pArr[x][y];
}
}
return pNewArr;
}
int CDynamicArray2D::fnCommonDivisor(int m,int n)
{
int p,r,temp;
if (n<m)
{
temp=n;
n=m;
m=temp;
}
p=n*m;
while(m!=0)
{
r=n%m;
n=m;
m=r;
}
return n;
}
int CDynamicArray2D::fnCommonMultiple(int m,int n)
{
m=m==0?1:m;
n=n==0?1:n;
m=m<0?-m:m;
n=n<0?-n:n;
/*int GBS;
for(GBS=m<=n?n:m;GBS%m!=0||GBS%n!=0||GBS<=0;GBS++){} //求最小公倍数,枚举法
return GBS;*/
int p,r,temp; //求最小公倍数,辗转相除法
if (n<m)
{
temp=n;
n=m;
m=temp;
}
p=n*m;
while(m!=0)
{
r=n%m;
n=m;
m=r;
}
return p/n;
}
CRESULT CDynamicArray2D::fnRunCalc()
{
CRESULT dat((const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,0,0,0,0,NULL,NULL,0);
return dat;
}
CDynamicArray2D& CDynamicArray2D::operator=(CDynamicArray2D &r)
{
if(r.iSizeX==0||r.iSizeY==0)
{
pArray=pTArray=NULL;
return *this;
}
if(r.pArray!=NULL)
{
if(pArray==NULL)
pArray=New2D(iSizeY,iSizeX);
fnArrayCopy(pArray,(const int**const)r.pArray,r.iSizeY,r.iSizeX);
}
else
{
if(pArray!=NULL)
Delete2D(pArray);
pArray=NULL;
}
if(r.pTArray!=NULL)
{
if(pTArray==NULL)
pTArray=New2D(r.iSizeX,r.iSizeY);
fnArrayCopy(pTArray,(const int**const)r.pTArray,r.iSizeX,r.iSizeY);
}
else
{
if(pTArray!=NULL)
Delete2D(pTArray,iSizeX);
pTArray=NULL;
}
iSizeY=r.iSizeY;
iSizeX=r.iSizeX;
return *this;
}
CDeterminant::CDeterminant(int** p,int iSize)
: CDynamicArray2D(p,iSize,iSize)
, iSize(CDynamicArray2D::iSizeX)
, pValue(NULL){}
CDeterminant::CDeterminant(int iSize)
: CDynamicArray2D(iSize,iSize)
, iSize(CDynamicArray2D::iSizeX)
, pValue(NULL){}
CDeterminant::CDeterminant()
: iSize(CDynamicArray2D::iSizeX)
, pValue(NULL){}
CDeterminant::~CDeterminant()
{
if (pValue!=NULL)
delete pValue;
}
int** CDeterminant::New2D()
{
return CDynamicArray2D::New2D();
}
int** CDeterminant::New2D(const int iSize)
{
return CDynamicArray2D::New2D(iSize,iSize);
}
int CDeterminant::fnDeterminantCalc()
{
if (pValue==NULL)
pValue=new int;
return *pValue=fnDeterminantCalc((const int**const)pArray,iSize);
}
int CDeterminant::fnDeterminantCalc(const int** const pDet,const int iSize)
{
if(iSize==1)
{
return pDet[0][0];
}
int iX,iResult=0;
for(iX=0;iX<iSize;iX++)
{
iResult+=pDet[0][iX]*fnCofactorValue(pDet,0,iX,iSize);
}
return iResult;
}
void CDeterminant::fnDeterminantZoom(int** const pDst,const int** const pSrc,const int iPosY,const int iPosX,const int iSize)
{
int x,y;
for(y=0;y<iSize-1;y++)
{
for(x=0;x<iSize-1;x++)
{
pDst[y][x]=pSrc[y+(y>=iPosY)][x+(x>=iPosX)];
}
}
}
void CDeterminant::fnArrayCopy(int** const pDst,const int** const pSrc,const int iSize)
{
CDynamicArray2D::fnArrayCopy(pDst,pSrc,iSize,iSize);
}
void CDeterminant::fnTranspose()
{
if(pTArray==NULL)
pTArray=New2D();
fnArrayCopy(pTArray,(const int**const)pArray,iSize);
fnTranspose(pArray,iSize);
}
void CDeterminant::fnTranspose(int** const pDet,const int iSize)
{
int** pTempDet=fnTransposeNew((const int**const)pDet,iSize);
fnArrayCopy(pDet,(const int**const)pTempDet,iSize);
Delete2D(pTempDet,iSize);
}
void CDeterminant::fnTransposeNew()
{
CDynamicArray2D::fnTransposeNew();
}
int** CDeterminant::fnTransposeNew(const int** const pDet,const int iSize)
{
return CDynamicArray2D::fnTransposeNew(pDet,iSize,iSize);
}
int** CDeterminant::fnCofactor(const int** const pDet,const int iPosY,const int iPosX,const int iSize)
{
int** pOutDet=New2D(iSize-1);
fnDeterminantZoom(pOutDet,pDet,iPosY,iPosX,iSize);
return pOutDet;
}
int CDeterminant::fnCofactorValue(const int** const pDet,const int iPosY,const int iPosX,const int iSize)
{
int** pTempDet=fnCofactor(pDet,iPosY,iPosX,iSize);
int iResult=(((iPosY+1+iPosX+1)%2==0)?1:-1)*fnDeterminantCalc((const int**const)pTempDet,iSize-1);
Delete2D(pTempDet,iSize-1);
return iResult;
}
int CDeterminant::GetValue()
{
return *pValue;
}
CRESULT CDeterminant::fnRunCalc()
{
CRESULT dat((const int**)pArray,(const int**)pTArray,NULL,iSize,iSize,0,0,*pValue,0,NULL,NULL,0);
return dat;
}
int CDeterminant::operator+(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue+(*(r.pValue));
}
int CDeterminant::operator-(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue-(*(r.pValue));
}
int CDeterminant::operator*(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue*(*(r.pValue));
}
int CDeterminant::operator/(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue/(*(r.pValue));
}
bool CDeterminant::operator==(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue==(*(r.pValue));
}
bool CDeterminant::operator!=(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue!=(*(r.pValue));
}
bool CDeterminant::operator>(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue>(*(r.pValue));
}
bool CDeterminant::operator<(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue<(*(r.pValue));
}
bool CDeterminant::operator>=(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue>=(*(r.pValue));
}
bool CDeterminant::operator<=(CDeterminant &r)
{
if(pValue==NULL)
{
pValue=new int;
fnDeterminantCalc();
}
if(r.pArray==NULL)
{
r.pValue=new int;
r.fnDeterminantCalc();
}
return *pValue<=(*(r.pValue));
}
CStep::CStep(int** p,int iSizeY,int iSizeX,CString s,int n)
: CDynamicArray2D(p,iSizeY,iSizeX)
, strOper(s)
, nIndex(n){}
CStep::CStep(int n)
: strOper("")
, nIndex(n){}
CStep::CStep()
: strOper("")
, nIndex(-1){}
CStep::~CStep(){}
const int** CStep::GetArray()
{
return (const int**)pArray;
}
bool CStep::operator==(const CStep &r)
{
return nIndex==r.nIndex;
}
CMatrix::CMatrix(int** p,int iSizeY,int iSizeX)
: CDynamicArray2D(p,iSizeY,iSizeX)
, iRank(iSizeY)
, steps(mylist){}
CMatrix::CMatrix(int iSizeY,int iSizeX)
:CDynamicArray2D(iSizeY,iSizeX)
, iRank(iSizeY)
, steps(mylist){}
CMatrix::CMatrix()
: iRank(0)
, steps(mylist){}
CMatrix::~CMatrix(){}
int CMatrix::fnRCommonDivisor(int iR,bool min/*=0*/)
{
int GYS=1;
for(int x=0;x<iSizeX;x++)
{
if (pArray[iR][x]!=0)
{
GYS=fabs(pArray[iR][x]);
break;
}
}
for(int x=1;x<iSizeX;x++)
if (GYS>fabs(pArray[iR][x])&&pArray[iR][x]!=0)
GYS=fabs(pArray[iR][x]);
for(int x=0;x<iSizeX;x++)
{
if ((fabs(pArray[iR][x]))%GYS!=0)
{
x=0;
GYS--;
}
}
if(min)
{
int x;
for(x=0;x<iSizeX;x++)
{
if (pArray[iR][x]>0)
break;
}
if (x==iSizeX&&!fnRZeroCheck(iR))
GYS*=-1;
}
return GYS;
}
bool CMatrix::fnRZeroCheck(int iR)
{
for(int x=0;x<iSizeX;x++)
{
if (pArray[iR][x]!=0)
return 0;
}
return 1;
}
bool CMatrix::fnRZeroCheck(int iR,int iX)
{
for(int x=0;x<=iX;x++)
{
if (pArray[iR][x]!=0)
return 0;
}
return 1;
}
void CMatrix::fnEleRowTran(int iMod,int iR,bool op/*=0*/)
{
if (iMod==1||iMod==0)
return;
if (iMod==-1)
op=0;
CString temp;
for(int x=0;x<iSizeX;x++)
{
if(!op)
pArray[iR][x]*=iMod;
else
pArray[iR][x]/=iMod;
}
if(!op)
temp.AppendFormat(_T("%d*R%d"),iMod,iR+1);
else if (iMod<0)
{
iMod*=-1;
temp.AppendFormat(_T("-(1/%d)*R%d"),iMod,iR+1);
}
else
temp.AppendFormat(_T("(1/%d)*R%d"),iMod,iR+1);
CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()+1);
steps+step;
step.pArray=NULL;
}
void CMatrix::fnEleRowTran(int iRa,int iMod,int iRb)
{
if (iMod==0)
return;
for(int x=0;x<iSizeX;x++)
pArray[iRa][x]+=iMod*pArray[iRb][x];
CString temp;
if (iMod>=0)
{
if (iMod==1)
temp.AppendFormat(_T("R%d+R%d"),iRa+1,iRb+1);
else
temp.AppendFormat(_T("R%d+%d*R%d"),iRa+1,iMod,iRb+1);
}
else
{
if (iMod==-1)
temp.AppendFormat(_T("R%d-R%d"),iRa+1,iRb+1);
else
temp.AppendFormat(_T("R%d%d*R%d"),iRa+1,iMod,iRb+1);
}
CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()+1);
steps+step;
step.pArray=NULL;
}
void CMatrix::fnEleRowTranEx(int iRa,int iRb)
{
if (iRa==iRb)
return;
int* temparr=new int[iSizeX];
for(int x=0;x<iSizeX;x++)
temparr[x]=pArray[iRa][x];
for(int x=0;x<iSizeX;x++)
pArray[iRa][x]=pArray[iRb][x];
for(int x=0;x<iSizeX;x++)
pArray[iRb][x]=temparr[x];
delete []temparr;
CString temp;
temp.AppendFormat(_T("R%d<-->R%d"),iRa+1,iRb+1);
CStep step(pArray,iSizeY,iSizeX,temp,steps.Count()+1);
steps+step;
step.pArray=NULL;
}
void CMatrix::fnEchelon()
{
steps.MakeEmpty(mylist);
for(int c=0;c<iSizeX&&c<iRank;c++)
{
for(int y=0;y<iRank;y++)
{
if(fnRZeroCheck(y,c))
{
for(int r=iRank-1;r>y;r--)
{
if (!fnRZeroCheck(r,c))
{
fnEleRowTranEx(y,r);
if (fnRZeroCheck(r))
iRank--;
break;
}
}
}
}
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);
if (pArray[c][c]==0)
continue;
if(pArray[c][c]!=1&&pArray[c][c]!=-1)
{
for(int r=c+1;r<iRank;r++)
{
if (pArray[r][c]==0)
continue;
if ((pArray[c][c]-1)%pArray[r][c]==0)
{
int mod=-(pArray[c][c]-1)/pArray[r][c];
fnEleRowTran(c,mod,r);
break;
}
else if ((pArray[c][c]+1)%pArray[r][c]==0)
{
int mod=-(pArray[c][c]+1)/pArray[r][c];
fnEleRowTran(c,mod,r);
fnEleRowTran(-1,c);
break;
}
}
}
for(int r=c+1;r<iRank;r++)
{
if (pArray[r][c]==0)
continue;
int cm=fnCommonMultiple(pArray[c][c],pArray[r][c]);
if (pArray[r][c]<0)
cm=-cm;
fnEleRowTran(cm/pArray[r][c],r);
fnEleRowTran(r,-pArray[r][c]/pArray[c][c],c);
}
for(int y=iRank-1;y>-1;y--)
{
bool bt=fnRZeroCheck(y);
if(fnRZeroCheck(y))
{
for(int r=iRank-1;r>y;r--)
{
if (!fnRZeroCheck(r))
{
fnEleRowTranEx(y,r);
break;
}
}
iRank--;
}
}
}
for(int y=0;y<iRank-1;y++)
{
int x1,x2;
for(x1=0;x1<iSizeX;x1++)
{
if(pArray[y][x1]!=0)
break;
}
for(x2=0;x2<iSizeX;x2++)
{
if(pArray[y+1][x2]!=0)
break;
}
if(x1==x2)
{
int c=x1;
int cm=fnCommonMultiple(pArray[y][c],pArray[y+1][c]);
if (pArray[y+1][c]<0)
cm=-cm;
fnEleRowTran(cm/pArray[y+1][c],y+1);
fnEleRowTran(y+1,-pArray[y+1][c]/pArray[y][c],y);
}
}
for(int y=0;y<iRank;y++)
{
if(fnRZeroCheck(y))
iRank--;
}
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);
}
void CMatrix::fnGauss()
{
fnEchelon();
for(int x=iSizeX-1;x>-1;x--)
{
int y;
for(y=iRank-1;y>0;y--)
{
if(pArray[y][x]!=0)
break;
}
if(y==0)
continue;
for(int r=y-1;r>-1;r--)
{
if(pArray[r][x]==0)
continue;
int cm=fnCommonMultiple(pArray[y][x],pArray[r][x]);
if (pArray[r][x]<0)
cm=-cm;
fnEleRowTran(cm/pArray[r][x],r);
fnEleRowTran(r,-pArray[r][x]/pArray[y][x],y);
}
for(int y=0;y<iRank-1;y++)
{
int x1,x2;
for(x1=0;x1<iSizeX;x1++)
{
if(pArray[y][x1]!=0)
break;
}
for(x2=0;x2<iSizeX;x2++)
{
if(pArray[y+1][x2]!=0)
break;
}
if(x1>x2)
fnEleRowTranEx(y,y+1);
}
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y,(bool)1),y,(bool)1);
}
/*
for(int r=1;r<iRank;r++)
{
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);
if (pArray[r][r]==0)
continue;
for(int y=r-1;y>-1;y--)
{
if (pArray[y][r]==0)
continue;
int cm=fnCommonMultiple(pArray[r][r],pArray[y][r]);
if (pArray[y][r]<0)
cm=-cm;
fnEleRowTran(cm/pArray[y][r],y);
fnEleRowTran(y,-pArray[y][r]/pArray[r][r],r);
}
for(int y=iRank-1;y>-1;y--)
{
bool bt=fnRZeroCheck(y);
if(fnRZeroCheck(y))
{
for(int r=iRank-1;r>y;r--)
{
if (!fnRZeroCheck(r))
{
fnEleRowTranEx(y,r);
break;
}
}
iRank--;
}
}
for(int y=0;y<iRank-1;y++)
{
int x1,x2;
for(x1=0;x1<iSizeX;x1++)
{
if(pArray[y][x1]!=0)
break;
}
for(x2=0;x2<iSizeX;x2++)
{
if(pArray[y+1][x2]!=0)
break;
}
if(x1>x2)
fnEleRowTranEx(y,y+1);
}
}
for(int y=0;y<iRank;y++)
fnEleRowTran(fnRCommonDivisor(y),y,(bool)1);*/
}
CMatrix* CMatrix::operator+(CMatrix &r)
{
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
return NULL;
CMatrix* pOutMatrix=new CMatrix(iSizeY,iSizeX);
for(int y=0;y<iSizeY;y++)
{
for(int x=0;x<iSizeX;x++)
{
pOutMatrix->pArray[y][x]=pArray[y][x]+r.pArray[y][x];
}
}
return pOutMatrix;
}
CMatrix* CMatrix::operator-(CMatrix &r)
{
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
return NULL;
CMatrix* pOutMatrix=new CMatrix(iSizeY,iSizeX);
for(int y=0;y<iSizeY;y++)
{
for(int x=0;x<iSizeX;x++)
{
pOutMatrix->pArray[y][x]=pArray[y][x]-r.pArray[y][x];
}
}
return pOutMatrix;
}
CMatrix* CMatrix::operator*(int iA)
{
CMatrix* pOutMatrix=new CMatrix(iSizeY,iSizeX);
for(int y=0;y<iSizeY;y++)
for(int x=0;x<iSizeX;x++)
pOutMatrix->pArray[y][x]=iA*pArray[y][x];
return pOutMatrix;
}
CMatrix* CMatrix::operator*(CMatrix &r)
{
if(iSizeX!=r.iSizeY)
return NULL;
CMatrix* pOutMatrix=new CMatrix(iSizeY,r.iSizeX);
for(int y=0;y<pOutMatrix->iSizeY;y++)
{
for(int x=0;x<pOutMatrix->iSizeX;x++)
{
for(int i=0;i<iSizeX;i++)
pOutMatrix->pArray[y][x]+=pArray[y][i]*r.pArray[i][x];
}
}
return pOutMatrix;
}
bool CMatrix::operator==(CMatrix &r)
{
if(iSizeY!=r.iSizeY||iSizeX!=r.iSizeX)
return 0;
for(int y=0;y<iSizeY;y++)
for(int x=0;x<iSizeX;x++)
if(pArray[y][x]!=r.pArray[y][x])
return 0;
return 1;
}
CRESULT CMatrix::fnRunCalc()
{
fnGauss();
CRESULT dat((const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,iRank,iRank,0,0,NULL,NULL,0);
return dat;
}
void CMatrix::fnAdjointNew(){};
CEquationGroup::CEquationGroup(int** p,int iSizeY,int iSizeX)
: CMatrix(p,iSizeY,iSizeX)
, iRankA(CMatrix::iRank)
, iRootsNum(NULL)
, iRootsDen(NULL)
, xMain(NULL)
, xFree(NULL){}
CEquationGroup::CEquationGroup(int iSizeY,int iSizeX)
: CMatrix(iSizeY,iSizeX)
, iRankA(CMatrix::iRank)
, iRootsNum(NULL)
, iRootsDen(NULL)
, xMain(NULL)
, xFree(NULL){}
CEquationGroup::CEquationGroup()
: iRankA(0)
, iRootsNum(NULL)
, iRootsDen(NULL)
, xMain(NULL)
, xFree(NULL){}
CEquationGroup::~CEquationGroup()
{
if(iRootsNum!=NULL)
Delete2D(iRootsNum,iSizeX-1);
if(iRootsDen!=NULL)
Delete2D(iRootsDen,iSizeX-1);
if(xMain!=NULL)
delete []xMain;
if(xFree!=NULL)
delete []xFree;
}
void CEquationGroup::fnGauss()
{
CMatrix::fnGauss();
iRankA=iRank;
for(int y=0;y<iRank;y++)
if(fnRZeroCheck(y,iSizeX-2))
iRankA--;
}
int CEquationGroup::fnSolve()
{ //判断是否为齐次方程
int y=0;
for(;y<iRank;y++)
{
if(pArray[y][iSizeX-1]!=0)
break;
}
if(y==iRank)
bHomo=1;
else
bHomo=0;
//非齐次,有唯一解的情况
if(!bHomo&&iRankA==iSizeX-1&&iRank==iSizeX-1)
{
iRootsNum=New2D(iSizeX-1,1);
iRootsDen=New2D(iSizeX-1,1);
for(int root=0;root<iSizeX-1;root++)
{
int iCD=fnCommonDivisor(pArray[root][root],pArray[root][iSizeX-1]);
iRootsDen[root][1]=pArray[root][root]/iCD;
iRootsNum[root][1]=pArray[root][iSizeX-1]/iCD;
if(iRootsDen[root][1]<0)
{
iRootsDen[root][1]*=-1;
iRootsNum[root][1]*=-1;
}
}
return 1;
}
//非齐次,无解的情况
if(!bHomo&&iRankA<iRank)
return -1;
//齐次,只有零解的情况
if(bHomo&&iRankA==iSizeX-1)
return 0;
//统计主变元与自由变元的位置
if(iRankA!=0)
{
xMain=new UnknownX[iRankA];
xFree=new UnknownX[iSizeX-1-iRankA];
int iCountM=-1;
int iCountF=-1;
for(int x=0;x<iSizeX-1;x++)
{
int y=0;
bool logic=0;
for(;y<iRankA;y++)
{
if(y==iCountM+1)
{
if(pArray[y][x]!=0)
logic=1;
continue;
}
if(pArray[y][x]!=0)
break;
}
if(y==iRankA&&logic)
{
++iCountM;
xMain[iCountM].iX=x;
xMain[iCountM].iMod=pArray[iCountM][x];
}
else
{
++iCountF;
xFree[iCountF].iX=x;
xFree[iCountF].iMod=0;
}
}
}
//齐次,有无穷多个解的情况
if(bHomo&&iRankA<iSizeX-1)
{
iRootsNum=New2D(iSizeX-1,iSizeX-1-iRankA);
for(int y=0;y<iSizeX-1;y++)
for(int x=0;x<iSizeX-1-iRankA;x++)
iRootsNum[y][x]=0;
iRootsDen=New2D(iSizeX-1,iSizeX-1-iRankA);
for(int y=0;y<iSizeX-1;y++)
for(int x=0;x<iSizeX-1-iRankA;x++)
iRootsDen[y][x]=1;
for(int xf=0;xf<iSizeX-1-iRankA;xf++)
{
iRootsNum[xFree[xf].iX][xf]=1;
for(int xm=0;xm<iRankA;xm++)
{
iRootsNum[xMain[xm].iX][xf]=-pArray[xm][xFree[xf].iX];
iRootsDen[xMain[xm].iX][xf]=xMain[xm].iMod;
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][xf],iRootsDen[xMain[xm].iX][xf]);
iRootsNum[xMain[xm].iX][xf]/=iCD;
iRootsDen[xMain[xm].iX][xf]/=iCD;
if(iRootsDen[xMain[xm].iX][xf]<0)
{
iRootsDen[xMain[xm].iX][xf]*=-1;
iRootsNum[xMain[xm].iX][xf]*=-1;
}
}
}
return iSizeX-1-iRankA;
}
//非齐次,有无穷多个解的情况
if(!bHomo&&iRank==iRankA&&iRankA<iSizeX-1)
{
//求通解
iRootsNum=New2D(iSizeX-1,iSizeX-iRankA);
for(int y=0;y<iSizeX-1;y++)
for(int x=0;x<iSizeX-iRankA;x++)
iRootsNum[y][x]=0;
iRootsDen=New2D(iSizeX-1,iSizeX-iRankA);
for(int y=0;y<iSizeX-1;y++)
for(int x=0;x<iSizeX-iRankA;x++)
iRootsDen[y][x]=1;
for(int xf=0;xf<iSizeX-1-iRankA;xf++)
{
iRootsNum[xFree[xf].iX][xf]=1;
for(int xm=0;xm<iRankA;xm++)
{
iRootsNum[xMain[xm].iX][xf]=-pArray[xm][xFree[xf].iX];
iRootsDen[xMain[xm].iX][xf]=xMain[xm].iMod;
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][xf],iRootsDen[xMain[xm].iX][xf]);
iRootsNum[xMain[xm].iX][xf]/=iCD;
iRootsDen[xMain[xm].iX][xf]/=iCD;
if(iRootsDen[xMain[xm].iX][xf]<0)
{
iRootsDen[xMain[xm].iX][xf]*=-1;
iRootsNum[xMain[xm].iX][xf]*=-1;
}
}
}
//求一特解
for(int xm=0;xm<iRankA;xm++)
{
iRootsNum[xMain[xm].iX][iSizeX-iRankA-1]=pArray[xm][iSizeX-1];
iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]=xMain[xm].iMod;
int iCD=fnCommonDivisor(iRootsNum[xMain[xm].iX][iSizeX-iRankA-1],iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]);
iRootsNum[xMain[xm].iX][iSizeX-iRankA-1]/=iCD;
iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]/=iCD;
if(iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]<0)
{
iRootsDen[xMain[xm].iX][iSizeX-iRankA-1]*=-1;
iRootsNum[xMain[xm].iX][iSizeX-iRankA-1]*=-1;
}
}
return iSizeX-iRankA;
}
return -1;
}
CRESULT CEquationGroup::fnRunCalc()
{
fnGauss();
int roots=fnSolve();
CRESULT dat((const int**)pArray,(const int**)pTArray,NULL,iSizeY,iSizeX,iRankA,iRank,0,roots,(const int**)iRootsNum,(const int**)iRootsDen,bHomo);
return dat;
}
CSquare::CSquare(int** p,int iSize)
: CDeterminant(p,iSize)
, pAArray(NULL)
{
CMatrix::pArray=CDeterminant::pArray;
CMatrix::iSizeX=CMatrix::iSizeY=CMatrix::iRank=iSize;
}
CSquare::CSquare(int iSize)
: CDeterminant(iSize)
, pAArray(NULL)
{
CMatrix::pArray=CDeterminant::pArray;
CMatrix::iSizeX=CMatrix::iSizeY=CMatrix::iRank=iSize;
}
CSquare::CSquare()
: pAArray(NULL){}
CSquare::~CSquare()
{
if (pAArray!=NULL)
CDeterminant::Delete2D(pAArray);
}
void CSquare::fnAdjoint(int** const pDet,const int iSize)
{
if(fnDeterminantCalc((const int**const)pDet,iSize)==0)
return;
int** pTempDet=CDeterminant::New2D(iSize);
CDeterminant::fnArrayCopy(pTempDet,(const int**const)pDet,iSize);
for(int y=0;y<iSize;y++)
{
for(int x=0;x<iSize;x++)
{
pDet[y][x]=fnCofactorValue((const int**const)pTempDet,y,x,iSize);
}
}
CDeterminant::fnTranspose(pDet,iSize);
CDeterminant::Delete2D(pTempDet,iSize);
}
int** CSquare::fnAdjointNew(const int** const pDet,const int iSize)
{
int** pOutDet=CDeterminant::New2D(iSize);
CDeterminant::fnArrayCopy(pOutDet,pDet,iSize);
fnAdjoint(pOutDet,iSize);
return pOutDet;
}
void CSquare::fnAdjointNew()
{
if(pAArray==NULL)
pAArray=CDeterminant::New2D();
CDeterminant::fnArrayCopy(pAArray,(const int**const)CDeterminant::pArray,iSize);
fnAdjoint(pAArray,iSize);
}
void CSquare::fnTranspose()
{
CDeterminant::fnTranspose();
CMatrix::pArray=CDeterminant::pArray;
CMatrix::pTArray=CDeterminant::pTArray;
}
void CSquare::fnTransposeNew()
{
CDeterminant::fnTransposeNew();
CMatrix::pTArray=CDeterminant::pTArray;
}
CRESULT CSquare::fnRunCalc()
{
fnDeterminantCalc();
fnAdjointNew();
fnGauss();
CRESULT dat((const int**)CDeterminant::pArray,(const int**)CDeterminant::pTArray,(const int**)pAArray,iSize,iSize,iRank,iRank,GetValue(),0,NULL,NULL,0);
return dat;
}
CRESULT::CRESULT(const int** pArray,const int** pTArray,const int** pAArray,const int iSizeY,const int iSizeX,const int iRankA,const int iRank,const int iDet,const int iRoots,const int** iRootsNum,const int** iRootsDen,const bool bHomo)
: pArray(pArray)
, pTArray(pTArray)
, pAArray(pAArray)
, iSizeY(iSizeY)
, iSizeX(iSizeX)
, iRankA(iRankA)
, iRank(iRank)
, iDet(iDet)
, iRoots(iRoots)
, iRootsNum(iRootsNum)
, iRootsDen(iRootsDen)
, bHomo(bHomo){}
/Files/takamachi660/矩阵计算器v0.9.3beta.rar