bgeneto

lapack zheev example program

May 24th, 2018
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module matgen
  2.     implicit none
  3.     contains
  4.  
  5.     ! Creates pseudo-random positive-definite hermetian matrix
  6.     function create_random_hermitian_matrix(N) result(A)
  7.     complex(8), allocatable, dimension(:,:) :: A, temp
  8.     real(8)                                 :: rv, iv
  9.     integer                                 :: i, j, N
  10.  
  11.     if (.not. allocated(A))    allocate(A(N,N))
  12.     if (.not. allocated(temp)) allocate(temp(N,N))
  13.  
  14.     ! Create general hermitian temp
  15.     do j = 1, N
  16.         do i = 1, N
  17.             if (i > j) then
  18.                 call random_number(rv)
  19.                 call random_number(iv)
  20.                 temp(i,j) = cmplx(rv, iv, 8)
  21.                 temp(j,i) = conjg(temp(i,j))
  22.             else if (i == j) then
  23.                 call random_number(rv)
  24.                 temp(i,j) = rv
  25.             end if
  26.         end do
  27.     end do
  28.  
  29.     ! Multiply temp by conjugate transpose of temp to get positive definite hermitian A
  30.     call zgemm('N', 'C', N, N, N, cmplx(1.0, 0.0, 8), temp, N, temp, N, cmplx(0.0, 0.0, 8), A, N)
  31.  
  32.     deallocate(temp)
  33.  
  34.     end function create_random_hermitian_matrix
  35.  
  36. end module matgen
  37.  
  38.  
  39. program main
  40.     use matgen
  41.     implicit none
  42.  
  43.     integer                                 :: N, i, k, lda, istat
  44.     integer                                 :: lwork, lrwork, liwork
  45.     character(len=20)                       :: arg
  46.     complex(8), dimension(:,:), allocatable :: A, Aref
  47.     complex(8), dimension(:,:), allocatable :: B, Bref
  48.     complex(8), dimension(:), allocatable   :: work
  49.     real(8), dimension(:), allocatable      :: w, rwork
  50.     integer, dimension(:), allocatable      :: iwork
  51.  
  52.     ! Parse command line arguments
  53.     i = command_argument_count()
  54.  
  55.     if (i >= 1) then
  56.         ! If N is provided, generate random hermetian matrices for A and B
  57.         print*, "Using randomly-generated matrices..."
  58.         call get_command_argument(1, arg)
  59.         read(arg, *) N
  60.         lda = N
  61.     else
  62.         print*, "Usage error: please provide at least one integer argument (matrix dimension)."
  63.         stop
  64.     endif
  65.  
  66.     print*, "Running with N = ", N
  67.  
  68.     ! size of temp. work arrays from lapack
  69.     lwork = 2*N + N*N
  70.     lrwork = 1 + 5*N + 2*N*N
  71.     liwork = 3 + 5*N
  72.  
  73.     ! deallocate first (just in case)
  74.     if (allocated(Aref))  deallocate(Aref)
  75.     if (allocated(Bref))  deallocate(Bref)
  76.     if (allocated(A))     deallocate(A)
  77.     if (allocated(B))     deallocate(B)
  78.     if (allocated(w))     deallocate(w)
  79.     if (allocated(iwork)) deallocate(iwork)
  80.     if (allocated(rwork)) deallocate(rwork)
  81.     if (allocated(work))  deallocate(work)
  82.     if (allocated(work))  deallocate(work)
  83.     if (allocated(rwork)) deallocate(rwork)
  84.     if (allocated(iwork)) deallocate(iwork)
  85.  
  86.     ! dynamic memory allocation
  87.     if (.not. allocated(Aref))  allocate(Aref(N,N))
  88.     if (.not. allocated(Bref))  allocate(Bref(N,N))
  89.     if (.not. allocated(A))     allocate(A(N,N))
  90.     if (.not. allocated(B))     allocate(B(N,N))
  91.     if (.not. allocated(w))     allocate(w(N))
  92.     if (.not. allocated(iwork)) allocate(iwork(liwork))
  93.     if (.not. allocated(rwork)) allocate(rwork(lrwork))
  94.     if (.not. allocated(work))  allocate(work(lwork))
  95.     if (.not. allocated(work))  allocate(work(lwork))
  96.     if (.not. allocated(rwork)) allocate(rwork(lrwork))
  97.     if (.not. allocated(iwork)) allocate(iwork(liwork))
  98.  
  99.  
  100.     ! Create random positive-definite hermetian matrices on host
  101.     Aref = create_random_hermitian_matrix(N)
  102.  
  103.     ! Bref is the identity matrix
  104.     Bref = 0
  105.     forall(k = 1:N) Bref(k,k) = cmplx(1.0, 0.0, 8)    ! Set the diagonal
  106.  
  107.     A(:,:) = Aref(:,:)
  108.     B(:,:) = Bref(:,:)
  109.  
  110.     !call zhegvd(1, 'V', 'U', N, A, lda, B, lda, w, work, lwork, rwork, lrwork, iwork, liwork, istat)
  111.     !call zheevd('V', 'U', N, A, lda, w, work, lwork, rwork, lrwork, iwork, liwork, istat)
  112.     call zheev( 'V', 'U', N, A, lda, w, work, lwork, rwork, istat)
  113.     if (istat /= 0) write(*,*) 'zhexxx failed. istat = ', istat
  114.  
  115.     print*, 'First eigenvalue = ', w(1)
  116.     print*, 'Last eigenvalue = ', w(N)
  117.  
  118.  
  119. end program main
Advertisement
Add Comment
Please, Sign In to add comment