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.

clalsd.f 23 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. *> \brief \b CLALSD uses the singular value decomposition of A to solve the least squares problem.
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download CLALSD + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clalsd.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clalsd.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clalsd.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE CLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
  22. * RANK, WORK, RWORK, IWORK, INFO )
  23. *
  24. * .. Scalar Arguments ..
  25. * CHARACTER UPLO
  26. * INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
  27. * REAL RCOND
  28. * ..
  29. * .. Array Arguments ..
  30. * INTEGER IWORK( * )
  31. * REAL D( * ), E( * ), RWORK( * )
  32. * COMPLEX B( LDB, * ), WORK( * )
  33. * ..
  34. *
  35. *
  36. *> \par Purpose:
  37. * =============
  38. *>
  39. *> \verbatim
  40. *>
  41. *> CLALSD uses the singular value decomposition of A to solve the least
  42. *> squares problem of finding X to minimize the Euclidean norm of each
  43. *> column of A*X-B, where A is N-by-N upper bidiagonal, and X and B
  44. *> are N-by-NRHS. The solution X overwrites B.
  45. *>
  46. *> The singular values of A smaller than RCOND times the largest
  47. *> singular value are treated as zero in solving the least squares
  48. *> problem; in this case a minimum norm solution is returned.
  49. *> The actual singular values are returned in D in ascending order.
  50. *>
  51. *> \endverbatim
  52. *
  53. * Arguments:
  54. * ==========
  55. *
  56. *> \param[in] UPLO
  57. *> \verbatim
  58. *> UPLO is CHARACTER*1
  59. *> = 'U': D and E define an upper bidiagonal matrix.
  60. *> = 'L': D and E define a lower bidiagonal matrix.
  61. *> \endverbatim
  62. *>
  63. *> \param[in] SMLSIZ
  64. *> \verbatim
  65. *> SMLSIZ is INTEGER
  66. *> The maximum size of the subproblems at the bottom of the
  67. *> computation tree.
  68. *> \endverbatim
  69. *>
  70. *> \param[in] N
  71. *> \verbatim
  72. *> N is INTEGER
  73. *> The dimension of the bidiagonal matrix. N >= 0.
  74. *> \endverbatim
  75. *>
  76. *> \param[in] NRHS
  77. *> \verbatim
  78. *> NRHS is INTEGER
  79. *> The number of columns of B. NRHS must be at least 1.
  80. *> \endverbatim
  81. *>
  82. *> \param[in,out] D
  83. *> \verbatim
  84. *> D is REAL array, dimension (N)
  85. *> On entry D contains the main diagonal of the bidiagonal
  86. *> matrix. On exit, if INFO = 0, D contains its singular values.
  87. *> \endverbatim
  88. *>
  89. *> \param[in,out] E
  90. *> \verbatim
  91. *> E is REAL array, dimension (N-1)
  92. *> Contains the super-diagonal entries of the bidiagonal matrix.
  93. *> On exit, E has been destroyed.
  94. *> \endverbatim
  95. *>
  96. *> \param[in,out] B
  97. *> \verbatim
  98. *> B is COMPLEX array, dimension (LDB,NRHS)
  99. *> On input, B contains the right hand sides of the least
  100. *> squares problem. On output, B contains the solution X.
  101. *> \endverbatim
  102. *>
  103. *> \param[in] LDB
  104. *> \verbatim
  105. *> LDB is INTEGER
  106. *> The leading dimension of B in the calling subprogram.
  107. *> LDB must be at least max(1,N).
  108. *> \endverbatim
  109. *>
  110. *> \param[in] RCOND
  111. *> \verbatim
  112. *> RCOND is REAL
  113. *> The singular values of A less than or equal to RCOND times
  114. *> the largest singular value are treated as zero in solving
  115. *> the least squares problem. If RCOND is negative,
  116. *> machine precision is used instead.
  117. *> For example, if diag(S)*X=B were the least squares problem,
  118. *> where diag(S) is a diagonal matrix of singular values, the
  119. *> solution would be X(i) = B(i) / S(i) if S(i) is greater than
  120. *> RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to
  121. *> RCOND*max(S).
  122. *> \endverbatim
  123. *>
  124. *> \param[out] RANK
  125. *> \verbatim
  126. *> RANK is INTEGER
  127. *> The number of singular values of A greater than RCOND times
  128. *> the largest singular value.
  129. *> \endverbatim
  130. *>
  131. *> \param[out] WORK
  132. *> \verbatim
  133. *> WORK is COMPLEX array, dimension (N * NRHS).
  134. *> \endverbatim
  135. *>
  136. *> \param[out] RWORK
  137. *> \verbatim
  138. *> RWORK is REAL array, dimension at least
  139. *> (9*N + 2*N*SMLSIZ + 8*N*NLVL + 3*SMLSIZ*NRHS +
  140. *> MAX( (SMLSIZ+1)**2, N*(1+NRHS) + 2*NRHS ),
  141. *> where
  142. *> NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
  143. *> \endverbatim
  144. *>
  145. *> \param[out] IWORK
  146. *> \verbatim
  147. *> IWORK is INTEGER array, dimension (3*N*NLVL + 11*N).
  148. *> \endverbatim
  149. *>
  150. *> \param[out] INFO
  151. *> \verbatim
  152. *> INFO is INTEGER
  153. *> = 0: successful exit.
  154. *> < 0: if INFO = -i, the i-th argument had an illegal value.
  155. *> > 0: The algorithm failed to compute a singular value while
  156. *> working on the submatrix lying in rows and columns
  157. *> INFO/(N+1) through MOD(INFO,N+1).
  158. *> \endverbatim
  159. *
  160. * Authors:
  161. * ========
  162. *
  163. *> \author Univ. of Tennessee
  164. *> \author Univ. of California Berkeley
  165. *> \author Univ. of Colorado Denver
  166. *> \author NAG Ltd.
  167. *
  168. *> \ingroup complexOTHERcomputational
  169. *
  170. *> \par Contributors:
  171. * ==================
  172. *>
  173. *> Ming Gu and Ren-Cang Li, Computer Science Division, University of
  174. *> California at Berkeley, USA \n
  175. *> Osni Marques, LBNL/NERSC, USA \n
  176. *
  177. * =====================================================================
  178. SUBROUTINE CLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
  179. $ RANK, WORK, RWORK, IWORK, INFO )
  180. *
  181. * -- LAPACK computational routine --
  182. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  183. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  184. *
  185. * .. Scalar Arguments ..
  186. CHARACTER UPLO
  187. INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
  188. REAL RCOND
  189. * ..
  190. * .. Array Arguments ..
  191. INTEGER IWORK( * )
  192. REAL D( * ), E( * ), RWORK( * )
  193. COMPLEX B( LDB, * ), WORK( * )
  194. * ..
  195. *
  196. * =====================================================================
  197. *
  198. * .. Parameters ..
  199. REAL ZERO, ONE, TWO
  200. PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0 )
  201. COMPLEX CZERO
  202. PARAMETER ( CZERO = ( 0.0E0, 0.0E0 ) )
  203. * ..
  204. * .. Local Scalars ..
  205. INTEGER BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
  206. $ GIVPTR, I, ICMPQ1, ICMPQ2, IRWB, IRWIB, IRWRB,
  207. $ IRWU, IRWVT, IRWWRK, IWK, J, JCOL, JIMAG,
  208. $ JREAL, JROW, K, NLVL, NM1, NRWORK, NSIZE, NSUB,
  209. $ PERM, POLES, S, SIZEI, SMLSZP, SQRE, ST, ST1,
  210. $ U, VT, Z
  211. REAL CS, EPS, ORGNRM, R, RCND, SN, TOL
  212. * ..
  213. * .. External Functions ..
  214. INTEGER ISAMAX
  215. REAL SLAMCH, SLANST
  216. EXTERNAL ISAMAX, SLAMCH, SLANST
  217. * ..
  218. * .. External Subroutines ..
  219. EXTERNAL CCOPY, CLACPY, CLALSA, CLASCL, CLASET, CSROT,
  220. $ SGEMM, SLARTG, SLASCL, SLASDA, SLASDQ, SLASET,
  221. $ SLASRT, XERBLA
  222. * ..
  223. * .. Intrinsic Functions ..
  224. INTRINSIC ABS, AIMAG, CMPLX, INT, LOG, REAL, SIGN
  225. * ..
  226. * .. Executable Statements ..
  227. *
  228. * Test the input parameters.
  229. *
  230. INFO = 0
  231. *
  232. IF( N.LT.0 ) THEN
  233. INFO = -3
  234. ELSE IF( NRHS.LT.1 ) THEN
  235. INFO = -4
  236. ELSE IF( ( LDB.LT.1 ) .OR. ( LDB.LT.N ) ) THEN
  237. INFO = -8
  238. END IF
  239. IF( INFO.NE.0 ) THEN
  240. CALL XERBLA( 'CLALSD', -INFO )
  241. RETURN
  242. END IF
  243. *
  244. EPS = SLAMCH( 'Epsilon' )
  245. *
  246. * Set up the tolerance.
  247. *
  248. IF( ( RCOND.LE.ZERO ) .OR. ( RCOND.GE.ONE ) ) THEN
  249. RCND = EPS
  250. ELSE
  251. RCND = RCOND
  252. END IF
  253. *
  254. RANK = 0
  255. *
  256. * Quick return if possible.
  257. *
  258. IF( N.EQ.0 ) THEN
  259. RETURN
  260. ELSE IF( N.EQ.1 ) THEN
  261. IF( D( 1 ).EQ.ZERO ) THEN
  262. CALL CLASET( 'A', 1, NRHS, CZERO, CZERO, B, LDB )
  263. ELSE
  264. RANK = 1
  265. CALL CLASCL( 'G', 0, 0, D( 1 ), ONE, 1, NRHS, B, LDB, INFO )
  266. D( 1 ) = ABS( D( 1 ) )
  267. END IF
  268. RETURN
  269. END IF
  270. *
  271. * Rotate the matrix if it is lower bidiagonal.
  272. *
  273. IF( UPLO.EQ.'L' ) THEN
  274. DO 10 I = 1, N - 1
  275. CALL SLARTG( D( I ), E( I ), CS, SN, R )
  276. D( I ) = R
  277. E( I ) = SN*D( I+1 )
  278. D( I+1 ) = CS*D( I+1 )
  279. IF( NRHS.EQ.1 ) THEN
  280. CALL CSROT( 1, B( I, 1 ), 1, B( I+1, 1 ), 1, CS, SN )
  281. ELSE
  282. RWORK( I*2-1 ) = CS
  283. RWORK( I*2 ) = SN
  284. END IF
  285. 10 CONTINUE
  286. IF( NRHS.GT.1 ) THEN
  287. DO 30 I = 1, NRHS
  288. DO 20 J = 1, N - 1
  289. CS = RWORK( J*2-1 )
  290. SN = RWORK( J*2 )
  291. CALL CSROT( 1, B( J, I ), 1, B( J+1, I ), 1, CS, SN )
  292. 20 CONTINUE
  293. 30 CONTINUE
  294. END IF
  295. END IF
  296. *
  297. * Scale.
  298. *
  299. NM1 = N - 1
  300. ORGNRM = SLANST( 'M', N, D, E )
  301. IF( ORGNRM.EQ.ZERO ) THEN
  302. CALL CLASET( 'A', N, NRHS, CZERO, CZERO, B, LDB )
  303. RETURN
  304. END IF
  305. *
  306. CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )
  307. CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, INFO )
  308. *
  309. * If N is smaller than the minimum divide size SMLSIZ, then solve
  310. * the problem with another solver.
  311. *
  312. IF( N.LE.SMLSIZ ) THEN
  313. IRWU = 1
  314. IRWVT = IRWU + N*N
  315. IRWWRK = IRWVT + N*N
  316. IRWRB = IRWWRK
  317. IRWIB = IRWRB + N*NRHS
  318. IRWB = IRWIB + N*NRHS
  319. CALL SLASET( 'A', N, N, ZERO, ONE, RWORK( IRWU ), N )
  320. CALL SLASET( 'A', N, N, ZERO, ONE, RWORK( IRWVT ), N )
  321. CALL SLASDQ( 'U', 0, N, N, N, 0, D, E, RWORK( IRWVT ), N,
  322. $ RWORK( IRWU ), N, RWORK( IRWWRK ), 1,
  323. $ RWORK( IRWWRK ), INFO )
  324. IF( INFO.NE.0 ) THEN
  325. RETURN
  326. END IF
  327. *
  328. * In the real version, B is passed to SLASDQ and multiplied
  329. * internally by Q**H. Here B is complex and that product is
  330. * computed below in two steps (real and imaginary parts).
  331. *
  332. J = IRWB - 1
  333. DO 50 JCOL = 1, NRHS
  334. DO 40 JROW = 1, N
  335. J = J + 1
  336. RWORK( J ) = REAL( B( JROW, JCOL ) )
  337. 40 CONTINUE
  338. 50 CONTINUE
  339. CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWU ), N,
  340. $ RWORK( IRWB ), N, ZERO, RWORK( IRWRB ), N )
  341. J = IRWB - 1
  342. DO 70 JCOL = 1, NRHS
  343. DO 60 JROW = 1, N
  344. J = J + 1
  345. RWORK( J ) = AIMAG( B( JROW, JCOL ) )
  346. 60 CONTINUE
  347. 70 CONTINUE
  348. CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWU ), N,
  349. $ RWORK( IRWB ), N, ZERO, RWORK( IRWIB ), N )
  350. JREAL = IRWRB - 1
  351. JIMAG = IRWIB - 1
  352. DO 90 JCOL = 1, NRHS
  353. DO 80 JROW = 1, N
  354. JREAL = JREAL + 1
  355. JIMAG = JIMAG + 1
  356. B( JROW, JCOL ) = CMPLX( RWORK( JREAL ), RWORK( JIMAG ) )
  357. 80 CONTINUE
  358. 90 CONTINUE
  359. *
  360. TOL = RCND*ABS( D( ISAMAX( N, D, 1 ) ) )
  361. DO 100 I = 1, N
  362. IF( D( I ).LE.TOL ) THEN
  363. CALL CLASET( 'A', 1, NRHS, CZERO, CZERO, B( I, 1 ), LDB )
  364. ELSE
  365. CALL CLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS, B( I, 1 ),
  366. $ LDB, INFO )
  367. RANK = RANK + 1
  368. END IF
  369. 100 CONTINUE
  370. *
  371. * Since B is complex, the following call to SGEMM is performed
  372. * in two steps (real and imaginary parts). That is for V * B
  373. * (in the real version of the code V**H is stored in WORK).
  374. *
  375. * CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, WORK, N, B, LDB, ZERO,
  376. * $ WORK( NWORK ), N )
  377. *
  378. J = IRWB - 1
  379. DO 120 JCOL = 1, NRHS
  380. DO 110 JROW = 1, N
  381. J = J + 1
  382. RWORK( J ) = REAL( B( JROW, JCOL ) )
  383. 110 CONTINUE
  384. 120 CONTINUE
  385. CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWVT ), N,
  386. $ RWORK( IRWB ), N, ZERO, RWORK( IRWRB ), N )
  387. J = IRWB - 1
  388. DO 140 JCOL = 1, NRHS
  389. DO 130 JROW = 1, N
  390. J = J + 1
  391. RWORK( J ) = AIMAG( B( JROW, JCOL ) )
  392. 130 CONTINUE
  393. 140 CONTINUE
  394. CALL SGEMM( 'T', 'N', N, NRHS, N, ONE, RWORK( IRWVT ), N,
  395. $ RWORK( IRWB ), N, ZERO, RWORK( IRWIB ), N )
  396. JREAL = IRWRB - 1
  397. JIMAG = IRWIB - 1
  398. DO 160 JCOL = 1, NRHS
  399. DO 150 JROW = 1, N
  400. JREAL = JREAL + 1
  401. JIMAG = JIMAG + 1
  402. B( JROW, JCOL ) = CMPLX( RWORK( JREAL ), RWORK( JIMAG ) )
  403. 150 CONTINUE
  404. 160 CONTINUE
  405. *
  406. * Unscale.
  407. *
  408. CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
  409. CALL SLASRT( 'D', N, D, INFO )
  410. CALL CLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
  411. *
  412. RETURN
  413. END IF
  414. *
  415. * Book-keeping and setting up some constants.
  416. *
  417. NLVL = INT( LOG( REAL( N ) / REAL( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1
  418. *
  419. SMLSZP = SMLSIZ + 1
  420. *
  421. U = 1
  422. VT = 1 + SMLSIZ*N
  423. DIFL = VT + SMLSZP*N
  424. DIFR = DIFL + NLVL*N
  425. Z = DIFR + NLVL*N*2
  426. C = Z + NLVL*N
  427. S = C + N
  428. POLES = S + N
  429. GIVNUM = POLES + 2*NLVL*N
  430. NRWORK = GIVNUM + 2*NLVL*N
  431. BX = 1
  432. *
  433. IRWRB = NRWORK
  434. IRWIB = IRWRB + SMLSIZ*NRHS
  435. IRWB = IRWIB + SMLSIZ*NRHS
  436. *
  437. SIZEI = 1 + N
  438. K = SIZEI + N
  439. GIVPTR = K + N
  440. PERM = GIVPTR + N
  441. GIVCOL = PERM + NLVL*N
  442. IWK = GIVCOL + NLVL*N*2
  443. *
  444. ST = 1
  445. SQRE = 0
  446. ICMPQ1 = 1
  447. ICMPQ2 = 0
  448. NSUB = 0
  449. *
  450. DO 170 I = 1, N
  451. IF( ABS( D( I ) ).LT.EPS ) THEN
  452. D( I ) = SIGN( EPS, D( I ) )
  453. END IF
  454. 170 CONTINUE
  455. *
  456. DO 240 I = 1, NM1
  457. IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN
  458. NSUB = NSUB + 1
  459. IWORK( NSUB ) = ST
  460. *
  461. * Subproblem found. First determine its size and then
  462. * apply divide and conquer on it.
  463. *
  464. IF( I.LT.NM1 ) THEN
  465. *
  466. * A subproblem with E(I) small for I < NM1.
  467. *
  468. NSIZE = I - ST + 1
  469. IWORK( SIZEI+NSUB-1 ) = NSIZE
  470. ELSE IF( ABS( E( I ) ).GE.EPS ) THEN
  471. *
  472. * A subproblem with E(NM1) not too small but I = NM1.
  473. *
  474. NSIZE = N - ST + 1
  475. IWORK( SIZEI+NSUB-1 ) = NSIZE
  476. ELSE
  477. *
  478. * A subproblem with E(NM1) small. This implies an
  479. * 1-by-1 subproblem at D(N), which is not solved
  480. * explicitly.
  481. *
  482. NSIZE = I - ST + 1
  483. IWORK( SIZEI+NSUB-1 ) = NSIZE
  484. NSUB = NSUB + 1
  485. IWORK( NSUB ) = N
  486. IWORK( SIZEI+NSUB-1 ) = 1
  487. CALL CCOPY( NRHS, B( N, 1 ), LDB, WORK( BX+NM1 ), N )
  488. END IF
  489. ST1 = ST - 1
  490. IF( NSIZE.EQ.1 ) THEN
  491. *
  492. * This is a 1-by-1 subproblem and is not solved
  493. * explicitly.
  494. *
  495. CALL CCOPY( NRHS, B( ST, 1 ), LDB, WORK( BX+ST1 ), N )
  496. ELSE IF( NSIZE.LE.SMLSIZ ) THEN
  497. *
  498. * This is a small subproblem and is solved by SLASDQ.
  499. *
  500. CALL SLASET( 'A', NSIZE, NSIZE, ZERO, ONE,
  501. $ RWORK( VT+ST1 ), N )
  502. CALL SLASET( 'A', NSIZE, NSIZE, ZERO, ONE,
  503. $ RWORK( U+ST1 ), N )
  504. CALL SLASDQ( 'U', 0, NSIZE, NSIZE, NSIZE, 0, D( ST ),
  505. $ E( ST ), RWORK( VT+ST1 ), N, RWORK( U+ST1 ),
  506. $ N, RWORK( NRWORK ), 1, RWORK( NRWORK ),
  507. $ INFO )
  508. IF( INFO.NE.0 ) THEN
  509. RETURN
  510. END IF
  511. *
  512. * In the real version, B is passed to SLASDQ and multiplied
  513. * internally by Q**H. Here B is complex and that product is
  514. * computed below in two steps (real and imaginary parts).
  515. *
  516. J = IRWB - 1
  517. DO 190 JCOL = 1, NRHS
  518. DO 180 JROW = ST, ST + NSIZE - 1
  519. J = J + 1
  520. RWORK( J ) = REAL( B( JROW, JCOL ) )
  521. 180 CONTINUE
  522. 190 CONTINUE
  523. CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
  524. $ RWORK( U+ST1 ), N, RWORK( IRWB ), NSIZE,
  525. $ ZERO, RWORK( IRWRB ), NSIZE )
  526. J = IRWB - 1
  527. DO 210 JCOL = 1, NRHS
  528. DO 200 JROW = ST, ST + NSIZE - 1
  529. J = J + 1
  530. RWORK( J ) = AIMAG( B( JROW, JCOL ) )
  531. 200 CONTINUE
  532. 210 CONTINUE
  533. CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
  534. $ RWORK( U+ST1 ), N, RWORK( IRWB ), NSIZE,
  535. $ ZERO, RWORK( IRWIB ), NSIZE )
  536. JREAL = IRWRB - 1
  537. JIMAG = IRWIB - 1
  538. DO 230 JCOL = 1, NRHS
  539. DO 220 JROW = ST, ST + NSIZE - 1
  540. JREAL = JREAL + 1
  541. JIMAG = JIMAG + 1
  542. B( JROW, JCOL ) = CMPLX( RWORK( JREAL ),
  543. $ RWORK( JIMAG ) )
  544. 220 CONTINUE
  545. 230 CONTINUE
  546. *
  547. CALL CLACPY( 'A', NSIZE, NRHS, B( ST, 1 ), LDB,
  548. $ WORK( BX+ST1 ), N )
  549. ELSE
  550. *
  551. * A large problem. Solve it using divide and conquer.
  552. *
  553. CALL SLASDA( ICMPQ1, SMLSIZ, NSIZE, SQRE, D( ST ),
  554. $ E( ST ), RWORK( U+ST1 ), N, RWORK( VT+ST1 ),
  555. $ IWORK( K+ST1 ), RWORK( DIFL+ST1 ),
  556. $ RWORK( DIFR+ST1 ), RWORK( Z+ST1 ),
  557. $ RWORK( POLES+ST1 ), IWORK( GIVPTR+ST1 ),
  558. $ IWORK( GIVCOL+ST1 ), N, IWORK( PERM+ST1 ),
  559. $ RWORK( GIVNUM+ST1 ), RWORK( C+ST1 ),
  560. $ RWORK( S+ST1 ), RWORK( NRWORK ),
  561. $ IWORK( IWK ), INFO )
  562. IF( INFO.NE.0 ) THEN
  563. RETURN
  564. END IF
  565. BXST = BX + ST1
  566. CALL CLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, B( ST, 1 ),
  567. $ LDB, WORK( BXST ), N, RWORK( U+ST1 ), N,
  568. $ RWORK( VT+ST1 ), IWORK( K+ST1 ),
  569. $ RWORK( DIFL+ST1 ), RWORK( DIFR+ST1 ),
  570. $ RWORK( Z+ST1 ), RWORK( POLES+ST1 ),
  571. $ IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
  572. $ IWORK( PERM+ST1 ), RWORK( GIVNUM+ST1 ),
  573. $ RWORK( C+ST1 ), RWORK( S+ST1 ),
  574. $ RWORK( NRWORK ), IWORK( IWK ), INFO )
  575. IF( INFO.NE.0 ) THEN
  576. RETURN
  577. END IF
  578. END IF
  579. ST = I + 1
  580. END IF
  581. 240 CONTINUE
  582. *
  583. * Apply the singular values and treat the tiny ones as zero.
  584. *
  585. TOL = RCND*ABS( D( ISAMAX( N, D, 1 ) ) )
  586. *
  587. DO 250 I = 1, N
  588. *
  589. * Some of the elements in D can be negative because 1-by-1
  590. * subproblems were not solved explicitly.
  591. *
  592. IF( ABS( D( I ) ).LE.TOL ) THEN
  593. CALL CLASET( 'A', 1, NRHS, CZERO, CZERO, WORK( BX+I-1 ), N )
  594. ELSE
  595. RANK = RANK + 1
  596. CALL CLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS,
  597. $ WORK( BX+I-1 ), N, INFO )
  598. END IF
  599. D( I ) = ABS( D( I ) )
  600. 250 CONTINUE
  601. *
  602. * Now apply back the right singular vectors.
  603. *
  604. ICMPQ2 = 1
  605. DO 320 I = 1, NSUB
  606. ST = IWORK( I )
  607. ST1 = ST - 1
  608. NSIZE = IWORK( SIZEI+I-1 )
  609. BXST = BX + ST1
  610. IF( NSIZE.EQ.1 ) THEN
  611. CALL CCOPY( NRHS, WORK( BXST ), N, B( ST, 1 ), LDB )
  612. ELSE IF( NSIZE.LE.SMLSIZ ) THEN
  613. *
  614. * Since B and BX are complex, the following call to SGEMM
  615. * is performed in two steps (real and imaginary parts).
  616. *
  617. * CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
  618. * $ RWORK( VT+ST1 ), N, RWORK( BXST ), N, ZERO,
  619. * $ B( ST, 1 ), LDB )
  620. *
  621. J = BXST - N - 1
  622. JREAL = IRWB - 1
  623. DO 270 JCOL = 1, NRHS
  624. J = J + N
  625. DO 260 JROW = 1, NSIZE
  626. JREAL = JREAL + 1
  627. RWORK( JREAL ) = REAL( WORK( J+JROW ) )
  628. 260 CONTINUE
  629. 270 CONTINUE
  630. CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
  631. $ RWORK( VT+ST1 ), N, RWORK( IRWB ), NSIZE, ZERO,
  632. $ RWORK( IRWRB ), NSIZE )
  633. J = BXST - N - 1
  634. JIMAG = IRWB - 1
  635. DO 290 JCOL = 1, NRHS
  636. J = J + N
  637. DO 280 JROW = 1, NSIZE
  638. JIMAG = JIMAG + 1
  639. RWORK( JIMAG ) = AIMAG( WORK( J+JROW ) )
  640. 280 CONTINUE
  641. 290 CONTINUE
  642. CALL SGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,
  643. $ RWORK( VT+ST1 ), N, RWORK( IRWB ), NSIZE, ZERO,
  644. $ RWORK( IRWIB ), NSIZE )
  645. JREAL = IRWRB - 1
  646. JIMAG = IRWIB - 1
  647. DO 310 JCOL = 1, NRHS
  648. DO 300 JROW = ST, ST + NSIZE - 1
  649. JREAL = JREAL + 1
  650. JIMAG = JIMAG + 1
  651. B( JROW, JCOL ) = CMPLX( RWORK( JREAL ),
  652. $ RWORK( JIMAG ) )
  653. 300 CONTINUE
  654. 310 CONTINUE
  655. ELSE
  656. CALL CLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, WORK( BXST ), N,
  657. $ B( ST, 1 ), LDB, RWORK( U+ST1 ), N,
  658. $ RWORK( VT+ST1 ), IWORK( K+ST1 ),
  659. $ RWORK( DIFL+ST1 ), RWORK( DIFR+ST1 ),
  660. $ RWORK( Z+ST1 ), RWORK( POLES+ST1 ),
  661. $ IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,
  662. $ IWORK( PERM+ST1 ), RWORK( GIVNUM+ST1 ),
  663. $ RWORK( C+ST1 ), RWORK( S+ST1 ),
  664. $ RWORK( NRWORK ), IWORK( IWK ), INFO )
  665. IF( INFO.NE.0 ) THEN
  666. RETURN
  667. END IF
  668. END IF
  669. 320 CONTINUE
  670. *
  671. * Unscale and sort the singular values.
  672. *
  673. CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )
  674. CALL SLASRT( 'D', N, D, INFO )
  675. CALL CLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )
  676. *
  677. RETURN
  678. *
  679. * End of CLALSD
  680. *
  681. END