-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmyLapack95.f90
137 lines (112 loc) · 4.07 KB
/
myLapack95.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
MODULE Interface_lapack
USE nrtype, ONLY: DBL
implicit none
INTERFACE dia
MODULE PROCEDURE ddiagonalize
MODULE PROCEDURE zdiagonalize
END INTERFACE
contains
!Diagonalize Hamitonian and reduced density matrix using LAPACK function(zheev).
subroutine ddiagonalize(n, a, w)
implicit none
integer, intent(in) :: n !dimension of hamitonian
real(KIND=DBL), dimension(n, n) :: a !diagolize a; output eigenvectors
real(KIND=DBL) :: w(n) !output eigenvalues
character(len=1), parameter :: jobz = 'V' !"V" for eigenvalues and eigenvectors
character(len=1), parameter :: uplo = 'U' !"U" is upper triangular, "L" is lower one
integer :: lda !a(lda, n) basicly a is square matrix
integer :: lwork
real(KIND=DBL), allocatable :: work(:)
integer :: info
lda = n
lwork = (3*n-1)
allocate ( work(lwork) )
call dsyev(jobz, uplo, n, a, lda, w, work, lwork, info)
deallocate ( work )
return
end subroutine ddiagonalize
!Diagonalize Hamitonian and reduced density matrix using LAPACK function(zheev).
subroutine zdiagonalize(n, a, w)
implicit none
character(len=1), parameter :: jobz = 'V' !"V" for eigenvalues and eigenvectors
character(len=1), parameter :: uplo = 'U' !"U" is upper triangular, "L" is lower one
integer :: n !dimension of hamitonian
integer :: lda !a(lda, n); basicly a is square matrix
complex(KIND=DBL), intent(in) :: a(n,n) !diagolize a; output eigenvectors
real(KIND=DBL) :: w(n) !output eigenvalues
integer lwork
complex(KIND=DBL), allocatable :: work(:)
integer lrwork
real(KIND=DBL), allocatable :: rwork(:)
integer :: info
lda = n
lwork = (2*n-1)
lrwork = (3*n-2)
allocate ( work(lwork) )
allocate ( rwork(lrwork) )
call zheev(jobz, uplo, n, a, lda, w, work, lwork, rwork, info)
deallocate ( work )
deallocate ( rwork )
return
end subroutine zdiagonalize
subroutine non_Hermitian(n,a,w)
implicit none
character(len=1), parameter :: jobvr='N'
character(len=1), parameter :: jobvl='N'
integer, intent(in) :: N
integer info, lda, ldvl, ldvr, lwork
real(KIND=DBL), allocatable :: rwork(:)
complex(KIND=DBL), intent(out) :: w(n)
complex(KIND=DBL), intent(inout) :: a(n,n)
complex(KIND=DBL), allocatable :: vl(:,:),vr(:,:),work(:)
w = cmplx(0.0E0_DBL,0.0E0_DBL)
lda = n
ldvl = n
ldvr = n
lwork = 2*n+1
allocate( vl(ldvl,n) )
allocate( vr(ldvr,n) )
allocate( work(lwork) )
allocate( rwork(2*n) )
call zgeev(jobvl,jobvr,n,a,lda,w,vl,ldvl,vr,ldvr,work,lwork,rwork,info)
deallocate( rwork )
deallocate( work )
deallocate( vr )
deallocate( vl )
if( info /= 0 ) then
write(*,*) 'wrong in non_Hermitian'
write(*,*) info
end if
return
end subroutine non_Hermitian
subroutine svd(n,a,w)
implicit none
character(len=1), parameter :: jobu='N'
character(len=1), parameter :: jobvt='N'
integer, intent(in) :: N
integer info, lda, ldu, ldvt, lwork, m
real(KIND=DBL), allocatable :: rwork(:)
real(KIND=DBL), intent(out) :: w(n)
complex(KIND=DBL), intent(inout) :: a(n,n)
complex(KIND=DBL), allocatable :: u(:,:),vt(:,:),work(:)
m = n
lda = n
ldu = n
ldvt = n
lwork = 4*n
allocate( vt(ldvt,n) )
allocate( u(ldu,m) )
allocate( work(lwork) )
allocate( rwork(5*n) )
call ZGESVD(jobu,jobvt,m,n,a,lda,w,u,ldu,vt,ldvt,work,lwork,rwork,info)
deallocate( rwork )
deallocate( work )
deallocate( u )
deallocate( vt )
if( info /= 0 ) then
write(*,*) 'wrong in SVD'
write(*,*) info
end if
return
end subroutine svd
end MODULE Interface_lapack