求逆矩阵程序(c语言)

这个程序是大二上学期中秋前后完成的一个程序,是学完c语言和数据结构后写的第一个小项目

1.方法

用于转化的arr数组是一个行数为n(阶数),列数为2n的数组,前n列用于储存原数组,后n列在原数组转化的过程做相应的变换,最终左边n列化为最简型后,右边n列即为所求的逆矩阵

2.转化过程

2.1化为阶梯型

2.1.1 将原数组存入变换数组

//把矩阵存入新数组
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
            arr[i][j]=a[i][j];
    for (int i=0;i<n;i++){
        arr[i][i+n]=1;
    }

2.1.2 遍历每一行,将矩阵化为上三角型(阶梯型)

//遍历每一行,将矩阵化为上三角型(阶梯型) 
    for (int i=0;i<n-1;i++) { 
       	int m=0;
    	while(arr[i][i]==0&&m<n-1-i){//如果i行i列为0,将该行放到末尾,其他行前移一行 
    		//第i行的第i个为0,就将第i行放到末尾,其他行前移一行
    		for(int j=i;j<2*n;j++){
    			double temp=arr[i][j];
    			for(int k=i;k<n-1;k++){
    				arr[k][j]=arr[k+1][j];
				}
				arr[n-1][j]=temp;
			}
			m++;
			if(m==n-1-i&&arr[i][i]==0){//i行以后任意行第i列都为0:秩小于n无逆矩阵 
				printf("该矩阵无逆矩阵\n");
				return; 
			}
		}
		
		//将第i行的主元化为1 
		double flag=arr[i][i];flag:该行需要除以的数
        for (int j = i; j < 2 * n; j++) {
            arr[i][j] /= flag;
        }
         
        //将主元所在列其他元素化为0
        for (int k = i+1; k<n;k++){//第i+1行到第n行的第i个元素化为0
        	double sign=arr[k][i];

            for (int j=i;j<2*n;j++)
            arr[k][j]=arr[k][j]-arr[i][j]*sign;
        }
       
    }

2.1.3计数矩阵的秩(秩小于n没有逆矩阵)

//第n行第n个不为1:将该列除以该数,化为1;
	int result=(arr[n-1][n-1]==0);
    if(result){
    	printf("该矩阵无逆矩阵\n");
    	return;
    }
	else if(arr[n-1][n-1]!=1){

		double flag=arr[n-1][n-1];
		//将第n行第n个元素化为1
        for (int j = n-1; j < 2 * n; j++) {
            arr[n-1][j] /= flag;
        }
	}

2.2阶梯型化为最简型

//将阶梯型化为最简型,arr数组的11-20列即为逆矩阵 
	for(int i=n-1;i>0;i--){
		for(int k=i-1;k>=0;k--){
			double flag=arr[k][i];
			for(int j=0;j<2*n;j++){
				arr[k][j]=arr[k][j]-arr[i][j]*flag;
			}
		}
	}

2.3得到逆矩阵

//将逆矩阵存入a数组的第n到2n列 
	for(int i=0;i<n;i++){
		for(int j=n;j<2*n;j++){
			a[i][j]=arr[i][j];
		}
	}

3.运行截图

 

4.完整代码

#include<stdio.h>
#define row 10
#define col 20

//初始化二维数组 
void init(double arr[row][col]){
	for(int i=0;i<10;i++){
		for(int j=0;j<20;j++){
			arr[i][j]=0;
		}
	}
}

/**********************show原矩阵******************************/
void showY(double arr[row][col],int n){//n为矩阵阶数 
	printf("---------------------------------------------\n"); 
    for (int i=0;i<n;i++){
        for (int j=0;j<n;j++){
        	printf("| %7.3lf\t",arr[i][j]);
        }
        printf("|\n\n");
    }
	printf("---------------------------------------------\n");
}

