求向量组的等价正交单位向量组-施密特正交化 C 语言 算法
一.施密特正交化
首先需要确定已有基底向量的顺序,不妨设为。Gram-Schmidt正交化的过程如下:
这样就得到上的一组正交基,以及相应的标准正交基。
给定的S个N维向量组,第一步先求出向量组的极大线性无关组
将向量组排成矩阵A:
(列向量组时)或(行向量组时)(*)
将列(或行)向量组排成矩阵A如(*)式,并用初等行(或列)变换化A为行(或列)阶梯形矩阵G(或),则G(或)中非零行(或列)的个数即等于向量组的秩,且是该向量组的一个极大线性无关组,其中是G(或)中各非零行(或列)的第1个非零元素所在的列(或行)。
二.C语言程序算法
#include <stdio.h> #include <stdlib.h> #include <math.h> void main() { int i,j,k; int s,n;//s个n维向量组 int groupNum=0;//极大线性无关组个数 double **array,**deterArray; double **result; int *groupPosition; void printfDouble2Dimension(int s, int n, double **array); void printfInt1Dimension(int n, int *array); void primaryRowChange(int s, int n, double **array); int getGreatLinerlyIndependentGroup(int s, int n, double **array, int *result); void calcOrthogonalization(int s, int n, double **result); printf("请输入向量个数S:"); scanf("%d",&s); printf("请输入向量维度N:"); scanf("%d",&n); array=(double**)malloc(s*sizeof(double*)); deterArray=(double**)malloc(n*sizeof(double*)); groupPosition =(int*)malloc(s*sizeof(int)); for(i=0;i<n;i++) { deterArray[i]=(double*)malloc(n*sizeof(double)); } for(i=0;i<s;i++) *(groupPosition+i)=-1; // for(i=0;i<s;i++) { array[i]=(double*)malloc(n*sizeof(double)); printf("请输入第%d个向量:",i+1); for(j=0;j<n;j++) { scanf("%lf",*(array+i)+j); *(*(deterArray+j)+i) = *(*(array+i)+j); } } printf("输入向量行矩阵: "); printfDouble2Dimension(s,n,array); printf("输入向量列矩阵: "); printfDouble2Dimension(n,s,deterArray); primaryRowChange(n,s,deterArray); printf("列矩阵初等行变换后: "); printfDouble2Dimension(n,s,deterArray); groupNum = getGreatLinerlyIndependentGroup(n,s,deterArray,groupPosition); result = (double**)malloc(groupNum*sizeof(double*)); for(i=0;i<groupNum;i++) { if(*(groupPosition+i)!=-1) { result[i] = (double*)malloc(n*sizeof(double)); result[i] = *(array+ *(groupPosition+i)); } } printf("极大线性无关组: "); printfDouble2Dimension(groupNum,n,result); calcOrthogonalization(groupNum,n,result); printf("等价正交单位向量组: "); printfDouble2Dimension(groupNum,n,result); system("pause"); } //初等行变换 void primaryRowChange(int s, int n, double **array) { int i,j,k,ii,kk,flag; double temp; for(i=0,j=0;i<s-1;i++,j++)//s行,最外围只需要变换s-1 { ii=i; //如果行的首元为0,向下查找一个不为0的,然后换行 if(*(*(array+i)+j) == 0) { flag=0; for(k=i+1;k<s;k++) { if(*(*(array+k)+j)!=0)//第k行与第i行交换 { for(kk=j;kk<n;kk++) { temp=*(*(array+k)+kk); *(*(array+k)+kk) = *(*(array+i)+kk); *(*(array+i)+kk) = temp; } flag =1; break; } } //判断是交换成功,如果没有成功,则i-- if(!flag) { i--; continue; } i--; j--; continue; } for(;ii<s-1;ii++) { if(*(*(array+ii+1)+j)==0) continue; temp =-*(*(array+ii+1)+j) / *(*(array+i)+j); for(k=j;k<n;k++) *(*(array+ii+1)+k) += *(*(array+i)+k) * temp; } } } //获取极大线性无关组位置及个数 int getGreatLinerlyIndependentGroup(int s, int n, double **array, int *result) { int i,j,num=0; for(i=0;i<s;i++) { for(j=0;j<n;j++) { if(*(*(array+i)+j)!=0) { *(result + num++)=j; break; } } } return num; } //计算正交单位向量组 void calcOrthogonalization(int s, int n, double **result) { int i,j,k; double **tempArray ,temp; double sqrt(double x); double getInnerProduct(int n,double *array1, double *array2); for(i=0;i<s;i++) { tempArray = (double**)malloc(i*sizeof(double*)); for(j=0;j<i;j++) { tempArray[j] = (double*)malloc(n*sizeof(double)); temp = getInnerProduct(n,*(result+i),*(result+j)) / getInnerProduct(n,*(result+j),*(result+j)); for(k=0;k<n;k++) { *(*(tempArray+j)+k) = temp * *(*(result+j)+k); } } for(j=0;j<i;j++) { for(k=0;k<n;k++) *(*(result+i)+k) -= *(*(tempArray+j)+k); } } //单位化 for(i=0;i<s;i++) { temp = getInnerProduct(n,*(result+i),*(result+i)); temp = sqrt(temp); for(j=0;j<n;j++) { *(*(result+i)+j) /= temp; } } } //计算两个向量的内积 double getInnerProduct(int n, double *array1, double *array2) { int i; double result=0; for(i=0;i<n;i++) result += *(array1+i) * *(array2+i); return result; } //print array void printfDouble2Dimension(int s, int n, double **array) { int i,j; for(i=0;i<s;i++) { for(j=0;j<n;j++) { printf("%6.2lf",*(*(array+i)+j)); } printf(" "); } } void printfInt1Dimension(int n, int *array) { int i; for(i=0;i<n;i++) { printf("%4d",*(array+i)); } printf(" "); }
三.程序截图
1> p219-例1
2> 3.5-9
3> test1
4> test2