当前位置:文档之家› C语言实现矩阵的LU分解、施密特正交化、Givens分解、Householder分解

C语言实现矩阵的LU分解、施密特正交化、Givens分解、Householder分解

C语言实现矩阵的LU分解、施密特正交化、Givens分解、Householder分解
C语言实现矩阵的LU分解、施密特正交化、Givens分解、Householder分解

C语言实现矩阵的LU分解、施密特正交化、Givens分解、Householder分解

By Kim.Wang,UCAS

#include

#include

#include

#define HS 10

#define LS 10

int n, m;

float a[HS][LS],bc[HS][LS];

void givens()

{

float fm,sc,cos,sin,r[HS][LS],q[HS][LS],swap[HS][LS],p[HS][LS];

int ih,jh,i, j,kh,iw;

for (i = 0; i < m; i++)

for (j = 0; j < n; j++)

r[i][j]=a[i][j];

for (i = 0; i < m; i++)

for (j = 0; j < m; j++)

{

if(i==j)

q[i][j]=1;

else

q[i][j]=0;

}

for(j=0;j

for (i = j+1; i < m; i++)

{

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < m; jh++)

{

if(ih==jh)

p[ih][jh]=1;

else

p[ih][jh]=0;

}

fm=sqrt(r[i][j]*r[i][j]+r[j][j]*r[j][j]);

cos=r[j][j]/fm;

sin=r[i][j]/fm;

p[i][i]=p[j][j]=cos;

p[i][j]=-sin;

p[j][i]=sin;

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < n; jh++)

{

sc=0;

for (kh = 0; kh < m; kh++)

sc=sc+p[ih][kh]*r[kh][jh];

swap[ih][jh]=sc;

}

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < n; jh++)

r[ih][jh]=swap[ih][jh];

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < m; jh++)

{

sc=0;

for (kh = 0; kh < m; kh++)

sc=sc+p[ih][kh]*q[kh][jh];

swap[ih][jh]=sc;

}

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < m; jh++)

q[ih][jh]=swap[ih][jh];

}

printf("\n Givens约减矩阵Q的结果如下:\n");

for (j = 0; j < m; j++)

{

for (i = 0; i < m; i++)

printf("%0.5f ", q[i][j]);

printf("\n");

}

printf("\n Givens约减矩阵R的结果如下:\n");

for (i = 0; i < m; i++)

{

for (j = 0; j < n; j++)

printf("%0.5f ", r[i][j]);

printf("\n");

}

}

void householder()

