You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

zgesvdx.f 29 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. *> \brief <b> ZGESVDX computes the singular value decomposition (SVD) for GE matrices</b>
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download ZGESVDX + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgesvdx.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgesvdx.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgesvdx.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE ZGESVDX( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
  22. * $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
  23. * $ LWORK, RWORK, IWORK, INFO )
  24. *
  25. *
  26. * .. Scalar Arguments ..
  27. * CHARACTER JOBU, JOBVT, RANGE
  28. * INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
  29. * DOUBLE PRECISION VL, VU
  30. * ..
  31. * .. Array Arguments ..
  32. * INTEGER IWORK( * )
  33. * DOUBLE PRECISION S( * ), RWORK( * )
  34. * COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
  35. * $ WORK( * )
  36. * ..
  37. *
  38. *
  39. *> \par Purpose:
  40. * =============
  41. *>
  42. *> \verbatim
  43. *>
  44. *> ZGESVDX computes the singular value decomposition (SVD) of a complex
  45. *> M-by-N matrix A, optionally computing the left and/or right singular
  46. *> vectors. The SVD is written
  47. *>
  48. *> A = U * SIGMA * transpose(V)
  49. *>
  50. *> where SIGMA is an M-by-N matrix which is zero except for its
  51. *> min(m,n) diagonal elements, U is an M-by-M unitary matrix, and
  52. *> V is an N-by-N unitary matrix. The diagonal elements of SIGMA
  53. *> are the singular values of A; they are real and non-negative, and
  54. *> are returned in descending order. The first min(m,n) columns of
  55. *> U and V are the left and right singular vectors of A.
  56. *>
  57. *> ZGESVDX uses an eigenvalue problem for obtaining the SVD, which
  58. *> allows for the computation of a subset of singular values and
  59. *> vectors. See DBDSVDX for details.
  60. *>
  61. *> Note that the routine returns V**T, not V.
  62. *> \endverbatim
  63. *
  64. * Arguments:
  65. * ==========
  66. *
  67. *> \param[in] JOBU
  68. *> \verbatim
  69. *> JOBU is CHARACTER*1
  70. *> Specifies options for computing all or part of the matrix U:
  71. *> = 'V': the first min(m,n) columns of U (the left singular
  72. *> vectors) or as specified by RANGE are returned in
  73. *> the array U;
  74. *> = 'N': no columns of U (no left singular vectors) are
  75. *> computed.
  76. *> \endverbatim
  77. *>
  78. *> \param[in] JOBVT
  79. *> \verbatim
  80. *> JOBVT is CHARACTER*1
  81. *> Specifies options for computing all or part of the matrix
  82. *> V**T:
  83. *> = 'V': the first min(m,n) rows of V**T (the right singular
  84. *> vectors) or as specified by RANGE are returned in
  85. *> the array VT;
  86. *> = 'N': no rows of V**T (no right singular vectors) are
  87. *> computed.
  88. *> \endverbatim
  89. *>
  90. *> \param[in] RANGE
  91. *> \verbatim
  92. *> RANGE is CHARACTER*1
  93. *> = 'A': all singular values will be found.
  94. *> = 'V': all singular values in the half-open interval (VL,VU]
  95. *> will be found.
  96. *> = 'I': the IL-th through IU-th singular values will be found.
  97. *> \endverbatim
  98. *>
  99. *> \param[in] M
  100. *> \verbatim
  101. *> M is INTEGER
  102. *> The number of rows of the input matrix A. M >= 0.
  103. *> \endverbatim
  104. *>
  105. *> \param[in] N
  106. *> \verbatim
  107. *> N is INTEGER
  108. *> The number of columns of the input matrix A. N >= 0.
  109. *> \endverbatim
  110. *>
  111. *> \param[in,out] A
  112. *> \verbatim
  113. *> A is COMPLEX*16 array, dimension (LDA,N)
  114. *> On entry, the M-by-N matrix A.
  115. *> On exit, the contents of A are destroyed.
  116. *> \endverbatim
  117. *>
  118. *> \param[in] LDA
  119. *> \verbatim
  120. *> LDA is INTEGER
  121. *> The leading dimension of the array A. LDA >= max(1,M).
  122. *> \endverbatim
  123. *>
  124. *> \param[in] VL
  125. *> \verbatim
  126. *> VL is DOUBLE PRECISION
  127. *> If RANGE='V', the lower bound of the interval to
  128. *> be searched for singular values. VU > VL.
  129. *> Not referenced if RANGE = 'A' or 'I'.
  130. *> \endverbatim
  131. *>
  132. *> \param[in] VU
  133. *> \verbatim
  134. *> VU is DOUBLE PRECISION
  135. *> If RANGE='V', the upper bound of the interval to
  136. *> be searched for singular values. VU > VL.
  137. *> Not referenced if RANGE = 'A' or 'I'.
  138. *> \endverbatim
  139. *>
  140. *> \param[in] IL
  141. *> \verbatim
  142. *> IL is INTEGER
  143. *> If RANGE='I', the index of the
  144. *> smallest singular value to be returned.
  145. *> 1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
  146. *> Not referenced if RANGE = 'A' or 'V'.
  147. *> \endverbatim
  148. *>
  149. *> \param[in] IU
  150. *> \verbatim
  151. *> IU is INTEGER
  152. *> If RANGE='I', the index of the
  153. *> largest singular value to be returned.
  154. *> 1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
  155. *> Not referenced if RANGE = 'A' or 'V'.
  156. *> \endverbatim
  157. *>
  158. *> \param[out] NS
  159. *> \verbatim
  160. *> NS is INTEGER
  161. *> The total number of singular values found,
  162. *> 0 <= NS <= min(M,N).
  163. *> If RANGE = 'A', NS = min(M,N); if RANGE = 'I', NS = IU-IL+1.
  164. *> \endverbatim
  165. *>
  166. *> \param[out] S
  167. *> \verbatim
  168. *> S is DOUBLE PRECISION array, dimension (min(M,N))
  169. *> The singular values of A, sorted so that S(i) >= S(i+1).
  170. *> \endverbatim
  171. *>
  172. *> \param[out] U
  173. *> \verbatim
  174. *> U is COMPLEX*16 array, dimension (LDU,UCOL)
  175. *> If JOBU = 'V', U contains columns of U (the left singular
  176. *> vectors, stored columnwise) as specified by RANGE; if
  177. *> JOBU = 'N', U is not referenced.
  178. *> Note: The user must ensure that UCOL >= NS; if RANGE = 'V',
  179. *> the exact value of NS is not known in advance and an upper
  180. *> bound must be used.
  181. *> \endverbatim
  182. *>
  183. *> \param[in] LDU
  184. *> \verbatim
  185. *> LDU is INTEGER
  186. *> The leading dimension of the array U. LDU >= 1; if
  187. *> JOBU = 'V', LDU >= M.
  188. *> \endverbatim
  189. *>
  190. *> \param[out] VT
  191. *> \verbatim
  192. *> VT is COMPLEX*16 array, dimension (LDVT,N)
  193. *> If JOBVT = 'V', VT contains the rows of V**T (the right singular
  194. *> vectors, stored rowwise) as specified by RANGE; if JOBVT = 'N',
  195. *> VT is not referenced.
  196. *> Note: The user must ensure that LDVT >= NS; if RANGE = 'V',
  197. *> the exact value of NS is not known in advance and an upper
  198. *> bound must be used.
  199. *> \endverbatim
  200. *>
  201. *> \param[in] LDVT
  202. *> \verbatim
  203. *> LDVT is INTEGER
  204. *> The leading dimension of the array VT. LDVT >= 1; if
  205. *> JOBVT = 'V', LDVT >= NS (see above).
  206. *> \endverbatim
  207. *>
  208. *> \param[out] WORK
  209. *> \verbatim
  210. *> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
  211. *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
  212. *> \endverbatim
  213. *>
  214. *> \param[in] LWORK
  215. *> \verbatim
  216. *> LWORK is INTEGER
  217. *> The dimension of the array WORK.
  218. *> LWORK >= MAX(1,MIN(M,N)*(MIN(M,N)+4)) for the paths (see
  219. *> comments inside the code):
  220. *> - PATH 1 (M much larger than N)
  221. *> - PATH 1t (N much larger than M)
  222. *> LWORK >= MAX(1,MIN(M,N)*2+MAX(M,N)) for the other paths.
  223. *> For good performance, LWORK should generally be larger.
  224. *>
  225. *> If LWORK = -1, then a workspace query is assumed; the routine
  226. *> only calculates the optimal size of the WORK array, returns
  227. *> this value as the first entry of the WORK array, and no error
  228. *> message related to LWORK is issued by XERBLA.
  229. *> \endverbatim
  230. *>
  231. *> \param[out] RWORK
  232. *> \verbatim
  233. *> RWORK is DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
  234. *> LRWORK >= MIN(M,N)*(MIN(M,N)*2+15*MIN(M,N)).
  235. *> \endverbatim
  236. *>
  237. *> \param[out] IWORK
  238. *> \verbatim
  239. *> IWORK is INTEGER array, dimension (12*MIN(M,N))
  240. *> If INFO = 0, the first NS elements of IWORK are zero. If INFO > 0,
  241. *> then IWORK contains the indices of the eigenvectors that failed
  242. *> to converge in DBDSVDX/DSTEVX.
  243. *> \endverbatim
  244. *>
  245. *> \param[out] INFO
  246. *> \verbatim
  247. *> INFO is INTEGER
  248. *> = 0: successful exit
  249. *> < 0: if INFO = -i, the i-th argument had an illegal value
  250. *> > 0: if INFO = i, then i eigenvectors failed to converge
  251. *> in DBDSVDX/DSTEVX.
  252. *> if INFO = N*2 + 1, an internal error occurred in
  253. *> DBDSVDX
  254. *> \endverbatim
  255. *
  256. * Authors:
  257. * ========
  258. *
  259. *> \author Univ. of Tennessee
  260. *> \author Univ. of California Berkeley
  261. *> \author Univ. of Colorado Denver
  262. *> \author NAG Ltd.
  263. *
  264. *> \date June 2016
  265. *
  266. *> \ingroup complex16GEsing
  267. *
  268. * =====================================================================
  269. SUBROUTINE ZGESVDX( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
  270. $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
  271. $ LWORK, RWORK, IWORK, INFO )
  272. *
  273. * -- LAPACK driver routine (version 3.8.0) --
  274. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  275. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  276. * June 2016
  277. *
  278. * .. Scalar Arguments ..
  279. CHARACTER JOBU, JOBVT, RANGE
  280. INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
  281. DOUBLE PRECISION VL, VU
  282. * ..
  283. * .. Array Arguments ..
  284. INTEGER IWORK( * )
  285. DOUBLE PRECISION S( * ), RWORK( * )
  286. COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
  287. $ WORK( * )
  288. * ..
  289. *
  290. * =====================================================================
  291. *
  292. * .. Parameters ..
  293. COMPLEX*16 CZERO, CONE
  294. PARAMETER ( CZERO = ( 0.0D0, 0.0D0 ),
  295. $ CONE = ( 1.0D0, 0.0D0 ) )
  296. DOUBLE PRECISION ZERO, ONE
  297. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  298. * ..
  299. * .. Local Scalars ..
  300. CHARACTER JOBZ, RNGTGK
  301. LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
  302. INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
  303. $ ITAU, ITAUP, ITAUQ, ITEMP, ITEMPR, ITGKZ,
  304. $ IUTGK, J, K, MAXWRK, MINMN, MINWRK, MNTHR
  305. DOUBLE PRECISION ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
  306. * ..
  307. * .. Local Arrays ..
  308. DOUBLE PRECISION DUM( 1 )
  309. * ..
  310. * .. External Subroutines ..
  311. EXTERNAL ZGEBRD, ZGELQF, ZGEQRF, ZLASCL, ZLASET, ZLACPY,
  312. $ ZUNMLQ, ZUNMBR, ZUNMQR, DBDSVDX, DLASCL, XERBLA
  313. * ..
  314. * .. External Functions ..
  315. LOGICAL LSAME
  316. INTEGER ILAENV
  317. DOUBLE PRECISION DLAMCH, ZLANGE
  318. EXTERNAL LSAME, ILAENV, DLAMCH, ZLANGE
  319. * ..
  320. * .. Intrinsic Functions ..
  321. INTRINSIC MAX, MIN, SQRT
  322. * ..
  323. * .. Executable Statements ..
  324. *
  325. * Test the input arguments.
  326. *
  327. NS = 0
  328. INFO = 0
  329. ABSTOL = 2*DLAMCH('S')
  330. LQUERY = ( LWORK.EQ.-1 )
  331. MINMN = MIN( M, N )
  332. WANTU = LSAME( JOBU, 'V' )
  333. WANTVT = LSAME( JOBVT, 'V' )
  334. IF( WANTU .OR. WANTVT ) THEN
  335. JOBZ = 'V'
  336. ELSE
  337. JOBZ = 'N'
  338. END IF
  339. ALLS = LSAME( RANGE, 'A' )
  340. VALS = LSAME( RANGE, 'V' )
  341. INDS = LSAME( RANGE, 'I' )
  342. *
  343. INFO = 0
  344. IF( .NOT.LSAME( JOBU, 'V' ) .AND.
  345. $ .NOT.LSAME( JOBU, 'N' ) ) THEN
  346. INFO = -1
  347. ELSE IF( .NOT.LSAME( JOBVT, 'V' ) .AND.
  348. $ .NOT.LSAME( JOBVT, 'N' ) ) THEN
  349. INFO = -2
  350. ELSE IF( .NOT.( ALLS .OR. VALS .OR. INDS ) ) THEN
  351. INFO = -3
  352. ELSE IF( M.LT.0 ) THEN
  353. INFO = -4
  354. ELSE IF( N.LT.0 ) THEN
  355. INFO = -5
  356. ELSE IF( M.GT.LDA ) THEN
  357. INFO = -7
  358. ELSE IF( MINMN.GT.0 ) THEN
  359. IF( VALS ) THEN
  360. IF( VL.LT.ZERO ) THEN
  361. INFO = -8
  362. ELSE IF( VU.LE.VL ) THEN
  363. INFO = -9
  364. END IF
  365. ELSE IF( INDS ) THEN
  366. IF( IL.LT.1 .OR. IL.GT.MAX( 1, MINMN ) ) THEN
  367. INFO = -10
  368. ELSE IF( IU.LT.MIN( MINMN, IL ) .OR. IU.GT.MINMN ) THEN
  369. INFO = -11
  370. END IF
  371. END IF
  372. IF( INFO.EQ.0 ) THEN
  373. IF( WANTU .AND. LDU.LT.M ) THEN
  374. INFO = -15
  375. ELSE IF( WANTVT ) THEN
  376. IF( INDS ) THEN
  377. IF( LDVT.LT.IU-IL+1 ) THEN
  378. INFO = -17
  379. END IF
  380. ELSE IF( LDVT.LT.MINMN ) THEN
  381. INFO = -17
  382. END IF
  383. END IF
  384. END IF
  385. END IF
  386. *
  387. * Compute workspace
  388. * (Note: Comments in the code beginning "Workspace:" describe the
  389. * minimal amount of workspace needed at that point in the code,
  390. * as well as the preferred amount for good performance.
  391. * NB refers to the optimal block size for the immediately
  392. * following subroutine, as returned by ILAENV.)
  393. *
  394. IF( INFO.EQ.0 ) THEN
  395. MINWRK = 1
  396. MAXWRK = 1
  397. IF( MINMN.GT.0 ) THEN
  398. IF( M.GE.N ) THEN
  399. MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
  400. IF( M.GE.MNTHR ) THEN
  401. *
  402. * Path 1 (M much larger than N)
  403. *
  404. MINWRK = N*(N+5)
  405. MAXWRK = N + N*ILAENV(1,'ZGEQRF',' ',M,N,-1,-1)
  406. MAXWRK = MAX(MAXWRK,
  407. $ N*N+2*N+2*N*ILAENV(1,'ZGEBRD',' ',N,N,-1,-1))
  408. IF (WANTU .OR. WANTVT) THEN
  409. MAXWRK = MAX(MAXWRK,
  410. $ N*N+2*N+N*ILAENV(1,'ZUNMQR','LN',N,N,N,-1))
  411. END IF
  412. ELSE
  413. *
  414. * Path 2 (M at least N, but not much larger)
  415. *
  416. MINWRK = 3*N + M
  417. MAXWRK = 2*N + (M+N)*ILAENV(1,'ZGEBRD',' ',M,N,-1,-1)
  418. IF (WANTU .OR. WANTVT) THEN
  419. MAXWRK = MAX(MAXWRK,
  420. $ 2*N+N*ILAENV(1,'ZUNMQR','LN',N,N,N,-1))
  421. END IF
  422. END IF
  423. ELSE
  424. MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
  425. IF( N.GE.MNTHR ) THEN
  426. *
  427. * Path 1t (N much larger than M)
  428. *
  429. MINWRK = M*(M+5)
  430. MAXWRK = M + M*ILAENV(1,'ZGELQF',' ',M,N,-1,-1)
  431. MAXWRK = MAX(MAXWRK,
  432. $ M*M+2*M+2*M*ILAENV(1,'ZGEBRD',' ',M,M,-1,-1))
  433. IF (WANTU .OR. WANTVT) THEN
  434. MAXWRK = MAX(MAXWRK,
  435. $ M*M+2*M+M*ILAENV(1,'ZUNMQR','LN',M,M,M,-1))
  436. END IF
  437. ELSE
  438. *
  439. * Path 2t (N greater than M, but not much larger)
  440. *
  441. *
  442. MINWRK = 3*M + N
  443. MAXWRK = 2*M + (M+N)*ILAENV(1,'ZGEBRD',' ',M,N,-1,-1)
  444. IF (WANTU .OR. WANTVT) THEN
  445. MAXWRK = MAX(MAXWRK,
  446. $ 2*M+M*ILAENV(1,'ZUNMQR','LN',M,M,M,-1))
  447. END IF
  448. END IF
  449. END IF
  450. END IF
  451. MAXWRK = MAX( MAXWRK, MINWRK )
  452. WORK( 1 ) = DCMPLX( DBLE( MAXWRK ), ZERO )
  453. *
  454. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  455. INFO = -19
  456. END IF
  457. END IF
  458. *
  459. IF( INFO.NE.0 ) THEN
  460. CALL XERBLA( 'ZGESVDX', -INFO )
  461. RETURN
  462. ELSE IF( LQUERY ) THEN
  463. RETURN
  464. END IF
  465. *
  466. * Quick return if possible
  467. *
  468. IF( M.EQ.0 .OR. N.EQ.0 ) THEN
  469. RETURN
  470. END IF
  471. *
  472. * Set singular values indices accord to RANGE='A'.
  473. *
  474. IF( ALLS ) THEN
  475. RNGTGK = 'I'
  476. ILTGK = 1
  477. IUTGK = MIN( M, N )
  478. ELSE IF( INDS ) THEN
  479. RNGTGK = 'I'
  480. ILTGK = IL
  481. IUTGK = IU
  482. ELSE
  483. RNGTGK = 'V'
  484. ILTGK = 0
  485. IUTGK = 0
  486. END IF
  487. *
  488. * Get machine constants
  489. *
  490. EPS = DLAMCH( 'P' )
  491. SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
  492. BIGNUM = ONE / SMLNUM
  493. *
  494. * Scale A if max element outside range [SMLNUM,BIGNUM]
  495. *
  496. ANRM = ZLANGE( 'M', M, N, A, LDA, DUM )
  497. ISCL = 0
  498. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  499. ISCL = 1
  500. CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
  501. ELSE IF( ANRM.GT.BIGNUM ) THEN
  502. ISCL = 1
  503. CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
  504. END IF
  505. *
  506. IF( M.GE.N ) THEN
  507. *
  508. * A has at least as many rows as columns. If A has sufficiently
  509. * more rows than columns, first reduce A using the QR
  510. * decomposition.
  511. *
  512. IF( M.GE.MNTHR ) THEN
  513. *
  514. * Path 1 (M much larger than N):
  515. * A = Q * R = Q * ( QB * B * PB**T )
  516. * = Q * ( QB * ( UB * S * VB**T ) * PB**T )
  517. * U = Q * QB * UB; V**T = VB**T * PB**T
  518. *
  519. * Compute A=Q*R
  520. * (Workspace: need 2*N, prefer N+N*NB)
  521. *
  522. ITAU = 1
  523. ITEMP = ITAU + N
  524. CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( ITEMP ),
  525. $ LWORK-ITEMP+1, INFO )
  526. *
  527. * Copy R into WORK and bidiagonalize it:
  528. * (Workspace: need N*N+3*N, prefer N*N+N+2*N*NB)
  529. *
  530. IQRF = ITEMP
  531. ITAUQ = ITEMP + N*N
  532. ITAUP = ITAUQ + N
  533. ITEMP = ITAUP + N
  534. ID = 1
  535. IE = ID + N
  536. ITGKZ = IE + N
  537. CALL ZLACPY( 'U', N, N, A, LDA, WORK( IQRF ), N )
  538. CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
  539. $ WORK( IQRF+1 ), N )
  540. CALL ZGEBRD( N, N, WORK( IQRF ), N, RWORK( ID ),
  541. $ RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
  542. $ WORK( ITEMP ), LWORK-ITEMP+1, INFO )
  543. ITEMPR = ITGKZ + N*(N*2+1)
  544. *
  545. * Solve eigenvalue problem TGK*Z=Z*S.
  546. * (Workspace: need 2*N*N+14*N)
  547. *
  548. CALL DBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
  549. $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
  550. $ RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
  551. $ IWORK, INFO)
  552. *
  553. * If needed, compute left singular vectors.
  554. *
  555. IF( WANTU ) THEN
  556. K = ITGKZ
  557. DO I = 1, NS
  558. DO J = 1, N
  559. U( J, I ) = DCMPLX( RWORK( K ), ZERO )
  560. K = K + 1
  561. END DO
  562. K = K + N
  563. END DO
  564. CALL ZLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
  565. *
  566. * Call ZUNMBR to compute QB*UB.
  567. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  568. *
  569. CALL ZUNMBR( 'Q', 'L', 'N', N, NS, N, WORK( IQRF ), N,
  570. $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
  571. $ LWORK-ITEMP+1, INFO )
  572. *
  573. * Call ZUNMQR to compute Q*(QB*UB).
  574. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  575. *
  576. CALL ZUNMQR( 'L', 'N', M, NS, N, A, LDA,
  577. $ WORK( ITAU ), U, LDU, WORK( ITEMP ),
  578. $ LWORK-ITEMP+1, INFO )
  579. END IF
  580. *
  581. * If needed, compute right singular vectors.
  582. *
  583. IF( WANTVT) THEN
  584. K = ITGKZ + N
  585. DO I = 1, NS
  586. DO J = 1, N
  587. VT( I, J ) = DCMPLX( RWORK( K ), ZERO )
  588. K = K + 1
  589. END DO
  590. K = K + N
  591. END DO
  592. *
  593. * Call ZUNMBR to compute VB**T * PB**T
  594. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  595. *
  596. CALL ZUNMBR( 'P', 'R', 'C', NS, N, N, WORK( IQRF ), N,
  597. $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
  598. $ LWORK-ITEMP+1, INFO )
  599. END IF
  600. ELSE
  601. *
  602. * Path 2 (M at least N, but not much larger)
  603. * Reduce A to bidiagonal form without QR decomposition
  604. * A = QB * B * PB**T = QB * ( UB * S * VB**T ) * PB**T
  605. * U = QB * UB; V**T = VB**T * PB**T
  606. *
  607. * Bidiagonalize A
  608. * (Workspace: need 2*N+M, prefer 2*N+(M+N)*NB)
  609. *
  610. ITAUQ = 1
  611. ITAUP = ITAUQ + N
  612. ITEMP = ITAUP + N
  613. ID = 1
  614. IE = ID + N
  615. ITGKZ = IE + N
  616. CALL ZGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ),
  617. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
  618. $ LWORK-ITEMP+1, INFO )
  619. ITEMPR = ITGKZ + N*(N*2+1)
  620. *
  621. * Solve eigenvalue problem TGK*Z=Z*S.
  622. * (Workspace: need 2*N*N+14*N)
  623. *
  624. CALL DBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
  625. $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
  626. $ RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
  627. $ IWORK, INFO)
  628. *
  629. * If needed, compute left singular vectors.
  630. *
  631. IF( WANTU ) THEN
  632. K = ITGKZ
  633. DO I = 1, NS
  634. DO J = 1, N
  635. U( J, I ) = DCMPLX( RWORK( K ), ZERO )
  636. K = K + 1
  637. END DO
  638. K = K + N
  639. END DO
  640. CALL ZLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
  641. *
  642. * Call ZUNMBR to compute QB*UB.
  643. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  644. *
  645. CALL ZUNMBR( 'Q', 'L', 'N', M, NS, N, A, LDA,
  646. $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
  647. $ LWORK-ITEMP+1, IERR )
  648. END IF
  649. *
  650. * If needed, compute right singular vectors.
  651. *
  652. IF( WANTVT) THEN
  653. K = ITGKZ + N
  654. DO I = 1, NS
  655. DO J = 1, N
  656. VT( I, J ) = DCMPLX( RWORK( K ), ZERO )
  657. K = K + 1
  658. END DO
  659. K = K + N
  660. END DO
  661. *
  662. * Call ZUNMBR to compute VB**T * PB**T
  663. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  664. *
  665. CALL ZUNMBR( 'P', 'R', 'C', NS, N, N, A, LDA,
  666. $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
  667. $ LWORK-ITEMP+1, IERR )
  668. END IF
  669. END IF
  670. ELSE
  671. *
  672. * A has more columns than rows. If A has sufficiently more
  673. * columns than rows, first reduce A using the LQ decomposition.
  674. *
  675. IF( N.GE.MNTHR ) THEN
  676. *
  677. * Path 1t (N much larger than M):
  678. * A = L * Q = ( QB * B * PB**T ) * Q
  679. * = ( QB * ( UB * S * VB**T ) * PB**T ) * Q
  680. * U = QB * UB ; V**T = VB**T * PB**T * Q
  681. *
  682. * Compute A=L*Q
  683. * (Workspace: need 2*M, prefer M+M*NB)
  684. *
  685. ITAU = 1
  686. ITEMP = ITAU + M
  687. CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( ITEMP ),
  688. $ LWORK-ITEMP+1, INFO )
  689. * Copy L into WORK and bidiagonalize it:
  690. * (Workspace in WORK( ITEMP ): need M*M+3*M, prefer M*M+M+2*M*NB)
  691. *
  692. ILQF = ITEMP
  693. ITAUQ = ILQF + M*M
  694. ITAUP = ITAUQ + M
  695. ITEMP = ITAUP + M
  696. ID = 1
  697. IE = ID + M
  698. ITGKZ = IE + M
  699. CALL ZLACPY( 'L', M, M, A, LDA, WORK( ILQF ), M )
  700. CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
  701. $ WORK( ILQF+M ), M )
  702. CALL ZGEBRD( M, M, WORK( ILQF ), M, RWORK( ID ),
  703. $ RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
  704. $ WORK( ITEMP ), LWORK-ITEMP+1, INFO )
  705. ITEMPR = ITGKZ + M*(M*2+1)
  706. *
  707. * Solve eigenvalue problem TGK*Z=Z*S.
  708. * (Workspace: need 2*M*M+14*M)
  709. *
  710. CALL DBDSVDX( 'U', JOBZ, RNGTGK, M, RWORK( ID ),
  711. $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
  712. $ RWORK( ITGKZ ), M*2, RWORK( ITEMPR ),
  713. $ IWORK, INFO)
  714. *
  715. * If needed, compute left singular vectors.
  716. *
  717. IF( WANTU ) THEN
  718. K = ITGKZ
  719. DO I = 1, NS
  720. DO J = 1, M
  721. U( J, I ) = DCMPLX( RWORK( K ), ZERO )
  722. K = K + 1
  723. END DO
  724. K = K + M
  725. END DO
  726. *
  727. * Call ZUNMBR to compute QB*UB.
  728. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  729. *
  730. CALL ZUNMBR( 'Q', 'L', 'N', M, NS, M, WORK( ILQF ), M,
  731. $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
  732. $ LWORK-ITEMP+1, INFO )
  733. END IF
  734. *
  735. * If needed, compute right singular vectors.
  736. *
  737. IF( WANTVT) THEN
  738. K = ITGKZ + M
  739. DO I = 1, NS
  740. DO J = 1, M
  741. VT( I, J ) = DCMPLX( RWORK( K ), ZERO )
  742. K = K + 1
  743. END DO
  744. K = K + M
  745. END DO
  746. CALL ZLASET( 'A', NS, N-M, CZERO, CZERO,
  747. $ VT( 1,M+1 ), LDVT )
  748. *
  749. * Call ZUNMBR to compute (VB**T)*(PB**T)
  750. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  751. *
  752. CALL ZUNMBR( 'P', 'R', 'C', NS, M, M, WORK( ILQF ), M,
  753. $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
  754. $ LWORK-ITEMP+1, INFO )
  755. *
  756. * Call ZUNMLQ to compute ((VB**T)*(PB**T))*Q.
  757. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  758. *
  759. CALL ZUNMLQ( 'R', 'N', NS, N, M, A, LDA,
  760. $ WORK( ITAU ), VT, LDVT, WORK( ITEMP ),
  761. $ LWORK-ITEMP+1, INFO )
  762. END IF
  763. ELSE
  764. *
  765. * Path 2t (N greater than M, but not much larger)
  766. * Reduce to bidiagonal form without LQ decomposition
  767. * A = QB * B * PB**T = QB * ( UB * S * VB**T ) * PB**T
  768. * U = QB * UB; V**T = VB**T * PB**T
  769. *
  770. * Bidiagonalize A
  771. * (Workspace: need 2*M+N, prefer 2*M+(M+N)*NB)
  772. *
  773. ITAUQ = 1
  774. ITAUP = ITAUQ + M
  775. ITEMP = ITAUP + M
  776. ID = 1
  777. IE = ID + M
  778. ITGKZ = IE + M
  779. CALL ZGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ),
  780. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
  781. $ LWORK-ITEMP+1, INFO )
  782. ITEMPR = ITGKZ + M*(M*2+1)
  783. *
  784. * Solve eigenvalue problem TGK*Z=Z*S.
  785. * (Workspace: need 2*M*M+14*M)
  786. *
  787. CALL DBDSVDX( 'L', JOBZ, RNGTGK, M, RWORK( ID ),
  788. $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
  789. $ RWORK( ITGKZ ), M*2, RWORK( ITEMPR ),
  790. $ IWORK, INFO)
  791. *
  792. * If needed, compute left singular vectors.
  793. *
  794. IF( WANTU ) THEN
  795. K = ITGKZ
  796. DO I = 1, NS
  797. DO J = 1, M
  798. U( J, I ) = DCMPLX( RWORK( K ), ZERO )
  799. K = K + 1
  800. END DO
  801. K = K + M
  802. END DO
  803. *
  804. * Call ZUNMBR to compute QB*UB.
  805. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  806. *
  807. CALL ZUNMBR( 'Q', 'L', 'N', M, NS, N, A, LDA,
  808. $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
  809. $ LWORK-ITEMP+1, INFO )
  810. END IF
  811. *
  812. * If needed, compute right singular vectors.
  813. *
  814. IF( WANTVT) THEN
  815. K = ITGKZ + M
  816. DO I = 1, NS
  817. DO J = 1, M
  818. VT( I, J ) = DCMPLX( RWORK( K ), ZERO )
  819. K = K + 1
  820. END DO
  821. K = K + M
  822. END DO
  823. CALL ZLASET( 'A', NS, N-M, CZERO, CZERO,
  824. $ VT( 1,M+1 ), LDVT )
  825. *
  826. * Call ZUNMBR to compute VB**T * PB**T
  827. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  828. *
  829. CALL ZUNMBR( 'P', 'R', 'C', NS, N, M, A, LDA,
  830. $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
  831. $ LWORK-ITEMP+1, INFO )
  832. END IF
  833. END IF
  834. END IF
  835. *
  836. * Undo scaling if necessary
  837. *
  838. IF( ISCL.EQ.1 ) THEN
  839. IF( ANRM.GT.BIGNUM )
  840. $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1,
  841. $ S, MINMN, INFO )
  842. IF( ANRM.LT.SMLNUM )
  843. $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1,
  844. $ S, MINMN, INFO )
  845. END IF
  846. *
  847. * Return optimal workspace in WORK(1)
  848. *
  849. WORK( 1 ) = DCMPLX( DBLE( MAXWRK ), ZERO )
  850. *
  851. RETURN
  852. *
  853. * End of ZGESVDX
  854. *
  855. END