11#:include "common.fypp"
2+ #:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
23module stdlib_linalg_svd
4+ !! Singular-Value Decomposition
35 use stdlib_linalg_constants
4- use stdlib_linalg_blas
5- use stdlib_linalg_lapack
6- use stdlib_linalg_state
7- use iso_fortran_env,only:real32,real64,real128,int8,int16,int32,int64,stderr => error_unit
6+ use stdlib_linalg_lapack, only: gesdd
7+ use stdlib_linalg_state, only: linalg_state_type, linalg_error_handling, LINALG_ERROR, &
8+ LINALG_INTERNAL_ERROR, LINALG_VALUE_ERROR, LINALG_SUCCESS
89 implicit none(type,external)
9- private
10+
11+ character(*), parameter :: this = 'svd'
1012
1113 !> Singular value decomposition
1214 public :: svd
@@ -17,14 +19,18 @@ module stdlib_linalg_svd
1719 ! Scipy: svd(a, full_matrices=True, compute_uv=True, overwrite_a=False, check_finite=True, lapack_driver='gesdd')
1820
1921 interface svd
20- #:for rk,rt,ri in ALL_KINDS_TYPES
22+ #:for rk,rt,ri in RC_KINDS_TYPES
23+ #:if rk!="xdp"
2124 module procedure stdlib_linalg_svd_${ri}$
25+ #:endif
2226 #:endfor
2327 end interface svd
2428
2529 interface svdvals
26- #:for rk,rt,ri in ALL_KINDS_TYPES
30+ #:for rk,rt,ri in RC_KINDS_TYPES
31+ #:if rk!="xdp"
2732 module procedure stdlib_linalg_svdvals_${ri}$
33+ #:endif
2834 #:endfor
2935 end interface svdvals
3036
@@ -40,15 +46,15 @@ module stdlib_linalg_svd
4046 !> Do not return either U or VT (singular values array only)
4147 character, parameter :: GESDD_SINGVAL_ONLY = 'N'
4248
43- character(*), parameter :: this = 'svd'
49+
4450
4551
4652 contains
4753
4854 !> Process GESDD output flag
49- elemental subroutine gesdd_info (err,info,m,n)
55+ elemental subroutine handle_gesdd_info (err,info,m,n)
5056 !> Error handler
51- type(linalg_state ), intent(inout) :: err
57+ type(linalg_state_type ), intent(inout) :: err
5258 !> GESDD return flag
5359 integer(ilp), intent(in) :: info
5460 !> Input matrix size
@@ -59,32 +65,33 @@ module stdlib_linalg_svd
5965 ! Success!
6066 err%state = LINALG_SUCCESS
6167 case (-1)
62- err = linalg_state (this,LINALG_INTERNAL_ERROR,'Invalid task ID on input to GESDD.')
68+ err = linalg_state_type (this,LINALG_INTERNAL_ERROR,'Invalid task ID on input to GESDD.')
6369 case (-5,-3:-2)
64- err = linalg_state (this,LINALG_VALUE_ERROR,'invalid matrix size: a=[',m,',',n,']')
70+ err = linalg_state_type (this,LINALG_VALUE_ERROR,'invalid matrix size: a=[',m,',',n,']')
6571 case (-8)
66- err = linalg_state (this,LINALG_VALUE_ERROR,'invalid matrix U size, with a=[',m,',',n,']')
72+ err = linalg_state_type (this,LINALG_VALUE_ERROR,'invalid matrix U size, with a=[',m,',',n,']')
6773 case (-10)
68- err = linalg_state (this,LINALG_VALUE_ERROR,'invalid matrix V size, with a=[',m,',',n,']')
74+ err = linalg_state_type (this,LINALG_VALUE_ERROR,'invalid matrix V size, with a=[',m,',',n,']')
6975 case (-4)
70- err = linalg_state (this,LINALG_VALUE_ERROR,'A contains invalid/NaN values.')
76+ err = linalg_state_type (this,LINALG_VALUE_ERROR,'A contains invalid/NaN values.')
7177 case (1:)
72- err = linalg_state (this,LINALG_ERROR,'SVD computation did not converge.')
78+ err = linalg_state_type (this,LINALG_ERROR,'SVD computation did not converge.')
7379 case default
74- err = linalg_state (this,LINALG_INTERNAL_ERROR,'Unknown error returned by GESDD.')
80+ err = linalg_state_type (this,LINALG_INTERNAL_ERROR,'Unknown error returned by GESDD.')
7581 end select
7682
77- end subroutine gesdd_info
83+ end subroutine handle_gesdd_info
7884
7985
80- #:for rk,rt,ri in ALL_KINDS_TYPES
86+ #:for rk,rt,ri in RC_KINDS_TYPES
87+ #:if rk!="xdp"
8188
8289 !> Singular values of matrix A
8390 function stdlib_linalg_svdvals_${ri}$(a,err) result(s)
8491 !> Input matrix A[m,n]
8592 ${rt}$, intent(in), target :: a(:,:)
8693 !> [optional] state return flag. On error if not requested, the code will stop
87- type(linalg_state ), optional, intent(out) :: err
94+ type(linalg_state_type ), optional, intent(out) :: err
8895 !> Array of singular values
8996 real(${rk}$), allocatable :: s(:)
9097
@@ -123,10 +130,10 @@ module stdlib_linalg_svd
123130 !> they are shape(u)==[m,k] and shape(vh)==[k,n] with k=min(m,n)
124131 logical(lk), optional, intent(in) :: full_matrices
125132 !> [optional] state return flag. On error if not requested, the code will stop
126- type(linalg_state ), optional, intent(out) :: err
133+ type(linalg_state_type ), optional, intent(out) :: err
127134
128135 !> Local variables
129- type(linalg_state ) :: err0
136+ type(linalg_state_type ) :: err0
130137 integer(ilp) :: m,n,lda,ldu,ldvt,info,k,lwork,liwork,lrwork
131138 integer(ilp), allocatable :: iwork(:)
132139 logical(lk) :: copy_a,full_storage,compute_uv,alloc_u,alloc_vt,can_overwrite_a
@@ -143,12 +150,12 @@ module stdlib_linalg_svd
143150 lda = m
144151
145152 if (.not.k>0) then
146- err0 = linalg_state (this,LINALG_VALUE_ERROR,'invalid or matrix size: a=[',m,',',n,']')
153+ err0 = linalg_state_type (this,LINALG_VALUE_ERROR,'invalid or matrix size: a=[',m,',',n,']')
147154 goto 1
148155 end if
149156
150157 if (.not.size(s,kind=ilp)>=k) then
151- err0 = linalg_state (this,LINALG_VALUE_ERROR,'singular value array has insufficient size:',&
158+ err0 = linalg_state_type (this,LINALG_VALUE_ERROR,'singular value array has insufficient size:',&
152159 ' s=[',size(s,kind=ilp),'], k=',k)
153160 goto 1
154161 endif
@@ -167,17 +174,13 @@ module stdlib_linalg_svd
167174 ! Initialize a matrix temporary
168175 if (copy_a) then
169176 allocate(amat(m,n),source=a)
170-
171- ! Check if we can overwrite A with data that will be lost
172- can_overwrite_a = merge(.not.present(u),.not.present(vt),m>=n)
173-
174177 else
175178 amat => a
176-
177- can_overwrite_a = .false.
178-
179179 endif
180-
180+
181+ ! Check if we can overwrite A with data that will be lost
182+ can_overwrite_a = copy_a .and. merge(.not.present(u),.not.present(vt),m>=n)
183+
181184 ! Full-size matrices
182185 if (present(full_matrices)) then
183186 full_storage = full_matrices
@@ -248,7 +251,7 @@ module stdlib_linalg_svd
248251
249252 call gesdd(task,m,n,amat,lda,s,umat,ldu,vtmat,ldvt,&
250253 work_dummy,lwork,#{if rt.startswith('complex')}#rwork,#{endif}#iwork,info)
251- call gesdd_info (err0,info,m,n)
254+ call handle_gesdd_info (err0,info,m,n)
252255
253256 ! Compute SVD
254257 if (info==0) then
@@ -260,7 +263,7 @@ module stdlib_linalg_svd
260263 !> Compute SVD
261264 call gesdd(task,m,n,amat,lda,s,umat,ldu,vtmat,ldvt,&
262265 work,lwork,#{if rt.startswith('comp')}#rwork,#{endif}#iwork,info)
263- call gesdd_info (err0,info,m,n)
266+ call handle_gesdd_info (err0,info,m,n)
264267
265268 endif
266269
@@ -271,6 +274,7 @@ module stdlib_linalg_svd
271274 1 call linalg_error_handling(err0,err)
272275
273276 end subroutine stdlib_linalg_svd_${ri}$
277+ #:endif
274278 #:endfor
275279
276280end module stdlib_linalg_svd
0 commit comments