C语言实现(不同阶数的)矩阵求逆(已用350个2-8阶的矩阵测试)

1、生成测试文件的代码

测试文件:

fp = fopen("Array_Test_Document.txt","r");

文件名为Array_Test_Document.txt  ,如果想要更换自己测试数据,仅需要在同一个目录下生成一个名为Array_Test_Document.txt 的文件,在文件中写入矩阵数据,每行为一个矩阵,每个元素之间用空格隔开。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<math.h>

//该代码是创建了一个文件,文件的内容是2-8阶的可逆矩阵,每个阶数的矩阵各50个。
//文件的每一行都是一个矩阵,每个矩阵的元素之间用空格分开。


void Write_to_file(FILE *fp);
float HlsCalculate(float **x,const int row,const int column);
int main(){
	FILE *fp;
	int i,j,k;

	//设置随机数
	srand((unsigned)time(NULL));
	
	fp = fopen("Array_Test_Document.txt","w");
	if (fp != NULL){
		Write_to_file(fp);
    	}else{
		printf("文件打开失败:\n");
	}

    fclose(fp);
    return 0;
}



//求行列式
float HlsCalculate(float **x,const int row,const int column){
	float hls = 0;
	float **c;
	int i,j,k;


	//动态分配二维数组
	c = (float **)malloc(sizeof(float *) * row);
	//分配列数
	for(j = 0;j < row;j++){
		c[j] = (float *)malloc(sizeof(float) * column);
	}

	//1阶2阶行列式计算
	if(row == 1){
		return x[0][0];
	}
	if(row == 2){
		float z = x[0][0]*x[1][1] - x[0][1]*x[1][0];
		//printf("2dimention hls= %f\n",k);
		return z;
	}



	//3阶以上求行列式
	for(j = 0;j < row ;j++){
		for(i = 0 ; i < column - 1;i++){
			for(k = 0 ; k < row - 1;k++){
				if(k<j)c[i][k] = (float)x[i+1][k];
				if(k>=j)c[i][k] = (float)x[i+1][k+1];
			}
		}
		hls += pow(-1,j)*x[0][j]*HlsCalculate(c,row-1,column-1);
	}
	//printf("原矩阵的行列式 = %f\n",hls);
	return hls;
}


//将行列式不为0的矩阵写入文件
void Write_to_file(FILE *fp){


	int i,j,k;
	i = 0;
	
	//矩阵的阶数
	int matrix_size;

	//接受随机数值的临时变量
	int  a;

	//count 用于记录每个维度的矩阵写入文件的个数
	int count;
	count = 0;


	do{
		//int matrix_size;
		//设置生成矩阵的维度
		matrix_size = 2;
		matrix_size += count / 50;
		
		 if(matrix_size == 9){
			break;
		}
		

		//动态分配一个二维数组
		float **p1;
		//分配行数
	        p1 = (float **)malloc(sizeof(float *) * matrix_size);
		//分配列数
		for(j = 0;j < matrix_size;j++){
			p1[j] = (float *)malloc(sizeof(float) * matrix_size);
		}
			
		//给数组中放入随机值
		for(j = 0;j < matrix_size;j++){
			for(k = 0;k < matrix_size;k++){
				//rand()%10 是设置数组中元素的值为0-10之间
				a = rand()%10;
				p1[j][k] = a;
			}
		}


		//求矩阵的行列式,如果行列式的绝对值在1 - pow(10,matrix_size)之间则将该数据写入文件
		//determinant 用于接受矩阵的行列式值
		float determinant;
		determinant = HlsCalculate(p1,matrix_size,matrix_size);
		if((determinant >= -pow(10,matrix_size) && determinant <= -1) ||
			(determinant <= pow(10,matrix_size) && determinant >= 1)){
			count ++;
			for(j = 0;j < matrix_size;j++){
				for(k = 0 ; k < matrix_size;k++){
					fprintf(fp,"%.2f",p1[j][k]);
					fprintf(fp," ");
				}
			}
			fputc('\n',fp);
		}
		free(p1);

	// matrix_size < 9 是指写入的可逆矩阵维度在2-8之间
	}while(matrix_size  < 9);  
    	
	


}

