给定一个巨大的对称正定矩阵,如何计算其逆的几个对角元素?

时间:2011-09-13 21:38:18

标签: fortran

更新:这是一个纯粹的 Fortran问题; I put the maths stuff on M.SE

考虑P x P对称和正定矩阵A(P = 70000,即A大约40 GB,使用8字节双精度)。我们想要计算逆矩阵inv(A)[1,1]inv(A)[2,2]inv(A)[3,3]的前三个对角线元素。

我找到了James R. Bunch的this paper,他似乎在没有计算完全反inv(A)的情况下解决了这个问题。 不幸的是他使用了Fortran和LINPACK,两者都是我从未使用过的

我正在尝试理解这个功能:

    SUBROUTINE SOLVEJ(A,LDA,P,Y,J)
    INTEGER LDA,P,J
    REAL A(LDA,1),Y(1)
C
    INTEGER K
    Y(J) = 1/A(J,J)
    DO 10 K = J + 1,P
    Y(K) = - SDOT(K - J,A(J,K),1,Y(J),1)/A(K,K)
    10 CONTINUE
    RETURN
    END

其中A是大小为LDA x P的矩阵,Y是长度为P的向量。

你能解释为什么他在函数头中定义Y(1)然后分配给Y(J) Fortran不关心定义数组的大小并让你访问超出其结束?为什么不定义Y(P),这似乎可以根据this Fortran Primer

1 个答案:

答案 0 :(得分:3)

首先,您应该了解不同的Fortran版本,尤其是77 VS 90/95及更高版本,而且确实您可以(通常)超出界限,就像在C. fortran中的数组可能会导致很多混乱,我会说这有点乱。为了将讨论局限于您的具体情况,我们可以使用这是关于虚拟数组的事实,这是一个出现在过程的伪参数列表中的数组。对于虚拟数组,我们可以有3种类型:

  1. 显式形状:显式声明尺寸
  2. 假设形状:没有给出尺寸,只有冒号表示数组的等级
  3. 假定大小:最后一个维度是星号,显式声明前导维度
  4. 使事情变得复杂,(3)可以与(1)组合,并且(2)通常与延迟形状的数组分组,例如,可分配的数组。延迟形状和假定形状仅适用于Fortran 90/95及更高版本,如果您想将它们用作伪参数,则需要显式接口,因此它通常用于模块中。

    所以,在你的情况下,虽然Y(1)可以工作,因为你可以超出范围,但是非常糟糕,因为当你用-fcheck=bounds编译程序时程序会失败。应该编写有效的Fortran 77:

    REAL A(LDA,*),Y(*)
    

    或更好:

    REAL A(LDA,P),Y(P)