矩阵行列式求法

本文详细介绍了矩阵行列式的多种求解方法,包括拉普拉斯展开、交错和、上三角矩阵转换、高斯消元法及LU分解。通过对比不同方法的时间复杂度,帮助读者理解并选择合适的求解策略。


行列式求法很多,下面是比较常见的几种。矩阵A的行列式记成 d e t ( A ) det(A) det(A).

拉普拉斯展开

根据行列式的代数余子式定义,矩阵按某行或某列展开: det ⁡ ( A ) = ∑ j = 1 n ( − 1 ) i + j a i j det ⁡ ( A i j ) = ∑ i = 1 n ( − 1 ) i + j a i j det ⁡ ( A i j ) \operatorname{det}(A)=\sum_{j=1}^{n}(-1)^{i+j} a_{i j} \operatorname{det}\left(A_{i j}\right)=\sum_{i=1}^{n}(-1)^{i+j} a_{i j} \operatorname{det}\left(A_{i j}\right) det(A)=j=1n(1)i+jaijdet(Aij)=i=1n(1)i+jaijdet(Aij)
这个直接递归就能搞定,时间复杂度: T ( n ) = T ( n − 1 ) n + n T(n)=T(n-1)n+n T(n)=T(n1)n+n
这个复杂度迭代计算得到: T ( n ) = ∑ i = 0 n − 1 n ! i ! = O ( n ∗ n ! ) T(n)=\sum_{i=0}^{n-1}\frac{n!}{i!}=O(n*n!) T(n)=i=0n1i!n!=O(nn!)
复杂度过于骇人听闻,所以实际没人敢用。只适用于一些线性代数考试题。
核心代码:

int det_matrix(Matrix& mat, int row)
{
    if(row == 2)
    {
        double* arr = mat.get_mat();
        return arr[0 * row + 0] * arr[1 * row + 1] - arr[0 * row + 1] * arr[1 * row + 0];
    }
    else
    {
        double res = 0;
        double *vec = mat.get_mat();
        for(int i = 0; i < row; i++)
        {
            int k = 1;
            if(i % 2 == 1)
            {
                k = -1;
            }
            Matrix new_mat = remove_row_col(mat,1, i + 1);
            res += vec[i] * k * det(new_mat,row - 1);   
        }
        return res;
    }
}

交错和

这种方法是生成一个1-n的排列p,然后按这个排列选数累乘,按排列的逆序对数决定符号。显然一共n!项,每项连乘O(n),复杂度还是O(n*n!)。连线性代数考试都不屑于用。

想办法变成上三角矩阵

上三角矩阵的行列式是主对角线元素的连乘,可以按第一列做拉普拉斯展开,数学归纳法证明。

经典高斯消元法

用第三类初等行变换把矩阵变成上三角阵,这样行列式是不变的。第三类初等行变换是把某行的k倍加到别的行上去。这个实际上是高斯消元。

LU分解

这个本质上还是高斯消元。因为把初等变换施加到单位矩阵E上,可以记录下变换操作。将原矩阵左乘这个记录矩阵就相当于对原矩阵做了初等行变换。这里大概描述LU分解的原理:
一个可逆矩阵A一定可以分解成 A = L ∗ U A=L*U A=LU
U是和A等价的上三角矩阵。
L是一个下三角矩阵,对主角线一定都是1,L与A向U变换的操作步骤有关。
很明显L和U的求法可以高斯消元,也可以直接求。具体另一篇博客会解释。

在C语言中计算对称矩阵行列式,可以使用高斯消元或者利用矩阵的特性来简化计算。对称矩阵意味着它的主对角线元素相等,其他元素关于主对角线是对称的。例如,一个3x3的对称矩阵会看起来像这样: ``` | a b c | | b a d | | c d a | ``` 其中a = d且b = c。 对于这类矩阵,有快速的算法可以利用这种特殊结构来计算行列式。你可以选择以下几种方法之一: 1. **LU分解**:首先将对称矩阵转换成上三角形式(U),然后通过乘积 `det(A) = det(U) * det(L)` 计算行列式,其中L是下三角矩阵,因为对称矩阵的L和U是对称的,这一步可以用递归公式完成。 2. **特征方法**:由于对称矩阵的实数特征是唯一确定的,可以先找到特征,然后行列式就是特征之积。计算特征通常涉及解特征多项式,但这需要额外的库支持,比如数计算库。 3. **行主序展开**:可以选择行主序(即按行交替展开法则),对称矩阵在这种情况下展开后的系数是相同的,这能简化计算过程。 ```c // 示例代码片段(非完整版) #include <stdio.h> double determinant(int n, double matrix[n][n]) { if (n == 2) { return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; } else { int i; double sub_determinant = 0.0; for (i = 0; i < n; i++) { // 按行交替展开 sub_determinant += matrix[0][i] * determinant(n - 1, &matrix[1][i]); } return sub_determinant; } } int main() { double symmetric_matrix[3][3] = { {1, 2, 2}, {2, 1, 2}, {2, 2, 1} }; printf("The determinant is: %.2f\n", determinant(3, symmetric_matrix)); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值