利用C程序编写格拉姆-施密特正交化的过程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
利用C程序编写格拉姆-施密特正交化的过程
格拉姆-施密特正交化
在线性代数中,如果内积空间上的一组向量能够组成一个子空间,那么这一组向量就称为这个子空间的一个基。Gram-Schmidt正交化提供了一种方法,能够通过这一子空间上的一个基得出子空间的一个正交基,并可进一步求出对应的标准正交基。
这种正交化方法以Jørgen Pedersen Gram和Erhard Schmidt命名,然而比他们更早的拉普拉斯(Laplace)和柯西(Cauchy)已经发现了这一方法。在李群分解中,这种方法被推广为岩泽分解(Iwasawa decomposition)。
在数值计算中,Gram-Schmidt正交化是数值不稳定的,计算中累积的舍入误差会使最终结果的正交性变得很差。因此在实际应用中通常使用豪斯霍尔德变换或Givens旋转进行正交化。
记法
•:维数为n的内积空间
•:中的元素,可以是向量、函数,等等
•:与的内积
•:、……张成的子空间
•:在上的投影
基本思想
Gram-Schmidt正交化的基本想法,是利用投影原理在已有正交基的基础上构造一个新的正交基。
设。是上的维子空间,其标准正交基为,且不在上。由投影原理知,与其在上的投影之差
是正交于子空间的,亦即正交于的正交基。因此只要将单位化,即
那么就是在上扩展的子空间的标准正交基。
根据上述分析,对于向量组张成的空间 (),只要从其中一个向量(不妨设为)所张成的一维子空间开始(注意到就是的正交基),重复上述扩展构造正交基的过程,就能够得到的一组正交基。这就是Gram-Schmidt正交化。
算法
首先需要确定已有基底向量的顺序,不妨设为。Gram-Schmidt 正交化的过程如下:
这样就得到上的一组正交基,以及相应的标准正交基。
例
考察如下欧几里得空间R n中向量的集合,欧氏空间上内积的定义为 = b T a:下面作Gram-Schmidt正交化,以得到一组正交向量:
下面验证向量与的正交性:
将这些向量单位化:
于是就是的一组标准正交基底。
不同的形式
随着内积空间上内积的定义以及构成内积空间的元素的不同,Gram-Schmidt正交化也表现出不同的形式。
例如,在实向量空间上,内积定义为:
在复向量空间上,内积定义为:
函数之间的内积则定义为:
与之对应,相应的Gram-Schmidt正交化就具有不同的形式。
利用C程序编写格拉姆-施密特正交化的过程
C语言程序如下:
#include
#include
#define N 3 //N表示基的个数
#define M 4 //M表示维数
float zj(float a[],float b[]) //这是求内积函数
{int i;
float k=0;
for(i=0;i k+=a[i]*b[i]; return k; } main() {float p[N][M],b[N][M],k[N]; int i,j,m; for(i=0;i { printf("请输入第%d个向量:\n",i+1); for(j=0;j scanf("%f",p[i]+j);} for(i=0;i b[0][i]=p[0][i]; //下面是正交化过程 for(i=1;i { for(m=0;m k[m]=zj(b[i],b[m])/zj(b[m],b[m]); //k[m]表示正交化过程中向量前的系数for(j=0;j for(m=0;m b[i][j]-=k[m]*b[m][j]; } printf("正交化结果为:\n"); for(i=0;i { printf("第%d个向量是:\n",i+1); for(j=0;j printf("%g ",b[i][j]); putchar('\n');} //下面是单位化过程 for(i=0;i for(j=0;j p[i][j]=b[i][j]/sqrt(zj(b[i],b[i])); printf("\n单位化结果为:\n"); for(i=0;i { printf("第%d个向量是:\n",i+1); for(j=0;j printf("%g ",p[i][j]); putchar('\n');} } 实验结果如下: 实践课总结: 在这次实践课的课题讨论中,我所在的这个组个个都发挥自己得能动性。都积极主动。拿到课题后,我们马上讨论分工,针对自己所分到得板块去查阅资料,然后再次讨论总结,最后每个人都提出问题共同解决。 当然,在整个过程中遇到问题也是必然的。例如,由于对C语言不熟练而导致在程序设计时遇到种种困难,多而杂得程序设计在排版上不能让读者一目了然,感觉有点凌乱,并且在第一次试讲过程中老师和细心得同学都提出了几个疑议。下来后我们再次讨论。针对那些问题并进行机上调试。结果得出,我们得设计可能繁杂冗长了些,但没有错,因为输入书上得例子后可以得到正确答案。 这次实践课题讨论让我们知道每一个题在深论时才发觉永远没有底限,源源不断地牵扯出来的新知识还等待学习和探索。此外就是一个团队的团结和作至关重要,只有大家和谐有序地进行每一次讨论,效果才能事半功倍。