Calculates the singular value decomposition (SVD) of a matrix A.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=rk), | intent(in), | dimension(:, :), contiguous | :: | A | ||
real(kind=rk), | intent(out), | dimension(:,:) | :: | U | ||
real(kind=rk), | intent(out), | dimension(:) | :: | S | ||
real(kind=rk), | intent(out), | dimension(:,:) | :: | VT |
pure subroutine gesdd_rel(A, U, S, VT) ! Inputs: real(rk), dimension(:, :), contiguous, intent(in) :: A ! Input matrix A ! Outputs: real(rk), dimension(:,:), intent(out) :: U ! Left singular vectors real(rk), dimension(:,:), intent(out) :: VT ! Right singular vectors real(rk), dimension(:), intent(out) :: S ! Singular values ! Local variables real(rk) :: work1(1) ! memory allocation query real(rk), dimension(:), allocatable :: work ! Work array integer :: m, n, lwork, info integer, dimension(:), allocatable :: iwork ! Integer work array ! External subroutine for calculating the SVD interface dgesdd pure subroutine dgesdd(f_jobz, f_m, f_n, f_a, f_lda, f_s, f_u, f_ldu, f_vt, f_ldvt, f_work, f_lwork, f_iwork, f_info) use kinds character, intent(in) :: f_jobz integer, intent(in) :: f_m, f_n, f_lda, f_ldu, f_ldvt, f_lwork real(rk), dimension(f_lda, *), intent(in) :: f_a real(rk), dimension(*), intent(out) :: f_s real(rk), dimension(f_ldu, *), intent(out) :: f_u real(rk), dimension(f_ldvt, *), intent(out) :: f_vt real(rk), dimension(*), intent(out) :: f_work integer, dimension(*), intent(out) :: f_iwork integer, intent(out) :: f_info end subroutine dgesdd end interface m = size(A, 1) n = size(A, 2) allocate(iwork(n * 8)) ! Adjust the size as needed ! Calculate the optimal size of the work array call dgesdd('S', m, n, A, m, S, U, m, VT, n, work1, -1, iwork, info) lwork = nint(work1(1)) allocate(work(lwork)) call dgesdd('S', m, n, A, m, S, U, m, VT, n, work, lwork, iwork, info) deallocate(work) deallocate(iwork) end subroutine gesdd_rel