2、部分测试文件截图

3、C代码实现矩阵求逆,用生成的测试文件测试代码

#include<stdio.h>
#include<math.h>
#include<stdlib.h>

void inverseArr(float **inverse,float **result,int N);
float HlsCalculate(float **x,const int row,const int column);

void mulMatrix(float **a,float **b,const int row);

int main(){

        
	int i,j,k,count;	

	//打开文件
	FILE *fp;
	fp = fopen("Array_Test_Document.txt","r");
	if(fp == NULL){
		printf("文件打开失败:");
		return -1;
	}

	count =0;
	while(++count <= 350){
	
		int row = 2 + (count-1)/50;
		int column = 2 + (count-1)/50;
		int i,j,k;


		//(0000000)动态分配一个二维数组,增广矩阵
		float **inverse;
        	//分配行
		inverse = (float **)malloc(sizeof(float *) * row); 
		//分配列数                 
		for(j = 0;j < row;j++){
	        	inverse[j] = (float *)malloc(sizeof(float)
			       	* column * 2);
		}
		

		//(1111111)动态分配一个二维数组,用于保存计算得到的逆矩阵
		float **ni_matrix;
        	//分配行
		ni_matrix = (float **)malloc(sizeof(float *) * row); 
		//分配列数                 
		for(j = 0;j < row;j++){ 
        		ni_matrix[j] = (float *)malloc(sizeof(float)* column );
		}


		//(2222222)动态分配一个二维数组,用于保存测试文件中的矩阵元素
		float **a;
        	//分配行
		a = (float **)malloc(sizeof(float *) * row); 
		//分配列数                 
		for(j = 0;j < row;j++){ 
        		a[j] = (float *)malloc(sizeof(float)* column );
		}


		//读取文件中的数据
		for(i = 0 ; i < row;i++){
			for(j = 0;j < column; j++){
				fscanf(fp,"%f",&a[i][j]);
			}
		}



		//打印原矩阵
		printf("第 %d 个矩阵\n",count);
		printf("==========原矩阵==========\n");
		for( i = 0; i < row ;i++){
			for(j = 0 ; j < column ; j++){
				printf("%6.2f ",a[i][j]);
			}
			printf("\n");
		}



		//求原矩阵的行列式,判断是否可逆
		//if行列式==0 则不可逆
		float  hls;
		hls = HlsCalculate(a,row,column);
		//printf("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&7&&&&行列式 = %.2f\n",hls);
		if(hls == 0){
			printf("该方阵的行列式==0,不可逆\n");
			continue;
		}


		//初始化增广矩阵
		//float inverse[N][2*N] = {0};
		for(i = 0 ; i < row;i++){
			for(j = 0 ; j < 2 * column;j++){
				if(i < row && j < row){
					inverse[i][j] = a[i][j];
				}else if(i + row== j){
					inverse[i][j] = 1.00;
				}else {
				
					inverse[i][j] = 0.00;
				}
			}
		}
	


		//求逆矩阵,并打印
		inverseArr(inverse,ni_matrix,row);

		//打印
		printf("==========逆矩阵==========\n");
		for( i = 0; i < row ;i++){
			for(j = 0 ; j < row ; j++){
				printf("%6.2f ",ni_matrix[i][j]);
			}
			printf("\n");
		}

		//原矩阵与逆矩阵的乘法运算,并输出结果矩阵
		mulMatrix(a,ni_matrix,row);

		free(a);
		free(inverse);
		free(ni_matrix);

		}
	
}


//矩阵乘法

