2
votes

I'm new to lapack and trying to find the determinant of an NxN matrix. I used the code from dualm.wordpress.com/2012/01/06/computing-determinant-in-fortran/

program lapackdet

  implicit none
  integer :: N
  complex, allocatable, dimension(:,:) :: mat
  complex :: det
  integer :: i, info
  integer, allocatable :: ipiv(:)
  real :: sgn

  N=2

  allocate(ipiv(N))
  allocate(mat(N,N))

  mat=2
  mat(1,2)=1
  mat(2,1)=1

  ipiv=0

  call zgetrf(N, N, mat, N, ipiv, info)

  do i=1, N
     det = det*mat(i,i)
  end do

  do i=1, N
     if(ipiv(i)/=i)then
        sgn=-sgn
     end if
  end do
  det=sgn*det

  write(*,*) det

end program lapackdet

When using this code, the error: "zgetrf", referenced from: det in cc8VZrbU.o ld: symbol(s) not found collect2: ld returned 1 exit status

I'm not sure what this means or how to fix it.

Thank you

1
The error msg means that the linker is not finding the subroutine zgetrf that you call from your source code. Are you including the Lapack library on your link command? - M. S. B.
Note also that det is not initialized to 1. - Kyle Kanos

1 Answers

1
votes

As signaled by @M.S.B. the first step to compile your code correctly is to link lapack. I used gfortran main.f90 -o main -llapack -lm and it compiled fine.

Moreover, to get a correct determinant, det and sgn must be initialized to 1, as signaled by @KileKanos. And the routine zgetrf of the LAPACK library needs COMPLEX*16 : the real and imaginary part of each complex number are double precision.

Finally, here is a working code which computes the determinant of a complex matrix. It is compiled with gfortran main.f90 -o main -llapack -lm :

program lapackdet

  implicit none
  integer :: N
  COMPLEX*16, allocatable, dimension(:,:) :: mat
  COMPLEX*16 :: det
  integer :: i, info
  integer, allocatable :: ipiv(:)
  real :: sgn

  N=2

  allocate(ipiv(N))
  allocate(mat(N,N))

  mat(1,2)=1
  mat(2,1)=1
  mat(1,1)=0
  mat(2,2)=0

  ipiv=0

  call zgetrf(N, N, mat, N, ipiv, info)

  det=1
  do i=1, N
     det = det*mat(i,i)
  end do

  sgn=1
  do i=1, N
     if(ipiv(i)/=i)then
        sgn=-sgn
     end if
  end do
  det=sgn*det

  write(*,*) det

end program lapackdet