求向量組的等價正交單位向量組-施密特正交化 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("輸入向量行矩陣:\n"); printfDouble2Dimension(s,n,array); printf("輸入向量列矩陣:\n"); printfDouble2Dimension(n,s,deterArray); primaryRowChange(n,s,deterArray); printf("列矩陣初等行變換后:\n"); 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("極大線性無關組:\n"); printfDouble2Dimension(groupNum,n,result); calcOrthogonalization(groupNum,n,result); printf("等價正交單位向量組:\n"); 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("\n"); } } void printfInt1Dimension(int n, int *array) { int i; for(i=0;i<n;i++) { printf("%4d",*(array+i)); } printf("\n"); }
三.程序截圖
1> p219-例1
2> 3.5-9
3> test1
4> test2