线性代数方程组求解.docx

上传人:b****1 文档编号:2335642 上传时间:2023-05-03 格式:DOCX 页数:21 大小:770.58KB
下载 相关 举报
线性代数方程组求解.docx_第1页
第1页 / 共21页
线性代数方程组求解.docx_第2页
第2页 / 共21页
线性代数方程组求解.docx_第3页
第3页 / 共21页
线性代数方程组求解.docx_第4页
第4页 / 共21页
线性代数方程组求解.docx_第5页
第5页 / 共21页
线性代数方程组求解.docx_第6页
第6页 / 共21页
线性代数方程组求解.docx_第7页
第7页 / 共21页
线性代数方程组求解.docx_第8页
第8页 / 共21页
线性代数方程组求解.docx_第9页
第9页 / 共21页
线性代数方程组求解.docx_第10页
第10页 / 共21页
线性代数方程组求解.docx_第11页
第11页 / 共21页
线性代数方程组求解.docx_第12页
第12页 / 共21页
线性代数方程组求解.docx_第13页
第13页 / 共21页
线性代数方程组求解.docx_第14页
第14页 / 共21页
线性代数方程组求解.docx_第15页
第15页 / 共21页
线性代数方程组求解.docx_第16页
第16页 / 共21页
线性代数方程组求解.docx_第17页
第17页 / 共21页
线性代数方程组求解.docx_第18页
第18页 / 共21页
线性代数方程组求解.docx_第19页
第19页 / 共21页
线性代数方程组求解.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

线性代数方程组求解.docx

《线性代数方程组求解.docx》由会员分享,可在线阅读,更多相关《线性代数方程组求解.docx(21页珍藏版)》请在冰点文库上搜索。

线性代数方程组求解.docx

线性代数方程组求解

线性代数方程组求解

  

一、实验要求

编程求解方程组:

方程组1:

方程组2:

方程组3:

  

要求:

用C/C++语言实现如下函数:

1.boollu(double*a, int*pivot,intn);

实现矩阵的LU分解。

pivot为输出参数,pivot[0,n)中存放主元的位置排列。

函数成功时返回false,否则返回true。

2.boolguass(doubleconst*lu,intconst*p,double* b,intn);

求线代数方程组的解

设矩阵Lunxn为某个矩阵anxn的LU分解,在内存中按行优先次序存放。

p[0,n)为LU分解的主元排列。

b为方程组Ax=b的右端向量。

此函数计算方程组Ax=b的解,并将结果存放在数组b[0,n)中。

函数成功时返回false,否则返回true。

3、void qr(double*a,double*d,intn);矩阵的QR分解

假设数组anxn在内存中按行优先次序存放。

此函数使用HouseHolder变换将其就地进行QR分解。

d为输出参数,d[0,n)中存放QR分解的上三角对角线元素。

4、boolhshld(doubleconst*qr, doubleconst*d,double*b, intn);求线代数方程组的解

设矩阵qrnxn为某个矩阵anxn的QR分解,在内存中按行优先次序存放。

d [0,n)为QR分解的上三角对角线元素。

b为方程组Ax=b的右端向量。

函数计算方程组Ax=b的解,并将结果存放在数组b[0,n)中。

函数成功时返回false,否则返回true。

二、问题分析

求解线性方程组Ax=b,其实质就就是把它的系数矩阵A通过各种变换成一个下三角或上三角矩阵,从而简化方程组的求解。

因此,在求解线性方程组的过程中,把系数矩阵A变换成上三角或下三角矩阵显得尤为重要,然而矩阵A的变换通常有两种分解方法:

LU分解法与QR分解法。

1、LU分解法:

将A分解为一个下三角矩阵L与一个上三角矩阵U,即:

A=LU,

其中 L=

  U=

2、QR分解法:

将A分解为一个正交矩阵Q与一个上三角矩阵R,即:

A=QR

三、实验原理

解Ax=b的问题就等价于要求解两个三角形方程组:

ﻫ ⑴Ly=b,求y;

   ⑵Ux=y,求x、

设A为非奇异矩阵,且有分解式A=LU, L为单位下三角阵,U为上三角阵。

L,U的元素可以有n步直接计算定出。

用直接三角分解法解Ax=b(要求A的所有顺序主子式都不为零)的计算公式:

① 

i=2,3,…,n.

计算U的第r行,L的第r列元素(i=2,3,…,n):

 ﻫ②  

 , i=r,r+1,…,n;

 i=r+1,…,n,且r≠n、ﻫ求解Ly=b,Ux=y的计算公式;

 ④ﻩ

四、实验步骤

1>将矩阵A保存进计算机中,再定义2个空矩阵L,U以便保存求出的三角矩阵的值。

利用公式①,②,③将矩阵A分解为LU,L为单位下三角阵,U为上三角阵。

2>可知计算方法有三层循环。

先通过公式①计算出U矩阵的第一行元素

 与L矩阵的第一列元素

再根据公式②与③,与上次的出的值,求出矩阵其余的元素,每次都要三次循环,求下一个元素需要上一个结果。

