Мне нужно вычислить логарифм матрицы 3х3 (A) в программе на Фортране 77.
В Python я использовал
scipy.linalg.logm(A)
для этой работы, но я не нашел решения этой задачи в Фортране.
До сих пор я выяснил, что эта операция невозможна со встроенными функциями Fortran 77. Также я искал в документации библиотеки Intel Math Kernel, но не нашел подходящей подпрограммы.Я нашел подпрограмму F01EJ в библиотеке NAG Fortran, но, к сожалению, у меня нет доступа к этой коммерческой библиотеке.Я знаком с работами Хайама и др., Но я бы не хотел реализовывать алгоритмы самостоятельно, так как считаю, что это должно быть решенной проблемой.
Может ли кто-нибудь дать мне подсказку для подпрограммы, которая вычисляет матричный логарифм?
Решение:
Я реализовал подпрограмму для логарифмаматрицы 3х3 по способу, предложенному @kvantour, и у меня все получилось.Возможно (не очень красивый) быстрый и грязный код подпрограммы полезен для других с такой же проблемой:
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