0

I have created the following module: quantum.f90

module quantum
implicit none

contains

function renyi_entropy(A, N, p) result(entropy)
    implicit none
    integer :: N, p, INFO, i
    real :: A(N,N), eval(N), WORK(3*N-1)
    real :: entropy

    call SSYEV('N', 'U', N, A, N, eval, WORK, 3*N-1, INFO)

    entropy = 0.0

    if (p == 1) then
        do i = 1,N            
            entropy = entropy - eval(i)*LOG(eval(i))
        end do
    else
        do i = 1,N
            entropy = entropy + eval(i)**p
        end do
        entropy = LOG(entropy) / (1-p)
    end if

    entropy = entropy / LOG(2.0)

end function renyi_entropy

end module quantum

I use it in my program wishart.f90 as follows:

program wishart
use quantum
implicit none

integer :: d1, d2
real, allocatable :: A(:, :), W(:, :)

d1 = 4
d2 = 3
allocate(A(d1, d2), W(d1, d1))

call random_number(A)

W = matmul(A, transpose(A))

print*, renyi_entropy(W, d1, 1)

end program wishart

On the command line I give: gfortran -c quantum.f90 wishart.f90 -llapack -lblas and then gfortran quantum.o wishart.o. This results in

quantum.o: in function `__quantum_MOD_renyi_entropy':
quantum.f90:(.text+0x13e): undefined reference to `ssyev_'
collect2: error: ld returned 1 exit status
  • dsyev takes "double precision". Your variables are default real. The routine you want is ssyev – Ian Bush May 25 '22 at 04:56
  • Note also `random_number` is elemental - `Call random_number( a )` is sufficient to fill all of a with random values. Also it is not good practice to use external procedures, contained or best module procedures are much less error prone - in fact were dsyev in a module, or at least had an interface in scope, the compiler would have found the above problem for you. – Ian Bush May 25 '22 at 05:05
  • "The routine you want is ssyev" - this works, thanks! I didn't know about this. Regarding your second comment "were dsyev in a module, or at least had an interface in scope, the compiler would have found the above problem for you", I was in fact trying to put it in a module and then do "use module". But I was getting this "undefined reference to dsyev". I have tried again with ssyev, but the same error persists. The command line input I give is this `gfortran -c my_module.f90 my_program.f90 -llapack -lblas`. Do you have any idea what might be wrong? – devanshu shekhar May 25 '22 at 05:41
  • If you put your whole subroutines in a module and you `use` that module (at the right place that actually calls the module, not just the main program),,you can remove the `-llapack`. If you only make a module with interface blocks, you can use this module but you have to keep linking the external library using `-llapack`. – Vladimir F Героям слава May 25 '22 at 05:44
  • @VladimirFГероямслава I am sorry, but I don't understand your comment. Can I edit my question above, so that I can upload the code for better clarification? – devanshu shekhar May 25 '22 at 05:57
  • Sure, you can. And show also the compilation command please. Since the question has no answerd yet, you can still completely rewrite it. – Vladimir F Героям слава May 25 '22 at 05:58
  • @VladimirFГероямслава I have edited the question above, please see! – devanshu shekhar May 25 '22 at 06:14
  • You did not really put ssyev in a module. You only call it from a module procedure. But it remains an external procedure from an external library. Basically nothing changed. – Vladimir F Героям слава May 25 '22 at 06:42
  • But the answer to your error message is: The `-llapack -lblas` and other linker options must be provided **in the last linking step**, not when you compile the .o files, but when you are linking them together to create the final executable. – Vladimir F Героям слава May 25 '22 at 06:45
  • Yes, I learned that now! Thanks! Although I am still not sure about your comment "You did not really put ssyev in a module". Can you suggest some references? – devanshu shekhar May 25 '22 at 07:03
  • The crucial thing is to provide an interface to the lapack routines, this will provided automatic argument checking - I have a module which just contains interfaces for the lapack and blas routines I need, and I use that whenever I call them. Any Fortran book should tell you about interfaces. – Ian Bush May 25 '22 at 08:03

0 Answers0