求一个矩阵的逆矩阵的方法有很多,我们同样为了程序计算方便,使用初等变换来求逆矩阵。例如:如果一个矩阵为A我们将(A, E)通过初等变换转为(E, B)形式,则B为A的逆矩阵。我们来看一个例子:
下面我们就利用矩阵的初等变换来求逆矩阵:
//逆矩阵
int matrix_inverse(s_Matrix *result, s_Matrix *src)
{
if (src == null)
{
return -1;
}
if (src->v == null)
{
return -1;
}
if (src->m <= 0 || src->n <= 0)
{
return -1;
}
if (src->m != src->n)
{
return -1;
}
if (result == null)
{
return -1;
}
if (result->v == null)
{
return -1;
}
if (result->m <= 0 || result->n <= 0)
{
return -1;
}
//必须是方阵
if (result->m != src->n)
{
return -1;
}
//一阶方阵
if (src->m == 1)
{
result->v[0] = 1.0 / src->v[0];
return 0;
}
int err = 0;
int n = src->m;
s_Matrix temp;
matrix_init(&temp, n, n * 2);
//(A, E),矩阵大小由m,n变为m,2n
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
temp.v[i * (n * 2) + j] = src->v[i * n + j];
}
temp.v[i * (n * 2) + (i + n)] = 1;
}
//对首行做初等变换
for (int i = 0; i < n; i++)
{
for (int row = 0; row < n; row++)
{
//将当前对角线上的元素值保留,其它行上的值为0
if (row != i)
{
if (temp.v[i * (n * 2) + i] == 0)
{
err = 1;
goto _label_inf;
}
//计算初等变换参数
num a = -temp.v[row * (n * 2) + i] / temp.v[i * (n * 2) + i];
//初等变换
for (int j = i; j < (n * 2); j++)
{
temp.v[row * (n * 2) + j] += temp.v[i * (n * 2) + j] * a;
}
}
}
}
//除以对角线的值,将当前对角线上的元素变为1
for (int i = 0; i < n; i++)
{
num a = temp.v[i * (n * 2) + i];
if (a == 0)
{
err = 1;
goto _label_inf;
}
//将当前对角线上的元素变为1
for (int j = i; j < (n * 2); j++)
{
temp.v[i * (n * 2) + j] /= a;
}
}
//取得逆矩阵
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
result->v[i * n + j] = temp.v[i * (n * 2) + (j + n)];
}
}
_label_inf: ;
matrix_destory(&temp);
//如果初等变换失败
if (err)
{
//采用伴随矩阵法递归计算
return matrix_inv(result, src);
}
return 0;
}
本教程所使用的源代码完全开放、免费。你可以自由的使用和修改本教程中的所有源代码:
git@github.com:magicworldos/matrix.git https://github.com/magicworldos/matrix.git
Copyright © 2015-2023 问渠网 辽ICP备15013245号