zoukankan      html  css  js  c++  java
  • 矩阵的逆 C 语言 算法二

    矩阵的逆 C 语言 算法二

      一.初等变换法

      如果矩阵A和B互逆,则AB=BA=E。由条件AB=BA以及矩阵乘法的定义可知,矩阵A和B都是方阵。再由条件AB=E以及定理“两个矩阵的乘积的行列式等于这两个矩阵的行列式的乘积”可知,这两个矩阵的行列式都不为0。也就是说,这两个矩阵的秩等于它们的级数(或称为阶,也就是说,A与B都是n	imes n方阵,且rank(A) = rank(B) = n)。换句话说,这两个矩阵可以只经由初等行变换,或者只经由初等列变换,变为单位矩阵。

      因为对矩阵A施以初等行变换(初等列变换)就相当于在A的左边(右边)乘以相应的初等矩阵,所以我们可以同时对A和E施以相同的初等行变换(初等列变换)。这样,当矩阵A被变为E时,E就被变为A的逆阵B。

      二.算法

    #include <stdio.h>
    #include <stdlib.h>
    
    void main()
    {
        int i,j,res;
        int dimension;
        double **array,**deterArray, **result, *temp;
    
        double primaryRowChange(int s, int n, double **array);
        void primaryRowChange2(int s, int n, double **array);
        void printfDouble2Dimension(int s, int n, double **array);
    
        printf("请输入方阵的阶数N:");
        scanf("%d",&dimension);
        
        array=(double**)malloc(dimension*sizeof(double*));
        deterArray=(double**)malloc(dimension*sizeof(double*));
        result =(double**)malloc(dimension*sizeof(double*));
        
        //循环输入方阵
        for(i=0;i<dimension;i++)
        {
            temp=(double*)malloc(dimension*sizeof(double));
            deterArray[i]=(double*)malloc(2*dimension*sizeof(double));
            result[i]=(double*)malloc(dimension*sizeof(double));
    
            printf("请输入方阵的第%d行:",i+1);
            for(j=0;j<dimension;j++)
                scanf("%lf",temp+j);
            array[i]=temp;
        }
    
        for(i=0;i<dimension;i++)
        {
            for(j=0;j<2*dimension;j++)
            {
                if(j<dimension)
                {
                    *(*(deterArray+i)+j) = *(*(array+i)+j);
                    continue;
                }
                //合并单位矩阵
                if(j-dimension ==i)//对角线为1,其余为0
                    *(*(deterArray+i)+j) = 1;
                else 
                    *(*(deterArray+i)+j) = 0;
            }
        }
        
        printf("输入矩阵如下:
    ");
        printfDouble2Dimension(dimension,dimension,array);
        
        printf("合并单位矩阵如下:
    ");
        printfDouble2Dimension(dimension,2*dimension,deterArray);
    
        res = primaryRowChange(dimension,2*dimension,deterArray);
        printf("初等变换之后如下:
    ");
        printfDouble2Dimension(dimension,2*dimension,deterArray);
    
        if(res==0)
        {
            printf("矩阵行列式的值为0,矩阵无逆矩阵.");
        }
        else
        {        
            primaryRowChange2(dimension,2*dimension ,deterArray);
    
            printf("继续变为单位矩阵之后:
    ");
            printfDouble2Dimension(dimension,2*dimension,deterArray);
    
            for(i=0;i<dimension;i++)
            {
                for(j=dimension;j<2*dimension;j++)
                    *(*(result+i)+j-dimension) = *(*(deterArray +i)+j);
            }
    
            printf("矩阵的逆如下:
    ");
            printfDouble2Dimension(dimension,dimension,result);
        }
        system("pause");
    }
    
    //初等行变换
    double primaryRowChange(int s, int n, double **array)
    {
        int i,j,k,ii,kk,flag;
        double temp,result=1;
        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;
                    
            }
        }
    
        //计算行列式的值 
        for(i=0;i<s;i++)
        {
            result *= *(*(array+i)+j);
        }
        return result;
    }
    
    void primaryRowChange2(int s, int n, double **array)
    {
        int i,j,k,l;
        double temp;
        for(i=s-1,j=s-1;i>=0;i--,j--)
        {
            if(*(*(array+i)+i)!=1)
            {
                temp = 1 / *(*(array+i)+i);
                for(k=0;k<n;k++)
                    *(*(array+i)+k) *= temp;
            }
    
            for(k=i-1;k>=0;k--)
            {
                if(*(*(array+k)+j) ==0)
                    continue;
                temp = - *(*(array+k)+j) / *(*(array+i)+j);
    
                for(l=0;l<n;l++)
                    *(*(array+k)+l) += temp * *(*(array+i)+l);
            }
        }
    }
    
    
    //打印数组
    void printfDouble2Dimension(int s, int n, double **array)
    {
        //printf("%d,%d",s,n);
        int i,j;
        for(i=0;i<s;i++)
        {
            for(j=0;j<n;j++)
            {
                printf("%6.2lf",*(*(array+i)+j));    
            }
            printf("
    ");
        }
    }

      三.程序截图

    1>  p211-例2

     

    2>  3.4-5.1

    3>  3.4-5.2

  • 相关阅读:
    20169210《Linux内核原理与分析》第十周作业
    Collabtive 系统 SQL 注入实验(补充)
    20169211《Linux内核原理与分析》课程总结
    20169211《Linux内核原理及分析》第十二周作业
    20169211 《Linux内核原理与分析》第十一周作业
    20169211《Linux内核原理与分析》 第十周作业
    20169211《Linux内核原理与分析》 第九周作业
    20169210《Linux内核原理与分析》第八周作业
    20169211《linux内核原理与分析》第七周作业
    20169211《Linux内核原理与分析》第六周作业
  • 原文地址:https://www.cnblogs.com/tianzhenyun/p/4543604.html
Copyright © 2011-2022 走看看