具有 Fortran 95 和 LAPACK 的实数非对称矩阵的矩阵指数

计算科学 线性代数 正则 拉帕克
2021-12-24 05:30:12

我最近问了一个关于斜厄米特矩阵的问题。受到该问题成功的启发,在将我的头撞到墙上几个小时后,我正在研究真正非对称矩阵的矩阵指数。找到特征值和特征向量的路径似乎相当复杂,我担心我迷路了。

背景:前段时间我在理论物理SE上问了这个问题。结果使我可以将主方程组表述为真正的非对称矩阵。在与时间无关的情况下,主方程通过对该矩阵求幂来求解。在依赖时间的情况下,它将需要集成。我现在只关心时间独立性。

在查看我认为我应该调用的各种子例程时(?gehrd?orghr?hseqr ...),不清楚将矩阵从real*8to 转换为complex*16并继续执行这些例程的复杂 double 版本是否更简单,或者坚持real*8并接受将我的数组数量翻倍并在以后制作它们的复杂矩阵的打击。

那么,我应该调用哪些例程(以及以什么顺序),我应该使用真正的 double 版本还是复杂的 double 版本?下面是尝试使用真正的双重版本进行此操作。我在寻找L*t.

function time_indep_master(s,L,t)
  ! s is the length of a side of L, which is square.
  ! L is a real*8, asymmetric square matrix.
  ! t is a real*8 value corresponding to time.
  ! This function (will) compute expm(L*t).

  integer, intent(in)    :: s
  real*8,  intent(in)    :: L(s,s), t
  real*8                 :: tau(s-1), work(s), wr(s), wi(s), vl
  real*8, dimension(s,s) :: time_indep_master, A, H, vr
  integer                :: info, m, ifaill(2*s), ifailr(2*s)
  logical                :: sel(s)

  A = L*t
  sel = .true.

  call dgehrd(s,1,s,A,s,tau,work,s,info)
  H = A
  call dorghr(s,1,s,A,s,tau,work,s,info)
  call dhseqr('e','v',s,1,s,H,s,wr,wi,A,s,work,s,info)
  call dhsein('r','q','n',sel,H,s,wr,wi,vl,1,vr,s,2*s,m,work,ifaill,ifailr,info)

  ! Confused now...

end function
3个回答

我首先会认真思考矩阵是否真的是完全任意的:是否有任何转换可以使它成为 Hermitian?物理学是否保证矩阵应该是可对角化的(具有合理条件的特征向量矩阵)?

如果事实证明确实没有任何对称性可以利用,那么您应该首先阅读19 种可疑的方法来计算矩阵指数,这是标准参考资料(由 MATLAB 的作者和 G&vL 的合著者编写) .

为了建立在杰克所说的基础上,似乎在软件中使用的标准方法(如您之前的问题中提到的 EXPOKIT)是缩放和平方,然后是 Padé 近似(方法 2 和 3)或 Krylov 子空间方法(方法20)。特别是,如果您正在研究指数积分器,您将需要考虑 Krylov 子空间方法,并查看有关指数积分器的论文(Moler & van Loan 论文中的方法 20 中提到了一些参考资料)。

如果您一心想要使用特征向量,请考虑使用特征向量的三角形系统(方法 15);由于您的矩阵可能是不可对角化的,因此这种方法可能不是最好的,但它比尝试直接计算特征向量和特征值(即方法 14)要好。

简化为 Hessenberg 形式不是一个好主意(方法 13)。

对我来说,使用实数还是复数算术会更好,因为 Fortran 复数算术速度很快,但可能会溢出/下溢(请参阅“Fortran 编译器真的好多少?”)。

您可以放心地忽略方法 5-7(基于 ODE 求解器的方法效率低下)、方法 8-13(昂贵)、方法 14(在没有特殊结构的情况下很难计算大型矩阵的特征向量,并且在病态情况下容易出现数值错误) , 和方法 16(计算矩阵的 Jordan 分解在数值上是不稳定的)。方法 17-19 实施起来比较棘手;特别是,方法 17 和 18 需要更多阅读。如果 Padé 近似不能很好地工作,方法 1 是缩放和平方的后备选项。

编辑#1:根据对杰克回答的评论,块对角化似乎是一种选择,在这种情况下,类似方法18(块三角形对角化)的方法是一种非常好的使用方法。一开始我犹豫是否推荐它,因为您的问题没有指定这种结构,但是如果您有一个块对角化矩阵的转换,它可以消除该方法的大部分复杂性。您只需要确保使用 GW Stewart 分解每个块对角矩阵的技巧Bj进入

Bj=γjI+Ej,

在哪里γj是特征值的平均值j第块对角矩阵。这种分解将使Ej几乎是幂零的,这将提高矩阵指数计算的准确性。这个技巧在 Jack 链接到的 Moler & van Loan 论文版本的第 26 页上进行了讨论。

我有一个简单的 Fortran 子程序,可以计算任意矩阵的指数。我用 Matlab 命令检查了它,它很好。它基于缩放和平方。几年前我写的。

我想找到另一个子程序,就像我从 gams.nist.gov 下载的那些。但还没有运气。