3>先由公式④,Ly=b

求出y,因为L为下三角矩阵,所以由第一行开始求y、

4>再由公式⑤,Ux=y

求出x,因为U为上三角矩阵,所以由最后一行开始求x、

五、程序流程图

1、LU分解法

 

 

2、QR分解法

ﻬ六、实验结果

1、LU分解法

方程组1:

方程组2:

方程组3:

2、QR分解法

方程组1:

方程组2:

ﻩ方程组3:

七、实验总结

为了求解线性方程组,我们通常需要一定的解法。

其中一种解法就就是通过矩阵的三角分解来实现的,属于求解线性方程组的直接法。

在不考虑舍入误差下,直接法可以用有限的运算得到精确解,因此主要适用于求解中小型稠密的线性方程组。

1、三角分解法

三角分解法就是将A矩阵分解成一个上三角形矩阵U与一个下三角形矩阵L,这样的分解法又称为LU分解法。

它的用途主要在简化一个大矩阵的行列式值的计算过程,求反矩阵与求解联立方程组。

不过要注意这种分解法所得到的上下三角形矩阵并非唯一,还可找到数个不同 的一对上下三角形矩阵,此两三角形矩阵相乘也会得到原矩阵。

 

2、 QR分解法

QR分解法就是将矩阵分解成一个正规正交矩阵Q与上三角形矩阵R,所以称为QR分解法。

 

在编写这两个程序过程中,起初遇到不少麻烦!

虽然课上老师反复重复着:

“算法不难的,It'ssoeasy!

”但就是当自己实际操作时,感觉并不就是那么容易。

毕竟就是要把实际的数学问题转化为计算机能够识别的编程算法,所以在编写程序之前我们仔细认真的把所求解的问题逐一进行详细的分析,最终转化为程序段。

每当遇到问题时,大家或许有些郁闷,但最终还就是静下心来反复仔细的琢磨,一一排除了错误,最终完成了本次实验。

回头一想原来编个程序其实也没有想象的那么复杂,只要思路清晰,逐步分析,就可以慢慢搞定了。

附源代码:

#include

#include<stdio、h>

#include<math.h>

#include<stdlib、h>

#include

using namespacestd;

boollu(double*a,int*pivot,intn);//矩阵LU分解

boolguass(doubleconst*lu,intconst* p, double*b,intn);//求线性代数方程组的解

void qr(double*a,double* d, intn); //矩阵的QR分解

bool householder(doubleconst*qr,doubleconst*d, double*b, int n);

intmain()

{

int n=0;

 inttemp=0;

 boolflag=false;

doubleexpct=0;//误差期望值

 double devsq=0;//误差的方差

int*P=NULL; 

   double* D=NULL; 

 doubleA[]={1,1/2、0,1/3、0, 1/4、0,1/5、0,1/6.0,

  1/2、0,1/3、0,1/4、0, 1/5、0, 1/6、0,1/7、0,

   1/3、0,1/4.0,1/5.0,1/6、0,1/7.0,1/8、0,

 1/4、0,1/5、0,1/6.0,1/7、0,1/8、0,1/9、0,

 1/5、0,1/6、0,1/7、0,1/8、0, 1/9、0,1/10、0,

  1/6、0,1/7.0,1/8、0, 1/9、0,1/10、0,1/11、0

 };

  double B[]={  1+ 1/2、0+1/3、0+1/4、0+1/5、0+1/6、0,

 1/2.0+1/3、0+1/4.0+1/5.0+1/6、0+1/7、0,

   1/3、0+1/4、0+1/5、0+ 1/6.0+1/7.0+1/8、0,

   1/4.0+1/5、0+1/6、0+1/7、0+1/8.0+1/9、0,

  1/5、0+1/6、0+ 1/7、0+1/8、0+1/9、0+1/10.0,

 1/6、0+1/7、0+1/8、0+1/9、0+1/10.0+1/11、0

  };

n=6;   

P= (int*)malloc(sizeof(int)*n);

 D=(double*)malloc(sizeof(double)*n);

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

{

  P[i]=D[i]=0;

  }

 cout<<"Please choosethewaytosolve(0:

lu,1:

qr):