void mulMatrix(float **a,float **b,const int row){
	int k ,i,j,p;
	k = row;
	int len = 0;

	//value1 用于保存矩阵的某一行和一列元素的相乘积的和
	float value1 = 0;

	//动态分配一个二维数组,用于保存矩阵乘法的结果
	float **c;
        //分配行
	c = (float **)malloc(sizeof(float *) * row); 
	//分配列数                 
	for(j = 0;j < row;j++){ 
        	c[j] = (float *)malloc(sizeof(float)* row );
		}
/*
	for(i = 0 ; i < k ;i++){
	
		for(j = 0 ;j < k ;j++){
		
			c[i][j] = 0;
		}
	}

	*/
	for( i = 0; i < k;i++){
		for( j = 0;j < k ;j++){
			for( p = 0 ; p < k;p++){
			value1 += a[i][p] * b[p][j];
			}
			c[i][len++] = value1;
			value1 = 0;
			if(len == k){
				len =0;
			} 
		}	
	}	

	//打印矩阵乘法的结果
	printf("====================原矩阵与逆矩阵的乘积================\n");
	for(int i = 0; i < k;i++){
		for(int j = 0;j < k ;j++){
			printf("%6.2f ",c[i][j]);
		} 
		printf("\n");
		
	}

	free(c);
}




//求行列式
float HlsCalculate(float **x,const int row,const int column){
	float hls = 0;

	int i ,j , k ;
	//动态分配一个二维数组
	float **c;
	c = (float **)malloc(sizeof(float *) * row); 
	for(j = 0;j < row;j++){
        	c[j] = (float *)malloc(sizeof(float)
			       	* column);
	}

	if(row == 1){
		return x[0][0];
	}
	if(row == 2){
		float k = x[0][0]*x[1][1] - x[0][1]*x[1][0];
		//printf("2dimention hls= %f\n",k);
		return k;
	}
	//求行列式
	for(j = 0;j < row ;j++){
		for(i = 0 ; i < column - 1;i++){
			for(k = 0 ; k < row - 1;k++){
				if(k<j)c[i][k] = x[i+1][k];
				if(k>=j)c[i][k] = x[i+1][k+1];
			}
		}
		hls += pow(-1,j)*x[0][j]*HlsCalculate(c,row-1,column-1);
	}
	//printf("原矩阵的行列式 = %f\n",hls);
	free(c);
	return hls;
}




//求逆
void inverseArr(float **inverse,float **result,int N){
	int i , j ,k;
	//float temp[2*N] ={0};
	for(i = 0 ;i < N ;i++){
		if(inverse[i][i] == 0){
			for(j = i + 1 ;j < N ;j++){
				if(inverse[j][i] != 0){
					break;
				}
			}
			for(k = 0; k < 2*N;k++){
				inverse[i][k] += inverse[j][k]; 
			}
		}
		float tmp = inverse[i][i];
		//
	       if(inverse[i][i] != 1){
	       		for(k = 0;k<2*N;k++){inverse[i][k] /= tmp;}
	       }
		//化为上三角矩阵
	       for(j=i+1;j<N;j++)
		{
			float tem_2 = inverse[j][i];
			for(k=i;k<2*N;k++)
			{
				inverse[j][k] = inverse[j][k] - tem_2 *
				       	inverse[i][k];
			}
		}
	}



	//将前部分矩阵化为E
	for(i = N-1 ; i >=0 ; i--){
		for(j = N - 1;j>i;j--){	
			if(inverse[i][j] == 0){continue;}
			float tmp = inverse[i][j];
			for(k = j;k< 2*N;k++){inverse[i][k] -= inverse[j][k]*tmp;}
		
		}
	}
	//保存在结果数组中
	for( i = 0; i < N ;i++){
		for(j = 0 ; j < N ; j++){
			result[i][j] = inverse[i][j+N];
		}
	}


} 


4、代码环境Linux

5、部分实验结果截图

 

 gitee路径:

