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.

cgesvdx.f 29 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. *> \brief <b> CGESVDX 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 CGESVDX + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgesvdx.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgesvdx.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgesvdx.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE CGESVDX( 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. * REAL VL, VU
  30. * ..
  31. * .. Array Arguments ..
  32. * INTEGER IWORK( * )
  33. * REAL S( * ), RWORK( * )
  34. * COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
  35. * $ WORK( * )
  36. * ..
  37. *
  38. *
  39. *> \par Purpose:
  40. * =============
  41. *>
  42. *> \verbatim
  43. *>
  44. *> CGESVDX 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. *> CGESVDX uses an eigenvalue problem for obtaining the SVD, which
  58. *> allows for the computation of a subset of singular values and
  59. *> vectors. See SBDSVDX 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 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 REAL
  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 REAL
  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 REAL 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 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 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 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 REAL 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 SBDSVDX/SSTEVX.
  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 SBDSVDX/SSTEVX.
  252. *> if INFO = N*2 + 1, an internal error occurred in
  253. *> SBDSVDX
  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 complexGEsing
  267. *
  268. * =====================================================================
  269. SUBROUTINE CGESVDX( 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. REAL VL, VU
  282. * ..
  283. * .. Array Arguments ..
  284. INTEGER IWORK( * )
  285. REAL S( * ), RWORK( * )
  286. COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
  287. $ WORK( * )
  288. * ..
  289. *
  290. * =====================================================================
  291. *
  292. * .. Parameters ..
  293. COMPLEX CZERO, CONE
  294. PARAMETER ( CZERO = ( 0.0E0, 0.0E0 ),
  295. $ CONE = ( 1.0E0, 0.0E0 ) )
  296. REAL ZERO, ONE
  297. PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
  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. REAL ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
  306. * ..
  307. * .. Local Arrays ..
  308. REAL DUM( 1 )
  309. * ..
  310. * .. External Subroutines ..
  311. EXTERNAL CGEBRD, CGELQF, CGEQRF, CLASCL, CLASET,
  312. $ CUNMBR, CUNMQR, CUNMLQ, CLACPY,
  313. $ SBDSVDX, SLASCL, XERBLA
  314. * ..
  315. * .. External Functions ..
  316. LOGICAL LSAME
  317. INTEGER ILAENV
  318. REAL SLAMCH, CLANGE
  319. EXTERNAL LSAME, ILAENV, SLAMCH, CLANGE
  320. * ..
  321. * .. Intrinsic Functions ..
  322. INTRINSIC MAX, MIN, SQRT
  323. * ..
  324. * .. Executable Statements ..
  325. *
  326. * Test the input arguments.
  327. *
  328. NS = 0
  329. INFO = 0
  330. ABSTOL = 2*SLAMCH('S')
  331. LQUERY = ( LWORK.EQ.-1 )
  332. MINMN = MIN( M, N )
  333. WANTU = LSAME( JOBU, 'V' )
  334. WANTVT = LSAME( JOBVT, 'V' )
  335. IF( WANTU .OR. WANTVT ) THEN
  336. JOBZ = 'V'
  337. ELSE
  338. JOBZ = 'N'
  339. END IF
  340. ALLS = LSAME( RANGE, 'A' )
  341. VALS = LSAME( RANGE, 'V' )
  342. INDS = LSAME( RANGE, 'I' )
  343. *
  344. INFO = 0
  345. IF( .NOT.LSAME( JOBU, 'V' ) .AND.
  346. $ .NOT.LSAME( JOBU, 'N' ) ) THEN
  347. INFO = -1
  348. ELSE IF( .NOT.LSAME( JOBVT, 'V' ) .AND.
  349. $ .NOT.LSAME( JOBVT, 'N' ) ) THEN
  350. INFO = -2
  351. ELSE IF( .NOT.( ALLS .OR. VALS .OR. INDS ) ) THEN
  352. INFO = -3
  353. ELSE IF( M.LT.0 ) THEN
  354. INFO = -4
  355. ELSE IF( N.LT.0 ) THEN
  356. INFO = -5
  357. ELSE IF( M.GT.LDA ) THEN
  358. INFO = -7
  359. ELSE IF( MINMN.GT.0 ) THEN
  360. IF( VALS ) THEN
  361. IF( VL.LT.ZERO ) THEN
  362. INFO = -8
  363. ELSE IF( VU.LE.VL ) THEN
  364. INFO = -9
  365. END IF
  366. ELSE IF( INDS ) THEN
  367. IF( IL.LT.1 .OR. IL.GT.MAX( 1, MINMN ) ) THEN
  368. INFO = -10
  369. ELSE IF( IU.LT.MIN( MINMN, IL ) .OR. IU.GT.MINMN ) THEN
  370. INFO = -11
  371. END IF
  372. END IF
  373. IF( INFO.EQ.0 ) THEN
  374. IF( WANTU .AND. LDU.LT.M ) THEN
  375. INFO = -15
  376. ELSE IF( WANTVT ) THEN
  377. IF( INDS ) THEN
  378. IF( LDVT.LT.IU-IL+1 ) THEN
  379. INFO = -17
  380. END IF
  381. ELSE IF( LDVT.LT.MINMN ) THEN
  382. INFO = -17
  383. END IF
  384. END IF
  385. END IF
  386. END IF
  387. *
  388. * Compute workspace
  389. * (Note: Comments in the code beginning "Workspace:" describe the
  390. * minimal amount of workspace needed at that point in the code,
  391. * as well as the preferred amount for good performance.
  392. * NB refers to the optimal block size for the immediately
  393. * following subroutine, as returned by ILAENV.)
  394. *
  395. IF( INFO.EQ.0 ) THEN
  396. MINWRK = 1
  397. MAXWRK = 1
  398. IF( MINMN.GT.0 ) THEN
  399. IF( M.GE.N ) THEN
  400. MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
  401. IF( M.GE.MNTHR ) THEN
  402. *
  403. * Path 1 (M much larger than N)
  404. *
  405. MINWRK = N*(N+5)
  406. MAXWRK = N + N*ILAENV(1,'CGEQRF',' ',M,N,-1,-1)
  407. MAXWRK = MAX(MAXWRK,
  408. $ N*N+2*N+2*N*ILAENV(1,'CGEBRD',' ',N,N,-1,-1))
  409. IF (WANTU .OR. WANTVT) THEN
  410. MAXWRK = MAX(MAXWRK,
  411. $ N*N+2*N+N*ILAENV(1,'CUNMQR','LN',N,N,N,-1))
  412. END IF
  413. ELSE
  414. *
  415. * Path 2 (M at least N, but not much larger)
  416. *
  417. MINWRK = 3*N + M
  418. MAXWRK = 2*N + (M+N)*ILAENV(1,'CGEBRD',' ',M,N,-1,-1)
  419. IF (WANTU .OR. WANTVT) THEN
  420. MAXWRK = MAX(MAXWRK,
  421. $ 2*N+N*ILAENV(1,'CUNMQR','LN',N,N,N,-1))
  422. END IF
  423. END IF
  424. ELSE
  425. MNTHR = ILAENV( 6, 'CGESVD', JOBU // JOBVT, M, N, 0, 0 )
  426. IF( N.GE.MNTHR ) THEN
  427. *
  428. * Path 1t (N much larger than M)
  429. *
  430. MINWRK = M*(M+5)
  431. MAXWRK = M + M*ILAENV(1,'CGELQF',' ',M,N,-1,-1)
  432. MAXWRK = MAX(MAXWRK,
  433. $ M*M+2*M+2*M*ILAENV(1,'CGEBRD',' ',M,M,-1,-1))
  434. IF (WANTU .OR. WANTVT) THEN
  435. MAXWRK = MAX(MAXWRK,
  436. $ M*M+2*M+M*ILAENV(1,'CUNMQR','LN',M,M,M,-1))
  437. END IF
  438. ELSE
  439. *
  440. * Path 2t (N greater than M, but not much larger)
  441. *
  442. *
  443. MINWRK = 3*M + N
  444. MAXWRK = 2*M + (M+N)*ILAENV(1,'CGEBRD',' ',M,N,-1,-1)
  445. IF (WANTU .OR. WANTVT) THEN
  446. MAXWRK = MAX(MAXWRK,
  447. $ 2*M+M*ILAENV(1,'CUNMQR','LN',M,M,M,-1))
  448. END IF
  449. END IF
  450. END IF
  451. END IF
  452. MAXWRK = MAX( MAXWRK, MINWRK )
  453. WORK( 1 ) = CMPLX( REAL( MAXWRK ), ZERO )
  454. *
  455. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  456. INFO = -19
  457. END IF
  458. END IF
  459. *
  460. IF( INFO.NE.0 ) THEN
  461. CALL XERBLA( 'CGESVDX', -INFO )
  462. RETURN
  463. ELSE IF( LQUERY ) THEN
  464. RETURN
  465. END IF
  466. *
  467. * Quick return if possible
  468. *
  469. IF( M.EQ.0 .OR. N.EQ.0 ) THEN
  470. RETURN
  471. END IF
  472. *
  473. * Set singular values indices accord to RANGE='A'.
  474. *
  475. IF( ALLS ) THEN
  476. RNGTGK = 'I'
  477. ILTGK = 1
  478. IUTGK = MIN( M, N )
  479. ELSE IF( INDS ) THEN
  480. RNGTGK = 'I'
  481. ILTGK = IL
  482. IUTGK = IU
  483. ELSE
  484. RNGTGK = 'V'
  485. ILTGK = 0
  486. IUTGK = 0
  487. END IF
  488. *
  489. * Get machine constants
  490. *
  491. EPS = SLAMCH( 'P' )
  492. SMLNUM = SQRT( SLAMCH( 'S' ) ) / EPS
  493. BIGNUM = ONE / SMLNUM
  494. *
  495. * Scale A if max element outside range [SMLNUM,BIGNUM]
  496. *
  497. ANRM = CLANGE( 'M', M, N, A, LDA, DUM )
  498. ISCL = 0
  499. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  500. ISCL = 1
  501. CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
  502. ELSE IF( ANRM.GT.BIGNUM ) THEN
  503. ISCL = 1
  504. CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
  505. END IF
  506. *
  507. IF( M.GE.N ) THEN
  508. *
  509. * A has at least as many rows as columns. If A has sufficiently
  510. * more rows than columns, first reduce A using the QR
  511. * decomposition.
  512. *
  513. IF( M.GE.MNTHR ) THEN
  514. *
  515. * Path 1 (M much larger than N):
  516. * A = Q * R = Q * ( QB * B * PB**T )
  517. * = Q * ( QB * ( UB * S * VB**T ) * PB**T )
  518. * U = Q * QB * UB; V**T = VB**T * PB**T
  519. *
  520. * Compute A=Q*R
  521. * (Workspace: need 2*N, prefer N+N*NB)
  522. *
  523. ITAU = 1
  524. ITEMP = ITAU + N
  525. CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( ITEMP ),
  526. $ LWORK-ITEMP+1, INFO )
  527. *
  528. * Copy R into WORK and bidiagonalize it:
  529. * (Workspace: need N*N+3*N, prefer N*N+N+2*N*NB)
  530. *
  531. IQRF = ITEMP
  532. ITAUQ = ITEMP + N*N
  533. ITAUP = ITAUQ + N
  534. ITEMP = ITAUP + N
  535. ID = 1
  536. IE = ID + N
  537. ITGKZ = IE + N
  538. CALL CLACPY( 'U', N, N, A, LDA, WORK( IQRF ), N )
  539. CALL CLASET( 'L', N-1, N-1, CZERO, CZERO,
  540. $ WORK( IQRF+1 ), N )
  541. CALL CGEBRD( N, N, WORK( IQRF ), N, RWORK( ID ),
  542. $ RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
  543. $ WORK( ITEMP ), LWORK-ITEMP+1, INFO )
  544. ITEMPR = ITGKZ + N*(N*2+1)
  545. *
  546. * Solve eigenvalue problem TGK*Z=Z*S.
  547. * (Workspace: need 2*N*N+14*N)
  548. *
  549. CALL SBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
  550. $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
  551. $ RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
  552. $ IWORK, INFO)
  553. *
  554. * If needed, compute left singular vectors.
  555. *
  556. IF( WANTU ) THEN
  557. K = ITGKZ
  558. DO I = 1, NS
  559. DO J = 1, N
  560. U( J, I ) = CMPLX( RWORK( K ), ZERO )
  561. K = K + 1
  562. END DO
  563. K = K + N
  564. END DO
  565. CALL CLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
  566. *
  567. * Call CUNMBR to compute QB*UB.
  568. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  569. *
  570. CALL CUNMBR( 'Q', 'L', 'N', N, NS, N, WORK( IQRF ), N,
  571. $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
  572. $ LWORK-ITEMP+1, INFO )
  573. *
  574. * Call CUNMQR to compute Q*(QB*UB).
  575. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  576. *
  577. CALL CUNMQR( 'L', 'N', M, NS, N, A, LDA,
  578. $ WORK( ITAU ), U, LDU, WORK( ITEMP ),
  579. $ LWORK-ITEMP+1, INFO )
  580. END IF
  581. *
  582. * If needed, compute right singular vectors.
  583. *
  584. IF( WANTVT) THEN
  585. K = ITGKZ + N
  586. DO I = 1, NS
  587. DO J = 1, N
  588. VT( I, J ) = CMPLX( RWORK( K ), ZERO )
  589. K = K + 1
  590. END DO
  591. K = K + N
  592. END DO
  593. *
  594. * Call CUNMBR to compute VB**T * PB**T
  595. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  596. *
  597. CALL CUNMBR( 'P', 'R', 'C', NS, N, N, WORK( IQRF ), N,
  598. $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
  599. $ LWORK-ITEMP+1, INFO )
  600. END IF
  601. ELSE
  602. *
  603. * Path 2 (M at least N, but not much larger)
  604. * Reduce A to bidiagonal form without QR decomposition
  605. * A = QB * B * PB**T = QB * ( UB * S * VB**T ) * PB**T
  606. * U = QB * UB; V**T = VB**T * PB**T
  607. *
  608. * Bidiagonalize A
  609. * (Workspace: need 2*N+M, prefer 2*N+(M+N)*NB)
  610. *
  611. ITAUQ = 1
  612. ITAUP = ITAUQ + N
  613. ITEMP = ITAUP + N
  614. ID = 1
  615. IE = ID + N
  616. ITGKZ = IE + N
  617. CALL CGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ),
  618. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
  619. $ LWORK-ITEMP+1, INFO )
  620. ITEMPR = ITGKZ + N*(N*2+1)
  621. *
  622. * Solve eigenvalue problem TGK*Z=Z*S.
  623. * (Workspace: need 2*N*N+14*N)
  624. *
  625. CALL SBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
  626. $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
  627. $ RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
  628. $ IWORK, INFO)
  629. *
  630. * If needed, compute left singular vectors.
  631. *
  632. IF( WANTU ) THEN
  633. K = ITGKZ
  634. DO I = 1, NS
  635. DO J = 1, N
  636. U( J, I ) = CMPLX( RWORK( K ), ZERO )
  637. K = K + 1
  638. END DO
  639. K = K + N
  640. END DO
  641. CALL CLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
  642. *
  643. * Call CUNMBR to compute QB*UB.
  644. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  645. *
  646. CALL CUNMBR( 'Q', 'L', 'N', M, NS, N, A, LDA,
  647. $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
  648. $ LWORK-ITEMP+1, IERR )
  649. END IF
  650. *
  651. * If needed, compute right singular vectors.
  652. *
  653. IF( WANTVT) THEN
  654. K = ITGKZ + N
  655. DO I = 1, NS
  656. DO J = 1, N
  657. VT( I, J ) = CMPLX( RWORK( K ), ZERO )
  658. K = K + 1
  659. END DO
  660. K = K + N
  661. END DO
  662. *
  663. * Call CUNMBR to compute VB**T * PB**T
  664. * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
  665. *
  666. CALL CUNMBR( 'P', 'R', 'C', NS, N, N, A, LDA,
  667. $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
  668. $ LWORK-ITEMP+1, IERR )
  669. END IF
  670. END IF
  671. ELSE
  672. *
  673. * A has more columns than rows. If A has sufficiently more
  674. * columns than rows, first reduce A using the LQ decomposition.
  675. *
  676. IF( N.GE.MNTHR ) THEN
  677. *
  678. * Path 1t (N much larger than M):
  679. * A = L * Q = ( QB * B * PB**T ) * Q
  680. * = ( QB * ( UB * S * VB**T ) * PB**T ) * Q
  681. * U = QB * UB ; V**T = VB**T * PB**T * Q
  682. *
  683. * Compute A=L*Q
  684. * (Workspace: need 2*M, prefer M+M*NB)
  685. *
  686. ITAU = 1
  687. ITEMP = ITAU + M
  688. CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( ITEMP ),
  689. $ LWORK-ITEMP+1, INFO )
  690. * Copy L into WORK and bidiagonalize it:
  691. * (Workspace in WORK( ITEMP ): need M*M+3*M, prefer M*M+M+2*M*NB)
  692. *
  693. ILQF = ITEMP
  694. ITAUQ = ILQF + M*M
  695. ITAUP = ITAUQ + M
  696. ITEMP = ITAUP + M
  697. ID = 1
  698. IE = ID + M
  699. ITGKZ = IE + M
  700. CALL CLACPY( 'L', M, M, A, LDA, WORK( ILQF ), M )
  701. CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
  702. $ WORK( ILQF+M ), M )
  703. CALL CGEBRD( M, M, WORK( ILQF ), M, RWORK( ID ),
  704. $ RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
  705. $ WORK( ITEMP ), LWORK-ITEMP+1, INFO )
  706. ITEMPR = ITGKZ + M*(M*2+1)
  707. *
  708. * Solve eigenvalue problem TGK*Z=Z*S.
  709. * (Workspace: need 2*M*M+14*M)
  710. *
  711. CALL SBDSVDX( 'U', JOBZ, RNGTGK, M, RWORK( ID ),
  712. $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
  713. $ RWORK( ITGKZ ), M*2, RWORK( ITEMPR ),
  714. $ IWORK, INFO)
  715. *
  716. * If needed, compute left singular vectors.
  717. *
  718. IF( WANTU ) THEN
  719. K = ITGKZ
  720. DO I = 1, NS
  721. DO J = 1, M
  722. U( J, I ) = CMPLX( RWORK( K ), ZERO )
  723. K = K + 1
  724. END DO
  725. K = K + M
  726. END DO
  727. *
  728. * Call CUNMBR to compute QB*UB.
  729. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  730. *
  731. CALL CUNMBR( 'Q', 'L', 'N', M, NS, M, WORK( ILQF ), M,
  732. $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
  733. $ LWORK-ITEMP+1, INFO )
  734. END IF
  735. *
  736. * If needed, compute right singular vectors.
  737. *
  738. IF( WANTVT) THEN
  739. K = ITGKZ + M
  740. DO I = 1, NS
  741. DO J = 1, M
  742. VT( I, J ) = CMPLX( RWORK( K ), ZERO )
  743. K = K + 1
  744. END DO
  745. K = K + M
  746. END DO
  747. CALL CLASET( 'A', NS, N-M, CZERO, CZERO,
  748. $ VT( 1,M+1 ), LDVT )
  749. *
  750. * Call CUNMBR to compute (VB**T)*(PB**T)
  751. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  752. *
  753. CALL CUNMBR( 'P', 'R', 'C', NS, M, M, WORK( ILQF ), M,
  754. $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
  755. $ LWORK-ITEMP+1, INFO )
  756. *
  757. * Call CUNMLQ to compute ((VB**T)*(PB**T))*Q.
  758. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  759. *
  760. CALL CUNMLQ( 'R', 'N', NS, N, M, A, LDA,
  761. $ WORK( ITAU ), VT, LDVT, WORK( ITEMP ),
  762. $ LWORK-ITEMP+1, INFO )
  763. END IF
  764. ELSE
  765. *
  766. * Path 2t (N greater than M, but not much larger)
  767. * Reduce to bidiagonal form without LQ decomposition
  768. * A = QB * B * PB**T = QB * ( UB * S * VB**T ) * PB**T
  769. * U = QB * UB; V**T = VB**T * PB**T
  770. *
  771. * Bidiagonalize A
  772. * (Workspace: need 2*M+N, prefer 2*M+(M+N)*NB)
  773. *
  774. ITAUQ = 1
  775. ITAUP = ITAUQ + M
  776. ITEMP = ITAUP + M
  777. ID = 1
  778. IE = ID + M
  779. ITGKZ = IE + M
  780. CALL CGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ),
  781. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
  782. $ LWORK-ITEMP+1, INFO )
  783. ITEMPR = ITGKZ + M*(M*2+1)
  784. *
  785. * Solve eigenvalue problem TGK*Z=Z*S.
  786. * (Workspace: need 2*M*M+14*M)
  787. *
  788. CALL SBDSVDX( 'L', JOBZ, RNGTGK, M, RWORK( ID ),
  789. $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
  790. $ RWORK( ITGKZ ), M*2, RWORK( ITEMPR ),
  791. $ IWORK, INFO)
  792. *
  793. * If needed, compute left singular vectors.
  794. *
  795. IF( WANTU ) THEN
  796. K = ITGKZ
  797. DO I = 1, NS
  798. DO J = 1, M
  799. U( J, I ) = CMPLX( RWORK( K ), ZERO )
  800. K = K + 1
  801. END DO
  802. K = K + M
  803. END DO
  804. *
  805. * Call CUNMBR to compute QB*UB.
  806. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  807. *
  808. CALL CUNMBR( 'Q', 'L', 'N', M, NS, N, A, LDA,
  809. $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
  810. $ LWORK-ITEMP+1, INFO )
  811. END IF
  812. *
  813. * If needed, compute right singular vectors.
  814. *
  815. IF( WANTVT) THEN
  816. K = ITGKZ + M
  817. DO I = 1, NS
  818. DO J = 1, M
  819. VT( I, J ) = CMPLX( RWORK( K ), ZERO )
  820. K = K + 1
  821. END DO
  822. K = K + M
  823. END DO
  824. CALL CLASET( 'A', NS, N-M, CZERO, CZERO,
  825. $ VT( 1,M+1 ), LDVT )
  826. *
  827. * Call CUNMBR to compute VB**T * PB**T
  828. * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
  829. *
  830. CALL CUNMBR( 'P', 'R', 'C', NS, N, M, A, LDA,
  831. $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
  832. $ LWORK-ITEMP+1, INFO )
  833. END IF
  834. END IF
  835. END IF
  836. *
  837. * Undo scaling if necessary
  838. *
  839. IF( ISCL.EQ.1 ) THEN
  840. IF( ANRM.GT.BIGNUM )
  841. $ CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1,
  842. $ S, MINMN, INFO )
  843. IF( ANRM.LT.SMLNUM )
  844. $ CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1,
  845. $ S, MINMN, INFO )
  846. END IF
  847. *
  848. * Return optimal workspace in WORK(1)
  849. *
  850. WORK( 1 ) = CMPLX( REAL( MAXWRK ), ZERO )
  851. *
  852. RETURN
  853. *
  854. * End of CGESVDX
  855. *
  856. END