я следующий минимальный пример сохранен в minimalexample.f90:
Wrong Умножение матриц с MATMUL (Fortran)
MODULE FUNCTION_CONTAINER
IMPLICIT NONE
SAVE
INTEGER, PARAMETER :: DBL = SELECTED_REAL_KIND(P = 15,R = 200)
INTEGER :: DIMSYS, DIMMAT
COMPLEX(KIND = DBL), DIMENSION(4,1) :: INSTATE_BASISSTATES
COMPLEX(KIND = DBL), DIMENSION(2,2) :: SIGMAX
REAL(KIND = DBL), DIMENSION(2,2) :: BASISSTATES
REAL(KIND = DBL), DIMENSION(2,2) :: ID
COMPLEX(KIND = DBL),DIMENSION(2,2) :: PROJECTOR
CONTAINS
SUBROUTINE INDEXCONVERTER(N,K,L)
IMPLICIT NONE
INTEGER, INTENT(IN)::N
INTEGER, INTENT(OUT)::K,L
INTEGER::X, REMAINDER
X = N/DIMSYS
REMAINDER = N - (X * DIMSYS)
IF (REMAINDER == 0) THEN
K = X
L = DIMSYS
ELSE
K = X + 1
L = REMAINDER
END IF
END SUBROUTINE INDEXCONVERTER
SUBROUTINE DENSITYMATRIX(X,RHO)
IMPLICIT NONE
COMPLEX(KIND = DBL), DIMENSION(DIMMAT,1), INTENT(IN) :: X
COMPLEX(KIND = DBL), DIMENSION(2,2),INTENT(OUT)::RHO
INTEGER :: J, K, L
DO J = 1, DIMMAT
CALL INDEXCONVERTER(J,K,L)
RHO(K,L) = X(J,1)
END DO
END SUBROUTINE DENSITYMATRIX
SUBROUTINE WRONGRESULT(X,RHONEW)
IMPLICIT NONE
COMPLEX(KIND = DBL), DIMENSION(DIMMAT,1), INTENT(IN) :: X
COMPLEX(KIND = DBL),DIMENSION(DIMSYS,DIMSYS),INTENT(OUT)::RHONEW
COMPLEX(KIND = DBL), DIMENSION(DIMSYS,DIMSYS) :: RHO
REAL(KIND = DBL), DIMENSION(DIMSYS,DIMSYS) :: ID
COMPLEX(KIND = DBL), DIMENSION(DIMSYS,DIMSYS) :: SIGMAZ
COMPLEX(KIND = DBL), DIMENSION(DIMSYS,DIMSYS) :: SIGMAX
CALL DENSITYMATRIX(X,RHO)
RHONEW = matmul(SIGMAX,rho)
END SUBROUTINE WRONGRESULT
SUBROUTINE EXPECTATION(X,D,ANS)
IMPLICIT NONE
COMPLEX(KIND = DBL), DIMENSION(DIMMAT,1), INTENT(IN) :: X
COMPLEX(KIND = DBL), DIMENSION(DIMSYS,DIMSYS) :: RHONEW
COMPLEX(KIND = DBL), DIMENSION(DIMSYS,DIMSYS), INTENT(IN) :: D
REAL(KIND = DBL),INTENT(OUT)::ANS
COMPLEX(KIND = DBL),DIMENSION(DIMSYS, DIMSYS) :: TEMP
INTEGER :: J
REAL(KIND = DBL)::SUMM
SUMM = 0.0D0
CALL WRONGRESULT(X,RHONEW)
TEMP = MATMUL(D,RHONEW)
DO J = 1, DIMSYS
SUMM = SUMM + DREAL(TEMP(J,J))
END DO
ANS = SUMM
END SUBROUTINE EXPECTATION
SUBROUTINE RK(ANSWER)
IMPLICIT NONE
REAL(KIND = DBL), INTENT(OUT) :: ANSWER
COMPLEX(KIND = DBL), DIMENSION(DIMMAT,1)::X
REAL(KIND = DBL) :: X_EXPECTATION
REAL(KIND = DBL)::T
T = 0.0D0
X = INSTATE_BASISSTATES
CALL EXPECTATION(X,SIGMAX,X_EXPECTATION)
ANSWER = X_EXPECTATION
END SUBROUTINE RK
END MODULE FUNCTION_CONTAINER
PROGRAM ONE
USE FUNCTION_CONTAINER
IMPLICIT NONE
REAL(KIND = DBL) :: ANS
SIGMAX(1,1) = (0.0D0,0.0D0)
SIGMAX(1,2) = (1.0D0,0.0D0)
SIGMAX(2,1) = (1.0D0,0.0D0)
SIGMAX(2,2) = (0.0D0,0.0D0)
ID(1,1) = 1.0D0
ID(1,2) = 0.0D0
ID(2,1) = 0.0D0
ID(2,2) = 1.0D0
DIMSYS = 2
DIMMAT = 4
BASISSTATES = ID
INSTATE_BASISSTATES(1,1) = (0.5D0,0.0D0)
INSTATE_BASISSTATES(2,1) = (0.5D0,0.0D0)
INSTATE_BASISSTATES(3,1) = (0.5D0,0.0D0)
INSTATE_BASISSTATES(4,1) = (0.5D0,0.0D0)
CALL RK(ANS)
WRITE (*,*) ANS
END PROGRAM ONE
Когда я запускаю его, компилятор cygwin
печатает ответ, как 1. Все в порядке - как и ожидалось. Теперь в подпрограмме неправильно, я играю с разными выражениями для RHONEW.
Например, с RHONEW = 2*RHO
, я получаю 2 в качестве ответа. Опять же, как и ожидалось.
Теперь я пишу RHONEW = matmul(id,rho)
. Я должен получить 1 в качестве ответа, поскольку я (тривиально) умножаюсь на идентификатор перед вычислением ожидаемого значения RHO
, как определено в подпрограмме EXPECTATION
. Вместо этого я получаю 1.2732139384274929E-313.
Полное отсутствие смысла.
Что может быть? В моем реальном коде, я хочу сделать сложное умножение матриц вида:
RHONEW = UCONJ*RHO*U,
где UCONJ
и U
являются линейными комбинациями матриц.
Я не получаю правильный результат даже для тривиального умножения. Возможные ошибки, которые я могу исправить, чтобы перейти к моей проблеме?
Обратите внимание, что код находится во всех CAPS, так как я получил его от моего руководителя, который написал его в фиксированной форме. Код компилируется как с расширениями .f
, так и с .f90
.
Исправьте углубление. Поддерживается фиксированный формат. Кроме того, Fortran не зависит от регистра - независимо от выбранной формы. –
@AlexanderVogt Хорошо, давайте проигнорируем случай. Я знаю, это; но я получил код, написанный в этой форме. Кроме того, отступы не должны иметь значения. Я использую '.f90.' –
@ Aftab123 Конечно, компилятору это не имеет значения. Но человеку, пытающемуся отлаживать ваш код, он делает. Вы должны облегчить людям помощь вам. –