The Elk Code
 
Loading...
Searching...
No Matches
unitary.f90
Go to the documentation of this file.
1
2! Copyright (C) 2020 J. K. Dewhurst and S. Sharma.
3! This file is distributed under the terms of the GNU General Public License.
4! See the file COPYING for license details.
5
6!BOP
7! !ROUTINE: unitary
8! !INTERFACE:
9subroutine unitary(n,a)
10! !INPUT/OUTPUT PARAMETERS:
11! n : order of matrix (in,integer)
12! a : complex square matrix (inout,complex(n,n))
13! !DESCRIPTION:
14! Finds the closest unitary matrix (in terms of the Frobenius norm) to a
15! given matrix $A$. Let $U\Sigma V^{\dag}$ be the singular value
16! decomposition of $A$. Then it can be shown that $UV^{\dag}$ is the closest
17! unitary matrix to $A$. The input matrix is overwritten by this matrix.
18!
19! !REVISION HISTORY:
20! Created January 2020 (JKD)
21!EOP
22!BOC
23implicit none
24! arguments
25integer, intent(in) :: n
26complex(8), intent(inout) :: a(n,n)
27! local variables
28integer info
29complex(8), parameter :: zzero=(0.d0,0.d0),zone=(1.d0,0.d0)
30! automatic arrays
31real(8) s(n),rwork(5*n)
32complex(8) work(3*n)
33! allocatable arrays
34complex(8), allocatable :: u(:,:),vt(:,:)
35! perform singular value decomposition on matrix
36allocate(u(n,n),vt(n,n))
37call zgesvd('A','A',n,n,a,n,s,u,n,vt,n,work,3*n,rwork,info)
38if (info /= 0) then
39 write(*,*)
40 write(*,'("Error(unitary): singular value decomposition failed")')
41 write(*,'(" ZGESVD returned INFO = ",I8)') info
42 write(*,*)
43 stop
44end if
45! multiply the two unitary matrices together and store in the input matrix
46call zgemm('N','N',n,n,n,zone,u,n,vt,n,zzero,a,n)
47deallocate(u,vt)
48end subroutine
49!EOC
50
subroutine unitary(n, a)
Definition unitary.f90:10