哪位大大能告诉我几种矩阵求逆的算法,最好有代码 一种不够,要好几种哦:P 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用C写的 double * MatrixOpp(double A[],int m,int n) /*矩阵求逆*/ { int i,j,x,y,k; double *SP=NULL,*AB=NULL,*B=NULL,X,*C; SP=(double *)malloc(m*n*sizeof(double)); AB=(double *)malloc(m*n*sizeof(double)); B=(double *)malloc(m*n*sizeof(double)); X=Surplus(A,m,n); X=1/X; for(i=0;i<m;i++) for(j=0;j<n;j++) {for(k=0;k<m*n;k++) B[k]=A[k]; {for(x=0;x<n;x++) B[i*n+x]=0; for(y=0;y<m;y++) B[m*y+j]=0; B[i*n+j]=1; SP[i*n+j]=Surplus(B,m,n); AB[i*n+j]=X*SP[i*n+j]; } } C=MatrixInver(AB,m,n); return C; } double * MatrixInver(double A[],int m,int n) /*矩阵转置*/ { int i,j; double *B=NULL; B=(double *)malloc(m*n*sizeof(double)); for(i=0;i<n;i++) for(j=0;j<m;j++) B[i*m+j]=A[j*n+i]; return B; } double Surplus(double A[],int m,int n) /*求矩阵行列式*/ { int i,j,k,p,r; double X,temp=1,temp1=1,s=0,s1=0; if(n==2) {for(i=0;i<m;i++) for(j=0;j<n;j++) if((i+j)%2) temp1*=A[i*n+j]; else temp*=A[i*n+j]; X=temp-temp1;} else{ for(k=0;k<n;k++) {for(i=0,j=k;i<m,j<n;i++,j++) temp*=A[i*n+j]; if(m-i) {for(p=m-i,r=m-1;p>0;p--,r--) temp*=A[r*n+p-1];} s+=temp; temp=1; } for(k=n-1;k>=0;k--) {for(i=0,j=k;i<m,j>=0;i++,j--) temp1*=A[i*n+j]; if(m-i) {for(p=m-1,r=i;r<m;p--,r++) temp1*=A[r*n+p];} s1+=temp1; temp1=1; } X=s-s1;} return X; } 矩阵求逆一般使用Gauss-Jordan消去法。具体程序可以参考徐士良编的《C语言常用算法程序集》(清华大学出版社出版,ISBN 7-302-02290-9)或Template Numerical Toolkit(http://math.nist.gov/tnt/index.html)。 高斯-约旦法(全选主元)求逆的步骤如下: 首先,对于 k 从 0 到 n - 1 作如下几步: 从第 k 行、第 k 列开始的右下角子阵中选取绝对值最大的元素,并记住次元素所在的行号和列号,在通过行交换和列交换将它交换到主元素位置上。这一步称为全选主元。 m(k, k) = 1 / m(k, k) m(k, j) = m(k, j) * m(k, k),j = 0, 1, ..., n-1;j != k m(i, j) = m(i, j) - m(i, k) * m(k, j),i, j = 0, 1, ..., n-1;i, j != k m(i, k) = -m(i, k) * m(k, k),i = 0, 1, ..., n-1;i != k 最后,根据在全选主元过程中所记录的行、列交换的信息进行恢复,恢复的原则如下:在全选主元过程中,先交换的行(列)后进行恢复;原来的行(列)交换用列(行)交换来恢复。 实现(4阶矩阵) float Inverse(CLAYMATRIX& mOut, const CLAYMATRIX& rhs) { CLAYMATRIX m(rhs); DWORD is[4]; DWORD js[4]; float fDet = 1.0f; int f = 1; for (int k = 0; k < 4; k ++) { // 第一步,全选主元 float fMax = 0.0f; for (DWORD i = k; i < 4; i ++) { for (DWORD j = k; j < 4; j ++) { const float f = Abs(m(i, j)); if (f > fMax) { fMax = f; is[k] = i; js[k] = j; } } } if (Abs(fMax) < 0.0001f) return 0; if (is[k] != k) { f = -f; swap(m(k, 0), m(is[k], 0)); swap(m(k, 1), m(is[k], 1)); swap(m(k, 2), m(is[k], 2)); swap(m(k, 3), m(is[k], 3)); } if (js[k] != k) { f = -f; swap(m(0, k), m(0, js[k])); swap(m(1, k), m(1, js[k])); swap(m(2, k), m(2, js[k])); swap(m(3, k), m(3, js[k])); } // 计算行列值 fDet *= m(k, k); // 计算逆矩阵 // 第二步 m(k, k) = 1.0f / m(k, k); // 第三步 for (DWORD j = 0; j < 4; j ++) { if (j != k) m(k, j) *= m(k, k); } // 第四步 for (DWORD i = 0; i < 4; i ++) { if (i != k) { for (j = 0; j < 4; j ++) { if (j != k) m(i, j) = m(i, j) - m(i, k) * m(k, j); } } } // 第五步 for (i = 0; i < 4; i ++) { if (i != k) m(i, k) *= -m(k, k); } } for (k = 3; k >= 0; k --) { if (js[k] != k) { swap(m(k, 0), m(js[k], 0)); swap(m(k, 1), m(js[k], 1)); swap(m(k, 2), m(js[k], 2)); swap(m(k, 3), m(js[k], 3)); } if (is[k] != k) { swap(m(0, k), m(0, is[k])); swap(m(1, k), m(1, is[k])); swap(m(2, k), m(2, is[k])); swap(m(3, k), m(3, is[k])); } } mOut = m; return fDet * f; } VC创建用户界面线程无法指定其父窗口? Combo Box 不显示数据,下拉菜单绝对够大。数据绝对添加。 一个用COM构建软件框架的问题 在Win32控制台下如何实现UDP文件传输? 创建线程出错 SDI小问题,达人过来说两句 寻求一份AES加密算法!! 用vc.net调试时不管我用逐语句还是逐过程好像都要把mfc的源文件调出来,有什么办法可以只调试工程文件里面的么? 帮忙发一个 请教微软专家一个关于MSMQ的问题 高分求助:视频会议中怎样把组播改成单播啊? 请问关于一个WM_MYEXIT 《在线等》 谢谢
double * MatrixOpp(double A[],int m,int n) /*矩阵求逆*/
{
int i,j,x,y,k;
double *SP=NULL,*AB=NULL,*B=NULL,X,*C;
SP=(double *)malloc(m*n*sizeof(double));
AB=(double *)malloc(m*n*sizeof(double));
B=(double *)malloc(m*n*sizeof(double));
X=Surplus(A,m,n);
X=1/X;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{for(k=0;k<m*n;k++)
B[k]=A[k];
{for(x=0;x<n;x++)
B[i*n+x]=0;
for(y=0;y<m;y++)
B[m*y+j]=0;
B[i*n+j]=1;
SP[i*n+j]=Surplus(B,m,n);
AB[i*n+j]=X*SP[i*n+j];
}
}
C=MatrixInver(AB,m,n);
return C;
}
double * MatrixInver(double A[],int m,int n) /*矩阵转置*/
{
int i,j;
double *B=NULL;
B=(double *)malloc(m*n*sizeof(double));
for(i=0;i<n;i++)
for(j=0;j<m;j++)
B[i*m+j]=A[j*n+i];
return B;
}
double Surplus(double A[],int m,int n) /*求矩阵行列式*/
{
int i,j,k,p,r;
double X,temp=1,temp1=1,s=0,s1=0;
if(n==2)
{for(i=0;i<m;i++)
for(j=0;j<n;j++)
if((i+j)%2) temp1*=A[i*n+j];
else temp*=A[i*n+j];
X=temp-temp1;}
else{
for(k=0;k<n;k++)
{for(i=0,j=k;i<m,j<n;i++,j++)
temp*=A[i*n+j];
if(m-i)
{for(p=m-i,r=m-1;p>0;p--,r--)
temp*=A[r*n+p-1];}
s+=temp;
temp=1;
}
for(k=n-1;k>=0;k--)
{for(i=0,j=k;i<m,j>=0;i++,j--)
temp1*=A[i*n+j];
if(m-i)
{for(p=m-1,r=i;r<m;p--,r++)
temp1*=A[r*n+p];}
s1+=temp1;
temp1=1;
}
X=s-s1;}
return X;
}
m(k, k) = 1 / m(k, k)
m(k, j) = m(k, j) * m(k, k),j = 0, 1, ..., n-1;j != k
m(i, j) = m(i, j) - m(i, k) * m(k, j),i, j = 0, 1, ..., n-1;i, j != k
m(i, k) = -m(i, k) * m(k, k),i = 0, 1, ..., n-1;i != k
最后,根据在全选主元过程中所记录的行、列交换的信息进行恢复,恢复的原则如下:在全选主元过程中,先交换的行(列)后进行恢复;原来的行(列)交换用列(行)交换来恢复。 实现(4阶矩阵)
float Inverse(CLAYMATRIX& mOut, const CLAYMATRIX& rhs)
{
CLAYMATRIX m(rhs);
DWORD is[4];
DWORD js[4];
float fDet = 1.0f;
int f = 1; for (int k = 0; k < 4; k ++)
{
// 第一步,全选主元
float fMax = 0.0f;
for (DWORD i = k; i < 4; i ++)
{
for (DWORD j = k; j < 4; j ++)
{
const float f = Abs(m(i, j));
if (f > fMax)
{
fMax = f;
is[k] = i;
js[k] = j;
}
}
}
if (Abs(fMax) < 0.0001f)
return 0; if (is[k] != k)
{
f = -f;
swap(m(k, 0), m(is[k], 0));
swap(m(k, 1), m(is[k], 1));
swap(m(k, 2), m(is[k], 2));
swap(m(k, 3), m(is[k], 3));
}
if (js[k] != k)
{
f = -f;
swap(m(0, k), m(0, js[k]));
swap(m(1, k), m(1, js[k]));
swap(m(2, k), m(2, js[k]));
swap(m(3, k), m(3, js[k]));
} // 计算行列值
fDet *= m(k, k); // 计算逆矩阵 // 第二步
m(k, k) = 1.0f / m(k, k);
// 第三步
for (DWORD j = 0; j < 4; j ++)
{
if (j != k)
m(k, j) *= m(k, k);
}
// 第四步
for (DWORD i = 0; i < 4; i ++)
{
if (i != k)
{
for (j = 0; j < 4; j ++)
{
if (j != k)
m(i, j) = m(i, j) - m(i, k) * m(k, j);
}
}
}
// 第五步
for (i = 0; i < 4; i ++)
{
if (i != k)
m(i, k) *= -m(k, k);
}
} for (k = 3; k >= 0; k --)
{
if (js[k] != k)
{
swap(m(k, 0), m(js[k], 0));
swap(m(k, 1), m(js[k], 1));
swap(m(k, 2), m(js[k], 2));
swap(m(k, 3), m(js[k], 3));
}
if (is[k] != k)
{
swap(m(0, k), m(0, is[k]));
swap(m(1, k), m(1, is[k]));
swap(m(2, k), m(2, is[k]));
swap(m(3, k), m(3, is[k]));
}
} mOut = m;
return fDet * f;
}