C语言小练习3:矩阵求逆(初等变换法)

今日没有新学东西,巩固一下基础。

学线性代数求矩阵的逆时,知晓了一种利用初等变换来求逆的方法。也即绑定A和E(总是执行同样的操作),把已知矩阵A转化为单位阵E,则单位阵E就会被转化为A逆。当时就猜想着,这种繁重且单调的运算肯定是能用代码实现的。今天终于敲了出来,耗时4个多小时......由于没有充分的理论准备,故代码到后面完全是想到什么方法就直接敲上去的,有很大的优化空间。

还有个硬伤是不知道怎么动态调节矩阵大小...只能根据需求,知道矩阵阶数后手动修改参数才能拿来用。

实现功能如下:

1.调整数组大小后能对n阶方阵求逆;

2.检测到奇异阵后提示所输入的矩阵无逆。(好像还会报错说数组越界了)

代码如下:

#include
int main
{
int i, j, k, k1 = 0, ia, ja, n;
const int q = 4;
double x, div, absAkk, A[4][4], E[4][4] = { 0 };
for (i = 0; i < q; i++) 
{ 
	E[i][i] = 1;//构建单元阵E
}
printf("请输入矩阵元素(先从左至右,再从上至下,相邻元素用空格或回车隔开):\n");
for (i = 0; i < q; i++)
{
	for (j = 0; j < q; j++)
	{
		scanf("%lf", &A[i][j]);//输入矩阵A
	}
}
//通过行变换实现求逆
for (k = 0; k < q; k++)//把下三角区归零
{
	absAkk = A[k][k] * (A[k][k] >= 0 ? 1 : -1);
		for (n=1; absAkk < 0.00001 && n  0 ? 1 : -1);
			k1 = k;
		}
		if (n >= q +1 - k1)//只要不进换行循环,k1就不会跟随k值一起更新
		{
			printf("该矩阵没有逆!\n");
			break;
		}
		div = A[k][k];//先保存系数
		for (j = 0; j < q; j++)
		{
			A[k][j] /= div;//令Akk为1,行变换,于是同行其他元素/Akk
			E[k][j] /= div;//同构
		}
	for (i = k + 1; i < q; i++)//接下来的运算从第k+1行开始
	{
		div = A[i][k];//保存系数
		for (j = 0; j < q; j++)
		{
			A[i][j] -= A[k][j] * div;//三层嵌套实现下三角元素归零
			E[i][j] -= E[k][j] * div;//同构
		}
	}
}
//执行完以上代码后k应取q
//现在已经实现对角归一化、下三角归零化了,接下来实现上三角归零化
k--;
for(;k>0;k--)
{
	for (i = k - 1; i >= 0; i--)
	{
		div = A[i][k];//保存系数
		for (j = q-1; j >= 0; j--)
		{
			A[i][j] -= A[k][j] * div;
			E[i][j] -= E[k][j] * div;
		}
	}
}
if (n < q + 1 - k1)
{
	printf("此时A矩阵变为E:\n");
	for (ia = 0; ia < q; ia++)
	{
		for (ja = 0; ja < q; ja++)
			printf("%10lf", A[ia][ja]);
		printf("\n");
	}
	printf("此时E矩阵变为A逆:\n");
	for (ia = 0; ia < q; ia++)
	{
		for (ja = 0; ja < q; ja++)
			printf("%10lf", E[ia][ja]);
		printf("\n");
	}
}
	return 0;
}

你可能感兴趣的:(矩阵,算法,线性代数)