求向量组的等价正交单位向量组-施密特正交化 C 语言 算法

求向量组的等价正交单位向量组-施密特正交化 C 语言 算法

  一.施密特正交化

首先需要确定已有基底向量的顺序,不妨设为{ oldsymbol{v}_1,ldots, oldsymbol{v}_{n} }。Gram-Schmidt正交化的过程如下:

  oldsymbol{eta}_1 = oldsymbol{v}_1,   oldsymbol{eta}_1 = {oldsymbol{eta}_1 over |oldsymbol{eta}_1|}
  oldsymbol{eta}_2 
         = oldsymbol{v}_2-langle oldsymbol{v}_2, oldsymbol{eta}_1 
angle oldsymbol{eta}_1,   oldsymbol{eta}_2 = {oldsymbol{eta}_2 over |oldsymbol{eta}_2|}
  oldsymbol{eta}_3 
            = oldsymbol{v}_3 -
              langle oldsymbol{v}_3, oldsymbol{eta}_1 
angle oldsymbol{eta}_1 -
              langle oldsymbol{v}_3, oldsymbol{eta}_2 
angle oldsymbol{eta}_2 , 
       oldsymbol{eta}_3 = {oldsymbol{eta}_3 over |oldsymbol{eta}_3|}
  vdots   vdots
  oldsymbol{eta}_n = oldsymbol{v}_n-sum_{i=1}^{n-1}langle oldsymbol{v}_n, oldsymbol{eta}_i 
angle oldsymbol{eta}_i,   oldsymbol{eta}_n = {oldsymbol{eta}_nover|oldsymbol{eta}_n|}

这样就得到mathrm{span}{ oldsymbol{v}_1, ldots , oldsymbol{v}_n }上的一组正交基{ oldsymbol{eta}_1, ldots , oldsymbol{eta}_n },以及相应的标准正交基{ oldsymbol{eta}_1, ldots , oldsymbol{eta}_n }

  给定的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

原文地址:https://www.cnblogs.com/tianzhenyun/p/4545322.html