{

int i, j, k, is,js,ks,iw, ie,je;

float udm,sc,em,nj,q[HS][LS],r[HS][LS],u[LS],swap[HS][LS],dw[HS][LS],p[HS][LS];

for (i = 0; i < m; i++)

for (j = 0; j < n; j++)

r[i][j]=a[i][j];

for (i = 0; i < m; i++)

for (j = 0; j < m; j++)

{

if(i==j)

dw[i][j]=q[i][j]=1;

else

dw[i][j]=q[i][j]=0;

}

for(k=0;k

{

for (i = 0; i < m; i++)

{

if(i

u[i]=0;

else if(i==k)

{

em=0;

for(iw=k;iw

em=em+r[iw][k]*r[iw][k];

em=sqrt(em);

u[i]=r[i][k]-em;

}

else

u[i]=r[i][k];

}

for (udm=0,ie = k; ie < m; ie++)

udm=udm+u[ie]*u[ie];

udm=sqrt(udm);

if(udm<0.00001)

break;

for (ie = 0; ie < m; ie++)

u[ie]=u[ie]/udm;

for (ie = 0; ie < m; ie++)

for (je = 0; je < m; je++)

p[ie][je]=dw[ie][je]-2*u[ie]*u[je];

for (is = 0; is < m; is++)

for (js = 0; js < m; js++)

{

sc=0;

for (ks = 0; ks < m; ks++)

sc=sc+p[is][ks]*q[ks][js];

swap[is][js]=sc;

}

for (is = 0; is < m; is++)

for (js = 0; js < m; js++)

q[is][js]=swap[is][js];

for (is = 0; is < m; is++)

for (js = 0; js < m; js++)

{

sc=0;

for (ks = 0; ks < m; ks++)

sc=sc+p[is][ks]*r[ks][js];

swap[is][js]=sc;

}

for (is = 0; is < m; is++)

for (js = 0; js < m; js++)

r[is][js]=swap[is][js];

}

printf("\n Householder约减矩阵Q的结果如下:\n");

for (j = 0; j < m; j++)

{

for (i = 0; i < m; i++)

printf("%0.5f ", q[i][j]);

printf("\n");

}

printf("\n Householder矩阵R的结果如下:\n");

for (i = 0; i < m; i++)

{

for (j = 0; j < n; j++)

printf("%0.5f ", r[i][j]);

printf("\n");

}

}

void schmidt()

{

int i, j, k, l, b, z;

float em,nj, r[HS][LS],q[HS][LS];

for (i = 0; i < m; i++)

for (j = 0; j < n; j++)

q[i][j]=a[i][j];

for(k=0;k

{

for(l=0;l

{

nj=0;

for(i=0;i

nj=nj+q[i][l]*a[i][k];

r[l][k]=nj;

for(i=0;i

q[i][k]=q[i][k]-r[l][k]*q[i][l];

}

em=0;

for(i=0;i

em=em+q[i][l]*q[i][l];

em=sqrt(em);

r[l][k]=em;

for(i=0;i

q[i][k]=q[i][k]/r[l][k];

}

for(i=0;i

for(j=n;j

q[i][j]=bc[i][j];

printf("\n Schmidt正交化矩阵Q的结果如下:\n");

for (i = 0; i < m; i++)

{

for (j = 0; j < m; j++)

printf("%0.5f ", q[i][j]);

printf("\n");

}

printf("\n Schmidt正交化矩阵R的结果如下:\n");

for (i = 0; i < m; i++)

{

for (j = 0; j < n; j++)

{

if(i>j) r[i][j]=0;

printf("%0.5f ", r[i][j]);

}

printf("\n");

}

}

void lufj()

{

int i, j, k,mm, z, o, p[HS][LS], w[HS];

float x, y,alu[HS][LS], s[HS],l[HS][LS],u[HS][LS]; for (i = 0; i < n; i++)

for (j = 0; j < n; j++)

{

alu[i][j]=a[i][j];

if (i == j)

p[i][j] = 1;

else

p[i][j] = 0;

}

for (j = 0; j < n; j++)

{

i = j; x = alu[i][j]; k = i;

for (; i < n - 1; i++)

{

mm = i + 1;

if (abs(x) < abs(alu[mm][j]))

{

k = mm;

x = alu[mm][j];

}

}

if (k != j)

for (o = 0,i = j; o < n; o++)

{

s[o] = alu[i][o];

alu[i][o] = alu[k][o];

alu[k][o] = s[o];

w[o] = p[i][o];

p[i][o] = p[k][o];

p[k][o] = w[o];

}

for (z = j + 1; z < n; z++)

{

y = alu[z][j] / alu[j][j];

alu[z][j] = y;

for (o = j+1; o < n; o++)

alu[z][o] = alu[z][o] - y*alu[j][o];

}

}

for (i = 0; i < n; i++)

for (j = 0; j < n; j++)

if(i>j)

{

l[i][j]=alu[i][j];

u[i][j]=0;

}

else if(i

{

l[i][j]=0;

u[i][j]=alu[i][j];

}

else

{

l[i][j]=1;

u[i][j]=alu[i][j];

}

printf(" LU分解矩阵L的结果如下:\n");

for (i = 0; i < n; i++)

{

for (j = 0; j < n; j++)

printf("%0.5f ", l[i][j]);

printf("\n");

}

printf("\n LU分解矩阵U的结果如下:\n");

for (i = 0; i < n; i++)

{

for (j = 0; j < n; j++)

printf("%0.5f ", u[i][j]);

printf("\n");

}

printf("\n LU分解行交换矩阵P的结果如下:\n");

for (i = 0; i < n; i++)

{

for (j = 0; j < n; j++)

printf("%d ", p[i][j]);

printf("\n");

}

}

int main()

{

int im,jm,b,z,zl;

printf("请输入矩阵行数M(M需为大于1的整数):\n");

scanf("%d",&m);

printf("请输入矩阵列数N(N需为大于1的整数):\n");

scanf("%d",&n);

for (im = 0; im < m; im++)

for (jm = 0; jm < n; jm++)

{

b = im + 1;

z = jm + 1;

printf("请输入第%d行的第%d个数,以enter键结束输入:\n", b, z);

scanf("%f", &a[im][jm]);

}

float fm,sc,cos,sin,jdz,r[HS][LS],q[HS][LS],swap[HS][LS],p[HS][LS];

int ih,jh,i, j,kh,iw;

for (i = 0; i < m; i++)

for (j = 0; j < n; j++)

r[i][j]=a[i][j];

for (i = 0; i < m; i++)

for (j = 0; j < m; j++)

{

if(i==j)

q[i][j]=1;

else

q[i][j]=0;

}

for(j=0;j

for (i = j+1; i < m; i++)

{

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < m; jh++)

{

if(ih==jh)

p[ih][jh]=1;

else

p[ih][jh]=0;

}

fm=sqrt(r[i][j]*r[i][j]+r[j][j]*r[j][j]);

cos=r[j][j]/fm;

sin=r[i][j]/fm;

p[i][i]=p[j][j]=cos;

p[i][j]=-sin;

p[j][i]=sin;

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < n; jh++)

sc=0;

for (kh = 0; kh < m; kh++)

sc=sc+p[ih][kh]*r[kh][jh];

swap[ih][jh]=sc;

}

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < n; jh++)

r[ih][jh]=swap[ih][jh];

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < m; jh++)

{

sc=0;

for (kh = 0; kh < m; kh++)

sc=sc+p[ih][kh]*q[kh][jh];

swap[ih][jh]=sc;

}

for (ih = 0; ih < m; ih++)

for (jh = 0; jh < m; jh++)

bc[jh][ih]=q[ih][jh]=swap[ih][jh];

}

if(r[n-1][n-1]<0)

jdz=-r[n-1][n-1];

else

jdz=r[n-1][n-1];

if(m

{

printf("\n 该矩阵列向量线性相关,无法进行分解! \n");

system("pause");

}

else if(jdz<0.0001)

{

printf("\n 该矩阵列向量线性相关,无法进行分解! \n");

system("pause");

}

else if(m==n)

{

do

{

printf("\n");

printf("该矩阵可进行四种分解,请输入选项前的数字选择!\n");

printf("0:退出程序\n");

printf("1:Gram-Schmidt正交化\n");

printf("2:Householder分解\n");

printf("3:Givens分解\n");

printf("4:LU分解\n\n");

scanf("%d", &zl);

switch(zl)

{

case 0:return 0; break;

case 1:schmidt(); break;

case 2:householder(); break;

case 3:givens(); break;

case 4:lufj(); break;

}

}

while(zl!=0);

}

else

do

{

printf("\n");

printf("该矩阵可进行除LU分解外的三种分解,请输入选项前的数字选择!\n");

printf("0:退出程序\n");

printf("1:Gram-Schmidt正交化\n");

printf("2:Householder分解\n");

printf("3:Givens分解\n\n");

scanf("%d", &zl);

switch(zl)

{

case 0:return 0; break;

case 1:schmidt(); break;

case 2:householder(); break;

case 3:givens(); break;

}

}

while(zl!=0);

}

相关主题
文本预览
相关文档 最新文档