";

 cin>>flag;

 if(!

flag)

 {

  cout<<"矩阵LU分解:

\n"; 

   lu(A,P,n);//矩阵LU分解

   for(inti=0; i

 {

  for(intj=0; j

       printf("%f\t",A[i]);

    cout<

   }

 cout<<"矩阵LU分解的主元位置:

\n";

 for(inti=0;i

     cout<<P[i]<<"\t";

  cout<<"\nGuass求线性代数方程组求解:

\n"; 

  guass(A,P,B,n);//求线性代数方程组的解

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

  {

    if(i==3)

      cout<<endl;

  printf("%、16f\t",B[i]);

 }

   cout<<"\nGuass解法的误差为:

\n";   

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

  {

     if(i==3)

       cout<<endl;

    printf("%、16f\t",B[i]-1);

  expct=expct+B[i]-1;

  }

   printf("\n误差期望值为%、16f\t\n",expct/6);

 cout<<endl;

 }

 else

  {

   cout<<"矩阵QR分解:

\n";

    qr(A,D,n);//矩阵qr分解 

 for(inti=0; i

  {

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

   printf("%d\t",A[i]);

    cout<<endl;

 }

   cout<<"QR分解的上三角矩阵对角线元素:

 \n";

  for(inti=0;i

   printf("%f\t",D[i]);

  cout<<"\nHouseholder线性代数方程组求解:

\n";   

  householder(A,D,B,n);//求线性代数方程组的解

 for(inti=0;i

   {

  if(i==3)

   cout<<endl;

   printf("%.16f\t",B[i]);

  }

    cout<<"\nHouseholder解法的误差为:

\n"; 

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

  {

   if(i==3)

     cout<

   printf("%、16f\t",B[i]-1);

  expct=expct+B[i]-1;

    } 

  printf("\n误差期望值为%、16f\t\n",expct/6);

   cout<

  }

return0;

}

boollu(double*a,int* pivot, int n)//矩阵LU分解

  inti,j,k;

  doublemax,temp;

 max =0;

temp=0;

for(i=0;i

 {

  //选出i列的主元,记录主元位置

   max=fabs(a[n*i+ i]);

 pivot[i]=i;

 for(j=i+1; j

  {

 if(fabs(a[n*j+i])>max)

    {

   max=fabs(a[n*j + i]);

     pivot[i]=j;

   }  

}

   //对第i列进行行变换,使得主元在对角线上

 if(pivot[i]!

=i)

  {

   for(j=i;j

    {

   temp=a[n*i+j];

    a[n*i+j]=a[n*pivot[i]+j];

     a[n*pivot[i]+j]=temp;

  }

 }

 for(j=i+1;j

   a[n*j +i]=a[n*j+i]/a[n*i+i];

 for(j=i+1;j<n;j++)//计算上三角U

   for(k=i+1;k

    a[n*j+k]=a[n*j+k]-a[n*j+i]*a[n*i+k];

 }

 //计算下三角L

 for(i=0; i<n-2;i++)//i行k列

 for(k=i+1; k

 {

  temp=a[n*pivot[k]+i];

   a[n*pivot[k]+i]=a[k*n+i];

    a[k*n+ i]=temp;

  }

  returnfalse; 

}

bool guass(doubleconst*lu,intconst*p,double*b,int n)//求线性代数方程组的解

{

 inti,j,k;

double temp;

 //按qivot对b行变换,与LU匹配 

  for(i=0;i

 {

 temp=b[p[i]];

  b[p[i]]=b[i];

 b[i]=temp;  

}

//Ly=b,将y的内容放入b

 for(i=0;i

  for(j=0; j

   b[i]=b[i]-lu[n*i+j]*b[j]; 

 //Uy=x,将x的内容放入b

 for(i=n-1;i>=0;i--)

 {

   for(j=n-1; j>i;j--)

     b[i]=b[i]-lu[n*i+j]*b[j]; 

   b[i]=b[i]/lu[n*i+i];

}

  returnfalse; 

}

voidqr(double*a,double*d,int n)//矩阵的QR分解

{

 inti,j,l,k;

 doubletem,m; 

double*temp;

  temp=(double*)malloc(sizeof(double)*n);

for(i=0; i

{

   //获得tem值

 m=0;

   for(j=i;j

 m=m+a[n*j+ i]*a[n*j+i]; 

if(a[n*i+i ]>0)

  m=-sqrt(m);

  else

      m=sqrt(m);

//获得temp放入矩阵,并存主元d

 tem =0 ;

  d[i]=m;

  a[n*i+i] = a[n*i+i]-m;

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

  tem=tem+ a[n*j+i]*a[n*j+i];

    tem=sqrt(tem);

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

   a[n*j +i]= a[n*j+i]/tem;

  //调整矩阵

  for(k=i+1;k

      {    

   for(j=i;j

  {

     tem=0 ;

      for(l=i; l

   tem=tem+ a[n*j+ i]*a[n*l+i]*a[n*l+k];

  temp[j]= a[j*n+k] - 2*tem;

   }

    for(j=i;j

   a[j*n+k]= temp[j];

   }

  }

 d[n-1] =a[(n-1)*n+n-1];

}

boolhouseholder(doubleconst*qr, double const*d, double*b, int n)//求线性代数方程组的解

int i,j,l;

   doublerem;

double*temp;

 temp=(double*)malloc(sizeof(double)*n);

 for(i=0; i

  {

  for(j=i;j

 {

   rem=0;

 for(l=i;l

   rem=rem + qr[l*n+i]*qr[j*n+i]*b[l];

  temp[j]=b[j]-2*rem;

 }

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

     b[j]=temp[j];

 for(j=n-1; j>-1; j--)

  {

 for(l=n-1;l!

=j;--l)

     b[j]=b[j] -b[l]*qr[j*n+l];

b[j]=b[j]/d[j];

 return false;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2