从lapack

时间:2017-11-15 19:11:27

标签: lapack

Lapack,很可能,没有任何计算行列式的例行程序。但是我们可以使用LU,QR或SVD分解来计算它。我更喜欢使用LU分解。现在,lapack使用一些dgetrf子程序将矩阵A分解成具有一些IPIV数组的PLU格式。我不知道如何处理这些信息。为了计算行列式,我只是乘以U矩阵的对角元素。但PLU格式的L和U是什么以及如何提取它们。我在C编程。

2 个答案:

答案 0 :(得分:3)

Lapack的dgetrf()计算一般M-by-N矩阵A的A=P*L*U分解。假设一个可逆方阵A,其行列式可以作为乘积计算:

  • U是一个上三角矩阵。因此,它的行列式是对角元素的乘积,它恰好是输出A的对角元素。确实,请参阅how the output A is defined

      

    退出时,因子化A = P*L*U中的因子L和U; L的单位对角元素不存储。

  • L是一个下三角矩阵,其中包含未存储的单位对角线元素。因此,它的决定因素总是1。

  • P是一个置换矩阵,编码为转置的乘积(即2个周期或交换)。确实,请参阅dgetri()以了解它是如何使用的。因此,其决定因素是1或-1,这取决于转置的数量是偶数还是奇数。因此,P的行列式可以计算为:

    int j;
    double detp=1.;
    for( j=0;j<n;j++){
        if(j+1!=ipiv[j]){
            // j+1 : following feedback of ead : ipiv is from Fortran, hence starts at 1.
            // hey ! This is a transpose !
            detp=-detp;
        }
    }
    

这种方法的复杂性主要是使用部分旋转的高斯消除的成本,即O(2 / 3n ^ 3)。

您可能会使用dgetc2()或QR分解转为完全旋转,以提高准确性。由潘等人在Algebraic and Numerical Techniques for the Computation of Matrix Determinants中发出信号。等,结合方程4.8,4.9和命题4.1,决定因素的最终误差可能是ed=(a+eps*a*n^4)^{n-1}*eps*an^5=a^n*(1+eps*n^4)^{n-1}*n^5*eps的标度,其中eps是双精度(约1e-13),a是最大的矩阵A和n中的所有元素都是矩阵的大小。这意味着计算的行列式对于“大”矩阵不是很重要:见表,特别是使用PLU分解时的相对误差!本文还提供了一种跟踪误差传播并产生更好的误差估计的算法。

您也可以尝试Faddeev–Le Verrier algorithm ...

答案 1 :(得分:2)

L是单位对角矩阵,因此其行列式始终为1。对于P,它可以是1-1,具体取决于排列的奇数/偶数,但ipiv是交换数组而非排列数组,因此您可以转换以下简单Python循环到C

det = 1

for i in range(len(ipiv)):
    det *= u(i,i)
    if ipiv[i] != i:
        det *= -1

但请注意,如果矩阵的条件在条​​件方面存在问题,则乘法可以上溢或下溢。而只是使用SVD。