C语言: 0-1,C语言学习路程 - Gitee.com

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 矩阵是一个非常常见的数学问题,可以使用C语言编写程序来解决。 以下是一个简单的矩阵函数的代码实现,该实现使用了高斯-约旦消元法来计算矩阵: ```c #include <stdio.h> #include <stdlib.h> #define N 3 int main() { double matrix[N][2*N]; double temp; int i, j, k; // 读取输入矩阵 printf("请输入一个 %d x %d 的矩阵:\n", N, N); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { scanf("%lf", &matrix[i][j]); } for (j = N; j < 2*N; j++) { if (i == j - N) { matrix[i][j] = 1.0; } else { matrix[i][j] = 0.0; } } } // 高斯-约旦消元 for (i = 0; i < N; i++) { temp = matrix[i][i]; for (j = i; j < 2*N; j++) { matrix[i][j] /= temp; } for (j = 0; j < N; j++) { if (i != j) { temp = matrix[j][i]; for (k = i; k < 2*N; k++) { matrix[j][k] -= temp * matrix[i][k]; } } } } // 输出矩阵 printf("该矩阵为:\n"); for (i = 0; i < N; i++) { for (j = N; j < 2*N; j++) { printf("%lf ", matrix[i][j]); } printf("\n"); } return 0; } ``` 此程序使用了一个3x3的矩阵作为示例输入,可以根据需要更改矩阵的大小和输入方式。程序首先读取输入矩阵,然后使用高斯-约旦消元来计算矩阵,并输出结果。 ### 回答2: 编写一个矩阵的函数,需要先理解矩阵原理。矩阵是指找到一个与原矩阵相乘得到单位矩阵矩阵。以下是用C语言编写矩阵的函数的示例: ```c #include <stdio.h> // 定义矩阵的维度 #define N 3 // 矩阵函数的实现 void matrix_inverse(float A[N][N], float inv[N][N]) { // 计算矩阵的行列式 float det = A[0][0] * (A[1][1] * A[2][2] - A[1][2] * A[2][1]) - A[0][1] * (A[1][0] * A[2][2] - A[1][2] * A[2][0]) + A[0][2] * (A[1][0] * A[2][1] - A[1][1] * A[2][0]); // 检查矩阵是否可 if (det == 0) { printf("矩阵不可\n"); return; } // 计算伴随矩阵矩阵 for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { inv[i][j] = (A[(j + 1) % N][(i + 1) % N] * A[(j + 2) % N][(i + 2) % N] - A[(j + 1) % N][(i + 2) % N] * A[(j + 2) % N][(i + 1) % N]) / det; } } } int main() { float A[N][N] = {{2, 1, 3}, {1, 2, 2}, {3, 1, 4}}; float inv[N][N]; matrix_inverse(A, inv); // 打印矩阵 printf("矩阵:\n"); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { printf("%f ", inv[i][j]); } printf("\n"); } return 0; } ``` 运行以上代码,将输出矩阵A的矩阵。请注意,该实现假设矩阵A是一个3x3矩阵。对于不同维度的矩阵,需要相应调整代码中的 N 定义,并确保矩阵。 ### 回答3: 要用C语言编写一个矩阵函数,需要以下步骤: 1. 首先,定义一个二维数组来表示矩阵。可以使用二维数组来存储矩阵的元素。例如,可以使用`float`类型的二维数组来表示一个浮点数矩阵。 2. 编写一个函数来读取矩阵的元素。可以使用循环来依次读取矩阵的每个元素并将其存储在二维数组中。 3. 编写一个函数来计算矩阵的行列式。可以使用递归的方法来计算行列式的值。若矩阵数为1,则行列式的值为矩阵中唯一的元素;若矩阵数大于1,则可以选择一行或一列,计算每个元素对应的代数余子式,然后依次递归计算每个代数余子式的行列式并将其相加。 4. 编写一个函数来计算矩阵的伴随矩阵。伴随矩阵即将矩阵的每个元素转置后乘以其代数余子式并取负。可以使用循环依次计算每个元素的代数余子式并将其存储在新的二维数组中。 5. 编写一个函数来计算矩阵矩阵矩阵可以通过将伴随矩阵除以矩阵的行列式得到。可以使用循环依次计算每个元素的值并将其存储在新的二维数组中。 6. 最后,编写一个主函数来依次调用上述函数。在主函数中,先读取用户输入的矩阵,然后计算行列式并判断是否为0(若为0,则无矩阵),接着计算伴随矩阵矩阵,并将结果输出。 这样就实现了一个用C语言编写的矩阵函数。在实际应用中,可以根据需要对其进行调整和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值