【发布时间】:2018-06-07 13:12:44
【问题描述】:
我必须在 Fortran 77 程序中计算 3x3 矩阵 (A) 的对数。
在 Python 中我使用了
scipy.linalg.logm(A)
对于这项工作,但我在 Fortran 中找不到此任务的解决方案。
到目前为止,我发现 Fortran 77 的内置函数无法执行此操作。我还搜索了 Intel Math Kernel Library 的文档,但没有找到合适的子例程。我在 NAG Fortran 库中找到了子程序 F01EJ,但不幸的是我无法访问这个商业库。我知道 Higham 等人的论文,但我想避免自己实现算法,因为我认为这一定是一个已解决的问题。
谁能给我一个计算矩阵对数的子程序的提示?
解决方案:
我已经根据@kvantour 提出的方法实现了一个 3x3 矩阵的对数子程序,它对我来说效果很好。也许子程序的(不是很漂亮)快速而肮脏的代码对其他有同样问题的人有用:
subroutine calclogM(M,logM)
implicit none
double precision,dimension(3,3)::M,logM,VL,VR,logMapo,VRinv
integer::n,INFO,LWORK,I,J
double precision,dimension(3)::WR,WI,logWR,ipiv
double precision,dimension(24)::WORK
n=3
LWORK=24
call DGEEV( 'N', 'V', n, M, n, WR, WI, VL, n, VR,
1 n, WORK, LWORK, INFO )
C Check if all eigenvalues are greater than zero
if (WR(1) .le. 0.D0) then
write(*,*) 'Unable to compute matrix logarithm!'
GOTO 111
end if
if (WR(2) .le. 0.D0) then
write(*,*) 'Unable to compute matrix logarithm!'
GOTO 111
end if
if (WR(3) .le. 0.D0) then
write(*,*) 'Unable to compute matrix logarithm!'
GOTO 111
end if
DO I = 1, 3
DO J = 1, 3
logMapo(I,J) = 0.D0
END DO
END DO
C Then Mapo will be a diagonal matrix whose diagonal elements
C are eigenvalues of M. Replace each diagonal element of Mapo by its
C (natural) logarithm in order to obtain logMapo.
DO I = 1, 3
LogMapo(I,I)=log(WR(I))
END DO
C Calculate inverse of V with LU Factorisation
C Copy VR to VRinv
DO I = 1, 3
DO J = 1, 3
VRinv(I,J) = VR(I,J)
END DO
END DO
call dgetrf( n, n, VRinv, n, ipiv, info )
write(*,*) 'INFO',INFO
call dgetri( n, VRinv, n, ipiv, WORK, LWORK, INFO )
write(*,*) 'INFO',INFO
C Build the logM Matrix
logM = matmul(matmul(VR,logMapo),VRinv)
111 end subroutine calclogM
【问题讨论】:
-
欢迎,请记得收下欢迎邮件tour 并阅读How to Ask。不幸的是,Fortran 中没有这样的内在函数,推荐一个外部库在这里是题外话。我想如果您搜索methods referenced in the SciPy documentation,您可能会找到 Fortran 实现,但在这里为您搜索它们是题外话。但也许它们太新了,无法实现 Fortran。您可能会找到一个 C 或 C++ 并从 Fortran 调用它。
-
C++ Eigen 库有矩阵对数,你可能想尝试从 Fortran 调用它。这需要您编写一些接口 C++ 代码。更多阅读eprints.maths.manchester.ac.uk/2450/1/catalog.pdf
-
感谢您对 C++ Eigen 库的建议。我会试一试,看看我是否能够从我的 Fortran 代码中调用该函数。
标签: matrix fortran linear-algebra logarithm intel-mkl