/**********************show逆矩阵******************************/
void showN(double arr[row][col],int n){
	printf("---------------------------------------------\n");
    for (int i=0;i<n;i++){
        for (int j=n;j<2*n;j++){
        	printf("| %7.3lf\t",arr[i][j]);
        }
        printf("|\n\n");
    }
	printf("---------------------------------------------\n");
}

/**********************化为逆矩阵******************************/
/*
a:输入输出的数组
arr:中间数组 
n:矩阵阶数
*/ 
void toInverse(double a[row][col],double arr[row][col],int n){
	printf("原矩阵:\n");
	showY(a,n);//输出原矩阵 
	
/*--------化为阶梯型--------*/

    //n为矩阵阶数
    //把矩阵存入新数组
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
            arr[i][j]=a[i][j];
    for (int i=0;i<n;i++){
        arr[i][i+n]=1;
    }
   
	//遍历每一行,将矩阵化为上三角型(阶梯型) 
    for (int i=0;i<n-1;i++) { 
       	int m=0;
    	while(arr[i][i]==0&&m<n-1-i){//如果i行i列为0,将该行放到末尾,其他行前移一行 
    		//第i行的第i个为0,就将第i行放到末尾,其他行前移一行
    		for(int j=i;j<2*n;j++){
    			double temp=arr[i][j];
    			for(int k=i;k<n-1;k++){
    				arr[k][j]=arr[k+1][j];
				}
				arr[n-1][j]=temp;
			}
			m++;
			if(m==n-1-i&&arr[i][i]==0){//i行以后任意行第i列都为0:秩小于n无逆矩阵 
				printf("该矩阵无逆矩阵\n");
				return; 
			}
		}
		
		//将第i行的主元化为1 
		double flag=arr[i][i];flag:该行需要除以的数
        for (int j = i; j < 2 * n; j++) {
            arr[i][j] /= flag;
        }
         
        //将主元所在列其他元素化为0
        for (int k = i+1; k<n;k++){//第i+1行到第n行的第i个元素化为0
        	double sign=arr[k][i];

            for (int j=i;j<2*n;j++)
            arr[k][j]=arr[k][j]-arr[i][j]*sign;
        }
       
    }
    
    
    
    //判断:阶梯型(n阶矩阵)第n行第n个为0:无逆矩阵; 
	//第n行第n个不为1:将该列除以该数,化为1;
	int result=(arr[n-1][n-1]==0);
    if(result){
    	printf("该矩阵无逆矩阵\n");
    	return;
    }
	else if(arr[n-1][n-1]!=1){

		double flag=arr[n-1][n-1];
		//将第n行第n个元素化为1
        for (int j = n-1; j < 2 * n; j++) {
            arr[n-1][j] /= flag;
        }
	}

	
/*--------求出逆矩阵--------*/
	//将阶梯型化为最简型,arr数组的11-20列即为逆矩阵 
	for(int i=n-1;i>0;i--){
		for(int k=i-1;k>=0;k--){
			double flag=arr[k][i];
			for(int j=0;j<2*n;j++){
				arr[k][j]=arr[k][j]-arr[i][j]*flag;
			}
		}
	}

	
	//将逆矩阵存入a数组的第n到2n列 
	for(int i=0;i<n;i++){
		for(int j=n;j<2*n;j++){
			a[i][j]=arr[i][j];
		}
	}

	
	//输出逆矩阵 
	printf("该矩阵的逆矩阵:\n");
	showN(a,n);//输出逆矩阵 
	//将矩阵存入文件 
	FILE* fp=NULL;
	fp=fopen("d:\\逆矩阵.txt","w");
	for(int i=0;i<n;i++){
		for(int j=n;j<2*n;j++){
			fprintf(fp,"%-14.3lf",arr[i][j]);
		}
		fprintf(fp,"\n");
	}
	
}

