zoukankan      html  css  js  c++  java
  • 求向量组的等价正交单位向量组-施密特正交化 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

  • 相关阅读:
    ACM XXX1
    最大公约数算法
    struct和typedef struct
    PKU 1012
    素数算法3种
    ZOJ 1088
    学习ios开发计划书
    iphone系统架构以及各层提供的主要服务
    iOS 界面元素尺寸
    开发手机版网站有哪些前端框架?
  • 原文地址:https://www.cnblogs.com/tianzhenyun/p/4545322.html
Copyright © 2011-2022 走看看