int main(){
	 int i,j,m,n; 
	 double arr[row][col];//开辟一个新数组以进行临时储存
	 init(arr);//初始化临时数组 
	 printf("请输入行数:");
	 scanf("%d",&m) ;
	 printf("请输入列数:");
	 scanf("%d",&n) ;
	 double a[row][col];//定义存储矩阵的数组
	 init(a);//初始化数组 
	 
 	 FILE* fp;
	 fp = fopen("d:\\data.txt", "rb");//打开文件,如果文件不存在,则结束程序
	 
	 if (fp == NULL)
	 {
	  printf("File not exist!");
	  return -1;
	 }
 
 //读取文件中的值,依次保存到二维数组的各元素中
 for (  i=0; i < m; i++)
 {
  for ( j=0; j < n; j++)
  {
   fscanf(fp, "%lf", &a[i][j]);//将文件中的值读到arr[][]数组中
  }
 }
 fclose(fp); 
 
 if(m==n){
 	toInverse(a,arr,n);
 }else{
 	printf("原矩阵:\n---------------------------------------------\n");
 	for(i=0;i<m;i++){
 		for(j=0;j<n;j++){
 			printf("| %7.3lf\t",a[i][j]);
		 }
		 printf("\n\n");
	 }
	 printf("---------------------------------------------\n");
 	printf("该矩阵无逆矩阵\n");
 } 
	return 0;
} 

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
### 回答1: 数值计算矩阵求逆是一种重要的数学计算过程,可以使用C语言编程实现。下面是一个基本的矩阵求逆算法的程序示例: ```c #include <stdio.h> // 定义矩阵大小 #define N 3 // 打印矩阵 void printMatrix(float matrix[N][N]) { for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { printf("%.2f ", matrix[i][j]); } printf("\n"); } printf("\n"); } // 矩阵求逆 void matrixInverse(float matrix[N][N]) { float identity[N][N]; float ratio, temp; int i, j, k; // 构造单位矩阵 for(i = 0; i < N; i++) { for(j = 0; j < N; j++) { if(i == j) { identity[i][j] = 1; } else { identity[i][j] = 0; } } } // 高斯-约当消元法逆 for(i = 0; i < N; i++) { ratio = matrix[i][i]; for(j = 0; j < N; j++) { matrix[i][j] /= ratio; identity[i][j] /= ratio; } for(k = 0; k < N; k++) { if(k != i) { ratio = matrix[k][i]; for(j = 0; j < N; j++) { matrix[k][j] -= ratio * matrix[i][j]; identity[k][j] -= ratio * identity[i][j]; } } } } printf("逆矩阵:\n"); printMatrix(identity); } int main() { float matrix[N][N] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; printf("原始矩阵:\n"); printMatrix(matrix); matrixInverse(matrix); return 0; } ``` 该程序C语言中实现了一个基本的矩阵求逆算法。它使用高斯-约当消元法来逆矩阵,首先构造一个单位矩阵,然后通过一系列的消元操作将原始矩阵转化为单位矩阵,此时单位矩阵所对应的就是原始矩阵逆矩阵。最后,通过调用`matrixInverse`函数,传入一个3x3大小的矩阵,即可计算并输出逆矩阵。 ### 回答2: 数值计算矩阵求逆是一种常见的数值算法,可以使用C语言编写。以下是一个大致的程序示例: #include <stdio.h> #define N 3 // 矩阵的维度 // 函数声明 int inverseMatrix(double A[][N], double invA[][N]); void printMatrix(double matrix[][N]); int main() { // 定义原始矩阵A和逆矩阵invA double A[N][N] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; double invA[N][N]; // 调用逆函数 int success = inverseMatrix(A, invA); if (success) { printf("矩阵A的逆矩阵为:\n"); printMatrix(invA); } else { printf("矩阵A不可逆!\n"); } return 0; } // 矩阵逆矩阵 int inverseMatrix(double A[][N], double invA[][N]) { // 请在这里实现计算矩阵逆矩阵的算法 // 返回是否成功逆,成功返回1,失败返回0 return 1; } // 打印矩阵 void printMatrix(double matrix[][N]) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { printf("%f ", matrix[i][j]); } printf("\n"); } } 该程序主要包含了两个函数:inverseMatrix和printMatrix。 invertMatrix函数负责计算给定矩阵逆矩阵。在该函数中,你需要实现逆矩阵的具体算法。根据不同的数值计算算法,计算逆矩阵有多种方法,比如高斯-约当消元法、LU分解等。根据你的具体需选择合适的方法来计算逆矩阵。该函数需要返回1表示成功逆,返回0表示矩阵不可逆。 printMatrix函数用于打印矩阵。你可以根据需要对打印的格式进行修改。 在main函数中,我们定义了一个3x3的矩阵A,并预留了一个与A维度相同的矩阵invA用于存储逆矩阵。调用inverseMatrix函数计算矩阵A的逆矩阵,并根据计算是否成功进行相应的输出。 ### 回答3: 数值计算矩阵求逆是一种常见的计算矩阵逆的算法,其中最常用的算法就是高斯-约当消元法。下面是用C语言实现的一个简单的矩阵求逆算法: ```c #include <stdio.h> #define SIZE 3 void printMatrix(double matrix[SIZE][SIZE]); void swap(double* a, double* b); void inverseMatrix(double matrix[SIZE][SIZE], double inverse[SIZE][SIZE]); int main() { double matrix[SIZE][SIZE] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; double inverse[SIZE][SIZE]; inverseMatrix(matrix, inverse); printf("原始矩阵:\n"); printMatrix(matrix); printf("逆矩阵:\n"); printMatrix(inverse); return 0; } void printMatrix(double matrix[SIZE][SIZE]) { for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { printf("%f ", matrix[i][j]); } printf("\n"); } printf("\n"); } void swap(double* a, double* b) { double temp = *a; *a = *b; *b = temp; } void inverseMatrix(double matrix[SIZE][SIZE], double inverse[SIZE][SIZE]) { // 初始化单位矩阵 for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { inverse[i][j] = (i == j) ? 1 : 0; } } for (int i = 0; i < SIZE; i++) { // 如果矩阵[i][i]为0,交换该行和下一行 if (matrix[i][i] == 0) { for (int j = i + 1; j < SIZE; j++) { if (matrix[j][i] != 0) { for (int k = 0; k < SIZE; k++) { swap(&matrix[i][k], &matrix[j][k]); swap(&inverse[i][k], &inverse[j][k]); } break; } } } // 将主对角线上的元素变为1 double factor = matrix[i][i]; for (int j = 0; j < SIZE; j++) { matrix[i][j] /= factor; inverse[i][j] /= factor; } // 消元得到上三角矩阵 for (int j = i + 1; j < SIZE; j++) { double factor = matrix[j][i]; for (int k = 0; k < SIZE; k++) { matrix[j][k] -= factor * matrix[i][k]; inverse[j][k] -= factor * inverse[i][k]; } } } for (int i = SIZE - 1; i >= 0; i--) { // 消元得到对角线为1的矩阵 for (int j = i - 1; j >= 0; j--) { double factor = matrix[j][i]; for (int k = 0; k < SIZE; k++) { matrix[j][k] -= factor * matrix[i][k]; inverse[j][k] -= factor * inverse[i][k]; } } } } ``` 上述程序中,我们定义了一个`printMatrix`函数来打印矩阵,一个`swap`函数用于交换两个数的值。`inverseMatrix`函数用于计算矩阵的逆。首先,我们初始化一个单位矩阵作为逆矩阵的初始值。然后,通过高斯-约当消元法来将原始矩阵转化为上三角矩阵,并且将对应的操作应用到逆矩阵上。最后,我们再次应用高斯-约当消元法将上三角矩阵变为对角线为1的矩阵,并将对应的操作应用到逆矩阵上。输出结果即为原始矩阵逆矩阵的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

li345376

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值