PageRenderTime 139ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 2ms

/R-2.15.1/src/modules/lapack/dlapack1.f

#
FORTRAN Legacy | 13729 lines | 5545 code | 1 blank | 8183 comment | 0 complexity | 2debfe568d485e45100b760897a8738e MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0, CC-BY-SA-4.0, BSD-3-Clause, AGPL-3.0, GPL-2.0, GPL-3.0, LGPL-2.0
  1. SUBROUTINE DGBSV( N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB, INFO )
  2. *
  3. * -- LAPACK driver routine (version 3.1) --
  4. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  5. * November 2006
  6. *
  7. * .. Scalar Arguments ..
  8. INTEGER INFO, KL, KU, LDAB, LDB, N, NRHS
  9. * ..
  10. * .. Array Arguments ..
  11. INTEGER IPIV( * )
  12. DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )
  13. * ..
  14. *
  15. * Purpose
  16. * =======
  17. *
  18. * DGBSV computes the solution to a real system of linear equations
  19. * A * X = B, where A is a band matrix of order N with KL subdiagonals
  20. * and KU superdiagonals, and X and B are N-by-NRHS matrices.
  21. *
  22. * The LU decomposition with partial pivoting and row interchanges is
  23. * used to factor A as A = L * U, where L is a product of permutation
  24. * and unit lower triangular matrices with KL subdiagonals, and U is
  25. * upper triangular with KL+KU superdiagonals. The factored form of A
  26. * is then used to solve the system of equations A * X = B.
  27. *
  28. * Arguments
  29. * =========
  30. *
  31. * N (input) INTEGER
  32. * The number of linear equations, i.e., the order of the
  33. * matrix A. N >= 0.
  34. *
  35. * KL (input) INTEGER
  36. * The number of subdiagonals within the band of A. KL >= 0.
  37. *
  38. * KU (input) INTEGER
  39. * The number of superdiagonals within the band of A. KU >= 0.
  40. *
  41. * NRHS (input) INTEGER
  42. * The number of right hand sides, i.e., the number of columns
  43. * of the matrix B. NRHS >= 0.
  44. *
  45. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
  46. * On entry, the matrix A in band storage, in rows KL+1 to
  47. * 2*KL+KU+1; rows 1 to KL of the array need not be set.
  48. * The j-th column of A is stored in the j-th column of the
  49. * array AB as follows:
  50. * AB(KL+KU+1+i-j,j) = A(i,j) for max(1,j-KU)<=i<=min(N,j+KL)
  51. * On exit, details of the factorization: U is stored as an
  52. * upper triangular band matrix with KL+KU superdiagonals in
  53. * rows 1 to KL+KU+1, and the multipliers used during the
  54. * factorization are stored in rows KL+KU+2 to 2*KL+KU+1.
  55. * See below for further details.
  56. *
  57. * LDAB (input) INTEGER
  58. * The leading dimension of the array AB. LDAB >= 2*KL+KU+1.
  59. *
  60. * IPIV (output) INTEGER array, dimension (N)
  61. * The pivot indices that define the permutation matrix P;
  62. * row i of the matrix was interchanged with row IPIV(i).
  63. *
  64. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  65. * On entry, the N-by-NRHS right hand side matrix B.
  66. * On exit, if INFO = 0, the N-by-NRHS solution matrix X.
  67. *
  68. * LDB (input) INTEGER
  69. * The leading dimension of the array B. LDB >= max(1,N).
  70. *
  71. * INFO (output) INTEGER
  72. * = 0: successful exit
  73. * < 0: if INFO = -i, the i-th argument had an illegal value
  74. * > 0: if INFO = i, U(i,i) is exactly zero. The factorization
  75. * has been completed, but the factor U is exactly
  76. * singular, and the solution has not been computed.
  77. *
  78. * Further Details
  79. * ===============
  80. *
  81. * The band storage scheme is illustrated by the following example, when
  82. * M = N = 6, KL = 2, KU = 1:
  83. *
  84. * On entry: On exit:
  85. *
  86. * * * * + + + * * * u14 u25 u36
  87. * * * + + + + * * u13 u24 u35 u46
  88. * * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56
  89. * a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66
  90. * a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 *
  91. * a31 a42 a53 a64 * * m31 m42 m53 m64 * *
  92. *
  93. * Array elements marked * are not used by the routine; elements marked
  94. * + need not be set on entry, but are required by the routine to store
  95. * elements of U because of fill-in resulting from the row interchanges.
  96. *
  97. * =====================================================================
  98. *
  99. * .. External Subroutines ..
  100. EXTERNAL DGBTRF, DGBTRS, XERBLA
  101. * ..
  102. * .. Intrinsic Functions ..
  103. INTRINSIC MAX
  104. * ..
  105. * .. Executable Statements ..
  106. *
  107. * Test the input parameters.
  108. *
  109. INFO = 0
  110. IF( N.LT.0 ) THEN
  111. INFO = -1
  112. ELSE IF( KL.LT.0 ) THEN
  113. INFO = -2
  114. ELSE IF( KU.LT.0 ) THEN
  115. INFO = -3
  116. ELSE IF( NRHS.LT.0 ) THEN
  117. INFO = -4
  118. ELSE IF( LDAB.LT.2*KL+KU+1 ) THEN
  119. INFO = -6
  120. ELSE IF( LDB.LT.MAX( N, 1 ) ) THEN
  121. INFO = -9
  122. END IF
  123. IF( INFO.NE.0 ) THEN
  124. CALL XERBLA( 'DGBSV ', -INFO )
  125. RETURN
  126. END IF
  127. *
  128. * Compute the LU factorization of the band matrix A.
  129. *
  130. CALL DGBTRF( N, N, KL, KU, AB, LDAB, IPIV, INFO )
  131. IF( INFO.EQ.0 ) THEN
  132. *
  133. * Solve the system A*X = B, overwriting B with X.
  134. *
  135. CALL DGBTRS( 'No transpose', N, KL, KU, NRHS, AB, LDAB, IPIV,
  136. $ B, LDB, INFO )
  137. END IF
  138. RETURN
  139. *
  140. * End of DGBSV
  141. *
  142. END
  143. SUBROUTINE DGBSVX( FACT, TRANS, N, KL, KU, NRHS, AB, LDAB, AFB,
  144. $ LDAFB, IPIV, EQUED, R, C, B, LDB, X, LDX,
  145. $ RCOND, FERR, BERR, WORK, IWORK, INFO )
  146. *
  147. * -- LAPACK driver routine (version 3.1) --
  148. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  149. * November 2006
  150. *
  151. * .. Scalar Arguments ..
  152. CHARACTER EQUED, FACT, TRANS
  153. INTEGER INFO, KL, KU, LDAB, LDAFB, LDB, LDX, N, NRHS
  154. DOUBLE PRECISION RCOND
  155. * ..
  156. * .. Array Arguments ..
  157. INTEGER IPIV( * ), IWORK( * )
  158. DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),
  159. $ BERR( * ), C( * ), FERR( * ), R( * ),
  160. $ WORK( * ), X( LDX, * )
  161. * ..
  162. *
  163. * Purpose
  164. * =======
  165. *
  166. * DGBSVX uses the LU factorization to compute the solution to a real
  167. * system of linear equations A * X = B, A**T * X = B, or A**H * X = B,
  168. * where A is a band matrix of order N with KL subdiagonals and KU
  169. * superdiagonals, and X and B are N-by-NRHS matrices.
  170. *
  171. * Error bounds on the solution and a condition estimate are also
  172. * provided.
  173. *
  174. * Description
  175. * ===========
  176. *
  177. * The following steps are performed by this subroutine:
  178. *
  179. * 1. If FACT = 'E', real scaling factors are computed to equilibrate
  180. * the system:
  181. * TRANS = 'N': diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
  182. * TRANS = 'T': (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
  183. * TRANS = 'C': (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
  184. * Whether or not the system will be equilibrated depends on the
  185. * scaling of the matrix A, but if equilibration is used, A is
  186. * overwritten by diag(R)*A*diag(C) and B by diag(R)*B (if TRANS='N')
  187. * or diag(C)*B (if TRANS = 'T' or 'C').
  188. *
  189. * 2. If FACT = 'N' or 'E', the LU decomposition is used to factor the
  190. * matrix A (after equilibration if FACT = 'E') as
  191. * A = L * U,
  192. * where L is a product of permutation and unit lower triangular
  193. * matrices with KL subdiagonals, and U is upper triangular with
  194. * KL+KU superdiagonals.
  195. *
  196. * 3. If some U(i,i)=0, so that U is exactly singular, then the routine
  197. * returns with INFO = i. Otherwise, the factored form of A is used
  198. * to estimate the condition number of the matrix A. If the
  199. * reciprocal of the condition number is less than machine precision,
  200. * INFO = N+1 is returned as a warning, but the routine still goes on
  201. * to solve for X and compute error bounds as described below.
  202. *
  203. * 4. The system of equations is solved for X using the factored form
  204. * of A.
  205. *
  206. * 5. Iterative refinement is applied to improve the computed solution
  207. * matrix and calculate error bounds and backward error estimates
  208. * for it.
  209. *
  210. * 6. If equilibration was used, the matrix X is premultiplied by
  211. * diag(C) (if TRANS = 'N') or diag(R) (if TRANS = 'T' or 'C') so
  212. * that it solves the original system before equilibration.
  213. *
  214. * Arguments
  215. * =========
  216. *
  217. * FACT (input) CHARACTER*1
  218. * Specifies whether or not the factored form of the matrix A is
  219. * supplied on entry, and if not, whether the matrix A should be
  220. * equilibrated before it is factored.
  221. * = 'F': On entry, AFB and IPIV contain the factored form of
  222. * A. If EQUED is not 'N', the matrix A has been
  223. * equilibrated with scaling factors given by R and C.
  224. * AB, AFB, and IPIV are not modified.
  225. * = 'N': The matrix A will be copied to AFB and factored.
  226. * = 'E': The matrix A will be equilibrated if necessary, then
  227. * copied to AFB and factored.
  228. *
  229. * TRANS (input) CHARACTER*1
  230. * Specifies the form of the system of equations.
  231. * = 'N': A * X = B (No transpose)
  232. * = 'T': A**T * X = B (Transpose)
  233. * = 'C': A**H * X = B (Transpose)
  234. *
  235. * N (input) INTEGER
  236. * The number of linear equations, i.e., the order of the
  237. * matrix A. N >= 0.
  238. *
  239. * KL (input) INTEGER
  240. * The number of subdiagonals within the band of A. KL >= 0.
  241. *
  242. * KU (input) INTEGER
  243. * The number of superdiagonals within the band of A. KU >= 0.
  244. *
  245. * NRHS (input) INTEGER
  246. * The number of right hand sides, i.e., the number of columns
  247. * of the matrices B and X. NRHS >= 0.
  248. *
  249. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
  250. * On entry, the matrix A in band storage, in rows 1 to KL+KU+1.
  251. * The j-th column of A is stored in the j-th column of the
  252. * array AB as follows:
  253. * AB(KU+1+i-j,j) = A(i,j) for max(1,j-KU)<=i<=min(N,j+kl)
  254. *
  255. * If FACT = 'F' and EQUED is not 'N', then A must have been
  256. * equilibrated by the scaling factors in R and/or C. AB is not
  257. * modified if FACT = 'F' or 'N', or if FACT = 'E' and
  258. * EQUED = 'N' on exit.
  259. *
  260. * On exit, if EQUED .ne. 'N', A is scaled as follows:
  261. * EQUED = 'R': A := diag(R) * A
  262. * EQUED = 'C': A := A * diag(C)
  263. * EQUED = 'B': A := diag(R) * A * diag(C).
  264. *
  265. * LDAB (input) INTEGER
  266. * The leading dimension of the array AB. LDAB >= KL+KU+1.
  267. *
  268. * AFB (input or output) DOUBLE PRECISION array, dimension (LDAFB,N)
  269. * If FACT = 'F', then AFB is an input argument and on entry
  270. * contains details of the LU factorization of the band matrix
  271. * A, as computed by DGBTRF. U is stored as an upper triangular
  272. * band matrix with KL+KU superdiagonals in rows 1 to KL+KU+1,
  273. * and the multipliers used during the factorization are stored
  274. * in rows KL+KU+2 to 2*KL+KU+1. If EQUED .ne. 'N', then AFB is
  275. * the factored form of the equilibrated matrix A.
  276. *
  277. * If FACT = 'N', then AFB is an output argument and on exit
  278. * returns details of the LU factorization of A.
  279. *
  280. * If FACT = 'E', then AFB is an output argument and on exit
  281. * returns details of the LU factorization of the equilibrated
  282. * matrix A (see the description of AB for the form of the
  283. * equilibrated matrix).
  284. *
  285. * LDAFB (input) INTEGER
  286. * The leading dimension of the array AFB. LDAFB >= 2*KL+KU+1.
  287. *
  288. * IPIV (input or output) INTEGER array, dimension (N)
  289. * If FACT = 'F', then IPIV is an input argument and on entry
  290. * contains the pivot indices from the factorization A = L*U
  291. * as computed by DGBTRF; row i of the matrix was interchanged
  292. * with row IPIV(i).
  293. *
  294. * If FACT = 'N', then IPIV is an output argument and on exit
  295. * contains the pivot indices from the factorization A = L*U
  296. * of the original matrix A.
  297. *
  298. * If FACT = 'E', then IPIV is an output argument and on exit
  299. * contains the pivot indices from the factorization A = L*U
  300. * of the equilibrated matrix A.
  301. *
  302. * EQUED (input or output) CHARACTER*1
  303. * Specifies the form of equilibration that was done.
  304. * = 'N': No equilibration (always true if FACT = 'N').
  305. * = 'R': Row equilibration, i.e., A has been premultiplied by
  306. * diag(R).
  307. * = 'C': Column equilibration, i.e., A has been postmultiplied
  308. * by diag(C).
  309. * = 'B': Both row and column equilibration, i.e., A has been
  310. * replaced by diag(R) * A * diag(C).
  311. * EQUED is an input argument if FACT = 'F'; otherwise, it is an
  312. * output argument.
  313. *
  314. * R (input or output) DOUBLE PRECISION array, dimension (N)
  315. * The row scale factors for A. If EQUED = 'R' or 'B', A is
  316. * multiplied on the left by diag(R); if EQUED = 'N' or 'C', R
  317. * is not accessed. R is an input argument if FACT = 'F';
  318. * otherwise, R is an output argument. If FACT = 'F' and
  319. * EQUED = 'R' or 'B', each element of R must be positive.
  320. *
  321. * C (input or output) DOUBLE PRECISION array, dimension (N)
  322. * The column scale factors for A. If EQUED = 'C' or 'B', A is
  323. * multiplied on the right by diag(C); if EQUED = 'N' or 'R', C
  324. * is not accessed. C is an input argument if FACT = 'F';
  325. * otherwise, C is an output argument. If FACT = 'F' and
  326. * EQUED = 'C' or 'B', each element of C must be positive.
  327. *
  328. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  329. * On entry, the right hand side matrix B.
  330. * On exit,
  331. * if EQUED = 'N', B is not modified;
  332. * if TRANS = 'N' and EQUED = 'R' or 'B', B is overwritten by
  333. * diag(R)*B;
  334. * if TRANS = 'T' or 'C' and EQUED = 'C' or 'B', B is
  335. * overwritten by diag(C)*B.
  336. *
  337. * LDB (input) INTEGER
  338. * The leading dimension of the array B. LDB >= max(1,N).
  339. *
  340. * X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
  341. * If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X
  342. * to the original system of equations. Note that A and B are
  343. * modified on exit if EQUED .ne. 'N', and the solution to the
  344. * equilibrated system is inv(diag(C))*X if TRANS = 'N' and
  345. * EQUED = 'C' or 'B', or inv(diag(R))*X if TRANS = 'T' or 'C'
  346. * and EQUED = 'R' or 'B'.
  347. *
  348. * LDX (input) INTEGER
  349. * The leading dimension of the array X. LDX >= max(1,N).
  350. *
  351. * RCOND (output) DOUBLE PRECISION
  352. * The estimate of the reciprocal condition number of the matrix
  353. * A after equilibration (if done). If RCOND is less than the
  354. * machine precision (in particular, if RCOND = 0), the matrix
  355. * is singular to working precision. This condition is
  356. * indicated by a return code of INFO > 0.
  357. *
  358. * FERR (output) DOUBLE PRECISION array, dimension (NRHS)
  359. * The estimated forward error bound for each solution vector
  360. * X(j) (the j-th column of the solution matrix X).
  361. * If XTRUE is the true solution corresponding to X(j), FERR(j)
  362. * is an estimated upper bound for the magnitude of the largest
  363. * element in (X(j) - XTRUE) divided by the magnitude of the
  364. * largest element in X(j). The estimate is as reliable as
  365. * the estimate for RCOND, and is almost always a slight
  366. * overestimate of the true error.
  367. *
  368. * BERR (output) DOUBLE PRECISION array, dimension (NRHS)
  369. * The componentwise relative backward error of each solution
  370. * vector X(j) (i.e., the smallest relative change in
  371. * any element of A or B that makes X(j) an exact solution).
  372. *
  373. * WORK (workspace/output) DOUBLE PRECISION array, dimension (3*N)
  374. * On exit, WORK(1) contains the reciprocal pivot growth
  375. * factor norm(A)/norm(U). The "max absolute element" norm is
  376. * used. If WORK(1) is much less than 1, then the stability
  377. * of the LU factorization of the (equilibrated) matrix A
  378. * could be poor. This also means that the solution X, condition
  379. * estimator RCOND, and forward error bound FERR could be
  380. * unreliable. If factorization fails with 0<INFO<=N, then
  381. * WORK(1) contains the reciprocal pivot growth factor for the
  382. * leading INFO columns of A.
  383. *
  384. * IWORK (workspace) INTEGER array, dimension (N)
  385. *
  386. * INFO (output) INTEGER
  387. * = 0: successful exit
  388. * < 0: if INFO = -i, the i-th argument had an illegal value
  389. * > 0: if INFO = i, and i is
  390. * <= N: U(i,i) is exactly zero. The factorization
  391. * has been completed, but the factor U is exactly
  392. * singular, so the solution and error bounds
  393. * could not be computed. RCOND = 0 is returned.
  394. * = N+1: U is nonsingular, but RCOND is less than machine
  395. * precision, meaning that the matrix is singular
  396. * to working precision. Nevertheless, the
  397. * solution and error bounds are computed because
  398. * there are a number of situations where the
  399. * computed solution can be more accurate than the
  400. * value of RCOND would suggest.
  401. *
  402. * =====================================================================
  403. *
  404. * .. Parameters ..
  405. DOUBLE PRECISION ZERO, ONE
  406. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  407. * ..
  408. * .. Local Scalars ..
  409. LOGICAL COLEQU, EQUIL, NOFACT, NOTRAN, ROWEQU
  410. CHARACTER NORM
  411. INTEGER I, INFEQU, J, J1, J2
  412. DOUBLE PRECISION AMAX, ANORM, BIGNUM, COLCND, RCMAX, RCMIN,
  413. $ ROWCND, RPVGRW, SMLNUM
  414. * ..
  415. * .. External Functions ..
  416. LOGICAL LSAME
  417. DOUBLE PRECISION DLAMCH, DLANGB, DLANTB
  418. EXTERNAL LSAME, DLAMCH, DLANGB, DLANTB
  419. * ..
  420. * .. External Subroutines ..
  421. EXTERNAL DCOPY, DGBCON, DGBEQU, DGBRFS, DGBTRF, DGBTRS,
  422. $ DLACPY, DLAQGB, XERBLA
  423. * ..
  424. * .. Intrinsic Functions ..
  425. INTRINSIC ABS, MAX, MIN
  426. * ..
  427. * .. Executable Statements ..
  428. *
  429. INFO = 0
  430. NOFACT = LSAME( FACT, 'N' )
  431. EQUIL = LSAME( FACT, 'E' )
  432. NOTRAN = LSAME( TRANS, 'N' )
  433. IF( NOFACT .OR. EQUIL ) THEN
  434. EQUED = 'N'
  435. ROWEQU = .FALSE.
  436. COLEQU = .FALSE.
  437. ELSE
  438. ROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )
  439. COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )
  440. SMLNUM = DLAMCH( 'Safe minimum' )
  441. BIGNUM = ONE / SMLNUM
  442. END IF
  443. *
  444. * Test the input parameters.
  445. *
  446. IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )
  447. $ THEN
  448. INFO = -1
  449. ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
  450. $ LSAME( TRANS, 'C' ) ) THEN
  451. INFO = -2
  452. ELSE IF( N.LT.0 ) THEN
  453. INFO = -3
  454. ELSE IF( KL.LT.0 ) THEN
  455. INFO = -4
  456. ELSE IF( KU.LT.0 ) THEN
  457. INFO = -5
  458. ELSE IF( NRHS.LT.0 ) THEN
  459. INFO = -6
  460. ELSE IF( LDAB.LT.KL+KU+1 ) THEN
  461. INFO = -8
  462. ELSE IF( LDAFB.LT.2*KL+KU+1 ) THEN
  463. INFO = -10
  464. ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.
  465. $ ( ROWEQU .OR. COLEQU .OR. LSAME( EQUED, 'N' ) ) ) THEN
  466. INFO = -12
  467. ELSE
  468. IF( ROWEQU ) THEN
  469. RCMIN = BIGNUM
  470. RCMAX = ZERO
  471. DO 10 J = 1, N
  472. RCMIN = MIN( RCMIN, R( J ) )
  473. RCMAX = MAX( RCMAX, R( J ) )
  474. 10 CONTINUE
  475. IF( RCMIN.LE.ZERO ) THEN
  476. INFO = -13
  477. ELSE IF( N.GT.0 ) THEN
  478. ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )
  479. ELSE
  480. ROWCND = ONE
  481. END IF
  482. END IF
  483. IF( COLEQU .AND. INFO.EQ.0 ) THEN
  484. RCMIN = BIGNUM
  485. RCMAX = ZERO
  486. DO 20 J = 1, N
  487. RCMIN = MIN( RCMIN, C( J ) )
  488. RCMAX = MAX( RCMAX, C( J ) )
  489. 20 CONTINUE
  490. IF( RCMIN.LE.ZERO ) THEN
  491. INFO = -14
  492. ELSE IF( N.GT.0 ) THEN
  493. COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )
  494. ELSE
  495. COLCND = ONE
  496. END IF
  497. END IF
  498. IF( INFO.EQ.0 ) THEN
  499. IF( LDB.LT.MAX( 1, N ) ) THEN
  500. INFO = -16
  501. ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
  502. INFO = -18
  503. END IF
  504. END IF
  505. END IF
  506. *
  507. IF( INFO.NE.0 ) THEN
  508. CALL XERBLA( 'DGBSVX', -INFO )
  509. RETURN
  510. END IF
  511. *
  512. IF( EQUIL ) THEN
  513. *
  514. * Compute row and column scalings to equilibrate the matrix A.
  515. *
  516. CALL DGBEQU( N, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,
  517. $ AMAX, INFEQU )
  518. IF( INFEQU.EQ.0 ) THEN
  519. *
  520. * Equilibrate the matrix.
  521. *
  522. CALL DLAQGB( N, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,
  523. $ AMAX, EQUED )
  524. ROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )
  525. COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )
  526. END IF
  527. END IF
  528. *
  529. * Scale the right hand side.
  530. *
  531. IF( NOTRAN ) THEN
  532. IF( ROWEQU ) THEN
  533. DO 40 J = 1, NRHS
  534. DO 30 I = 1, N
  535. B( I, J ) = R( I )*B( I, J )
  536. 30 CONTINUE
  537. 40 CONTINUE
  538. END IF
  539. ELSE IF( COLEQU ) THEN
  540. DO 60 J = 1, NRHS
  541. DO 50 I = 1, N
  542. B( I, J ) = C( I )*B( I, J )
  543. 50 CONTINUE
  544. 60 CONTINUE
  545. END IF
  546. *
  547. IF( NOFACT .OR. EQUIL ) THEN
  548. *
  549. * Compute the LU factorization of the band matrix A.
  550. *
  551. DO 70 J = 1, N
  552. J1 = MAX( J-KU, 1 )
  553. J2 = MIN( J+KL, N )
  554. CALL DCOPY( J2-J1+1, AB( KU+1-J+J1, J ), 1,
  555. $ AFB( KL+KU+1-J+J1, J ), 1 )
  556. 70 CONTINUE
  557. *
  558. CALL DGBTRF( N, N, KL, KU, AFB, LDAFB, IPIV, INFO )
  559. *
  560. * Return if INFO is non-zero.
  561. *
  562. IF( INFO.GT.0 ) THEN
  563. *
  564. * Compute the reciprocal pivot growth factor of the
  565. * leading rank-deficient INFO columns of A.
  566. *
  567. ANORM = ZERO
  568. DO 90 J = 1, INFO
  569. DO 80 I = MAX( KU+2-J, 1 ), MIN( N+KU+1-J, KL+KU+1 )
  570. ANORM = MAX( ANORM, ABS( AB( I, J ) ) )
  571. 80 CONTINUE
  572. 90 CONTINUE
  573. RPVGRW = DLANTB( 'M', 'U', 'N', INFO, MIN( INFO-1, KL+KU ),
  574. $ AFB( MAX( 1, KL+KU+2-INFO ), 1 ), LDAFB,
  575. $ WORK )
  576. IF( RPVGRW.EQ.ZERO ) THEN
  577. RPVGRW = ONE
  578. ELSE
  579. RPVGRW = ANORM / RPVGRW
  580. END IF
  581. WORK( 1 ) = RPVGRW
  582. RCOND = ZERO
  583. RETURN
  584. END IF
  585. END IF
  586. *
  587. * Compute the norm of the matrix A and the
  588. * reciprocal pivot growth factor RPVGRW.
  589. *
  590. IF( NOTRAN ) THEN
  591. NORM = '1'
  592. ELSE
  593. NORM = 'I'
  594. END IF
  595. ANORM = DLANGB( NORM, N, KL, KU, AB, LDAB, WORK )
  596. RPVGRW = DLANTB( 'M', 'U', 'N', N, KL+KU, AFB, LDAFB, WORK )
  597. IF( RPVGRW.EQ.ZERO ) THEN
  598. RPVGRW = ONE
  599. ELSE
  600. RPVGRW = DLANGB( 'M', N, KL, KU, AB, LDAB, WORK ) / RPVGRW
  601. END IF
  602. *
  603. * Compute the reciprocal of the condition number of A.
  604. *
  605. CALL DGBCON( NORM, N, KL, KU, AFB, LDAFB, IPIV, ANORM, RCOND,
  606. $ WORK, IWORK, INFO )
  607. *
  608. * Compute the solution matrix X.
  609. *
  610. CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
  611. CALL DGBTRS( TRANS, N, KL, KU, NRHS, AFB, LDAFB, IPIV, X, LDX,
  612. $ INFO )
  613. *
  614. * Use iterative refinement to improve the computed solution and
  615. * compute error bounds and backward error estimates for it.
  616. *
  617. CALL DGBRFS( TRANS, N, KL, KU, NRHS, AB, LDAB, AFB, LDAFB, IPIV,
  618. $ B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )
  619. *
  620. * Transform the solution matrix X to a solution of the original
  621. * system.
  622. *
  623. IF( NOTRAN ) THEN
  624. IF( COLEQU ) THEN
  625. DO 110 J = 1, NRHS
  626. DO 100 I = 1, N
  627. X( I, J ) = C( I )*X( I, J )
  628. 100 CONTINUE
  629. 110 CONTINUE
  630. DO 120 J = 1, NRHS
  631. FERR( J ) = FERR( J ) / COLCND
  632. 120 CONTINUE
  633. END IF
  634. ELSE IF( ROWEQU ) THEN
  635. DO 140 J = 1, NRHS
  636. DO 130 I = 1, N
  637. X( I, J ) = R( I )*X( I, J )
  638. 130 CONTINUE
  639. 140 CONTINUE
  640. DO 150 J = 1, NRHS
  641. FERR( J ) = FERR( J ) / ROWCND
  642. 150 CONTINUE
  643. END IF
  644. *
  645. * Set INFO = N+1 if the matrix is singular to working precision.
  646. *
  647. IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
  648. $ INFO = N + 1
  649. *
  650. WORK( 1 ) = RPVGRW
  651. RETURN
  652. *
  653. * End of DGBSVX
  654. *
  655. END
  656. SUBROUTINE DGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, WR, WI,
  657. $ VS, LDVS, WORK, LWORK, BWORK, INFO )
  658. *
  659. * -- LAPACK driver routine (version 3.1) --
  660. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  661. * November 2006
  662. *
  663. * .. Scalar Arguments ..
  664. CHARACTER JOBVS, SORT
  665. INTEGER INFO, LDA, LDVS, LWORK, N, SDIM
  666. * ..
  667. * .. Array Arguments ..
  668. LOGICAL BWORK( * )
  669. DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
  670. $ WR( * )
  671. * ..
  672. * .. Function Arguments ..
  673. LOGICAL SELECT
  674. EXTERNAL SELECT
  675. * ..
  676. *
  677. * Purpose
  678. * =======
  679. *
  680. * DGEES computes for an N-by-N real nonsymmetric matrix A, the
  681. * eigenvalues, the real Schur form T, and, optionally, the matrix of
  682. * Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T).
  683. *
  684. * Optionally, it also orders the eigenvalues on the diagonal of the
  685. * real Schur form so that selected eigenvalues are at the top left.
  686. * The leading columns of Z then form an orthonormal basis for the
  687. * invariant subspace corresponding to the selected eigenvalues.
  688. *
  689. * A matrix is in real Schur form if it is upper quasi-triangular with
  690. * 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in the
  691. * form
  692. * [ a b ]
  693. * [ c a ]
  694. *
  695. * where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).
  696. *
  697. * Arguments
  698. * =========
  699. *
  700. * JOBVS (input) CHARACTER*1
  701. * = 'N': Schur vectors are not computed;
  702. * = 'V': Schur vectors are computed.
  703. *
  704. * SORT (input) CHARACTER*1
  705. * Specifies whether or not to order the eigenvalues on the
  706. * diagonal of the Schur form.
  707. * = 'N': Eigenvalues are not ordered;
  708. * = 'S': Eigenvalues are ordered (see SELECT).
  709. *
  710. * SELECT (external procedure) LOGICAL FUNCTION of two DOUBLE PRECISION arguments
  711. * SELECT must be declared EXTERNAL in the calling subroutine.
  712. * If SORT = 'S', SELECT is used to select eigenvalues to sort
  713. * to the top left of the Schur form.
  714. * If SORT = 'N', SELECT is not referenced.
  715. * An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if
  716. * SELECT(WR(j),WI(j)) is true; i.e., if either one of a complex
  717. * conjugate pair of eigenvalues is selected, then both complex
  718. * eigenvalues are selected.
  719. * Note that a selected complex eigenvalue may no longer
  720. * satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since
  721. * ordering may change the value of complex eigenvalues
  722. * (especially if the eigenvalue is ill-conditioned); in this
  723. * case INFO is set to N+2 (see INFO below).
  724. *
  725. * N (input) INTEGER
  726. * The order of the matrix A. N >= 0.
  727. *
  728. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  729. * On entry, the N-by-N matrix A.
  730. * On exit, A has been overwritten by its real Schur form T.
  731. *
  732. * LDA (input) INTEGER
  733. * The leading dimension of the array A. LDA >= max(1,N).
  734. *
  735. * SDIM (output) INTEGER
  736. * If SORT = 'N', SDIM = 0.
  737. * If SORT = 'S', SDIM = number of eigenvalues (after sorting)
  738. * for which SELECT is true. (Complex conjugate
  739. * pairs for which SELECT is true for either
  740. * eigenvalue count as 2.)
  741. *
  742. * WR (output) DOUBLE PRECISION array, dimension (N)
  743. * WI (output) DOUBLE PRECISION array, dimension (N)
  744. * WR and WI contain the real and imaginary parts,
  745. * respectively, of the computed eigenvalues in the same order
  746. * that they appear on the diagonal of the output Schur form T.
  747. * Complex conjugate pairs of eigenvalues will appear
  748. * consecutively with the eigenvalue having the positive
  749. * imaginary part first.
  750. *
  751. * VS (output) DOUBLE PRECISION array, dimension (LDVS,N)
  752. * If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur
  753. * vectors.
  754. * If JOBVS = 'N', VS is not referenced.
  755. *
  756. * LDVS (input) INTEGER
  757. * The leading dimension of the array VS. LDVS >= 1; if
  758. * JOBVS = 'V', LDVS >= N.
  759. *
  760. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  761. * On exit, if INFO = 0, WORK(1) contains the optimal LWORK.
  762. *
  763. * LWORK (input) INTEGER
  764. * The dimension of the array WORK. LWORK >= max(1,3*N).
  765. * For good performance, LWORK must generally be larger.
  766. *
  767. * If LWORK = -1, then a workspace query is assumed; the routine
  768. * only calculates the optimal size of the WORK array, returns
  769. * this value as the first entry of the WORK array, and no error
  770. * message related to LWORK is issued by XERBLA.
  771. *
  772. * BWORK (workspace) LOGICAL array, dimension (N)
  773. * Not referenced if SORT = 'N'.
  774. *
  775. * INFO (output) INTEGER
  776. * = 0: successful exit
  777. * < 0: if INFO = -i, the i-th argument had an illegal value.
  778. * > 0: if INFO = i, and i is
  779. * <= N: the QR algorithm failed to compute all the
  780. * eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI
  781. * contain those eigenvalues which have converged; if
  782. * JOBVS = 'V', VS contains the matrix which reduces A
  783. * to its partially converged Schur form.
  784. * = N+1: the eigenvalues could not be reordered because some
  785. * eigenvalues were too close to separate (the problem
  786. * is very ill-conditioned);
  787. * = N+2: after reordering, roundoff changed values of some
  788. * complex eigenvalues so that leading eigenvalues in
  789. * the Schur form no longer satisfy SELECT=.TRUE. This
  790. * could also be caused by underflow due to scaling.
  791. *
  792. * =====================================================================
  793. *
  794. * .. Parameters ..
  795. DOUBLE PRECISION ZERO, ONE
  796. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  797. * ..
  798. * .. Local Scalars ..
  799. LOGICAL CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTST,
  800. $ WANTVS
  801. INTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,
  802. $ IHI, ILO, INXT, IP, ITAU, IWRK, MAXWRK, MINWRK
  803. DOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, S, SEP, SMLNUM
  804. * ..
  805. * .. Local Arrays ..
  806. INTEGER IDUM( 1 )
  807. DOUBLE PRECISION DUM( 1 )
  808. * ..
  809. * .. External Subroutines ..
  810. EXTERNAL DCOPY, DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY,
  811. $ DLABAD, DLASCL, DORGHR, DSWAP, DTRSEN, XERBLA
  812. * ..
  813. * .. External Functions ..
  814. LOGICAL LSAME
  815. INTEGER ILAENV
  816. DOUBLE PRECISION DLAMCH, DLANGE
  817. EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE
  818. * ..
  819. * .. Intrinsic Functions ..
  820. INTRINSIC MAX, SQRT
  821. * ..
  822. * .. Executable Statements ..
  823. *
  824. * Test the input arguments
  825. *
  826. INFO = 0
  827. LQUERY = ( LWORK.EQ.-1 )
  828. WANTVS = LSAME( JOBVS, 'V' )
  829. WANTST = LSAME( SORT, 'S' )
  830. IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
  831. INFO = -1
  832. ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
  833. INFO = -2
  834. ELSE IF( N.LT.0 ) THEN
  835. INFO = -4
  836. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  837. INFO = -6
  838. ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
  839. INFO = -11
  840. END IF
  841. *
  842. * Compute workspace
  843. * (Note: Comments in the code beginning "Workspace:" describe the
  844. * minimal amount of workspace needed at that point in the code,
  845. * as well as the preferred amount for good performance.
  846. * NB refers to the optimal block size for the immediately
  847. * following subroutine, as returned by ILAENV.
  848. * HSWORK refers to the workspace preferred by DHSEQR, as
  849. * calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
  850. * the worst case.)
  851. *
  852. IF( INFO.EQ.0 ) THEN
  853. IF( N.EQ.0 ) THEN
  854. MINWRK = 1
  855. MAXWRK = 1
  856. ELSE
  857. MAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )
  858. MINWRK = 3*N
  859. *
  860. CALL DHSEQR( 'S', JOBVS, N, 1, N, A, LDA, WR, WI, VS, LDVS,
  861. $ WORK, -1, IEVAL )
  862. HSWORK = WORK( 1 )
  863. *
  864. IF( .NOT.WANTVS ) THEN
  865. MAXWRK = MAX( MAXWRK, N + HSWORK )
  866. ELSE
  867. MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
  868. $ 'DORGHR', ' ', N, 1, N, -1 ) )
  869. MAXWRK = MAX( MAXWRK, N + HSWORK )
  870. END IF
  871. END IF
  872. WORK( 1 ) = MAXWRK
  873. *
  874. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  875. INFO = -13
  876. END IF
  877. END IF
  878. *
  879. IF( INFO.NE.0 ) THEN
  880. CALL XERBLA( 'DGEES ', -INFO )
  881. RETURN
  882. ELSE IF( LQUERY ) THEN
  883. RETURN
  884. END IF
  885. *
  886. * Quick return if possible
  887. *
  888. IF( N.EQ.0 ) THEN
  889. SDIM = 0
  890. RETURN
  891. END IF
  892. *
  893. * Get machine constants
  894. *
  895. EPS = DLAMCH( 'P' )
  896. SMLNUM = DLAMCH( 'S' )
  897. BIGNUM = ONE / SMLNUM
  898. CALL DLABAD( SMLNUM, BIGNUM )
  899. SMLNUM = SQRT( SMLNUM ) / EPS
  900. BIGNUM = ONE / SMLNUM
  901. *
  902. * Scale A if max element outside range [SMLNUM,BIGNUM]
  903. *
  904. ANRM = DLANGE( 'M', N, N, A, LDA, DUM )
  905. SCALEA = .FALSE.
  906. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  907. SCALEA = .TRUE.
  908. CSCALE = SMLNUM
  909. ELSE IF( ANRM.GT.BIGNUM ) THEN
  910. SCALEA = .TRUE.
  911. CSCALE = BIGNUM
  912. END IF
  913. IF( SCALEA )
  914. $ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
  915. *
  916. * Permute the matrix to make it more nearly triangular
  917. * (Workspace: need N)
  918. *
  919. IBAL = 1
  920. CALL DGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
  921. *
  922. * Reduce to upper Hessenberg form
  923. * (Workspace: need 3*N, prefer 2*N+N*NB)
  924. *
  925. ITAU = N + IBAL
  926. IWRK = N + ITAU
  927. CALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
  928. $ LWORK-IWRK+1, IERR )
  929. *
  930. IF( WANTVS ) THEN
  931. *
  932. * Copy Householder vectors to VS
  933. *
  934. CALL DLACPY( 'L', N, N, A, LDA, VS, LDVS )
  935. *
  936. * Generate orthogonal matrix in VS
  937. * (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
  938. *
  939. CALL DORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
  940. $ LWORK-IWRK+1, IERR )
  941. END IF
  942. *
  943. SDIM = 0
  944. *
  945. * Perform QR iteration, accumulating Schur vectors in VS if desired
  946. * (Workspace: need N+1, prefer N+HSWORK (see comments) )
  947. *
  948. IWRK = ITAU
  949. CALL DHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,
  950. $ WORK( IWRK ), LWORK-IWRK+1, IEVAL )
  951. IF( IEVAL.GT.0 )
  952. $ INFO = IEVAL
  953. *
  954. * Sort eigenvalues if desired
  955. *
  956. IF( WANTST .AND. INFO.EQ.0 ) THEN
  957. IF( SCALEA ) THEN
  958. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )
  959. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )
  960. END IF
  961. DO 10 I = 1, N
  962. BWORK( I ) = SELECT( WR( I ), WI( I ) )
  963. 10 CONTINUE
  964. *
  965. * Reorder eigenvalues and transform Schur vectors
  966. * (Workspace: none needed)
  967. *
  968. CALL DTRSEN( 'N', JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,
  969. $ SDIM, S, SEP, WORK( IWRK ), LWORK-IWRK+1, IDUM, 1,
  970. $ ICOND )
  971. IF( ICOND.GT.0 )
  972. $ INFO = N + ICOND
  973. END IF
  974. *
  975. IF( WANTVS ) THEN
  976. *
  977. * Undo balancing
  978. * (Workspace: need N)
  979. *
  980. CALL DGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,
  981. $ IERR )
  982. END IF
  983. *
  984. IF( SCALEA ) THEN
  985. *
  986. * Undo scaling for the Schur form of A
  987. *
  988. CALL DLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
  989. CALL DCOPY( N, A, LDA+1, WR, 1 )
  990. IF( CSCALE.EQ.SMLNUM ) THEN
  991. *
  992. * If scaling back towards underflow, adjust WI if an
  993. * offdiagonal element of a 2-by-2 block in the Schur form
  994. * underflows.
  995. *
  996. IF( IEVAL.GT.0 ) THEN
  997. I1 = IEVAL + 1
  998. I2 = IHI - 1
  999. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI,
  1000. $ MAX( ILO-1, 1 ), IERR )
  1001. ELSE IF( WANTST ) THEN
  1002. I1 = 1
  1003. I2 = N - 1
  1004. ELSE
  1005. I1 = ILO
  1006. I2 = IHI - 1
  1007. END IF
  1008. INXT = I1 - 1
  1009. DO 20 I = I1, I2
  1010. IF( I.LT.INXT )
  1011. $ GO TO 20
  1012. IF( WI( I ).EQ.ZERO ) THEN
  1013. INXT = I + 1
  1014. ELSE
  1015. IF( A( I+1, I ).EQ.ZERO ) THEN
  1016. WI( I ) = ZERO
  1017. WI( I+1 ) = ZERO
  1018. ELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.
  1019. $ ZERO ) THEN
  1020. WI( I ) = ZERO
  1021. WI( I+1 ) = ZERO
  1022. IF( I.GT.1 )
  1023. $ CALL DSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )
  1024. IF( N.GT.I+1 )
  1025. $ CALL DSWAP( N-I-1, A( I, I+2 ), LDA,
  1026. $ A( I+1, I+2 ), LDA )
  1027. IF( WANTVS ) THEN
  1028. CALL DSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )
  1029. END IF
  1030. A( I, I+1 ) = A( I+1, I )
  1031. A( I+1, I ) = ZERO
  1032. END IF
  1033. INXT = I + 2
  1034. END IF
  1035. 20 CONTINUE
  1036. END IF
  1037. *
  1038. * Undo scaling for the imaginary part of the eigenvalues
  1039. *
  1040. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,
  1041. $ WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )
  1042. END IF
  1043. *
  1044. IF( WANTST .AND. INFO.EQ.0 ) THEN
  1045. *
  1046. * Check if reordering successful
  1047. *
  1048. LASTSL = .TRUE.
  1049. LST2SL = .TRUE.
  1050. SDIM = 0
  1051. IP = 0
  1052. DO 30 I = 1, N
  1053. CURSL = SELECT( WR( I ), WI( I ) )
  1054. IF( WI( I ).EQ.ZERO ) THEN
  1055. IF( CURSL )
  1056. $ SDIM = SDIM + 1
  1057. IP = 0
  1058. IF( CURSL .AND. .NOT.LASTSL )
  1059. $ INFO = N + 2
  1060. ELSE
  1061. IF( IP.EQ.1 ) THEN
  1062. *
  1063. * Last eigenvalue of conjugate pair
  1064. *
  1065. CURSL = CURSL .OR. LASTSL
  1066. LASTSL = CURSL
  1067. IF( CURSL )
  1068. $ SDIM = SDIM + 2
  1069. IP = -1
  1070. IF( CURSL .AND. .NOT.LST2SL )
  1071. $ INFO = N + 2
  1072. ELSE
  1073. *
  1074. * First eigenvalue of conjugate pair
  1075. *
  1076. IP = 1
  1077. END IF
  1078. END IF
  1079. LST2SL = LASTSL
  1080. LASTSL = CURSL
  1081. 30 CONTINUE
  1082. END IF
  1083. *
  1084. WORK( 1 ) = MAXWRK
  1085. RETURN
  1086. *
  1087. * End of DGEES
  1088. *
  1089. END
  1090. SUBROUTINE DGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM,
  1091. $ WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,
  1092. $ IWORK, LIWORK, BWORK, INFO )
  1093. *
  1094. * -- LAPACK driver routine (version 3.1) --
  1095. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  1096. * November 2006
  1097. *
  1098. * .. Scalar Arguments ..
  1099. CHARACTER JOBVS, SENSE, SORT
  1100. INTEGER INFO, LDA, LDVS, LIWORK, LWORK, N, SDIM
  1101. DOUBLE PRECISION RCONDE, RCONDV
  1102. * ..
  1103. * .. Array Arguments ..
  1104. LOGICAL BWORK( * )
  1105. INTEGER IWORK( * )
  1106. DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
  1107. $ WR( * )
  1108. * ..
  1109. * .. Function Arguments ..
  1110. LOGICAL SELECT
  1111. EXTERNAL SELECT
  1112. * ..
  1113. *
  1114. * Purpose
  1115. * =======
  1116. *
  1117. * DGEESX computes for an N-by-N real nonsymmetric matrix A, the
  1118. * eigenvalues, the real Schur form T, and, optionally, the matrix of
  1119. * Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T).
  1120. *
  1121. * Optionally, it also orders the eigenvalues on the diagonal of the
  1122. * real Schur form so that selected eigenvalues are at the top left;
  1123. * computes a reciprocal condition number for the average of the
  1124. * selected eigenvalues (RCONDE); and computes a reciprocal condition
  1125. * number for the right invariant subspace corresponding to the
  1126. * selected eigenvalues (RCONDV). The leading columns of Z form an
  1127. * orthonormal basis for this invariant subspace.
  1128. *
  1129. * For further explanation of the reciprocal condition numbers RCONDE
  1130. * and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where
  1131. * these quantities are called s and sep respectively).
  1132. *
  1133. * A real matrix is in real Schur form if it is upper quasi-triangular
  1134. * with 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in
  1135. * the form
  1136. * [ a b ]
  1137. * [ c a ]
  1138. *
  1139. * where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).
  1140. *
  1141. * Arguments
  1142. * =========
  1143. *
  1144. * JOBVS (input) CHARACTER*1
  1145. * = 'N': Schur vectors are not computed;
  1146. * = 'V': Schur vectors are computed.
  1147. *
  1148. * SORT (input) CHARACTER*1
  1149. * Specifies whether or not to order the eigenvalues on the
  1150. * diagonal of the Schur form.
  1151. * = 'N': Eigenvalues are not ordered;
  1152. * = 'S': Eigenvalues are ordered (see SELECT).
  1153. *
  1154. * SELECT (external procedure) LOGICAL FUNCTION of two DOUBLE PRECISION arguments
  1155. * SELECT must be declared EXTERNAL in the calling subroutine.
  1156. * If SORT = 'S', SELECT is used to select eigenvalues to sort
  1157. * to the top left of the Schur form.
  1158. * If SORT = 'N', SELECT is not referenced.
  1159. * An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if
  1160. * SELECT(WR(j),WI(j)) is true; i.e., if either one of a
  1161. * complex conjugate pair of eigenvalues is selected, then both
  1162. * are. Note that a selected complex eigenvalue may no longer
  1163. * satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since
  1164. * ordering may change the value of complex eigenvalues
  1165. * (especially if the eigenvalue is ill-conditioned); in this
  1166. * case INFO may be set to N+3 (see INFO below).
  1167. *
  1168. * SENSE (input) CHARACTER*1
  1169. * Determines which reciprocal condition numbers are computed.
  1170. * = 'N': None are computed;
  1171. * = 'E': Computed for average of selected eigenvalues only;
  1172. * = 'V': Computed for selected right invariant subspace only;
  1173. * = 'B': Computed for both.
  1174. * If SENSE = 'E', 'V' or 'B', SORT must equal 'S'.
  1175. *
  1176. * N (input) INTEGER
  1177. * The order of the matrix A. N >= 0.
  1178. *
  1179. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  1180. * On entry, the N-by-N matrix A.
  1181. * On exit, A is overwritten by its real Schur form T.
  1182. *
  1183. * LDA (input) INTEGER
  1184. * The leading dimension of the array A. LDA >= max(1,N).
  1185. *
  1186. * SDIM (output) INTEGER
  1187. * If SORT = 'N', SDIM = 0.
  1188. * If SORT = 'S', SDIM = number of eigenvalues (after sorting)
  1189. * for which SELECT is true. (Complex conjugate
  1190. * pairs for which SELECT is true for either
  1191. * eigenvalue count as 2.)
  1192. *
  1193. * WR (output) DOUBLE PRECISION array, dimension (N)
  1194. * WI (output) DOUBLE PRECISION array, dimension (N)
  1195. * WR and WI contain the real and imaginary parts, respectively,
  1196. * of the computed eigenvalues, in the same order that they
  1197. * appear on the diagonal of the output Schur form T. Complex
  1198. * conjugate pairs of eigenvalues appear consecutively with the
  1199. * eigenvalue having the positive imaginary part first.
  1200. *
  1201. * VS (output) DOUBLE PRECISION array, dimension (LDVS,N)
  1202. * If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur
  1203. * vectors.
  1204. * If JOBVS = 'N', VS is not referenced.
  1205. *
  1206. * LDVS (input) INTEGER
  1207. * The leading dimension of the array VS. LDVS >= 1, and if
  1208. * JOBVS = 'V', LDVS >= N.
  1209. *
  1210. * RCONDE (output) DOUBLE PRECISION
  1211. * If SENSE = 'E' or 'B', RCONDE contains the reciprocal
  1212. * condition number for the average of the selected eigenvalues.
  1213. * Not referenced if SENSE = 'N' or 'V'.
  1214. *
  1215. * RCONDV (output) DOUBLE PRECISION
  1216. * If SENSE = 'V' or 'B', RCONDV contains the reciprocal
  1217. * condition number for the selected right invariant subspace.
  1218. * Not referenced if SENSE = 'N' or 'E'.
  1219. *
  1220. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  1221. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  1222. *
  1223. * LWORK (input) INTEGER
  1224. * The dimension of the array WORK. LWORK >= max(1,3*N).
  1225. * Also, if SENSE = 'E' or 'V' or 'B',
  1226. * LWORK >= N+2*SDIM*(N-SDIM), where SDIM is the number of
  1227. * selected eigenvalues computed by this routine. Note that
  1228. * N+2*SDIM*(N-SDIM) <= N+N*N/2. Note also that an error is only
  1229. * returned if LWORK < max(1,3*N), but if SENSE = 'E' or 'V' or
  1230. * 'B' this may not be large enough.
  1231. * For good performance, LWORK must generally be larger.
  1232. *
  1233. * If LWORK = -1, then a workspace query is assumed; the routine
  1234. * only calculates upper bounds on the optimal sizes of the
  1235. * arrays WORK and IWORK, returns these values as the first
  1236. * entries of the WORK and IWORK arrays, and no error messages
  1237. * related to LWORK or LIWORK are issued by XERBLA.
  1238. *
  1239. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  1240. * On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
  1241. *
  1242. * LIWORK (input) INTEGER
  1243. * The dimension of the array IWORK.
  1244. * LIWORK >= 1; if SENSE = 'V' or 'B', LIWORK >= SDIM*(N-SDIM).
  1245. * Note that SDIM*(N-SDIM) <= N*N/4. Note also that an error is
  1246. * only returned if LIWORK < 1, but if SENSE = 'V' or 'B' this
  1247. * may not be large enough.
  1248. *
  1249. * If LIWORK = -1, then a workspace query is assumed; the
  1250. * routine only calculates upper bounds on the optimal sizes of
  1251. * the arrays WORK and IWORK, returns these values as the first
  1252. * entries of the WORK and IWORK arrays, and no error messages
  1253. * related to LWORK or LIWORK are issued by XERBLA.
  1254. *
  1255. * BWORK (workspace) LOGICAL array, dimension (N)
  1256. * Not referenced if SORT = 'N'.
  1257. *
  1258. * INFO (output) INTEGER
  1259. * = 0: successful exit
  1260. * < 0: if INFO = -i, the i-th argument had an illegal value.
  1261. * > 0: if INFO = i, and i is
  1262. * <= N: the QR algorithm failed to compute all the
  1263. * eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI
  1264. * contain those eigenvalues which have converged; if
  1265. * JOBVS = 'V', VS contains the transformation which
  1266. * reduces A to its partially converged Schur form.
  1267. * = N+1: the eigenvalues could not be reordered because some
  1268. * eigenvalues were too close to separate (the problem
  1269. * is very ill-conditioned);
  1270. * = N+2: after reordering, roundoff changed values of some
  1271. * complex eigenvalues so that leading eigenvalues in
  1272. * the Schur form no longer satisfy SELECT=.TRUE. This
  1273. * could also be caused by underflow due to scaling.
  1274. *
  1275. * =====================================================================
  1276. *
  1277. * .. Parameters ..
  1278. DOUBLE PRECISION ZERO, ONE
  1279. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  1280. * ..
  1281. * .. Local Scalars ..
  1282. LOGICAL CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTSB,
  1283. $ WANTSE, WANTSN, WANTST, WANTSV, WANTVS
  1284. INTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,
  1285. $ IHI, ILO, INXT, IP, ITAU, IWRK, LIWRK, LWRK,
  1286. $ MAXWRK, MINWRK
  1287. DOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, SMLNUM
  1288. * ..
  1289. * .. Local Arrays ..
  1290. DOUBLE PRECISION DUM( 1 )
  1291. * ..
  1292. * .. External Subroutines ..
  1293. EXTERNAL DCOPY, DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY,
  1294. $ DLASCL, DORGHR, DSWAP, DTRSEN, XERBLA
  1295. * ..
  1296. * .. External Functions ..
  1297. LOGICAL LSAME
  1298. INTEGER ILAENV
  1299. DOUBLE PRECISION DLAMCH, DLANGE
  1300. EXTERNAL LSAME, ILAENV, DLABAD, DLAMCH, DLANGE
  1301. * ..
  1302. * .. Intrinsic Functions ..
  1303. INTRINSIC MAX, SQRT
  1304. * ..
  1305. * .. Executable Statements ..
  1306. *
  1307. * Test the input arguments
  1308. *
  1309. INFO = 0
  1310. WANTVS = LSAME( JOBVS, 'V' )
  1311. WANTST = LSAME( SORT, 'S' )
  1312. WANTSN = LSAME( SENSE, 'N' )
  1313. WANTSE = LSAME( SENSE, 'E' )
  1314. WANTSV = LSAME( SENSE, 'V' )
  1315. WANTSB = LSAME( SENSE, 'B' )
  1316. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  1317. IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
  1318. INFO = -1
  1319. ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
  1320. INFO = -2
  1321. ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
  1322. $ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
  1323. INFO = -4
  1324. ELSE IF( N.LT.0 ) THEN
  1325. INFO = -5
  1326. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  1327. INFO = -7
  1328. ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
  1329. INFO = -12
  1330. END IF
  1331. *
  1332. * Compute workspace
  1333. * (Note: Comments in the code beginning "RWorkspace:" describe the
  1334. * minimal amount of real workspace needed at that point in the
  1335. * code, as well as the preferred amount for good performance.
  1336. * IWorkspace refers to integer workspace.
  1337. * NB refers to the optimal block size for the immediately
  1338. * following subroutine, as returned by ILAENV.
  1339. * HSWORK refers to the workspace preferred by DHSEQR, as
  1340. * calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
  1341. * the worst case.
  1342. * If SENSE = 'E', 'V' or 'B', then the amount of workspace needed
  1343. * depends on SDIM, which is computed by the routine DTRSEN later
  1344. * in the code.)
  1345. *
  1346. IF( INFO.EQ.0 ) THEN
  1347. LIWRK = 1
  1348. IF( N.EQ.0 ) THEN
  1349. MINWRK = 1
  1350. LWRK = 1
  1351. ELSE
  1352. MAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )
  1353. MINWRK = 3*N
  1354. *
  1355. CALL DHSEQR( 'S', JOBVS, N, 1, N, A, LDA, WR, WI, VS, LDVS,
  1356. $ WORK, -1, IEVAL )
  1357. HSWORK = WORK( 1 )
  1358. *
  1359. IF( .NOT.WANTVS ) THEN
  1360. MAXWRK = MAX( MAXWRK, N + HSWORK )
  1361. ELSE
  1362. MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
  1363. $ 'DORGHR', ' ', N, 1, N, -1 ) )
  1364. MAXWRK = MAX( MAXWRK, N + HSWORK )
  1365. END IF
  1366. LWRK = MAXWRK
  1367. IF( .NOT.WANTSN )
  1368. $ LWRK = MAX( LWRK, N + ( N*N )/2 )
  1369. IF( WANTSV .OR. WANTSB )
  1370. $ LIWRK = ( N*N )/4
  1371. END IF
  1372. IWORK( 1 ) = LIWRK
  1373. WORK( 1 ) = LWRK
  1374. *
  1375. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  1376. INFO = -16
  1377. ELSE IF( LIWORK.LT.1 .AND. .NOT.LQUERY ) THEN
  1378. INFO = -18
  1379. END IF
  1380. END IF
  1381. *
  1382. IF( INFO.NE.0 ) THEN
  1383. CALL XERBLA( 'DGEESX', -INFO )
  1384. RETURN
  1385. END IF
  1386. *
  1387. * Quick return if possible
  1388. *
  1389. IF( N.EQ.0 ) THEN
  1390. SDIM = 0
  1391. RETURN
  1392. END IF
  1393. *
  1394. * Get machine constants
  1395. *
  1396. EPS = DLAMCH( 'P' )
  1397. SMLNUM = DLAMCH( 'S' )
  1398. BIGNUM = ONE / SMLNUM
  1399. CALL DLABAD( SMLNUM, BIGNUM )
  1400. SMLNUM = SQRT( SMLNUM ) / EPS
  1401. BIGNUM = ONE / SMLNUM
  1402. *
  1403. * Scale A if max element outside range [SMLNUM,BIGNUM]
  1404. *
  1405. ANRM = DLANGE( 'M', N, N, A, LDA, DUM )
  1406. SCALEA = .FALSE.
  1407. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  1408. SCALEA = .TRUE.
  1409. CSCALE = SMLNUM
  1410. ELSE IF( ANRM.GT.BIGNUM ) THEN
  1411. SCALEA = .TRUE.
  1412. CSCALE = BIGNUM
  1413. END IF
  1414. IF( SCALEA )
  1415. $ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
  1416. *
  1417. * Permute the matrix to make it more nearly triangular
  1418. * (RWorkspace: need N)
  1419. *
  1420. IBAL = 1
  1421. CALL DGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
  1422. *
  1423. * Reduce to upper Hessenberg form
  1424. * (RWorkspace: need 3*N, prefer 2*N+N*NB)
  1425. *
  1426. ITAU = N + IBAL
  1427. IWRK = N + ITAU
  1428. CALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
  1429. $ LWORK-IWRK+1, IERR )
  1430. *
  1431. IF( WANTVS ) THEN
  1432. *
  1433. * Copy Householder vectors to VS
  1434. *
  1435. CALL DLACPY( 'L', N, N, A, LDA, VS, LDVS )
  1436. *
  1437. * Generate orthogonal matrix in VS
  1438. * (RWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
  1439. *
  1440. CALL DORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
  1441. $ LWORK-IWRK+1, IERR )
  1442. END IF
  1443. *
  1444. SDIM = 0
  1445. *
  1446. * Perform QR iteration, accumulating Schur vectors in VS if desired
  1447. * (RWorkspace: need N+1, prefer N+HSWORK (see comments) )
  1448. *
  1449. IWRK = ITAU
  1450. CALL DHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,
  1451. $ WORK( IWRK ), LWORK-IWRK+1, IEVAL )
  1452. IF( IEVAL.GT.0 )
  1453. $ INFO = IEVAL
  1454. *
  1455. * Sort eigenvalues if desired
  1456. *
  1457. IF( WANTST .AND. INFO.EQ.0 ) THEN
  1458. IF( SCALEA ) THEN
  1459. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )
  1460. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )
  1461. END IF
  1462. DO 10 I = 1, N
  1463. BWORK( I ) = SELECT( WR( I ), WI( I ) )
  1464. 10 CONTINUE
  1465. *
  1466. * Reorder eigenvalues, transform Schur vectors, and compute
  1467. * reciprocal condition numbers
  1468. * (RWorkspace: if SENSE is not 'N', need N+2*SDIM*(N-SDIM)
  1469. * otherwise, need N )
  1470. * (IWorkspace: if SENSE is 'V' or 'B', need SDIM*(N-SDIM)
  1471. * otherwise, need 0 )
  1472. *
  1473. CALL DTRSEN( SENSE, JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,
  1474. $ SDIM, RCONDE, RCONDV, WORK( IWRK ), LWORK-IWRK+1,
  1475. $ IWORK, LIWORK, ICOND )
  1476. IF( .NOT.WANTSN )
  1477. $ MAXWRK = MAX( MAXWRK, N+2*SDIM*( N-SDIM ) )
  1478. IF( ICOND.EQ.-15 ) THEN
  1479. *
  1480. * Not enough real workspace
  1481. *
  1482. INFO = -16
  1483. ELSE IF( ICOND.EQ.-17 ) THEN
  1484. *
  1485. * Not enough integer workspace
  1486. *
  1487. INFO = -18
  1488. ELSE IF( ICOND.GT.0 ) THEN
  1489. *
  1490. * DTRSEN failed to reorder or to restore standard Schur form
  1491. *
  1492. INFO = ICOND + N
  1493. END IF
  1494. END IF
  1495. *
  1496. IF( WANTVS ) THEN
  1497. *
  1498. * Undo balancing
  1499. * (RWorkspace: need N)
  1500. *
  1501. CALL DGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,
  1502. $ IERR )
  1503. END IF
  1504. *
  1505. IF( SCALEA ) THEN
  1506. *
  1507. * Undo scaling for the Schur form of A
  1508. *
  1509. CALL DLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
  1510. CALL DCOPY( N, A, LDA+1, WR, 1 )
  1511. IF( ( WANTSV .OR. WANTSB ) .AND. INFO.EQ.0 ) THEN
  1512. DUM( 1 ) = RCONDV
  1513. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )
  1514. RCONDV = DUM( 1 )
  1515. END IF
  1516. IF( CSCALE.EQ.SMLNUM ) THEN
  1517. *
  1518. * If scaling back towards underflow, adjust WI if an
  1519. * offdiagonal element of a 2-by-2 block in the Schur form
  1520. * underflows.
  1521. *
  1522. IF( IEVAL.GT.0 ) THEN
  1523. I1 = IEVAL + 1
  1524. I2 = IHI - 1
  1525. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
  1526. $ IERR )
  1527. ELSE IF( WANTST ) THEN
  1528. I1 = 1
  1529. I2 = N - 1
  1530. ELSE
  1531. I1 = ILO
  1532. I2 = IHI - 1
  1533. END IF
  1534. INXT = I1 - 1
  1535. DO 20 I = I1, I2
  1536. IF( I.LT.INXT )
  1537. $ GO TO 20
  1538. IF( WI( I ).EQ.ZERO ) THEN
  1539. INXT = I + 1
  1540. ELSE
  1541. IF( A( I+1, I ).EQ.ZERO ) THEN
  1542. WI( I ) = ZERO
  1543. WI( I+1 ) = ZERO
  1544. ELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.
  1545. $ ZERO ) THEN
  1546. WI( I ) = ZERO
  1547. WI( I+1 ) = ZERO
  1548. IF( I.GT.1 )
  1549. $ CALL DSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )
  1550. IF( N.GT.I+1 )
  1551. $ CALL DSWAP( N-I-1, A( I, I+2 ), LDA,
  1552. $ A( I+1, I+2 ), LDA )
  1553. CALL DSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )
  1554. A( I, I+1 ) = A( I+1, I )
  1555. A( I+1, I ) = ZERO
  1556. END IF
  1557. INXT = I + 2
  1558. END IF
  1559. 20 CONTINUE
  1560. END IF
  1561. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,
  1562. $ WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )
  1563. END IF
  1564. *
  1565. IF( WANTST .AND. INFO.EQ.0 ) THEN
  1566. *
  1567. * Check if reordering successful
  1568. *
  1569. LASTSL = .TRUE.
  1570. LST2SL = .TRUE.
  1571. SDIM = 0
  1572. IP = 0
  1573. DO 30 I = 1, N
  1574. CURSL = SELECT( WR( I ), WI( I ) )
  1575. IF( WI( I ).EQ.ZERO ) THEN
  1576. IF( CURSL )
  1577. $ SDIM = SDIM + 1
  1578. IP = 0
  1579. IF( CURSL .AND. .NOT.LASTSL )
  1580. $ INFO = N + 2
  1581. ELSE
  1582. IF( IP.EQ.1 ) THEN
  1583. *
  1584. * Last eigenvalue of conjugate pair
  1585. *
  1586. CURSL = CURSL .OR. LASTSL
  1587. LASTSL = CURSL
  1588. IF( CURSL )
  1589. $ SDIM = SDIM + 2
  1590. IP = -1
  1591. IF( CURSL .AND. .NOT.LST2SL )
  1592. $ INFO = N + 2
  1593. ELSE
  1594. *
  1595. * First eigenvalue of conjugate pair
  1596. *
  1597. IP = 1
  1598. END IF
  1599. END IF
  1600. LST2SL = LASTSL
  1601. LASTSL = CURSL
  1602. 30 CONTINUE
  1603. END IF
  1604. *
  1605. WORK( 1 ) = MAXWRK
  1606. IF( WANTSV .OR. WANTSB ) THEN
  1607. IWORK( 1 ) = MAX( 1, SDIM*( N-SDIM ) )
  1608. ELSE
  1609. IWORK( 1 ) = 1
  1610. END IF
  1611. *
  1612. RETURN
  1613. *
  1614. * End of DGEESX
  1615. *
  1616. END
  1617. SUBROUTINE DGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,
  1618. $ LDVR, WORK, LWORK, INFO )
  1619. *
  1620. * -- LAPACK driver routine (version 3.1) --
  1621. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  1622. * November 2006
  1623. *
  1624. * .. Scalar Arguments ..
  1625. CHARACTER JOBVL, JOBVR
  1626. INTEGER INFO, LDA, LDVL, LDVR, LWORK, N
  1627. * ..
  1628. * .. Array Arguments ..
  1629. DOUBLE PRECISION A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
  1630. $ WI( * ), WORK( * ), WR( * )
  1631. * ..
  1632. *
  1633. * Purpose
  1634. * =======
  1635. *
  1636. * DGEEV computes for an N-by-N real nonsymmetric matrix A, the
  1637. * eigenvalues and, optionally, the left and/or right eigenvectors.
  1638. *
  1639. * The right eigenvector v(j) of A satisfies
  1640. * A * v(j) = lambda(j) * v(j)
  1641. * where lambda(j) is its eigenvalue.
  1642. * The left eigenvector u(j) of A satisfies
  1643. * u(j)**H * A = lambda(j) * u(j)**H
  1644. * where u(j)**H denotes the conjugate transpose of u(j).
  1645. *
  1646. * The computed eigenvectors are normalized to have Euclidean norm
  1647. * equal to 1 and largest component real.
  1648. *
  1649. * Arguments
  1650. * =========
  1651. *
  1652. * JOBVL (input) CHARACTER*1
  1653. * = 'N': left eigenvectors of A are not computed;
  1654. * = 'V': left eigenvectors of A are computed.
  1655. *
  1656. * JOBVR (input) CHARACTER*1
  1657. * = 'N': right eigenvectors of A are not computed;
  1658. * = 'V': right eigenvectors of A are computed.
  1659. *
  1660. * N (input) INTEGER
  1661. * The order of the matrix A. N >= 0.
  1662. *
  1663. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  1664. * On entry, the N-by-N matrix A.
  1665. * On exit, A has been overwritten.
  1666. *
  1667. * LDA (input) INTEGER
  1668. * The leading dimension of the array A. LDA >= max(1,N).
  1669. *
  1670. * WR (output) DOUBLE PRECISION array, dimension (N)
  1671. * WI (output) DOUBLE PRECISION array, dimension (N)
  1672. * WR and WI contain the real and imaginary parts,
  1673. * respectively, of the computed eigenvalues. Complex
  1674. * conjugate pairs of eigenvalues appear consecutively
  1675. * with the eigenvalue having the positive imaginary part
  1676. * first.
  1677. *
  1678. * VL (output) DOUBLE PRECISION array, dimension (LDVL,N)
  1679. * If JOBVL = 'V', the left eigenvectors u(j) are stored one
  1680. * after another in the columns of VL, in the same order
  1681. * as their eigenvalues.
  1682. * If JOBVL = 'N', VL is not referenced.
  1683. * If the j-th eigenvalue is real, then u(j) = VL(:,j),
  1684. * the j-th column of VL.
  1685. * If the j-th and (j+1)-st eigenvalues form a complex
  1686. * conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and
  1687. * u(j+1) = VL(:,j) - i*VL(:,j+1).
  1688. *
  1689. * LDVL (input) INTEGER
  1690. * The leading dimension of the array VL. LDVL >= 1; if
  1691. * JOBVL = 'V', LDVL >= N.
  1692. *
  1693. * VR (output) DOUBLE PRECISION array, dimension (LDVR,N)
  1694. * If JOBVR = 'V', the right eigenvectors v(j) are stored one
  1695. * after another in the columns of VR, in the same order
  1696. * as their eigenvalues.
  1697. * If JOBVR = 'N', VR is not referenced.
  1698. * If the j-th eigenvalue is real, then v(j) = VR(:,j),
  1699. * the j-th column of VR.
  1700. * If the j-th and (j+1)-st eigenvalues form a complex
  1701. * conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and
  1702. * v(j+1) = VR(:,j) - i*VR(:,j+1).
  1703. *
  1704. * LDVR (input) INTEGER
  1705. * The leading dimension of the array VR. LDVR >= 1; if
  1706. * JOBVR = 'V', LDVR >= N.
  1707. *
  1708. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  1709. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  1710. *
  1711. * LWORK (input) INTEGER
  1712. * The dimension of the array WORK. LWORK >= max(1,3*N), and
  1713. * if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N. For good
  1714. * performance, LWORK must generally be larger.
  1715. *
  1716. * If LWORK = -1, then a workspace query is assumed; the routine
  1717. * only calculates the optimal size of the WORK array, returns
  1718. * this value as the first entry of the WORK array, and no error
  1719. * message related to LWORK is issued by XERBLA.
  1720. *
  1721. * INFO (output) INTEGER
  1722. * = 0: successful exit
  1723. * < 0: if INFO = -i, the i-th argument had an illegal value.
  1724. * > 0: if INFO = i, the QR algorithm failed to compute all the
  1725. * eigenvalues, and no eigenvectors have been computed;
  1726. * elements i+1:N of WR and WI contain eigenvalues which
  1727. * have converged.
  1728. *
  1729. * =====================================================================
  1730. *
  1731. * .. Parameters ..
  1732. DOUBLE PRECISION ZERO, ONE
  1733. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  1734. * ..
  1735. * .. Local Scalars ..
  1736. LOGICAL LQUERY, SCALEA, WANTVL, WANTVR
  1737. CHARACTER SIDE
  1738. INTEGER HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,
  1739. $ MAXWRK, MINWRK, NOUT
  1740. DOUBLE PRECISION ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
  1741. $ SN
  1742. * ..
  1743. * .. Local Arrays ..
  1744. LOGICAL SELECT( 1 )
  1745. DOUBLE PRECISION DUM( 1 )
  1746. * ..
  1747. * .. External Subroutines ..
  1748. EXTERNAL DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLABAD, DLACPY,
  1749. $ DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC,
  1750. $ XERBLA
  1751. * ..
  1752. * .. External Functions ..
  1753. LOGICAL LSAME
  1754. INTEGER IDAMAX, ILAENV
  1755. DOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2
  1756. EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DLANGE, DLAPY2,
  1757. $ DNRM2
  1758. * ..
  1759. * .. Intrinsic Functions ..
  1760. INTRINSIC MAX, SQRT
  1761. * ..
  1762. * .. Executable Statements ..
  1763. *
  1764. * Test the input arguments
  1765. *
  1766. INFO = 0
  1767. LQUERY = ( LWORK.EQ.-1 )
  1768. WANTVL = LSAME( JOBVL, 'V' )
  1769. WANTVR = LSAME( JOBVR, 'V' )
  1770. IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
  1771. INFO = -1
  1772. ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
  1773. INFO = -2
  1774. ELSE IF( N.LT.0 ) THEN
  1775. INFO = -3
  1776. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  1777. INFO = -5
  1778. ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
  1779. INFO = -9
  1780. ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
  1781. INFO = -11
  1782. END IF
  1783. *
  1784. * Compute workspace
  1785. * (Note: Comments in the code beginning "Workspace:" describe the
  1786. * minimal amount of workspace needed at that point in the code,
  1787. * as well as the preferred amount for good performance.
  1788. * NB refers to the optimal block size for the immediately
  1789. * following subroutine, as returned by ILAENV.
  1790. * HSWORK refers to the workspace preferred by DHSEQR, as
  1791. * calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
  1792. * the worst case.)
  1793. *
  1794. IF( INFO.EQ.0 ) THEN
  1795. IF( N.EQ.0 ) THEN
  1796. MINWRK = 1
  1797. MAXWRK = 1
  1798. ELSE
  1799. MAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )
  1800. IF( WANTVL ) THEN
  1801. MINWRK = 4*N
  1802. MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
  1803. $ 'DORGHR', ' ', N, 1, N, -1 ) )
  1804. CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
  1805. $ WORK, -1, INFO )
  1806. HSWORK = WORK( 1 )
  1807. MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
  1808. MAXWRK = MAX( MAXWRK, 4*N )
  1809. ELSE IF( WANTVR ) THEN
  1810. MINWRK = 4*N
  1811. MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
  1812. $ 'DORGHR', ' ', N, 1, N, -1 ) )
  1813. CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
  1814. $ WORK, -1, INFO )
  1815. HSWORK = WORK( 1 )
  1816. MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
  1817. MAXWRK = MAX( MAXWRK, 4*N )
  1818. ELSE
  1819. MINWRK = 3*N
  1820. CALL DHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR, LDVR,
  1821. $ WORK, -1, INFO )
  1822. HSWORK = WORK( 1 )
  1823. MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )
  1824. END IF
  1825. MAXWRK = MAX( MAXWRK, MINWRK )
  1826. END IF
  1827. WORK( 1 ) = MAXWRK
  1828. *
  1829. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  1830. INFO = -13
  1831. END IF
  1832. END IF
  1833. *
  1834. IF( INFO.NE.0 ) THEN
  1835. CALL XERBLA( 'DGEEV ', -INFO )
  1836. RETURN
  1837. ELSE IF( LQUERY ) THEN
  1838. RETURN
  1839. END IF
  1840. *
  1841. * Quick return if possible
  1842. *
  1843. IF( N.EQ.0 )
  1844. $ RETURN
  1845. *
  1846. * Get machine constants
  1847. *
  1848. EPS = DLAMCH( 'P' )
  1849. SMLNUM = DLAMCH( 'S' )
  1850. BIGNUM = ONE / SMLNUM
  1851. CALL DLABAD( SMLNUM, BIGNUM )
  1852. SMLNUM = SQRT( SMLNUM ) / EPS
  1853. BIGNUM = ONE / SMLNUM
  1854. *
  1855. * Scale A if max element outside range [SMLNUM,BIGNUM]
  1856. *
  1857. ANRM = DLANGE( 'M', N, N, A, LDA, DUM )
  1858. SCALEA = .FALSE.
  1859. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  1860. SCALEA = .TRUE.
  1861. CSCALE = SMLNUM
  1862. ELSE IF( ANRM.GT.BIGNUM ) THEN
  1863. SCALEA = .TRUE.
  1864. CSCALE = BIGNUM
  1865. END IF
  1866. IF( SCALEA )
  1867. $ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
  1868. *
  1869. * Balance the matrix
  1870. * (Workspace: need N)
  1871. *
  1872. IBAL = 1
  1873. CALL DGEBAL( 'B', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
  1874. *
  1875. * Reduce to upper Hessenberg form
  1876. * (Workspace: need 3*N, prefer 2*N+N*NB)
  1877. *
  1878. ITAU = IBAL + N
  1879. IWRK = ITAU + N
  1880. CALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
  1881. $ LWORK-IWRK+1, IERR )
  1882. *
  1883. IF( WANTVL ) THEN
  1884. *
  1885. * Want left eigenvectors
  1886. * Copy Householder vectors to VL
  1887. *
  1888. SIDE = 'L'
  1889. CALL DLACPY( 'L', N, N, A, LDA, VL, LDVL )
  1890. *
  1891. * Generate orthogonal matrix in VL
  1892. * (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
  1893. *
  1894. CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
  1895. $ LWORK-IWRK+1, IERR )
  1896. *
  1897. * Perform QR iteration, accumulating Schur vectors in VL
  1898. * (Workspace: need N+1, prefer N+HSWORK (see comments) )
  1899. *
  1900. IWRK = ITAU
  1901. CALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,
  1902. $ WORK( IWRK ), LWORK-IWRK+1, INFO )
  1903. *
  1904. IF( WANTVR ) THEN
  1905. *
  1906. * Want left and right eigenvectors
  1907. * Copy Schur vectors to VR
  1908. *
  1909. SIDE = 'B'
  1910. CALL DLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
  1911. END IF
  1912. *
  1913. ELSE IF( WANTVR ) THEN
  1914. *
  1915. * Want right eigenvectors
  1916. * Copy Householder vectors to VR
  1917. *
  1918. SIDE = 'R'
  1919. CALL DLACPY( 'L', N, N, A, LDA, VR, LDVR )
  1920. *
  1921. * Generate orthogonal matrix in VR
  1922. * (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)
  1923. *
  1924. CALL DORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
  1925. $ LWORK-IWRK+1, IERR )
  1926. *
  1927. * Perform QR iteration, accumulating Schur vectors in VR
  1928. * (Workspace: need N+1, prefer N+HSWORK (see comments) )
  1929. *
  1930. IWRK = ITAU
  1931. CALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
  1932. $ WORK( IWRK ), LWORK-IWRK+1, INFO )
  1933. *
  1934. ELSE
  1935. *
  1936. * Compute eigenvalues only
  1937. * (Workspace: need N+1, prefer N+HSWORK (see comments) )
  1938. *
  1939. IWRK = ITAU
  1940. CALL DHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
  1941. $ WORK( IWRK ), LWORK-IWRK+1, INFO )
  1942. END IF
  1943. *
  1944. * If INFO > 0 from DHSEQR, then quit
  1945. *
  1946. IF( INFO.GT.0 )
  1947. $ GO TO 50
  1948. *
  1949. IF( WANTVL .OR. WANTVR ) THEN
  1950. *
  1951. * Compute left and/or right eigenvectors
  1952. * (Workspace: need 4*N)
  1953. *
  1954. CALL DTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
  1955. $ N, NOUT, WORK( IWRK ), IERR )
  1956. END IF
  1957. *
  1958. IF( WANTVL ) THEN
  1959. *
  1960. * Undo balancing of left eigenvectors
  1961. * (Workspace: need N)
  1962. *
  1963. CALL DGEBAK( 'B', 'L', N, ILO, IHI, WORK( IBAL ), N, VL, LDVL,
  1964. $ IERR )
  1965. *
  1966. * Normalize left eigenvectors and make largest component real
  1967. *
  1968. DO 20 I = 1, N
  1969. IF( WI( I ).EQ.ZERO ) THEN
  1970. SCL = ONE / DNRM2( N, VL( 1, I ), 1 )
  1971. CALL DSCAL( N, SCL, VL( 1, I ), 1 )
  1972. ELSE IF( WI( I ).GT.ZERO ) THEN
  1973. SCL = ONE / DLAPY2( DNRM2( N, VL( 1, I ), 1 ),
  1974. $ DNRM2( N, VL( 1, I+1 ), 1 ) )
  1975. CALL DSCAL( N, SCL, VL( 1, I ), 1 )
  1976. CALL DSCAL( N, SCL, VL( 1, I+1 ), 1 )
  1977. DO 10 K = 1, N
  1978. WORK( IWRK+K-1 ) = VL( K, I )**2 + VL( K, I+1 )**2
  1979. 10 CONTINUE
  1980. K = IDAMAX( N, WORK( IWRK ), 1 )
  1981. CALL DLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )
  1982. CALL DROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )
  1983. VL( K, I+1 ) = ZERO
  1984. END IF
  1985. 20 CONTINUE
  1986. END IF
  1987. *
  1988. IF( WANTVR ) THEN
  1989. *
  1990. * Undo balancing of right eigenvectors
  1991. * (Workspace: need N)
  1992. *
  1993. CALL DGEBAK( 'B', 'R', N, ILO, IHI, WORK( IBAL ), N, VR, LDVR,
  1994. $ IERR )
  1995. *
  1996. * Normalize right eigenvectors and make largest component real
  1997. *
  1998. DO 40 I = 1, N
  1999. IF( WI( I ).EQ.ZERO ) THEN
  2000. SCL = ONE / DNRM2( N, VR( 1, I ), 1 )
  2001. CALL DSCAL( N, SCL, VR( 1, I ), 1 )
  2002. ELSE IF( WI( I ).GT.ZERO ) THEN
  2003. SCL = ONE / DLAPY2( DNRM2( N, VR( 1, I ), 1 ),
  2004. $ DNRM2( N, VR( 1, I+1 ), 1 ) )
  2005. CALL DSCAL( N, SCL, VR( 1, I ), 1 )
  2006. CALL DSCAL( N, SCL, VR( 1, I+1 ), 1 )
  2007. DO 30 K = 1, N
  2008. WORK( IWRK+K-1 ) = VR( K, I )**2 + VR( K, I+1 )**2
  2009. 30 CONTINUE
  2010. K = IDAMAX( N, WORK( IWRK ), 1 )
  2011. CALL DLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )
  2012. CALL DROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )
  2013. VR( K, I+1 ) = ZERO
  2014. END IF
  2015. 40 CONTINUE
  2016. END IF
  2017. *
  2018. * Undo scaling if necessary
  2019. *
  2020. 50 CONTINUE
  2021. IF( SCALEA ) THEN
  2022. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),
  2023. $ MAX( N-INFO, 1 ), IERR )
  2024. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),
  2025. $ MAX( N-INFO, 1 ), IERR )
  2026. IF( INFO.GT.0 ) THEN
  2027. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,
  2028. $ IERR )
  2029. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
  2030. $ IERR )
  2031. END IF
  2032. END IF
  2033. *
  2034. WORK( 1 ) = MAXWRK
  2035. RETURN
  2036. *
  2037. * End of DGEEV
  2038. *
  2039. END
  2040. SUBROUTINE DGEEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR, WI,
  2041. $ VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM,
  2042. $ RCONDE, RCONDV, WORK, LWORK, IWORK, INFO )
  2043. *
  2044. * -- LAPACK driver routine (version 3.1) --
  2045. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  2046. * November 2006
  2047. *
  2048. * .. Scalar Arguments ..
  2049. CHARACTER BALANC, JOBVL, JOBVR, SENSE
  2050. INTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N
  2051. DOUBLE PRECISION ABNRM
  2052. * ..
  2053. * .. Array Arguments ..
  2054. INTEGER IWORK( * )
  2055. DOUBLE PRECISION A( LDA, * ), RCONDE( * ), RCONDV( * ),
  2056. $ SCALE( * ), VL( LDVL, * ), VR( LDVR, * ),
  2057. $ WI( * ), WORK( * ), WR( * )
  2058. * ..
  2059. *
  2060. * Purpose
  2061. * =======
  2062. *
  2063. * DGEEVX computes for an N-by-N real nonsymmetric matrix A, the
  2064. * eigenvalues and, optionally, the left and/or right eigenvectors.
  2065. *
  2066. * Optionally also, it computes a balancing transformation to improve
  2067. * the conditioning of the eigenvalues and eigenvectors (ILO, IHI,
  2068. * SCALE, and ABNRM), reciprocal condition numbers for the eigenvalues
  2069. * (RCONDE), and reciprocal condition numbers for the right
  2070. * eigenvectors (RCONDV).
  2071. *
  2072. * The right eigenvector v(j) of A satisfies
  2073. * A * v(j) = lambda(j) * v(j)
  2074. * where lambda(j) is its eigenvalue.
  2075. * The left eigenvector u(j) of A satisfies
  2076. * u(j)**H * A = lambda(j) * u(j)**H
  2077. * where u(j)**H denotes the conjugate transpose of u(j).
  2078. *
  2079. * The computed eigenvectors are normalized to have Euclidean norm
  2080. * equal to 1 and largest component real.
  2081. *
  2082. * Balancing a matrix means permuting the rows and columns to make it
  2083. * more nearly upper triangular, and applying a diagonal similarity
  2084. * transformation D * A * D**(-1), where D is a diagonal matrix, to
  2085. * make its rows and columns closer in norm and the condition numbers
  2086. * of its eigenvalues and eigenvectors smaller. The computed
  2087. * reciprocal condition numbers correspond to the balanced matrix.
  2088. * Permuting rows and columns will not change the condition numbers
  2089. * (in exact arithmetic) but diagonal scaling will. For further
  2090. * explanation of balancing, see section 4.10.2 of the LAPACK
  2091. * Users' Guide.
  2092. *
  2093. * Arguments
  2094. * =========
  2095. *
  2096. * BALANC (input) CHARACTER*1
  2097. * Indicates how the input matrix should be diagonally scaled
  2098. * and/or permuted to improve the conditioning of its
  2099. * eigenvalues.
  2100. * = 'N': Do not diagonally scale or permute;
  2101. * = 'P': Perform permutations to make the matrix more nearly
  2102. * upper triangular. Do not diagonally scale;
  2103. * = 'S': Diagonally scale the matrix, i.e. replace A by
  2104. * D*A*D**(-1), where D is a diagonal matrix chosen
  2105. * to make the rows and columns of A more equal in
  2106. * norm. Do not permute;
  2107. * = 'B': Both diagonally scale and permute A.
  2108. *
  2109. * Computed reciprocal condition numbers will be for the matrix
  2110. * after balancing and/or permuting. Permuting does not change
  2111. * condition numbers (in exact arithmetic), but balancing does.
  2112. *
  2113. * JOBVL (input) CHARACTER*1
  2114. * = 'N': left eigenvectors of A are not computed;
  2115. * = 'V': left eigenvectors of A are computed.
  2116. * If SENSE = 'E' or 'B', JOBVL must = 'V'.
  2117. *
  2118. * JOBVR (input) CHARACTER*1
  2119. * = 'N': right eigenvectors of A are not computed;
  2120. * = 'V': right eigenvectors of A are computed.
  2121. * If SENSE = 'E' or 'B', JOBVR must = 'V'.
  2122. *
  2123. * SENSE (input) CHARACTER*1
  2124. * Determines which reciprocal condition numbers are computed.
  2125. * = 'N': None are computed;
  2126. * = 'E': Computed for eigenvalues only;
  2127. * = 'V': Computed for right eigenvectors only;
  2128. * = 'B': Computed for eigenvalues and right eigenvectors.
  2129. *
  2130. * If SENSE = 'E' or 'B', both left and right eigenvectors
  2131. * must also be computed (JOBVL = 'V' and JOBVR = 'V').
  2132. *
  2133. * N (input) INTEGER
  2134. * The order of the matrix A. N >= 0.
  2135. *
  2136. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  2137. * On entry, the N-by-N matrix A.
  2138. * On exit, A has been overwritten. If JOBVL = 'V' or
  2139. * JOBVR = 'V', A contains the real Schur form of the balanced
  2140. * version of the input matrix A.
  2141. *
  2142. * LDA (input) INTEGER
  2143. * The leading dimension of the array A. LDA >= max(1,N).
  2144. *
  2145. * WR (output) DOUBLE PRECISION array, dimension (N)
  2146. * WI (output) DOUBLE PRECISION array, dimension (N)
  2147. * WR and WI contain the real and imaginary parts,
  2148. * respectively, of the computed eigenvalues. Complex
  2149. * conjugate pairs of eigenvalues will appear consecutively
  2150. * with the eigenvalue having the positive imaginary part
  2151. * first.
  2152. *
  2153. * VL (output) DOUBLE PRECISION array, dimension (LDVL,N)
  2154. * If JOBVL = 'V', the left eigenvectors u(j) are stored one
  2155. * after another in the columns of VL, in the same order
  2156. * as their eigenvalues.
  2157. * If JOBVL = 'N', VL is not referenced.
  2158. * If the j-th eigenvalue is real, then u(j) = VL(:,j),
  2159. * the j-th column of VL.
  2160. * If the j-th and (j+1)-st eigenvalues form a complex
  2161. * conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and
  2162. * u(j+1) = VL(:,j) - i*VL(:,j+1).
  2163. *
  2164. * LDVL (input) INTEGER
  2165. * The leading dimension of the array VL. LDVL >= 1; if
  2166. * JOBVL = 'V', LDVL >= N.
  2167. *
  2168. * VR (output) DOUBLE PRECISION array, dimension (LDVR,N)
  2169. * If JOBVR = 'V', the right eigenvectors v(j) are stored one
  2170. * after another in the columns of VR, in the same order
  2171. * as their eigenvalues.
  2172. * If JOBVR = 'N', VR is not referenced.
  2173. * If the j-th eigenvalue is real, then v(j) = VR(:,j),
  2174. * the j-th column of VR.
  2175. * If the j-th and (j+1)-st eigenvalues form a complex
  2176. * conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and
  2177. * v(j+1) = VR(:,j) - i*VR(:,j+1).
  2178. *
  2179. * LDVR (input) INTEGER
  2180. * The leading dimension of the array VR. LDVR >= 1, and if
  2181. * JOBVR = 'V', LDVR >= N.
  2182. *
  2183. * ILO (output) INTEGER
  2184. * IHI (output) INTEGER
  2185. * ILO and IHI are integer values determined when A was
  2186. * balanced. The balanced A(i,j) = 0 if I > J and
  2187. * J = 1,...,ILO-1 or I = IHI+1,...,N.
  2188. *
  2189. * SCALE (output) DOUBLE PRECISION array, dimension (N)
  2190. * Details of the permutations and scaling factors applied
  2191. * when balancing A. If P(j) is the index of the row and column
  2192. * interchanged with row and column j, and D(j) is the scaling
  2193. * factor applied to row and column j, then
  2194. * SCALE(J) = P(J), for J = 1,...,ILO-1
  2195. * = D(J), for J = ILO,...,IHI
  2196. * = P(J) for J = IHI+1,...,N.
  2197. * The order in which the interchanges are made is N to IHI+1,
  2198. * then 1 to ILO-1.
  2199. *
  2200. * ABNRM (output) DOUBLE PRECISION
  2201. * The one-norm of the balanced matrix (the maximum
  2202. * of the sum of absolute values of elements of any column).
  2203. *
  2204. * RCONDE (output) DOUBLE PRECISION array, dimension (N)
  2205. * RCONDE(j) is the reciprocal condition number of the j-th
  2206. * eigenvalue.
  2207. *
  2208. * RCONDV (output) DOUBLE PRECISION array, dimension (N)
  2209. * RCONDV(j) is the reciprocal condition number of the j-th
  2210. * right eigenvector.
  2211. *
  2212. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  2213. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  2214. *
  2215. * LWORK (input) INTEGER
  2216. * The dimension of the array WORK. If SENSE = 'N' or 'E',
  2217. * LWORK >= max(1,2*N), and if JOBVL = 'V' or JOBVR = 'V',
  2218. * LWORK >= 3*N. If SENSE = 'V' or 'B', LWORK >= N*(N+6).
  2219. * For good performance, LWORK must generally be larger.
  2220. *
  2221. * If LWORK = -1, then a workspace query is assumed; the routine
  2222. * only calculates the optimal size of the WORK array, returns
  2223. * this value as the first entry of the WORK array, and no error
  2224. * message related to LWORK is issued by XERBLA.
  2225. *
  2226. * IWORK (workspace) INTEGER array, dimension (2*N-2)
  2227. * If SENSE = 'N' or 'E', not referenced.
  2228. *
  2229. * INFO (output) INTEGER
  2230. * = 0: successful exit
  2231. * < 0: if INFO = -i, the i-th argument had an illegal value.
  2232. * > 0: if INFO = i, the QR algorithm failed to compute all the
  2233. * eigenvalues, and no eigenvectors or condition numbers
  2234. * have been computed; elements 1:ILO-1 and i+1:N of WR
  2235. * and WI contain eigenvalues which have converged.
  2236. *
  2237. * =====================================================================
  2238. *
  2239. * .. Parameters ..
  2240. DOUBLE PRECISION ZERO, ONE
  2241. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  2242. * ..
  2243. * .. Local Scalars ..
  2244. LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,
  2245. $ WNTSNN, WNTSNV
  2246. CHARACTER JOB, SIDE
  2247. INTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K, MAXWRK,
  2248. $ MINWRK, NOUT
  2249. DOUBLE PRECISION ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
  2250. $ SN
  2251. * ..
  2252. * .. Local Arrays ..
  2253. LOGICAL SELECT( 1 )
  2254. DOUBLE PRECISION DUM( 1 )
  2255. * ..
  2256. * .. External Subroutines ..
  2257. EXTERNAL DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLABAD, DLACPY,
  2258. $ DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC,
  2259. $ DTRSNA, XERBLA
  2260. * ..
  2261. * .. External Functions ..
  2262. LOGICAL LSAME
  2263. INTEGER IDAMAX, ILAENV
  2264. DOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2
  2265. EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DLANGE, DLAPY2,
  2266. $ DNRM2
  2267. * ..
  2268. * .. Intrinsic Functions ..
  2269. INTRINSIC MAX, SQRT
  2270. * ..
  2271. * .. Executable Statements ..
  2272. *
  2273. * Test the input arguments
  2274. *
  2275. INFO = 0
  2276. LQUERY = ( LWORK.EQ.-1 )
  2277. WANTVL = LSAME( JOBVL, 'V' )
  2278. WANTVR = LSAME( JOBVR, 'V' )
  2279. WNTSNN = LSAME( SENSE, 'N' )
  2280. WNTSNE = LSAME( SENSE, 'E' )
  2281. WNTSNV = LSAME( SENSE, 'V' )
  2282. WNTSNB = LSAME( SENSE, 'B' )
  2283. IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC,
  2284. $ 'S' ) .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) )
  2285. $ THEN
  2286. INFO = -1
  2287. ELSE IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN
  2288. INFO = -2
  2289. ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN
  2290. INFO = -3
  2291. ELSE IF( .NOT.( WNTSNN .OR. WNTSNE .OR. WNTSNB .OR. WNTSNV ) .OR.
  2292. $ ( ( WNTSNE .OR. WNTSNB ) .AND. .NOT.( WANTVL .AND.
  2293. $ WANTVR ) ) ) THEN
  2294. INFO = -4
  2295. ELSE IF( N.LT.0 ) THEN
  2296. INFO = -5
  2297. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  2298. INFO = -7
  2299. ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN
  2300. INFO = -11
  2301. ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN
  2302. INFO = -13
  2303. END IF
  2304. *
  2305. * Compute workspace
  2306. * (Note: Comments in the code beginning "Workspace:" describe the
  2307. * minimal amount of workspace needed at that point in the code,
  2308. * as well as the preferred amount for good performance.
  2309. * NB refers to the optimal block size for the immediately
  2310. * following subroutine, as returned by ILAENV.
  2311. * HSWORK refers to the workspace preferred by DHSEQR, as
  2312. * calculated below. HSWORK is computed assuming ILO=1 and IHI=N,
  2313. * the worst case.)
  2314. *
  2315. IF( INFO.EQ.0 ) THEN
  2316. IF( N.EQ.0 ) THEN
  2317. MINWRK = 1
  2318. MAXWRK = 1
  2319. ELSE
  2320. MAXWRK = N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )
  2321. *
  2322. IF( WANTVL ) THEN
  2323. CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,
  2324. $ WORK, -1, INFO )
  2325. ELSE IF( WANTVR ) THEN
  2326. CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,
  2327. $ WORK, -1, INFO )
  2328. ELSE
  2329. IF( WNTSNN ) THEN
  2330. CALL DHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR,
  2331. $ LDVR, WORK, -1, INFO )
  2332. ELSE
  2333. CALL DHSEQR( 'S', 'N', N, 1, N, A, LDA, WR, WI, VR,
  2334. $ LDVR, WORK, -1, INFO )
  2335. END IF
  2336. END IF
  2337. HSWORK = WORK( 1 )
  2338. *
  2339. IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THEN
  2340. MINWRK = 2*N
  2341. IF( .NOT.WNTSNN )
  2342. $ MINWRK = MAX( MINWRK, N*N+6*N )
  2343. MAXWRK = MAX( MAXWRK, HSWORK )
  2344. IF( .NOT.WNTSNN )
  2345. $ MAXWRK = MAX( MAXWRK, N*N + 6*N )
  2346. ELSE
  2347. MINWRK = 3*N
  2348. IF( ( .NOT.WNTSNN ) .AND. ( .NOT.WNTSNE ) )
  2349. $ MINWRK = MAX( MINWRK, N*N + 6*N )
  2350. MAXWRK = MAX( MAXWRK, HSWORK )
  2351. MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'DORGHR',
  2352. $ ' ', N, 1, N, -1 ) )
  2353. IF( ( .NOT.WNTSNN ) .AND. ( .NOT.WNTSNE ) )
  2354. $ MAXWRK = MAX( MAXWRK, N*N + 6*N )
  2355. MAXWRK = MAX( MAXWRK, 3*N )
  2356. END IF
  2357. MAXWRK = MAX( MAXWRK, MINWRK )
  2358. END IF
  2359. WORK( 1 ) = MAXWRK
  2360. *
  2361. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  2362. INFO = -21
  2363. END IF
  2364. END IF
  2365. *
  2366. IF( INFO.NE.0 ) THEN
  2367. CALL XERBLA( 'DGEEVX', -INFO )
  2368. RETURN
  2369. ELSE IF( LQUERY ) THEN
  2370. RETURN
  2371. END IF
  2372. *
  2373. * Quick return if possible
  2374. *
  2375. IF( N.EQ.0 )
  2376. $ RETURN
  2377. *
  2378. * Get machine constants
  2379. *
  2380. EPS = DLAMCH( 'P' )
  2381. SMLNUM = DLAMCH( 'S' )
  2382. BIGNUM = ONE / SMLNUM
  2383. CALL DLABAD( SMLNUM, BIGNUM )
  2384. SMLNUM = SQRT( SMLNUM ) / EPS
  2385. BIGNUM = ONE / SMLNUM
  2386. *
  2387. * Scale A if max element outside range [SMLNUM,BIGNUM]
  2388. *
  2389. ICOND = 0
  2390. ANRM = DLANGE( 'M', N, N, A, LDA, DUM )
  2391. SCALEA = .FALSE.
  2392. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  2393. SCALEA = .TRUE.
  2394. CSCALE = SMLNUM
  2395. ELSE IF( ANRM.GT.BIGNUM ) THEN
  2396. SCALEA = .TRUE.
  2397. CSCALE = BIGNUM
  2398. END IF
  2399. IF( SCALEA )
  2400. $ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
  2401. *
  2402. * Balance the matrix and compute ABNRM
  2403. *
  2404. CALL DGEBAL( BALANC, N, A, LDA, ILO, IHI, SCALE, IERR )
  2405. ABNRM = DLANGE( '1', N, N, A, LDA, DUM )
  2406. IF( SCALEA ) THEN
  2407. DUM( 1 ) = ABNRM
  2408. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )
  2409. ABNRM = DUM( 1 )
  2410. END IF
  2411. *
  2412. * Reduce to upper Hessenberg form
  2413. * (Workspace: need 2*N, prefer N+N*NB)
  2414. *
  2415. ITAU = 1
  2416. IWRK = ITAU + N
  2417. CALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
  2418. $ LWORK-IWRK+1, IERR )
  2419. *
  2420. IF( WANTVL ) THEN
  2421. *
  2422. * Want left eigenvectors
  2423. * Copy Householder vectors to VL
  2424. *
  2425. SIDE = 'L'
  2426. CALL DLACPY( 'L', N, N, A, LDA, VL, LDVL )
  2427. *
  2428. * Generate orthogonal matrix in VL
  2429. * (Workspace: need 2*N-1, prefer N+(N-1)*NB)
  2430. *
  2431. CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),
  2432. $ LWORK-IWRK+1, IERR )
  2433. *
  2434. * Perform QR iteration, accumulating Schur vectors in VL
  2435. * (Workspace: need 1, prefer HSWORK (see comments) )
  2436. *
  2437. IWRK = ITAU
  2438. CALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,
  2439. $ WORK( IWRK ), LWORK-IWRK+1, INFO )
  2440. *
  2441. IF( WANTVR ) THEN
  2442. *
  2443. * Want left and right eigenvectors
  2444. * Copy Schur vectors to VR
  2445. *
  2446. SIDE = 'B'
  2447. CALL DLACPY( 'F', N, N, VL, LDVL, VR, LDVR )
  2448. END IF
  2449. *
  2450. ELSE IF( WANTVR ) THEN
  2451. *
  2452. * Want right eigenvectors
  2453. * Copy Householder vectors to VR
  2454. *
  2455. SIDE = 'R'
  2456. CALL DLACPY( 'L', N, N, A, LDA, VR, LDVR )
  2457. *
  2458. * Generate orthogonal matrix in VR
  2459. * (Workspace: need 2*N-1, prefer N+(N-1)*NB)
  2460. *
  2461. CALL DORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),
  2462. $ LWORK-IWRK+1, IERR )
  2463. *
  2464. * Perform QR iteration, accumulating Schur vectors in VR
  2465. * (Workspace: need 1, prefer HSWORK (see comments) )
  2466. *
  2467. IWRK = ITAU
  2468. CALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
  2469. $ WORK( IWRK ), LWORK-IWRK+1, INFO )
  2470. *
  2471. ELSE
  2472. *
  2473. * Compute eigenvalues only
  2474. * If condition numbers desired, compute Schur form
  2475. *
  2476. IF( WNTSNN ) THEN
  2477. JOB = 'E'
  2478. ELSE
  2479. JOB = 'S'
  2480. END IF
  2481. *
  2482. * (Workspace: need 1, prefer HSWORK (see comments) )
  2483. *
  2484. IWRK = ITAU
  2485. CALL DHSEQR( JOB, 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,
  2486. $ WORK( IWRK ), LWORK-IWRK+1, INFO )
  2487. END IF
  2488. *
  2489. * If INFO > 0 from DHSEQR, then quit
  2490. *
  2491. IF( INFO.GT.0 )
  2492. $ GO TO 50
  2493. *
  2494. IF( WANTVL .OR. WANTVR ) THEN
  2495. *
  2496. * Compute left and/or right eigenvectors
  2497. * (Workspace: need 3*N)
  2498. *
  2499. CALL DTREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
  2500. $ N, NOUT, WORK( IWRK ), IERR )
  2501. END IF
  2502. *
  2503. * Compute condition numbers if desired
  2504. * (Workspace: need N*N+6*N unless SENSE = 'E')
  2505. *
  2506. IF( .NOT.WNTSNN ) THEN
  2507. CALL DTRSNA( SENSE, 'A', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,
  2508. $ RCONDE, RCONDV, N, NOUT, WORK( IWRK ), N, IWORK,
  2509. $ ICOND )
  2510. END IF
  2511. *
  2512. IF( WANTVL ) THEN
  2513. *
  2514. * Undo balancing of left eigenvectors
  2515. *
  2516. CALL DGEBAK( BALANC, 'L', N, ILO, IHI, SCALE, N, VL, LDVL,
  2517. $ IERR )
  2518. *
  2519. * Normalize left eigenvectors and make largest component real
  2520. *
  2521. DO 20 I = 1, N
  2522. IF( WI( I ).EQ.ZERO ) THEN
  2523. SCL = ONE / DNRM2( N, VL( 1, I ), 1 )
  2524. CALL DSCAL( N, SCL, VL( 1, I ), 1 )
  2525. ELSE IF( WI( I ).GT.ZERO ) THEN
  2526. SCL = ONE / DLAPY2( DNRM2( N, VL( 1, I ), 1 ),
  2527. $ DNRM2( N, VL( 1, I+1 ), 1 ) )
  2528. CALL DSCAL( N, SCL, VL( 1, I ), 1 )
  2529. CALL DSCAL( N, SCL, VL( 1, I+1 ), 1 )
  2530. DO 10 K = 1, N
  2531. WORK( K ) = VL( K, I )**2 + VL( K, I+1 )**2
  2532. 10 CONTINUE
  2533. K = IDAMAX( N, WORK, 1 )
  2534. CALL DLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )
  2535. CALL DROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )
  2536. VL( K, I+1 ) = ZERO
  2537. END IF
  2538. 20 CONTINUE
  2539. END IF
  2540. *
  2541. IF( WANTVR ) THEN
  2542. *
  2543. * Undo balancing of right eigenvectors
  2544. *
  2545. CALL DGEBAK( BALANC, 'R', N, ILO, IHI, SCALE, N, VR, LDVR,
  2546. $ IERR )
  2547. *
  2548. * Normalize right eigenvectors and make largest component real
  2549. *
  2550. DO 40 I = 1, N
  2551. IF( WI( I ).EQ.ZERO ) THEN
  2552. SCL = ONE / DNRM2( N, VR( 1, I ), 1 )
  2553. CALL DSCAL( N, SCL, VR( 1, I ), 1 )
  2554. ELSE IF( WI( I ).GT.ZERO ) THEN
  2555. SCL = ONE / DLAPY2( DNRM2( N, VR( 1, I ), 1 ),
  2556. $ DNRM2( N, VR( 1, I+1 ), 1 ) )
  2557. CALL DSCAL( N, SCL, VR( 1, I ), 1 )
  2558. CALL DSCAL( N, SCL, VR( 1, I+1 ), 1 )
  2559. DO 30 K = 1, N
  2560. WORK( K ) = VR( K, I )**2 + VR( K, I+1 )**2
  2561. 30 CONTINUE
  2562. K = IDAMAX( N, WORK, 1 )
  2563. CALL DLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )
  2564. CALL DROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )
  2565. VR( K, I+1 ) = ZERO
  2566. END IF
  2567. 40 CONTINUE
  2568. END IF
  2569. *
  2570. * Undo scaling if necessary
  2571. *
  2572. 50 CONTINUE
  2573. IF( SCALEA ) THEN
  2574. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),
  2575. $ MAX( N-INFO, 1 ), IERR )
  2576. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),
  2577. $ MAX( N-INFO, 1 ), IERR )
  2578. IF( INFO.EQ.0 ) THEN
  2579. IF( ( WNTSNV .OR. WNTSNB ) .AND. ICOND.EQ.0 )
  2580. $ CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, RCONDV, N,
  2581. $ IERR )
  2582. ELSE
  2583. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,
  2584. $ IERR )
  2585. CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,
  2586. $ IERR )
  2587. END IF
  2588. END IF
  2589. *
  2590. WORK( 1 ) = MAXWRK
  2591. RETURN
  2592. *
  2593. * End of DGEEVX
  2594. *
  2595. END
  2596. SUBROUTINE DGEGS( JOBVSL, JOBVSR, N, A, LDA, B, LDB, ALPHAR,
  2597. $ ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, WORK,
  2598. $ LWORK, INFO )
  2599. *
  2600. * -- LAPACK driver routine (version 3.1) --
  2601. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  2602. * November 2006
  2603. *
  2604. * .. Scalar Arguments ..
  2605. CHARACTER JOBVSL, JOBVSR
  2606. INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N
  2607. * ..
  2608. * .. Array Arguments ..
  2609. DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
  2610. $ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),
  2611. $ VSR( LDVSR, * ), WORK( * )
  2612. * ..
  2613. *
  2614. * Purpose
  2615. * =======
  2616. *
  2617. * This routine is deprecated and has been replaced by routine DGGES.
  2618. *
  2619. * DGEGS computes the eigenvalues, real Schur form, and, optionally,
  2620. * left and or/right Schur vectors of a real matrix pair (A,B).
  2621. * Given two square matrices A and B, the generalized real Schur
  2622. * factorization has the form
  2623. *
  2624. * A = Q*S*Z**T, B = Q*T*Z**T
  2625. *
  2626. * where Q and Z are orthogonal matrices, T is upper triangular, and S
  2627. * is an upper quasi-triangular matrix with 1-by-1 and 2-by-2 diagonal
  2628. * blocks, the 2-by-2 blocks corresponding to complex conjugate pairs
  2629. * of eigenvalues of (A,B). The columns of Q are the left Schur vectors
  2630. * and the columns of Z are the right Schur vectors.
  2631. *
  2632. * If only the eigenvalues of (A,B) are needed, the driver routine
  2633. * DGEGV should be used instead. See DGEGV for a description of the
  2634. * eigenvalues of the generalized nonsymmetric eigenvalue problem
  2635. * (GNEP).
  2636. *
  2637. * Arguments
  2638. * =========
  2639. *
  2640. * JOBVSL (input) CHARACTER*1
  2641. * = 'N': do not compute the left Schur vectors;
  2642. * = 'V': compute the left Schur vectors (returned in VSL).
  2643. *
  2644. * JOBVSR (input) CHARACTER*1
  2645. * = 'N': do not compute the right Schur vectors;
  2646. * = 'V': compute the right Schur vectors (returned in VSR).
  2647. *
  2648. * N (input) INTEGER
  2649. * The order of the matrices A, B, VSL, and VSR. N >= 0.
  2650. *
  2651. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  2652. * On entry, the matrix A.
  2653. * On exit, the upper quasi-triangular matrix S from the
  2654. * generalized real Schur factorization.
  2655. *
  2656. * LDA (input) INTEGER
  2657. * The leading dimension of A. LDA >= max(1,N).
  2658. *
  2659. * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
  2660. * On entry, the matrix B.
  2661. * On exit, the upper triangular matrix T from the generalized
  2662. * real Schur factorization.
  2663. *
  2664. * LDB (input) INTEGER
  2665. * The leading dimension of B. LDB >= max(1,N).
  2666. *
  2667. * ALPHAR (output) DOUBLE PRECISION array, dimension (N)
  2668. * The real parts of each scalar alpha defining an eigenvalue
  2669. * of GNEP.
  2670. *
  2671. * ALPHAI (output) DOUBLE PRECISION array, dimension (N)
  2672. * The imaginary parts of each scalar alpha defining an
  2673. * eigenvalue of GNEP. If ALPHAI(j) is zero, then the j-th
  2674. * eigenvalue is real; if positive, then the j-th and (j+1)-st
  2675. * eigenvalues are a complex conjugate pair, with
  2676. * ALPHAI(j+1) = -ALPHAI(j).
  2677. *
  2678. * BETA (output) DOUBLE PRECISION array, dimension (N)
  2679. * The scalars beta that define the eigenvalues of GNEP.
  2680. * Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and
  2681. * beta = BETA(j) represent the j-th eigenvalue of the matrix
  2682. * pair (A,B), in one of the forms lambda = alpha/beta or
  2683. * mu = beta/alpha. Since either lambda or mu may overflow,
  2684. * they should not, in general, be computed.
  2685. *
  2686. * VSL (output) DOUBLE PRECISION array, dimension (LDVSL,N)
  2687. * If JOBVSL = 'V', the matrix of left Schur vectors Q.
  2688. * Not referenced if JOBVSL = 'N'.
  2689. *
  2690. * LDVSL (input) INTEGER
  2691. * The leading dimension of the matrix VSL. LDVSL >=1, and
  2692. * if JOBVSL = 'V', LDVSL >= N.
  2693. *
  2694. * VSR (output) DOUBLE PRECISION array, dimension (LDVSR,N)
  2695. * If JOBVSR = 'V', the matrix of right Schur vectors Z.
  2696. * Not referenced if JOBVSR = 'N'.
  2697. *
  2698. * LDVSR (input) INTEGER
  2699. * The leading dimension of the matrix VSR. LDVSR >= 1, and
  2700. * if JOBVSR = 'V', LDVSR >= N.
  2701. *
  2702. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  2703. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  2704. *
  2705. * LWORK (input) INTEGER
  2706. * The dimension of the array WORK. LWORK >= max(1,4*N).
  2707. * For good performance, LWORK must generally be larger.
  2708. * To compute the optimal value of LWORK, call ILAENV to get
  2709. * blocksizes (for DGEQRF, DORMQR, and DORGQR.) Then compute:
  2710. * NB -- MAX of the blocksizes for DGEQRF, DORMQR, and DORGQR
  2711. * The optimal LWORK is 2*N + N*(NB+1).
  2712. *
  2713. * If LWORK = -1, then a workspace query is assumed; the routine
  2714. * only calculates the optimal size of the WORK array, returns
  2715. * this value as the first entry of the WORK array, and no error
  2716. * message related to LWORK is issued by XERBLA.
  2717. *
  2718. * INFO (output) INTEGER
  2719. * = 0: successful exit
  2720. * < 0: if INFO = -i, the i-th argument had an illegal value.
  2721. * = 1,...,N:
  2722. * The QZ iteration failed. (A,B) are not in Schur
  2723. * form, but ALPHAR(j), ALPHAI(j), and BETA(j) should
  2724. * be correct for j=INFO+1,...,N.
  2725. * > N: errors that usually indicate LAPACK problems:
  2726. * =N+1: error return from DGGBAL
  2727. * =N+2: error return from DGEQRF
  2728. * =N+3: error return from DORMQR
  2729. * =N+4: error return from DORGQR
  2730. * =N+5: error return from DGGHRD
  2731. * =N+6: error return from DHGEQZ (other than failed
  2732. * iteration)
  2733. * =N+7: error return from DGGBAK (computing VSL)
  2734. * =N+8: error return from DGGBAK (computing VSR)
  2735. * =N+9: error return from DLASCL (various places)
  2736. *
  2737. * =====================================================================
  2738. *
  2739. * .. Parameters ..
  2740. DOUBLE PRECISION ZERO, ONE
  2741. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  2742. * ..
  2743. * .. Local Scalars ..
  2744. LOGICAL ILASCL, ILBSCL, ILVSL, ILVSR, LQUERY
  2745. INTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,
  2746. $ IRIGHT, IROWS, ITAU, IWORK, LOPT, LWKMIN,
  2747. $ LWKOPT, NB, NB1, NB2, NB3
  2748. DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
  2749. $ SAFMIN, SMLNUM
  2750. * ..
  2751. * .. External Subroutines ..
  2752. EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLACPY,
  2753. $ DLASCL, DLASET, DORGQR, DORMQR, XERBLA
  2754. * ..
  2755. * .. External Functions ..
  2756. LOGICAL LSAME
  2757. INTEGER ILAENV
  2758. DOUBLE PRECISION DLAMCH, DLANGE
  2759. EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE
  2760. * ..
  2761. * .. Intrinsic Functions ..
  2762. INTRINSIC INT, MAX
  2763. * ..
  2764. * .. Executable Statements ..
  2765. *
  2766. * Decode the input arguments
  2767. *
  2768. IF( LSAME( JOBVSL, 'N' ) ) THEN
  2769. IJOBVL = 1
  2770. ILVSL = .FALSE.
  2771. ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
  2772. IJOBVL = 2
  2773. ILVSL = .TRUE.
  2774. ELSE
  2775. IJOBVL = -1
  2776. ILVSL = .FALSE.
  2777. END IF
  2778. *
  2779. IF( LSAME( JOBVSR, 'N' ) ) THEN
  2780. IJOBVR = 1
  2781. ILVSR = .FALSE.
  2782. ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
  2783. IJOBVR = 2
  2784. ILVSR = .TRUE.
  2785. ELSE
  2786. IJOBVR = -1
  2787. ILVSR = .FALSE.
  2788. END IF
  2789. *
  2790. * Test the input arguments
  2791. *
  2792. LWKMIN = MAX( 4*N, 1 )
  2793. LWKOPT = LWKMIN
  2794. WORK( 1 ) = LWKOPT
  2795. LQUERY = ( LWORK.EQ.-1 )
  2796. INFO = 0
  2797. IF( IJOBVL.LE.0 ) THEN
  2798. INFO = -1
  2799. ELSE IF( IJOBVR.LE.0 ) THEN
  2800. INFO = -2
  2801. ELSE IF( N.LT.0 ) THEN
  2802. INFO = -3
  2803. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  2804. INFO = -5
  2805. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  2806. INFO = -7
  2807. ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
  2808. INFO = -12
  2809. ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
  2810. INFO = -14
  2811. ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
  2812. INFO = -16
  2813. END IF
  2814. *
  2815. IF( INFO.EQ.0 ) THEN
  2816. NB1 = ILAENV( 1, 'DGEQRF', ' ', N, N, -1, -1 )
  2817. NB2 = ILAENV( 1, 'DORMQR', ' ', N, N, N, -1 )
  2818. NB3 = ILAENV( 1, 'DORGQR', ' ', N, N, N, -1 )
  2819. NB = MAX( NB1, NB2, NB3 )
  2820. LOPT = 2*N + N*( NB+1 )
  2821. WORK( 1 ) = LOPT
  2822. END IF
  2823. *
  2824. IF( INFO.NE.0 ) THEN
  2825. CALL XERBLA( 'DGEGS ', -INFO )
  2826. RETURN
  2827. ELSE IF( LQUERY ) THEN
  2828. RETURN
  2829. END IF
  2830. *
  2831. * Quick return if possible
  2832. *
  2833. IF( N.EQ.0 )
  2834. $ RETURN
  2835. *
  2836. * Get machine constants
  2837. *
  2838. EPS = DLAMCH( 'E' )*DLAMCH( 'B' )
  2839. SAFMIN = DLAMCH( 'S' )
  2840. SMLNUM = N*SAFMIN / EPS
  2841. BIGNUM = ONE / SMLNUM
  2842. *
  2843. * Scale A if max element outside range [SMLNUM,BIGNUM]
  2844. *
  2845. ANRM = DLANGE( 'M', N, N, A, LDA, WORK )
  2846. ILASCL = .FALSE.
  2847. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  2848. ANRMTO = SMLNUM
  2849. ILASCL = .TRUE.
  2850. ELSE IF( ANRM.GT.BIGNUM ) THEN
  2851. ANRMTO = BIGNUM
  2852. ILASCL = .TRUE.
  2853. END IF
  2854. *
  2855. IF( ILASCL ) THEN
  2856. CALL DLASCL( 'G', -1, -1, ANRM, ANRMTO, N, N, A, LDA, IINFO )
  2857. IF( IINFO.NE.0 ) THEN
  2858. INFO = N + 9
  2859. RETURN
  2860. END IF
  2861. END IF
  2862. *
  2863. * Scale B if max element outside range [SMLNUM,BIGNUM]
  2864. *
  2865. BNRM = DLANGE( 'M', N, N, B, LDB, WORK )
  2866. ILBSCL = .FALSE.
  2867. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  2868. BNRMTO = SMLNUM
  2869. ILBSCL = .TRUE.
  2870. ELSE IF( BNRM.GT.BIGNUM ) THEN
  2871. BNRMTO = BIGNUM
  2872. ILBSCL = .TRUE.
  2873. END IF
  2874. *
  2875. IF( ILBSCL ) THEN
  2876. CALL DLASCL( 'G', -1, -1, BNRM, BNRMTO, N, N, B, LDB, IINFO )
  2877. IF( IINFO.NE.0 ) THEN
  2878. INFO = N + 9
  2879. RETURN
  2880. END IF
  2881. END IF
  2882. *
  2883. * Permute the matrix to make it more nearly triangular
  2884. * Workspace layout: (2*N words -- "work..." not actually used)
  2885. * left_permutation, right_permutation, work...
  2886. *
  2887. ILEFT = 1
  2888. IRIGHT = N + 1
  2889. IWORK = IRIGHT + N
  2890. CALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
  2891. $ WORK( IRIGHT ), WORK( IWORK ), IINFO )
  2892. IF( IINFO.NE.0 ) THEN
  2893. INFO = N + 1
  2894. GO TO 10
  2895. END IF
  2896. *
  2897. * Reduce B to triangular form, and initialize VSL and/or VSR
  2898. * Workspace layout: ("work..." must have at least N words)
  2899. * left_permutation, right_permutation, tau, work...
  2900. *
  2901. IROWS = IHI + 1 - ILO
  2902. ICOLS = N + 1 - ILO
  2903. ITAU = IWORK
  2904. IWORK = ITAU + IROWS
  2905. CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
  2906. $ WORK( IWORK ), LWORK+1-IWORK, IINFO )
  2907. IF( IINFO.GE.0 )
  2908. $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  2909. IF( IINFO.NE.0 ) THEN
  2910. INFO = N + 2
  2911. GO TO 10
  2912. END IF
  2913. *
  2914. CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
  2915. $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),
  2916. $ LWORK+1-IWORK, IINFO )
  2917. IF( IINFO.GE.0 )
  2918. $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  2919. IF( IINFO.NE.0 ) THEN
  2920. INFO = N + 3
  2921. GO TO 10
  2922. END IF
  2923. *
  2924. IF( ILVSL ) THEN
  2925. CALL DLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL )
  2926. CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
  2927. $ VSL( ILO+1, ILO ), LDVSL )
  2928. CALL DORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
  2929. $ WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,
  2930. $ IINFO )
  2931. IF( IINFO.GE.0 )
  2932. $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  2933. IF( IINFO.NE.0 ) THEN
  2934. INFO = N + 4
  2935. GO TO 10
  2936. END IF
  2937. END IF
  2938. *
  2939. IF( ILVSR )
  2940. $ CALL DLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR )
  2941. *
  2942. * Reduce to generalized Hessenberg form
  2943. *
  2944. CALL DGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
  2945. $ LDVSL, VSR, LDVSR, IINFO )
  2946. IF( IINFO.NE.0 ) THEN
  2947. INFO = N + 5
  2948. GO TO 10
  2949. END IF
  2950. *
  2951. * Perform QZ algorithm, computing Schur vectors if desired
  2952. * Workspace layout: ("work..." must have at least 1 word)
  2953. * left_permutation, right_permutation, work...
  2954. *
  2955. IWORK = ITAU
  2956. CALL DHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
  2957. $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
  2958. $ WORK( IWORK ), LWORK+1-IWORK, IINFO )
  2959. IF( IINFO.GE.0 )
  2960. $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  2961. IF( IINFO.NE.0 ) THEN
  2962. IF( IINFO.GT.0 .AND. IINFO.LE.N ) THEN
  2963. INFO = IINFO
  2964. ELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THEN
  2965. INFO = IINFO - N
  2966. ELSE
  2967. INFO = N + 6
  2968. END IF
  2969. GO TO 10
  2970. END IF
  2971. *
  2972. * Apply permutation to VSL and VSR
  2973. *
  2974. IF( ILVSL ) THEN
  2975. CALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
  2976. $ WORK( IRIGHT ), N, VSL, LDVSL, IINFO )
  2977. IF( IINFO.NE.0 ) THEN
  2978. INFO = N + 7
  2979. GO TO 10
  2980. END IF
  2981. END IF
  2982. IF( ILVSR ) THEN
  2983. CALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
  2984. $ WORK( IRIGHT ), N, VSR, LDVSR, IINFO )
  2985. IF( IINFO.NE.0 ) THEN
  2986. INFO = N + 8
  2987. GO TO 10
  2988. END IF
  2989. END IF
  2990. *
  2991. * Undo scaling
  2992. *
  2993. IF( ILASCL ) THEN
  2994. CALL DLASCL( 'H', -1, -1, ANRMTO, ANRM, N, N, A, LDA, IINFO )
  2995. IF( IINFO.NE.0 ) THEN
  2996. INFO = N + 9
  2997. RETURN
  2998. END IF
  2999. CALL DLASCL( 'G', -1, -1, ANRMTO, ANRM, N, 1, ALPHAR, N,
  3000. $ IINFO )
  3001. IF( IINFO.NE.0 ) THEN
  3002. INFO = N + 9
  3003. RETURN
  3004. END IF
  3005. CALL DLASCL( 'G', -1, -1, ANRMTO, ANRM, N, 1, ALPHAI, N,
  3006. $ IINFO )
  3007. IF( IINFO.NE.0 ) THEN
  3008. INFO = N + 9
  3009. RETURN
  3010. END IF
  3011. END IF
  3012. *
  3013. IF( ILBSCL ) THEN
  3014. CALL DLASCL( 'U', -1, -1, BNRMTO, BNRM, N, N, B, LDB, IINFO )
  3015. IF( IINFO.NE.0 ) THEN
  3016. INFO = N + 9
  3017. RETURN
  3018. END IF
  3019. CALL DLASCL( 'G', -1, -1, BNRMTO, BNRM, N, 1, BETA, N, IINFO )
  3020. IF( IINFO.NE.0 ) THEN
  3021. INFO = N + 9
  3022. RETURN
  3023. END IF
  3024. END IF
  3025. *
  3026. 10 CONTINUE
  3027. WORK( 1 ) = LWKOPT
  3028. *
  3029. RETURN
  3030. *
  3031. * End of DGEGS
  3032. *
  3033. END
  3034. SUBROUTINE DGEGV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,
  3035. $ BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )
  3036. *
  3037. * -- LAPACK driver routine (version 3.1) --
  3038. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  3039. * November 2006
  3040. *
  3041. * .. Scalar Arguments ..
  3042. CHARACTER JOBVL, JOBVR
  3043. INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
  3044. * ..
  3045. * .. Array Arguments ..
  3046. DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
  3047. $ B( LDB, * ), BETA( * ), VL( LDVL, * ),
  3048. $ VR( LDVR, * ), WORK( * )
  3049. * ..
  3050. *
  3051. * Purpose
  3052. * =======
  3053. *
  3054. * This routine is deprecated and has been replaced by routine DGGEV.
  3055. *
  3056. * DGEGV computes the eigenvalues and, optionally, the left and/or right
  3057. * eigenvectors of a real matrix pair (A,B).
  3058. * Given two square matrices A and B,
  3059. * the generalized nonsymmetric eigenvalue problem (GNEP) is to find the
  3060. * eigenvalues lambda and corresponding (non-zero) eigenvectors x such
  3061. * that
  3062. *
  3063. * A*x = lambda*B*x.
  3064. *
  3065. * An alternate form is to find the eigenvalues mu and corresponding
  3066. * eigenvectors y such that
  3067. *
  3068. * mu*A*y = B*y.
  3069. *
  3070. * These two forms are equivalent with mu = 1/lambda and x = y if
  3071. * neither lambda nor mu is zero. In order to deal with the case that
  3072. * lambda or mu is zero or small, two values alpha and beta are returned
  3073. * for each eigenvalue, such that lambda = alpha/beta and
  3074. * mu = beta/alpha.
  3075. *
  3076. * The vectors x and y in the above equations are right eigenvectors of
  3077. * the matrix pair (A,B). Vectors u and v satisfying
  3078. *
  3079. * u**H*A = lambda*u**H*B or mu*v**H*A = v**H*B
  3080. *
  3081. * are left eigenvectors of (A,B).
  3082. *
  3083. * Note: this routine performs "full balancing" on A and B -- see
  3084. * "Further Details", below.
  3085. *
  3086. * Arguments
  3087. * =========
  3088. *
  3089. * JOBVL (input) CHARACTER*1
  3090. * = 'N': do not compute the left generalized eigenvectors;
  3091. * = 'V': compute the left generalized eigenvectors (returned
  3092. * in VL).
  3093. *
  3094. * JOBVR (input) CHARACTER*1
  3095. * = 'N': do not compute the right generalized eigenvectors;
  3096. * = 'V': compute the right generalized eigenvectors (returned
  3097. * in VR).
  3098. *
  3099. * N (input) INTEGER
  3100. * The order of the matrices A, B, VL, and VR. N >= 0.
  3101. *
  3102. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  3103. * On entry, the matrix A.
  3104. * If JOBVL = 'V' or JOBVR = 'V', then on exit A
  3105. * contains the real Schur form of A from the generalized Schur
  3106. * factorization of the pair (A,B) after balancing.
  3107. * If no eigenvectors were computed, then only the diagonal
  3108. * blocks from the Schur form will be correct. See DGGHRD and
  3109. * DHGEQZ for details.
  3110. *
  3111. * LDA (input) INTEGER
  3112. * The leading dimension of A. LDA >= max(1,N).
  3113. *
  3114. * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
  3115. * On entry, the matrix B.
  3116. * If JOBVL = 'V' or JOBVR = 'V', then on exit B contains the
  3117. * upper triangular matrix obtained from B in the generalized
  3118. * Schur factorization of the pair (A,B) after balancing.
  3119. * If no eigenvectors were computed, then only those elements of
  3120. * B corresponding to the diagonal blocks from the Schur form of
  3121. * A will be correct. See DGGHRD and DHGEQZ for details.
  3122. *
  3123. * LDB (input) INTEGER
  3124. * The leading dimension of B. LDB >= max(1,N).
  3125. *
  3126. * ALPHAR (output) DOUBLE PRECISION array, dimension (N)
  3127. * The real parts of each scalar alpha defining an eigenvalue of
  3128. * GNEP.
  3129. *
  3130. * ALPHAI (output) DOUBLE PRECISION array, dimension (N)
  3131. * The imaginary parts of each scalar alpha defining an
  3132. * eigenvalue of GNEP. If ALPHAI(j) is zero, then the j-th
  3133. * eigenvalue is real; if positive, then the j-th and
  3134. * (j+1)-st eigenvalues are a complex conjugate pair, with
  3135. * ALPHAI(j+1) = -ALPHAI(j).
  3136. *
  3137. * BETA (output) DOUBLE PRECISION array, dimension (N)
  3138. * The scalars beta that define the eigenvalues of GNEP.
  3139. *
  3140. * Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and
  3141. * beta = BETA(j) represent the j-th eigenvalue of the matrix
  3142. * pair (A,B), in one of the forms lambda = alpha/beta or
  3143. * mu = beta/alpha. Since either lambda or mu may overflow,
  3144. * they should not, in general, be computed.
  3145. *
  3146. * VL (output) DOUBLE PRECISION array, dimension (LDVL,N)
  3147. * If JOBVL = 'V', the left eigenvectors u(j) are stored
  3148. * in the columns of VL, in the same order as their eigenvalues.
  3149. * If the j-th eigenvalue is real, then u(j) = VL(:,j).
  3150. * If the j-th and (j+1)-st eigenvalues form a complex conjugate
  3151. * pair, then
  3152. * u(j) = VL(:,j) + i*VL(:,j+1)
  3153. * and
  3154. * u(j+1) = VL(:,j) - i*VL(:,j+1).
  3155. *
  3156. * Each eigenvector is scaled so that its largest component has
  3157. * abs(real part) + abs(imag. part) = 1, except for eigenvectors
  3158. * corresponding to an eigenvalue with alpha = beta = 0, which
  3159. * are set to zero.
  3160. * Not referenced if JOBVL = 'N'.
  3161. *
  3162. * LDVL (input) INTEGER
  3163. * The leading dimension of the matrix VL. LDVL >= 1, and
  3164. * if JOBVL = 'V', LDVL >= N.
  3165. *
  3166. * VR (output) DOUBLE PRECISION array, dimension (LDVR,N)
  3167. * If JOBVR = 'V', the right eigenvectors x(j) are stored
  3168. * in the columns of VR, in the same order as their eigenvalues.
  3169. * If the j-th eigenvalue is real, then x(j) = VR(:,j).
  3170. * If the j-th and (j+1)-st eigenvalues form a complex conjugate
  3171. * pair, then
  3172. * x(j) = VR(:,j) + i*VR(:,j+1)
  3173. * and
  3174. * x(j+1) = VR(:,j) - i*VR(:,j+1).
  3175. *
  3176. * Each eigenvector is scaled so that its largest component has
  3177. * abs(real part) + abs(imag. part) = 1, except for eigenvalues
  3178. * corresponding to an eigenvalue with alpha = beta = 0, which
  3179. * are set to zero.
  3180. * Not referenced if JOBVR = 'N'.
  3181. *
  3182. * LDVR (input) INTEGER
  3183. * The leading dimension of the matrix VR. LDVR >= 1, and
  3184. * if JOBVR = 'V', LDVR >= N.
  3185. *
  3186. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  3187. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  3188. *
  3189. * LWORK (input) INTEGER
  3190. * The dimension of the array WORK. LWORK >= max(1,8*N).
  3191. * For good performance, LWORK must generally be larger.
  3192. * To compute the optimal value of LWORK, call ILAENV to get
  3193. * blocksizes (for DGEQRF, DORMQR, and DORGQR.) Then compute:
  3194. * NB -- MAX of the blocksizes for DGEQRF, DORMQR, and DORGQR;
  3195. * The optimal LWORK is:
  3196. * 2*N + MAX( 6*N, N*(NB+1) ).
  3197. *
  3198. * If LWORK = -1, then a workspace query is assumed; the routine
  3199. * only calculates the optimal size of the WORK array, returns
  3200. * this value as the first entry of the WORK array, and no error
  3201. * message related to LWORK is issued by XERBLA.
  3202. *
  3203. * INFO (output) INTEGER
  3204. * = 0: successful exit
  3205. * < 0: if INFO = -i, the i-th argument had an illegal value.
  3206. * = 1,...,N:
  3207. * The QZ iteration failed. No eigenvectors have been
  3208. * calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
  3209. * should be correct for j=INFO+1,...,N.
  3210. * > N: errors that usually indicate LAPACK problems:
  3211. * =N+1: error return from DGGBAL
  3212. * =N+2: error return from DGEQRF
  3213. * =N+3: error return from DORMQR
  3214. * =N+4: error return from DORGQR
  3215. * =N+5: error return from DGGHRD
  3216. * =N+6: error return from DHGEQZ (other than failed
  3217. * iteration)
  3218. * =N+7: error return from DTGEVC
  3219. * =N+8: error return from DGGBAK (computing VL)
  3220. * =N+9: error return from DGGBAK (computing VR)
  3221. * =N+10: error return from DLASCL (various calls)
  3222. *
  3223. * Further Details
  3224. * ===============
  3225. *
  3226. * Balancing
  3227. * ---------
  3228. *
  3229. * This driver calls DGGBAL to both permute and scale rows and columns
  3230. * of A and B. The permutations PL and PR are chosen so that PL*A*PR
  3231. * and PL*B*R will be upper triangular except for the diagonal blocks
  3232. * A(i:j,i:j) and B(i:j,i:j), with i and j as close together as
  3233. * possible. The diagonal scaling matrices DL and DR are chosen so
  3234. * that the pair DL*PL*A*PR*DR, DL*PL*B*PR*DR have elements close to
  3235. * one (except for the elements that start out zero.)
  3236. *
  3237. * After the eigenvalues and eigenvectors of the balanced matrices
  3238. * have been computed, DGGBAK transforms the eigenvectors back to what
  3239. * they would have been (in perfect arithmetic) if they had not been
  3240. * balanced.
  3241. *
  3242. * Contents of A and B on Exit
  3243. * -------- -- - --- - -- ----
  3244. *
  3245. * If any eigenvectors are computed (either JOBVL='V' or JOBVR='V' or
  3246. * both), then on exit the arrays A and B will contain the real Schur
  3247. * form[*] of the "balanced" versions of A and B. If no eigenvectors
  3248. * are computed, then only the diagonal blocks will be correct.
  3249. *
  3250. * [*] See DHGEQZ, DGEGS, or read the book "Matrix Computations",
  3251. * by Golub & van Loan, pub. by Johns Hopkins U. Press.
  3252. *
  3253. * =====================================================================
  3254. *
  3255. * .. Parameters ..
  3256. DOUBLE PRECISION ZERO, ONE
  3257. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  3258. * ..
  3259. * .. Local Scalars ..
  3260. LOGICAL ILIMIT, ILV, ILVL, ILVR, LQUERY
  3261. CHARACTER CHTEMP
  3262. INTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,
  3263. $ IN, IRIGHT, IROWS, ITAU, IWORK, JC, JR, LOPT,
  3264. $ LWKMIN, LWKOPT, NB, NB1, NB2, NB3
  3265. DOUBLE PRECISION ABSAI, ABSAR, ABSB, ANRM, ANRM1, ANRM2, BNRM,
  3266. $ BNRM1, BNRM2, EPS, ONEPLS, SAFMAX, SAFMIN,
  3267. $ SALFAI, SALFAR, SBETA, SCALE, TEMP
  3268. * ..
  3269. * .. Local Arrays ..
  3270. LOGICAL LDUMMA( 1 )
  3271. * ..
  3272. * .. External Subroutines ..
  3273. EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLACPY,
  3274. $ DLASCL, DLASET, DORGQR, DORMQR, DTGEVC, XERBLA
  3275. * ..
  3276. * .. External Functions ..
  3277. LOGICAL LSAME
  3278. INTEGER ILAENV
  3279. DOUBLE PRECISION DLAMCH, DLANGE
  3280. EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE
  3281. * ..
  3282. * .. Intrinsic Functions ..
  3283. INTRINSIC ABS, INT, MAX
  3284. * ..
  3285. * .. Executable Statements ..
  3286. *
  3287. * Decode the input arguments
  3288. *
  3289. IF( LSAME( JOBVL, 'N' ) ) THEN
  3290. IJOBVL = 1
  3291. ILVL = .FALSE.
  3292. ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
  3293. IJOBVL = 2
  3294. ILVL = .TRUE.
  3295. ELSE
  3296. IJOBVL = -1
  3297. ILVL = .FALSE.
  3298. END IF
  3299. *
  3300. IF( LSAME( JOBVR, 'N' ) ) THEN
  3301. IJOBVR = 1
  3302. ILVR = .FALSE.
  3303. ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
  3304. IJOBVR = 2
  3305. ILVR = .TRUE.
  3306. ELSE
  3307. IJOBVR = -1
  3308. ILVR = .FALSE.
  3309. END IF
  3310. ILV = ILVL .OR. ILVR
  3311. *
  3312. * Test the input arguments
  3313. *
  3314. LWKMIN = MAX( 8*N, 1 )
  3315. LWKOPT = LWKMIN
  3316. WORK( 1 ) = LWKOPT
  3317. LQUERY = ( LWORK.EQ.-1 )
  3318. INFO = 0
  3319. IF( IJOBVL.LE.0 ) THEN
  3320. INFO = -1
  3321. ELSE IF( IJOBVR.LE.0 ) THEN
  3322. INFO = -2
  3323. ELSE IF( N.LT.0 ) THEN
  3324. INFO = -3
  3325. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  3326. INFO = -5
  3327. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  3328. INFO = -7
  3329. ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
  3330. INFO = -12
  3331. ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
  3332. INFO = -14
  3333. ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
  3334. INFO = -16
  3335. END IF
  3336. *
  3337. IF( INFO.EQ.0 ) THEN
  3338. NB1 = ILAENV( 1, 'DGEQRF', ' ', N, N, -1, -1 )
  3339. NB2 = ILAENV( 1, 'DORMQR', ' ', N, N, N, -1 )
  3340. NB3 = ILAENV( 1, 'DORGQR', ' ', N, N, N, -1 )
  3341. NB = MAX( NB1, NB2, NB3 )
  3342. LOPT = 2*N + MAX( 6*N, N*( NB+1 ) )
  3343. WORK( 1 ) = LOPT
  3344. END IF
  3345. *
  3346. IF( INFO.NE.0 ) THEN
  3347. CALL XERBLA( 'DGEGV ', -INFO )
  3348. RETURN
  3349. ELSE IF( LQUERY ) THEN
  3350. RETURN
  3351. END IF
  3352. *
  3353. * Quick return if possible
  3354. *
  3355. IF( N.EQ.0 )
  3356. $ RETURN
  3357. *
  3358. * Get machine constants
  3359. *
  3360. EPS = DLAMCH( 'E' )*DLAMCH( 'B' )
  3361. SAFMIN = DLAMCH( 'S' )
  3362. SAFMIN = SAFMIN + SAFMIN
  3363. SAFMAX = ONE / SAFMIN
  3364. ONEPLS = ONE + ( 4*EPS )
  3365. *
  3366. * Scale A
  3367. *
  3368. ANRM = DLANGE( 'M', N, N, A, LDA, WORK )
  3369. ANRM1 = ANRM
  3370. ANRM2 = ONE
  3371. IF( ANRM.LT.ONE ) THEN
  3372. IF( SAFMAX*ANRM.LT.ONE ) THEN
  3373. ANRM1 = SAFMIN
  3374. ANRM2 = SAFMAX*ANRM
  3375. END IF
  3376. END IF
  3377. *
  3378. IF( ANRM.GT.ZERO ) THEN
  3379. CALL DLASCL( 'G', -1, -1, ANRM, ONE, N, N, A, LDA, IINFO )
  3380. IF( IINFO.NE.0 ) THEN
  3381. INFO = N + 10
  3382. RETURN
  3383. END IF
  3384. END IF
  3385. *
  3386. * Scale B
  3387. *
  3388. BNRM = DLANGE( 'M', N, N, B, LDB, WORK )
  3389. BNRM1 = BNRM
  3390. BNRM2 = ONE
  3391. IF( BNRM.LT.ONE ) THEN
  3392. IF( SAFMAX*BNRM.LT.ONE ) THEN
  3393. BNRM1 = SAFMIN
  3394. BNRM2 = SAFMAX*BNRM
  3395. END IF
  3396. END IF
  3397. *
  3398. IF( BNRM.GT.ZERO ) THEN
  3399. CALL DLASCL( 'G', -1, -1, BNRM, ONE, N, N, B, LDB, IINFO )
  3400. IF( IINFO.NE.0 ) THEN
  3401. INFO = N + 10
  3402. RETURN
  3403. END IF
  3404. END IF
  3405. *
  3406. * Permute the matrix to make it more nearly triangular
  3407. * Workspace layout: (8*N words -- "work" requires 6*N words)
  3408. * left_permutation, right_permutation, work...
  3409. *
  3410. ILEFT = 1
  3411. IRIGHT = N + 1
  3412. IWORK = IRIGHT + N
  3413. CALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
  3414. $ WORK( IRIGHT ), WORK( IWORK ), IINFO )
  3415. IF( IINFO.NE.0 ) THEN
  3416. INFO = N + 1
  3417. GO TO 120
  3418. END IF
  3419. *
  3420. * Reduce B to triangular form, and initialize VL and/or VR
  3421. * Workspace layout: ("work..." must have at least N words)
  3422. * left_permutation, right_permutation, tau, work...
  3423. *
  3424. IROWS = IHI + 1 - ILO
  3425. IF( ILV ) THEN
  3426. ICOLS = N + 1 - ILO
  3427. ELSE
  3428. ICOLS = IROWS
  3429. END IF
  3430. ITAU = IWORK
  3431. IWORK = ITAU + IROWS
  3432. CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
  3433. $ WORK( IWORK ), LWORK+1-IWORK, IINFO )
  3434. IF( IINFO.GE.0 )
  3435. $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  3436. IF( IINFO.NE.0 ) THEN
  3437. INFO = N + 2
  3438. GO TO 120
  3439. END IF
  3440. *
  3441. CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
  3442. $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),
  3443. $ LWORK+1-IWORK, IINFO )
  3444. IF( IINFO.GE.0 )
  3445. $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  3446. IF( IINFO.NE.0 ) THEN
  3447. INFO = N + 3
  3448. GO TO 120
  3449. END IF
  3450. *
  3451. IF( ILVL ) THEN
  3452. CALL DLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )
  3453. CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
  3454. $ VL( ILO+1, ILO ), LDVL )
  3455. CALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
  3456. $ WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,
  3457. $ IINFO )
  3458. IF( IINFO.GE.0 )
  3459. $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  3460. IF( IINFO.NE.0 ) THEN
  3461. INFO = N + 4
  3462. GO TO 120
  3463. END IF
  3464. END IF
  3465. *
  3466. IF( ILVR )
  3467. $ CALL DLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )
  3468. *
  3469. * Reduce to generalized Hessenberg form
  3470. *
  3471. IF( ILV ) THEN
  3472. *
  3473. * Eigenvectors requested -- work on whole matrix.
  3474. *
  3475. CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
  3476. $ LDVL, VR, LDVR, IINFO )
  3477. ELSE
  3478. CALL DGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
  3479. $ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IINFO )
  3480. END IF
  3481. IF( IINFO.NE.0 ) THEN
  3482. INFO = N + 5
  3483. GO TO 120
  3484. END IF
  3485. *
  3486. * Perform QZ algorithm
  3487. * Workspace layout: ("work..." must have at least 1 word)
  3488. * left_permutation, right_permutation, work...
  3489. *
  3490. IWORK = ITAU
  3491. IF( ILV ) THEN
  3492. CHTEMP = 'S'
  3493. ELSE
  3494. CHTEMP = 'E'
  3495. END IF
  3496. CALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
  3497. $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,
  3498. $ WORK( IWORK ), LWORK+1-IWORK, IINFO )
  3499. IF( IINFO.GE.0 )
  3500. $ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  3501. IF( IINFO.NE.0 ) THEN
  3502. IF( IINFO.GT.0 .AND. IINFO.LE.N ) THEN
  3503. INFO = IINFO
  3504. ELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THEN
  3505. INFO = IINFO - N
  3506. ELSE
  3507. INFO = N + 6
  3508. END IF
  3509. GO TO 120
  3510. END IF
  3511. *
  3512. IF( ILV ) THEN
  3513. *
  3514. * Compute Eigenvectors (DTGEVC requires 6*N words of workspace)
  3515. *
  3516. IF( ILVL ) THEN
  3517. IF( ILVR ) THEN
  3518. CHTEMP = 'B'
  3519. ELSE
  3520. CHTEMP = 'L'
  3521. END IF
  3522. ELSE
  3523. CHTEMP = 'R'
  3524. END IF
  3525. *
  3526. CALL DTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
  3527. $ VR, LDVR, N, IN, WORK( IWORK ), IINFO )
  3528. IF( IINFO.NE.0 ) THEN
  3529. INFO = N + 7
  3530. GO TO 120
  3531. END IF
  3532. *
  3533. * Undo balancing on VL and VR, rescale
  3534. *
  3535. IF( ILVL ) THEN
  3536. CALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
  3537. $ WORK( IRIGHT ), N, VL, LDVL, IINFO )
  3538. IF( IINFO.NE.0 ) THEN
  3539. INFO = N + 8
  3540. GO TO 120
  3541. END IF
  3542. DO 50 JC = 1, N
  3543. IF( ALPHAI( JC ).LT.ZERO )
  3544. $ GO TO 50
  3545. TEMP = ZERO
  3546. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  3547. DO 10 JR = 1, N
  3548. TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )
  3549. 10 CONTINUE
  3550. ELSE
  3551. DO 20 JR = 1, N
  3552. TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+
  3553. $ ABS( VL( JR, JC+1 ) ) )
  3554. 20 CONTINUE
  3555. END IF
  3556. IF( TEMP.LT.SAFMIN )
  3557. $ GO TO 50
  3558. TEMP = ONE / TEMP
  3559. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  3560. DO 30 JR = 1, N
  3561. VL( JR, JC ) = VL( JR, JC )*TEMP
  3562. 30 CONTINUE
  3563. ELSE
  3564. DO 40 JR = 1, N
  3565. VL( JR, JC ) = VL( JR, JC )*TEMP
  3566. VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP
  3567. 40 CONTINUE
  3568. END IF
  3569. 50 CONTINUE
  3570. END IF
  3571. IF( ILVR ) THEN
  3572. CALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
  3573. $ WORK( IRIGHT ), N, VR, LDVR, IINFO )
  3574. IF( IINFO.NE.0 ) THEN
  3575. INFO = N + 9
  3576. GO TO 120
  3577. END IF
  3578. DO 100 JC = 1, N
  3579. IF( ALPHAI( JC ).LT.ZERO )
  3580. $ GO TO 100
  3581. TEMP = ZERO
  3582. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  3583. DO 60 JR = 1, N
  3584. TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )
  3585. 60 CONTINUE
  3586. ELSE
  3587. DO 70 JR = 1, N
  3588. TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+
  3589. $ ABS( VR( JR, JC+1 ) ) )
  3590. 70 CONTINUE
  3591. END IF
  3592. IF( TEMP.LT.SAFMIN )
  3593. $ GO TO 100
  3594. TEMP = ONE / TEMP
  3595. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  3596. DO 80 JR = 1, N
  3597. VR( JR, JC ) = VR( JR, JC )*TEMP
  3598. 80 CONTINUE
  3599. ELSE
  3600. DO 90 JR = 1, N
  3601. VR( JR, JC ) = VR( JR, JC )*TEMP
  3602. VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP
  3603. 90 CONTINUE
  3604. END IF
  3605. 100 CONTINUE
  3606. END IF
  3607. *
  3608. * End of eigenvector calculation
  3609. *
  3610. END IF
  3611. *
  3612. * Undo scaling in alpha, beta
  3613. *
  3614. * Note: this does not give the alpha and beta for the unscaled
  3615. * problem.
  3616. *
  3617. * Un-scaling is limited to avoid underflow in alpha and beta
  3618. * if they are significant.
  3619. *
  3620. DO 110 JC = 1, N
  3621. ABSAR = ABS( ALPHAR( JC ) )
  3622. ABSAI = ABS( ALPHAI( JC ) )
  3623. ABSB = ABS( BETA( JC ) )
  3624. SALFAR = ANRM*ALPHAR( JC )
  3625. SALFAI = ANRM*ALPHAI( JC )
  3626. SBETA = BNRM*BETA( JC )
  3627. ILIMIT = .FALSE.
  3628. SCALE = ONE
  3629. *
  3630. * Check for significant underflow in ALPHAI
  3631. *
  3632. IF( ABS( SALFAI ).LT.SAFMIN .AND. ABSAI.GE.
  3633. $ MAX( SAFMIN, EPS*ABSAR, EPS*ABSB ) ) THEN
  3634. ILIMIT = .TRUE.
  3635. SCALE = ( ONEPLS*SAFMIN / ANRM1 ) /
  3636. $ MAX( ONEPLS*SAFMIN, ANRM2*ABSAI )
  3637. *
  3638. ELSE IF( SALFAI.EQ.ZERO ) THEN
  3639. *
  3640. * If insignificant underflow in ALPHAI, then make the
  3641. * conjugate eigenvalue real.
  3642. *
  3643. IF( ALPHAI( JC ).LT.ZERO .AND. JC.GT.1 ) THEN
  3644. ALPHAI( JC-1 ) = ZERO
  3645. ELSE IF( ALPHAI( JC ).GT.ZERO .AND. JC.LT.N ) THEN
  3646. ALPHAI( JC+1 ) = ZERO
  3647. END IF
  3648. END IF
  3649. *
  3650. * Check for significant underflow in ALPHAR
  3651. *
  3652. IF( ABS( SALFAR ).LT.SAFMIN .AND. ABSAR.GE.
  3653. $ MAX( SAFMIN, EPS*ABSAI, EPS*ABSB ) ) THEN
  3654. ILIMIT = .TRUE.
  3655. SCALE = MAX( SCALE, ( ONEPLS*SAFMIN / ANRM1 ) /
  3656. $ MAX( ONEPLS*SAFMIN, ANRM2*ABSAR ) )
  3657. END IF
  3658. *
  3659. * Check for significant underflow in BETA
  3660. *
  3661. IF( ABS( SBETA ).LT.SAFMIN .AND. ABSB.GE.
  3662. $ MAX( SAFMIN, EPS*ABSAR, EPS*ABSAI ) ) THEN
  3663. ILIMIT = .TRUE.
  3664. SCALE = MAX( SCALE, ( ONEPLS*SAFMIN / BNRM1 ) /
  3665. $ MAX( ONEPLS*SAFMIN, BNRM2*ABSB ) )
  3666. END IF
  3667. *
  3668. * Check for possible overflow when limiting scaling
  3669. *
  3670. IF( ILIMIT ) THEN
  3671. TEMP = ( SCALE*SAFMIN )*MAX( ABS( SALFAR ), ABS( SALFAI ),
  3672. $ ABS( SBETA ) )
  3673. IF( TEMP.GT.ONE )
  3674. $ SCALE = SCALE / TEMP
  3675. IF( SCALE.LT.ONE )
  3676. $ ILIMIT = .FALSE.
  3677. END IF
  3678. *
  3679. * Recompute un-scaled ALPHAR, ALPHAI, BETA if necessary.
  3680. *
  3681. IF( ILIMIT ) THEN
  3682. SALFAR = ( SCALE*ALPHAR( JC ) )*ANRM
  3683. SALFAI = ( SCALE*ALPHAI( JC ) )*ANRM
  3684. SBETA = ( SCALE*BETA( JC ) )*BNRM
  3685. END IF
  3686. ALPHAR( JC ) = SALFAR
  3687. ALPHAI( JC ) = SALFAI
  3688. BETA( JC ) = SBETA
  3689. 110 CONTINUE
  3690. *
  3691. 120 CONTINUE
  3692. WORK( 1 ) = LWKOPT
  3693. *
  3694. RETURN
  3695. *
  3696. * End of DGEGV
  3697. *
  3698. END
  3699. SUBROUTINE DGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
  3700. $ INFO )
  3701. *
  3702. * -- LAPACK driver routine (version 3.1) --
  3703. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  3704. * November 2006
  3705. *
  3706. * .. Scalar Arguments ..
  3707. CHARACTER TRANS
  3708. INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
  3709. * ..
  3710. * .. Array Arguments ..
  3711. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )
  3712. * ..
  3713. *
  3714. * Purpose
  3715. * =======
  3716. *
  3717. * DGELS solves overdetermined or underdetermined real linear systems
  3718. * involving an M-by-N matrix A, or its transpose, using a QR or LQ
  3719. * factorization of A. It is assumed that A has full rank.
  3720. *
  3721. * The following options are provided:
  3722. *
  3723. * 1. If TRANS = 'N' and m >= n: find the least squares solution of
  3724. * an overdetermined system, i.e., solve the least squares problem
  3725. * minimize || B - A*X ||.
  3726. *
  3727. * 2. If TRANS = 'N' and m < n: find the minimum norm solution of
  3728. * an underdetermined system A * X = B.
  3729. *
  3730. * 3. If TRANS = 'T' and m >= n: find the minimum norm solution of
  3731. * an undetermined system A**T * X = B.
  3732. *
  3733. * 4. If TRANS = 'T' and m < n: find the least squares solution of
  3734. * an overdetermined system, i.e., solve the least squares problem
  3735. * minimize || B - A**T * X ||.
  3736. *
  3737. * Several right hand side vectors b and solution vectors x can be
  3738. * handled in a single call; they are stored as the columns of the
  3739. * M-by-NRHS right hand side matrix B and the N-by-NRHS solution
  3740. * matrix X.
  3741. *
  3742. * Arguments
  3743. * =========
  3744. *
  3745. * TRANS (input) CHARACTER*1
  3746. * = 'N': the linear system involves A;
  3747. * = 'T': the linear system involves A**T.
  3748. *
  3749. * M (input) INTEGER
  3750. * The number of rows of the matrix A. M >= 0.
  3751. *
  3752. * N (input) INTEGER
  3753. * The number of columns of the matrix A. N >= 0.
  3754. *
  3755. * NRHS (input) INTEGER
  3756. * The number of right hand sides, i.e., the number of
  3757. * columns of the matrices B and X. NRHS >=0.
  3758. *
  3759. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  3760. * On entry, the M-by-N matrix A.
  3761. * On exit,
  3762. * if M >= N, A is overwritten by details of its QR
  3763. * factorization as returned by DGEQRF;
  3764. * if M < N, A is overwritten by details of its LQ
  3765. * factorization as returned by DGELQF.
  3766. *
  3767. * LDA (input) INTEGER
  3768. * The leading dimension of the array A. LDA >= max(1,M).
  3769. *
  3770. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  3771. * On entry, the matrix B of right hand side vectors, stored
  3772. * columnwise; B is M-by-NRHS if TRANS = 'N', or N-by-NRHS
  3773. * if TRANS = 'T'.
  3774. * On exit, if INFO = 0, B is overwritten by the solution
  3775. * vectors, stored columnwise:
  3776. * if TRANS = 'N' and m >= n, rows 1 to n of B contain the least
  3777. * squares solution vectors; the residual sum of squares for the
  3778. * solution in each column is given by the sum of squares of
  3779. * elements N+1 to M in that column;
  3780. * if TRANS = 'N' and m < n, rows 1 to N of B contain the
  3781. * minimum norm solution vectors;
  3782. * if TRANS = 'T' and m >= n, rows 1 to M of B contain the
  3783. * minimum norm solution vectors;
  3784. * if TRANS = 'T' and m < n, rows 1 to M of B contain the
  3785. * least squares solution vectors; the residual sum of squares
  3786. * for the solution in each column is given by the sum of
  3787. * squares of elements M+1 to N in that column.
  3788. *
  3789. * LDB (input) INTEGER
  3790. * The leading dimension of the array B. LDB >= MAX(1,M,N).
  3791. *
  3792. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  3793. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  3794. *
  3795. * LWORK (input) INTEGER
  3796. * The dimension of the array WORK.
  3797. * LWORK >= max( 1, MN + max( MN, NRHS ) ).
  3798. * For optimal performance,
  3799. * LWORK >= max( 1, MN + max( MN, NRHS )*NB ).
  3800. * where MN = min(M,N) and NB is the optimum block size.
  3801. *
  3802. * If LWORK = -1, then a workspace query is assumed; the routine
  3803. * only calculates the optimal size of the WORK array, returns
  3804. * this value as the first entry of the WORK array, and no error
  3805. * message related to LWORK is issued by XERBLA.
  3806. *
  3807. * INFO (output) INTEGER
  3808. * = 0: successful exit
  3809. * < 0: if INFO = -i, the i-th argument had an illegal value
  3810. * > 0: if INFO = i, the i-th diagonal element of the
  3811. * triangular factor of A is zero, so that A does not have
  3812. * full rank; the least squares solution could not be
  3813. * computed.
  3814. *
  3815. * =====================================================================
  3816. *
  3817. * .. Parameters ..
  3818. DOUBLE PRECISION ZERO, ONE
  3819. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  3820. * ..
  3821. * .. Local Scalars ..
  3822. LOGICAL LQUERY, TPSD
  3823. INTEGER BROW, I, IASCL, IBSCL, J, MN, NB, SCLLEN, WSIZE
  3824. DOUBLE PRECISION ANRM, BIGNUM, BNRM, SMLNUM
  3825. * ..
  3826. * .. Local Arrays ..
  3827. DOUBLE PRECISION RWORK( 1 )
  3828. * ..
  3829. * .. External Functions ..
  3830. LOGICAL LSAME
  3831. INTEGER ILAENV
  3832. DOUBLE PRECISION DLAMCH, DLANGE
  3833. EXTERNAL LSAME, ILAENV, DLABAD, DLAMCH, DLANGE
  3834. * ..
  3835. * .. External Subroutines ..
  3836. EXTERNAL DGELQF, DGEQRF, DLASCL, DLASET, DORMLQ, DORMQR,
  3837. $ DTRTRS, XERBLA
  3838. * ..
  3839. * .. Intrinsic Functions ..
  3840. INTRINSIC DBLE, MAX, MIN
  3841. * ..
  3842. * .. Executable Statements ..
  3843. *
  3844. * Test the input arguments.
  3845. *
  3846. INFO = 0
  3847. MN = MIN( M, N )
  3848. LQUERY = ( LWORK.EQ.-1 )
  3849. IF( .NOT.( LSAME( TRANS, 'N' ) .OR. LSAME( TRANS, 'T' ) ) ) THEN
  3850. INFO = -1
  3851. ELSE IF( M.LT.0 ) THEN
  3852. INFO = -2
  3853. ELSE IF( N.LT.0 ) THEN
  3854. INFO = -3
  3855. ELSE IF( NRHS.LT.0 ) THEN
  3856. INFO = -4
  3857. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  3858. INFO = -6
  3859. ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
  3860. INFO = -8
  3861. ELSE IF( LWORK.LT.MAX( 1, MN+MAX( MN, NRHS ) ) .AND. .NOT.LQUERY )
  3862. $ THEN
  3863. INFO = -10
  3864. END IF
  3865. *
  3866. * Figure out optimal block size
  3867. *
  3868. IF( INFO.EQ.0 .OR. INFO.EQ.-10 ) THEN
  3869. *
  3870. TPSD = .TRUE.
  3871. IF( LSAME( TRANS, 'N' ) )
  3872. $ TPSD = .FALSE.
  3873. *
  3874. IF( M.GE.N ) THEN
  3875. NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  3876. IF( TPSD ) THEN
  3877. NB = MAX( NB, ILAENV( 1, 'DORMQR', 'LN', M, NRHS, N,
  3878. $ -1 ) )
  3879. ELSE
  3880. NB = MAX( NB, ILAENV( 1, 'DORMQR', 'LT', M, NRHS, N,
  3881. $ -1 ) )
  3882. END IF
  3883. ELSE
  3884. NB = ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  3885. IF( TPSD ) THEN
  3886. NB = MAX( NB, ILAENV( 1, 'DORMLQ', 'LT', N, NRHS, M,
  3887. $ -1 ) )
  3888. ELSE
  3889. NB = MAX( NB, ILAENV( 1, 'DORMLQ', 'LN', N, NRHS, M,
  3890. $ -1 ) )
  3891. END IF
  3892. END IF
  3893. *
  3894. WSIZE = MAX( 1, MN+MAX( MN, NRHS )*NB )
  3895. WORK( 1 ) = DBLE( WSIZE )
  3896. *
  3897. END IF
  3898. *
  3899. IF( INFO.NE.0 ) THEN
  3900. CALL XERBLA( 'DGELS ', -INFO )
  3901. RETURN
  3902. ELSE IF( LQUERY ) THEN
  3903. RETURN
  3904. END IF
  3905. *
  3906. * Quick return if possible
  3907. *
  3908. IF( MIN( M, N, NRHS ).EQ.0 ) THEN
  3909. CALL DLASET( 'Full', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
  3910. RETURN
  3911. END IF
  3912. *
  3913. * Get machine parameters
  3914. *
  3915. SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
  3916. BIGNUM = ONE / SMLNUM
  3917. CALL DLABAD( SMLNUM, BIGNUM )
  3918. *
  3919. * Scale A, B if max element outside range [SMLNUM,BIGNUM]
  3920. *
  3921. ANRM = DLANGE( 'M', M, N, A, LDA, RWORK )
  3922. IASCL = 0
  3923. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  3924. *
  3925. * Scale matrix norm up to SMLNUM
  3926. *
  3927. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
  3928. IASCL = 1
  3929. ELSE IF( ANRM.GT.BIGNUM ) THEN
  3930. *
  3931. * Scale matrix norm down to BIGNUM
  3932. *
  3933. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
  3934. IASCL = 2
  3935. ELSE IF( ANRM.EQ.ZERO ) THEN
  3936. *
  3937. * Matrix all zero. Return zero solution.
  3938. *
  3939. CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
  3940. GO TO 50
  3941. END IF
  3942. *
  3943. BROW = M
  3944. IF( TPSD )
  3945. $ BROW = N
  3946. BNRM = DLANGE( 'M', BROW, NRHS, B, LDB, RWORK )
  3947. IBSCL = 0
  3948. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  3949. *
  3950. * Scale matrix norm up to SMLNUM
  3951. *
  3952. CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, BROW, NRHS, B, LDB,
  3953. $ INFO )
  3954. IBSCL = 1
  3955. ELSE IF( BNRM.GT.BIGNUM ) THEN
  3956. *
  3957. * Scale matrix norm down to BIGNUM
  3958. *
  3959. CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, BROW, NRHS, B, LDB,
  3960. $ INFO )
  3961. IBSCL = 2
  3962. END IF
  3963. *
  3964. IF( M.GE.N ) THEN
  3965. *
  3966. * compute QR factorization of A
  3967. *
  3968. CALL DGEQRF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ), LWORK-MN,
  3969. $ INFO )
  3970. *
  3971. * workspace at least N, optimally N*NB
  3972. *
  3973. IF( .NOT.TPSD ) THEN
  3974. *
  3975. * Least-Squares Problem min || A * X - B ||
  3976. *
  3977. * B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
  3978. *
  3979. CALL DORMQR( 'Left', 'Transpose', M, NRHS, N, A, LDA,
  3980. $ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
  3981. $ INFO )
  3982. *
  3983. * workspace at least NRHS, optimally NRHS*NB
  3984. *
  3985. * B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)
  3986. *
  3987. CALL DTRTRS( 'Upper', 'No transpose', 'Non-unit', N, NRHS,
  3988. $ A, LDA, B, LDB, INFO )
  3989. *
  3990. IF( INFO.GT.0 ) THEN
  3991. RETURN
  3992. END IF
  3993. *
  3994. SCLLEN = N
  3995. *
  3996. ELSE
  3997. *
  3998. * Overdetermined system of equations A' * X = B
  3999. *
  4000. * B(1:N,1:NRHS) := inv(R') * B(1:N,1:NRHS)
  4001. *
  4002. CALL DTRTRS( 'Upper', 'Transpose', 'Non-unit', N, NRHS,
  4003. $ A, LDA, B, LDB, INFO )
  4004. *
  4005. IF( INFO.GT.0 ) THEN
  4006. RETURN
  4007. END IF
  4008. *
  4009. * B(N+1:M,1:NRHS) = ZERO
  4010. *
  4011. DO 20 J = 1, NRHS
  4012. DO 10 I = N + 1, M
  4013. B( I, J ) = ZERO
  4014. 10 CONTINUE
  4015. 20 CONTINUE
  4016. *
  4017. * B(1:M,1:NRHS) := Q(1:N,:) * B(1:N,1:NRHS)
  4018. *
  4019. CALL DORMQR( 'Left', 'No transpose', M, NRHS, N, A, LDA,
  4020. $ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
  4021. $ INFO )
  4022. *
  4023. * workspace at least NRHS, optimally NRHS*NB
  4024. *
  4025. SCLLEN = M
  4026. *
  4027. END IF
  4028. *
  4029. ELSE
  4030. *
  4031. * Compute LQ factorization of A
  4032. *
  4033. CALL DGELQF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ), LWORK-MN,
  4034. $ INFO )
  4035. *
  4036. * workspace at least M, optimally M*NB.
  4037. *
  4038. IF( .NOT.TPSD ) THEN
  4039. *
  4040. * underdetermined system of equations A * X = B
  4041. *
  4042. * B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)
  4043. *
  4044. CALL DTRTRS( 'Lower', 'No transpose', 'Non-unit', M, NRHS,
  4045. $ A, LDA, B, LDB, INFO )
  4046. *
  4047. IF( INFO.GT.0 ) THEN
  4048. RETURN
  4049. END IF
  4050. *
  4051. * B(M+1:N,1:NRHS) = 0
  4052. *
  4053. DO 40 J = 1, NRHS
  4054. DO 30 I = M + 1, N
  4055. B( I, J ) = ZERO
  4056. 30 CONTINUE
  4057. 40 CONTINUE
  4058. *
  4059. * B(1:N,1:NRHS) := Q(1:N,:)' * B(1:M,1:NRHS)
  4060. *
  4061. CALL DORMLQ( 'Left', 'Transpose', N, NRHS, M, A, LDA,
  4062. $ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
  4063. $ INFO )
  4064. *
  4065. * workspace at least NRHS, optimally NRHS*NB
  4066. *
  4067. SCLLEN = N
  4068. *
  4069. ELSE
  4070. *
  4071. * overdetermined system min || A' * X - B ||
  4072. *
  4073. * B(1:N,1:NRHS) := Q * B(1:N,1:NRHS)
  4074. *
  4075. CALL DORMLQ( 'Left', 'No transpose', N, NRHS, M, A, LDA,
  4076. $ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
  4077. $ INFO )
  4078. *
  4079. * workspace at least NRHS, optimally NRHS*NB
  4080. *
  4081. * B(1:M,1:NRHS) := inv(L') * B(1:M,1:NRHS)
  4082. *
  4083. CALL DTRTRS( 'Lower', 'Transpose', 'Non-unit', M, NRHS,
  4084. $ A, LDA, B, LDB, INFO )
  4085. *
  4086. IF( INFO.GT.0 ) THEN
  4087. RETURN
  4088. END IF
  4089. *
  4090. SCLLEN = M
  4091. *
  4092. END IF
  4093. *
  4094. END IF
  4095. *
  4096. * Undo scaling
  4097. *
  4098. IF( IASCL.EQ.1 ) THEN
  4099. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, SCLLEN, NRHS, B, LDB,
  4100. $ INFO )
  4101. ELSE IF( IASCL.EQ.2 ) THEN
  4102. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, SCLLEN, NRHS, B, LDB,
  4103. $ INFO )
  4104. END IF
  4105. IF( IBSCL.EQ.1 ) THEN
  4106. CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, SCLLEN, NRHS, B, LDB,
  4107. $ INFO )
  4108. ELSE IF( IBSCL.EQ.2 ) THEN
  4109. CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, SCLLEN, NRHS, B, LDB,
  4110. $ INFO )
  4111. END IF
  4112. *
  4113. 50 CONTINUE
  4114. WORK( 1 ) = DBLE( WSIZE )
  4115. *
  4116. RETURN
  4117. *
  4118. * End of DGELS
  4119. *
  4120. END
  4121. SUBROUTINE DGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
  4122. $ WORK, LWORK, IWORK, INFO )
  4123. *
  4124. * -- LAPACK driver routine (version 3.1) --
  4125. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  4126. * November 2006
  4127. *
  4128. * .. Scalar Arguments ..
  4129. INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
  4130. DOUBLE PRECISION RCOND
  4131. * ..
  4132. * .. Array Arguments ..
  4133. INTEGER IWORK( * )
  4134. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
  4135. * ..
  4136. *
  4137. * Purpose
  4138. * =======
  4139. *
  4140. * DGELSD computes the minimum-norm solution to a real linear least
  4141. * squares problem:
  4142. * minimize 2-norm(| b - A*x |)
  4143. * using the singular value decomposition (SVD) of A. A is an M-by-N
  4144. * matrix which may be rank-deficient.
  4145. *
  4146. * Several right hand side vectors b and solution vectors x can be
  4147. * handled in a single call; they are stored as the columns of the
  4148. * M-by-NRHS right hand side matrix B and the N-by-NRHS solution
  4149. * matrix X.
  4150. *
  4151. * The problem is solved in three steps:
  4152. * (1) Reduce the coefficient matrix A to bidiagonal form with
  4153. * Householder transformations, reducing the original problem
  4154. * into a "bidiagonal least squares problem" (BLS)
  4155. * (2) Solve the BLS using a divide and conquer approach.
  4156. * (3) Apply back all the Householder tranformations to solve
  4157. * the original least squares problem.
  4158. *
  4159. * The effective rank of A is determined by treating as zero those
  4160. * singular values which are less than RCOND times the largest singular
  4161. * value.
  4162. *
  4163. * The divide and conquer algorithm makes very mild assumptions about
  4164. * floating point arithmetic. It will work on machines with a guard
  4165. * digit in add/subtract, or on those binary machines without guard
  4166. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  4167. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  4168. * without guard digits, but we know of none.
  4169. *
  4170. * Arguments
  4171. * =========
  4172. *
  4173. * M (input) INTEGER
  4174. * The number of rows of A. M >= 0.
  4175. *
  4176. * N (input) INTEGER
  4177. * The number of columns of A. N >= 0.
  4178. *
  4179. * NRHS (input) INTEGER
  4180. * The number of right hand sides, i.e., the number of columns
  4181. * of the matrices B and X. NRHS >= 0.
  4182. *
  4183. * A (input) DOUBLE PRECISION array, dimension (LDA,N)
  4184. * On entry, the M-by-N matrix A.
  4185. * On exit, A has been destroyed.
  4186. *
  4187. * LDA (input) INTEGER
  4188. * The leading dimension of the array A. LDA >= max(1,M).
  4189. *
  4190. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  4191. * On entry, the M-by-NRHS right hand side matrix B.
  4192. * On exit, B is overwritten by the N-by-NRHS solution
  4193. * matrix X. If m >= n and RANK = n, the residual
  4194. * sum-of-squares for the solution in the i-th column is given
  4195. * by the sum of squares of elements n+1:m in that column.
  4196. *
  4197. * LDB (input) INTEGER
  4198. * The leading dimension of the array B. LDB >= max(1,max(M,N)).
  4199. *
  4200. * S (output) DOUBLE PRECISION array, dimension (min(M,N))
  4201. * The singular values of A in decreasing order.
  4202. * The condition number of A in the 2-norm = S(1)/S(min(m,n)).
  4203. *
  4204. * RCOND (input) DOUBLE PRECISION
  4205. * RCOND is used to determine the effective rank of A.
  4206. * Singular values S(i) <= RCOND*S(1) are treated as zero.
  4207. * If RCOND < 0, machine precision is used instead.
  4208. *
  4209. * RANK (output) INTEGER
  4210. * The effective rank of A, i.e., the number of singular values
  4211. * which are greater than RCOND*S(1).
  4212. *
  4213. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  4214. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  4215. *
  4216. * LWORK (input) INTEGER
  4217. * The dimension of the array WORK. LWORK must be at least 1.
  4218. * The exact minimum amount of workspace needed depends on M,
  4219. * N and NRHS. As long as LWORK is at least
  4220. * 12*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2,
  4221. * if M is greater than or equal to N or
  4222. * 12*M + 2*M*SMLSIZ + 8*M*NLVL + M*NRHS + (SMLSIZ+1)**2,
  4223. * if M is less than N, the code will execute correctly.
  4224. * SMLSIZ is returned by ILAENV and is equal to the maximum
  4225. * size of the subproblems at the bottom of the computation
  4226. * tree (usually about 25), and
  4227. * NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
  4228. * For good performance, LWORK should generally be larger.
  4229. *
  4230. * If LWORK = -1, then a workspace query is assumed; the routine
  4231. * only calculates the optimal size of the WORK array, returns
  4232. * this value as the first entry of the WORK array, and no error
  4233. * message related to LWORK is issued by XERBLA.
  4234. *
  4235. * IWORK (workspace) INTEGER array, dimension (MAX(1,LIWORK))
  4236. * LIWORK >= 3 * MINMN * NLVL + 11 * MINMN,
  4237. * where MINMN = MIN( M,N ).
  4238. *
  4239. * INFO (output) INTEGER
  4240. * = 0: successful exit
  4241. * < 0: if INFO = -i, the i-th argument had an illegal value.
  4242. * > 0: the algorithm for computing the SVD failed to converge;
  4243. * if INFO = i, i off-diagonal elements of an intermediate
  4244. * bidiagonal form did not converge to zero.
  4245. *
  4246. * Further Details
  4247. * ===============
  4248. *
  4249. * Based on contributions by
  4250. * Ming Gu and Ren-Cang Li, Computer Science Division, University of
  4251. * California at Berkeley, USA
  4252. * Osni Marques, LBNL/NERSC, USA
  4253. *
  4254. * =====================================================================
  4255. *
  4256. * .. Parameters ..
  4257. DOUBLE PRECISION ZERO, ONE, TWO
  4258. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
  4259. * ..
  4260. * .. Local Scalars ..
  4261. LOGICAL LQUERY
  4262. INTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
  4263. $ LDWORK, MAXMN, MAXWRK, MINMN, MINWRK, MM,
  4264. $ MNTHR, NLVL, NWORK, SMLSIZ, WLALSD
  4265. DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
  4266. * ..
  4267. * .. External Subroutines ..
  4268. EXTERNAL DGEBRD, DGELQF, DGEQRF, DLABAD, DLACPY, DLALSD,
  4269. $ DLASCL, DLASET, DORMBR, DORMLQ, DORMQR, XERBLA
  4270. * ..
  4271. * .. External Functions ..
  4272. INTEGER ILAENV
  4273. DOUBLE PRECISION DLAMCH, DLANGE
  4274. EXTERNAL ILAENV, DLAMCH, DLANGE
  4275. * ..
  4276. * .. Intrinsic Functions ..
  4277. INTRINSIC DBLE, INT, LOG, MAX, MIN
  4278. * ..
  4279. * .. Executable Statements ..
  4280. *
  4281. * Test the input arguments.
  4282. *
  4283. INFO = 0
  4284. MINMN = MIN( M, N )
  4285. MAXMN = MAX( M, N )
  4286. MNTHR = ILAENV( 6, 'DGELSD', ' ', M, N, NRHS, -1 )
  4287. LQUERY = ( LWORK.EQ.-1 )
  4288. IF( M.LT.0 ) THEN
  4289. INFO = -1
  4290. ELSE IF( N.LT.0 ) THEN
  4291. INFO = -2
  4292. ELSE IF( NRHS.LT.0 ) THEN
  4293. INFO = -3
  4294. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  4295. INFO = -5
  4296. ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
  4297. INFO = -7
  4298. END IF
  4299. *
  4300. SMLSIZ = ILAENV( 9, 'DGELSD', ' ', 0, 0, 0, 0 )
  4301. *
  4302. * Compute workspace.
  4303. * (Note: Comments in the code beginning "Workspace:" describe the
  4304. * minimal amount of workspace needed at that point in the code,
  4305. * as well as the preferred amount for good performance.
  4306. * NB refers to the optimal block size for the immediately
  4307. * following subroutine, as returned by ILAENV.)
  4308. *
  4309. MINWRK = 1
  4310. MINMN = MAX( 1, MINMN )
  4311. NLVL = MAX( INT( LOG( DBLE( MINMN ) / DBLE( SMLSIZ+1 ) ) /
  4312. $ LOG( TWO ) ) + 1, 0 )
  4313. *
  4314. IF( INFO.EQ.0 ) THEN
  4315. MAXWRK = 0
  4316. MM = M
  4317. IF( M.GE.N .AND. M.GE.MNTHR ) THEN
  4318. *
  4319. * Path 1a - overdetermined, with many more rows than columns.
  4320. *
  4321. MM = N
  4322. MAXWRK = MAX( MAXWRK, N+N*ILAENV( 1, 'DGEQRF', ' ', M, N,
  4323. $ -1, -1 ) )
  4324. MAXWRK = MAX( MAXWRK, N+NRHS*
  4325. $ ILAENV( 1, 'DORMQR', 'LT', M, NRHS, N, -1 ) )
  4326. END IF
  4327. IF( M.GE.N ) THEN
  4328. *
  4329. * Path 1 - overdetermined or exactly determined.
  4330. *
  4331. MAXWRK = MAX( MAXWRK, 3*N+( MM+N )*
  4332. $ ILAENV( 1, 'DGEBRD', ' ', MM, N, -1, -1 ) )
  4333. MAXWRK = MAX( MAXWRK, 3*N+NRHS*
  4334. $ ILAENV( 1, 'DORMBR', 'QLT', MM, NRHS, N, -1 ) )
  4335. MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
  4336. $ ILAENV( 1, 'DORMBR', 'PLN', N, NRHS, N, -1 ) )
  4337. WLALSD = 9*N+2*N*SMLSIZ+8*N*NLVL+N*NRHS+(SMLSIZ+1)**2
  4338. MAXWRK = MAX( MAXWRK, 3*N+WLALSD )
  4339. MINWRK = MAX( 3*N+MM, 3*N+NRHS, 3*N+WLALSD )
  4340. END IF
  4341. IF( N.GT.M ) THEN
  4342. WLALSD = 9*M+2*M*SMLSIZ+8*M*NLVL+M*NRHS+(SMLSIZ+1)**2
  4343. IF( N.GE.MNTHR ) THEN
  4344. *
  4345. * Path 2a - underdetermined, with many more columns
  4346. * than rows.
  4347. *
  4348. MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  4349. MAXWRK = MAX( MAXWRK, M*M+4*M+2*M*
  4350. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  4351. MAXWRK = MAX( MAXWRK, M*M+4*M+NRHS*
  4352. $ ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, M, -1 ) )
  4353. MAXWRK = MAX( MAXWRK, M*M+4*M+( M-1 )*
  4354. $ ILAENV( 1, 'DORMBR', 'PLN', M, NRHS, M, -1 ) )
  4355. IF( NRHS.GT.1 ) THEN
  4356. MAXWRK = MAX( MAXWRK, M*M+M+M*NRHS )
  4357. ELSE
  4358. MAXWRK = MAX( MAXWRK, M*M+2*M )
  4359. END IF
  4360. MAXWRK = MAX( MAXWRK, M+NRHS*
  4361. $ ILAENV( 1, 'DORMLQ', 'LT', N, NRHS, M, -1 ) )
  4362. MAXWRK = MAX( MAXWRK, M*M+4*M+WLALSD )
  4363. ELSE
  4364. *
  4365. * Path 2 - remaining underdetermined cases.
  4366. *
  4367. MAXWRK = 3*M + ( N+M )*ILAENV( 1, 'DGEBRD', ' ', M, N,
  4368. $ -1, -1 )
  4369. MAXWRK = MAX( MAXWRK, 3*M+NRHS*
  4370. $ ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, N, -1 ) )
  4371. MAXWRK = MAX( MAXWRK, 3*M+M*
  4372. $ ILAENV( 1, 'DORMBR', 'PLN', N, NRHS, M, -1 ) )
  4373. MAXWRK = MAX( MAXWRK, 3*M+WLALSD )
  4374. END IF
  4375. MINWRK = MAX( 3*M+NRHS, 3*M+M, 3*M+WLALSD )
  4376. END IF
  4377. MINWRK = MIN( MINWRK, MAXWRK )
  4378. WORK( 1 ) = MAXWRK
  4379. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  4380. INFO = -12
  4381. END IF
  4382. END IF
  4383. *
  4384. IF( INFO.NE.0 ) THEN
  4385. CALL XERBLA( 'DGELSD', -INFO )
  4386. RETURN
  4387. ELSE IF( LQUERY ) THEN
  4388. GO TO 10
  4389. END IF
  4390. *
  4391. * Quick return if possible.
  4392. *
  4393. IF( M.EQ.0 .OR. N.EQ.0 ) THEN
  4394. RANK = 0
  4395. RETURN
  4396. END IF
  4397. *
  4398. * Get machine parameters.
  4399. *
  4400. EPS = DLAMCH( 'P' )
  4401. SFMIN = DLAMCH( 'S' )
  4402. SMLNUM = SFMIN / EPS
  4403. BIGNUM = ONE / SMLNUM
  4404. CALL DLABAD( SMLNUM, BIGNUM )
  4405. *
  4406. * Scale A if max entry outside range [SMLNUM,BIGNUM].
  4407. *
  4408. ANRM = DLANGE( 'M', M, N, A, LDA, WORK )
  4409. IASCL = 0
  4410. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  4411. *
  4412. * Scale matrix norm up to SMLNUM.
  4413. *
  4414. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
  4415. IASCL = 1
  4416. ELSE IF( ANRM.GT.BIGNUM ) THEN
  4417. *
  4418. * Scale matrix norm down to BIGNUM.
  4419. *
  4420. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
  4421. IASCL = 2
  4422. ELSE IF( ANRM.EQ.ZERO ) THEN
  4423. *
  4424. * Matrix all zero. Return zero solution.
  4425. *
  4426. CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
  4427. CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )
  4428. RANK = 0
  4429. GO TO 10
  4430. END IF
  4431. *
  4432. * Scale B if max entry outside range [SMLNUM,BIGNUM].
  4433. *
  4434. BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )
  4435. IBSCL = 0
  4436. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  4437. *
  4438. * Scale matrix norm up to SMLNUM.
  4439. *
  4440. CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
  4441. IBSCL = 1
  4442. ELSE IF( BNRM.GT.BIGNUM ) THEN
  4443. *
  4444. * Scale matrix norm down to BIGNUM.
  4445. *
  4446. CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
  4447. IBSCL = 2
  4448. END IF
  4449. *
  4450. * If M < N make sure certain entries of B are zero.
  4451. *
  4452. IF( M.LT.N )
  4453. $ CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
  4454. *
  4455. * Overdetermined case.
  4456. *
  4457. IF( M.GE.N ) THEN
  4458. *
  4459. * Path 1 - overdetermined or exactly determined.
  4460. *
  4461. MM = M
  4462. IF( M.GE.MNTHR ) THEN
  4463. *
  4464. * Path 1a - overdetermined, with many more rows than columns.
  4465. *
  4466. MM = N
  4467. ITAU = 1
  4468. NWORK = ITAU + N
  4469. *
  4470. * Compute A=Q*R.
  4471. * (Workspace: need 2*N, prefer N+N*NB)
  4472. *
  4473. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  4474. $ LWORK-NWORK+1, INFO )
  4475. *
  4476. * Multiply B by transpose(Q).
  4477. * (Workspace: need N+NRHS, prefer N+NRHS*NB)
  4478. *
  4479. CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,
  4480. $ LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
  4481. *
  4482. * Zero out below R.
  4483. *
  4484. IF( N.GT.1 ) THEN
  4485. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
  4486. END IF
  4487. END IF
  4488. *
  4489. IE = 1
  4490. ITAUQ = IE + N
  4491. ITAUP = ITAUQ + N
  4492. NWORK = ITAUP + N
  4493. *
  4494. * Bidiagonalize R in A.
  4495. * (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)
  4496. *
  4497. CALL DGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  4498. $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
  4499. $ INFO )
  4500. *
  4501. * Multiply B by transpose of left bidiagonalizing vectors of R.
  4502. * (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)
  4503. *
  4504. CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
  4505. $ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
  4506. *
  4507. * Solve the bidiagonal least squares problem.
  4508. *
  4509. CALL DLALSD( 'U', SMLSIZ, N, NRHS, S, WORK( IE ), B, LDB,
  4510. $ RCOND, RANK, WORK( NWORK ), IWORK, INFO )
  4511. IF( INFO.NE.0 ) THEN
  4512. GO TO 10
  4513. END IF
  4514. *
  4515. * Multiply B by right bidiagonalizing vectors of R.
  4516. *
  4517. CALL DORMBR( 'P', 'L', 'N', N, NRHS, N, A, LDA, WORK( ITAUP ),
  4518. $ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
  4519. *
  4520. ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+
  4521. $ MAX( M, 2*M-4, NRHS, N-3*M, WLALSD ) ) THEN
  4522. *
  4523. * Path 2a - underdetermined, with many more columns than rows
  4524. * and sufficient workspace for an efficient algorithm.
  4525. *
  4526. LDWORK = M
  4527. IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
  4528. $ M*LDA+M+M*NRHS, 4*M+M*LDA+WLALSD ) )LDWORK = LDA
  4529. ITAU = 1
  4530. NWORK = M + 1
  4531. *
  4532. * Compute A=L*Q.
  4533. * (Workspace: need 2*M, prefer M+M*NB)
  4534. *
  4535. CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  4536. $ LWORK-NWORK+1, INFO )
  4537. IL = NWORK
  4538. *
  4539. * Copy L to WORK(IL), zeroing out above its diagonal.
  4540. *
  4541. CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
  4542. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),
  4543. $ LDWORK )
  4544. IE = IL + LDWORK*M
  4545. ITAUQ = IE + M
  4546. ITAUP = ITAUQ + M
  4547. NWORK = ITAUP + M
  4548. *
  4549. * Bidiagonalize L in WORK(IL).
  4550. * (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)
  4551. *
  4552. CALL DGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),
  4553. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
  4554. $ LWORK-NWORK+1, INFO )
  4555. *
  4556. * Multiply B by transpose of left bidiagonalizing vectors of L.
  4557. * (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
  4558. *
  4559. CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,
  4560. $ WORK( ITAUQ ), B, LDB, WORK( NWORK ),
  4561. $ LWORK-NWORK+1, INFO )
  4562. *
  4563. * Solve the bidiagonal least squares problem.
  4564. *
  4565. CALL DLALSD( 'U', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,
  4566. $ RCOND, RANK, WORK( NWORK ), IWORK, INFO )
  4567. IF( INFO.NE.0 ) THEN
  4568. GO TO 10
  4569. END IF
  4570. *
  4571. * Multiply B by right bidiagonalizing vectors of L.
  4572. *
  4573. CALL DORMBR( 'P', 'L', 'N', M, NRHS, M, WORK( IL ), LDWORK,
  4574. $ WORK( ITAUP ), B, LDB, WORK( NWORK ),
  4575. $ LWORK-NWORK+1, INFO )
  4576. *
  4577. * Zero out below first M rows of B.
  4578. *
  4579. CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
  4580. NWORK = ITAU + M
  4581. *
  4582. * Multiply transpose(Q) by B.
  4583. * (Workspace: need M+NRHS, prefer M+NRHS*NB)
  4584. *
  4585. CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,
  4586. $ LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
  4587. *
  4588. ELSE
  4589. *
  4590. * Path 2 - remaining underdetermined cases.
  4591. *
  4592. IE = 1
  4593. ITAUQ = IE + M
  4594. ITAUP = ITAUQ + M
  4595. NWORK = ITAUP + M
  4596. *
  4597. * Bidiagonalize A.
  4598. * (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
  4599. *
  4600. CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  4601. $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
  4602. $ INFO )
  4603. *
  4604. * Multiply B by transpose of left bidiagonalizing vectors.
  4605. * (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)
  4606. *
  4607. CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),
  4608. $ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
  4609. *
  4610. * Solve the bidiagonal least squares problem.
  4611. *
  4612. CALL DLALSD( 'L', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,
  4613. $ RCOND, RANK, WORK( NWORK ), IWORK, INFO )
  4614. IF( INFO.NE.0 ) THEN
  4615. GO TO 10
  4616. END IF
  4617. *
  4618. * Multiply B by right bidiagonalizing vectors of A.
  4619. *
  4620. CALL DORMBR( 'P', 'L', 'N', N, NRHS, M, A, LDA, WORK( ITAUP ),
  4621. $ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
  4622. *
  4623. END IF
  4624. *
  4625. * Undo scaling.
  4626. *
  4627. IF( IASCL.EQ.1 ) THEN
  4628. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
  4629. CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
  4630. $ INFO )
  4631. ELSE IF( IASCL.EQ.2 ) THEN
  4632. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
  4633. CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
  4634. $ INFO )
  4635. END IF
  4636. IF( IBSCL.EQ.1 ) THEN
  4637. CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
  4638. ELSE IF( IBSCL.EQ.2 ) THEN
  4639. CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
  4640. END IF
  4641. *
  4642. 10 CONTINUE
  4643. WORK( 1 ) = MAXWRK
  4644. RETURN
  4645. *
  4646. * End of DGELSD
  4647. *
  4648. END
  4649. SUBROUTINE DGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
  4650. $ WORK, LWORK, INFO )
  4651. *
  4652. * -- LAPACK driver routine (version 3.1) --
  4653. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  4654. * November 2006
  4655. *
  4656. * .. Scalar Arguments ..
  4657. INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
  4658. DOUBLE PRECISION RCOND
  4659. * ..
  4660. * .. Array Arguments ..
  4661. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
  4662. * ..
  4663. *
  4664. * Purpose
  4665. * =======
  4666. *
  4667. * DGELSS computes the minimum norm solution to a real linear least
  4668. * squares problem:
  4669. *
  4670. * Minimize 2-norm(| b - A*x |).
  4671. *
  4672. * using the singular value decomposition (SVD) of A. A is an M-by-N
  4673. * matrix which may be rank-deficient.
  4674. *
  4675. * Several right hand side vectors b and solution vectors x can be
  4676. * handled in a single call; they are stored as the columns of the
  4677. * M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix
  4678. * X.
  4679. *
  4680. * The effective rank of A is determined by treating as zero those
  4681. * singular values which are less than RCOND times the largest singular
  4682. * value.
  4683. *
  4684. * Arguments
  4685. * =========
  4686. *
  4687. * M (input) INTEGER
  4688. * The number of rows of the matrix A. M >= 0.
  4689. *
  4690. * N (input) INTEGER
  4691. * The number of columns of the matrix A. N >= 0.
  4692. *
  4693. * NRHS (input) INTEGER
  4694. * The number of right hand sides, i.e., the number of columns
  4695. * of the matrices B and X. NRHS >= 0.
  4696. *
  4697. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  4698. * On entry, the M-by-N matrix A.
  4699. * On exit, the first min(m,n) rows of A are overwritten with
  4700. * its right singular vectors, stored rowwise.
  4701. *
  4702. * LDA (input) INTEGER
  4703. * The leading dimension of the array A. LDA >= max(1,M).
  4704. *
  4705. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  4706. * On entry, the M-by-NRHS right hand side matrix B.
  4707. * On exit, B is overwritten by the N-by-NRHS solution
  4708. * matrix X. If m >= n and RANK = n, the residual
  4709. * sum-of-squares for the solution in the i-th column is given
  4710. * by the sum of squares of elements n+1:m in that column.
  4711. *
  4712. * LDB (input) INTEGER
  4713. * The leading dimension of the array B. LDB >= max(1,max(M,N)).
  4714. *
  4715. * S (output) DOUBLE PRECISION array, dimension (min(M,N))
  4716. * The singular values of A in decreasing order.
  4717. * The condition number of A in the 2-norm = S(1)/S(min(m,n)).
  4718. *
  4719. * RCOND (input) DOUBLE PRECISION
  4720. * RCOND is used to determine the effective rank of A.
  4721. * Singular values S(i) <= RCOND*S(1) are treated as zero.
  4722. * If RCOND < 0, machine precision is used instead.
  4723. *
  4724. * RANK (output) INTEGER
  4725. * The effective rank of A, i.e., the number of singular values
  4726. * which are greater than RCOND*S(1).
  4727. *
  4728. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  4729. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  4730. *
  4731. * LWORK (input) INTEGER
  4732. * The dimension of the array WORK. LWORK >= 1, and also:
  4733. * LWORK >= 3*min(M,N) + max( 2*min(M,N), max(M,N), NRHS )
  4734. * For good performance, LWORK should generally be larger.
  4735. *
  4736. * If LWORK = -1, then a workspace query is assumed; the routine
  4737. * only calculates the optimal size of the WORK array, returns
  4738. * this value as the first entry of the WORK array, and no error
  4739. * message related to LWORK is issued by XERBLA.
  4740. *
  4741. * INFO (output) INTEGER
  4742. * = 0: successful exit
  4743. * < 0: if INFO = -i, the i-th argument had an illegal value.
  4744. * > 0: the algorithm for computing the SVD failed to converge;
  4745. * if INFO = i, i off-diagonal elements of an intermediate
  4746. * bidiagonal form did not converge to zero.
  4747. *
  4748. * =====================================================================
  4749. *
  4750. * .. Parameters ..
  4751. DOUBLE PRECISION ZERO, ONE
  4752. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  4753. * ..
  4754. * .. Local Scalars ..
  4755. LOGICAL LQUERY
  4756. INTEGER BDSPAC, BL, CHUNK, I, IASCL, IBSCL, IE, IL,
  4757. $ ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,
  4758. $ MAXWRK, MINMN, MINWRK, MM, MNTHR
  4759. DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
  4760. * ..
  4761. * .. Local Arrays ..
  4762. DOUBLE PRECISION VDUM( 1 )
  4763. * ..
  4764. * .. External Subroutines ..
  4765. EXTERNAL DBDSQR, DCOPY, DGEBRD, DGELQF, DGEMM, DGEMV,
  4766. $ DGEQRF, DLABAD, DLACPY, DLASCL, DLASET, DORGBR,
  4767. $ DORMBR, DORMLQ, DORMQR, DRSCL, XERBLA
  4768. * ..
  4769. * .. External Functions ..
  4770. INTEGER ILAENV
  4771. DOUBLE PRECISION DLAMCH, DLANGE
  4772. EXTERNAL ILAENV, DLAMCH, DLANGE
  4773. * ..
  4774. * .. Intrinsic Functions ..
  4775. INTRINSIC MAX, MIN
  4776. * ..
  4777. * .. Executable Statements ..
  4778. *
  4779. * Test the input arguments
  4780. *
  4781. INFO = 0
  4782. MINMN = MIN( M, N )
  4783. MAXMN = MAX( M, N )
  4784. LQUERY = ( LWORK.EQ.-1 )
  4785. IF( M.LT.0 ) THEN
  4786. INFO = -1
  4787. ELSE IF( N.LT.0 ) THEN
  4788. INFO = -2
  4789. ELSE IF( NRHS.LT.0 ) THEN
  4790. INFO = -3
  4791. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  4792. INFO = -5
  4793. ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN
  4794. INFO = -7
  4795. END IF
  4796. *
  4797. * Compute workspace
  4798. * (Note: Comments in the code beginning "Workspace:" describe the
  4799. * minimal amount of workspace needed at that point in the code,
  4800. * as well as the preferred amount for good performance.
  4801. * NB refers to the optimal block size for the immediately
  4802. * following subroutine, as returned by ILAENV.)
  4803. *
  4804. IF( INFO.EQ.0 ) THEN
  4805. MINWRK = 1
  4806. MAXWRK = 1
  4807. IF( MINMN.GT.0 ) THEN
  4808. MM = M
  4809. MNTHR = ILAENV( 6, 'DGELSS', ' ', M, N, NRHS, -1 )
  4810. IF( M.GE.N .AND. M.GE.MNTHR ) THEN
  4811. *
  4812. * Path 1a - overdetermined, with many more rows than
  4813. * columns
  4814. *
  4815. MM = N
  4816. MAXWRK = MAX( MAXWRK, N + N*ILAENV( 1, 'DGEQRF', ' ', M,
  4817. $ N, -1, -1 ) )
  4818. MAXWRK = MAX( MAXWRK, N + NRHS*ILAENV( 1, 'DORMQR', 'LT',
  4819. $ M, NRHS, N, -1 ) )
  4820. END IF
  4821. IF( M.GE.N ) THEN
  4822. *
  4823. * Path 1 - overdetermined or exactly determined
  4824. *
  4825. * Compute workspace needed for DBDSQR
  4826. *
  4827. BDSPAC = MAX( 1, 5*N )
  4828. MAXWRK = MAX( MAXWRK, 3*N + ( MM + N )*ILAENV( 1,
  4829. $ 'DGEBRD', ' ', MM, N, -1, -1 ) )
  4830. MAXWRK = MAX( MAXWRK, 3*N + NRHS*ILAENV( 1, 'DORMBR',
  4831. $ 'QLT', MM, NRHS, N, -1 ) )
  4832. MAXWRK = MAX( MAXWRK, 3*N + ( N - 1 )*ILAENV( 1,
  4833. $ 'DORGBR', 'P', N, N, N, -1 ) )
  4834. MAXWRK = MAX( MAXWRK, BDSPAC )
  4835. MAXWRK = MAX( MAXWRK, N*NRHS )
  4836. MINWRK = MAX( 3*N + MM, 3*N + NRHS, BDSPAC )
  4837. MAXWRK = MAX( MINWRK, MAXWRK )
  4838. END IF
  4839. IF( N.GT.M ) THEN
  4840. *
  4841. * Compute workspace needed for DBDSQR
  4842. *
  4843. BDSPAC = MAX( 1, 5*M )
  4844. MINWRK = MAX( 3*M+NRHS, 3*M+N, BDSPAC )
  4845. IF( N.GE.MNTHR ) THEN
  4846. *
  4847. * Path 2a - underdetermined, with many more columns
  4848. * than rows
  4849. *
  4850. MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
  4851. $ -1 )
  4852. MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
  4853. $ 'DGEBRD', ' ', M, M, -1, -1 ) )
  4854. MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
  4855. $ 'DORMBR', 'QLT', M, NRHS, M, -1 ) )
  4856. MAXWRK = MAX( MAXWRK, M*M + 4*M +
  4857. $ ( M - 1 )*ILAENV( 1, 'DORGBR', 'P', M,
  4858. $ M, M, -1 ) )
  4859. MAXWRK = MAX( MAXWRK, M*M + M + BDSPAC )
  4860. IF( NRHS.GT.1 ) THEN
  4861. MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
  4862. ELSE
  4863. MAXWRK = MAX( MAXWRK, M*M + 2*M )
  4864. END IF
  4865. MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'DORMLQ',
  4866. $ 'LT', N, NRHS, M, -1 ) )
  4867. ELSE
  4868. *
  4869. * Path 2 - underdetermined
  4870. *
  4871. MAXWRK = 3*M + ( N + M )*ILAENV( 1, 'DGEBRD', ' ', M,
  4872. $ N, -1, -1 )
  4873. MAXWRK = MAX( MAXWRK, 3*M + NRHS*ILAENV( 1, 'DORMBR',
  4874. $ 'QLT', M, NRHS, M, -1 ) )
  4875. MAXWRK = MAX( MAXWRK, 3*M + M*ILAENV( 1, 'DORGBR',
  4876. $ 'P', M, N, M, -1 ) )
  4877. MAXWRK = MAX( MAXWRK, BDSPAC )
  4878. MAXWRK = MAX( MAXWRK, N*NRHS )
  4879. END IF
  4880. END IF
  4881. MAXWRK = MAX( MINWRK, MAXWRK )
  4882. END IF
  4883. WORK( 1 ) = MAXWRK
  4884. *
  4885. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
  4886. $ INFO = -12
  4887. END IF
  4888. *
  4889. IF( INFO.NE.0 ) THEN
  4890. CALL XERBLA( 'DGELSS', -INFO )
  4891. RETURN
  4892. ELSE IF( LQUERY ) THEN
  4893. RETURN
  4894. END IF
  4895. *
  4896. * Quick return if possible
  4897. *
  4898. IF( M.EQ.0 .OR. N.EQ.0 ) THEN
  4899. RANK = 0
  4900. RETURN
  4901. END IF
  4902. *
  4903. * Get machine parameters
  4904. *
  4905. EPS = DLAMCH( 'P' )
  4906. SFMIN = DLAMCH( 'S' )
  4907. SMLNUM = SFMIN / EPS
  4908. BIGNUM = ONE / SMLNUM
  4909. CALL DLABAD( SMLNUM, BIGNUM )
  4910. *
  4911. * Scale A if max element outside range [SMLNUM,BIGNUM]
  4912. *
  4913. ANRM = DLANGE( 'M', M, N, A, LDA, WORK )
  4914. IASCL = 0
  4915. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  4916. *
  4917. * Scale matrix norm up to SMLNUM
  4918. *
  4919. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
  4920. IASCL = 1
  4921. ELSE IF( ANRM.GT.BIGNUM ) THEN
  4922. *
  4923. * Scale matrix norm down to BIGNUM
  4924. *
  4925. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
  4926. IASCL = 2
  4927. ELSE IF( ANRM.EQ.ZERO ) THEN
  4928. *
  4929. * Matrix all zero. Return zero solution.
  4930. *
  4931. CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
  4932. CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )
  4933. RANK = 0
  4934. GO TO 70
  4935. END IF
  4936. *
  4937. * Scale B if max element outside range [SMLNUM,BIGNUM]
  4938. *
  4939. BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )
  4940. IBSCL = 0
  4941. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  4942. *
  4943. * Scale matrix norm up to SMLNUM
  4944. *
  4945. CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
  4946. IBSCL = 1
  4947. ELSE IF( BNRM.GT.BIGNUM ) THEN
  4948. *
  4949. * Scale matrix norm down to BIGNUM
  4950. *
  4951. CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
  4952. IBSCL = 2
  4953. END IF
  4954. *
  4955. * Overdetermined case
  4956. *
  4957. IF( M.GE.N ) THEN
  4958. *
  4959. * Path 1 - overdetermined or exactly determined
  4960. *
  4961. MM = M
  4962. IF( M.GE.MNTHR ) THEN
  4963. *
  4964. * Path 1a - overdetermined, with many more rows than columns
  4965. *
  4966. MM = N
  4967. ITAU = 1
  4968. IWORK = ITAU + N
  4969. *
  4970. * Compute A=Q*R
  4971. * (Workspace: need 2*N, prefer N+N*NB)
  4972. *
  4973. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
  4974. $ LWORK-IWORK+1, INFO )
  4975. *
  4976. * Multiply B by transpose(Q)
  4977. * (Workspace: need N+NRHS, prefer N+NRHS*NB)
  4978. *
  4979. CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,
  4980. $ LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
  4981. *
  4982. * Zero out below R
  4983. *
  4984. IF( N.GT.1 )
  4985. $ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
  4986. END IF
  4987. *
  4988. IE = 1
  4989. ITAUQ = IE + N
  4990. ITAUP = ITAUQ + N
  4991. IWORK = ITAUP + N
  4992. *
  4993. * Bidiagonalize R in A
  4994. * (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)
  4995. *
  4996. CALL DGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  4997. $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
  4998. $ INFO )
  4999. *
  5000. * Multiply B by transpose of left bidiagonalizing vectors of R
  5001. * (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)
  5002. *
  5003. CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
  5004. $ B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
  5005. *
  5006. * Generate right bidiagonalizing vectors of R in A
  5007. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  5008. *
  5009. CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
  5010. $ WORK( IWORK ), LWORK-IWORK+1, INFO )
  5011. IWORK = IE + N
  5012. *
  5013. * Perform bidiagonal QR iteration
  5014. * multiply B by transpose of left singular vectors
  5015. * compute right singular vectors in A
  5016. * (Workspace: need BDSPAC)
  5017. *
  5018. CALL DBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
  5019. $ 1, B, LDB, WORK( IWORK ), INFO )
  5020. IF( INFO.NE.0 )
  5021. $ GO TO 70
  5022. *
  5023. * Multiply B by reciprocals of singular values
  5024. *
  5025. THR = MAX( RCOND*S( 1 ), SFMIN )
  5026. IF( RCOND.LT.ZERO )
  5027. $ THR = MAX( EPS*S( 1 ), SFMIN )
  5028. RANK = 0
  5029. DO 10 I = 1, N
  5030. IF( S( I ).GT.THR ) THEN
  5031. CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )
  5032. RANK = RANK + 1
  5033. ELSE
  5034. CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
  5035. END IF
  5036. 10 CONTINUE
  5037. *
  5038. * Multiply B by right singular vectors
  5039. * (Workspace: need N, prefer N*NRHS)
  5040. *
  5041. IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
  5042. CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, A, LDA, B, LDB, ZERO,
  5043. $ WORK, LDB )
  5044. CALL DLACPY( 'G', N, NRHS, WORK, LDB, B, LDB )
  5045. ELSE IF( NRHS.GT.1 ) THEN
  5046. CHUNK = LWORK / N
  5047. DO 20 I = 1, NRHS, CHUNK
  5048. BL = MIN( NRHS-I+1, CHUNK )
  5049. CALL DGEMM( 'T', 'N', N, BL, N, ONE, A, LDA, B( 1, I ),
  5050. $ LDB, ZERO, WORK, N )
  5051. CALL DLACPY( 'G', N, BL, WORK, N, B( 1, I ), LDB )
  5052. 20 CONTINUE
  5053. ELSE
  5054. CALL DGEMV( 'T', N, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 )
  5055. CALL DCOPY( N, WORK, 1, B, 1 )
  5056. END IF
  5057. *
  5058. ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+
  5059. $ MAX( M, 2*M-4, NRHS, N-3*M ) ) THEN
  5060. *
  5061. * Path 2a - underdetermined, with many more columns than rows
  5062. * and sufficient workspace for an efficient algorithm
  5063. *
  5064. LDWORK = M
  5065. IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
  5066. $ M*LDA+M+M*NRHS ) )LDWORK = LDA
  5067. ITAU = 1
  5068. IWORK = M + 1
  5069. *
  5070. * Compute A=L*Q
  5071. * (Workspace: need 2*M, prefer M+M*NB)
  5072. *
  5073. CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
  5074. $ LWORK-IWORK+1, INFO )
  5075. IL = IWORK
  5076. *
  5077. * Copy L to WORK(IL), zeroing out above it
  5078. *
  5079. CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )
  5080. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),
  5081. $ LDWORK )
  5082. IE = IL + LDWORK*M
  5083. ITAUQ = IE + M
  5084. ITAUP = ITAUQ + M
  5085. IWORK = ITAUP + M
  5086. *
  5087. * Bidiagonalize L in WORK(IL)
  5088. * (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)
  5089. *
  5090. CALL DGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),
  5091. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( IWORK ),
  5092. $ LWORK-IWORK+1, INFO )
  5093. *
  5094. * Multiply B by transpose of left bidiagonalizing vectors of L
  5095. * (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
  5096. *
  5097. CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,
  5098. $ WORK( ITAUQ ), B, LDB, WORK( IWORK ),
  5099. $ LWORK-IWORK+1, INFO )
  5100. *
  5101. * Generate right bidiagonalizing vectors of R in WORK(IL)
  5102. * (Workspace: need M*M+5*M-1, prefer M*M+4*M+(M-1)*NB)
  5103. *
  5104. CALL DORGBR( 'P', M, M, M, WORK( IL ), LDWORK, WORK( ITAUP ),
  5105. $ WORK( IWORK ), LWORK-IWORK+1, INFO )
  5106. IWORK = IE + M
  5107. *
  5108. * Perform bidiagonal QR iteration,
  5109. * computing right singular vectors of L in WORK(IL) and
  5110. * multiplying B by transpose of left singular vectors
  5111. * (Workspace: need M*M+M+BDSPAC)
  5112. *
  5113. CALL DBDSQR( 'U', M, M, 0, NRHS, S, WORK( IE ), WORK( IL ),
  5114. $ LDWORK, A, LDA, B, LDB, WORK( IWORK ), INFO )
  5115. IF( INFO.NE.0 )
  5116. $ GO TO 70
  5117. *
  5118. * Multiply B by reciprocals of singular values
  5119. *
  5120. THR = MAX( RCOND*S( 1 ), SFMIN )
  5121. IF( RCOND.LT.ZERO )
  5122. $ THR = MAX( EPS*S( 1 ), SFMIN )
  5123. RANK = 0
  5124. DO 30 I = 1, M
  5125. IF( S( I ).GT.THR ) THEN
  5126. CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )
  5127. RANK = RANK + 1
  5128. ELSE
  5129. CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
  5130. END IF
  5131. 30 CONTINUE
  5132. IWORK = IE
  5133. *
  5134. * Multiply B by right singular vectors of L in WORK(IL)
  5135. * (Workspace: need M*M+2*M, prefer M*M+M+M*NRHS)
  5136. *
  5137. IF( LWORK.GE.LDB*NRHS+IWORK-1 .AND. NRHS.GT.1 ) THEN
  5138. CALL DGEMM( 'T', 'N', M, NRHS, M, ONE, WORK( IL ), LDWORK,
  5139. $ B, LDB, ZERO, WORK( IWORK ), LDB )
  5140. CALL DLACPY( 'G', M, NRHS, WORK( IWORK ), LDB, B, LDB )
  5141. ELSE IF( NRHS.GT.1 ) THEN
  5142. CHUNK = ( LWORK-IWORK+1 ) / M
  5143. DO 40 I = 1, NRHS, CHUNK
  5144. BL = MIN( NRHS-I+1, CHUNK )
  5145. CALL DGEMM( 'T', 'N', M, BL, M, ONE, WORK( IL ), LDWORK,
  5146. $ B( 1, I ), LDB, ZERO, WORK( IWORK ), M )
  5147. CALL DLACPY( 'G', M, BL, WORK( IWORK ), M, B( 1, I ),
  5148. $ LDB )
  5149. 40 CONTINUE
  5150. ELSE
  5151. CALL DGEMV( 'T', M, M, ONE, WORK( IL ), LDWORK, B( 1, 1 ),
  5152. $ 1, ZERO, WORK( IWORK ), 1 )
  5153. CALL DCOPY( M, WORK( IWORK ), 1, B( 1, 1 ), 1 )
  5154. END IF
  5155. *
  5156. * Zero out below first M rows of B
  5157. *
  5158. CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
  5159. IWORK = ITAU + M
  5160. *
  5161. * Multiply transpose(Q) by B
  5162. * (Workspace: need M+NRHS, prefer M+NRHS*NB)
  5163. *
  5164. CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,
  5165. $ LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
  5166. *
  5167. ELSE
  5168. *
  5169. * Path 2 - remaining underdetermined cases
  5170. *
  5171. IE = 1
  5172. ITAUQ = IE + M
  5173. ITAUP = ITAUQ + M
  5174. IWORK = ITAUP + M
  5175. *
  5176. * Bidiagonalize A
  5177. * (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
  5178. *
  5179. CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  5180. $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
  5181. $ INFO )
  5182. *
  5183. * Multiply B by transpose of left bidiagonalizing vectors
  5184. * (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)
  5185. *
  5186. CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),
  5187. $ B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )
  5188. *
  5189. * Generate right bidiagonalizing vectors in A
  5190. * (Workspace: need 4*M, prefer 3*M+M*NB)
  5191. *
  5192. CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
  5193. $ WORK( IWORK ), LWORK-IWORK+1, INFO )
  5194. IWORK = IE + M
  5195. *
  5196. * Perform bidiagonal QR iteration,
  5197. * computing right singular vectors of A in A and
  5198. * multiplying B by transpose of left singular vectors
  5199. * (Workspace: need BDSPAC)
  5200. *
  5201. CALL DBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM,
  5202. $ 1, B, LDB, WORK( IWORK ), INFO )
  5203. IF( INFO.NE.0 )
  5204. $ GO TO 70
  5205. *
  5206. * Multiply B by reciprocals of singular values
  5207. *
  5208. THR = MAX( RCOND*S( 1 ), SFMIN )
  5209. IF( RCOND.LT.ZERO )
  5210. $ THR = MAX( EPS*S( 1 ), SFMIN )
  5211. RANK = 0
  5212. DO 50 I = 1, M
  5213. IF( S( I ).GT.THR ) THEN
  5214. CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )
  5215. RANK = RANK + 1
  5216. ELSE
  5217. CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )
  5218. END IF
  5219. 50 CONTINUE
  5220. *
  5221. * Multiply B by right singular vectors of A
  5222. * (Workspace: need N, prefer N*NRHS)
  5223. *
  5224. IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN
  5225. CALL DGEMM( 'T', 'N', N, NRHS, M, ONE, A, LDA, B, LDB, ZERO,
  5226. $ WORK, LDB )
  5227. CALL DLACPY( 'F', N, NRHS, WORK, LDB, B, LDB )
  5228. ELSE IF( NRHS.GT.1 ) THEN
  5229. CHUNK = LWORK / N
  5230. DO 60 I = 1, NRHS, CHUNK
  5231. BL = MIN( NRHS-I+1, CHUNK )
  5232. CALL DGEMM( 'T', 'N', N, BL, M, ONE, A, LDA, B( 1, I ),
  5233. $ LDB, ZERO, WORK, N )
  5234. CALL DLACPY( 'F', N, BL, WORK, N, B( 1, I ), LDB )
  5235. 60 CONTINUE
  5236. ELSE
  5237. CALL DGEMV( 'T', M, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 )
  5238. CALL DCOPY( N, WORK, 1, B, 1 )
  5239. END IF
  5240. END IF
  5241. *
  5242. * Undo scaling
  5243. *
  5244. IF( IASCL.EQ.1 ) THEN
  5245. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
  5246. CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
  5247. $ INFO )
  5248. ELSE IF( IASCL.EQ.2 ) THEN
  5249. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
  5250. CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
  5251. $ INFO )
  5252. END IF
  5253. IF( IBSCL.EQ.1 ) THEN
  5254. CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
  5255. ELSE IF( IBSCL.EQ.2 ) THEN
  5256. CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
  5257. END IF
  5258. *
  5259. 70 CONTINUE
  5260. WORK( 1 ) = MAXWRK
  5261. RETURN
  5262. *
  5263. * End of DGELSS
  5264. *
  5265. END
  5266. SUBROUTINE DGELSX( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
  5267. $ WORK, INFO )
  5268. *
  5269. * -- LAPACK driver routine (version 3.1) --
  5270. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  5271. * November 2006
  5272. *
  5273. * .. Scalar Arguments ..
  5274. INTEGER INFO, LDA, LDB, M, N, NRHS, RANK
  5275. DOUBLE PRECISION RCOND
  5276. * ..
  5277. * .. Array Arguments ..
  5278. INTEGER JPVT( * )
  5279. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )
  5280. * ..
  5281. *
  5282. * Purpose
  5283. * =======
  5284. *
  5285. * This routine is deprecated and has been replaced by routine DGELSY.
  5286. *
  5287. * DGELSX computes the minimum-norm solution to a real linear least
  5288. * squares problem:
  5289. * minimize || A * X - B ||
  5290. * using a complete orthogonal factorization of A. A is an M-by-N
  5291. * matrix which may be rank-deficient.
  5292. *
  5293. * Several right hand side vectors b and solution vectors x can be
  5294. * handled in a single call; they are stored as the columns of the
  5295. * M-by-NRHS right hand side matrix B and the N-by-NRHS solution
  5296. * matrix X.
  5297. *
  5298. * The routine first computes a QR factorization with column pivoting:
  5299. * A * P = Q * [ R11 R12 ]
  5300. * [ 0 R22 ]
  5301. * with R11 defined as the largest leading submatrix whose estimated
  5302. * condition number is less than 1/RCOND. The order of R11, RANK,
  5303. * is the effective rank of A.
  5304. *
  5305. * Then, R22 is considered to be negligible, and R12 is annihilated
  5306. * by orthogonal transformations from the right, arriving at the
  5307. * complete orthogonal factorization:
  5308. * A * P = Q * [ T11 0 ] * Z
  5309. * [ 0 0 ]
  5310. * The minimum-norm solution is then
  5311. * X = P * Z' [ inv(T11)*Q1'*B ]
  5312. * [ 0 ]
  5313. * where Q1 consists of the first RANK columns of Q.
  5314. *
  5315. * Arguments
  5316. * =========
  5317. *
  5318. * M (input) INTEGER
  5319. * The number of rows of the matrix A. M >= 0.
  5320. *
  5321. * N (input) INTEGER
  5322. * The number of columns of the matrix A. N >= 0.
  5323. *
  5324. * NRHS (input) INTEGER
  5325. * The number of right hand sides, i.e., the number of
  5326. * columns of matrices B and X. NRHS >= 0.
  5327. *
  5328. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  5329. * On entry, the M-by-N matrix A.
  5330. * On exit, A has been overwritten by details of its
  5331. * complete orthogonal factorization.
  5332. *
  5333. * LDA (input) INTEGER
  5334. * The leading dimension of the array A. LDA >= max(1,M).
  5335. *
  5336. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  5337. * On entry, the M-by-NRHS right hand side matrix B.
  5338. * On exit, the N-by-NRHS solution matrix X.
  5339. * If m >= n and RANK = n, the residual sum-of-squares for
  5340. * the solution in the i-th column is given by the sum of
  5341. * squares of elements N+1:M in that column.
  5342. *
  5343. * LDB (input) INTEGER
  5344. * The leading dimension of the array B. LDB >= max(1,M,N).
  5345. *
  5346. * JPVT (input/output) INTEGER array, dimension (N)
  5347. * On entry, if JPVT(i) .ne. 0, the i-th column of A is an
  5348. * initial column, otherwise it is a free column. Before
  5349. * the QR factorization of A, all initial columns are
  5350. * permuted to the leading positions; only the remaining
  5351. * free columns are moved as a result of column pivoting
  5352. * during the factorization.
  5353. * On exit, if JPVT(i) = k, then the i-th column of A*P
  5354. * was the k-th column of A.
  5355. *
  5356. * RCOND (input) DOUBLE PRECISION
  5357. * RCOND is used to determine the effective rank of A, which
  5358. * is defined as the order of the largest leading triangular
  5359. * submatrix R11 in the QR factorization with pivoting of A,
  5360. * whose estimated condition number < 1/RCOND.
  5361. *
  5362. * RANK (output) INTEGER
  5363. * The effective rank of A, i.e., the order of the submatrix
  5364. * R11. This is the same as the order of the submatrix T11
  5365. * in the complete orthogonal factorization of A.
  5366. *
  5367. * WORK (workspace) DOUBLE PRECISION array, dimension
  5368. * (max( min(M,N)+3*N, 2*min(M,N)+NRHS )),
  5369. *
  5370. * INFO (output) INTEGER
  5371. * = 0: successful exit
  5372. * < 0: if INFO = -i, the i-th argument had an illegal value
  5373. *
  5374. * =====================================================================
  5375. *
  5376. * .. Parameters ..
  5377. INTEGER IMAX, IMIN
  5378. PARAMETER ( IMAX = 1, IMIN = 2 )
  5379. DOUBLE PRECISION ZERO, ONE, DONE, NTDONE
  5380. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, DONE = ZERO,
  5381. $ NTDONE = ONE )
  5382. * ..
  5383. * .. Local Scalars ..
  5384. INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, K, MN
  5385. DOUBLE PRECISION ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
  5386. $ SMAXPR, SMIN, SMINPR, SMLNUM, T1, T2
  5387. * ..
  5388. * .. External Functions ..
  5389. DOUBLE PRECISION DLAMCH, DLANGE
  5390. EXTERNAL DLAMCH, DLANGE
  5391. * ..
  5392. * .. External Subroutines ..
  5393. EXTERNAL DGEQPF, DLAIC1, DLASCL, DLASET, DLATZM, DORM2R,
  5394. $ DTRSM, DTZRQF, XERBLA
  5395. * ..
  5396. * .. Intrinsic Functions ..
  5397. INTRINSIC ABS, MAX, MIN
  5398. * ..
  5399. * .. Executable Statements ..
  5400. *
  5401. MN = MIN( M, N )
  5402. ISMIN = MN + 1
  5403. ISMAX = 2*MN + 1
  5404. *
  5405. * Test the input arguments.
  5406. *
  5407. INFO = 0
  5408. IF( M.LT.0 ) THEN
  5409. INFO = -1
  5410. ELSE IF( N.LT.0 ) THEN
  5411. INFO = -2
  5412. ELSE IF( NRHS.LT.0 ) THEN
  5413. INFO = -3
  5414. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  5415. INFO = -5
  5416. ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
  5417. INFO = -7
  5418. END IF
  5419. *
  5420. IF( INFO.NE.0 ) THEN
  5421. CALL XERBLA( 'DGELSX', -INFO )
  5422. RETURN
  5423. END IF
  5424. *
  5425. * Quick return if possible
  5426. *
  5427. IF( MIN( M, N, NRHS ).EQ.0 ) THEN
  5428. RANK = 0
  5429. RETURN
  5430. END IF
  5431. *
  5432. * Get machine parameters
  5433. *
  5434. SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
  5435. BIGNUM = ONE / SMLNUM
  5436. CALL DLABAD( SMLNUM, BIGNUM )
  5437. *
  5438. * Scale A, B if max elements outside range [SMLNUM,BIGNUM]
  5439. *
  5440. ANRM = DLANGE( 'M', M, N, A, LDA, WORK )
  5441. IASCL = 0
  5442. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  5443. *
  5444. * Scale matrix norm up to SMLNUM
  5445. *
  5446. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
  5447. IASCL = 1
  5448. ELSE IF( ANRM.GT.BIGNUM ) THEN
  5449. *
  5450. * Scale matrix norm down to BIGNUM
  5451. *
  5452. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
  5453. IASCL = 2
  5454. ELSE IF( ANRM.EQ.ZERO ) THEN
  5455. *
  5456. * Matrix all zero. Return zero solution.
  5457. *
  5458. CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
  5459. RANK = 0
  5460. GO TO 100
  5461. END IF
  5462. *
  5463. BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )
  5464. IBSCL = 0
  5465. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  5466. *
  5467. * Scale matrix norm up to SMLNUM
  5468. *
  5469. CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
  5470. IBSCL = 1
  5471. ELSE IF( BNRM.GT.BIGNUM ) THEN
  5472. *
  5473. * Scale matrix norm down to BIGNUM
  5474. *
  5475. CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
  5476. IBSCL = 2
  5477. END IF
  5478. *
  5479. * Compute QR factorization with column pivoting of A:
  5480. * A * P = Q * R
  5481. *
  5482. CALL DGEQPF( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ), INFO )
  5483. *
  5484. * workspace 3*N. Details of Householder rotations stored
  5485. * in WORK(1:MN).
  5486. *
  5487. * Determine RANK using incremental condition estimation
  5488. *
  5489. WORK( ISMIN ) = ONE
  5490. WORK( ISMAX ) = ONE
  5491. SMAX = ABS( A( 1, 1 ) )
  5492. SMIN = SMAX
  5493. IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
  5494. RANK = 0
  5495. CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
  5496. GO TO 100
  5497. ELSE
  5498. RANK = 1
  5499. END IF
  5500. *
  5501. 10 CONTINUE
  5502. IF( RANK.LT.MN ) THEN
  5503. I = RANK + 1
  5504. CALL DLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),
  5505. $ A( I, I ), SMINPR, S1, C1 )
  5506. CALL DLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),
  5507. $ A( I, I ), SMAXPR, S2, C2 )
  5508. *
  5509. IF( SMAXPR*RCOND.LE.SMINPR ) THEN
  5510. DO 20 I = 1, RANK
  5511. WORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )
  5512. WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
  5513. 20 CONTINUE
  5514. WORK( ISMIN+RANK ) = C1
  5515. WORK( ISMAX+RANK ) = C2
  5516. SMIN = SMINPR
  5517. SMAX = SMAXPR
  5518. RANK = RANK + 1
  5519. GO TO 10
  5520. END IF
  5521. END IF
  5522. *
  5523. * Logically partition R = [ R11 R12 ]
  5524. * [ 0 R22 ]
  5525. * where R11 = R(1:RANK,1:RANK)
  5526. *
  5527. * [R11,R12] = [ T11, 0 ] * Y
  5528. *
  5529. IF( RANK.LT.N )
  5530. $ CALL DTZRQF( RANK, N, A, LDA, WORK( MN+1 ), INFO )
  5531. *
  5532. * Details of Householder rotations stored in WORK(MN+1:2*MN)
  5533. *
  5534. * B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
  5535. *
  5536. CALL DORM2R( 'Left', 'Transpose', M, NRHS, MN, A, LDA, WORK( 1 ),
  5537. $ B, LDB, WORK( 2*MN+1 ), INFO )
  5538. *
  5539. * workspace NRHS
  5540. *
  5541. * B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)
  5542. *
  5543. CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
  5544. $ NRHS, ONE, A, LDA, B, LDB )
  5545. *
  5546. DO 40 I = RANK + 1, N
  5547. DO 30 J = 1, NRHS
  5548. B( I, J ) = ZERO
  5549. 30 CONTINUE
  5550. 40 CONTINUE
  5551. *
  5552. * B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS)
  5553. *
  5554. IF( RANK.LT.N ) THEN
  5555. DO 50 I = 1, RANK
  5556. CALL DLATZM( 'Left', N-RANK+1, NRHS, A( I, RANK+1 ), LDA,
  5557. $ WORK( MN+I ), B( I, 1 ), B( RANK+1, 1 ), LDB,
  5558. $ WORK( 2*MN+1 ) )
  5559. 50 CONTINUE
  5560. END IF
  5561. *
  5562. * workspace NRHS
  5563. *
  5564. * B(1:N,1:NRHS) := P * B(1:N,1:NRHS)
  5565. *
  5566. DO 90 J = 1, NRHS
  5567. DO 60 I = 1, N
  5568. WORK( 2*MN+I ) = NTDONE
  5569. 60 CONTINUE
  5570. DO 80 I = 1, N
  5571. IF( WORK( 2*MN+I ).EQ.NTDONE ) THEN
  5572. IF( JPVT( I ).NE.I ) THEN
  5573. K = I
  5574. T1 = B( K, J )
  5575. T2 = B( JPVT( K ), J )
  5576. 70 CONTINUE
  5577. B( JPVT( K ), J ) = T1
  5578. WORK( 2*MN+K ) = DONE
  5579. T1 = T2
  5580. K = JPVT( K )
  5581. T2 = B( JPVT( K ), J )
  5582. IF( JPVT( K ).NE.I )
  5583. $ GO TO 70
  5584. B( I, J ) = T1
  5585. WORK( 2*MN+K ) = DONE
  5586. END IF
  5587. END IF
  5588. 80 CONTINUE
  5589. 90 CONTINUE
  5590. *
  5591. * Undo scaling
  5592. *
  5593. IF( IASCL.EQ.1 ) THEN
  5594. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
  5595. CALL DLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
  5596. $ INFO )
  5597. ELSE IF( IASCL.EQ.2 ) THEN
  5598. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
  5599. CALL DLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
  5600. $ INFO )
  5601. END IF
  5602. IF( IBSCL.EQ.1 ) THEN
  5603. CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
  5604. ELSE IF( IBSCL.EQ.2 ) THEN
  5605. CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
  5606. END IF
  5607. *
  5608. 100 CONTINUE
  5609. *
  5610. RETURN
  5611. *
  5612. * End of DGELSX
  5613. *
  5614. END
  5615. SUBROUTINE DGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
  5616. $ WORK, LWORK, INFO )
  5617. *
  5618. * -- LAPACK driver routine (version 3.1) --
  5619. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  5620. * November 2006
  5621. *
  5622. * .. Scalar Arguments ..
  5623. INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
  5624. DOUBLE PRECISION RCOND
  5625. * ..
  5626. * .. Array Arguments ..
  5627. INTEGER JPVT( * )
  5628. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )
  5629. * ..
  5630. *
  5631. * Purpose
  5632. * =======
  5633. *
  5634. * DGELSY computes the minimum-norm solution to a real linear least
  5635. * squares problem:
  5636. * minimize || A * X - B ||
  5637. * using a complete orthogonal factorization of A. A is an M-by-N
  5638. * matrix which may be rank-deficient.
  5639. *
  5640. * Several right hand side vectors b and solution vectors x can be
  5641. * handled in a single call; they are stored as the columns of the
  5642. * M-by-NRHS right hand side matrix B and the N-by-NRHS solution
  5643. * matrix X.
  5644. *
  5645. * The routine first computes a QR factorization with column pivoting:
  5646. * A * P = Q * [ R11 R12 ]
  5647. * [ 0 R22 ]
  5648. * with R11 defined as the largest leading submatrix whose estimated
  5649. * condition number is less than 1/RCOND. The order of R11, RANK,
  5650. * is the effective rank of A.
  5651. *
  5652. * Then, R22 is considered to be negligible, and R12 is annihilated
  5653. * by orthogonal transformations from the right, arriving at the
  5654. * complete orthogonal factorization:
  5655. * A * P = Q * [ T11 0 ] * Z
  5656. * [ 0 0 ]
  5657. * The minimum-norm solution is then
  5658. * X = P * Z' [ inv(T11)*Q1'*B ]
  5659. * [ 0 ]
  5660. * where Q1 consists of the first RANK columns of Q.
  5661. *
  5662. * This routine is basically identical to the original xGELSX except
  5663. * three differences:
  5664. * o The call to the subroutine xGEQPF has been substituted by the
  5665. * the call to the subroutine xGEQP3. This subroutine is a Blas-3
  5666. * version of the QR factorization with column pivoting.
  5667. * o Matrix B (the right hand side) is updated with Blas-3.
  5668. * o The permutation of matrix B (the right hand side) is faster and
  5669. * more simple.
  5670. *
  5671. * Arguments
  5672. * =========
  5673. *
  5674. * M (input) INTEGER
  5675. * The number of rows of the matrix A. M >= 0.
  5676. *
  5677. * N (input) INTEGER
  5678. * The number of columns of the matrix A. N >= 0.
  5679. *
  5680. * NRHS (input) INTEGER
  5681. * The number of right hand sides, i.e., the number of
  5682. * columns of matrices B and X. NRHS >= 0.
  5683. *
  5684. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  5685. * On entry, the M-by-N matrix A.
  5686. * On exit, A has been overwritten by details of its
  5687. * complete orthogonal factorization.
  5688. *
  5689. * LDA (input) INTEGER
  5690. * The leading dimension of the array A. LDA >= max(1,M).
  5691. *
  5692. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  5693. * On entry, the M-by-NRHS right hand side matrix B.
  5694. * On exit, the N-by-NRHS solution matrix X.
  5695. *
  5696. * LDB (input) INTEGER
  5697. * The leading dimension of the array B. LDB >= max(1,M,N).
  5698. *
  5699. * JPVT (input/output) INTEGER array, dimension (N)
  5700. * On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
  5701. * to the front of AP, otherwise column i is a free column.
  5702. * On exit, if JPVT(i) = k, then the i-th column of AP
  5703. * was the k-th column of A.
  5704. *
  5705. * RCOND (input) DOUBLE PRECISION
  5706. * RCOND is used to determine the effective rank of A, which
  5707. * is defined as the order of the largest leading triangular
  5708. * submatrix R11 in the QR factorization with pivoting of A,
  5709. * whose estimated condition number < 1/RCOND.
  5710. *
  5711. * RANK (output) INTEGER
  5712. * The effective rank of A, i.e., the order of the submatrix
  5713. * R11. This is the same as the order of the submatrix T11
  5714. * in the complete orthogonal factorization of A.
  5715. *
  5716. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  5717. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  5718. *
  5719. * LWORK (input) INTEGER
  5720. * The dimension of the array WORK.
  5721. * The unblocked strategy requires that:
  5722. * LWORK >= MAX( MN+3*N+1, 2*MN+NRHS ),
  5723. * where MN = min( M, N ).
  5724. * The block algorithm requires that:
  5725. * LWORK >= MAX( MN+2*N+NB*(N+1), 2*MN+NB*NRHS ),
  5726. * where NB is an upper bound on the blocksize returned
  5727. * by ILAENV for the routines DGEQP3, DTZRZF, STZRQF, DORMQR,
  5728. * and DORMRZ.
  5729. *
  5730. * If LWORK = -1, then a workspace query is assumed; the routine
  5731. * only calculates the optimal size of the WORK array, returns
  5732. * this value as the first entry of the WORK array, and no error
  5733. * message related to LWORK is issued by XERBLA.
  5734. *
  5735. * INFO (output) INTEGER
  5736. * = 0: successful exit
  5737. * < 0: If INFO = -i, the i-th argument had an illegal value.
  5738. *
  5739. * Further Details
  5740. * ===============
  5741. *
  5742. * Based on contributions by
  5743. * A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA
  5744. * E. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
  5745. * G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain
  5746. *
  5747. * =====================================================================
  5748. *
  5749. * .. Parameters ..
  5750. INTEGER IMAX, IMIN
  5751. PARAMETER ( IMAX = 1, IMIN = 2 )
  5752. DOUBLE PRECISION ZERO, ONE
  5753. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  5754. * ..
  5755. * .. Local Scalars ..
  5756. LOGICAL LQUERY
  5757. INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN,
  5758. $ LWKOPT, MN, NB, NB1, NB2, NB3, NB4
  5759. DOUBLE PRECISION ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
  5760. $ SMAXPR, SMIN, SMINPR, SMLNUM, WSIZE
  5761. * ..
  5762. * .. External Functions ..
  5763. INTEGER ILAENV
  5764. DOUBLE PRECISION DLAMCH, DLANGE
  5765. EXTERNAL ILAENV, DLAMCH, DLANGE
  5766. * ..
  5767. * .. External Subroutines ..
  5768. EXTERNAL DCOPY, DGEQP3, DLABAD, DLAIC1, DLASCL, DLASET,
  5769. $ DORMQR, DORMRZ, DTRSM, DTZRZF, XERBLA
  5770. * ..
  5771. * .. Intrinsic Functions ..
  5772. INTRINSIC ABS, MAX, MIN
  5773. * ..
  5774. * .. Executable Statements ..
  5775. *
  5776. MN = MIN( M, N )
  5777. ISMIN = MN + 1
  5778. ISMAX = 2*MN + 1
  5779. *
  5780. * Test the input arguments.
  5781. *
  5782. INFO = 0
  5783. LQUERY = ( LWORK.EQ.-1 )
  5784. IF( M.LT.0 ) THEN
  5785. INFO = -1
  5786. ELSE IF( N.LT.0 ) THEN
  5787. INFO = -2
  5788. ELSE IF( NRHS.LT.0 ) THEN
  5789. INFO = -3
  5790. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  5791. INFO = -5
  5792. ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
  5793. INFO = -7
  5794. END IF
  5795. *
  5796. * Figure out optimal block size
  5797. *
  5798. IF( INFO.EQ.0 ) THEN
  5799. IF( MN.EQ.0 .OR. NRHS.EQ.0 ) THEN
  5800. LWKMIN = 1
  5801. LWKOPT = 1
  5802. ELSE
  5803. NB1 = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  5804. NB2 = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )
  5805. NB3 = ILAENV( 1, 'DORMQR', ' ', M, N, NRHS, -1 )
  5806. NB4 = ILAENV( 1, 'DORMRQ', ' ', M, N, NRHS, -1 )
  5807. NB = MAX( NB1, NB2, NB3, NB4 )
  5808. LWKMIN = MN + MAX( 2*MN, N + 1, MN + NRHS )
  5809. LWKOPT = MAX( LWKMIN,
  5810. $ MN + 2*N + NB*( N + 1 ), 2*MN + NB*NRHS )
  5811. END IF
  5812. WORK( 1 ) = LWKOPT
  5813. *
  5814. IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
  5815. INFO = -12
  5816. END IF
  5817. END IF
  5818. *
  5819. IF( INFO.NE.0 ) THEN
  5820. CALL XERBLA( 'DGELSY', -INFO )
  5821. RETURN
  5822. ELSE IF( LQUERY ) THEN
  5823. RETURN
  5824. END IF
  5825. *
  5826. * Quick return if possible
  5827. *
  5828. IF( MN.EQ.0 .OR. NRHS.EQ.0 ) THEN
  5829. RANK = 0
  5830. RETURN
  5831. END IF
  5832. *
  5833. * Get machine parameters
  5834. *
  5835. SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
  5836. BIGNUM = ONE / SMLNUM
  5837. CALL DLABAD( SMLNUM, BIGNUM )
  5838. *
  5839. * Scale A, B if max entries outside range [SMLNUM,BIGNUM]
  5840. *
  5841. ANRM = DLANGE( 'M', M, N, A, LDA, WORK )
  5842. IASCL = 0
  5843. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  5844. *
  5845. * Scale matrix norm up to SMLNUM
  5846. *
  5847. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
  5848. IASCL = 1
  5849. ELSE IF( ANRM.GT.BIGNUM ) THEN
  5850. *
  5851. * Scale matrix norm down to BIGNUM
  5852. *
  5853. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
  5854. IASCL = 2
  5855. ELSE IF( ANRM.EQ.ZERO ) THEN
  5856. *
  5857. * Matrix all zero. Return zero solution.
  5858. *
  5859. CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
  5860. RANK = 0
  5861. GO TO 70
  5862. END IF
  5863. *
  5864. BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )
  5865. IBSCL = 0
  5866. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  5867. *
  5868. * Scale matrix norm up to SMLNUM
  5869. *
  5870. CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
  5871. IBSCL = 1
  5872. ELSE IF( BNRM.GT.BIGNUM ) THEN
  5873. *
  5874. * Scale matrix norm down to BIGNUM
  5875. *
  5876. CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
  5877. IBSCL = 2
  5878. END IF
  5879. *
  5880. * Compute QR factorization with column pivoting of A:
  5881. * A * P = Q * R
  5882. *
  5883. CALL DGEQP3( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ),
  5884. $ LWORK-MN, INFO )
  5885. WSIZE = MN + WORK( MN+1 )
  5886. *
  5887. * workspace: MN+2*N+NB*(N+1).
  5888. * Details of Householder rotations stored in WORK(1:MN).
  5889. *
  5890. * Determine RANK using incremental condition estimation
  5891. *
  5892. WORK( ISMIN ) = ONE
  5893. WORK( ISMAX ) = ONE
  5894. SMAX = ABS( A( 1, 1 ) )
  5895. SMIN = SMAX
  5896. IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
  5897. RANK = 0
  5898. CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
  5899. GO TO 70
  5900. ELSE
  5901. RANK = 1
  5902. END IF
  5903. *
  5904. 10 CONTINUE
  5905. IF( RANK.LT.MN ) THEN
  5906. I = RANK + 1
  5907. CALL DLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),
  5908. $ A( I, I ), SMINPR, S1, C1 )
  5909. CALL DLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),
  5910. $ A( I, I ), SMAXPR, S2, C2 )
  5911. *
  5912. IF( SMAXPR*RCOND.LE.SMINPR ) THEN
  5913. DO 20 I = 1, RANK
  5914. WORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )
  5915. WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
  5916. 20 CONTINUE
  5917. WORK( ISMIN+RANK ) = C1
  5918. WORK( ISMAX+RANK ) = C2
  5919. SMIN = SMINPR
  5920. SMAX = SMAXPR
  5921. RANK = RANK + 1
  5922. GO TO 10
  5923. END IF
  5924. END IF
  5925. *
  5926. * workspace: 3*MN.
  5927. *
  5928. * Logically partition R = [ R11 R12 ]
  5929. * [ 0 R22 ]
  5930. * where R11 = R(1:RANK,1:RANK)
  5931. *
  5932. * [R11,R12] = [ T11, 0 ] * Y
  5933. *
  5934. IF( RANK.LT.N )
  5935. $ CALL DTZRZF( RANK, N, A, LDA, WORK( MN+1 ), WORK( 2*MN+1 ),
  5936. $ LWORK-2*MN, INFO )
  5937. *
  5938. * workspace: 2*MN.
  5939. * Details of Householder rotations stored in WORK(MN+1:2*MN)
  5940. *
  5941. * B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
  5942. *
  5943. CALL DORMQR( 'Left', 'Transpose', M, NRHS, MN, A, LDA, WORK( 1 ),
  5944. $ B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
  5945. WSIZE = MAX( WSIZE, 2*MN+WORK( 2*MN+1 ) )
  5946. *
  5947. * workspace: 2*MN+NB*NRHS.
  5948. *
  5949. * B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)
  5950. *
  5951. CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
  5952. $ NRHS, ONE, A, LDA, B, LDB )
  5953. *
  5954. DO 40 J = 1, NRHS
  5955. DO 30 I = RANK + 1, N
  5956. B( I, J ) = ZERO
  5957. 30 CONTINUE
  5958. 40 CONTINUE
  5959. *
  5960. * B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS)
  5961. *
  5962. IF( RANK.LT.N ) THEN
  5963. CALL DORMRZ( 'Left', 'Transpose', N, NRHS, RANK, N-RANK, A,
  5964. $ LDA, WORK( MN+1 ), B, LDB, WORK( 2*MN+1 ),
  5965. $ LWORK-2*MN, INFO )
  5966. END IF
  5967. *
  5968. * workspace: 2*MN+NRHS.
  5969. *
  5970. * B(1:N,1:NRHS) := P * B(1:N,1:NRHS)
  5971. *
  5972. DO 60 J = 1, NRHS
  5973. DO 50 I = 1, N
  5974. WORK( JPVT( I ) ) = B( I, J )
  5975. 50 CONTINUE
  5976. CALL DCOPY( N, WORK( 1 ), 1, B( 1, J ), 1 )
  5977. 60 CONTINUE
  5978. *
  5979. * workspace: N.
  5980. *
  5981. * Undo scaling
  5982. *
  5983. IF( IASCL.EQ.1 ) THEN
  5984. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
  5985. CALL DLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
  5986. $ INFO )
  5987. ELSE IF( IASCL.EQ.2 ) THEN
  5988. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
  5989. CALL DLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
  5990. $ INFO )
  5991. END IF
  5992. IF( IBSCL.EQ.1 ) THEN
  5993. CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
  5994. ELSE IF( IBSCL.EQ.2 ) THEN
  5995. CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
  5996. END IF
  5997. *
  5998. 70 CONTINUE
  5999. WORK( 1 ) = LWKOPT
  6000. *
  6001. RETURN
  6002. *
  6003. * End of DGELSY
  6004. *
  6005. END
  6006. SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
  6007. $ LWORK, IWORK, INFO )
  6008. *
  6009. * -- LAPACK driver routine (version 3.1) --
  6010. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  6011. * November 2006
  6012. *
  6013. * .. Scalar Arguments ..
  6014. CHARACTER JOBZ
  6015. INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
  6016. * ..
  6017. * .. Array Arguments ..
  6018. INTEGER IWORK( * )
  6019. DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),
  6020. $ VT( LDVT, * ), WORK( * )
  6021. * ..
  6022. *
  6023. * Purpose
  6024. * =======
  6025. *
  6026. * DGESDD computes the singular value decomposition (SVD) of a real
  6027. * M-by-N matrix A, optionally computing the left and right singular
  6028. * vectors. If singular vectors are desired, it uses a
  6029. * divide-and-conquer algorithm.
  6030. *
  6031. * The SVD is written
  6032. *
  6033. * A = U * SIGMA * transpose(V)
  6034. *
  6035. * where SIGMA is an M-by-N matrix which is zero except for its
  6036. * min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
  6037. * V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA
  6038. * are the singular values of A; they are real and non-negative, and
  6039. * are returned in descending order. The first min(m,n) columns of
  6040. * U and V are the left and right singular vectors of A.
  6041. *
  6042. * Note that the routine returns VT = V**T, not V.
  6043. *
  6044. * The divide and conquer algorithm makes very mild assumptions about
  6045. * floating point arithmetic. It will work on machines with a guard
  6046. * digit in add/subtract, or on those binary machines without guard
  6047. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  6048. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  6049. * without guard digits, but we know of none.
  6050. *
  6051. * Arguments
  6052. * =========
  6053. *
  6054. * JOBZ (input) CHARACTER*1
  6055. * Specifies options for computing all or part of the matrix U:
  6056. * = 'A': all M columns of U and all N rows of V**T are
  6057. * returned in the arrays U and VT;
  6058. * = 'S': the first min(M,N) columns of U and the first
  6059. * min(M,N) rows of V**T are returned in the arrays U
  6060. * and VT;
  6061. * = 'O': If M >= N, the first N columns of U are overwritten
  6062. * on the array A and all rows of V**T are returned in
  6063. * the array VT;
  6064. * otherwise, all columns of U are returned in the
  6065. * array U and the first M rows of V**T are overwritten
  6066. * in the array A;
  6067. * = 'N': no columns of U or rows of V**T are computed.
  6068. *
  6069. * M (input) INTEGER
  6070. * The number of rows of the input matrix A. M >= 0.
  6071. *
  6072. * N (input) INTEGER
  6073. * The number of columns of the input matrix A. N >= 0.
  6074. *
  6075. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  6076. * On entry, the M-by-N matrix A.
  6077. * On exit,
  6078. * if JOBZ = 'O', A is overwritten with the first N columns
  6079. * of U (the left singular vectors, stored
  6080. * columnwise) if M >= N;
  6081. * A is overwritten with the first M rows
  6082. * of V**T (the right singular vectors, stored
  6083. * rowwise) otherwise.
  6084. * if JOBZ .ne. 'O', the contents of A are destroyed.
  6085. *
  6086. * LDA (input) INTEGER
  6087. * The leading dimension of the array A. LDA >= max(1,M).
  6088. *
  6089. * S (output) DOUBLE PRECISION array, dimension (min(M,N))
  6090. * The singular values of A, sorted so that S(i) >= S(i+1).
  6091. *
  6092. * U (output) DOUBLE PRECISION array, dimension (LDU,UCOL)
  6093. * UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N;
  6094. * UCOL = min(M,N) if JOBZ = 'S'.
  6095. * If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M
  6096. * orthogonal matrix U;
  6097. * if JOBZ = 'S', U contains the first min(M,N) columns of U
  6098. * (the left singular vectors, stored columnwise);
  6099. * if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced.
  6100. *
  6101. * LDU (input) INTEGER
  6102. * The leading dimension of the array U. LDU >= 1; if
  6103. * JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.
  6104. *
  6105. * VT (output) DOUBLE PRECISION array, dimension (LDVT,N)
  6106. * If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the
  6107. * N-by-N orthogonal matrix V**T;
  6108. * if JOBZ = 'S', VT contains the first min(M,N) rows of
  6109. * V**T (the right singular vectors, stored rowwise);
  6110. * if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced.
  6111. *
  6112. * LDVT (input) INTEGER
  6113. * The leading dimension of the array VT. LDVT >= 1; if
  6114. * JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
  6115. * if JOBZ = 'S', LDVT >= min(M,N).
  6116. *
  6117. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  6118. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
  6119. *
  6120. * LWORK (input) INTEGER
  6121. * The dimension of the array WORK. LWORK >= 1.
  6122. * If JOBZ = 'N',
  6123. * LWORK >= 3*min(M,N) + max(max(M,N),7*min(M,N)).
  6124. * If JOBZ = 'O',
  6125. * LWORK >= 3*min(M,N)*min(M,N) +
  6126. * max(max(M,N),5*min(M,N)*min(M,N)+4*min(M,N)).
  6127. * If JOBZ = 'S' or 'A'
  6128. * LWORK >= 3*min(M,N)*min(M,N) +
  6129. * max(max(M,N),4*min(M,N)*min(M,N)+4*min(M,N)).
  6130. * For good performance, LWORK should generally be larger.
  6131. * If LWORK = -1 but other input arguments are legal, WORK(1)
  6132. * returns the optimal LWORK.
  6133. *
  6134. * IWORK (workspace) INTEGER array, dimension (8*min(M,N))
  6135. *
  6136. * INFO (output) INTEGER
  6137. * = 0: successful exit.
  6138. * < 0: if INFO = -i, the i-th argument had an illegal value.
  6139. * > 0: DBDSDC did not converge, updating process failed.
  6140. *
  6141. * Further Details
  6142. * ===============
  6143. *
  6144. * Based on contributions by
  6145. * Ming Gu and Huan Ren, Computer Science Division, University of
  6146. * California at Berkeley, USA
  6147. *
  6148. * =====================================================================
  6149. *
  6150. * .. Parameters ..
  6151. DOUBLE PRECISION ZERO, ONE
  6152. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  6153. * ..
  6154. * .. Local Scalars ..
  6155. LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
  6156. INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
  6157. $ IR, ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
  6158. $ LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
  6159. $ MNTHR, NWORK, WRKBL
  6160. DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
  6161. * ..
  6162. * .. Local Arrays ..
  6163. INTEGER IDUM( 1 )
  6164. DOUBLE PRECISION DUM( 1 )
  6165. * ..
  6166. * .. External Subroutines ..
  6167. EXTERNAL DBDSDC, DGEBRD, DGELQF, DGEMM, DGEQRF, DLACPY,
  6168. $ DLASCL, DLASET, DORGBR, DORGLQ, DORGQR, DORMBR,
  6169. $ XERBLA
  6170. * ..
  6171. * .. External Functions ..
  6172. LOGICAL LSAME
  6173. INTEGER ILAENV
  6174. DOUBLE PRECISION DLAMCH, DLANGE
  6175. EXTERNAL DLAMCH, DLANGE, ILAENV, LSAME
  6176. * ..
  6177. * .. Intrinsic Functions ..
  6178. INTRINSIC INT, MAX, MIN, SQRT
  6179. * ..
  6180. * .. Executable Statements ..
  6181. *
  6182. * Test the input arguments
  6183. *
  6184. INFO = 0
  6185. MINMN = MIN( M, N )
  6186. WNTQA = LSAME( JOBZ, 'A' )
  6187. WNTQS = LSAME( JOBZ, 'S' )
  6188. WNTQAS = WNTQA .OR. WNTQS
  6189. WNTQO = LSAME( JOBZ, 'O' )
  6190. WNTQN = LSAME( JOBZ, 'N' )
  6191. LQUERY = ( LWORK.EQ.-1 )
  6192. *
  6193. IF( .NOT.( WNTQA .OR. WNTQS .OR. WNTQO .OR. WNTQN ) ) THEN
  6194. INFO = -1
  6195. ELSE IF( M.LT.0 ) THEN
  6196. INFO = -2
  6197. ELSE IF( N.LT.0 ) THEN
  6198. INFO = -3
  6199. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  6200. INFO = -5
  6201. ELSE IF( LDU.LT.1 .OR. ( WNTQAS .AND. LDU.LT.M ) .OR.
  6202. $ ( WNTQO .AND. M.LT.N .AND. LDU.LT.M ) ) THEN
  6203. INFO = -8
  6204. ELSE IF( LDVT.LT.1 .OR. ( WNTQA .AND. LDVT.LT.N ) .OR.
  6205. $ ( WNTQS .AND. LDVT.LT.MINMN ) .OR.
  6206. $ ( WNTQO .AND. M.GE.N .AND. LDVT.LT.N ) ) THEN
  6207. INFO = -10
  6208. END IF
  6209. *
  6210. * Compute workspace
  6211. * (Note: Comments in the code beginning "Workspace:" describe the
  6212. * minimal amount of workspace needed at that point in the code,
  6213. * as well as the preferred amount for good performance.
  6214. * NB refers to the optimal block size for the immediately
  6215. * following subroutine, as returned by ILAENV.)
  6216. *
  6217. IF( INFO.EQ.0 ) THEN
  6218. MINWRK = 1
  6219. MAXWRK = 1
  6220. IF( M.GE.N .AND. MINMN.GT.0 ) THEN
  6221. *
  6222. * Compute space needed for DBDSDC
  6223. *
  6224. MNTHR = INT( MINMN*11.0D0 / 6.0D0 )
  6225. IF( WNTQN ) THEN
  6226. BDSPAC = 7*N
  6227. ELSE
  6228. BDSPAC = 3*N*N + 4*N
  6229. END IF
  6230. IF( M.GE.MNTHR ) THEN
  6231. IF( WNTQN ) THEN
  6232. *
  6233. * Path 1 (M much larger than N, JOBZ='N')
  6234. *
  6235. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1,
  6236. $ -1 )
  6237. WRKBL = MAX( WRKBL, 3*N+2*N*
  6238. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  6239. MAXWRK = MAX( WRKBL, BDSPAC+N )
  6240. MINWRK = BDSPAC + N
  6241. ELSE IF( WNTQO ) THEN
  6242. *
  6243. * Path 2 (M much larger than N, JOBZ='O')
  6244. *
  6245. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  6246. WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
  6247. $ N, N, -1 ) )
  6248. WRKBL = MAX( WRKBL, 3*N+2*N*
  6249. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  6250. WRKBL = MAX( WRKBL, 3*N+N*
  6251. $ ILAENV( 1, 'DORMBR', 'QLN', N, N, N, -1 ) )
  6252. WRKBL = MAX( WRKBL, 3*N+N*
  6253. $ ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
  6254. WRKBL = MAX( WRKBL, BDSPAC+3*N )
  6255. MAXWRK = WRKBL + 2*N*N
  6256. MINWRK = BDSPAC + 2*N*N + 3*N
  6257. ELSE IF( WNTQS ) THEN
  6258. *
  6259. * Path 3 (M much larger than N, JOBZ='S')
  6260. *
  6261. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  6262. WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
  6263. $ N, N, -1 ) )
  6264. WRKBL = MAX( WRKBL, 3*N+2*N*
  6265. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  6266. WRKBL = MAX( WRKBL, 3*N+N*
  6267. $ ILAENV( 1, 'DORMBR', 'QLN', N, N, N, -1 ) )
  6268. WRKBL = MAX( WRKBL, 3*N+N*
  6269. $ ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
  6270. WRKBL = MAX( WRKBL, BDSPAC+3*N )
  6271. MAXWRK = WRKBL + N*N
  6272. MINWRK = BDSPAC + N*N + 3*N
  6273. ELSE IF( WNTQA ) THEN
  6274. *
  6275. * Path 4 (M much larger than N, JOBZ='A')
  6276. *
  6277. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  6278. WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
  6279. $ M, N, -1 ) )
  6280. WRKBL = MAX( WRKBL, 3*N+2*N*
  6281. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  6282. WRKBL = MAX( WRKBL, 3*N+N*
  6283. $ ILAENV( 1, 'DORMBR', 'QLN', N, N, N, -1 ) )
  6284. WRKBL = MAX( WRKBL, 3*N+N*
  6285. $ ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
  6286. WRKBL = MAX( WRKBL, BDSPAC+3*N )
  6287. MAXWRK = WRKBL + N*N
  6288. MINWRK = BDSPAC + N*N + 3*N
  6289. END IF
  6290. ELSE
  6291. *
  6292. * Path 5 (M at least N, but not much larger)
  6293. *
  6294. WRKBL = 3*N + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N, -1,
  6295. $ -1 )
  6296. IF( WNTQN ) THEN
  6297. MAXWRK = MAX( WRKBL, BDSPAC+3*N )
  6298. MINWRK = 3*N + MAX( M, BDSPAC )
  6299. ELSE IF( WNTQO ) THEN
  6300. WRKBL = MAX( WRKBL, 3*N+N*
  6301. $ ILAENV( 1, 'DORMBR', 'QLN', M, N, N, -1 ) )
  6302. WRKBL = MAX( WRKBL, 3*N+N*
  6303. $ ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
  6304. WRKBL = MAX( WRKBL, BDSPAC+3*N )
  6305. MAXWRK = WRKBL + M*N
  6306. MINWRK = 3*N + MAX( M, N*N+BDSPAC )
  6307. ELSE IF( WNTQS ) THEN
  6308. WRKBL = MAX( WRKBL, 3*N+N*
  6309. $ ILAENV( 1, 'DORMBR', 'QLN', M, N, N, -1 ) )
  6310. WRKBL = MAX( WRKBL, 3*N+N*
  6311. $ ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
  6312. MAXWRK = MAX( WRKBL, BDSPAC+3*N )
  6313. MINWRK = 3*N + MAX( M, BDSPAC )
  6314. ELSE IF( WNTQA ) THEN
  6315. WRKBL = MAX( WRKBL, 3*N+M*
  6316. $ ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )
  6317. WRKBL = MAX( WRKBL, 3*N+N*
  6318. $ ILAENV( 1, 'DORMBR', 'PRT', N, N, N, -1 ) )
  6319. MAXWRK = MAX( MAXWRK, BDSPAC+3*N )
  6320. MINWRK = 3*N + MAX( M, BDSPAC )
  6321. END IF
  6322. END IF
  6323. ELSE IF( MINMN.GT.0 ) THEN
  6324. *
  6325. * Compute space needed for DBDSDC
  6326. *
  6327. MNTHR = INT( MINMN*11.0D0 / 6.0D0 )
  6328. IF( WNTQN ) THEN
  6329. BDSPAC = 7*M
  6330. ELSE
  6331. BDSPAC = 3*M*M + 4*M
  6332. END IF
  6333. IF( N.GE.MNTHR ) THEN
  6334. IF( WNTQN ) THEN
  6335. *
  6336. * Path 1t (N much larger than M, JOBZ='N')
  6337. *
  6338. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
  6339. $ -1 )
  6340. WRKBL = MAX( WRKBL, 3*M+2*M*
  6341. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  6342. MAXWRK = MAX( WRKBL, BDSPAC+M )
  6343. MINWRK = BDSPAC + M
  6344. ELSE IF( WNTQO ) THEN
  6345. *
  6346. * Path 2t (N much larger than M, JOBZ='O')
  6347. *
  6348. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  6349. WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
  6350. $ N, M, -1 ) )
  6351. WRKBL = MAX( WRKBL, 3*M+2*M*
  6352. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  6353. WRKBL = MAX( WRKBL, 3*M+M*
  6354. $ ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 ) )
  6355. WRKBL = MAX( WRKBL, 3*M+M*
  6356. $ ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 ) )
  6357. WRKBL = MAX( WRKBL, BDSPAC+3*M )
  6358. MAXWRK = WRKBL + 2*M*M
  6359. MINWRK = BDSPAC + 2*M*M + 3*M
  6360. ELSE IF( WNTQS ) THEN
  6361. *
  6362. * Path 3t (N much larger than M, JOBZ='S')
  6363. *
  6364. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  6365. WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
  6366. $ N, M, -1 ) )
  6367. WRKBL = MAX( WRKBL, 3*M+2*M*
  6368. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  6369. WRKBL = MAX( WRKBL, 3*M+M*
  6370. $ ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 ) )
  6371. WRKBL = MAX( WRKBL, 3*M+M*
  6372. $ ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 ) )
  6373. WRKBL = MAX( WRKBL, BDSPAC+3*M )
  6374. MAXWRK = WRKBL + M*M
  6375. MINWRK = BDSPAC + M*M + 3*M
  6376. ELSE IF( WNTQA ) THEN
  6377. *
  6378. * Path 4t (N much larger than M, JOBZ='A')
  6379. *
  6380. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  6381. WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
  6382. $ N, M, -1 ) )
  6383. WRKBL = MAX( WRKBL, 3*M+2*M*
  6384. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  6385. WRKBL = MAX( WRKBL, 3*M+M*
  6386. $ ILAENV( 1, 'DORMBR', 'QLN', M, M, M, -1 ) )
  6387. WRKBL = MAX( WRKBL, 3*M+M*
  6388. $ ILAENV( 1, 'DORMBR', 'PRT', M, M, M, -1 ) )
  6389. WRKBL = MAX( WRKBL, BDSPAC+3*M )
  6390. MAXWRK = WRKBL + M*M
  6391. MINWRK = BDSPAC + M*M + 3*M
  6392. END IF
  6393. ELSE
  6394. *
  6395. * Path 5t (N greater than M, but not much larger)
  6396. *
  6397. WRKBL = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N, -1,
  6398. $ -1 )
  6399. IF( WNTQN ) THEN
  6400. MAXWRK = MAX( WRKBL, BDSPAC+3*M )
  6401. MINWRK = 3*M + MAX( N, BDSPAC )
  6402. ELSE IF( WNTQO ) THEN
  6403. WRKBL = MAX( WRKBL, 3*M+M*
  6404. $ ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )
  6405. WRKBL = MAX( WRKBL, 3*M+M*
  6406. $ ILAENV( 1, 'DORMBR', 'PRT', M, N, M, -1 ) )
  6407. WRKBL = MAX( WRKBL, BDSPAC+3*M )
  6408. MAXWRK = WRKBL + M*N
  6409. MINWRK = 3*M + MAX( N, M*M+BDSPAC )
  6410. ELSE IF( WNTQS ) THEN
  6411. WRKBL = MAX( WRKBL, 3*M+M*
  6412. $ ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )
  6413. WRKBL = MAX( WRKBL, 3*M+M*
  6414. $ ILAENV( 1, 'DORMBR', 'PRT', M, N, M, -1 ) )
  6415. MAXWRK = MAX( WRKBL, BDSPAC+3*M )
  6416. MINWRK = 3*M + MAX( N, BDSPAC )
  6417. ELSE IF( WNTQA ) THEN
  6418. WRKBL = MAX( WRKBL, 3*M+M*
  6419. $ ILAENV( 1, 'DORMBR', 'QLN', M, M, N, -1 ) )
  6420. WRKBL = MAX( WRKBL, 3*M+M*
  6421. $ ILAENV( 1, 'DORMBR', 'PRT', N, N, M, -1 ) )
  6422. MAXWRK = MAX( WRKBL, BDSPAC+3*M )
  6423. MINWRK = 3*M + MAX( N, BDSPAC )
  6424. END IF
  6425. END IF
  6426. END IF
  6427. MAXWRK = MAX( MAXWRK, MINWRK )
  6428. WORK( 1 ) = MAXWRK
  6429. *
  6430. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  6431. INFO = -12
  6432. END IF
  6433. END IF
  6434. *
  6435. IF( INFO.NE.0 ) THEN
  6436. CALL XERBLA( 'DGESDD', -INFO )
  6437. RETURN
  6438. ELSE IF( LQUERY ) THEN
  6439. RETURN
  6440. END IF
  6441. *
  6442. * Quick return if possible
  6443. *
  6444. IF( M.EQ.0 .OR. N.EQ.0 ) THEN
  6445. RETURN
  6446. END IF
  6447. *
  6448. * Get machine constants
  6449. *
  6450. EPS = DLAMCH( 'P' )
  6451. SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
  6452. BIGNUM = ONE / SMLNUM
  6453. *
  6454. * Scale A if max element outside range [SMLNUM,BIGNUM]
  6455. *
  6456. ANRM = DLANGE( 'M', M, N, A, LDA, DUM )
  6457. ISCL = 0
  6458. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  6459. ISCL = 1
  6460. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
  6461. ELSE IF( ANRM.GT.BIGNUM ) THEN
  6462. ISCL = 1
  6463. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
  6464. END IF
  6465. *
  6466. IF( M.GE.N ) THEN
  6467. *
  6468. * A has at least as many rows as columns. If A has sufficiently
  6469. * more rows than columns, first reduce using the QR
  6470. * decomposition (if sufficient workspace available)
  6471. *
  6472. IF( M.GE.MNTHR ) THEN
  6473. *
  6474. IF( WNTQN ) THEN
  6475. *
  6476. * Path 1 (M much larger than N, JOBZ='N')
  6477. * No singular vectors to be computed
  6478. *
  6479. ITAU = 1
  6480. NWORK = ITAU + N
  6481. *
  6482. * Compute A=Q*R
  6483. * (Workspace: need 2*N, prefer N+N*NB)
  6484. *
  6485. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  6486. $ LWORK-NWORK+1, IERR )
  6487. *
  6488. * Zero out below R
  6489. *
  6490. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
  6491. IE = 1
  6492. ITAUQ = IE + N
  6493. ITAUP = ITAUQ + N
  6494. NWORK = ITAUP + N
  6495. *
  6496. * Bidiagonalize R in A
  6497. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  6498. *
  6499. CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  6500. $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
  6501. $ IERR )
  6502. NWORK = IE + N
  6503. *
  6504. * Perform bidiagonal SVD, computing singular values only
  6505. * (Workspace: need N+BDSPAC)
  6506. *
  6507. CALL DBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,
  6508. $ DUM, IDUM, WORK( NWORK ), IWORK, INFO )
  6509. *
  6510. ELSE IF( WNTQO ) THEN
  6511. *
  6512. * Path 2 (M much larger than N, JOBZ = 'O')
  6513. * N left singular vectors to be overwritten on A and
  6514. * N right singular vectors to be computed in VT
  6515. *
  6516. IR = 1
  6517. *
  6518. * WORK(IR) is LDWRKR by N
  6519. *
  6520. IF( LWORK.GE.LDA*N+N*N+3*N+BDSPAC ) THEN
  6521. LDWRKR = LDA
  6522. ELSE
  6523. LDWRKR = ( LWORK-N*N-3*N-BDSPAC ) / N
  6524. END IF
  6525. ITAU = IR + LDWRKR*N
  6526. NWORK = ITAU + N
  6527. *
  6528. * Compute A=Q*R
  6529. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6530. *
  6531. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  6532. $ LWORK-NWORK+1, IERR )
  6533. *
  6534. * Copy R to WORK(IR), zeroing out below it
  6535. *
  6536. CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
  6537. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
  6538. $ LDWRKR )
  6539. *
  6540. * Generate Q in A
  6541. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6542. *
  6543. CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
  6544. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  6545. IE = ITAU
  6546. ITAUQ = IE + N
  6547. ITAUP = ITAUQ + N
  6548. NWORK = ITAUP + N
  6549. *
  6550. * Bidiagonalize R in VT, copying result to WORK(IR)
  6551. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  6552. *
  6553. CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
  6554. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
  6555. $ LWORK-NWORK+1, IERR )
  6556. *
  6557. * WORK(IU) is N by N
  6558. *
  6559. IU = NWORK
  6560. NWORK = IU + N*N
  6561. *
  6562. * Perform bidiagonal SVD, computing left singular vectors
  6563. * of bidiagonal matrix in WORK(IU) and computing right
  6564. * singular vectors of bidiagonal matrix in VT
  6565. * (Workspace: need N+N*N+BDSPAC)
  6566. *
  6567. CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,
  6568. $ VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
  6569. $ INFO )
  6570. *
  6571. * Overwrite WORK(IU) by left singular vectors of R
  6572. * and VT by right singular vectors of R
  6573. * (Workspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB)
  6574. *
  6575. CALL DORMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
  6576. $ WORK( ITAUQ ), WORK( IU ), N, WORK( NWORK ),
  6577. $ LWORK-NWORK+1, IERR )
  6578. CALL DORMBR( 'P', 'R', 'T', N, N, N, WORK( IR ), LDWRKR,
  6579. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  6580. $ LWORK-NWORK+1, IERR )
  6581. *
  6582. * Multiply Q in A by left singular vectors of R in
  6583. * WORK(IU), storing result in WORK(IR) and copying to A
  6584. * (Workspace: need 2*N*N, prefer N*N+M*N)
  6585. *
  6586. DO 10 I = 1, M, LDWRKR
  6587. CHUNK = MIN( M-I+1, LDWRKR )
  6588. CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
  6589. $ LDA, WORK( IU ), N, ZERO, WORK( IR ),
  6590. $ LDWRKR )
  6591. CALL DLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,
  6592. $ A( I, 1 ), LDA )
  6593. 10 CONTINUE
  6594. *
  6595. ELSE IF( WNTQS ) THEN
  6596. *
  6597. * Path 3 (M much larger than N, JOBZ='S')
  6598. * N left singular vectors to be computed in U and
  6599. * N right singular vectors to be computed in VT
  6600. *
  6601. IR = 1
  6602. *
  6603. * WORK(IR) is N by N
  6604. *
  6605. LDWRKR = N
  6606. ITAU = IR + LDWRKR*N
  6607. NWORK = ITAU + N
  6608. *
  6609. * Compute A=Q*R
  6610. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6611. *
  6612. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  6613. $ LWORK-NWORK+1, IERR )
  6614. *
  6615. * Copy R to WORK(IR), zeroing out below it
  6616. *
  6617. CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
  6618. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
  6619. $ LDWRKR )
  6620. *
  6621. * Generate Q in A
  6622. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6623. *
  6624. CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
  6625. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  6626. IE = ITAU
  6627. ITAUQ = IE + N
  6628. ITAUP = ITAUQ + N
  6629. NWORK = ITAUP + N
  6630. *
  6631. * Bidiagonalize R in WORK(IR)
  6632. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  6633. *
  6634. CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
  6635. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
  6636. $ LWORK-NWORK+1, IERR )
  6637. *
  6638. * Perform bidiagonal SVD, computing left singular vectors
  6639. * of bidiagoal matrix in U and computing right singular
  6640. * vectors of bidiagonal matrix in VT
  6641. * (Workspace: need N+BDSPAC)
  6642. *
  6643. CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
  6644. $ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
  6645. $ INFO )
  6646. *
  6647. * Overwrite U by left singular vectors of R and VT
  6648. * by right singular vectors of R
  6649. * (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB)
  6650. *
  6651. CALL DORMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
  6652. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  6653. $ LWORK-NWORK+1, IERR )
  6654. *
  6655. CALL DORMBR( 'P', 'R', 'T', N, N, N, WORK( IR ), LDWRKR,
  6656. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  6657. $ LWORK-NWORK+1, IERR )
  6658. *
  6659. * Multiply Q in A by left singular vectors of R in
  6660. * WORK(IR), storing result in U
  6661. * (Workspace: need N*N)
  6662. *
  6663. CALL DLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
  6664. CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA, WORK( IR ),
  6665. $ LDWRKR, ZERO, U, LDU )
  6666. *
  6667. ELSE IF( WNTQA ) THEN
  6668. *
  6669. * Path 4 (M much larger than N, JOBZ='A')
  6670. * M left singular vectors to be computed in U and
  6671. * N right singular vectors to be computed in VT
  6672. *
  6673. IU = 1
  6674. *
  6675. * WORK(IU) is N by N
  6676. *
  6677. LDWRKU = N
  6678. ITAU = IU + LDWRKU*N
  6679. NWORK = ITAU + N
  6680. *
  6681. * Compute A=Q*R, copying result to U
  6682. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6683. *
  6684. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  6685. $ LWORK-NWORK+1, IERR )
  6686. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  6687. *
  6688. * Generate Q in U
  6689. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6690. CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
  6691. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  6692. *
  6693. * Produce R in A, zeroing out other entries
  6694. *
  6695. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
  6696. IE = ITAU
  6697. ITAUQ = IE + N
  6698. ITAUP = ITAUQ + N
  6699. NWORK = ITAUP + N
  6700. *
  6701. * Bidiagonalize R in A
  6702. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  6703. *
  6704. CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  6705. $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
  6706. $ IERR )
  6707. *
  6708. * Perform bidiagonal SVD, computing left singular vectors
  6709. * of bidiagonal matrix in WORK(IU) and computing right
  6710. * singular vectors of bidiagonal matrix in VT
  6711. * (Workspace: need N+N*N+BDSPAC)
  6712. *
  6713. CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,
  6714. $ VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
  6715. $ INFO )
  6716. *
  6717. * Overwrite WORK(IU) by left singular vectors of R and VT
  6718. * by right singular vectors of R
  6719. * (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB)
  6720. *
  6721. CALL DORMBR( 'Q', 'L', 'N', N, N, N, A, LDA,
  6722. $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
  6723. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  6724. CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
  6725. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  6726. $ LWORK-NWORK+1, IERR )
  6727. *
  6728. * Multiply Q in U by left singular vectors of R in
  6729. * WORK(IU), storing result in A
  6730. * (Workspace: need N*N)
  6731. *
  6732. CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU, WORK( IU ),
  6733. $ LDWRKU, ZERO, A, LDA )
  6734. *
  6735. * Copy left singular vectors of A from A to U
  6736. *
  6737. CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
  6738. *
  6739. END IF
  6740. *
  6741. ELSE
  6742. *
  6743. * M .LT. MNTHR
  6744. *
  6745. * Path 5 (M at least N, but not much larger)
  6746. * Reduce to bidiagonal form without QR decomposition
  6747. *
  6748. IE = 1
  6749. ITAUQ = IE + N
  6750. ITAUP = ITAUQ + N
  6751. NWORK = ITAUP + N
  6752. *
  6753. * Bidiagonalize A
  6754. * (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
  6755. *
  6756. CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  6757. $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
  6758. $ IERR )
  6759. IF( WNTQN ) THEN
  6760. *
  6761. * Perform bidiagonal SVD, only computing singular values
  6762. * (Workspace: need N+BDSPAC)
  6763. *
  6764. CALL DBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,
  6765. $ DUM, IDUM, WORK( NWORK ), IWORK, INFO )
  6766. ELSE IF( WNTQO ) THEN
  6767. IU = NWORK
  6768. IF( LWORK.GE.M*N+3*N+BDSPAC ) THEN
  6769. *
  6770. * WORK( IU ) is M by N
  6771. *
  6772. LDWRKU = M
  6773. NWORK = IU + LDWRKU*N
  6774. CALL DLASET( 'F', M, N, ZERO, ZERO, WORK( IU ),
  6775. $ LDWRKU )
  6776. ELSE
  6777. *
  6778. * WORK( IU ) is N by N
  6779. *
  6780. LDWRKU = N
  6781. NWORK = IU + LDWRKU*N
  6782. *
  6783. * WORK(IR) is LDWRKR by N
  6784. *
  6785. IR = NWORK
  6786. LDWRKR = ( LWORK-N*N-3*N ) / N
  6787. END IF
  6788. NWORK = IU + LDWRKU*N
  6789. *
  6790. * Perform bidiagonal SVD, computing left singular vectors
  6791. * of bidiagonal matrix in WORK(IU) and computing right
  6792. * singular vectors of bidiagonal matrix in VT
  6793. * (Workspace: need N+N*N+BDSPAC)
  6794. *
  6795. CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ),
  6796. $ LDWRKU, VT, LDVT, DUM, IDUM, WORK( NWORK ),
  6797. $ IWORK, INFO )
  6798. *
  6799. * Overwrite VT by right singular vectors of A
  6800. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6801. *
  6802. CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
  6803. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  6804. $ LWORK-NWORK+1, IERR )
  6805. *
  6806. IF( LWORK.GE.M*N+3*N+BDSPAC ) THEN
  6807. *
  6808. * Overwrite WORK(IU) by left singular vectors of A
  6809. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6810. *
  6811. CALL DORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
  6812. $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
  6813. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  6814. *
  6815. * Copy left singular vectors of A from WORK(IU) to A
  6816. *
  6817. CALL DLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
  6818. ELSE
  6819. *
  6820. * Generate Q in A
  6821. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  6822. *
  6823. CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
  6824. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  6825. *
  6826. * Multiply Q in A by left singular vectors of
  6827. * bidiagonal matrix in WORK(IU), storing result in
  6828. * WORK(IR) and copying to A
  6829. * (Workspace: need 2*N*N, prefer N*N+M*N)
  6830. *
  6831. DO 20 I = 1, M, LDWRKR
  6832. CHUNK = MIN( M-I+1, LDWRKR )
  6833. CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
  6834. $ LDA, WORK( IU ), LDWRKU, ZERO,
  6835. $ WORK( IR ), LDWRKR )
  6836. CALL DLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,
  6837. $ A( I, 1 ), LDA )
  6838. 20 CONTINUE
  6839. END IF
  6840. *
  6841. ELSE IF( WNTQS ) THEN
  6842. *
  6843. * Perform bidiagonal SVD, computing left singular vectors
  6844. * of bidiagonal matrix in U and computing right singular
  6845. * vectors of bidiagonal matrix in VT
  6846. * (Workspace: need N+BDSPAC)
  6847. *
  6848. CALL DLASET( 'F', M, N, ZERO, ZERO, U, LDU )
  6849. CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
  6850. $ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
  6851. $ INFO )
  6852. *
  6853. * Overwrite U by left singular vectors of A and VT
  6854. * by right singular vectors of A
  6855. * (Workspace: need 3*N, prefer 2*N+N*NB)
  6856. *
  6857. CALL DORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
  6858. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  6859. $ LWORK-NWORK+1, IERR )
  6860. CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,
  6861. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  6862. $ LWORK-NWORK+1, IERR )
  6863. ELSE IF( WNTQA ) THEN
  6864. *
  6865. * Perform bidiagonal SVD, computing left singular vectors
  6866. * of bidiagonal matrix in U and computing right singular
  6867. * vectors of bidiagonal matrix in VT
  6868. * (Workspace: need N+BDSPAC)
  6869. *
  6870. CALL DLASET( 'F', M, M, ZERO, ZERO, U, LDU )
  6871. CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,
  6872. $ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
  6873. $ INFO )
  6874. *
  6875. * Set the right corner of U to identity matrix
  6876. *
  6877. IF( M.GT.N ) THEN
  6878. CALL DLASET( 'F', M-N, M-N, ZERO, ONE, U( N+1, N+1 ),
  6879. $ LDU )
  6880. END IF
  6881. *
  6882. * Overwrite U by left singular vectors of A and VT
  6883. * by right singular vectors of A
  6884. * (Workspace: need N*N+2*N+M, prefer N*N+2*N+M*NB)
  6885. *
  6886. CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
  6887. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  6888. $ LWORK-NWORK+1, IERR )
  6889. CALL DORMBR( 'P', 'R', 'T', N, N, M, A, LDA,
  6890. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  6891. $ LWORK-NWORK+1, IERR )
  6892. END IF
  6893. *
  6894. END IF
  6895. *
  6896. ELSE
  6897. *
  6898. * A has more columns than rows. If A has sufficiently more
  6899. * columns than rows, first reduce using the LQ decomposition (if
  6900. * sufficient workspace available)
  6901. *
  6902. IF( N.GE.MNTHR ) THEN
  6903. *
  6904. IF( WNTQN ) THEN
  6905. *
  6906. * Path 1t (N much larger than M, JOBZ='N')
  6907. * No singular vectors to be computed
  6908. *
  6909. ITAU = 1
  6910. NWORK = ITAU + M
  6911. *
  6912. * Compute A=L*Q
  6913. * (Workspace: need 2*M, prefer M+M*NB)
  6914. *
  6915. CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  6916. $ LWORK-NWORK+1, IERR )
  6917. *
  6918. * Zero out above L
  6919. *
  6920. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )
  6921. IE = 1
  6922. ITAUQ = IE + M
  6923. ITAUP = ITAUQ + M
  6924. NWORK = ITAUP + M
  6925. *
  6926. * Bidiagonalize L in A
  6927. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  6928. *
  6929. CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  6930. $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
  6931. $ IERR )
  6932. NWORK = IE + M
  6933. *
  6934. * Perform bidiagonal SVD, computing singular values only
  6935. * (Workspace: need M+BDSPAC)
  6936. *
  6937. CALL DBDSDC( 'U', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,
  6938. $ DUM, IDUM, WORK( NWORK ), IWORK, INFO )
  6939. *
  6940. ELSE IF( WNTQO ) THEN
  6941. *
  6942. * Path 2t (N much larger than M, JOBZ='O')
  6943. * M right singular vectors to be overwritten on A and
  6944. * M left singular vectors to be computed in U
  6945. *
  6946. IVT = 1
  6947. *
  6948. * IVT is M by M
  6949. *
  6950. IL = IVT + M*M
  6951. IF( LWORK.GE.M*N+M*M+3*M+BDSPAC ) THEN
  6952. *
  6953. * WORK(IL) is M by N
  6954. *
  6955. LDWRKL = M
  6956. CHUNK = N
  6957. ELSE
  6958. LDWRKL = M
  6959. CHUNK = ( LWORK-M*M ) / M
  6960. END IF
  6961. ITAU = IL + LDWRKL*M
  6962. NWORK = ITAU + M
  6963. *
  6964. * Compute A=L*Q
  6965. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  6966. *
  6967. CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  6968. $ LWORK-NWORK+1, IERR )
  6969. *
  6970. * Copy L to WORK(IL), zeroing about above it
  6971. *
  6972. CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
  6973. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  6974. $ WORK( IL+LDWRKL ), LDWRKL )
  6975. *
  6976. * Generate Q in A
  6977. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  6978. *
  6979. CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
  6980. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  6981. IE = ITAU
  6982. ITAUQ = IE + M
  6983. ITAUP = ITAUQ + M
  6984. NWORK = ITAUP + M
  6985. *
  6986. * Bidiagonalize L in WORK(IL)
  6987. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  6988. *
  6989. CALL DGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),
  6990. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
  6991. $ LWORK-NWORK+1, IERR )
  6992. *
  6993. * Perform bidiagonal SVD, computing left singular vectors
  6994. * of bidiagonal matrix in U, and computing right singular
  6995. * vectors of bidiagonal matrix in WORK(IVT)
  6996. * (Workspace: need M+M*M+BDSPAC)
  6997. *
  6998. CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,
  6999. $ WORK( IVT ), M, DUM, IDUM, WORK( NWORK ),
  7000. $ IWORK, INFO )
  7001. *
  7002. * Overwrite U by left singular vectors of L and WORK(IVT)
  7003. * by right singular vectors of L
  7004. * (Workspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB)
  7005. *
  7006. CALL DORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
  7007. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  7008. $ LWORK-NWORK+1, IERR )
  7009. CALL DORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,
  7010. $ WORK( ITAUP ), WORK( IVT ), M,
  7011. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  7012. *
  7013. * Multiply right singular vectors of L in WORK(IVT) by Q
  7014. * in A, storing result in WORK(IL) and copying to A
  7015. * (Workspace: need 2*M*M, prefer M*M+M*N)
  7016. *
  7017. DO 30 I = 1, N, CHUNK
  7018. BLK = MIN( N-I+1, CHUNK )
  7019. CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ), M,
  7020. $ A( 1, I ), LDA, ZERO, WORK( IL ), LDWRKL )
  7021. CALL DLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,
  7022. $ A( 1, I ), LDA )
  7023. 30 CONTINUE
  7024. *
  7025. ELSE IF( WNTQS ) THEN
  7026. *
  7027. * Path 3t (N much larger than M, JOBZ='S')
  7028. * M right singular vectors to be computed in VT and
  7029. * M left singular vectors to be computed in U
  7030. *
  7031. IL = 1
  7032. *
  7033. * WORK(IL) is M by M
  7034. *
  7035. LDWRKL = M
  7036. ITAU = IL + LDWRKL*M
  7037. NWORK = ITAU + M
  7038. *
  7039. * Compute A=L*Q
  7040. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  7041. *
  7042. CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  7043. $ LWORK-NWORK+1, IERR )
  7044. *
  7045. * Copy L to WORK(IL), zeroing out above it
  7046. *
  7047. CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
  7048. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  7049. $ WORK( IL+LDWRKL ), LDWRKL )
  7050. *
  7051. * Generate Q in A
  7052. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  7053. *
  7054. CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
  7055. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  7056. IE = ITAU
  7057. ITAUQ = IE + M
  7058. ITAUP = ITAUQ + M
  7059. NWORK = ITAUP + M
  7060. *
  7061. * Bidiagonalize L in WORK(IU), copying result to U
  7062. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  7063. *
  7064. CALL DGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),
  7065. $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
  7066. $ LWORK-NWORK+1, IERR )
  7067. *
  7068. * Perform bidiagonal SVD, computing left singular vectors
  7069. * of bidiagonal matrix in U and computing right singular
  7070. * vectors of bidiagonal matrix in VT
  7071. * (Workspace: need M+BDSPAC)
  7072. *
  7073. CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU, VT,
  7074. $ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
  7075. $ INFO )
  7076. *
  7077. * Overwrite U by left singular vectors of L and VT
  7078. * by right singular vectors of L
  7079. * (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB)
  7080. *
  7081. CALL DORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
  7082. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  7083. $ LWORK-NWORK+1, IERR )
  7084. CALL DORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,
  7085. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  7086. $ LWORK-NWORK+1, IERR )
  7087. *
  7088. * Multiply right singular vectors of L in WORK(IL) by
  7089. * Q in A, storing result in VT
  7090. * (Workspace: need M*M)
  7091. *
  7092. CALL DLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
  7093. CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IL ), LDWRKL,
  7094. $ A, LDA, ZERO, VT, LDVT )
  7095. *
  7096. ELSE IF( WNTQA ) THEN
  7097. *
  7098. * Path 4t (N much larger than M, JOBZ='A')
  7099. * N right singular vectors to be computed in VT and
  7100. * M left singular vectors to be computed in U
  7101. *
  7102. IVT = 1
  7103. *
  7104. * WORK(IVT) is M by M
  7105. *
  7106. LDWKVT = M
  7107. ITAU = IVT + LDWKVT*M
  7108. NWORK = ITAU + M
  7109. *
  7110. * Compute A=L*Q, copying result to VT
  7111. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  7112. *
  7113. CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
  7114. $ LWORK-NWORK+1, IERR )
  7115. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  7116. *
  7117. * Generate Q in VT
  7118. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  7119. *
  7120. CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
  7121. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  7122. *
  7123. * Produce L in A, zeroing out other entries
  7124. *
  7125. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )
  7126. IE = ITAU
  7127. ITAUQ = IE + M
  7128. ITAUP = ITAUQ + M
  7129. NWORK = ITAUP + M
  7130. *
  7131. * Bidiagonalize L in A
  7132. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  7133. *
  7134. CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  7135. $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
  7136. $ IERR )
  7137. *
  7138. * Perform bidiagonal SVD, computing left singular vectors
  7139. * of bidiagonal matrix in U and computing right singular
  7140. * vectors of bidiagonal matrix in WORK(IVT)
  7141. * (Workspace: need M+M*M+BDSPAC)
  7142. *
  7143. CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,
  7144. $ WORK( IVT ), LDWKVT, DUM, IDUM,
  7145. $ WORK( NWORK ), IWORK, INFO )
  7146. *
  7147. * Overwrite U by left singular vectors of L and WORK(IVT)
  7148. * by right singular vectors of L
  7149. * (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB)
  7150. *
  7151. CALL DORMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
  7152. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  7153. $ LWORK-NWORK+1, IERR )
  7154. CALL DORMBR( 'P', 'R', 'T', M, M, M, A, LDA,
  7155. $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
  7156. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  7157. *
  7158. * Multiply right singular vectors of L in WORK(IVT) by
  7159. * Q in VT, storing result in A
  7160. * (Workspace: need M*M)
  7161. *
  7162. CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IVT ), LDWKVT,
  7163. $ VT, LDVT, ZERO, A, LDA )
  7164. *
  7165. * Copy right singular vectors of A from A to VT
  7166. *
  7167. CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
  7168. *
  7169. END IF
  7170. *
  7171. ELSE
  7172. *
  7173. * N .LT. MNTHR
  7174. *
  7175. * Path 5t (N greater than M, but not much larger)
  7176. * Reduce to bidiagonal form without LQ decomposition
  7177. *
  7178. IE = 1
  7179. ITAUQ = IE + M
  7180. ITAUP = ITAUQ + M
  7181. NWORK = ITAUP + M
  7182. *
  7183. * Bidiagonalize A
  7184. * (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
  7185. *
  7186. CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  7187. $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
  7188. $ IERR )
  7189. IF( WNTQN ) THEN
  7190. *
  7191. * Perform bidiagonal SVD, only computing singular values
  7192. * (Workspace: need M+BDSPAC)
  7193. *
  7194. CALL DBDSDC( 'L', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,
  7195. $ DUM, IDUM, WORK( NWORK ), IWORK, INFO )
  7196. ELSE IF( WNTQO ) THEN
  7197. LDWKVT = M
  7198. IVT = NWORK
  7199. IF( LWORK.GE.M*N+3*M+BDSPAC ) THEN
  7200. *
  7201. * WORK( IVT ) is M by N
  7202. *
  7203. CALL DLASET( 'F', M, N, ZERO, ZERO, WORK( IVT ),
  7204. $ LDWKVT )
  7205. NWORK = IVT + LDWKVT*N
  7206. ELSE
  7207. *
  7208. * WORK( IVT ) is M by M
  7209. *
  7210. NWORK = IVT + LDWKVT*M
  7211. IL = NWORK
  7212. *
  7213. * WORK(IL) is M by CHUNK
  7214. *
  7215. CHUNK = ( LWORK-M*M-3*M ) / M
  7216. END IF
  7217. *
  7218. * Perform bidiagonal SVD, computing left singular vectors
  7219. * of bidiagonal matrix in U and computing right singular
  7220. * vectors of bidiagonal matrix in WORK(IVT)
  7221. * (Workspace: need M*M+BDSPAC)
  7222. *
  7223. CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU,
  7224. $ WORK( IVT ), LDWKVT, DUM, IDUM,
  7225. $ WORK( NWORK ), IWORK, INFO )
  7226. *
  7227. * Overwrite U by left singular vectors of A
  7228. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  7229. *
  7230. CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
  7231. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  7232. $ LWORK-NWORK+1, IERR )
  7233. *
  7234. IF( LWORK.GE.M*N+3*M+BDSPAC ) THEN
  7235. *
  7236. * Overwrite WORK(IVT) by left singular vectors of A
  7237. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  7238. *
  7239. CALL DORMBR( 'P', 'R', 'T', M, N, M, A, LDA,
  7240. $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
  7241. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  7242. *
  7243. * Copy right singular vectors of A from WORK(IVT) to A
  7244. *
  7245. CALL DLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
  7246. ELSE
  7247. *
  7248. * Generate P**T in A
  7249. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  7250. *
  7251. CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
  7252. $ WORK( NWORK ), LWORK-NWORK+1, IERR )
  7253. *
  7254. * Multiply Q in A by right singular vectors of
  7255. * bidiagonal matrix in WORK(IVT), storing result in
  7256. * WORK(IL) and copying to A
  7257. * (Workspace: need 2*M*M, prefer M*M+M*N)
  7258. *
  7259. DO 40 I = 1, N, CHUNK
  7260. BLK = MIN( N-I+1, CHUNK )
  7261. CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ),
  7262. $ LDWKVT, A( 1, I ), LDA, ZERO,
  7263. $ WORK( IL ), M )
  7264. CALL DLACPY( 'F', M, BLK, WORK( IL ), M, A( 1, I ),
  7265. $ LDA )
  7266. 40 CONTINUE
  7267. END IF
  7268. ELSE IF( WNTQS ) THEN
  7269. *
  7270. * Perform bidiagonal SVD, computing left singular vectors
  7271. * of bidiagonal matrix in U and computing right singular
  7272. * vectors of bidiagonal matrix in VT
  7273. * (Workspace: need M+BDSPAC)
  7274. *
  7275. CALL DLASET( 'F', M, N, ZERO, ZERO, VT, LDVT )
  7276. CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU, VT,
  7277. $ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
  7278. $ INFO )
  7279. *
  7280. * Overwrite U by left singular vectors of A and VT
  7281. * by right singular vectors of A
  7282. * (Workspace: need 3*M, prefer 2*M+M*NB)
  7283. *
  7284. CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
  7285. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  7286. $ LWORK-NWORK+1, IERR )
  7287. CALL DORMBR( 'P', 'R', 'T', M, N, M, A, LDA,
  7288. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  7289. $ LWORK-NWORK+1, IERR )
  7290. ELSE IF( WNTQA ) THEN
  7291. *
  7292. * Perform bidiagonal SVD, computing left singular vectors
  7293. * of bidiagonal matrix in U and computing right singular
  7294. * vectors of bidiagonal matrix in VT
  7295. * (Workspace: need M+BDSPAC)
  7296. *
  7297. CALL DLASET( 'F', N, N, ZERO, ZERO, VT, LDVT )
  7298. CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU, VT,
  7299. $ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,
  7300. $ INFO )
  7301. *
  7302. * Set the right corner of VT to identity matrix
  7303. *
  7304. IF( N.GT.M ) THEN
  7305. CALL DLASET( 'F', N-M, N-M, ZERO, ONE, VT( M+1, M+1 ),
  7306. $ LDVT )
  7307. END IF
  7308. *
  7309. * Overwrite U by left singular vectors of A and VT
  7310. * by right singular vectors of A
  7311. * (Workspace: need 2*M+N, prefer 2*M+N*NB)
  7312. *
  7313. CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
  7314. $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
  7315. $ LWORK-NWORK+1, IERR )
  7316. CALL DORMBR( 'P', 'R', 'T', N, N, M, A, LDA,
  7317. $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
  7318. $ LWORK-NWORK+1, IERR )
  7319. END IF
  7320. *
  7321. END IF
  7322. *
  7323. END IF
  7324. *
  7325. * Undo scaling if necessary
  7326. *
  7327. IF( ISCL.EQ.1 ) THEN
  7328. IF( ANRM.GT.BIGNUM )
  7329. $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
  7330. $ IERR )
  7331. IF( ANRM.LT.SMLNUM )
  7332. $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
  7333. $ IERR )
  7334. END IF
  7335. *
  7336. * Return optimal workspace in WORK(1)
  7337. *
  7338. WORK( 1 ) = MAXWRK
  7339. *
  7340. RETURN
  7341. *
  7342. * End of DGESDD
  7343. *
  7344. END
  7345. SUBROUTINE DGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )
  7346. *
  7347. * -- LAPACK driver routine (version 3.1) --
  7348. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  7349. * November 2006
  7350. *
  7351. * .. Scalar Arguments ..
  7352. INTEGER INFO, LDA, LDB, N, NRHS
  7353. * ..
  7354. * .. Array Arguments ..
  7355. INTEGER IPIV( * )
  7356. DOUBLE PRECISION A( LDA, * ), B( LDB, * )
  7357. * ..
  7358. *
  7359. * Purpose
  7360. * =======
  7361. *
  7362. * DGESV computes the solution to a real system of linear equations
  7363. * A * X = B,
  7364. * where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
  7365. *
  7366. * The LU decomposition with partial pivoting and row interchanges is
  7367. * used to factor A as
  7368. * A = P * L * U,
  7369. * where P is a permutation matrix, L is unit lower triangular, and U is
  7370. * upper triangular. The factored form of A is then used to solve the
  7371. * system of equations A * X = B.
  7372. *
  7373. * Arguments
  7374. * =========
  7375. *
  7376. * N (input) INTEGER
  7377. * The number of linear equations, i.e., the order of the
  7378. * matrix A. N >= 0.
  7379. *
  7380. * NRHS (input) INTEGER
  7381. * The number of right hand sides, i.e., the number of columns
  7382. * of the matrix B. NRHS >= 0.
  7383. *
  7384. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  7385. * On entry, the N-by-N coefficient matrix A.
  7386. * On exit, the factors L and U from the factorization
  7387. * A = P*L*U; the unit diagonal elements of L are not stored.
  7388. *
  7389. * LDA (input) INTEGER
  7390. * The leading dimension of the array A. LDA >= max(1,N).
  7391. *
  7392. * IPIV (output) INTEGER array, dimension (N)
  7393. * The pivot indices that define the permutation matrix P;
  7394. * row i of the matrix was interchanged with row IPIV(i).
  7395. *
  7396. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  7397. * On entry, the N-by-NRHS matrix of right hand side matrix B.
  7398. * On exit, if INFO = 0, the N-by-NRHS solution matrix X.
  7399. *
  7400. * LDB (input) INTEGER
  7401. * The leading dimension of the array B. LDB >= max(1,N).
  7402. *
  7403. * INFO (output) INTEGER
  7404. * = 0: successful exit
  7405. * < 0: if INFO = -i, the i-th argument had an illegal value
  7406. * > 0: if INFO = i, U(i,i) is exactly zero. The factorization
  7407. * has been completed, but the factor U is exactly
  7408. * singular, so the solution could not be computed.
  7409. *
  7410. * =====================================================================
  7411. *
  7412. * .. External Subroutines ..
  7413. EXTERNAL DGETRF, DGETRS, XERBLA
  7414. * ..
  7415. * .. Intrinsic Functions ..
  7416. INTRINSIC MAX
  7417. * ..
  7418. * .. Executable Statements ..
  7419. *
  7420. * Test the input parameters.
  7421. *
  7422. INFO = 0
  7423. IF( N.LT.0 ) THEN
  7424. INFO = -1
  7425. ELSE IF( NRHS.LT.0 ) THEN
  7426. INFO = -2
  7427. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  7428. INFO = -4
  7429. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  7430. INFO = -7
  7431. END IF
  7432. IF( INFO.NE.0 ) THEN
  7433. CALL XERBLA( 'DGESV ', -INFO )
  7434. RETURN
  7435. END IF
  7436. *
  7437. * Compute the LU factorization of A.
  7438. *
  7439. CALL DGETRF( N, N, A, LDA, IPIV, INFO )
  7440. IF( INFO.EQ.0 ) THEN
  7441. *
  7442. * Solve the system A*X = B, overwriting B with X.
  7443. *
  7444. CALL DGETRS( 'No transpose', N, NRHS, A, LDA, IPIV, B, LDB,
  7445. $ INFO )
  7446. END IF
  7447. RETURN
  7448. *
  7449. * End of DGESV
  7450. *
  7451. END
  7452. SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
  7453. $ WORK, LWORK, INFO )
  7454. *
  7455. * -- LAPACK driver routine (version 3.1) --
  7456. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  7457. * November 2006
  7458. *
  7459. * .. Scalar Arguments ..
  7460. CHARACTER JOBU, JOBVT
  7461. INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
  7462. * ..
  7463. * .. Array Arguments ..
  7464. DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),
  7465. $ VT( LDVT, * ), WORK( * )
  7466. * ..
  7467. *
  7468. * Purpose
  7469. * =======
  7470. *
  7471. * DGESVD computes the singular value decomposition (SVD) of a real
  7472. * M-by-N matrix A, optionally computing the left and/or right singular
  7473. * vectors. The SVD is written
  7474. *
  7475. * A = U * SIGMA * transpose(V)
  7476. *
  7477. * where SIGMA is an M-by-N matrix which is zero except for its
  7478. * min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
  7479. * V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA
  7480. * are the singular values of A; they are real and non-negative, and
  7481. * are returned in descending order. The first min(m,n) columns of
  7482. * U and V are the left and right singular vectors of A.
  7483. *
  7484. * Note that the routine returns V**T, not V.
  7485. *
  7486. * Arguments
  7487. * =========
  7488. *
  7489. * JOBU (input) CHARACTER*1
  7490. * Specifies options for computing all or part of the matrix U:
  7491. * = 'A': all M columns of U are returned in array U:
  7492. * = 'S': the first min(m,n) columns of U (the left singular
  7493. * vectors) are returned in the array U;
  7494. * = 'O': the first min(m,n) columns of U (the left singular
  7495. * vectors) are overwritten on the array A;
  7496. * = 'N': no columns of U (no left singular vectors) are
  7497. * computed.
  7498. *
  7499. * JOBVT (input) CHARACTER*1
  7500. * Specifies options for computing all or part of the matrix
  7501. * V**T:
  7502. * = 'A': all N rows of V**T are returned in the array VT;
  7503. * = 'S': the first min(m,n) rows of V**T (the right singular
  7504. * vectors) are returned in the array VT;
  7505. * = 'O': the first min(m,n) rows of V**T (the right singular
  7506. * vectors) are overwritten on the array A;
  7507. * = 'N': no rows of V**T (no right singular vectors) are
  7508. * computed.
  7509. *
  7510. * JOBVT and JOBU cannot both be 'O'.
  7511. *
  7512. * M (input) INTEGER
  7513. * The number of rows of the input matrix A. M >= 0.
  7514. *
  7515. * N (input) INTEGER
  7516. * The number of columns of the input matrix A. N >= 0.
  7517. *
  7518. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  7519. * On entry, the M-by-N matrix A.
  7520. * On exit,
  7521. * if JOBU = 'O', A is overwritten with the first min(m,n)
  7522. * columns of U (the left singular vectors,
  7523. * stored columnwise);
  7524. * if JOBVT = 'O', A is overwritten with the first min(m,n)
  7525. * rows of V**T (the right singular vectors,
  7526. * stored rowwise);
  7527. * if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A
  7528. * are destroyed.
  7529. *
  7530. * LDA (input) INTEGER
  7531. * The leading dimension of the array A. LDA >= max(1,M).
  7532. *
  7533. * S (output) DOUBLE PRECISION array, dimension (min(M,N))
  7534. * The singular values of A, sorted so that S(i) >= S(i+1).
  7535. *
  7536. * U (output) DOUBLE PRECISION array, dimension (LDU,UCOL)
  7537. * (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
  7538. * If JOBU = 'A', U contains the M-by-M orthogonal matrix U;
  7539. * if JOBU = 'S', U contains the first min(m,n) columns of U
  7540. * (the left singular vectors, stored columnwise);
  7541. * if JOBU = 'N' or 'O', U is not referenced.
  7542. *
  7543. * LDU (input) INTEGER
  7544. * The leading dimension of the array U. LDU >= 1; if
  7545. * JOBU = 'S' or 'A', LDU >= M.
  7546. *
  7547. * VT (output) DOUBLE PRECISION array, dimension (LDVT,N)
  7548. * If JOBVT = 'A', VT contains the N-by-N orthogonal matrix
  7549. * V**T;
  7550. * if JOBVT = 'S', VT contains the first min(m,n) rows of
  7551. * V**T (the right singular vectors, stored rowwise);
  7552. * if JOBVT = 'N' or 'O', VT is not referenced.
  7553. *
  7554. * LDVT (input) INTEGER
  7555. * The leading dimension of the array VT. LDVT >= 1; if
  7556. * JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).
  7557. *
  7558. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  7559. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
  7560. * if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged
  7561. * superdiagonal elements of an upper bidiagonal matrix B
  7562. * whose diagonal is in S (not necessarily sorted). B
  7563. * satisfies A = U * B * VT, so it has the same singular values
  7564. * as A, and singular vectors related by U and VT.
  7565. *
  7566. * LWORK (input) INTEGER
  7567. * The dimension of the array WORK.
  7568. * LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)).
  7569. * For good performance, LWORK should generally be larger.
  7570. *
  7571. * If LWORK = -1, then a workspace query is assumed; the routine
  7572. * only calculates the optimal size of the WORK array, returns
  7573. * this value as the first entry of the WORK array, and no error
  7574. * message related to LWORK is issued by XERBLA.
  7575. *
  7576. * INFO (output) INTEGER
  7577. * = 0: successful exit.
  7578. * < 0: if INFO = -i, the i-th argument had an illegal value.
  7579. * > 0: if DBDSQR did not converge, INFO specifies how many
  7580. * superdiagonals of an intermediate bidiagonal form B
  7581. * did not converge to zero. See the description of WORK
  7582. * above for details.
  7583. *
  7584. * =====================================================================
  7585. *
  7586. * .. Parameters ..
  7587. DOUBLE PRECISION ZERO, ONE
  7588. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  7589. * ..
  7590. * .. Local Scalars ..
  7591. LOGICAL LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,
  7592. $ WNTVA, WNTVAS, WNTVN, WNTVO, WNTVS
  7593. INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IR, ISCL,
  7594. $ ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
  7595. $ MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
  7596. $ NRVT, WRKBL
  7597. DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
  7598. * ..
  7599. * .. Local Arrays ..
  7600. DOUBLE PRECISION DUM( 1 )
  7601. * ..
  7602. * .. External Subroutines ..
  7603. EXTERNAL DBDSQR, DGEBRD, DGELQF, DGEMM, DGEQRF, DLACPY,
  7604. $ DLASCL, DLASET, DORGBR, DORGLQ, DORGQR, DORMBR,
  7605. $ XERBLA
  7606. * ..
  7607. * .. External Functions ..
  7608. LOGICAL LSAME
  7609. INTEGER ILAENV
  7610. DOUBLE PRECISION DLAMCH, DLANGE
  7611. EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE
  7612. * ..
  7613. * .. Intrinsic Functions ..
  7614. INTRINSIC MAX, MIN, SQRT
  7615. * ..
  7616. * .. Executable Statements ..
  7617. *
  7618. * Test the input arguments
  7619. *
  7620. INFO = 0
  7621. MINMN = MIN( M, N )
  7622. WNTUA = LSAME( JOBU, 'A' )
  7623. WNTUS = LSAME( JOBU, 'S' )
  7624. WNTUAS = WNTUA .OR. WNTUS
  7625. WNTUO = LSAME( JOBU, 'O' )
  7626. WNTUN = LSAME( JOBU, 'N' )
  7627. WNTVA = LSAME( JOBVT, 'A' )
  7628. WNTVS = LSAME( JOBVT, 'S' )
  7629. WNTVAS = WNTVA .OR. WNTVS
  7630. WNTVO = LSAME( JOBVT, 'O' )
  7631. WNTVN = LSAME( JOBVT, 'N' )
  7632. LQUERY = ( LWORK.EQ.-1 )
  7633. *
  7634. IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THEN
  7635. INFO = -1
  7636. ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.
  7637. $ ( WNTVO .AND. WNTUO ) ) THEN
  7638. INFO = -2
  7639. ELSE IF( M.LT.0 ) THEN
  7640. INFO = -3
  7641. ELSE IF( N.LT.0 ) THEN
  7642. INFO = -4
  7643. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  7644. INFO = -6
  7645. ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THEN
  7646. INFO = -9
  7647. ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.
  7648. $ ( WNTVS .AND. LDVT.LT.MINMN ) ) THEN
  7649. INFO = -11
  7650. END IF
  7651. *
  7652. * Compute workspace
  7653. * (Note: Comments in the code beginning "Workspace:" describe the
  7654. * minimal amount of workspace needed at that point in the code,
  7655. * as well as the preferred amount for good performance.
  7656. * NB refers to the optimal block size for the immediately
  7657. * following subroutine, as returned by ILAENV.)
  7658. *
  7659. IF( INFO.EQ.0 ) THEN
  7660. MINWRK = 1
  7661. MAXWRK = 1
  7662. IF( M.GE.N .AND. MINMN.GT.0 ) THEN
  7663. *
  7664. * Compute space needed for DBDSQR
  7665. *
  7666. MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
  7667. BDSPAC = 5*N
  7668. IF( M.GE.MNTHR ) THEN
  7669. IF( WNTUN ) THEN
  7670. *
  7671. * Path 1 (M much larger than N, JOBU='N')
  7672. *
  7673. MAXWRK = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1,
  7674. $ -1 )
  7675. MAXWRK = MAX( MAXWRK, 3*N+2*N*
  7676. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7677. IF( WNTVO .OR. WNTVAS )
  7678. $ MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
  7679. $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
  7680. MAXWRK = MAX( MAXWRK, BDSPAC )
  7681. MINWRK = MAX( 4*N, BDSPAC )
  7682. ELSE IF( WNTUO .AND. WNTVN ) THEN
  7683. *
  7684. * Path 2 (M much larger than N, JOBU='O', JOBVT='N')
  7685. *
  7686. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  7687. WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
  7688. $ N, N, -1 ) )
  7689. WRKBL = MAX( WRKBL, 3*N+2*N*
  7690. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7691. WRKBL = MAX( WRKBL, 3*N+N*
  7692. $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
  7693. WRKBL = MAX( WRKBL, BDSPAC )
  7694. MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
  7695. MINWRK = MAX( 3*N+M, BDSPAC )
  7696. ELSE IF( WNTUO .AND. WNTVAS ) THEN
  7697. *
  7698. * Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
  7699. * 'A')
  7700. *
  7701. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  7702. WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
  7703. $ N, N, -1 ) )
  7704. WRKBL = MAX( WRKBL, 3*N+2*N*
  7705. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7706. WRKBL = MAX( WRKBL, 3*N+N*
  7707. $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
  7708. WRKBL = MAX( WRKBL, 3*N+( N-1 )*
  7709. $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
  7710. WRKBL = MAX( WRKBL, BDSPAC )
  7711. MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
  7712. MINWRK = MAX( 3*N+M, BDSPAC )
  7713. ELSE IF( WNTUS .AND. WNTVN ) THEN
  7714. *
  7715. * Path 4 (M much larger than N, JOBU='S', JOBVT='N')
  7716. *
  7717. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  7718. WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
  7719. $ N, N, -1 ) )
  7720. WRKBL = MAX( WRKBL, 3*N+2*N*
  7721. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7722. WRKBL = MAX( WRKBL, 3*N+N*
  7723. $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
  7724. WRKBL = MAX( WRKBL, BDSPAC )
  7725. MAXWRK = N*N + WRKBL
  7726. MINWRK = MAX( 3*N+M, BDSPAC )
  7727. ELSE IF( WNTUS .AND. WNTVO ) THEN
  7728. *
  7729. * Path 5 (M much larger than N, JOBU='S', JOBVT='O')
  7730. *
  7731. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  7732. WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
  7733. $ N, N, -1 ) )
  7734. WRKBL = MAX( WRKBL, 3*N+2*N*
  7735. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7736. WRKBL = MAX( WRKBL, 3*N+N*
  7737. $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
  7738. WRKBL = MAX( WRKBL, 3*N+( N-1 )*
  7739. $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
  7740. WRKBL = MAX( WRKBL, BDSPAC )
  7741. MAXWRK = 2*N*N + WRKBL
  7742. MINWRK = MAX( 3*N+M, BDSPAC )
  7743. ELSE IF( WNTUS .AND. WNTVAS ) THEN
  7744. *
  7745. * Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
  7746. * 'A')
  7747. *
  7748. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  7749. WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
  7750. $ N, N, -1 ) )
  7751. WRKBL = MAX( WRKBL, 3*N+2*N*
  7752. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7753. WRKBL = MAX( WRKBL, 3*N+N*
  7754. $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
  7755. WRKBL = MAX( WRKBL, 3*N+( N-1 )*
  7756. $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
  7757. WRKBL = MAX( WRKBL, BDSPAC )
  7758. MAXWRK = N*N + WRKBL
  7759. MINWRK = MAX( 3*N+M, BDSPAC )
  7760. ELSE IF( WNTUA .AND. WNTVN ) THEN
  7761. *
  7762. * Path 7 (M much larger than N, JOBU='A', JOBVT='N')
  7763. *
  7764. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  7765. WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
  7766. $ M, N, -1 ) )
  7767. WRKBL = MAX( WRKBL, 3*N+2*N*
  7768. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7769. WRKBL = MAX( WRKBL, 3*N+N*
  7770. $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
  7771. WRKBL = MAX( WRKBL, BDSPAC )
  7772. MAXWRK = N*N + WRKBL
  7773. MINWRK = MAX( 3*N+M, BDSPAC )
  7774. ELSE IF( WNTUA .AND. WNTVO ) THEN
  7775. *
  7776. * Path 8 (M much larger than N, JOBU='A', JOBVT='O')
  7777. *
  7778. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  7779. WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
  7780. $ M, N, -1 ) )
  7781. WRKBL = MAX( WRKBL, 3*N+2*N*
  7782. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7783. WRKBL = MAX( WRKBL, 3*N+N*
  7784. $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
  7785. WRKBL = MAX( WRKBL, 3*N+( N-1 )*
  7786. $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
  7787. WRKBL = MAX( WRKBL, BDSPAC )
  7788. MAXWRK = 2*N*N + WRKBL
  7789. MINWRK = MAX( 3*N+M, BDSPAC )
  7790. ELSE IF( WNTUA .AND. WNTVAS ) THEN
  7791. *
  7792. * Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
  7793. * 'A')
  7794. *
  7795. WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  7796. WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
  7797. $ M, N, -1 ) )
  7798. WRKBL = MAX( WRKBL, 3*N+2*N*
  7799. $ ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
  7800. WRKBL = MAX( WRKBL, 3*N+N*
  7801. $ ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
  7802. WRKBL = MAX( WRKBL, 3*N+( N-1 )*
  7803. $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
  7804. WRKBL = MAX( WRKBL, BDSPAC )
  7805. MAXWRK = N*N + WRKBL
  7806. MINWRK = MAX( 3*N+M, BDSPAC )
  7807. END IF
  7808. ELSE
  7809. *
  7810. * Path 10 (M at least N, but not much larger)
  7811. *
  7812. MAXWRK = 3*N + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
  7813. $ -1, -1 )
  7814. IF( WNTUS .OR. WNTUO )
  7815. $ MAXWRK = MAX( MAXWRK, 3*N+N*
  7816. $ ILAENV( 1, 'DORGBR', 'Q', M, N, N, -1 ) )
  7817. IF( WNTUA )
  7818. $ MAXWRK = MAX( MAXWRK, 3*N+M*
  7819. $ ILAENV( 1, 'DORGBR', 'Q', M, M, N, -1 ) )
  7820. IF( .NOT.WNTVN )
  7821. $ MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
  7822. $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
  7823. MAXWRK = MAX( MAXWRK, BDSPAC )
  7824. MINWRK = MAX( 3*N+M, BDSPAC )
  7825. END IF
  7826. ELSE IF( MINMN.GT.0 ) THEN
  7827. *
  7828. * Compute space needed for DBDSQR
  7829. *
  7830. MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
  7831. BDSPAC = 5*M
  7832. IF( N.GE.MNTHR ) THEN
  7833. IF( WNTVN ) THEN
  7834. *
  7835. * Path 1t(N much larger than M, JOBVT='N')
  7836. *
  7837. MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
  7838. $ -1 )
  7839. MAXWRK = MAX( MAXWRK, 3*M+2*M*
  7840. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7841. IF( WNTUO .OR. WNTUAS )
  7842. $ MAXWRK = MAX( MAXWRK, 3*M+M*
  7843. $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
  7844. MAXWRK = MAX( MAXWRK, BDSPAC )
  7845. MINWRK = MAX( 4*M, BDSPAC )
  7846. ELSE IF( WNTVO .AND. WNTUN ) THEN
  7847. *
  7848. * Path 2t(N much larger than M, JOBU='N', JOBVT='O')
  7849. *
  7850. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  7851. WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
  7852. $ N, M, -1 ) )
  7853. WRKBL = MAX( WRKBL, 3*M+2*M*
  7854. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7855. WRKBL = MAX( WRKBL, 3*M+( M-1 )*
  7856. $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
  7857. WRKBL = MAX( WRKBL, BDSPAC )
  7858. MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
  7859. MINWRK = MAX( 3*M+N, BDSPAC )
  7860. ELSE IF( WNTVO .AND. WNTUAS ) THEN
  7861. *
  7862. * Path 3t(N much larger than M, JOBU='S' or 'A',
  7863. * JOBVT='O')
  7864. *
  7865. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  7866. WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
  7867. $ N, M, -1 ) )
  7868. WRKBL = MAX( WRKBL, 3*M+2*M*
  7869. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7870. WRKBL = MAX( WRKBL, 3*M+( M-1 )*
  7871. $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
  7872. WRKBL = MAX( WRKBL, 3*M+M*
  7873. $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
  7874. WRKBL = MAX( WRKBL, BDSPAC )
  7875. MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
  7876. MINWRK = MAX( 3*M+N, BDSPAC )
  7877. ELSE IF( WNTVS .AND. WNTUN ) THEN
  7878. *
  7879. * Path 4t(N much larger than M, JOBU='N', JOBVT='S')
  7880. *
  7881. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  7882. WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
  7883. $ N, M, -1 ) )
  7884. WRKBL = MAX( WRKBL, 3*M+2*M*
  7885. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7886. WRKBL = MAX( WRKBL, 3*M+( M-1 )*
  7887. $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
  7888. WRKBL = MAX( WRKBL, BDSPAC )
  7889. MAXWRK = M*M + WRKBL
  7890. MINWRK = MAX( 3*M+N, BDSPAC )
  7891. ELSE IF( WNTVS .AND. WNTUO ) THEN
  7892. *
  7893. * Path 5t(N much larger than M, JOBU='O', JOBVT='S')
  7894. *
  7895. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  7896. WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
  7897. $ N, M, -1 ) )
  7898. WRKBL = MAX( WRKBL, 3*M+2*M*
  7899. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7900. WRKBL = MAX( WRKBL, 3*M+( M-1 )*
  7901. $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
  7902. WRKBL = MAX( WRKBL, 3*M+M*
  7903. $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
  7904. WRKBL = MAX( WRKBL, BDSPAC )
  7905. MAXWRK = 2*M*M + WRKBL
  7906. MINWRK = MAX( 3*M+N, BDSPAC )
  7907. ELSE IF( WNTVS .AND. WNTUAS ) THEN
  7908. *
  7909. * Path 6t(N much larger than M, JOBU='S' or 'A',
  7910. * JOBVT='S')
  7911. *
  7912. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  7913. WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
  7914. $ N, M, -1 ) )
  7915. WRKBL = MAX( WRKBL, 3*M+2*M*
  7916. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7917. WRKBL = MAX( WRKBL, 3*M+( M-1 )*
  7918. $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
  7919. WRKBL = MAX( WRKBL, 3*M+M*
  7920. $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
  7921. WRKBL = MAX( WRKBL, BDSPAC )
  7922. MAXWRK = M*M + WRKBL
  7923. MINWRK = MAX( 3*M+N, BDSPAC )
  7924. ELSE IF( WNTVA .AND. WNTUN ) THEN
  7925. *
  7926. * Path 7t(N much larger than M, JOBU='N', JOBVT='A')
  7927. *
  7928. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  7929. WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
  7930. $ N, M, -1 ) )
  7931. WRKBL = MAX( WRKBL, 3*M+2*M*
  7932. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7933. WRKBL = MAX( WRKBL, 3*M+( M-1 )*
  7934. $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
  7935. WRKBL = MAX( WRKBL, BDSPAC )
  7936. MAXWRK = M*M + WRKBL
  7937. MINWRK = MAX( 3*M+N, BDSPAC )
  7938. ELSE IF( WNTVA .AND. WNTUO ) THEN
  7939. *
  7940. * Path 8t(N much larger than M, JOBU='O', JOBVT='A')
  7941. *
  7942. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  7943. WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
  7944. $ N, M, -1 ) )
  7945. WRKBL = MAX( WRKBL, 3*M+2*M*
  7946. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7947. WRKBL = MAX( WRKBL, 3*M+( M-1 )*
  7948. $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
  7949. WRKBL = MAX( WRKBL, 3*M+M*
  7950. $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
  7951. WRKBL = MAX( WRKBL, BDSPAC )
  7952. MAXWRK = 2*M*M + WRKBL
  7953. MINWRK = MAX( 3*M+N, BDSPAC )
  7954. ELSE IF( WNTVA .AND. WNTUAS ) THEN
  7955. *
  7956. * Path 9t(N much larger than M, JOBU='S' or 'A',
  7957. * JOBVT='A')
  7958. *
  7959. WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
  7960. WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
  7961. $ N, M, -1 ) )
  7962. WRKBL = MAX( WRKBL, 3*M+2*M*
  7963. $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
  7964. WRKBL = MAX( WRKBL, 3*M+( M-1 )*
  7965. $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
  7966. WRKBL = MAX( WRKBL, 3*M+M*
  7967. $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
  7968. WRKBL = MAX( WRKBL, BDSPAC )
  7969. MAXWRK = M*M + WRKBL
  7970. MINWRK = MAX( 3*M+N, BDSPAC )
  7971. END IF
  7972. ELSE
  7973. *
  7974. * Path 10t(N greater than M, but not much larger)
  7975. *
  7976. MAXWRK = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
  7977. $ -1, -1 )
  7978. IF( WNTVS .OR. WNTVO )
  7979. $ MAXWRK = MAX( MAXWRK, 3*M+M*
  7980. $ ILAENV( 1, 'DORGBR', 'P', M, N, M, -1 ) )
  7981. IF( WNTVA )
  7982. $ MAXWRK = MAX( MAXWRK, 3*M+N*
  7983. $ ILAENV( 1, 'DORGBR', 'P', N, N, M, -1 ) )
  7984. IF( .NOT.WNTUN )
  7985. $ MAXWRK = MAX( MAXWRK, 3*M+( M-1 )*
  7986. $ ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
  7987. MAXWRK = MAX( MAXWRK, BDSPAC )
  7988. MINWRK = MAX( 3*M+N, BDSPAC )
  7989. END IF
  7990. END IF
  7991. MAXWRK = MAX( MAXWRK, MINWRK )
  7992. WORK( 1 ) = MAXWRK
  7993. *
  7994. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  7995. INFO = -13
  7996. END IF
  7997. END IF
  7998. *
  7999. IF( INFO.NE.0 ) THEN
  8000. CALL XERBLA( 'DGESVD', -INFO )
  8001. RETURN
  8002. ELSE IF( LQUERY ) THEN
  8003. RETURN
  8004. END IF
  8005. *
  8006. * Quick return if possible
  8007. *
  8008. IF( M.EQ.0 .OR. N.EQ.0 ) THEN
  8009. RETURN
  8010. END IF
  8011. *
  8012. * Get machine constants
  8013. *
  8014. EPS = DLAMCH( 'P' )
  8015. SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
  8016. BIGNUM = ONE / SMLNUM
  8017. *
  8018. * Scale A if max element outside range [SMLNUM,BIGNUM]
  8019. *
  8020. ANRM = DLANGE( 'M', M, N, A, LDA, DUM )
  8021. ISCL = 0
  8022. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  8023. ISCL = 1
  8024. CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
  8025. ELSE IF( ANRM.GT.BIGNUM ) THEN
  8026. ISCL = 1
  8027. CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
  8028. END IF
  8029. *
  8030. IF( M.GE.N ) THEN
  8031. *
  8032. * A has at least as many rows as columns. If A has sufficiently
  8033. * more rows than columns, first reduce using the QR
  8034. * decomposition (if sufficient workspace available)
  8035. *
  8036. IF( M.GE.MNTHR ) THEN
  8037. *
  8038. IF( WNTUN ) THEN
  8039. *
  8040. * Path 1 (M much larger than N, JOBU='N')
  8041. * No left singular vectors to be computed
  8042. *
  8043. ITAU = 1
  8044. IWORK = ITAU + N
  8045. *
  8046. * Compute A=Q*R
  8047. * (Workspace: need 2*N, prefer N+N*NB)
  8048. *
  8049. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
  8050. $ LWORK-IWORK+1, IERR )
  8051. *
  8052. * Zero out below R
  8053. *
  8054. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
  8055. IE = 1
  8056. ITAUQ = IE + N
  8057. ITAUP = ITAUQ + N
  8058. IWORK = ITAUP + N
  8059. *
  8060. * Bidiagonalize R in A
  8061. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  8062. *
  8063. CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  8064. $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
  8065. $ IERR )
  8066. NCVT = 0
  8067. IF( WNTVO .OR. WNTVAS ) THEN
  8068. *
  8069. * If right singular vectors desired, generate P'.
  8070. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  8071. *
  8072. CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
  8073. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8074. NCVT = N
  8075. END IF
  8076. IWORK = IE + N
  8077. *
  8078. * Perform bidiagonal QR iteration, computing right
  8079. * singular vectors of A in A if desired
  8080. * (Workspace: need BDSPAC)
  8081. *
  8082. CALL DBDSQR( 'U', N, NCVT, 0, 0, S, WORK( IE ), A, LDA,
  8083. $ DUM, 1, DUM, 1, WORK( IWORK ), INFO )
  8084. *
  8085. * If right singular vectors desired in VT, copy them there
  8086. *
  8087. IF( WNTVAS )
  8088. $ CALL DLACPY( 'F', N, N, A, LDA, VT, LDVT )
  8089. *
  8090. ELSE IF( WNTUO .AND. WNTVN ) THEN
  8091. *
  8092. * Path 2 (M much larger than N, JOBU='O', JOBVT='N')
  8093. * N left singular vectors to be overwritten on A and
  8094. * no right singular vectors to be computed
  8095. *
  8096. IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
  8097. *
  8098. * Sufficient workspace for a fast algorithm
  8099. *
  8100. IR = 1
  8101. IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
  8102. *
  8103. * WORK(IU) is LDA by N, WORK(IR) is LDA by N
  8104. *
  8105. LDWRKU = LDA
  8106. LDWRKR = LDA
  8107. ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
  8108. *
  8109. * WORK(IU) is LDA by N, WORK(IR) is N by N
  8110. *
  8111. LDWRKU = LDA
  8112. LDWRKR = N
  8113. ELSE
  8114. *
  8115. * WORK(IU) is LDWRKU by N, WORK(IR) is N by N
  8116. *
  8117. LDWRKU = ( LWORK-N*N-N ) / N
  8118. LDWRKR = N
  8119. END IF
  8120. ITAU = IR + LDWRKR*N
  8121. IWORK = ITAU + N
  8122. *
  8123. * Compute A=Q*R
  8124. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8125. *
  8126. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8127. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8128. *
  8129. * Copy R to WORK(IR) and zero out below it
  8130. *
  8131. CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
  8132. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
  8133. $ LDWRKR )
  8134. *
  8135. * Generate Q in A
  8136. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8137. *
  8138. CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
  8139. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8140. IE = ITAU
  8141. ITAUQ = IE + N
  8142. ITAUP = ITAUQ + N
  8143. IWORK = ITAUP + N
  8144. *
  8145. * Bidiagonalize R in WORK(IR)
  8146. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  8147. *
  8148. CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
  8149. $ WORK( ITAUQ ), WORK( ITAUP ),
  8150. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8151. *
  8152. * Generate left vectors bidiagonalizing R
  8153. * (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
  8154. *
  8155. CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
  8156. $ WORK( ITAUQ ), WORK( IWORK ),
  8157. $ LWORK-IWORK+1, IERR )
  8158. IWORK = IE + N
  8159. *
  8160. * Perform bidiagonal QR iteration, computing left
  8161. * singular vectors of R in WORK(IR)
  8162. * (Workspace: need N*N+BDSPAC)
  8163. *
  8164. CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM, 1,
  8165. $ WORK( IR ), LDWRKR, DUM, 1,
  8166. $ WORK( IWORK ), INFO )
  8167. IU = IE + N
  8168. *
  8169. * Multiply Q in A by left singular vectors of R in
  8170. * WORK(IR), storing result in WORK(IU) and copying to A
  8171. * (Workspace: need N*N+2*N, prefer N*N+M*N+N)
  8172. *
  8173. DO 10 I = 1, M, LDWRKU
  8174. CHUNK = MIN( M-I+1, LDWRKU )
  8175. CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
  8176. $ LDA, WORK( IR ), LDWRKR, ZERO,
  8177. $ WORK( IU ), LDWRKU )
  8178. CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
  8179. $ A( I, 1 ), LDA )
  8180. 10 CONTINUE
  8181. *
  8182. ELSE
  8183. *
  8184. * Insufficient workspace for a fast algorithm
  8185. *
  8186. IE = 1
  8187. ITAUQ = IE + N
  8188. ITAUP = ITAUQ + N
  8189. IWORK = ITAUP + N
  8190. *
  8191. * Bidiagonalize A
  8192. * (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
  8193. *
  8194. CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
  8195. $ WORK( ITAUQ ), WORK( ITAUP ),
  8196. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8197. *
  8198. * Generate left vectors bidiagonalizing A
  8199. * (Workspace: need 4*N, prefer 3*N+N*NB)
  8200. *
  8201. CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
  8202. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8203. IWORK = IE + N
  8204. *
  8205. * Perform bidiagonal QR iteration, computing left
  8206. * singular vectors of A in A
  8207. * (Workspace: need BDSPAC)
  8208. *
  8209. CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM, 1,
  8210. $ A, LDA, DUM, 1, WORK( IWORK ), INFO )
  8211. *
  8212. END IF
  8213. *
  8214. ELSE IF( WNTUO .AND. WNTVAS ) THEN
  8215. *
  8216. * Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')
  8217. * N left singular vectors to be overwritten on A and
  8218. * N right singular vectors to be computed in VT
  8219. *
  8220. IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
  8221. *
  8222. * Sufficient workspace for a fast algorithm
  8223. *
  8224. IR = 1
  8225. IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
  8226. *
  8227. * WORK(IU) is LDA by N and WORK(IR) is LDA by N
  8228. *
  8229. LDWRKU = LDA
  8230. LDWRKR = LDA
  8231. ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
  8232. *
  8233. * WORK(IU) is LDA by N and WORK(IR) is N by N
  8234. *
  8235. LDWRKU = LDA
  8236. LDWRKR = N
  8237. ELSE
  8238. *
  8239. * WORK(IU) is LDWRKU by N and WORK(IR) is N by N
  8240. *
  8241. LDWRKU = ( LWORK-N*N-N ) / N
  8242. LDWRKR = N
  8243. END IF
  8244. ITAU = IR + LDWRKR*N
  8245. IWORK = ITAU + N
  8246. *
  8247. * Compute A=Q*R
  8248. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8249. *
  8250. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8251. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8252. *
  8253. * Copy R to VT, zeroing out below it
  8254. *
  8255. CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
  8256. IF( N.GT.1 )
  8257. $ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  8258. $ VT( 2, 1 ), LDVT )
  8259. *
  8260. * Generate Q in A
  8261. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8262. *
  8263. CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
  8264. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8265. IE = ITAU
  8266. ITAUQ = IE + N
  8267. ITAUP = ITAUQ + N
  8268. IWORK = ITAUP + N
  8269. *
  8270. * Bidiagonalize R in VT, copying result to WORK(IR)
  8271. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  8272. *
  8273. CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
  8274. $ WORK( ITAUQ ), WORK( ITAUP ),
  8275. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8276. CALL DLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
  8277. *
  8278. * Generate left vectors bidiagonalizing R in WORK(IR)
  8279. * (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
  8280. *
  8281. CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
  8282. $ WORK( ITAUQ ), WORK( IWORK ),
  8283. $ LWORK-IWORK+1, IERR )
  8284. *
  8285. * Generate right vectors bidiagonalizing R in VT
  8286. * (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB)
  8287. *
  8288. CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
  8289. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8290. IWORK = IE + N
  8291. *
  8292. * Perform bidiagonal QR iteration, computing left
  8293. * singular vectors of R in WORK(IR) and computing right
  8294. * singular vectors of R in VT
  8295. * (Workspace: need N*N+BDSPAC)
  8296. *
  8297. CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT, LDVT,
  8298. $ WORK( IR ), LDWRKR, DUM, 1,
  8299. $ WORK( IWORK ), INFO )
  8300. IU = IE + N
  8301. *
  8302. * Multiply Q in A by left singular vectors of R in
  8303. * WORK(IR), storing result in WORK(IU) and copying to A
  8304. * (Workspace: need N*N+2*N, prefer N*N+M*N+N)
  8305. *
  8306. DO 20 I = 1, M, LDWRKU
  8307. CHUNK = MIN( M-I+1, LDWRKU )
  8308. CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
  8309. $ LDA, WORK( IR ), LDWRKR, ZERO,
  8310. $ WORK( IU ), LDWRKU )
  8311. CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
  8312. $ A( I, 1 ), LDA )
  8313. 20 CONTINUE
  8314. *
  8315. ELSE
  8316. *
  8317. * Insufficient workspace for a fast algorithm
  8318. *
  8319. ITAU = 1
  8320. IWORK = ITAU + N
  8321. *
  8322. * Compute A=Q*R
  8323. * (Workspace: need 2*N, prefer N+N*NB)
  8324. *
  8325. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8326. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8327. *
  8328. * Copy R to VT, zeroing out below it
  8329. *
  8330. CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
  8331. IF( N.GT.1 )
  8332. $ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  8333. $ VT( 2, 1 ), LDVT )
  8334. *
  8335. * Generate Q in A
  8336. * (Workspace: need 2*N, prefer N+N*NB)
  8337. *
  8338. CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
  8339. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8340. IE = ITAU
  8341. ITAUQ = IE + N
  8342. ITAUP = ITAUQ + N
  8343. IWORK = ITAUP + N
  8344. *
  8345. * Bidiagonalize R in VT
  8346. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  8347. *
  8348. CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
  8349. $ WORK( ITAUQ ), WORK( ITAUP ),
  8350. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8351. *
  8352. * Multiply Q in A by left vectors bidiagonalizing R
  8353. * (Workspace: need 3*N+M, prefer 3*N+M*NB)
  8354. *
  8355. CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
  8356. $ WORK( ITAUQ ), A, LDA, WORK( IWORK ),
  8357. $ LWORK-IWORK+1, IERR )
  8358. *
  8359. * Generate right vectors bidiagonalizing R in VT
  8360. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  8361. *
  8362. CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
  8363. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8364. IWORK = IE + N
  8365. *
  8366. * Perform bidiagonal QR iteration, computing left
  8367. * singular vectors of A in A and computing right
  8368. * singular vectors of A in VT
  8369. * (Workspace: need BDSPAC)
  8370. *
  8371. CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT, LDVT,
  8372. $ A, LDA, DUM, 1, WORK( IWORK ), INFO )
  8373. *
  8374. END IF
  8375. *
  8376. ELSE IF( WNTUS ) THEN
  8377. *
  8378. IF( WNTVN ) THEN
  8379. *
  8380. * Path 4 (M much larger than N, JOBU='S', JOBVT='N')
  8381. * N left singular vectors to be computed in U and
  8382. * no right singular vectors to be computed
  8383. *
  8384. IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
  8385. *
  8386. * Sufficient workspace for a fast algorithm
  8387. *
  8388. IR = 1
  8389. IF( LWORK.GE.WRKBL+LDA*N ) THEN
  8390. *
  8391. * WORK(IR) is LDA by N
  8392. *
  8393. LDWRKR = LDA
  8394. ELSE
  8395. *
  8396. * WORK(IR) is N by N
  8397. *
  8398. LDWRKR = N
  8399. END IF
  8400. ITAU = IR + LDWRKR*N
  8401. IWORK = ITAU + N
  8402. *
  8403. * Compute A=Q*R
  8404. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8405. *
  8406. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8407. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8408. *
  8409. * Copy R to WORK(IR), zeroing out below it
  8410. *
  8411. CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),
  8412. $ LDWRKR )
  8413. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  8414. $ WORK( IR+1 ), LDWRKR )
  8415. *
  8416. * Generate Q in A
  8417. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8418. *
  8419. CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
  8420. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8421. IE = ITAU
  8422. ITAUQ = IE + N
  8423. ITAUP = ITAUQ + N
  8424. IWORK = ITAUP + N
  8425. *
  8426. * Bidiagonalize R in WORK(IR)
  8427. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  8428. *
  8429. CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
  8430. $ WORK( IE ), WORK( ITAUQ ),
  8431. $ WORK( ITAUP ), WORK( IWORK ),
  8432. $ LWORK-IWORK+1, IERR )
  8433. *
  8434. * Generate left vectors bidiagonalizing R in WORK(IR)
  8435. * (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
  8436. *
  8437. CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
  8438. $ WORK( ITAUQ ), WORK( IWORK ),
  8439. $ LWORK-IWORK+1, IERR )
  8440. IWORK = IE + N
  8441. *
  8442. * Perform bidiagonal QR iteration, computing left
  8443. * singular vectors of R in WORK(IR)
  8444. * (Workspace: need N*N+BDSPAC)
  8445. *
  8446. CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
  8447. $ 1, WORK( IR ), LDWRKR, DUM, 1,
  8448. $ WORK( IWORK ), INFO )
  8449. *
  8450. * Multiply Q in A by left singular vectors of R in
  8451. * WORK(IR), storing result in U
  8452. * (Workspace: need N*N)
  8453. *
  8454. CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
  8455. $ WORK( IR ), LDWRKR, ZERO, U, LDU )
  8456. *
  8457. ELSE
  8458. *
  8459. * Insufficient workspace for a fast algorithm
  8460. *
  8461. ITAU = 1
  8462. IWORK = ITAU + N
  8463. *
  8464. * Compute A=Q*R, copying result to U
  8465. * (Workspace: need 2*N, prefer N+N*NB)
  8466. *
  8467. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8468. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8469. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  8470. *
  8471. * Generate Q in U
  8472. * (Workspace: need 2*N, prefer N+N*NB)
  8473. *
  8474. CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
  8475. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8476. IE = ITAU
  8477. ITAUQ = IE + N
  8478. ITAUP = ITAUQ + N
  8479. IWORK = ITAUP + N
  8480. *
  8481. * Zero out below R in A
  8482. *
  8483. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
  8484. $ LDA )
  8485. *
  8486. * Bidiagonalize R in A
  8487. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  8488. *
  8489. CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
  8490. $ WORK( ITAUQ ), WORK( ITAUP ),
  8491. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8492. *
  8493. * Multiply Q in U by left vectors bidiagonalizing R
  8494. * (Workspace: need 3*N+M, prefer 3*N+M*NB)
  8495. *
  8496. CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
  8497. $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
  8498. $ LWORK-IWORK+1, IERR )
  8499. IWORK = IE + N
  8500. *
  8501. * Perform bidiagonal QR iteration, computing left
  8502. * singular vectors of A in U
  8503. * (Workspace: need BDSPAC)
  8504. *
  8505. CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
  8506. $ 1, U, LDU, DUM, 1, WORK( IWORK ),
  8507. $ INFO )
  8508. *
  8509. END IF
  8510. *
  8511. ELSE IF( WNTVO ) THEN
  8512. *
  8513. * Path 5 (M much larger than N, JOBU='S', JOBVT='O')
  8514. * N left singular vectors to be computed in U and
  8515. * N right singular vectors to be overwritten on A
  8516. *
  8517. IF( LWORK.GE.2*N*N+MAX( 4*N, BDSPAC ) ) THEN
  8518. *
  8519. * Sufficient workspace for a fast algorithm
  8520. *
  8521. IU = 1
  8522. IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
  8523. *
  8524. * WORK(IU) is LDA by N and WORK(IR) is LDA by N
  8525. *
  8526. LDWRKU = LDA
  8527. IR = IU + LDWRKU*N
  8528. LDWRKR = LDA
  8529. ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
  8530. *
  8531. * WORK(IU) is LDA by N and WORK(IR) is N by N
  8532. *
  8533. LDWRKU = LDA
  8534. IR = IU + LDWRKU*N
  8535. LDWRKR = N
  8536. ELSE
  8537. *
  8538. * WORK(IU) is N by N and WORK(IR) is N by N
  8539. *
  8540. LDWRKU = N
  8541. IR = IU + LDWRKU*N
  8542. LDWRKR = N
  8543. END IF
  8544. ITAU = IR + LDWRKR*N
  8545. IWORK = ITAU + N
  8546. *
  8547. * Compute A=Q*R
  8548. * (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
  8549. *
  8550. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8551. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8552. *
  8553. * Copy R to WORK(IU), zeroing out below it
  8554. *
  8555. CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
  8556. $ LDWRKU )
  8557. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  8558. $ WORK( IU+1 ), LDWRKU )
  8559. *
  8560. * Generate Q in A
  8561. * (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
  8562. *
  8563. CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
  8564. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8565. IE = ITAU
  8566. ITAUQ = IE + N
  8567. ITAUP = ITAUQ + N
  8568. IWORK = ITAUP + N
  8569. *
  8570. * Bidiagonalize R in WORK(IU), copying result to
  8571. * WORK(IR)
  8572. * (Workspace: need 2*N*N+4*N,
  8573. * prefer 2*N*N+3*N+2*N*NB)
  8574. *
  8575. CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
  8576. $ WORK( IE ), WORK( ITAUQ ),
  8577. $ WORK( ITAUP ), WORK( IWORK ),
  8578. $ LWORK-IWORK+1, IERR )
  8579. CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,
  8580. $ WORK( IR ), LDWRKR )
  8581. *
  8582. * Generate left bidiagonalizing vectors in WORK(IU)
  8583. * (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
  8584. *
  8585. CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
  8586. $ WORK( ITAUQ ), WORK( IWORK ),
  8587. $ LWORK-IWORK+1, IERR )
  8588. *
  8589. * Generate right bidiagonalizing vectors in WORK(IR)
  8590. * (Workspace: need 2*N*N+4*N-1,
  8591. * prefer 2*N*N+3*N+(N-1)*NB)
  8592. *
  8593. CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
  8594. $ WORK( ITAUP ), WORK( IWORK ),
  8595. $ LWORK-IWORK+1, IERR )
  8596. IWORK = IE + N
  8597. *
  8598. * Perform bidiagonal QR iteration, computing left
  8599. * singular vectors of R in WORK(IU) and computing
  8600. * right singular vectors of R in WORK(IR)
  8601. * (Workspace: need 2*N*N+BDSPAC)
  8602. *
  8603. CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
  8604. $ WORK( IR ), LDWRKR, WORK( IU ),
  8605. $ LDWRKU, DUM, 1, WORK( IWORK ), INFO )
  8606. *
  8607. * Multiply Q in A by left singular vectors of R in
  8608. * WORK(IU), storing result in U
  8609. * (Workspace: need N*N)
  8610. *
  8611. CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
  8612. $ WORK( IU ), LDWRKU, ZERO, U, LDU )
  8613. *
  8614. * Copy right singular vectors of R to A
  8615. * (Workspace: need N*N)
  8616. *
  8617. CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
  8618. $ LDA )
  8619. *
  8620. ELSE
  8621. *
  8622. * Insufficient workspace for a fast algorithm
  8623. *
  8624. ITAU = 1
  8625. IWORK = ITAU + N
  8626. *
  8627. * Compute A=Q*R, copying result to U
  8628. * (Workspace: need 2*N, prefer N+N*NB)
  8629. *
  8630. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8631. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8632. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  8633. *
  8634. * Generate Q in U
  8635. * (Workspace: need 2*N, prefer N+N*NB)
  8636. *
  8637. CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
  8638. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8639. IE = ITAU
  8640. ITAUQ = IE + N
  8641. ITAUP = ITAUQ + N
  8642. IWORK = ITAUP + N
  8643. *
  8644. * Zero out below R in A
  8645. *
  8646. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
  8647. $ LDA )
  8648. *
  8649. * Bidiagonalize R in A
  8650. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  8651. *
  8652. CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
  8653. $ WORK( ITAUQ ), WORK( ITAUP ),
  8654. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8655. *
  8656. * Multiply Q in U by left vectors bidiagonalizing R
  8657. * (Workspace: need 3*N+M, prefer 3*N+M*NB)
  8658. *
  8659. CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
  8660. $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
  8661. $ LWORK-IWORK+1, IERR )
  8662. *
  8663. * Generate right vectors bidiagonalizing R in A
  8664. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  8665. *
  8666. CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
  8667. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8668. IWORK = IE + N
  8669. *
  8670. * Perform bidiagonal QR iteration, computing left
  8671. * singular vectors of A in U and computing right
  8672. * singular vectors of A in A
  8673. * (Workspace: need BDSPAC)
  8674. *
  8675. CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
  8676. $ LDA, U, LDU, DUM, 1, WORK( IWORK ),
  8677. $ INFO )
  8678. *
  8679. END IF
  8680. *
  8681. ELSE IF( WNTVAS ) THEN
  8682. *
  8683. * Path 6 (M much larger than N, JOBU='S', JOBVT='S'
  8684. * or 'A')
  8685. * N left singular vectors to be computed in U and
  8686. * N right singular vectors to be computed in VT
  8687. *
  8688. IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
  8689. *
  8690. * Sufficient workspace for a fast algorithm
  8691. *
  8692. IU = 1
  8693. IF( LWORK.GE.WRKBL+LDA*N ) THEN
  8694. *
  8695. * WORK(IU) is LDA by N
  8696. *
  8697. LDWRKU = LDA
  8698. ELSE
  8699. *
  8700. * WORK(IU) is N by N
  8701. *
  8702. LDWRKU = N
  8703. END IF
  8704. ITAU = IU + LDWRKU*N
  8705. IWORK = ITAU + N
  8706. *
  8707. * Compute A=Q*R
  8708. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8709. *
  8710. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8711. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8712. *
  8713. * Copy R to WORK(IU), zeroing out below it
  8714. *
  8715. CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
  8716. $ LDWRKU )
  8717. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  8718. $ WORK( IU+1 ), LDWRKU )
  8719. *
  8720. * Generate Q in A
  8721. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8722. *
  8723. CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
  8724. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8725. IE = ITAU
  8726. ITAUQ = IE + N
  8727. ITAUP = ITAUQ + N
  8728. IWORK = ITAUP + N
  8729. *
  8730. * Bidiagonalize R in WORK(IU), copying result to VT
  8731. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  8732. *
  8733. CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
  8734. $ WORK( IE ), WORK( ITAUQ ),
  8735. $ WORK( ITAUP ), WORK( IWORK ),
  8736. $ LWORK-IWORK+1, IERR )
  8737. CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
  8738. $ LDVT )
  8739. *
  8740. * Generate left bidiagonalizing vectors in WORK(IU)
  8741. * (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
  8742. *
  8743. CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
  8744. $ WORK( ITAUQ ), WORK( IWORK ),
  8745. $ LWORK-IWORK+1, IERR )
  8746. *
  8747. * Generate right bidiagonalizing vectors in VT
  8748. * (Workspace: need N*N+4*N-1,
  8749. * prefer N*N+3*N+(N-1)*NB)
  8750. *
  8751. CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
  8752. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8753. IWORK = IE + N
  8754. *
  8755. * Perform bidiagonal QR iteration, computing left
  8756. * singular vectors of R in WORK(IU) and computing
  8757. * right singular vectors of R in VT
  8758. * (Workspace: need N*N+BDSPAC)
  8759. *
  8760. CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
  8761. $ LDVT, WORK( IU ), LDWRKU, DUM, 1,
  8762. $ WORK( IWORK ), INFO )
  8763. *
  8764. * Multiply Q in A by left singular vectors of R in
  8765. * WORK(IU), storing result in U
  8766. * (Workspace: need N*N)
  8767. *
  8768. CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
  8769. $ WORK( IU ), LDWRKU, ZERO, U, LDU )
  8770. *
  8771. ELSE
  8772. *
  8773. * Insufficient workspace for a fast algorithm
  8774. *
  8775. ITAU = 1
  8776. IWORK = ITAU + N
  8777. *
  8778. * Compute A=Q*R, copying result to U
  8779. * (Workspace: need 2*N, prefer N+N*NB)
  8780. *
  8781. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8782. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8783. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  8784. *
  8785. * Generate Q in U
  8786. * (Workspace: need 2*N, prefer N+N*NB)
  8787. *
  8788. CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
  8789. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8790. *
  8791. * Copy R to VT, zeroing out below it
  8792. *
  8793. CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
  8794. IF( N.GT.1 )
  8795. $ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  8796. $ VT( 2, 1 ), LDVT )
  8797. IE = ITAU
  8798. ITAUQ = IE + N
  8799. ITAUP = ITAUQ + N
  8800. IWORK = ITAUP + N
  8801. *
  8802. * Bidiagonalize R in VT
  8803. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  8804. *
  8805. CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
  8806. $ WORK( ITAUQ ), WORK( ITAUP ),
  8807. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8808. *
  8809. * Multiply Q in U by left bidiagonalizing vectors
  8810. * in VT
  8811. * (Workspace: need 3*N+M, prefer 3*N+M*NB)
  8812. *
  8813. CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
  8814. $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
  8815. $ LWORK-IWORK+1, IERR )
  8816. *
  8817. * Generate right bidiagonalizing vectors in VT
  8818. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  8819. *
  8820. CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
  8821. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8822. IWORK = IE + N
  8823. *
  8824. * Perform bidiagonal QR iteration, computing left
  8825. * singular vectors of A in U and computing right
  8826. * singular vectors of A in VT
  8827. * (Workspace: need BDSPAC)
  8828. *
  8829. CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
  8830. $ LDVT, U, LDU, DUM, 1, WORK( IWORK ),
  8831. $ INFO )
  8832. *
  8833. END IF
  8834. *
  8835. END IF
  8836. *
  8837. ELSE IF( WNTUA ) THEN
  8838. *
  8839. IF( WNTVN ) THEN
  8840. *
  8841. * Path 7 (M much larger than N, JOBU='A', JOBVT='N')
  8842. * M left singular vectors to be computed in U and
  8843. * no right singular vectors to be computed
  8844. *
  8845. IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
  8846. *
  8847. * Sufficient workspace for a fast algorithm
  8848. *
  8849. IR = 1
  8850. IF( LWORK.GE.WRKBL+LDA*N ) THEN
  8851. *
  8852. * WORK(IR) is LDA by N
  8853. *
  8854. LDWRKR = LDA
  8855. ELSE
  8856. *
  8857. * WORK(IR) is N by N
  8858. *
  8859. LDWRKR = N
  8860. END IF
  8861. ITAU = IR + LDWRKR*N
  8862. IWORK = ITAU + N
  8863. *
  8864. * Compute A=Q*R, copying result to U
  8865. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  8866. *
  8867. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8868. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8869. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  8870. *
  8871. * Copy R to WORK(IR), zeroing out below it
  8872. *
  8873. CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),
  8874. $ LDWRKR )
  8875. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  8876. $ WORK( IR+1 ), LDWRKR )
  8877. *
  8878. * Generate Q in U
  8879. * (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
  8880. *
  8881. CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
  8882. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8883. IE = ITAU
  8884. ITAUQ = IE + N
  8885. ITAUP = ITAUQ + N
  8886. IWORK = ITAUP + N
  8887. *
  8888. * Bidiagonalize R in WORK(IR)
  8889. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  8890. *
  8891. CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
  8892. $ WORK( IE ), WORK( ITAUQ ),
  8893. $ WORK( ITAUP ), WORK( IWORK ),
  8894. $ LWORK-IWORK+1, IERR )
  8895. *
  8896. * Generate left bidiagonalizing vectors in WORK(IR)
  8897. * (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
  8898. *
  8899. CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
  8900. $ WORK( ITAUQ ), WORK( IWORK ),
  8901. $ LWORK-IWORK+1, IERR )
  8902. IWORK = IE + N
  8903. *
  8904. * Perform bidiagonal QR iteration, computing left
  8905. * singular vectors of R in WORK(IR)
  8906. * (Workspace: need N*N+BDSPAC)
  8907. *
  8908. CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
  8909. $ 1, WORK( IR ), LDWRKR, DUM, 1,
  8910. $ WORK( IWORK ), INFO )
  8911. *
  8912. * Multiply Q in U by left singular vectors of R in
  8913. * WORK(IR), storing result in A
  8914. * (Workspace: need N*N)
  8915. *
  8916. CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
  8917. $ WORK( IR ), LDWRKR, ZERO, A, LDA )
  8918. *
  8919. * Copy left singular vectors of A from A to U
  8920. *
  8921. CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
  8922. *
  8923. ELSE
  8924. *
  8925. * Insufficient workspace for a fast algorithm
  8926. *
  8927. ITAU = 1
  8928. IWORK = ITAU + N
  8929. *
  8930. * Compute A=Q*R, copying result to U
  8931. * (Workspace: need 2*N, prefer N+N*NB)
  8932. *
  8933. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  8934. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8935. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  8936. *
  8937. * Generate Q in U
  8938. * (Workspace: need N+M, prefer N+M*NB)
  8939. *
  8940. CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
  8941. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8942. IE = ITAU
  8943. ITAUQ = IE + N
  8944. ITAUP = ITAUQ + N
  8945. IWORK = ITAUP + N
  8946. *
  8947. * Zero out below R in A
  8948. *
  8949. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
  8950. $ LDA )
  8951. *
  8952. * Bidiagonalize R in A
  8953. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  8954. *
  8955. CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
  8956. $ WORK( ITAUQ ), WORK( ITAUP ),
  8957. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  8958. *
  8959. * Multiply Q in U by left bidiagonalizing vectors
  8960. * in A
  8961. * (Workspace: need 3*N+M, prefer 3*N+M*NB)
  8962. *
  8963. CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
  8964. $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
  8965. $ LWORK-IWORK+1, IERR )
  8966. IWORK = IE + N
  8967. *
  8968. * Perform bidiagonal QR iteration, computing left
  8969. * singular vectors of A in U
  8970. * (Workspace: need BDSPAC)
  8971. *
  8972. CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
  8973. $ 1, U, LDU, DUM, 1, WORK( IWORK ),
  8974. $ INFO )
  8975. *
  8976. END IF
  8977. *
  8978. ELSE IF( WNTVO ) THEN
  8979. *
  8980. * Path 8 (M much larger than N, JOBU='A', JOBVT='O')
  8981. * M left singular vectors to be computed in U and
  8982. * N right singular vectors to be overwritten on A
  8983. *
  8984. IF( LWORK.GE.2*N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
  8985. *
  8986. * Sufficient workspace for a fast algorithm
  8987. *
  8988. IU = 1
  8989. IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
  8990. *
  8991. * WORK(IU) is LDA by N and WORK(IR) is LDA by N
  8992. *
  8993. LDWRKU = LDA
  8994. IR = IU + LDWRKU*N
  8995. LDWRKR = LDA
  8996. ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
  8997. *
  8998. * WORK(IU) is LDA by N and WORK(IR) is N by N
  8999. *
  9000. LDWRKU = LDA
  9001. IR = IU + LDWRKU*N
  9002. LDWRKR = N
  9003. ELSE
  9004. *
  9005. * WORK(IU) is N by N and WORK(IR) is N by N
  9006. *
  9007. LDWRKU = N
  9008. IR = IU + LDWRKU*N
  9009. LDWRKR = N
  9010. END IF
  9011. ITAU = IR + LDWRKR*N
  9012. IWORK = ITAU + N
  9013. *
  9014. * Compute A=Q*R, copying result to U
  9015. * (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
  9016. *
  9017. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  9018. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9019. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  9020. *
  9021. * Generate Q in U
  9022. * (Workspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)
  9023. *
  9024. CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
  9025. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9026. *
  9027. * Copy R to WORK(IU), zeroing out below it
  9028. *
  9029. CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
  9030. $ LDWRKU )
  9031. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  9032. $ WORK( IU+1 ), LDWRKU )
  9033. IE = ITAU
  9034. ITAUQ = IE + N
  9035. ITAUP = ITAUQ + N
  9036. IWORK = ITAUP + N
  9037. *
  9038. * Bidiagonalize R in WORK(IU), copying result to
  9039. * WORK(IR)
  9040. * (Workspace: need 2*N*N+4*N,
  9041. * prefer 2*N*N+3*N+2*N*NB)
  9042. *
  9043. CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
  9044. $ WORK( IE ), WORK( ITAUQ ),
  9045. $ WORK( ITAUP ), WORK( IWORK ),
  9046. $ LWORK-IWORK+1, IERR )
  9047. CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,
  9048. $ WORK( IR ), LDWRKR )
  9049. *
  9050. * Generate left bidiagonalizing vectors in WORK(IU)
  9051. * (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
  9052. *
  9053. CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
  9054. $ WORK( ITAUQ ), WORK( IWORK ),
  9055. $ LWORK-IWORK+1, IERR )
  9056. *
  9057. * Generate right bidiagonalizing vectors in WORK(IR)
  9058. * (Workspace: need 2*N*N+4*N-1,
  9059. * prefer 2*N*N+3*N+(N-1)*NB)
  9060. *
  9061. CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
  9062. $ WORK( ITAUP ), WORK( IWORK ),
  9063. $ LWORK-IWORK+1, IERR )
  9064. IWORK = IE + N
  9065. *
  9066. * Perform bidiagonal QR iteration, computing left
  9067. * singular vectors of R in WORK(IU) and computing
  9068. * right singular vectors of R in WORK(IR)
  9069. * (Workspace: need 2*N*N+BDSPAC)
  9070. *
  9071. CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
  9072. $ WORK( IR ), LDWRKR, WORK( IU ),
  9073. $ LDWRKU, DUM, 1, WORK( IWORK ), INFO )
  9074. *
  9075. * Multiply Q in U by left singular vectors of R in
  9076. * WORK(IU), storing result in A
  9077. * (Workspace: need N*N)
  9078. *
  9079. CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
  9080. $ WORK( IU ), LDWRKU, ZERO, A, LDA )
  9081. *
  9082. * Copy left singular vectors of A from A to U
  9083. *
  9084. CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
  9085. *
  9086. * Copy right singular vectors of R from WORK(IR) to A
  9087. *
  9088. CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
  9089. $ LDA )
  9090. *
  9091. ELSE
  9092. *
  9093. * Insufficient workspace for a fast algorithm
  9094. *
  9095. ITAU = 1
  9096. IWORK = ITAU + N
  9097. *
  9098. * Compute A=Q*R, copying result to U
  9099. * (Workspace: need 2*N, prefer N+N*NB)
  9100. *
  9101. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  9102. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9103. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  9104. *
  9105. * Generate Q in U
  9106. * (Workspace: need N+M, prefer N+M*NB)
  9107. *
  9108. CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
  9109. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9110. IE = ITAU
  9111. ITAUQ = IE + N
  9112. ITAUP = ITAUQ + N
  9113. IWORK = ITAUP + N
  9114. *
  9115. * Zero out below R in A
  9116. *
  9117. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
  9118. $ LDA )
  9119. *
  9120. * Bidiagonalize R in A
  9121. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  9122. *
  9123. CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
  9124. $ WORK( ITAUQ ), WORK( ITAUP ),
  9125. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9126. *
  9127. * Multiply Q in U by left bidiagonalizing vectors
  9128. * in A
  9129. * (Workspace: need 3*N+M, prefer 3*N+M*NB)
  9130. *
  9131. CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
  9132. $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
  9133. $ LWORK-IWORK+1, IERR )
  9134. *
  9135. * Generate right bidiagonalizing vectors in A
  9136. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  9137. *
  9138. CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
  9139. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9140. IWORK = IE + N
  9141. *
  9142. * Perform bidiagonal QR iteration, computing left
  9143. * singular vectors of A in U and computing right
  9144. * singular vectors of A in A
  9145. * (Workspace: need BDSPAC)
  9146. *
  9147. CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
  9148. $ LDA, U, LDU, DUM, 1, WORK( IWORK ),
  9149. $ INFO )
  9150. *
  9151. END IF
  9152. *
  9153. ELSE IF( WNTVAS ) THEN
  9154. *
  9155. * Path 9 (M much larger than N, JOBU='A', JOBVT='S'
  9156. * or 'A')
  9157. * M left singular vectors to be computed in U and
  9158. * N right singular vectors to be computed in VT
  9159. *
  9160. IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
  9161. *
  9162. * Sufficient workspace for a fast algorithm
  9163. *
  9164. IU = 1
  9165. IF( LWORK.GE.WRKBL+LDA*N ) THEN
  9166. *
  9167. * WORK(IU) is LDA by N
  9168. *
  9169. LDWRKU = LDA
  9170. ELSE
  9171. *
  9172. * WORK(IU) is N by N
  9173. *
  9174. LDWRKU = N
  9175. END IF
  9176. ITAU = IU + LDWRKU*N
  9177. IWORK = ITAU + N
  9178. *
  9179. * Compute A=Q*R, copying result to U
  9180. * (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
  9181. *
  9182. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  9183. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9184. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  9185. *
  9186. * Generate Q in U
  9187. * (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
  9188. *
  9189. CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
  9190. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9191. *
  9192. * Copy R to WORK(IU), zeroing out below it
  9193. *
  9194. CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
  9195. $ LDWRKU )
  9196. CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  9197. $ WORK( IU+1 ), LDWRKU )
  9198. IE = ITAU
  9199. ITAUQ = IE + N
  9200. ITAUP = ITAUQ + N
  9201. IWORK = ITAUP + N
  9202. *
  9203. * Bidiagonalize R in WORK(IU), copying result to VT
  9204. * (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
  9205. *
  9206. CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
  9207. $ WORK( IE ), WORK( ITAUQ ),
  9208. $ WORK( ITAUP ), WORK( IWORK ),
  9209. $ LWORK-IWORK+1, IERR )
  9210. CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
  9211. $ LDVT )
  9212. *
  9213. * Generate left bidiagonalizing vectors in WORK(IU)
  9214. * (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
  9215. *
  9216. CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
  9217. $ WORK( ITAUQ ), WORK( IWORK ),
  9218. $ LWORK-IWORK+1, IERR )
  9219. *
  9220. * Generate right bidiagonalizing vectors in VT
  9221. * (Workspace: need N*N+4*N-1,
  9222. * prefer N*N+3*N+(N-1)*NB)
  9223. *
  9224. CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
  9225. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9226. IWORK = IE + N
  9227. *
  9228. * Perform bidiagonal QR iteration, computing left
  9229. * singular vectors of R in WORK(IU) and computing
  9230. * right singular vectors of R in VT
  9231. * (Workspace: need N*N+BDSPAC)
  9232. *
  9233. CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
  9234. $ LDVT, WORK( IU ), LDWRKU, DUM, 1,
  9235. $ WORK( IWORK ), INFO )
  9236. *
  9237. * Multiply Q in U by left singular vectors of R in
  9238. * WORK(IU), storing result in A
  9239. * (Workspace: need N*N)
  9240. *
  9241. CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
  9242. $ WORK( IU ), LDWRKU, ZERO, A, LDA )
  9243. *
  9244. * Copy left singular vectors of A from A to U
  9245. *
  9246. CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
  9247. *
  9248. ELSE
  9249. *
  9250. * Insufficient workspace for a fast algorithm
  9251. *
  9252. ITAU = 1
  9253. IWORK = ITAU + N
  9254. *
  9255. * Compute A=Q*R, copying result to U
  9256. * (Workspace: need 2*N, prefer N+N*NB)
  9257. *
  9258. CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
  9259. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9260. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  9261. *
  9262. * Generate Q in U
  9263. * (Workspace: need N+M, prefer N+M*NB)
  9264. *
  9265. CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
  9266. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9267. *
  9268. * Copy R from A to VT, zeroing out below it
  9269. *
  9270. CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
  9271. IF( N.GT.1 )
  9272. $ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
  9273. $ VT( 2, 1 ), LDVT )
  9274. IE = ITAU
  9275. ITAUQ = IE + N
  9276. ITAUP = ITAUQ + N
  9277. IWORK = ITAUP + N
  9278. *
  9279. * Bidiagonalize R in VT
  9280. * (Workspace: need 4*N, prefer 3*N+2*N*NB)
  9281. *
  9282. CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
  9283. $ WORK( ITAUQ ), WORK( ITAUP ),
  9284. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9285. *
  9286. * Multiply Q in U by left bidiagonalizing vectors
  9287. * in VT
  9288. * (Workspace: need 3*N+M, prefer 3*N+M*NB)
  9289. *
  9290. CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
  9291. $ WORK( ITAUQ ), U, LDU, WORK( IWORK ),
  9292. $ LWORK-IWORK+1, IERR )
  9293. *
  9294. * Generate right bidiagonalizing vectors in VT
  9295. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  9296. *
  9297. CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
  9298. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9299. IWORK = IE + N
  9300. *
  9301. * Perform bidiagonal QR iteration, computing left
  9302. * singular vectors of A in U and computing right
  9303. * singular vectors of A in VT
  9304. * (Workspace: need BDSPAC)
  9305. *
  9306. CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
  9307. $ LDVT, U, LDU, DUM, 1, WORK( IWORK ),
  9308. $ INFO )
  9309. *
  9310. END IF
  9311. *
  9312. END IF
  9313. *
  9314. END IF
  9315. *
  9316. ELSE
  9317. *
  9318. * M .LT. MNTHR
  9319. *
  9320. * Path 10 (M at least N, but not much larger)
  9321. * Reduce to bidiagonal form without QR decomposition
  9322. *
  9323. IE = 1
  9324. ITAUQ = IE + N
  9325. ITAUP = ITAUQ + N
  9326. IWORK = ITAUP + N
  9327. *
  9328. * Bidiagonalize A
  9329. * (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
  9330. *
  9331. CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  9332. $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
  9333. $ IERR )
  9334. IF( WNTUAS ) THEN
  9335. *
  9336. * If left singular vectors desired in U, copy result to U
  9337. * and generate left bidiagonalizing vectors in U
  9338. * (Workspace: need 3*N+NCU, prefer 3*N+NCU*NB)
  9339. *
  9340. CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
  9341. IF( WNTUS )
  9342. $ NCU = N
  9343. IF( WNTUA )
  9344. $ NCU = M
  9345. CALL DORGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),
  9346. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9347. END IF
  9348. IF( WNTVAS ) THEN
  9349. *
  9350. * If right singular vectors desired in VT, copy result to
  9351. * VT and generate right bidiagonalizing vectors in VT
  9352. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  9353. *
  9354. CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
  9355. CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
  9356. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9357. END IF
  9358. IF( WNTUO ) THEN
  9359. *
  9360. * If left singular vectors desired in A, generate left
  9361. * bidiagonalizing vectors in A
  9362. * (Workspace: need 4*N, prefer 3*N+N*NB)
  9363. *
  9364. CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
  9365. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9366. END IF
  9367. IF( WNTVO ) THEN
  9368. *
  9369. * If right singular vectors desired in A, generate right
  9370. * bidiagonalizing vectors in A
  9371. * (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
  9372. *
  9373. CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
  9374. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9375. END IF
  9376. IWORK = IE + N
  9377. IF( WNTUAS .OR. WNTUO )
  9378. $ NRU = M
  9379. IF( WNTUN )
  9380. $ NRU = 0
  9381. IF( WNTVAS .OR. WNTVO )
  9382. $ NCVT = N
  9383. IF( WNTVN )
  9384. $ NCVT = 0
  9385. IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
  9386. *
  9387. * Perform bidiagonal QR iteration, if desired, computing
  9388. * left singular vectors in U and computing right singular
  9389. * vectors in VT
  9390. * (Workspace: need BDSPAC)
  9391. *
  9392. CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
  9393. $ LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
  9394. ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
  9395. *
  9396. * Perform bidiagonal QR iteration, if desired, computing
  9397. * left singular vectors in U and computing right singular
  9398. * vectors in A
  9399. * (Workspace: need BDSPAC)
  9400. *
  9401. CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
  9402. $ U, LDU, DUM, 1, WORK( IWORK ), INFO )
  9403. ELSE
  9404. *
  9405. * Perform bidiagonal QR iteration, if desired, computing
  9406. * left singular vectors in A and computing right singular
  9407. * vectors in VT
  9408. * (Workspace: need BDSPAC)
  9409. *
  9410. CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
  9411. $ LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
  9412. END IF
  9413. *
  9414. END IF
  9415. *
  9416. ELSE
  9417. *
  9418. * A has more columns than rows. If A has sufficiently more
  9419. * columns than rows, first reduce using the LQ decomposition (if
  9420. * sufficient workspace available)
  9421. *
  9422. IF( N.GE.MNTHR ) THEN
  9423. *
  9424. IF( WNTVN ) THEN
  9425. *
  9426. * Path 1t(N much larger than M, JOBVT='N')
  9427. * No right singular vectors to be computed
  9428. *
  9429. ITAU = 1
  9430. IWORK = ITAU + M
  9431. *
  9432. * Compute A=L*Q
  9433. * (Workspace: need 2*M, prefer M+M*NB)
  9434. *
  9435. CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
  9436. $ LWORK-IWORK+1, IERR )
  9437. *
  9438. * Zero out above L
  9439. *
  9440. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )
  9441. IE = 1
  9442. ITAUQ = IE + M
  9443. ITAUP = ITAUQ + M
  9444. IWORK = ITAUP + M
  9445. *
  9446. * Bidiagonalize L in A
  9447. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  9448. *
  9449. CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  9450. $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
  9451. $ IERR )
  9452. IF( WNTUO .OR. WNTUAS ) THEN
  9453. *
  9454. * If left singular vectors desired, generate Q
  9455. * (Workspace: need 4*M, prefer 3*M+M*NB)
  9456. *
  9457. CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
  9458. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9459. END IF
  9460. IWORK = IE + M
  9461. NRU = 0
  9462. IF( WNTUO .OR. WNTUAS )
  9463. $ NRU = M
  9464. *
  9465. * Perform bidiagonal QR iteration, computing left singular
  9466. * vectors of A in A if desired
  9467. * (Workspace: need BDSPAC)
  9468. *
  9469. CALL DBDSQR( 'U', M, 0, NRU, 0, S, WORK( IE ), DUM, 1, A,
  9470. $ LDA, DUM, 1, WORK( IWORK ), INFO )
  9471. *
  9472. * If left singular vectors desired in U, copy them there
  9473. *
  9474. IF( WNTUAS )
  9475. $ CALL DLACPY( 'F', M, M, A, LDA, U, LDU )
  9476. *
  9477. ELSE IF( WNTVO .AND. WNTUN ) THEN
  9478. *
  9479. * Path 2t(N much larger than M, JOBU='N', JOBVT='O')
  9480. * M right singular vectors to be overwritten on A and
  9481. * no left singular vectors to be computed
  9482. *
  9483. IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
  9484. *
  9485. * Sufficient workspace for a fast algorithm
  9486. *
  9487. IR = 1
  9488. IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
  9489. *
  9490. * WORK(IU) is LDA by N and WORK(IR) is LDA by M
  9491. *
  9492. LDWRKU = LDA
  9493. CHUNK = N
  9494. LDWRKR = LDA
  9495. ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
  9496. *
  9497. * WORK(IU) is LDA by N and WORK(IR) is M by M
  9498. *
  9499. LDWRKU = LDA
  9500. CHUNK = N
  9501. LDWRKR = M
  9502. ELSE
  9503. *
  9504. * WORK(IU) is M by CHUNK and WORK(IR) is M by M
  9505. *
  9506. LDWRKU = M
  9507. CHUNK = ( LWORK-M*M-M ) / M
  9508. LDWRKR = M
  9509. END IF
  9510. ITAU = IR + LDWRKR*M
  9511. IWORK = ITAU + M
  9512. *
  9513. * Compute A=L*Q
  9514. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  9515. *
  9516. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  9517. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9518. *
  9519. * Copy L to WORK(IR) and zero out above it
  9520. *
  9521. CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )
  9522. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  9523. $ WORK( IR+LDWRKR ), LDWRKR )
  9524. *
  9525. * Generate Q in A
  9526. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  9527. *
  9528. CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
  9529. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9530. IE = ITAU
  9531. ITAUQ = IE + M
  9532. ITAUP = ITAUQ + M
  9533. IWORK = ITAUP + M
  9534. *
  9535. * Bidiagonalize L in WORK(IR)
  9536. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  9537. *
  9538. CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S, WORK( IE ),
  9539. $ WORK( ITAUQ ), WORK( ITAUP ),
  9540. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9541. *
  9542. * Generate right vectors bidiagonalizing L
  9543. * (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
  9544. *
  9545. CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
  9546. $ WORK( ITAUP ), WORK( IWORK ),
  9547. $ LWORK-IWORK+1, IERR )
  9548. IWORK = IE + M
  9549. *
  9550. * Perform bidiagonal QR iteration, computing right
  9551. * singular vectors of L in WORK(IR)
  9552. * (Workspace: need M*M+BDSPAC)
  9553. *
  9554. CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
  9555. $ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
  9556. $ WORK( IWORK ), INFO )
  9557. IU = IE + M
  9558. *
  9559. * Multiply right singular vectors of L in WORK(IR) by Q
  9560. * in A, storing result in WORK(IU) and copying to A
  9561. * (Workspace: need M*M+2*M, prefer M*M+M*N+M)
  9562. *
  9563. DO 30 I = 1, N, CHUNK
  9564. BLK = MIN( N-I+1, CHUNK )
  9565. CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
  9566. $ LDWRKR, A( 1, I ), LDA, ZERO,
  9567. $ WORK( IU ), LDWRKU )
  9568. CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
  9569. $ A( 1, I ), LDA )
  9570. 30 CONTINUE
  9571. *
  9572. ELSE
  9573. *
  9574. * Insufficient workspace for a fast algorithm
  9575. *
  9576. IE = 1
  9577. ITAUQ = IE + M
  9578. ITAUP = ITAUQ + M
  9579. IWORK = ITAUP + M
  9580. *
  9581. * Bidiagonalize A
  9582. * (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
  9583. *
  9584. CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
  9585. $ WORK( ITAUQ ), WORK( ITAUP ),
  9586. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9587. *
  9588. * Generate right vectors bidiagonalizing A
  9589. * (Workspace: need 4*M, prefer 3*M+M*NB)
  9590. *
  9591. CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
  9592. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9593. IWORK = IE + M
  9594. *
  9595. * Perform bidiagonal QR iteration, computing right
  9596. * singular vectors of A in A
  9597. * (Workspace: need BDSPAC)
  9598. *
  9599. CALL DBDSQR( 'L', M, N, 0, 0, S, WORK( IE ), A, LDA,
  9600. $ DUM, 1, DUM, 1, WORK( IWORK ), INFO )
  9601. *
  9602. END IF
  9603. *
  9604. ELSE IF( WNTVO .AND. WNTUAS ) THEN
  9605. *
  9606. * Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')
  9607. * M right singular vectors to be overwritten on A and
  9608. * M left singular vectors to be computed in U
  9609. *
  9610. IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
  9611. *
  9612. * Sufficient workspace for a fast algorithm
  9613. *
  9614. IR = 1
  9615. IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
  9616. *
  9617. * WORK(IU) is LDA by N and WORK(IR) is LDA by M
  9618. *
  9619. LDWRKU = LDA
  9620. CHUNK = N
  9621. LDWRKR = LDA
  9622. ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
  9623. *
  9624. * WORK(IU) is LDA by N and WORK(IR) is M by M
  9625. *
  9626. LDWRKU = LDA
  9627. CHUNK = N
  9628. LDWRKR = M
  9629. ELSE
  9630. *
  9631. * WORK(IU) is M by CHUNK and WORK(IR) is M by M
  9632. *
  9633. LDWRKU = M
  9634. CHUNK = ( LWORK-M*M-M ) / M
  9635. LDWRKR = M
  9636. END IF
  9637. ITAU = IR + LDWRKR*M
  9638. IWORK = ITAU + M
  9639. *
  9640. * Compute A=L*Q
  9641. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  9642. *
  9643. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  9644. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9645. *
  9646. * Copy L to U, zeroing about above it
  9647. *
  9648. CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
  9649. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
  9650. $ LDU )
  9651. *
  9652. * Generate Q in A
  9653. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  9654. *
  9655. CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
  9656. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9657. IE = ITAU
  9658. ITAUQ = IE + M
  9659. ITAUP = ITAUQ + M
  9660. IWORK = ITAUP + M
  9661. *
  9662. * Bidiagonalize L in U, copying result to WORK(IR)
  9663. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  9664. *
  9665. CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
  9666. $ WORK( ITAUQ ), WORK( ITAUP ),
  9667. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9668. CALL DLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
  9669. *
  9670. * Generate right vectors bidiagonalizing L in WORK(IR)
  9671. * (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
  9672. *
  9673. CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
  9674. $ WORK( ITAUP ), WORK( IWORK ),
  9675. $ LWORK-IWORK+1, IERR )
  9676. *
  9677. * Generate left vectors bidiagonalizing L in U
  9678. * (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
  9679. *
  9680. CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
  9681. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9682. IWORK = IE + M
  9683. *
  9684. * Perform bidiagonal QR iteration, computing left
  9685. * singular vectors of L in U, and computing right
  9686. * singular vectors of L in WORK(IR)
  9687. * (Workspace: need M*M+BDSPAC)
  9688. *
  9689. CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
  9690. $ WORK( IR ), LDWRKR, U, LDU, DUM, 1,
  9691. $ WORK( IWORK ), INFO )
  9692. IU = IE + M
  9693. *
  9694. * Multiply right singular vectors of L in WORK(IR) by Q
  9695. * in A, storing result in WORK(IU) and copying to A
  9696. * (Workspace: need M*M+2*M, prefer M*M+M*N+M))
  9697. *
  9698. DO 40 I = 1, N, CHUNK
  9699. BLK = MIN( N-I+1, CHUNK )
  9700. CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
  9701. $ LDWRKR, A( 1, I ), LDA, ZERO,
  9702. $ WORK( IU ), LDWRKU )
  9703. CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
  9704. $ A( 1, I ), LDA )
  9705. 40 CONTINUE
  9706. *
  9707. ELSE
  9708. *
  9709. * Insufficient workspace for a fast algorithm
  9710. *
  9711. ITAU = 1
  9712. IWORK = ITAU + M
  9713. *
  9714. * Compute A=L*Q
  9715. * (Workspace: need 2*M, prefer M+M*NB)
  9716. *
  9717. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  9718. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9719. *
  9720. * Copy L to U, zeroing out above it
  9721. *
  9722. CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
  9723. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
  9724. $ LDU )
  9725. *
  9726. * Generate Q in A
  9727. * (Workspace: need 2*M, prefer M+M*NB)
  9728. *
  9729. CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
  9730. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9731. IE = ITAU
  9732. ITAUQ = IE + M
  9733. ITAUP = ITAUQ + M
  9734. IWORK = ITAUP + M
  9735. *
  9736. * Bidiagonalize L in U
  9737. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  9738. *
  9739. CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
  9740. $ WORK( ITAUQ ), WORK( ITAUP ),
  9741. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9742. *
  9743. * Multiply right vectors bidiagonalizing L by Q in A
  9744. * (Workspace: need 3*M+N, prefer 3*M+N*NB)
  9745. *
  9746. CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
  9747. $ WORK( ITAUP ), A, LDA, WORK( IWORK ),
  9748. $ LWORK-IWORK+1, IERR )
  9749. *
  9750. * Generate left vectors bidiagonalizing L in U
  9751. * (Workspace: need 4*M, prefer 3*M+M*NB)
  9752. *
  9753. CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
  9754. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9755. IWORK = IE + M
  9756. *
  9757. * Perform bidiagonal QR iteration, computing left
  9758. * singular vectors of A in U and computing right
  9759. * singular vectors of A in A
  9760. * (Workspace: need BDSPAC)
  9761. *
  9762. CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), A, LDA,
  9763. $ U, LDU, DUM, 1, WORK( IWORK ), INFO )
  9764. *
  9765. END IF
  9766. *
  9767. ELSE IF( WNTVS ) THEN
  9768. *
  9769. IF( WNTUN ) THEN
  9770. *
  9771. * Path 4t(N much larger than M, JOBU='N', JOBVT='S')
  9772. * M right singular vectors to be computed in VT and
  9773. * no left singular vectors to be computed
  9774. *
  9775. IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
  9776. *
  9777. * Sufficient workspace for a fast algorithm
  9778. *
  9779. IR = 1
  9780. IF( LWORK.GE.WRKBL+LDA*M ) THEN
  9781. *
  9782. * WORK(IR) is LDA by M
  9783. *
  9784. LDWRKR = LDA
  9785. ELSE
  9786. *
  9787. * WORK(IR) is M by M
  9788. *
  9789. LDWRKR = M
  9790. END IF
  9791. ITAU = IR + LDWRKR*M
  9792. IWORK = ITAU + M
  9793. *
  9794. * Compute A=L*Q
  9795. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  9796. *
  9797. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  9798. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9799. *
  9800. * Copy L to WORK(IR), zeroing out above it
  9801. *
  9802. CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),
  9803. $ LDWRKR )
  9804. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  9805. $ WORK( IR+LDWRKR ), LDWRKR )
  9806. *
  9807. * Generate Q in A
  9808. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  9809. *
  9810. CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
  9811. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9812. IE = ITAU
  9813. ITAUQ = IE + M
  9814. ITAUP = ITAUQ + M
  9815. IWORK = ITAUP + M
  9816. *
  9817. * Bidiagonalize L in WORK(IR)
  9818. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  9819. *
  9820. CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
  9821. $ WORK( IE ), WORK( ITAUQ ),
  9822. $ WORK( ITAUP ), WORK( IWORK ),
  9823. $ LWORK-IWORK+1, IERR )
  9824. *
  9825. * Generate right vectors bidiagonalizing L in
  9826. * WORK(IR)
  9827. * (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
  9828. *
  9829. CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
  9830. $ WORK( ITAUP ), WORK( IWORK ),
  9831. $ LWORK-IWORK+1, IERR )
  9832. IWORK = IE + M
  9833. *
  9834. * Perform bidiagonal QR iteration, computing right
  9835. * singular vectors of L in WORK(IR)
  9836. * (Workspace: need M*M+BDSPAC)
  9837. *
  9838. CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
  9839. $ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
  9840. $ WORK( IWORK ), INFO )
  9841. *
  9842. * Multiply right singular vectors of L in WORK(IR) by
  9843. * Q in A, storing result in VT
  9844. * (Workspace: need M*M)
  9845. *
  9846. CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
  9847. $ LDWRKR, A, LDA, ZERO, VT, LDVT )
  9848. *
  9849. ELSE
  9850. *
  9851. * Insufficient workspace for a fast algorithm
  9852. *
  9853. ITAU = 1
  9854. IWORK = ITAU + M
  9855. *
  9856. * Compute A=L*Q
  9857. * (Workspace: need 2*M, prefer M+M*NB)
  9858. *
  9859. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  9860. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9861. *
  9862. * Copy result to VT
  9863. *
  9864. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  9865. *
  9866. * Generate Q in VT
  9867. * (Workspace: need 2*M, prefer M+M*NB)
  9868. *
  9869. CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
  9870. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9871. IE = ITAU
  9872. ITAUQ = IE + M
  9873. ITAUP = ITAUQ + M
  9874. IWORK = ITAUP + M
  9875. *
  9876. * Zero out above L in A
  9877. *
  9878. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
  9879. $ LDA )
  9880. *
  9881. * Bidiagonalize L in A
  9882. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  9883. *
  9884. CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
  9885. $ WORK( ITAUQ ), WORK( ITAUP ),
  9886. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9887. *
  9888. * Multiply right vectors bidiagonalizing L by Q in VT
  9889. * (Workspace: need 3*M+N, prefer 3*M+N*NB)
  9890. *
  9891. CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
  9892. $ WORK( ITAUP ), VT, LDVT,
  9893. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9894. IWORK = IE + M
  9895. *
  9896. * Perform bidiagonal QR iteration, computing right
  9897. * singular vectors of A in VT
  9898. * (Workspace: need BDSPAC)
  9899. *
  9900. CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
  9901. $ LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
  9902. $ INFO )
  9903. *
  9904. END IF
  9905. *
  9906. ELSE IF( WNTUO ) THEN
  9907. *
  9908. * Path 5t(N much larger than M, JOBU='O', JOBVT='S')
  9909. * M right singular vectors to be computed in VT and
  9910. * M left singular vectors to be overwritten on A
  9911. *
  9912. IF( LWORK.GE.2*M*M+MAX( 4*M, BDSPAC ) ) THEN
  9913. *
  9914. * Sufficient workspace for a fast algorithm
  9915. *
  9916. IU = 1
  9917. IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
  9918. *
  9919. * WORK(IU) is LDA by M and WORK(IR) is LDA by M
  9920. *
  9921. LDWRKU = LDA
  9922. IR = IU + LDWRKU*M
  9923. LDWRKR = LDA
  9924. ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
  9925. *
  9926. * WORK(IU) is LDA by M and WORK(IR) is M by M
  9927. *
  9928. LDWRKU = LDA
  9929. IR = IU + LDWRKU*M
  9930. LDWRKR = M
  9931. ELSE
  9932. *
  9933. * WORK(IU) is M by M and WORK(IR) is M by M
  9934. *
  9935. LDWRKU = M
  9936. IR = IU + LDWRKU*M
  9937. LDWRKR = M
  9938. END IF
  9939. ITAU = IR + LDWRKR*M
  9940. IWORK = ITAU + M
  9941. *
  9942. * Compute A=L*Q
  9943. * (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
  9944. *
  9945. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  9946. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9947. *
  9948. * Copy L to WORK(IU), zeroing out below it
  9949. *
  9950. CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
  9951. $ LDWRKU )
  9952. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  9953. $ WORK( IU+LDWRKU ), LDWRKU )
  9954. *
  9955. * Generate Q in A
  9956. * (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
  9957. *
  9958. CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
  9959. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  9960. IE = ITAU
  9961. ITAUQ = IE + M
  9962. ITAUP = ITAUQ + M
  9963. IWORK = ITAUP + M
  9964. *
  9965. * Bidiagonalize L in WORK(IU), copying result to
  9966. * WORK(IR)
  9967. * (Workspace: need 2*M*M+4*M,
  9968. * prefer 2*M*M+3*M+2*M*NB)
  9969. *
  9970. CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
  9971. $ WORK( IE ), WORK( ITAUQ ),
  9972. $ WORK( ITAUP ), WORK( IWORK ),
  9973. $ LWORK-IWORK+1, IERR )
  9974. CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,
  9975. $ WORK( IR ), LDWRKR )
  9976. *
  9977. * Generate right bidiagonalizing vectors in WORK(IU)
  9978. * (Workspace: need 2*M*M+4*M-1,
  9979. * prefer 2*M*M+3*M+(M-1)*NB)
  9980. *
  9981. CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
  9982. $ WORK( ITAUP ), WORK( IWORK ),
  9983. $ LWORK-IWORK+1, IERR )
  9984. *
  9985. * Generate left bidiagonalizing vectors in WORK(IR)
  9986. * (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
  9987. *
  9988. CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
  9989. $ WORK( ITAUQ ), WORK( IWORK ),
  9990. $ LWORK-IWORK+1, IERR )
  9991. IWORK = IE + M
  9992. *
  9993. * Perform bidiagonal QR iteration, computing left
  9994. * singular vectors of L in WORK(IR) and computing
  9995. * right singular vectors of L in WORK(IU)
  9996. * (Workspace: need 2*M*M+BDSPAC)
  9997. *
  9998. CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
  9999. $ WORK( IU ), LDWRKU, WORK( IR ),
  10000. $ LDWRKR, DUM, 1, WORK( IWORK ), INFO )
  10001. *
  10002. * Multiply right singular vectors of L in WORK(IU) by
  10003. * Q in A, storing result in VT
  10004. * (Workspace: need M*M)
  10005. *
  10006. CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
  10007. $ LDWRKU, A, LDA, ZERO, VT, LDVT )
  10008. *
  10009. * Copy left singular vectors of L to A
  10010. * (Workspace: need M*M)
  10011. *
  10012. CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
  10013. $ LDA )
  10014. *
  10015. ELSE
  10016. *
  10017. * Insufficient workspace for a fast algorithm
  10018. *
  10019. ITAU = 1
  10020. IWORK = ITAU + M
  10021. *
  10022. * Compute A=L*Q, copying result to VT
  10023. * (Workspace: need 2*M, prefer M+M*NB)
  10024. *
  10025. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10026. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10027. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10028. *
  10029. * Generate Q in VT
  10030. * (Workspace: need 2*M, prefer M+M*NB)
  10031. *
  10032. CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
  10033. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10034. IE = ITAU
  10035. ITAUQ = IE + M
  10036. ITAUP = ITAUQ + M
  10037. IWORK = ITAUP + M
  10038. *
  10039. * Zero out above L in A
  10040. *
  10041. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
  10042. $ LDA )
  10043. *
  10044. * Bidiagonalize L in A
  10045. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  10046. *
  10047. CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
  10048. $ WORK( ITAUQ ), WORK( ITAUP ),
  10049. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10050. *
  10051. * Multiply right vectors bidiagonalizing L by Q in VT
  10052. * (Workspace: need 3*M+N, prefer 3*M+N*NB)
  10053. *
  10054. CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
  10055. $ WORK( ITAUP ), VT, LDVT,
  10056. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10057. *
  10058. * Generate left bidiagonalizing vectors of L in A
  10059. * (Workspace: need 4*M, prefer 3*M+M*NB)
  10060. *
  10061. CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
  10062. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10063. IWORK = IE + M
  10064. *
  10065. * Perform bidiagonal QR iteration, compute left
  10066. * singular vectors of A in A and compute right
  10067. * singular vectors of A in VT
  10068. * (Workspace: need BDSPAC)
  10069. *
  10070. CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
  10071. $ LDVT, A, LDA, DUM, 1, WORK( IWORK ),
  10072. $ INFO )
  10073. *
  10074. END IF
  10075. *
  10076. ELSE IF( WNTUAS ) THEN
  10077. *
  10078. * Path 6t(N much larger than M, JOBU='S' or 'A',
  10079. * JOBVT='S')
  10080. * M right singular vectors to be computed in VT and
  10081. * M left singular vectors to be computed in U
  10082. *
  10083. IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
  10084. *
  10085. * Sufficient workspace for a fast algorithm
  10086. *
  10087. IU = 1
  10088. IF( LWORK.GE.WRKBL+LDA*M ) THEN
  10089. *
  10090. * WORK(IU) is LDA by N
  10091. *
  10092. LDWRKU = LDA
  10093. ELSE
  10094. *
  10095. * WORK(IU) is LDA by M
  10096. *
  10097. LDWRKU = M
  10098. END IF
  10099. ITAU = IU + LDWRKU*M
  10100. IWORK = ITAU + M
  10101. *
  10102. * Compute A=L*Q
  10103. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  10104. *
  10105. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10106. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10107. *
  10108. * Copy L to WORK(IU), zeroing out above it
  10109. *
  10110. CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
  10111. $ LDWRKU )
  10112. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  10113. $ WORK( IU+LDWRKU ), LDWRKU )
  10114. *
  10115. * Generate Q in A
  10116. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  10117. *
  10118. CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
  10119. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10120. IE = ITAU
  10121. ITAUQ = IE + M
  10122. ITAUP = ITAUQ + M
  10123. IWORK = ITAUP + M
  10124. *
  10125. * Bidiagonalize L in WORK(IU), copying result to U
  10126. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  10127. *
  10128. CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
  10129. $ WORK( IE ), WORK( ITAUQ ),
  10130. $ WORK( ITAUP ), WORK( IWORK ),
  10131. $ LWORK-IWORK+1, IERR )
  10132. CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
  10133. $ LDU )
  10134. *
  10135. * Generate right bidiagonalizing vectors in WORK(IU)
  10136. * (Workspace: need M*M+4*M-1,
  10137. * prefer M*M+3*M+(M-1)*NB)
  10138. *
  10139. CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
  10140. $ WORK( ITAUP ), WORK( IWORK ),
  10141. $ LWORK-IWORK+1, IERR )
  10142. *
  10143. * Generate left bidiagonalizing vectors in U
  10144. * (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
  10145. *
  10146. CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
  10147. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10148. IWORK = IE + M
  10149. *
  10150. * Perform bidiagonal QR iteration, computing left
  10151. * singular vectors of L in U and computing right
  10152. * singular vectors of L in WORK(IU)
  10153. * (Workspace: need M*M+BDSPAC)
  10154. *
  10155. CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
  10156. $ WORK( IU ), LDWRKU, U, LDU, DUM, 1,
  10157. $ WORK( IWORK ), INFO )
  10158. *
  10159. * Multiply right singular vectors of L in WORK(IU) by
  10160. * Q in A, storing result in VT
  10161. * (Workspace: need M*M)
  10162. *
  10163. CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
  10164. $ LDWRKU, A, LDA, ZERO, VT, LDVT )
  10165. *
  10166. ELSE
  10167. *
  10168. * Insufficient workspace for a fast algorithm
  10169. *
  10170. ITAU = 1
  10171. IWORK = ITAU + M
  10172. *
  10173. * Compute A=L*Q, copying result to VT
  10174. * (Workspace: need 2*M, prefer M+M*NB)
  10175. *
  10176. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10177. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10178. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10179. *
  10180. * Generate Q in VT
  10181. * (Workspace: need 2*M, prefer M+M*NB)
  10182. *
  10183. CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
  10184. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10185. *
  10186. * Copy L to U, zeroing out above it
  10187. *
  10188. CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
  10189. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
  10190. $ LDU )
  10191. IE = ITAU
  10192. ITAUQ = IE + M
  10193. ITAUP = ITAUQ + M
  10194. IWORK = ITAUP + M
  10195. *
  10196. * Bidiagonalize L in U
  10197. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  10198. *
  10199. CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
  10200. $ WORK( ITAUQ ), WORK( ITAUP ),
  10201. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10202. *
  10203. * Multiply right bidiagonalizing vectors in U by Q
  10204. * in VT
  10205. * (Workspace: need 3*M+N, prefer 3*M+N*NB)
  10206. *
  10207. CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
  10208. $ WORK( ITAUP ), VT, LDVT,
  10209. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10210. *
  10211. * Generate left bidiagonalizing vectors in U
  10212. * (Workspace: need 4*M, prefer 3*M+M*NB)
  10213. *
  10214. CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
  10215. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10216. IWORK = IE + M
  10217. *
  10218. * Perform bidiagonal QR iteration, computing left
  10219. * singular vectors of A in U and computing right
  10220. * singular vectors of A in VT
  10221. * (Workspace: need BDSPAC)
  10222. *
  10223. CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
  10224. $ LDVT, U, LDU, DUM, 1, WORK( IWORK ),
  10225. $ INFO )
  10226. *
  10227. END IF
  10228. *
  10229. END IF
  10230. *
  10231. ELSE IF( WNTVA ) THEN
  10232. *
  10233. IF( WNTUN ) THEN
  10234. *
  10235. * Path 7t(N much larger than M, JOBU='N', JOBVT='A')
  10236. * N right singular vectors to be computed in VT and
  10237. * no left singular vectors to be computed
  10238. *
  10239. IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
  10240. *
  10241. * Sufficient workspace for a fast algorithm
  10242. *
  10243. IR = 1
  10244. IF( LWORK.GE.WRKBL+LDA*M ) THEN
  10245. *
  10246. * WORK(IR) is LDA by M
  10247. *
  10248. LDWRKR = LDA
  10249. ELSE
  10250. *
  10251. * WORK(IR) is M by M
  10252. *
  10253. LDWRKR = M
  10254. END IF
  10255. ITAU = IR + LDWRKR*M
  10256. IWORK = ITAU + M
  10257. *
  10258. * Compute A=L*Q, copying result to VT
  10259. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  10260. *
  10261. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10262. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10263. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10264. *
  10265. * Copy L to WORK(IR), zeroing out above it
  10266. *
  10267. CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),
  10268. $ LDWRKR )
  10269. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  10270. $ WORK( IR+LDWRKR ), LDWRKR )
  10271. *
  10272. * Generate Q in VT
  10273. * (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
  10274. *
  10275. CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
  10276. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10277. IE = ITAU
  10278. ITAUQ = IE + M
  10279. ITAUP = ITAUQ + M
  10280. IWORK = ITAUP + M
  10281. *
  10282. * Bidiagonalize L in WORK(IR)
  10283. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  10284. *
  10285. CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
  10286. $ WORK( IE ), WORK( ITAUQ ),
  10287. $ WORK( ITAUP ), WORK( IWORK ),
  10288. $ LWORK-IWORK+1, IERR )
  10289. *
  10290. * Generate right bidiagonalizing vectors in WORK(IR)
  10291. * (Workspace: need M*M+4*M-1,
  10292. * prefer M*M+3*M+(M-1)*NB)
  10293. *
  10294. CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
  10295. $ WORK( ITAUP ), WORK( IWORK ),
  10296. $ LWORK-IWORK+1, IERR )
  10297. IWORK = IE + M
  10298. *
  10299. * Perform bidiagonal QR iteration, computing right
  10300. * singular vectors of L in WORK(IR)
  10301. * (Workspace: need M*M+BDSPAC)
  10302. *
  10303. CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
  10304. $ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
  10305. $ WORK( IWORK ), INFO )
  10306. *
  10307. * Multiply right singular vectors of L in WORK(IR) by
  10308. * Q in VT, storing result in A
  10309. * (Workspace: need M*M)
  10310. *
  10311. CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
  10312. $ LDWRKR, VT, LDVT, ZERO, A, LDA )
  10313. *
  10314. * Copy right singular vectors of A from A to VT
  10315. *
  10316. CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
  10317. *
  10318. ELSE
  10319. *
  10320. * Insufficient workspace for a fast algorithm
  10321. *
  10322. ITAU = 1
  10323. IWORK = ITAU + M
  10324. *
  10325. * Compute A=L*Q, copying result to VT
  10326. * (Workspace: need 2*M, prefer M+M*NB)
  10327. *
  10328. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10329. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10330. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10331. *
  10332. * Generate Q in VT
  10333. * (Workspace: need M+N, prefer M+N*NB)
  10334. *
  10335. CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
  10336. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10337. IE = ITAU
  10338. ITAUQ = IE + M
  10339. ITAUP = ITAUQ + M
  10340. IWORK = ITAUP + M
  10341. *
  10342. * Zero out above L in A
  10343. *
  10344. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
  10345. $ LDA )
  10346. *
  10347. * Bidiagonalize L in A
  10348. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  10349. *
  10350. CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
  10351. $ WORK( ITAUQ ), WORK( ITAUP ),
  10352. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10353. *
  10354. * Multiply right bidiagonalizing vectors in A by Q
  10355. * in VT
  10356. * (Workspace: need 3*M+N, prefer 3*M+N*NB)
  10357. *
  10358. CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
  10359. $ WORK( ITAUP ), VT, LDVT,
  10360. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10361. IWORK = IE + M
  10362. *
  10363. * Perform bidiagonal QR iteration, computing right
  10364. * singular vectors of A in VT
  10365. * (Workspace: need BDSPAC)
  10366. *
  10367. CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
  10368. $ LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
  10369. $ INFO )
  10370. *
  10371. END IF
  10372. *
  10373. ELSE IF( WNTUO ) THEN
  10374. *
  10375. * Path 8t(N much larger than M, JOBU='O', JOBVT='A')
  10376. * N right singular vectors to be computed in VT and
  10377. * M left singular vectors to be overwritten on A
  10378. *
  10379. IF( LWORK.GE.2*M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
  10380. *
  10381. * Sufficient workspace for a fast algorithm
  10382. *
  10383. IU = 1
  10384. IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
  10385. *
  10386. * WORK(IU) is LDA by M and WORK(IR) is LDA by M
  10387. *
  10388. LDWRKU = LDA
  10389. IR = IU + LDWRKU*M
  10390. LDWRKR = LDA
  10391. ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
  10392. *
  10393. * WORK(IU) is LDA by M and WORK(IR) is M by M
  10394. *
  10395. LDWRKU = LDA
  10396. IR = IU + LDWRKU*M
  10397. LDWRKR = M
  10398. ELSE
  10399. *
  10400. * WORK(IU) is M by M and WORK(IR) is M by M
  10401. *
  10402. LDWRKU = M
  10403. IR = IU + LDWRKU*M
  10404. LDWRKR = M
  10405. END IF
  10406. ITAU = IR + LDWRKR*M
  10407. IWORK = ITAU + M
  10408. *
  10409. * Compute A=L*Q, copying result to VT
  10410. * (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
  10411. *
  10412. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10413. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10414. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10415. *
  10416. * Generate Q in VT
  10417. * (Workspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)
  10418. *
  10419. CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
  10420. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10421. *
  10422. * Copy L to WORK(IU), zeroing out above it
  10423. *
  10424. CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
  10425. $ LDWRKU )
  10426. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  10427. $ WORK( IU+LDWRKU ), LDWRKU )
  10428. IE = ITAU
  10429. ITAUQ = IE + M
  10430. ITAUP = ITAUQ + M
  10431. IWORK = ITAUP + M
  10432. *
  10433. * Bidiagonalize L in WORK(IU), copying result to
  10434. * WORK(IR)
  10435. * (Workspace: need 2*M*M+4*M,
  10436. * prefer 2*M*M+3*M+2*M*NB)
  10437. *
  10438. CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
  10439. $ WORK( IE ), WORK( ITAUQ ),
  10440. $ WORK( ITAUP ), WORK( IWORK ),
  10441. $ LWORK-IWORK+1, IERR )
  10442. CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,
  10443. $ WORK( IR ), LDWRKR )
  10444. *
  10445. * Generate right bidiagonalizing vectors in WORK(IU)
  10446. * (Workspace: need 2*M*M+4*M-1,
  10447. * prefer 2*M*M+3*M+(M-1)*NB)
  10448. *
  10449. CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
  10450. $ WORK( ITAUP ), WORK( IWORK ),
  10451. $ LWORK-IWORK+1, IERR )
  10452. *
  10453. * Generate left bidiagonalizing vectors in WORK(IR)
  10454. * (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
  10455. *
  10456. CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
  10457. $ WORK( ITAUQ ), WORK( IWORK ),
  10458. $ LWORK-IWORK+1, IERR )
  10459. IWORK = IE + M
  10460. *
  10461. * Perform bidiagonal QR iteration, computing left
  10462. * singular vectors of L in WORK(IR) and computing
  10463. * right singular vectors of L in WORK(IU)
  10464. * (Workspace: need 2*M*M+BDSPAC)
  10465. *
  10466. CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
  10467. $ WORK( IU ), LDWRKU, WORK( IR ),
  10468. $ LDWRKR, DUM, 1, WORK( IWORK ), INFO )
  10469. *
  10470. * Multiply right singular vectors of L in WORK(IU) by
  10471. * Q in VT, storing result in A
  10472. * (Workspace: need M*M)
  10473. *
  10474. CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
  10475. $ LDWRKU, VT, LDVT, ZERO, A, LDA )
  10476. *
  10477. * Copy right singular vectors of A from A to VT
  10478. *
  10479. CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
  10480. *
  10481. * Copy left singular vectors of A from WORK(IR) to A
  10482. *
  10483. CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
  10484. $ LDA )
  10485. *
  10486. ELSE
  10487. *
  10488. * Insufficient workspace for a fast algorithm
  10489. *
  10490. ITAU = 1
  10491. IWORK = ITAU + M
  10492. *
  10493. * Compute A=L*Q, copying result to VT
  10494. * (Workspace: need 2*M, prefer M+M*NB)
  10495. *
  10496. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10497. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10498. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10499. *
  10500. * Generate Q in VT
  10501. * (Workspace: need M+N, prefer M+N*NB)
  10502. *
  10503. CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
  10504. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10505. IE = ITAU
  10506. ITAUQ = IE + M
  10507. ITAUP = ITAUQ + M
  10508. IWORK = ITAUP + M
  10509. *
  10510. * Zero out above L in A
  10511. *
  10512. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
  10513. $ LDA )
  10514. *
  10515. * Bidiagonalize L in A
  10516. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  10517. *
  10518. CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
  10519. $ WORK( ITAUQ ), WORK( ITAUP ),
  10520. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10521. *
  10522. * Multiply right bidiagonalizing vectors in A by Q
  10523. * in VT
  10524. * (Workspace: need 3*M+N, prefer 3*M+N*NB)
  10525. *
  10526. CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
  10527. $ WORK( ITAUP ), VT, LDVT,
  10528. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10529. *
  10530. * Generate left bidiagonalizing vectors in A
  10531. * (Workspace: need 4*M, prefer 3*M+M*NB)
  10532. *
  10533. CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
  10534. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10535. IWORK = IE + M
  10536. *
  10537. * Perform bidiagonal QR iteration, computing left
  10538. * singular vectors of A in A and computing right
  10539. * singular vectors of A in VT
  10540. * (Workspace: need BDSPAC)
  10541. *
  10542. CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
  10543. $ LDVT, A, LDA, DUM, 1, WORK( IWORK ),
  10544. $ INFO )
  10545. *
  10546. END IF
  10547. *
  10548. ELSE IF( WNTUAS ) THEN
  10549. *
  10550. * Path 9t(N much larger than M, JOBU='S' or 'A',
  10551. * JOBVT='A')
  10552. * N right singular vectors to be computed in VT and
  10553. * M left singular vectors to be computed in U
  10554. *
  10555. IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
  10556. *
  10557. * Sufficient workspace for a fast algorithm
  10558. *
  10559. IU = 1
  10560. IF( LWORK.GE.WRKBL+LDA*M ) THEN
  10561. *
  10562. * WORK(IU) is LDA by M
  10563. *
  10564. LDWRKU = LDA
  10565. ELSE
  10566. *
  10567. * WORK(IU) is M by M
  10568. *
  10569. LDWRKU = M
  10570. END IF
  10571. ITAU = IU + LDWRKU*M
  10572. IWORK = ITAU + M
  10573. *
  10574. * Compute A=L*Q, copying result to VT
  10575. * (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
  10576. *
  10577. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10578. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10579. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10580. *
  10581. * Generate Q in VT
  10582. * (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
  10583. *
  10584. CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
  10585. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10586. *
  10587. * Copy L to WORK(IU), zeroing out above it
  10588. *
  10589. CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
  10590. $ LDWRKU )
  10591. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
  10592. $ WORK( IU+LDWRKU ), LDWRKU )
  10593. IE = ITAU
  10594. ITAUQ = IE + M
  10595. ITAUP = ITAUQ + M
  10596. IWORK = ITAUP + M
  10597. *
  10598. * Bidiagonalize L in WORK(IU), copying result to U
  10599. * (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
  10600. *
  10601. CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
  10602. $ WORK( IE ), WORK( ITAUQ ),
  10603. $ WORK( ITAUP ), WORK( IWORK ),
  10604. $ LWORK-IWORK+1, IERR )
  10605. CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
  10606. $ LDU )
  10607. *
  10608. * Generate right bidiagonalizing vectors in WORK(IU)
  10609. * (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
  10610. *
  10611. CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
  10612. $ WORK( ITAUP ), WORK( IWORK ),
  10613. $ LWORK-IWORK+1, IERR )
  10614. *
  10615. * Generate left bidiagonalizing vectors in U
  10616. * (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
  10617. *
  10618. CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
  10619. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10620. IWORK = IE + M
  10621. *
  10622. * Perform bidiagonal QR iteration, computing left
  10623. * singular vectors of L in U and computing right
  10624. * singular vectors of L in WORK(IU)
  10625. * (Workspace: need M*M+BDSPAC)
  10626. *
  10627. CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
  10628. $ WORK( IU ), LDWRKU, U, LDU, DUM, 1,
  10629. $ WORK( IWORK ), INFO )
  10630. *
  10631. * Multiply right singular vectors of L in WORK(IU) by
  10632. * Q in VT, storing result in A
  10633. * (Workspace: need M*M)
  10634. *
  10635. CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
  10636. $ LDWRKU, VT, LDVT, ZERO, A, LDA )
  10637. *
  10638. * Copy right singular vectors of A from A to VT
  10639. *
  10640. CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
  10641. *
  10642. ELSE
  10643. *
  10644. * Insufficient workspace for a fast algorithm
  10645. *
  10646. ITAU = 1
  10647. IWORK = ITAU + M
  10648. *
  10649. * Compute A=L*Q, copying result to VT
  10650. * (Workspace: need 2*M, prefer M+M*NB)
  10651. *
  10652. CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
  10653. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10654. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10655. *
  10656. * Generate Q in VT
  10657. * (Workspace: need M+N, prefer M+N*NB)
  10658. *
  10659. CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
  10660. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10661. *
  10662. * Copy L to U, zeroing out above it
  10663. *
  10664. CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
  10665. CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
  10666. $ LDU )
  10667. IE = ITAU
  10668. ITAUQ = IE + M
  10669. ITAUP = ITAUQ + M
  10670. IWORK = ITAUP + M
  10671. *
  10672. * Bidiagonalize L in U
  10673. * (Workspace: need 4*M, prefer 3*M+2*M*NB)
  10674. *
  10675. CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
  10676. $ WORK( ITAUQ ), WORK( ITAUP ),
  10677. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10678. *
  10679. * Multiply right bidiagonalizing vectors in U by Q
  10680. * in VT
  10681. * (Workspace: need 3*M+N, prefer 3*M+N*NB)
  10682. *
  10683. CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
  10684. $ WORK( ITAUP ), VT, LDVT,
  10685. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10686. *
  10687. * Generate left bidiagonalizing vectors in U
  10688. * (Workspace: need 4*M, prefer 3*M+M*NB)
  10689. *
  10690. CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
  10691. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10692. IWORK = IE + M
  10693. *
  10694. * Perform bidiagonal QR iteration, computing left
  10695. * singular vectors of A in U and computing right
  10696. * singular vectors of A in VT
  10697. * (Workspace: need BDSPAC)
  10698. *
  10699. CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
  10700. $ LDVT, U, LDU, DUM, 1, WORK( IWORK ),
  10701. $ INFO )
  10702. *
  10703. END IF
  10704. *
  10705. END IF
  10706. *
  10707. END IF
  10708. *
  10709. ELSE
  10710. *
  10711. * N .LT. MNTHR
  10712. *
  10713. * Path 10t(N greater than M, but not much larger)
  10714. * Reduce to bidiagonal form without LQ decomposition
  10715. *
  10716. IE = 1
  10717. ITAUQ = IE + M
  10718. ITAUP = ITAUQ + M
  10719. IWORK = ITAUP + M
  10720. *
  10721. * Bidiagonalize A
  10722. * (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
  10723. *
  10724. CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
  10725. $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
  10726. $ IERR )
  10727. IF( WNTUAS ) THEN
  10728. *
  10729. * If left singular vectors desired in U, copy result to U
  10730. * and generate left bidiagonalizing vectors in U
  10731. * (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
  10732. *
  10733. CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
  10734. CALL DORGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
  10735. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10736. END IF
  10737. IF( WNTVAS ) THEN
  10738. *
  10739. * If right singular vectors desired in VT, copy result to
  10740. * VT and generate right bidiagonalizing vectors in VT
  10741. * (Workspace: need 3*M+NRVT, prefer 3*M+NRVT*NB)
  10742. *
  10743. CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
  10744. IF( WNTVA )
  10745. $ NRVT = N
  10746. IF( WNTVS )
  10747. $ NRVT = M
  10748. CALL DORGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),
  10749. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10750. END IF
  10751. IF( WNTUO ) THEN
  10752. *
  10753. * If left singular vectors desired in A, generate left
  10754. * bidiagonalizing vectors in A
  10755. * (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
  10756. *
  10757. CALL DORGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
  10758. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10759. END IF
  10760. IF( WNTVO ) THEN
  10761. *
  10762. * If right singular vectors desired in A, generate right
  10763. * bidiagonalizing vectors in A
  10764. * (Workspace: need 4*M, prefer 3*M+M*NB)
  10765. *
  10766. CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
  10767. $ WORK( IWORK ), LWORK-IWORK+1, IERR )
  10768. END IF
  10769. IWORK = IE + M
  10770. IF( WNTUAS .OR. WNTUO )
  10771. $ NRU = M
  10772. IF( WNTUN )
  10773. $ NRU = 0
  10774. IF( WNTVAS .OR. WNTVO )
  10775. $ NCVT = N
  10776. IF( WNTVN )
  10777. $ NCVT = 0
  10778. IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
  10779. *
  10780. * Perform bidiagonal QR iteration, if desired, computing
  10781. * left singular vectors in U and computing right singular
  10782. * vectors in VT
  10783. * (Workspace: need BDSPAC)
  10784. *
  10785. CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
  10786. $ LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
  10787. ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
  10788. *
  10789. * Perform bidiagonal QR iteration, if desired, computing
  10790. * left singular vectors in U and computing right singular
  10791. * vectors in A
  10792. * (Workspace: need BDSPAC)
  10793. *
  10794. CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
  10795. $ U, LDU, DUM, 1, WORK( IWORK ), INFO )
  10796. ELSE
  10797. *
  10798. * Perform bidiagonal QR iteration, if desired, computing
  10799. * left singular vectors in A and computing right singular
  10800. * vectors in VT
  10801. * (Workspace: need BDSPAC)
  10802. *
  10803. CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
  10804. $ LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
  10805. END IF
  10806. *
  10807. END IF
  10808. *
  10809. END IF
  10810. *
  10811. * If DBDSQR failed to converge, copy unconverged superdiagonals
  10812. * to WORK( 2:MINMN )
  10813. *
  10814. IF( INFO.NE.0 ) THEN
  10815. IF( IE.GT.2 ) THEN
  10816. DO 50 I = 1, MINMN - 1
  10817. WORK( I+1 ) = WORK( I+IE-1 )
  10818. 50 CONTINUE
  10819. END IF
  10820. IF( IE.LT.2 ) THEN
  10821. DO 60 I = MINMN - 1, 1, -1
  10822. WORK( I+1 ) = WORK( I+IE-1 )
  10823. 60 CONTINUE
  10824. END IF
  10825. END IF
  10826. *
  10827. * Undo scaling if necessary
  10828. *
  10829. IF( ISCL.EQ.1 ) THEN
  10830. IF( ANRM.GT.BIGNUM )
  10831. $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
  10832. $ IERR )
  10833. IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
  10834. $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1, WORK( 2 ),
  10835. $ MINMN, IERR )
  10836. IF( ANRM.LT.SMLNUM )
  10837. $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
  10838. $ IERR )
  10839. IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
  10840. $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1, WORK( 2 ),
  10841. $ MINMN, IERR )
  10842. END IF
  10843. *
  10844. * Return optimal workspace in WORK(1)
  10845. *
  10846. WORK( 1 ) = MAXWRK
  10847. *
  10848. RETURN
  10849. *
  10850. * End of DGESVD
  10851. *
  10852. END
  10853. SUBROUTINE DGESVX( FACT, TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV,
  10854. $ EQUED, R, C, B, LDB, X, LDX, RCOND, FERR, BERR,
  10855. $ WORK, IWORK, INFO )
  10856. *
  10857. * -- LAPACK driver routine (version 3.1) --
  10858. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  10859. * November 2006
  10860. *
  10861. * .. Scalar Arguments ..
  10862. CHARACTER EQUED, FACT, TRANS
  10863. INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS
  10864. DOUBLE PRECISION RCOND
  10865. * ..
  10866. * .. Array Arguments ..
  10867. INTEGER IPIV( * ), IWORK( * )
  10868. DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),
  10869. $ BERR( * ), C( * ), FERR( * ), R( * ),
  10870. $ WORK( * ), X( LDX, * )
  10871. * ..
  10872. *
  10873. * Purpose
  10874. * =======
  10875. *
  10876. * DGESVX uses the LU factorization to compute the solution to a real
  10877. * system of linear equations
  10878. * A * X = B,
  10879. * where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
  10880. *
  10881. * Error bounds on the solution and a condition estimate are also
  10882. * provided.
  10883. *
  10884. * Description
  10885. * ===========
  10886. *
  10887. * The following steps are performed:
  10888. *
  10889. * 1. If FACT = 'E', real scaling factors are computed to equilibrate
  10890. * the system:
  10891. * TRANS = 'N': diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
  10892. * TRANS = 'T': (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
  10893. * TRANS = 'C': (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
  10894. * Whether or not the system will be equilibrated depends on the
  10895. * scaling of the matrix A, but if equilibration is used, A is
  10896. * overwritten by diag(R)*A*diag(C) and B by diag(R)*B (if TRANS='N')
  10897. * or diag(C)*B (if TRANS = 'T' or 'C').
  10898. *
  10899. * 2. If FACT = 'N' or 'E', the LU decomposition is used to factor the
  10900. * matrix A (after equilibration if FACT = 'E') as
  10901. * A = P * L * U,
  10902. * where P is a permutation matrix, L is a unit lower triangular
  10903. * matrix, and U is upper triangular.
  10904. *
  10905. * 3. If some U(i,i)=0, so that U is exactly singular, then the routine
  10906. * returns with INFO = i. Otherwise, the factored form of A is used
  10907. * to estimate the condition number of the matrix A. If the
  10908. * reciprocal of the condition number is less than machine precision,
  10909. * INFO = N+1 is returned as a warning, but the routine still goes on
  10910. * to solve for X and compute error bounds as described below.
  10911. *
  10912. * 4. The system of equations is solved for X using the factored form
  10913. * of A.
  10914. *
  10915. * 5. Iterative refinement is applied to improve the computed solution
  10916. * matrix and calculate error bounds and backward error estimates
  10917. * for it.
  10918. *
  10919. * 6. If equilibration was used, the matrix X is premultiplied by
  10920. * diag(C) (if TRANS = 'N') or diag(R) (if TRANS = 'T' or 'C') so
  10921. * that it solves the original system before equilibration.
  10922. *
  10923. * Arguments
  10924. * =========
  10925. *
  10926. * FACT (input) CHARACTER*1
  10927. * Specifies whether or not the factored form of the matrix A is
  10928. * supplied on entry, and if not, whether the matrix A should be
  10929. * equilibrated before it is factored.
  10930. * = 'F': On entry, AF and IPIV contain the factored form of A.
  10931. * If EQUED is not 'N', the matrix A has been
  10932. * equilibrated with scaling factors given by R and C.
  10933. * A, AF, and IPIV are not modified.
  10934. * = 'N': The matrix A will be copied to AF and factored.
  10935. * = 'E': The matrix A will be equilibrated if necessary, then
  10936. * copied to AF and factored.
  10937. *
  10938. * TRANS (input) CHARACTER*1
  10939. * Specifies the form of the system of equations:
  10940. * = 'N': A * X = B (No transpose)
  10941. * = 'T': A**T * X = B (Transpose)
  10942. * = 'C': A**H * X = B (Transpose)
  10943. *
  10944. * N (input) INTEGER
  10945. * The number of linear equations, i.e., the order of the
  10946. * matrix A. N >= 0.
  10947. *
  10948. * NRHS (input) INTEGER
  10949. * The number of right hand sides, i.e., the number of columns
  10950. * of the matrices B and X. NRHS >= 0.
  10951. *
  10952. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  10953. * On entry, the N-by-N matrix A. If FACT = 'F' and EQUED is
  10954. * not 'N', then A must have been equilibrated by the scaling
  10955. * factors in R and/or C. A is not modified if FACT = 'F' or
  10956. * 'N', or if FACT = 'E' and EQUED = 'N' on exit.
  10957. *
  10958. * On exit, if EQUED .ne. 'N', A is scaled as follows:
  10959. * EQUED = 'R': A := diag(R) * A
  10960. * EQUED = 'C': A := A * diag(C)
  10961. * EQUED = 'B': A := diag(R) * A * diag(C).
  10962. *
  10963. * LDA (input) INTEGER
  10964. * The leading dimension of the array A. LDA >= max(1,N).
  10965. *
  10966. * AF (input or output) DOUBLE PRECISION array, dimension (LDAF,N)
  10967. * If FACT = 'F', then AF is an input argument and on entry
  10968. * contains the factors L and U from the factorization
  10969. * A = P*L*U as computed by DGETRF. If EQUED .ne. 'N', then
  10970. * AF is the factored form of the equilibrated matrix A.
  10971. *
  10972. * If FACT = 'N', then AF is an output argument and on exit
  10973. * returns the factors L and U from the factorization A = P*L*U
  10974. * of the original matrix A.
  10975. *
  10976. * If FACT = 'E', then AF is an output argument and on exit
  10977. * returns the factors L and U from the factorization A = P*L*U
  10978. * of the equilibrated matrix A (see the description of A for
  10979. * the form of the equilibrated matrix).
  10980. *
  10981. * LDAF (input) INTEGER
  10982. * The leading dimension of the array AF. LDAF >= max(1,N).
  10983. *
  10984. * IPIV (input or output) INTEGER array, dimension (N)
  10985. * If FACT = 'F', then IPIV is an input argument and on entry
  10986. * contains the pivot indices from the factorization A = P*L*U
  10987. * as computed by DGETRF; row i of the matrix was interchanged
  10988. * with row IPIV(i).
  10989. *
  10990. * If FACT = 'N', then IPIV is an output argument and on exit
  10991. * contains the pivot indices from the factorization A = P*L*U
  10992. * of the original matrix A.
  10993. *
  10994. * If FACT = 'E', then IPIV is an output argument and on exit
  10995. * contains the pivot indices from the factorization A = P*L*U
  10996. * of the equilibrated matrix A.
  10997. *
  10998. * EQUED (input or output) CHARACTER*1
  10999. * Specifies the form of equilibration that was done.
  11000. * = 'N': No equilibration (always true if FACT = 'N').
  11001. * = 'R': Row equilibration, i.e., A has been premultiplied by
  11002. * diag(R).
  11003. * = 'C': Column equilibration, i.e., A has been postmultiplied
  11004. * by diag(C).
  11005. * = 'B': Both row and column equilibration, i.e., A has been
  11006. * replaced by diag(R) * A * diag(C).
  11007. * EQUED is an input argument if FACT = 'F'; otherwise, it is an
  11008. * output argument.
  11009. *
  11010. * R (input or output) DOUBLE PRECISION array, dimension (N)
  11011. * The row scale factors for A. If EQUED = 'R' or 'B', A is
  11012. * multiplied on the left by diag(R); if EQUED = 'N' or 'C', R
  11013. * is not accessed. R is an input argument if FACT = 'F';
  11014. * otherwise, R is an output argument. If FACT = 'F' and
  11015. * EQUED = 'R' or 'B', each element of R must be positive.
  11016. *
  11017. * C (input or output) DOUBLE PRECISION array, dimension (N)
  11018. * The column scale factors for A. If EQUED = 'C' or 'B', A is
  11019. * multiplied on the right by diag(C); if EQUED = 'N' or 'R', C
  11020. * is not accessed. C is an input argument if FACT = 'F';
  11021. * otherwise, C is an output argument. If FACT = 'F' and
  11022. * EQUED = 'C' or 'B', each element of C must be positive.
  11023. *
  11024. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  11025. * On entry, the N-by-NRHS right hand side matrix B.
  11026. * On exit,
  11027. * if EQUED = 'N', B is not modified;
  11028. * if TRANS = 'N' and EQUED = 'R' or 'B', B is overwritten by
  11029. * diag(R)*B;
  11030. * if TRANS = 'T' or 'C' and EQUED = 'C' or 'B', B is
  11031. * overwritten by diag(C)*B.
  11032. *
  11033. * LDB (input) INTEGER
  11034. * The leading dimension of the array B. LDB >= max(1,N).
  11035. *
  11036. * X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
  11037. * If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X
  11038. * to the original system of equations. Note that A and B are
  11039. * modified on exit if EQUED .ne. 'N', and the solution to the
  11040. * equilibrated system is inv(diag(C))*X if TRANS = 'N' and
  11041. * EQUED = 'C' or 'B', or inv(diag(R))*X if TRANS = 'T' or 'C'
  11042. * and EQUED = 'R' or 'B'.
  11043. *
  11044. * LDX (input) INTEGER
  11045. * The leading dimension of the array X. LDX >= max(1,N).
  11046. *
  11047. * RCOND (output) DOUBLE PRECISION
  11048. * The estimate of the reciprocal condition number of the matrix
  11049. * A after equilibration (if done). If RCOND is less than the
  11050. * machine precision (in particular, if RCOND = 0), the matrix
  11051. * is singular to working precision. This condition is
  11052. * indicated by a return code of INFO > 0.
  11053. *
  11054. * FERR (output) DOUBLE PRECISION array, dimension (NRHS)
  11055. * The estimated forward error bound for each solution vector
  11056. * X(j) (the j-th column of the solution matrix X).
  11057. * If XTRUE is the true solution corresponding to X(j), FERR(j)
  11058. * is an estimated upper bound for the magnitude of the largest
  11059. * element in (X(j) - XTRUE) divided by the magnitude of the
  11060. * largest element in X(j). The estimate is as reliable as
  11061. * the estimate for RCOND, and is almost always a slight
  11062. * overestimate of the true error.
  11063. *
  11064. * BERR (output) DOUBLE PRECISION array, dimension (NRHS)
  11065. * The componentwise relative backward error of each solution
  11066. * vector X(j) (i.e., the smallest relative change in
  11067. * any element of A or B that makes X(j) an exact solution).
  11068. *
  11069. * WORK (workspace/output) DOUBLE PRECISION array, dimension (4*N)
  11070. * On exit, WORK(1) contains the reciprocal pivot growth
  11071. * factor norm(A)/norm(U). The "max absolute element" norm is
  11072. * used. If WORK(1) is much less than 1, then the stability
  11073. * of the LU factorization of the (equilibrated) matrix A
  11074. * could be poor. This also means that the solution X, condition
  11075. * estimator RCOND, and forward error bound FERR could be
  11076. * unreliable. If factorization fails with 0<INFO<=N, then
  11077. * WORK(1) contains the reciprocal pivot growth factor for the
  11078. * leading INFO columns of A.
  11079. *
  11080. * IWORK (workspace) INTEGER array, dimension (N)
  11081. *
  11082. * INFO (output) INTEGER
  11083. * = 0: successful exit
  11084. * < 0: if INFO = -i, the i-th argument had an illegal value
  11085. * > 0: if INFO = i, and i is
  11086. * <= N: U(i,i) is exactly zero. The factorization has
  11087. * been completed, but the factor U is exactly
  11088. * singular, so the solution and error bounds
  11089. * could not be computed. RCOND = 0 is returned.
  11090. * = N+1: U is nonsingular, but RCOND is less than machine
  11091. * precision, meaning that the matrix is singular
  11092. * to working precision. Nevertheless, the
  11093. * solution and error bounds are computed because
  11094. * there are a number of situations where the
  11095. * computed solution can be more accurate than the
  11096. * value of RCOND would suggest.
  11097. *
  11098. * =====================================================================
  11099. *
  11100. * .. Parameters ..
  11101. DOUBLE PRECISION ZERO, ONE
  11102. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  11103. * ..
  11104. * .. Local Scalars ..
  11105. LOGICAL COLEQU, EQUIL, NOFACT, NOTRAN, ROWEQU
  11106. CHARACTER NORM
  11107. INTEGER I, INFEQU, J
  11108. DOUBLE PRECISION AMAX, ANORM, BIGNUM, COLCND, RCMAX, RCMIN,
  11109. $ ROWCND, RPVGRW, SMLNUM
  11110. * ..
  11111. * .. External Functions ..
  11112. LOGICAL LSAME
  11113. DOUBLE PRECISION DLAMCH, DLANGE, DLANTR
  11114. EXTERNAL LSAME, DLAMCH, DLANGE, DLANTR
  11115. * ..
  11116. * .. External Subroutines ..
  11117. EXTERNAL DGECON, DGEEQU, DGERFS, DGETRF, DGETRS, DLACPY,
  11118. $ DLAQGE, XERBLA
  11119. * ..
  11120. * .. Intrinsic Functions ..
  11121. INTRINSIC MAX, MIN
  11122. * ..
  11123. * .. Executable Statements ..
  11124. *
  11125. INFO = 0
  11126. NOFACT = LSAME( FACT, 'N' )
  11127. EQUIL = LSAME( FACT, 'E' )
  11128. NOTRAN = LSAME( TRANS, 'N' )
  11129. IF( NOFACT .OR. EQUIL ) THEN
  11130. EQUED = 'N'
  11131. ROWEQU = .FALSE.
  11132. COLEQU = .FALSE.
  11133. ELSE
  11134. ROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )
  11135. COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )
  11136. SMLNUM = DLAMCH( 'Safe minimum' )
  11137. BIGNUM = ONE / SMLNUM
  11138. END IF
  11139. *
  11140. * Test the input parameters.
  11141. *
  11142. IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )
  11143. $ THEN
  11144. INFO = -1
  11145. ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
  11146. $ LSAME( TRANS, 'C' ) ) THEN
  11147. INFO = -2
  11148. ELSE IF( N.LT.0 ) THEN
  11149. INFO = -3
  11150. ELSE IF( NRHS.LT.0 ) THEN
  11151. INFO = -4
  11152. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  11153. INFO = -6
  11154. ELSE IF( LDAF.LT.MAX( 1, N ) ) THEN
  11155. INFO = -8
  11156. ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.
  11157. $ ( ROWEQU .OR. COLEQU .OR. LSAME( EQUED, 'N' ) ) ) THEN
  11158. INFO = -10
  11159. ELSE
  11160. IF( ROWEQU ) THEN
  11161. RCMIN = BIGNUM
  11162. RCMAX = ZERO
  11163. DO 10 J = 1, N
  11164. RCMIN = MIN( RCMIN, R( J ) )
  11165. RCMAX = MAX( RCMAX, R( J ) )
  11166. 10 CONTINUE
  11167. IF( RCMIN.LE.ZERO ) THEN
  11168. INFO = -11
  11169. ELSE IF( N.GT.0 ) THEN
  11170. ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )
  11171. ELSE
  11172. ROWCND = ONE
  11173. END IF
  11174. END IF
  11175. IF( COLEQU .AND. INFO.EQ.0 ) THEN
  11176. RCMIN = BIGNUM
  11177. RCMAX = ZERO
  11178. DO 20 J = 1, N
  11179. RCMIN = MIN( RCMIN, C( J ) )
  11180. RCMAX = MAX( RCMAX, C( J ) )
  11181. 20 CONTINUE
  11182. IF( RCMIN.LE.ZERO ) THEN
  11183. INFO = -12
  11184. ELSE IF( N.GT.0 ) THEN
  11185. COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )
  11186. ELSE
  11187. COLCND = ONE
  11188. END IF
  11189. END IF
  11190. IF( INFO.EQ.0 ) THEN
  11191. IF( LDB.LT.MAX( 1, N ) ) THEN
  11192. INFO = -14
  11193. ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
  11194. INFO = -16
  11195. END IF
  11196. END IF
  11197. END IF
  11198. *
  11199. IF( INFO.NE.0 ) THEN
  11200. CALL XERBLA( 'DGESVX', -INFO )
  11201. RETURN
  11202. END IF
  11203. *
  11204. IF( EQUIL ) THEN
  11205. *
  11206. * Compute row and column scalings to equilibrate the matrix A.
  11207. *
  11208. CALL DGEEQU( N, N, A, LDA, R, C, ROWCND, COLCND, AMAX, INFEQU )
  11209. IF( INFEQU.EQ.0 ) THEN
  11210. *
  11211. * Equilibrate the matrix.
  11212. *
  11213. CALL DLAQGE( N, N, A, LDA, R, C, ROWCND, COLCND, AMAX,
  11214. $ EQUED )
  11215. ROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )
  11216. COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )
  11217. END IF
  11218. END IF
  11219. *
  11220. * Scale the right hand side.
  11221. *
  11222. IF( NOTRAN ) THEN
  11223. IF( ROWEQU ) THEN
  11224. DO 40 J = 1, NRHS
  11225. DO 30 I = 1, N
  11226. B( I, J ) = R( I )*B( I, J )
  11227. 30 CONTINUE
  11228. 40 CONTINUE
  11229. END IF
  11230. ELSE IF( COLEQU ) THEN
  11231. DO 60 J = 1, NRHS
  11232. DO 50 I = 1, N
  11233. B( I, J ) = C( I )*B( I, J )
  11234. 50 CONTINUE
  11235. 60 CONTINUE
  11236. END IF
  11237. *
  11238. IF( NOFACT .OR. EQUIL ) THEN
  11239. *
  11240. * Compute the LU factorization of A.
  11241. *
  11242. CALL DLACPY( 'Full', N, N, A, LDA, AF, LDAF )
  11243. CALL DGETRF( N, N, AF, LDAF, IPIV, INFO )
  11244. *
  11245. * Return if INFO is non-zero.
  11246. *
  11247. IF( INFO.GT.0 ) THEN
  11248. *
  11249. * Compute the reciprocal pivot growth factor of the
  11250. * leading rank-deficient INFO columns of A.
  11251. *
  11252. RPVGRW = DLANTR( 'M', 'U', 'N', INFO, INFO, AF, LDAF,
  11253. $ WORK )
  11254. IF( RPVGRW.EQ.ZERO ) THEN
  11255. RPVGRW = ONE
  11256. ELSE
  11257. RPVGRW = DLANGE( 'M', N, INFO, A, LDA, WORK ) / RPVGRW
  11258. END IF
  11259. WORK( 1 ) = RPVGRW
  11260. RCOND = ZERO
  11261. RETURN
  11262. END IF
  11263. END IF
  11264. *
  11265. * Compute the norm of the matrix A and the
  11266. * reciprocal pivot growth factor RPVGRW.
  11267. *
  11268. IF( NOTRAN ) THEN
  11269. NORM = '1'
  11270. ELSE
  11271. NORM = 'I'
  11272. END IF
  11273. ANORM = DLANGE( NORM, N, N, A, LDA, WORK )
  11274. RPVGRW = DLANTR( 'M', 'U', 'N', N, N, AF, LDAF, WORK )
  11275. IF( RPVGRW.EQ.ZERO ) THEN
  11276. RPVGRW = ONE
  11277. ELSE
  11278. RPVGRW = DLANGE( 'M', N, N, A, LDA, WORK ) / RPVGRW
  11279. END IF
  11280. *
  11281. * Compute the reciprocal of the condition number of A.
  11282. *
  11283. CALL DGECON( NORM, N, AF, LDAF, ANORM, RCOND, WORK, IWORK, INFO )
  11284. *
  11285. * Compute the solution matrix X.
  11286. *
  11287. CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
  11288. CALL DGETRS( TRANS, N, NRHS, AF, LDAF, IPIV, X, LDX, INFO )
  11289. *
  11290. * Use iterative refinement to improve the computed solution and
  11291. * compute error bounds and backward error estimates for it.
  11292. *
  11293. CALL DGERFS( TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB, X,
  11294. $ LDX, FERR, BERR, WORK, IWORK, INFO )
  11295. *
  11296. * Transform the solution matrix X to a solution of the original
  11297. * system.
  11298. *
  11299. IF( NOTRAN ) THEN
  11300. IF( COLEQU ) THEN
  11301. DO 80 J = 1, NRHS
  11302. DO 70 I = 1, N
  11303. X( I, J ) = C( I )*X( I, J )
  11304. 70 CONTINUE
  11305. 80 CONTINUE
  11306. DO 90 J = 1, NRHS
  11307. FERR( J ) = FERR( J ) / COLCND
  11308. 90 CONTINUE
  11309. END IF
  11310. ELSE IF( ROWEQU ) THEN
  11311. DO 110 J = 1, NRHS
  11312. DO 100 I = 1, N
  11313. X( I, J ) = R( I )*X( I, J )
  11314. 100 CONTINUE
  11315. 110 CONTINUE
  11316. DO 120 J = 1, NRHS
  11317. FERR( J ) = FERR( J ) / ROWCND
  11318. 120 CONTINUE
  11319. END IF
  11320. *
  11321. WORK( 1 ) = RPVGRW
  11322. *
  11323. * Set INFO = N+1 if the matrix is singular to working precision.
  11324. *
  11325. IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
  11326. $ INFO = N + 1
  11327. RETURN
  11328. *
  11329. * End of DGESVX
  11330. *
  11331. END
  11332. SUBROUTINE DGGES( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B, LDB,
  11333. $ SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR,
  11334. $ LDVSR, WORK, LWORK, BWORK, INFO )
  11335. *
  11336. * -- LAPACK driver routine (version 3.1) --
  11337. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  11338. * November 2006
  11339. *
  11340. * .. Scalar Arguments ..
  11341. CHARACTER JOBVSL, JOBVSR, SORT
  11342. INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM
  11343. * ..
  11344. * .. Array Arguments ..
  11345. LOGICAL BWORK( * )
  11346. DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
  11347. $ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),
  11348. $ VSR( LDVSR, * ), WORK( * )
  11349. * ..
  11350. * .. Function Arguments ..
  11351. LOGICAL SELCTG
  11352. EXTERNAL SELCTG
  11353. * ..
  11354. *
  11355. * Purpose
  11356. * =======
  11357. *
  11358. * DGGES computes for a pair of N-by-N real nonsymmetric matrices (A,B),
  11359. * the generalized eigenvalues, the generalized real Schur form (S,T),
  11360. * optionally, the left and/or right matrices of Schur vectors (VSL and
  11361. * VSR). This gives the generalized Schur factorization
  11362. *
  11363. * (A,B) = ( (VSL)*S*(VSR)**T, (VSL)*T*(VSR)**T )
  11364. *
  11365. * Optionally, it also orders the eigenvalues so that a selected cluster
  11366. * of eigenvalues appears in the leading diagonal blocks of the upper
  11367. * quasi-triangular matrix S and the upper triangular matrix T.The
  11368. * leading columns of VSL and VSR then form an orthonormal basis for the
  11369. * corresponding left and right eigenspaces (deflating subspaces).
  11370. *
  11371. * (If only the generalized eigenvalues are needed, use the driver
  11372. * DGGEV instead, which is faster.)
  11373. *
  11374. * A generalized eigenvalue for a pair of matrices (A,B) is a scalar w
  11375. * or a ratio alpha/beta = w, such that A - w*B is singular. It is
  11376. * usually represented as the pair (alpha,beta), as there is a
  11377. * reasonable interpretation for beta=0 or both being zero.
  11378. *
  11379. * A pair of matrices (S,T) is in generalized real Schur form if T is
  11380. * upper triangular with non-negative diagonal and S is block upper
  11381. * triangular with 1-by-1 and 2-by-2 blocks. 1-by-1 blocks correspond
  11382. * to real generalized eigenvalues, while 2-by-2 blocks of S will be
  11383. * "standardized" by making the corresponding elements of T have the
  11384. * form:
  11385. * [ a 0 ]
  11386. * [ 0 b ]
  11387. *
  11388. * and the pair of corresponding 2-by-2 blocks in S and T will have a
  11389. * complex conjugate pair of generalized eigenvalues.
  11390. *
  11391. *
  11392. * Arguments
  11393. * =========
  11394. *
  11395. * JOBVSL (input) CHARACTER*1
  11396. * = 'N': do not compute the left Schur vectors;
  11397. * = 'V': compute the left Schur vectors.
  11398. *
  11399. * JOBVSR (input) CHARACTER*1
  11400. * = 'N': do not compute the right Schur vectors;
  11401. * = 'V': compute the right Schur vectors.
  11402. *
  11403. * SORT (input) CHARACTER*1
  11404. * Specifies whether or not to order the eigenvalues on the
  11405. * diagonal of the generalized Schur form.
  11406. * = 'N': Eigenvalues are not ordered;
  11407. * = 'S': Eigenvalues are ordered (see SELCTG);
  11408. *
  11409. * SELCTG (external procedure) LOGICAL FUNCTION of three DOUBLE PRECISION arguments
  11410. * SELCTG must be declared EXTERNAL in the calling subroutine.
  11411. * If SORT = 'N', SELCTG is not referenced.
  11412. * If SORT = 'S', SELCTG is used to select eigenvalues to sort
  11413. * to the top left of the Schur form.
  11414. * An eigenvalue (ALPHAR(j)+ALPHAI(j))/BETA(j) is selected if
  11415. * SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) is true; i.e. if either
  11416. * one of a complex conjugate pair of eigenvalues is selected,
  11417. * then both complex eigenvalues are selected.
  11418. *
  11419. * Note that in the ill-conditioned case, a selected complex
  11420. * eigenvalue may no longer satisfy SELCTG(ALPHAR(j),ALPHAI(j),
  11421. * BETA(j)) = .TRUE. after ordering. INFO is to be set to N+2
  11422. * in this case.
  11423. *
  11424. * N (input) INTEGER
  11425. * The order of the matrices A, B, VSL, and VSR. N >= 0.
  11426. *
  11427. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  11428. * On entry, the first of the pair of matrices.
  11429. * On exit, A has been overwritten by its generalized Schur
  11430. * form S.
  11431. *
  11432. * LDA (input) INTEGER
  11433. * The leading dimension of A. LDA >= max(1,N).
  11434. *
  11435. * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
  11436. * On entry, the second of the pair of matrices.
  11437. * On exit, B has been overwritten by its generalized Schur
  11438. * form T.
  11439. *
  11440. * LDB (input) INTEGER
  11441. * The leading dimension of B. LDB >= max(1,N).
  11442. *
  11443. * SDIM (output) INTEGER
  11444. * If SORT = 'N', SDIM = 0.
  11445. * If SORT = 'S', SDIM = number of eigenvalues (after sorting)
  11446. * for which SELCTG is true. (Complex conjugate pairs for which
  11447. * SELCTG is true for either eigenvalue count as 2.)
  11448. *
  11449. * ALPHAR (output) DOUBLE PRECISION array, dimension (N)
  11450. * ALPHAI (output) DOUBLE PRECISION array, dimension (N)
  11451. * BETA (output) DOUBLE PRECISION array, dimension (N)
  11452. * On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
  11453. * be the generalized eigenvalues. ALPHAR(j) + ALPHAI(j)*i,
  11454. * and BETA(j),j=1,...,N are the diagonals of the complex Schur
  11455. * form (S,T) that would result if the 2-by-2 diagonal blocks of
  11456. * the real Schur form of (A,B) were further reduced to
  11457. * triangular form using 2-by-2 complex unitary transformations.
  11458. * If ALPHAI(j) is zero, then the j-th eigenvalue is real; if
  11459. * positive, then the j-th and (j+1)-st eigenvalues are a
  11460. * complex conjugate pair, with ALPHAI(j+1) negative.
  11461. *
  11462. * Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
  11463. * may easily over- or underflow, and BETA(j) may even be zero.
  11464. * Thus, the user should avoid naively computing the ratio.
  11465. * However, ALPHAR and ALPHAI will be always less than and
  11466. * usually comparable with norm(A) in magnitude, and BETA always
  11467. * less than and usually comparable with norm(B).
  11468. *
  11469. * VSL (output) DOUBLE PRECISION array, dimension (LDVSL,N)
  11470. * If JOBVSL = 'V', VSL will contain the left Schur vectors.
  11471. * Not referenced if JOBVSL = 'N'.
  11472. *
  11473. * LDVSL (input) INTEGER
  11474. * The leading dimension of the matrix VSL. LDVSL >=1, and
  11475. * if JOBVSL = 'V', LDVSL >= N.
  11476. *
  11477. * VSR (output) DOUBLE PRECISION array, dimension (LDVSR,N)
  11478. * If JOBVSR = 'V', VSR will contain the right Schur vectors.
  11479. * Not referenced if JOBVSR = 'N'.
  11480. *
  11481. * LDVSR (input) INTEGER
  11482. * The leading dimension of the matrix VSR. LDVSR >= 1, and
  11483. * if JOBVSR = 'V', LDVSR >= N.
  11484. *
  11485. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  11486. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  11487. *
  11488. * LWORK (input) INTEGER
  11489. * The dimension of the array WORK.
  11490. * If N = 0, LWORK >= 1, else LWORK >= 8*N+16.
  11491. * For good performance , LWORK must generally be larger.
  11492. *
  11493. * If LWORK = -1, then a workspace query is assumed; the routine
  11494. * only calculates the optimal size of the WORK array, returns
  11495. * this value as the first entry of the WORK array, and no error
  11496. * message related to LWORK is issued by XERBLA.
  11497. *
  11498. * BWORK (workspace) LOGICAL array, dimension (N)
  11499. * Not referenced if SORT = 'N'.
  11500. *
  11501. * INFO (output) INTEGER
  11502. * = 0: successful exit
  11503. * < 0: if INFO = -i, the i-th argument had an illegal value.
  11504. * = 1,...,N:
  11505. * The QZ iteration failed. (A,B) are not in Schur
  11506. * form, but ALPHAR(j), ALPHAI(j), and BETA(j) should
  11507. * be correct for j=INFO+1,...,N.
  11508. * > N: =N+1: other than QZ iteration failed in DHGEQZ.
  11509. * =N+2: after reordering, roundoff changed values of
  11510. * some complex eigenvalues so that leading
  11511. * eigenvalues in the Generalized Schur form no
  11512. * longer satisfy SELCTG=.TRUE. This could also
  11513. * be caused due to scaling.
  11514. * =N+3: reordering failed in DTGSEN.
  11515. *
  11516. * =====================================================================
  11517. *
  11518. * .. Parameters ..
  11519. DOUBLE PRECISION ZERO, ONE
  11520. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  11521. * ..
  11522. * .. Local Scalars ..
  11523. LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
  11524. $ LQUERY, LST2SL, WANTST
  11525. INTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT,
  11526. $ ILO, IP, IRIGHT, IROWS, ITAU, IWRK, MAXWRK,
  11527. $ MINWRK
  11528. DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,
  11529. $ PVSR, SAFMAX, SAFMIN, SMLNUM
  11530. * ..
  11531. * .. Local Arrays ..
  11532. INTEGER IDUM( 1 )
  11533. DOUBLE PRECISION DIF( 2 )
  11534. * ..
  11535. * .. External Subroutines ..
  11536. EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,
  11537. $ DLACPY, DLASCL, DLASET, DORGQR, DORMQR, DTGSEN,
  11538. $ XERBLA
  11539. * ..
  11540. * .. External Functions ..
  11541. LOGICAL LSAME
  11542. INTEGER ILAENV
  11543. DOUBLE PRECISION DLAMCH, DLANGE
  11544. EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE
  11545. * ..
  11546. * .. Intrinsic Functions ..
  11547. INTRINSIC ABS, MAX, SQRT
  11548. * ..
  11549. * .. Executable Statements ..
  11550. *
  11551. * Decode the input arguments
  11552. *
  11553. IF( LSAME( JOBVSL, 'N' ) ) THEN
  11554. IJOBVL = 1
  11555. ILVSL = .FALSE.
  11556. ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
  11557. IJOBVL = 2
  11558. ILVSL = .TRUE.
  11559. ELSE
  11560. IJOBVL = -1
  11561. ILVSL = .FALSE.
  11562. END IF
  11563. *
  11564. IF( LSAME( JOBVSR, 'N' ) ) THEN
  11565. IJOBVR = 1
  11566. ILVSR = .FALSE.
  11567. ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
  11568. IJOBVR = 2
  11569. ILVSR = .TRUE.
  11570. ELSE
  11571. IJOBVR = -1
  11572. ILVSR = .FALSE.
  11573. END IF
  11574. *
  11575. WANTST = LSAME( SORT, 'S' )
  11576. *
  11577. * Test the input arguments
  11578. *
  11579. INFO = 0
  11580. LQUERY = ( LWORK.EQ.-1 )
  11581. IF( IJOBVL.LE.0 ) THEN
  11582. INFO = -1
  11583. ELSE IF( IJOBVR.LE.0 ) THEN
  11584. INFO = -2
  11585. ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
  11586. INFO = -3
  11587. ELSE IF( N.LT.0 ) THEN
  11588. INFO = -5
  11589. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  11590. INFO = -7
  11591. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  11592. INFO = -9
  11593. ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
  11594. INFO = -15
  11595. ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
  11596. INFO = -17
  11597. END IF
  11598. *
  11599. * Compute workspace
  11600. * (Note: Comments in the code beginning "Workspace:" describe the
  11601. * minimal amount of workspace needed at that point in the code,
  11602. * as well as the preferred amount for good performance.
  11603. * NB refers to the optimal block size for the immediately
  11604. * following subroutine, as returned by ILAENV.)
  11605. *
  11606. IF( INFO.EQ.0 ) THEN
  11607. IF( N.GT.0 )THEN
  11608. MINWRK = MAX( 8*N, 6*N + 16 )
  11609. MAXWRK = MINWRK - N +
  11610. $ N*ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 )
  11611. MAXWRK = MAX( MAXWRK, MINWRK - N +
  11612. $ N*ILAENV( 1, 'DORMQR', ' ', N, 1, N, -1 ) )
  11613. IF( ILVSL ) THEN
  11614. MAXWRK = MAX( MAXWRK, MINWRK - N +
  11615. $ N*ILAENV( 1, 'DORGQR', ' ', N, 1, N, -1 ) )
  11616. END IF
  11617. ELSE
  11618. MINWRK = 1
  11619. MAXWRK = 1
  11620. END IF
  11621. WORK( 1 ) = MAXWRK
  11622. *
  11623. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
  11624. $ INFO = -19
  11625. END IF
  11626. *
  11627. IF( INFO.NE.0 ) THEN
  11628. CALL XERBLA( 'DGGES ', -INFO )
  11629. RETURN
  11630. ELSE IF( LQUERY ) THEN
  11631. RETURN
  11632. END IF
  11633. *
  11634. * Quick return if possible
  11635. *
  11636. IF( N.EQ.0 ) THEN
  11637. SDIM = 0
  11638. RETURN
  11639. END IF
  11640. *
  11641. * Get machine constants
  11642. *
  11643. EPS = DLAMCH( 'P' )
  11644. SAFMIN = DLAMCH( 'S' )
  11645. SAFMAX = ONE / SAFMIN
  11646. CALL DLABAD( SAFMIN, SAFMAX )
  11647. SMLNUM = SQRT( SAFMIN ) / EPS
  11648. BIGNUM = ONE / SMLNUM
  11649. *
  11650. * Scale A if max element outside range [SMLNUM,BIGNUM]
  11651. *
  11652. ANRM = DLANGE( 'M', N, N, A, LDA, WORK )
  11653. ILASCL = .FALSE.
  11654. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  11655. ANRMTO = SMLNUM
  11656. ILASCL = .TRUE.
  11657. ELSE IF( ANRM.GT.BIGNUM ) THEN
  11658. ANRMTO = BIGNUM
  11659. ILASCL = .TRUE.
  11660. END IF
  11661. IF( ILASCL )
  11662. $ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
  11663. *
  11664. * Scale B if max element outside range [SMLNUM,BIGNUM]
  11665. *
  11666. BNRM = DLANGE( 'M', N, N, B, LDB, WORK )
  11667. ILBSCL = .FALSE.
  11668. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  11669. BNRMTO = SMLNUM
  11670. ILBSCL = .TRUE.
  11671. ELSE IF( BNRM.GT.BIGNUM ) THEN
  11672. BNRMTO = BIGNUM
  11673. ILBSCL = .TRUE.
  11674. END IF
  11675. IF( ILBSCL )
  11676. $ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
  11677. *
  11678. * Permute the matrix to make it more nearly triangular
  11679. * (Workspace: need 6*N + 2*N space for storing balancing factors)
  11680. *
  11681. ILEFT = 1
  11682. IRIGHT = N + 1
  11683. IWRK = IRIGHT + N
  11684. CALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
  11685. $ WORK( IRIGHT ), WORK( IWRK ), IERR )
  11686. *
  11687. * Reduce B to triangular form (QR decomposition of B)
  11688. * (Workspace: need N, prefer N*NB)
  11689. *
  11690. IROWS = IHI + 1 - ILO
  11691. ICOLS = N + 1 - ILO
  11692. ITAU = IWRK
  11693. IWRK = ITAU + IROWS
  11694. CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
  11695. $ WORK( IWRK ), LWORK+1-IWRK, IERR )
  11696. *
  11697. * Apply the orthogonal transformation to matrix A
  11698. * (Workspace: need N, prefer N*NB)
  11699. *
  11700. CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
  11701. $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
  11702. $ LWORK+1-IWRK, IERR )
  11703. *
  11704. * Initialize VSL
  11705. * (Workspace: need N, prefer N*NB)
  11706. *
  11707. IF( ILVSL ) THEN
  11708. CALL DLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL )
  11709. IF( IROWS.GT.1 ) THEN
  11710. CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
  11711. $ VSL( ILO+1, ILO ), LDVSL )
  11712. END IF
  11713. CALL DORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
  11714. $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
  11715. END IF
  11716. *
  11717. * Initialize VSR
  11718. *
  11719. IF( ILVSR )
  11720. $ CALL DLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR )
  11721. *
  11722. * Reduce to generalized Hessenberg form
  11723. * (Workspace: none needed)
  11724. *
  11725. CALL DGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
  11726. $ LDVSL, VSR, LDVSR, IERR )
  11727. *
  11728. * Perform QZ algorithm, computing Schur vectors if desired
  11729. * (Workspace: need N)
  11730. *
  11731. IWRK = ITAU
  11732. CALL DHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
  11733. $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
  11734. $ WORK( IWRK ), LWORK+1-IWRK, IERR )
  11735. IF( IERR.NE.0 ) THEN
  11736. IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
  11737. INFO = IERR
  11738. ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
  11739. INFO = IERR - N
  11740. ELSE
  11741. INFO = N + 1
  11742. END IF
  11743. GO TO 50
  11744. END IF
  11745. *
  11746. * Sort eigenvalues ALPHA/BETA if desired
  11747. * (Workspace: need 4*N+16 )
  11748. *
  11749. SDIM = 0
  11750. IF( WANTST ) THEN
  11751. *
  11752. * Undo scaling on eigenvalues before SELCTGing
  11753. *
  11754. IF( ILASCL ) THEN
  11755. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N,
  11756. $ IERR )
  11757. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N,
  11758. $ IERR )
  11759. END IF
  11760. IF( ILBSCL )
  11761. $ CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
  11762. *
  11763. * Select eigenvalues
  11764. *
  11765. DO 10 I = 1, N
  11766. BWORK( I ) = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )
  11767. 10 CONTINUE
  11768. *
  11769. CALL DTGSEN( 0, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB, ALPHAR,
  11770. $ ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, SDIM, PVSL,
  11771. $ PVSR, DIF, WORK( IWRK ), LWORK-IWRK+1, IDUM, 1,
  11772. $ IERR )
  11773. IF( IERR.EQ.1 )
  11774. $ INFO = N + 3
  11775. *
  11776. END IF
  11777. *
  11778. * Apply back-permutation to VSL and VSR
  11779. * (Workspace: none needed)
  11780. *
  11781. IF( ILVSL )
  11782. $ CALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
  11783. $ WORK( IRIGHT ), N, VSL, LDVSL, IERR )
  11784. *
  11785. IF( ILVSR )
  11786. $ CALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
  11787. $ WORK( IRIGHT ), N, VSR, LDVSR, IERR )
  11788. *
  11789. * Check if unscaling would cause over/underflow, if so, rescale
  11790. * (ALPHAR(I),ALPHAI(I),BETA(I)) so BETA(I) is on the order of
  11791. * B(I,I) and ALPHAR(I) and ALPHAI(I) are on the order of A(I,I)
  11792. *
  11793. IF( ILASCL ) THEN
  11794. DO 20 I = 1, N
  11795. IF( ALPHAI( I ).NE.ZERO ) THEN
  11796. IF( ( ALPHAR( I ) / SAFMAX ).GT.( ANRMTO / ANRM ) .OR.
  11797. $ ( SAFMIN / ALPHAR( I ) ).GT.( ANRM / ANRMTO ) ) THEN
  11798. WORK( 1 ) = ABS( A( I, I ) / ALPHAR( I ) )
  11799. BETA( I ) = BETA( I )*WORK( 1 )
  11800. ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
  11801. ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
  11802. ELSE IF( ( ALPHAI( I ) / SAFMAX ).GT.
  11803. $ ( ANRMTO / ANRM ) .OR.
  11804. $ ( SAFMIN / ALPHAI( I ) ).GT.( ANRM / ANRMTO ) )
  11805. $ THEN
  11806. WORK( 1 ) = ABS( A( I, I+1 ) / ALPHAI( I ) )
  11807. BETA( I ) = BETA( I )*WORK( 1 )
  11808. ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
  11809. ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
  11810. END IF
  11811. END IF
  11812. 20 CONTINUE
  11813. END IF
  11814. *
  11815. IF( ILBSCL ) THEN
  11816. DO 30 I = 1, N
  11817. IF( ALPHAI( I ).NE.ZERO ) THEN
  11818. IF( ( BETA( I ) / SAFMAX ).GT.( BNRMTO / BNRM ) .OR.
  11819. $ ( SAFMIN / BETA( I ) ).GT.( BNRM / BNRMTO ) ) THEN
  11820. WORK( 1 ) = ABS( B( I, I ) / BETA( I ) )
  11821. BETA( I ) = BETA( I )*WORK( 1 )
  11822. ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
  11823. ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
  11824. END IF
  11825. END IF
  11826. 30 CONTINUE
  11827. END IF
  11828. *
  11829. * Undo scaling
  11830. *
  11831. IF( ILASCL ) THEN
  11832. CALL DLASCL( 'H', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )
  11833. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
  11834. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
  11835. END IF
  11836. *
  11837. IF( ILBSCL ) THEN
  11838. CALL DLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )
  11839. CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
  11840. END IF
  11841. *
  11842. IF( WANTST ) THEN
  11843. *
  11844. * Check if reordering is correct
  11845. *
  11846. LASTSL = .TRUE.
  11847. LST2SL = .TRUE.
  11848. SDIM = 0
  11849. IP = 0
  11850. DO 40 I = 1, N
  11851. CURSL = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )
  11852. IF( ALPHAI( I ).EQ.ZERO ) THEN
  11853. IF( CURSL )
  11854. $ SDIM = SDIM + 1
  11855. IP = 0
  11856. IF( CURSL .AND. .NOT.LASTSL )
  11857. $ INFO = N + 2
  11858. ELSE
  11859. IF( IP.EQ.1 ) THEN
  11860. *
  11861. * Last eigenvalue of conjugate pair
  11862. *
  11863. CURSL = CURSL .OR. LASTSL
  11864. LASTSL = CURSL
  11865. IF( CURSL )
  11866. $ SDIM = SDIM + 2
  11867. IP = -1
  11868. IF( CURSL .AND. .NOT.LST2SL )
  11869. $ INFO = N + 2
  11870. ELSE
  11871. *
  11872. * First eigenvalue of conjugate pair
  11873. *
  11874. IP = 1
  11875. END IF
  11876. END IF
  11877. LST2SL = LASTSL
  11878. LASTSL = CURSL
  11879. 40 CONTINUE
  11880. *
  11881. END IF
  11882. *
  11883. 50 CONTINUE
  11884. *
  11885. WORK( 1 ) = MAXWRK
  11886. *
  11887. RETURN
  11888. *
  11889. * End of DGGES
  11890. *
  11891. END
  11892. SUBROUTINE DGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
  11893. $ B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,
  11894. $ VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK,
  11895. $ LIWORK, BWORK, INFO )
  11896. *
  11897. * -- LAPACK driver routine (version 3.1) --
  11898. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  11899. * November 2006
  11900. *
  11901. * .. Scalar Arguments ..
  11902. CHARACTER JOBVSL, JOBVSR, SENSE, SORT
  11903. INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
  11904. $ SDIM
  11905. * ..
  11906. * .. Array Arguments ..
  11907. LOGICAL BWORK( * )
  11908. INTEGER IWORK( * )
  11909. DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
  11910. $ B( LDB, * ), BETA( * ), RCONDE( 2 ),
  11911. $ RCONDV( 2 ), VSL( LDVSL, * ), VSR( LDVSR, * ),
  11912. $ WORK( * )
  11913. * ..
  11914. * .. Function Arguments ..
  11915. LOGICAL SELCTG
  11916. EXTERNAL SELCTG
  11917. * ..
  11918. *
  11919. * Purpose
  11920. * =======
  11921. *
  11922. * DGGESX computes for a pair of N-by-N real nonsymmetric matrices
  11923. * (A,B), the generalized eigenvalues, the real Schur form (S,T), and,
  11924. * optionally, the left and/or right matrices of Schur vectors (VSL and
  11925. * VSR). This gives the generalized Schur factorization
  11926. *
  11927. * (A,B) = ( (VSL) S (VSR)**T, (VSL) T (VSR)**T )
  11928. *
  11929. * Optionally, it also orders the eigenvalues so that a selected cluster
  11930. * of eigenvalues appears in the leading diagonal blocks of the upper
  11931. * quasi-triangular matrix S and the upper triangular matrix T; computes
  11932. * a reciprocal condition number for the average of the selected
  11933. * eigenvalues (RCONDE); and computes a reciprocal condition number for
  11934. * the right and left deflating subspaces corresponding to the selected
  11935. * eigenvalues (RCONDV). The leading columns of VSL and VSR then form
  11936. * an orthonormal basis for the corresponding left and right eigenspaces
  11937. * (deflating subspaces).
  11938. *
  11939. * A generalized eigenvalue for a pair of matrices (A,B) is a scalar w
  11940. * or a ratio alpha/beta = w, such that A - w*B is singular. It is
  11941. * usually represented as the pair (alpha,beta), as there is a
  11942. * reasonable interpretation for beta=0 or for both being zero.
  11943. *
  11944. * A pair of matrices (S,T) is in generalized real Schur form if T is
  11945. * upper triangular with non-negative diagonal and S is block upper
  11946. * triangular with 1-by-1 and 2-by-2 blocks. 1-by-1 blocks correspond
  11947. * to real generalized eigenvalues, while 2-by-2 blocks of S will be
  11948. * "standardized" by making the corresponding elements of T have the
  11949. * form:
  11950. * [ a 0 ]
  11951. * [ 0 b ]
  11952. *
  11953. * and the pair of corresponding 2-by-2 blocks in S and T will have a
  11954. * complex conjugate pair of generalized eigenvalues.
  11955. *
  11956. *
  11957. * Arguments
  11958. * =========
  11959. *
  11960. * JOBVSL (input) CHARACTER*1
  11961. * = 'N': do not compute the left Schur vectors;
  11962. * = 'V': compute the left Schur vectors.
  11963. *
  11964. * JOBVSR (input) CHARACTER*1
  11965. * = 'N': do not compute the right Schur vectors;
  11966. * = 'V': compute the right Schur vectors.
  11967. *
  11968. * SORT (input) CHARACTER*1
  11969. * Specifies whether or not to order the eigenvalues on the
  11970. * diagonal of the generalized Schur form.
  11971. * = 'N': Eigenvalues are not ordered;
  11972. * = 'S': Eigenvalues are ordered (see SELCTG).
  11973. *
  11974. * SELCTG (external procedure) LOGICAL FUNCTION of three DOUBLE PRECISION arguments
  11975. * SELCTG must be declared EXTERNAL in the calling subroutine.
  11976. * If SORT = 'N', SELCTG is not referenced.
  11977. * If SORT = 'S', SELCTG is used to select eigenvalues to sort
  11978. * to the top left of the Schur form.
  11979. * An eigenvalue (ALPHAR(j)+ALPHAI(j))/BETA(j) is selected if
  11980. * SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) is true; i.e. if either
  11981. * one of a complex conjugate pair of eigenvalues is selected,
  11982. * then both complex eigenvalues are selected.
  11983. * Note that a selected complex eigenvalue may no longer satisfy
  11984. * SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) = .TRUE. after ordering,
  11985. * since ordering may change the value of complex eigenvalues
  11986. * (especially if the eigenvalue is ill-conditioned), in this
  11987. * case INFO is set to N+3.
  11988. *
  11989. * SENSE (input) CHARACTER*1
  11990. * Determines which reciprocal condition numbers are computed.
  11991. * = 'N' : None are computed;
  11992. * = 'E' : Computed for average of selected eigenvalues only;
  11993. * = 'V' : Computed for selected deflating subspaces only;
  11994. * = 'B' : Computed for both.
  11995. * If SENSE = 'E', 'V', or 'B', SORT must equal 'S'.
  11996. *
  11997. * N (input) INTEGER
  11998. * The order of the matrices A, B, VSL, and VSR. N >= 0.
  11999. *
  12000. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  12001. * On entry, the first of the pair of matrices.
  12002. * On exit, A has been overwritten by its generalized Schur
  12003. * form S.
  12004. *
  12005. * LDA (input) INTEGER
  12006. * The leading dimension of A. LDA >= max(1,N).
  12007. *
  12008. * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
  12009. * On entry, the second of the pair of matrices.
  12010. * On exit, B has been overwritten by its generalized Schur
  12011. * form T.
  12012. *
  12013. * LDB (input) INTEGER
  12014. * The leading dimension of B. LDB >= max(1,N).
  12015. *
  12016. * SDIM (output) INTEGER
  12017. * If SORT = 'N', SDIM = 0.
  12018. * If SORT = 'S', SDIM = number of eigenvalues (after sorting)
  12019. * for which SELCTG is true. (Complex conjugate pairs for which
  12020. * SELCTG is true for either eigenvalue count as 2.)
  12021. *
  12022. * ALPHAR (output) DOUBLE PRECISION array, dimension (N)
  12023. * ALPHAI (output) DOUBLE PRECISION array, dimension (N)
  12024. * BETA (output) DOUBLE PRECISION array, dimension (N)
  12025. * On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
  12026. * be the generalized eigenvalues. ALPHAR(j) + ALPHAI(j)*i
  12027. * and BETA(j),j=1,...,N are the diagonals of the complex Schur
  12028. * form (S,T) that would result if the 2-by-2 diagonal blocks of
  12029. * the real Schur form of (A,B) were further reduced to
  12030. * triangular form using 2-by-2 complex unitary transformations.
  12031. * If ALPHAI(j) is zero, then the j-th eigenvalue is real; if
  12032. * positive, then the j-th and (j+1)-st eigenvalues are a
  12033. * complex conjugate pair, with ALPHAI(j+1) negative.
  12034. *
  12035. * Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
  12036. * may easily over- or underflow, and BETA(j) may even be zero.
  12037. * Thus, the user should avoid naively computing the ratio.
  12038. * However, ALPHAR and ALPHAI will be always less than and
  12039. * usually comparable with norm(A) in magnitude, and BETA always
  12040. * less than and usually comparable with norm(B).
  12041. *
  12042. * VSL (output) DOUBLE PRECISION array, dimension (LDVSL,N)
  12043. * If JOBVSL = 'V', VSL will contain the left Schur vectors.
  12044. * Not referenced if JOBVSL = 'N'.
  12045. *
  12046. * LDVSL (input) INTEGER
  12047. * The leading dimension of the matrix VSL. LDVSL >=1, and
  12048. * if JOBVSL = 'V', LDVSL >= N.
  12049. *
  12050. * VSR (output) DOUBLE PRECISION array, dimension (LDVSR,N)
  12051. * If JOBVSR = 'V', VSR will contain the right Schur vectors.
  12052. * Not referenced if JOBVSR = 'N'.
  12053. *
  12054. * LDVSR (input) INTEGER
  12055. * The leading dimension of the matrix VSR. LDVSR >= 1, and
  12056. * if JOBVSR = 'V', LDVSR >= N.
  12057. *
  12058. * RCONDE (output) DOUBLE PRECISION array, dimension ( 2 )
  12059. * If SENSE = 'E' or 'B', RCONDE(1) and RCONDE(2) contain the
  12060. * reciprocal condition numbers for the average of the selected
  12061. * eigenvalues.
  12062. * Not referenced if SENSE = 'N' or 'V'.
  12063. *
  12064. * RCONDV (output) DOUBLE PRECISION array, dimension ( 2 )
  12065. * If SENSE = 'V' or 'B', RCONDV(1) and RCONDV(2) contain the
  12066. * reciprocal condition numbers for the selected deflating
  12067. * subspaces.
  12068. * Not referenced if SENSE = 'N' or 'E'.
  12069. *
  12070. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  12071. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  12072. *
  12073. * LWORK (input) INTEGER
  12074. * The dimension of the array WORK.
  12075. * If N = 0, LWORK >= 1, else if SENSE = 'E', 'V', or 'B',
  12076. * LWORK >= max( 8*N, 6*N+16, 2*SDIM*(N-SDIM) ), else
  12077. * LWORK >= max( 8*N, 6*N+16 ).
  12078. * Note that 2*SDIM*(N-SDIM) <= N*N/2.
  12079. * Note also that an error is only returned if
  12080. * LWORK < max( 8*N, 6*N+16), but if SENSE = 'E' or 'V' or 'B'
  12081. * this may not be large enough.
  12082. *
  12083. * If LWORK = -1, then a workspace query is assumed; the routine
  12084. * only calculates the bound on the optimal size of the WORK
  12085. * array and the minimum size of the IWORK array, returns these
  12086. * values as the first entries of the WORK and IWORK arrays, and
  12087. * no error message related to LWORK or LIWORK is issued by
  12088. * XERBLA.
  12089. *
  12090. * IWORK (workspace) INTEGER array, dimension (MAX(1,LIWORK))
  12091. * On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.
  12092. *
  12093. * LIWORK (input) INTEGER
  12094. * The dimension of the array IWORK.
  12095. * If SENSE = 'N' or N = 0, LIWORK >= 1, otherwise
  12096. * LIWORK >= N+6.
  12097. *
  12098. * If LIWORK = -1, then a workspace query is assumed; the
  12099. * routine only calculates the bound on the optimal size of the
  12100. * WORK array and the minimum size of the IWORK array, returns
  12101. * these values as the first entries of the WORK and IWORK
  12102. * arrays, and no error message related to LWORK or LIWORK is
  12103. * issued by XERBLA.
  12104. *
  12105. * BWORK (workspace) LOGICAL array, dimension (N)
  12106. * Not referenced if SORT = 'N'.
  12107. *
  12108. * INFO (output) INTEGER
  12109. * = 0: successful exit
  12110. * < 0: if INFO = -i, the i-th argument had an illegal value.
  12111. * = 1,...,N:
  12112. * The QZ iteration failed. (A,B) are not in Schur
  12113. * form, but ALPHAR(j), ALPHAI(j), and BETA(j) should
  12114. * be correct for j=INFO+1,...,N.
  12115. * > N: =N+1: other than QZ iteration failed in DHGEQZ
  12116. * =N+2: after reordering, roundoff changed values of
  12117. * some complex eigenvalues so that leading
  12118. * eigenvalues in the Generalized Schur form no
  12119. * longer satisfy SELCTG=.TRUE. This could also
  12120. * be caused due to scaling.
  12121. * =N+3: reordering failed in DTGSEN.
  12122. *
  12123. * Further details
  12124. * ===============
  12125. *
  12126. * An approximate (asymptotic) bound on the average absolute error of
  12127. * the selected eigenvalues is
  12128. *
  12129. * EPS * norm((A, B)) / RCONDE( 1 ).
  12130. *
  12131. * An approximate (asymptotic) bound on the maximum angular error in
  12132. * the computed deflating subspaces is
  12133. *
  12134. * EPS * norm((A, B)) / RCONDV( 2 ).
  12135. *
  12136. * See LAPACK User's Guide, section 4.11 for more information.
  12137. *
  12138. * =====================================================================
  12139. *
  12140. * .. Parameters ..
  12141. DOUBLE PRECISION ZERO, ONE
  12142. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  12143. * ..
  12144. * .. Local Scalars ..
  12145. LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
  12146. $ LQUERY, LST2SL, WANTSB, WANTSE, WANTSN, WANTST,
  12147. $ WANTSV
  12148. INTEGER I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,
  12149. $ ILEFT, ILO, IP, IRIGHT, IROWS, ITAU, IWRK,
  12150. $ LIWMIN, LWRK, MAXWRK, MINWRK
  12151. DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
  12152. $ PR, SAFMAX, SAFMIN, SMLNUM
  12153. * ..
  12154. * .. Local Arrays ..
  12155. DOUBLE PRECISION DIF( 2 )
  12156. * ..
  12157. * .. External Subroutines ..
  12158. EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,
  12159. $ DLACPY, DLASCL, DLASET, DORGQR, DORMQR, DTGSEN,
  12160. $ XERBLA
  12161. * ..
  12162. * .. External Functions ..
  12163. LOGICAL LSAME
  12164. INTEGER ILAENV
  12165. DOUBLE PRECISION DLAMCH, DLANGE
  12166. EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE
  12167. * ..
  12168. * .. Intrinsic Functions ..
  12169. INTRINSIC ABS, MAX, SQRT
  12170. * ..
  12171. * .. Executable Statements ..
  12172. *
  12173. * Decode the input arguments
  12174. *
  12175. IF( LSAME( JOBVSL, 'N' ) ) THEN
  12176. IJOBVL = 1
  12177. ILVSL = .FALSE.
  12178. ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
  12179. IJOBVL = 2
  12180. ILVSL = .TRUE.
  12181. ELSE
  12182. IJOBVL = -1
  12183. ILVSL = .FALSE.
  12184. END IF
  12185. *
  12186. IF( LSAME( JOBVSR, 'N' ) ) THEN
  12187. IJOBVR = 1
  12188. ILVSR = .FALSE.
  12189. ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
  12190. IJOBVR = 2
  12191. ILVSR = .TRUE.
  12192. ELSE
  12193. IJOBVR = -1
  12194. ILVSR = .FALSE.
  12195. END IF
  12196. *
  12197. WANTST = LSAME( SORT, 'S' )
  12198. WANTSN = LSAME( SENSE, 'N' )
  12199. WANTSE = LSAME( SENSE, 'E' )
  12200. WANTSV = LSAME( SENSE, 'V' )
  12201. WANTSB = LSAME( SENSE, 'B' )
  12202. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  12203. IF( WANTSN ) THEN
  12204. IJOB = 0
  12205. ELSE IF( WANTSE ) THEN
  12206. IJOB = 1
  12207. ELSE IF( WANTSV ) THEN
  12208. IJOB = 2
  12209. ELSE IF( WANTSB ) THEN
  12210. IJOB = 4
  12211. END IF
  12212. *
  12213. * Test the input arguments
  12214. *
  12215. INFO = 0
  12216. IF( IJOBVL.LE.0 ) THEN
  12217. INFO = -1
  12218. ELSE IF( IJOBVR.LE.0 ) THEN
  12219. INFO = -2
  12220. ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
  12221. INFO = -3
  12222. ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
  12223. $ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
  12224. INFO = -5
  12225. ELSE IF( N.LT.0 ) THEN
  12226. INFO = -6
  12227. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  12228. INFO = -8
  12229. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  12230. INFO = -10
  12231. ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
  12232. INFO = -16
  12233. ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
  12234. INFO = -18
  12235. END IF
  12236. *
  12237. * Compute workspace
  12238. * (Note: Comments in the code beginning "Workspace:" describe the
  12239. * minimal amount of workspace needed at that point in the code,
  12240. * as well as the preferred amount for good performance.
  12241. * NB refers to the optimal block size for the immediately
  12242. * following subroutine, as returned by ILAENV.)
  12243. *
  12244. IF( INFO.EQ.0 ) THEN
  12245. IF( N.GT.0) THEN
  12246. MINWRK = MAX( 8*N, 6*N + 16 )
  12247. MAXWRK = MINWRK - N +
  12248. $ N*ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 )
  12249. MAXWRK = MAX( MAXWRK, MINWRK - N +
  12250. $ N*ILAENV( 1, 'DORMQR', ' ', N, 1, N, -1 ) )
  12251. IF( ILVSL ) THEN
  12252. MAXWRK = MAX( MAXWRK, MINWRK - N +
  12253. $ N*ILAENV( 1, 'DORGQR', ' ', N, 1, N, -1 ) )
  12254. END IF
  12255. LWRK = MAXWRK
  12256. IF( IJOB.GE.1 )
  12257. $ LWRK = MAX( LWRK, N*N/2 )
  12258. ELSE
  12259. MINWRK = 1
  12260. MAXWRK = 1
  12261. LWRK = 1
  12262. END IF
  12263. WORK( 1 ) = LWRK
  12264. IF( WANTSN .OR. N.EQ.0 ) THEN
  12265. LIWMIN = 1
  12266. ELSE
  12267. LIWMIN = N + 6
  12268. END IF
  12269. IWORK( 1 ) = LIWMIN
  12270. *
  12271. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  12272. INFO = -22
  12273. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  12274. INFO = -24
  12275. END IF
  12276. END IF
  12277. *
  12278. IF( INFO.NE.0 ) THEN
  12279. CALL XERBLA( 'DGGESX', -INFO )
  12280. RETURN
  12281. ELSE IF (LQUERY) THEN
  12282. RETURN
  12283. END IF
  12284. *
  12285. * Quick return if possible
  12286. *
  12287. IF( N.EQ.0 ) THEN
  12288. SDIM = 0
  12289. RETURN
  12290. END IF
  12291. *
  12292. * Get machine constants
  12293. *
  12294. EPS = DLAMCH( 'P' )
  12295. SAFMIN = DLAMCH( 'S' )
  12296. SAFMAX = ONE / SAFMIN
  12297. CALL DLABAD( SAFMIN, SAFMAX )
  12298. SMLNUM = SQRT( SAFMIN ) / EPS
  12299. BIGNUM = ONE / SMLNUM
  12300. *
  12301. * Scale A if max element outside range [SMLNUM,BIGNUM]
  12302. *
  12303. ANRM = DLANGE( 'M', N, N, A, LDA, WORK )
  12304. ILASCL = .FALSE.
  12305. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  12306. ANRMTO = SMLNUM
  12307. ILASCL = .TRUE.
  12308. ELSE IF( ANRM.GT.BIGNUM ) THEN
  12309. ANRMTO = BIGNUM
  12310. ILASCL = .TRUE.
  12311. END IF
  12312. IF( ILASCL )
  12313. $ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
  12314. *
  12315. * Scale B if max element outside range [SMLNUM,BIGNUM]
  12316. *
  12317. BNRM = DLANGE( 'M', N, N, B, LDB, WORK )
  12318. ILBSCL = .FALSE.
  12319. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  12320. BNRMTO = SMLNUM
  12321. ILBSCL = .TRUE.
  12322. ELSE IF( BNRM.GT.BIGNUM ) THEN
  12323. BNRMTO = BIGNUM
  12324. ILBSCL = .TRUE.
  12325. END IF
  12326. IF( ILBSCL )
  12327. $ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
  12328. *
  12329. * Permute the matrix to make it more nearly triangular
  12330. * (Workspace: need 6*N + 2*N for permutation parameters)
  12331. *
  12332. ILEFT = 1
  12333. IRIGHT = N + 1
  12334. IWRK = IRIGHT + N
  12335. CALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
  12336. $ WORK( IRIGHT ), WORK( IWRK ), IERR )
  12337. *
  12338. * Reduce B to triangular form (QR decomposition of B)
  12339. * (Workspace: need N, prefer N*NB)
  12340. *
  12341. IROWS = IHI + 1 - ILO
  12342. ICOLS = N + 1 - ILO
  12343. ITAU = IWRK
  12344. IWRK = ITAU + IROWS
  12345. CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
  12346. $ WORK( IWRK ), LWORK+1-IWRK, IERR )
  12347. *
  12348. * Apply the orthogonal transformation to matrix A
  12349. * (Workspace: need N, prefer N*NB)
  12350. *
  12351. CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
  12352. $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
  12353. $ LWORK+1-IWRK, IERR )
  12354. *
  12355. * Initialize VSL
  12356. * (Workspace: need N, prefer N*NB)
  12357. *
  12358. IF( ILVSL ) THEN
  12359. CALL DLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL )
  12360. IF( IROWS.GT.1 ) THEN
  12361. CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
  12362. $ VSL( ILO+1, ILO ), LDVSL )
  12363. END IF
  12364. CALL DORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
  12365. $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
  12366. END IF
  12367. *
  12368. * Initialize VSR
  12369. *
  12370. IF( ILVSR )
  12371. $ CALL DLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR )
  12372. *
  12373. * Reduce to generalized Hessenberg form
  12374. * (Workspace: none needed)
  12375. *
  12376. CALL DGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
  12377. $ LDVSL, VSR, LDVSR, IERR )
  12378. *
  12379. SDIM = 0
  12380. *
  12381. * Perform QZ algorithm, computing Schur vectors if desired
  12382. * (Workspace: need N)
  12383. *
  12384. IWRK = ITAU
  12385. CALL DHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
  12386. $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
  12387. $ WORK( IWRK ), LWORK+1-IWRK, IERR )
  12388. IF( IERR.NE.0 ) THEN
  12389. IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
  12390. INFO = IERR
  12391. ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
  12392. INFO = IERR - N
  12393. ELSE
  12394. INFO = N + 1
  12395. END IF
  12396. GO TO 60
  12397. END IF
  12398. *
  12399. * Sort eigenvalues ALPHA/BETA and compute the reciprocal of
  12400. * condition number(s)
  12401. * (Workspace: If IJOB >= 1, need MAX( 8*(N+1), 2*SDIM*(N-SDIM) )
  12402. * otherwise, need 8*(N+1) )
  12403. *
  12404. IF( WANTST ) THEN
  12405. *
  12406. * Undo scaling on eigenvalues before SELCTGing
  12407. *
  12408. IF( ILASCL ) THEN
  12409. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N,
  12410. $ IERR )
  12411. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N,
  12412. $ IERR )
  12413. END IF
  12414. IF( ILBSCL )
  12415. $ CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
  12416. *
  12417. * Select eigenvalues
  12418. *
  12419. DO 10 I = 1, N
  12420. BWORK( I ) = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )
  12421. 10 CONTINUE
  12422. *
  12423. * Reorder eigenvalues, transform Generalized Schur vectors, and
  12424. * compute reciprocal condition numbers
  12425. *
  12426. CALL DTGSEN( IJOB, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
  12427. $ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,
  12428. $ SDIM, PL, PR, DIF, WORK( IWRK ), LWORK-IWRK+1,
  12429. $ IWORK, LIWORK, IERR )
  12430. *
  12431. IF( IJOB.GE.1 )
  12432. $ MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )
  12433. IF( IERR.EQ.-22 ) THEN
  12434. *
  12435. * not enough real workspace
  12436. *
  12437. INFO = -22
  12438. ELSE
  12439. IF( IJOB.EQ.1 .OR. IJOB.EQ.4 ) THEN
  12440. RCONDE( 1 ) = PL
  12441. RCONDE( 2 ) = PR
  12442. END IF
  12443. IF( IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
  12444. RCONDV( 1 ) = DIF( 1 )
  12445. RCONDV( 2 ) = DIF( 2 )
  12446. END IF
  12447. IF( IERR.EQ.1 )
  12448. $ INFO = N + 3
  12449. END IF
  12450. *
  12451. END IF
  12452. *
  12453. * Apply permutation to VSL and VSR
  12454. * (Workspace: none needed)
  12455. *
  12456. IF( ILVSL )
  12457. $ CALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
  12458. $ WORK( IRIGHT ), N, VSL, LDVSL, IERR )
  12459. *
  12460. IF( ILVSR )
  12461. $ CALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
  12462. $ WORK( IRIGHT ), N, VSR, LDVSR, IERR )
  12463. *
  12464. * Check if unscaling would cause over/underflow, if so, rescale
  12465. * (ALPHAR(I),ALPHAI(I),BETA(I)) so BETA(I) is on the order of
  12466. * B(I,I) and ALPHAR(I) and ALPHAI(I) are on the order of A(I,I)
  12467. *
  12468. IF( ILASCL ) THEN
  12469. DO 20 I = 1, N
  12470. IF( ALPHAI( I ).NE.ZERO ) THEN
  12471. IF( ( ALPHAR( I ) / SAFMAX ).GT.( ANRMTO / ANRM ) .OR.
  12472. $ ( SAFMIN / ALPHAR( I ) ).GT.( ANRM / ANRMTO ) ) THEN
  12473. WORK( 1 ) = ABS( A( I, I ) / ALPHAR( I ) )
  12474. BETA( I ) = BETA( I )*WORK( 1 )
  12475. ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
  12476. ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
  12477. ELSE IF( ( ALPHAI( I ) / SAFMAX ).GT.
  12478. $ ( ANRMTO / ANRM ) .OR.
  12479. $ ( SAFMIN / ALPHAI( I ) ).GT.( ANRM / ANRMTO ) )
  12480. $ THEN
  12481. WORK( 1 ) = ABS( A( I, I+1 ) / ALPHAI( I ) )
  12482. BETA( I ) = BETA( I )*WORK( 1 )
  12483. ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
  12484. ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
  12485. END IF
  12486. END IF
  12487. 20 CONTINUE
  12488. END IF
  12489. *
  12490. IF( ILBSCL ) THEN
  12491. DO 30 I = 1, N
  12492. IF( ALPHAI( I ).NE.ZERO ) THEN
  12493. IF( ( BETA( I ) / SAFMAX ).GT.( BNRMTO / BNRM ) .OR.
  12494. $ ( SAFMIN / BETA( I ) ).GT.( BNRM / BNRMTO ) ) THEN
  12495. WORK( 1 ) = ABS( B( I, I ) / BETA( I ) )
  12496. BETA( I ) = BETA( I )*WORK( 1 )
  12497. ALPHAR( I ) = ALPHAR( I )*WORK( 1 )
  12498. ALPHAI( I ) = ALPHAI( I )*WORK( 1 )
  12499. END IF
  12500. END IF
  12501. 30 CONTINUE
  12502. END IF
  12503. *
  12504. * Undo scaling
  12505. *
  12506. IF( ILASCL ) THEN
  12507. CALL DLASCL( 'H', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )
  12508. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
  12509. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
  12510. END IF
  12511. *
  12512. IF( ILBSCL ) THEN
  12513. CALL DLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )
  12514. CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
  12515. END IF
  12516. *
  12517. IF( WANTST ) THEN
  12518. *
  12519. * Check if reordering is correct
  12520. *
  12521. LASTSL = .TRUE.
  12522. LST2SL = .TRUE.
  12523. SDIM = 0
  12524. IP = 0
  12525. DO 50 I = 1, N
  12526. CURSL = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )
  12527. IF( ALPHAI( I ).EQ.ZERO ) THEN
  12528. IF( CURSL )
  12529. $ SDIM = SDIM + 1
  12530. IP = 0
  12531. IF( CURSL .AND. .NOT.LASTSL )
  12532. $ INFO = N + 2
  12533. ELSE
  12534. IF( IP.EQ.1 ) THEN
  12535. *
  12536. * Last eigenvalue of conjugate pair
  12537. *
  12538. CURSL = CURSL .OR. LASTSL
  12539. LASTSL = CURSL
  12540. IF( CURSL )
  12541. $ SDIM = SDIM + 2
  12542. IP = -1
  12543. IF( CURSL .AND. .NOT.LST2SL )
  12544. $ INFO = N + 2
  12545. ELSE
  12546. *
  12547. * First eigenvalue of conjugate pair
  12548. *
  12549. IP = 1
  12550. END IF
  12551. END IF
  12552. LST2SL = LASTSL
  12553. LASTSL = CURSL
  12554. 50 CONTINUE
  12555. *
  12556. END IF
  12557. *
  12558. 60 CONTINUE
  12559. *
  12560. WORK( 1 ) = MAXWRK
  12561. IWORK( 1 ) = LIWMIN
  12562. *
  12563. RETURN
  12564. *
  12565. * End of DGGESX
  12566. *
  12567. END
  12568. SUBROUTINE DGGEV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,
  12569. $ BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )
  12570. *
  12571. * -- LAPACK driver routine (version 3.1) --
  12572. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  12573. * November 2006
  12574. *
  12575. * .. Scalar Arguments ..
  12576. CHARACTER JOBVL, JOBVR
  12577. INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N
  12578. * ..
  12579. * .. Array Arguments ..
  12580. DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
  12581. $ B( LDB, * ), BETA( * ), VL( LDVL, * ),
  12582. $ VR( LDVR, * ), WORK( * )
  12583. * ..
  12584. *
  12585. * Purpose
  12586. * =======
  12587. *
  12588. * DGGEV computes for a pair of N-by-N real nonsymmetric matrices (A,B)
  12589. * the generalized eigenvalues, and optionally, the left and/or right
  12590. * generalized eigenvectors.
  12591. *
  12592. * A generalized eigenvalue for a pair of matrices (A,B) is a scalar
  12593. * lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
  12594. * singular. It is usually represented as the pair (alpha,beta), as
  12595. * there is a reasonable interpretation for beta=0, and even for both
  12596. * being zero.
  12597. *
  12598. * The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
  12599. * of (A,B) satisfies
  12600. *
  12601. * A * v(j) = lambda(j) * B * v(j).
  12602. *
  12603. * The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
  12604. * of (A,B) satisfies
  12605. *
  12606. * u(j)**H * A = lambda(j) * u(j)**H * B .
  12607. *
  12608. * where u(j)**H is the conjugate-transpose of u(j).
  12609. *
  12610. *
  12611. * Arguments
  12612. * =========
  12613. *
  12614. * JOBVL (input) CHARACTER*1
  12615. * = 'N': do not compute the left generalized eigenvectors;
  12616. * = 'V': compute the left generalized eigenvectors.
  12617. *
  12618. * JOBVR (input) CHARACTER*1
  12619. * = 'N': do not compute the right generalized eigenvectors;
  12620. * = 'V': compute the right generalized eigenvectors.
  12621. *
  12622. * N (input) INTEGER
  12623. * The order of the matrices A, B, VL, and VR. N >= 0.
  12624. *
  12625. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  12626. * On entry, the matrix A in the pair (A,B).
  12627. * On exit, A has been overwritten.
  12628. *
  12629. * LDA (input) INTEGER
  12630. * The leading dimension of A. LDA >= max(1,N).
  12631. *
  12632. * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
  12633. * On entry, the matrix B in the pair (A,B).
  12634. * On exit, B has been overwritten.
  12635. *
  12636. * LDB (input) INTEGER
  12637. * The leading dimension of B. LDB >= max(1,N).
  12638. *
  12639. * ALPHAR (output) DOUBLE PRECISION array, dimension (N)
  12640. * ALPHAI (output) DOUBLE PRECISION array, dimension (N)
  12641. * BETA (output) DOUBLE PRECISION array, dimension (N)
  12642. * On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
  12643. * be the generalized eigenvalues. If ALPHAI(j) is zero, then
  12644. * the j-th eigenvalue is real; if positive, then the j-th and
  12645. * (j+1)-st eigenvalues are a complex conjugate pair, with
  12646. * ALPHAI(j+1) negative.
  12647. *
  12648. * Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
  12649. * may easily over- or underflow, and BETA(j) may even be zero.
  12650. * Thus, the user should avoid naively computing the ratio
  12651. * alpha/beta. However, ALPHAR and ALPHAI will be always less
  12652. * than and usually comparable with norm(A) in magnitude, and
  12653. * BETA always less than and usually comparable with norm(B).
  12654. *
  12655. * VL (output) DOUBLE PRECISION array, dimension (LDVL,N)
  12656. * If JOBVL = 'V', the left eigenvectors u(j) are stored one
  12657. * after another in the columns of VL, in the same order as
  12658. * their eigenvalues. If the j-th eigenvalue is real, then
  12659. * u(j) = VL(:,j), the j-th column of VL. If the j-th and
  12660. * (j+1)-th eigenvalues form a complex conjugate pair, then
  12661. * u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).
  12662. * Each eigenvector is scaled so the largest component has
  12663. * abs(real part)+abs(imag. part)=1.
  12664. * Not referenced if JOBVL = 'N'.
  12665. *
  12666. * LDVL (input) INTEGER
  12667. * The leading dimension of the matrix VL. LDVL >= 1, and
  12668. * if JOBVL = 'V', LDVL >= N.
  12669. *
  12670. * VR (output) DOUBLE PRECISION array, dimension (LDVR,N)
  12671. * If JOBVR = 'V', the right eigenvectors v(j) are stored one
  12672. * after another in the columns of VR, in the same order as
  12673. * their eigenvalues. If the j-th eigenvalue is real, then
  12674. * v(j) = VR(:,j), the j-th column of VR. If the j-th and
  12675. * (j+1)-th eigenvalues form a complex conjugate pair, then
  12676. * v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).
  12677. * Each eigenvector is scaled so the largest component has
  12678. * abs(real part)+abs(imag. part)=1.
  12679. * Not referenced if JOBVR = 'N'.
  12680. *
  12681. * LDVR (input) INTEGER
  12682. * The leading dimension of the matrix VR. LDVR >= 1, and
  12683. * if JOBVR = 'V', LDVR >= N.
  12684. *
  12685. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  12686. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  12687. *
  12688. * LWORK (input) INTEGER
  12689. * The dimension of the array WORK. LWORK >= max(1,8*N).
  12690. * For good performance, LWORK must generally be larger.
  12691. *
  12692. * If LWORK = -1, then a workspace query is assumed; the routine
  12693. * only calculates the optimal size of the WORK array, returns
  12694. * this value as the first entry of the WORK array, and no error
  12695. * message related to LWORK is issued by XERBLA.
  12696. *
  12697. * INFO (output) INTEGER
  12698. * = 0: successful exit
  12699. * < 0: if INFO = -i, the i-th argument had an illegal value.
  12700. * = 1,...,N:
  12701. * The QZ iteration failed. No eigenvectors have been
  12702. * calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
  12703. * should be correct for j=INFO+1,...,N.
  12704. * > N: =N+1: other than QZ iteration failed in DHGEQZ.
  12705. * =N+2: error return from DTGEVC.
  12706. *
  12707. * =====================================================================
  12708. *
  12709. * .. Parameters ..
  12710. DOUBLE PRECISION ZERO, ONE
  12711. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  12712. * ..
  12713. * .. Local Scalars ..
  12714. LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY
  12715. CHARACTER CHTEMP
  12716. INTEGER ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,
  12717. $ IN, IRIGHT, IROWS, ITAU, IWRK, JC, JR, MAXWRK,
  12718. $ MINWRK
  12719. DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
  12720. $ SMLNUM, TEMP
  12721. * ..
  12722. * .. Local Arrays ..
  12723. LOGICAL LDUMMA( 1 )
  12724. * ..
  12725. * .. External Subroutines ..
  12726. EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,
  12727. $ DLACPY,DLASCL, DLASET, DORGQR, DORMQR, DTGEVC,
  12728. $ XERBLA
  12729. * ..
  12730. * .. External Functions ..
  12731. LOGICAL LSAME
  12732. INTEGER ILAENV
  12733. DOUBLE PRECISION DLAMCH, DLANGE
  12734. EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE
  12735. * ..
  12736. * .. Intrinsic Functions ..
  12737. INTRINSIC ABS, MAX, SQRT
  12738. * ..
  12739. * .. Executable Statements ..
  12740. *
  12741. * Decode the input arguments
  12742. *
  12743. IF( LSAME( JOBVL, 'N' ) ) THEN
  12744. IJOBVL = 1
  12745. ILVL = .FALSE.
  12746. ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
  12747. IJOBVL = 2
  12748. ILVL = .TRUE.
  12749. ELSE
  12750. IJOBVL = -1
  12751. ILVL = .FALSE.
  12752. END IF
  12753. *
  12754. IF( LSAME( JOBVR, 'N' ) ) THEN
  12755. IJOBVR = 1
  12756. ILVR = .FALSE.
  12757. ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
  12758. IJOBVR = 2
  12759. ILVR = .TRUE.
  12760. ELSE
  12761. IJOBVR = -1
  12762. ILVR = .FALSE.
  12763. END IF
  12764. ILV = ILVL .OR. ILVR
  12765. *
  12766. * Test the input arguments
  12767. *
  12768. INFO = 0
  12769. LQUERY = ( LWORK.EQ.-1 )
  12770. IF( IJOBVL.LE.0 ) THEN
  12771. INFO = -1
  12772. ELSE IF( IJOBVR.LE.0 ) THEN
  12773. INFO = -2
  12774. ELSE IF( N.LT.0 ) THEN
  12775. INFO = -3
  12776. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  12777. INFO = -5
  12778. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  12779. INFO = -7
  12780. ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
  12781. INFO = -12
  12782. ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
  12783. INFO = -14
  12784. END IF
  12785. *
  12786. * Compute workspace
  12787. * (Note: Comments in the code beginning "Workspace:" describe the
  12788. * minimal amount of workspace needed at that point in the code,
  12789. * as well as the preferred amount for good performance.
  12790. * NB refers to the optimal block size for the immediately
  12791. * following subroutine, as returned by ILAENV. The workspace is
  12792. * computed assuming ILO = 1 and IHI = N, the worst case.)
  12793. *
  12794. IF( INFO.EQ.0 ) THEN
  12795. MINWRK = MAX( 1, 8*N )
  12796. MAXWRK = MAX( 1, N*( 7 +
  12797. $ ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 ) ) )
  12798. MAXWRK = MAX( MAXWRK, N*( 7 +
  12799. $ ILAENV( 1, 'DORMQR', ' ', N, 1, N, 0 ) ) )
  12800. IF( ILVL ) THEN
  12801. MAXWRK = MAX( MAXWRK, N*( 7 +
  12802. $ ILAENV( 1, 'DORGQR', ' ', N, 1, N, -1 ) ) )
  12803. END IF
  12804. WORK( 1 ) = MAXWRK
  12805. *
  12806. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )
  12807. $ INFO = -16
  12808. END IF
  12809. *
  12810. IF( INFO.NE.0 ) THEN
  12811. CALL XERBLA( 'DGGEV ', -INFO )
  12812. RETURN
  12813. ELSE IF( LQUERY ) THEN
  12814. RETURN
  12815. END IF
  12816. *
  12817. * Quick return if possible
  12818. *
  12819. IF( N.EQ.0 )
  12820. $ RETURN
  12821. *
  12822. * Get machine constants
  12823. *
  12824. EPS = DLAMCH( 'P' )
  12825. SMLNUM = DLAMCH( 'S' )
  12826. BIGNUM = ONE / SMLNUM
  12827. CALL DLABAD( SMLNUM, BIGNUM )
  12828. SMLNUM = SQRT( SMLNUM ) / EPS
  12829. BIGNUM = ONE / SMLNUM
  12830. *
  12831. * Scale A if max element outside range [SMLNUM,BIGNUM]
  12832. *
  12833. ANRM = DLANGE( 'M', N, N, A, LDA, WORK )
  12834. ILASCL = .FALSE.
  12835. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  12836. ANRMTO = SMLNUM
  12837. ILASCL = .TRUE.
  12838. ELSE IF( ANRM.GT.BIGNUM ) THEN
  12839. ANRMTO = BIGNUM
  12840. ILASCL = .TRUE.
  12841. END IF
  12842. IF( ILASCL )
  12843. $ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
  12844. *
  12845. * Scale B if max element outside range [SMLNUM,BIGNUM]
  12846. *
  12847. BNRM = DLANGE( 'M', N, N, B, LDB, WORK )
  12848. ILBSCL = .FALSE.
  12849. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  12850. BNRMTO = SMLNUM
  12851. ILBSCL = .TRUE.
  12852. ELSE IF( BNRM.GT.BIGNUM ) THEN
  12853. BNRMTO = BIGNUM
  12854. ILBSCL = .TRUE.
  12855. END IF
  12856. IF( ILBSCL )
  12857. $ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
  12858. *
  12859. * Permute the matrices A, B to isolate eigenvalues if possible
  12860. * (Workspace: need 6*N)
  12861. *
  12862. ILEFT = 1
  12863. IRIGHT = N + 1
  12864. IWRK = IRIGHT + N
  12865. CALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),
  12866. $ WORK( IRIGHT ), WORK( IWRK ), IERR )
  12867. *
  12868. * Reduce B to triangular form (QR decomposition of B)
  12869. * (Workspace: need N, prefer N*NB)
  12870. *
  12871. IROWS = IHI + 1 - ILO
  12872. IF( ILV ) THEN
  12873. ICOLS = N + 1 - ILO
  12874. ELSE
  12875. ICOLS = IROWS
  12876. END IF
  12877. ITAU = IWRK
  12878. IWRK = ITAU + IROWS
  12879. CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
  12880. $ WORK( IWRK ), LWORK+1-IWRK, IERR )
  12881. *
  12882. * Apply the orthogonal transformation to matrix A
  12883. * (Workspace: need N, prefer N*NB)
  12884. *
  12885. CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
  12886. $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
  12887. $ LWORK+1-IWRK, IERR )
  12888. *
  12889. * Initialize VL
  12890. * (Workspace: need N, prefer N*NB)
  12891. *
  12892. IF( ILVL ) THEN
  12893. CALL DLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )
  12894. IF( IROWS.GT.1 ) THEN
  12895. CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
  12896. $ VL( ILO+1, ILO ), LDVL )
  12897. END IF
  12898. CALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
  12899. $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
  12900. END IF
  12901. *
  12902. * Initialize VR
  12903. *
  12904. IF( ILVR )
  12905. $ CALL DLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )
  12906. *
  12907. * Reduce to generalized Hessenberg form
  12908. * (Workspace: none needed)
  12909. *
  12910. IF( ILV ) THEN
  12911. *
  12912. * Eigenvectors requested -- work on whole matrix.
  12913. *
  12914. CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
  12915. $ LDVL, VR, LDVR, IERR )
  12916. ELSE
  12917. CALL DGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
  12918. $ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )
  12919. END IF
  12920. *
  12921. * Perform QZ algorithm (Compute eigenvalues, and optionally, the
  12922. * Schur forms and Schur vectors)
  12923. * (Workspace: need N)
  12924. *
  12925. IWRK = ITAU
  12926. IF( ILV ) THEN
  12927. CHTEMP = 'S'
  12928. ELSE
  12929. CHTEMP = 'E'
  12930. END IF
  12931. CALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
  12932. $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,
  12933. $ WORK( IWRK ), LWORK+1-IWRK, IERR )
  12934. IF( IERR.NE.0 ) THEN
  12935. IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
  12936. INFO = IERR
  12937. ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
  12938. INFO = IERR - N
  12939. ELSE
  12940. INFO = N + 1
  12941. END IF
  12942. GO TO 110
  12943. END IF
  12944. *
  12945. * Compute Eigenvectors
  12946. * (Workspace: need 6*N)
  12947. *
  12948. IF( ILV ) THEN
  12949. IF( ILVL ) THEN
  12950. IF( ILVR ) THEN
  12951. CHTEMP = 'B'
  12952. ELSE
  12953. CHTEMP = 'L'
  12954. END IF
  12955. ELSE
  12956. CHTEMP = 'R'
  12957. END IF
  12958. CALL DTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
  12959. $ VR, LDVR, N, IN, WORK( IWRK ), IERR )
  12960. IF( IERR.NE.0 ) THEN
  12961. INFO = N + 2
  12962. GO TO 110
  12963. END IF
  12964. *
  12965. * Undo balancing on VL and VR and normalization
  12966. * (Workspace: none needed)
  12967. *
  12968. IF( ILVL ) THEN
  12969. CALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),
  12970. $ WORK( IRIGHT ), N, VL, LDVL, IERR )
  12971. DO 50 JC = 1, N
  12972. IF( ALPHAI( JC ).LT.ZERO )
  12973. $ GO TO 50
  12974. TEMP = ZERO
  12975. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  12976. DO 10 JR = 1, N
  12977. TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )
  12978. 10 CONTINUE
  12979. ELSE
  12980. DO 20 JR = 1, N
  12981. TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+
  12982. $ ABS( VL( JR, JC+1 ) ) )
  12983. 20 CONTINUE
  12984. END IF
  12985. IF( TEMP.LT.SMLNUM )
  12986. $ GO TO 50
  12987. TEMP = ONE / TEMP
  12988. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  12989. DO 30 JR = 1, N
  12990. VL( JR, JC ) = VL( JR, JC )*TEMP
  12991. 30 CONTINUE
  12992. ELSE
  12993. DO 40 JR = 1, N
  12994. VL( JR, JC ) = VL( JR, JC )*TEMP
  12995. VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP
  12996. 40 CONTINUE
  12997. END IF
  12998. 50 CONTINUE
  12999. END IF
  13000. IF( ILVR ) THEN
  13001. CALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),
  13002. $ WORK( IRIGHT ), N, VR, LDVR, IERR )
  13003. DO 100 JC = 1, N
  13004. IF( ALPHAI( JC ).LT.ZERO )
  13005. $ GO TO 100
  13006. TEMP = ZERO
  13007. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  13008. DO 60 JR = 1, N
  13009. TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )
  13010. 60 CONTINUE
  13011. ELSE
  13012. DO 70 JR = 1, N
  13013. TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+
  13014. $ ABS( VR( JR, JC+1 ) ) )
  13015. 70 CONTINUE
  13016. END IF
  13017. IF( TEMP.LT.SMLNUM )
  13018. $ GO TO 100
  13019. TEMP = ONE / TEMP
  13020. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  13021. DO 80 JR = 1, N
  13022. VR( JR, JC ) = VR( JR, JC )*TEMP
  13023. 80 CONTINUE
  13024. ELSE
  13025. DO 90 JR = 1, N
  13026. VR( JR, JC ) = VR( JR, JC )*TEMP
  13027. VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP
  13028. 90 CONTINUE
  13029. END IF
  13030. 100 CONTINUE
  13031. END IF
  13032. *
  13033. * End of eigenvector calculation
  13034. *
  13035. END IF
  13036. *
  13037. * Undo scaling if necessary
  13038. *
  13039. IF( ILASCL ) THEN
  13040. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
  13041. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
  13042. END IF
  13043. *
  13044. IF( ILBSCL ) THEN
  13045. CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
  13046. END IF
  13047. *
  13048. 110 CONTINUE
  13049. *
  13050. WORK( 1 ) = MAXWRK
  13051. *
  13052. RETURN
  13053. *
  13054. * End of DGGEV
  13055. *
  13056. END
  13057. SUBROUTINE DGGEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B, LDB,
  13058. $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO,
  13059. $ IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE,
  13060. $ RCONDV, WORK, LWORK, IWORK, BWORK, INFO )
  13061. *
  13062. * -- LAPACK driver routine (version 3.1) --
  13063. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  13064. * November 2006
  13065. *
  13066. * .. Scalar Arguments ..
  13067. CHARACTER BALANC, JOBVL, JOBVR, SENSE
  13068. INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N
  13069. DOUBLE PRECISION ABNRM, BBNRM
  13070. * ..
  13071. * .. Array Arguments ..
  13072. LOGICAL BWORK( * )
  13073. INTEGER IWORK( * )
  13074. DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),
  13075. $ B( LDB, * ), BETA( * ), LSCALE( * ),
  13076. $ RCONDE( * ), RCONDV( * ), RSCALE( * ),
  13077. $ VL( LDVL, * ), VR( LDVR, * ), WORK( * )
  13078. * ..
  13079. *
  13080. * Purpose
  13081. * =======
  13082. *
  13083. * DGGEVX computes for a pair of N-by-N real nonsymmetric matrices (A,B)
  13084. * the generalized eigenvalues, and optionally, the left and/or right
  13085. * generalized eigenvectors.
  13086. *
  13087. * Optionally also, it computes a balancing transformation to improve
  13088. * the conditioning of the eigenvalues and eigenvectors (ILO, IHI,
  13089. * LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for
  13090. * the eigenvalues (RCONDE), and reciprocal condition numbers for the
  13091. * right eigenvectors (RCONDV).
  13092. *
  13093. * A generalized eigenvalue for a pair of matrices (A,B) is a scalar
  13094. * lambda or a ratio alpha/beta = lambda, such that A - lambda*B is
  13095. * singular. It is usually represented as the pair (alpha,beta), as
  13096. * there is a reasonable interpretation for beta=0, and even for both
  13097. * being zero.
  13098. *
  13099. * The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
  13100. * of (A,B) satisfies
  13101. *
  13102. * A * v(j) = lambda(j) * B * v(j) .
  13103. *
  13104. * The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
  13105. * of (A,B) satisfies
  13106. *
  13107. * u(j)**H * A = lambda(j) * u(j)**H * B.
  13108. *
  13109. * where u(j)**H is the conjugate-transpose of u(j).
  13110. *
  13111. *
  13112. * Arguments
  13113. * =========
  13114. *
  13115. * BALANC (input) CHARACTER*1
  13116. * Specifies the balance option to be performed.
  13117. * = 'N': do not diagonally scale or permute;
  13118. * = 'P': permute only;
  13119. * = 'S': scale only;
  13120. * = 'B': both permute and scale.
  13121. * Computed reciprocal condition numbers will be for the
  13122. * matrices after permuting and/or balancing. Permuting does
  13123. * not change condition numbers (in exact arithmetic), but
  13124. * balancing does.
  13125. *
  13126. * JOBVL (input) CHARACTER*1
  13127. * = 'N': do not compute the left generalized eigenvectors;
  13128. * = 'V': compute the left generalized eigenvectors.
  13129. *
  13130. * JOBVR (input) CHARACTER*1
  13131. * = 'N': do not compute the right generalized eigenvectors;
  13132. * = 'V': compute the right generalized eigenvectors.
  13133. *
  13134. * SENSE (input) CHARACTER*1
  13135. * Determines which reciprocal condition numbers are computed.
  13136. * = 'N': none are computed;
  13137. * = 'E': computed for eigenvalues only;
  13138. * = 'V': computed for eigenvectors only;
  13139. * = 'B': computed for eigenvalues and eigenvectors.
  13140. *
  13141. * N (input) INTEGER
  13142. * The order of the matrices A, B, VL, and VR. N >= 0.
  13143. *
  13144. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  13145. * On entry, the matrix A in the pair (A,B).
  13146. * On exit, A has been overwritten. If JOBVL='V' or JOBVR='V'
  13147. * or both, then A contains the first part of the real Schur
  13148. * form of the "balanced" versions of the input A and B.
  13149. *
  13150. * LDA (input) INTEGER
  13151. * The leading dimension of A. LDA >= max(1,N).
  13152. *
  13153. * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
  13154. * On entry, the matrix B in the pair (A,B).
  13155. * On exit, B has been overwritten. If JOBVL='V' or JOBVR='V'
  13156. * or both, then B contains the second part of the real Schur
  13157. * form of the "balanced" versions of the input A and B.
  13158. *
  13159. * LDB (input) INTEGER
  13160. * The leading dimension of B. LDB >= max(1,N).
  13161. *
  13162. * ALPHAR (output) DOUBLE PRECISION array, dimension (N)
  13163. * ALPHAI (output) DOUBLE PRECISION array, dimension (N)
  13164. * BETA (output) DOUBLE PRECISION array, dimension (N)
  13165. * On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will
  13166. * be the generalized eigenvalues. If ALPHAI(j) is zero, then
  13167. * the j-th eigenvalue is real; if positive, then the j-th and
  13168. * (j+1)-st eigenvalues are a complex conjugate pair, with
  13169. * ALPHAI(j+1) negative.
  13170. *
  13171. * Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
  13172. * may easily over- or underflow, and BETA(j) may even be zero.
  13173. * Thus, the user should avoid naively computing the ratio
  13174. * ALPHA/BETA. However, ALPHAR and ALPHAI will be always less
  13175. * than and usually comparable with norm(A) in magnitude, and
  13176. * BETA always less than and usually comparable with norm(B).
  13177. *
  13178. * VL (output) DOUBLE PRECISION array, dimension (LDVL,N)
  13179. * If JOBVL = 'V', the left eigenvectors u(j) are stored one
  13180. * after another in the columns of VL, in the same order as
  13181. * their eigenvalues. If the j-th eigenvalue is real, then
  13182. * u(j) = VL(:,j), the j-th column of VL. If the j-th and
  13183. * (j+1)-th eigenvalues form a complex conjugate pair, then
  13184. * u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).
  13185. * Each eigenvector will be scaled so the largest component have
  13186. * abs(real part) + abs(imag. part) = 1.
  13187. * Not referenced if JOBVL = 'N'.
  13188. *
  13189. * LDVL (input) INTEGER
  13190. * The leading dimension of the matrix VL. LDVL >= 1, and
  13191. * if JOBVL = 'V', LDVL >= N.
  13192. *
  13193. * VR (output) DOUBLE PRECISION array, dimension (LDVR,N)
  13194. * If JOBVR = 'V', the right eigenvectors v(j) are stored one
  13195. * after another in the columns of VR, in the same order as
  13196. * their eigenvalues. If the j-th eigenvalue is real, then
  13197. * v(j) = VR(:,j), the j-th column of VR. If the j-th and
  13198. * (j+1)-th eigenvalues form a complex conjugate pair, then
  13199. * v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).
  13200. * Each eigenvector will be scaled so the largest component have
  13201. * abs(real part) + abs(imag. part) = 1.
  13202. * Not referenced if JOBVR = 'N'.
  13203. *
  13204. * LDVR (input) INTEGER
  13205. * The leading dimension of the matrix VR. LDVR >= 1, and
  13206. * if JOBVR = 'V', LDVR >= N.
  13207. *
  13208. * ILO (output) INTEGER
  13209. * IHI (output) INTEGER
  13210. * ILO and IHI are integer values such that on exit
  13211. * A(i,j) = 0 and B(i,j) = 0 if i > j and
  13212. * j = 1,...,ILO-1 or i = IHI+1,...,N.
  13213. * If BALANC = 'N' or 'S', ILO = 1 and IHI = N.
  13214. *
  13215. * LSCALE (output) DOUBLE PRECISION array, dimension (N)
  13216. * Details of the permutations and scaling factors applied
  13217. * to the left side of A and B. If PL(j) is the index of the
  13218. * row interchanged with row j, and DL(j) is the scaling
  13219. * factor applied to row j, then
  13220. * LSCALE(j) = PL(j) for j = 1,...,ILO-1
  13221. * = DL(j) for j = ILO,...,IHI
  13222. * = PL(j) for j = IHI+1,...,N.
  13223. * The order in which the interchanges are made is N to IHI+1,
  13224. * then 1 to ILO-1.
  13225. *
  13226. * RSCALE (output) DOUBLE PRECISION array, dimension (N)
  13227. * Details of the permutations and scaling factors applied
  13228. * to the right side of A and B. If PR(j) is the index of the
  13229. * column interchanged with column j, and DR(j) is the scaling
  13230. * factor applied to column j, then
  13231. * RSCALE(j) = PR(j) for j = 1,...,ILO-1
  13232. * = DR(j) for j = ILO,...,IHI
  13233. * = PR(j) for j = IHI+1,...,N
  13234. * The order in which the interchanges are made is N to IHI+1,
  13235. * then 1 to ILO-1.
  13236. *
  13237. * ABNRM (output) DOUBLE PRECISION
  13238. * The one-norm of the balanced matrix A.
  13239. *
  13240. * BBNRM (output) DOUBLE PRECISION
  13241. * The one-norm of the balanced matrix B.
  13242. *
  13243. * RCONDE (output) DOUBLE PRECISION array, dimension (N)
  13244. * If SENSE = 'E' or 'B', the reciprocal condition numbers of
  13245. * the eigenvalues, stored in consecutive elements of the array.
  13246. * For a complex conjugate pair of eigenvalues two consecutive
  13247. * elements of RCONDE are set to the same value. Thus RCONDE(j),
  13248. * RCONDV(j), and the j-th columns of VL and VR all correspond
  13249. * to the j-th eigenpair.
  13250. * If SENSE = 'N or 'V', RCONDE is not referenced.
  13251. *
  13252. * RCONDV (output) DOUBLE PRECISION array, dimension (N)
  13253. * If SENSE = 'V' or 'B', the estimated reciprocal condition
  13254. * numbers of the eigenvectors, stored in consecutive elements
  13255. * of the array. For a complex eigenvector two consecutive
  13256. * elements of RCONDV are set to the same value. If the
  13257. * eigenvalues cannot be reordered to compute RCONDV(j),
  13258. * RCONDV(j) is set to 0; this can only occur when the true
  13259. * value would be very small anyway.
  13260. * If SENSE = 'N' or 'E', RCONDV is not referenced.
  13261. *
  13262. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  13263. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  13264. *
  13265. * LWORK (input) INTEGER
  13266. * The dimension of the array WORK. LWORK >= max(1,2*N).
  13267. * If BALANC = 'S' or 'B', or JOBVL = 'V', or JOBVR = 'V',
  13268. * LWORK >= max(1,6*N).
  13269. * If SENSE = 'E' or 'B', LWORK >= max(1,10*N).
  13270. * If SENSE = 'V' or 'B', LWORK >= 2*N*N+8*N+16.
  13271. *
  13272. * If LWORK = -1, then a workspace query is assumed; the routine
  13273. * only calculates the optimal size of the WORK array, returns
  13274. * this value as the first entry of the WORK array, and no error
  13275. * message related to LWORK is issued by XERBLA.
  13276. *
  13277. * IWORK (workspace) INTEGER array, dimension (N+6)
  13278. * If SENSE = 'E', IWORK is not referenced.
  13279. *
  13280. * BWORK (workspace) LOGICAL array, dimension (N)
  13281. * If SENSE = 'N', BWORK is not referenced.
  13282. *
  13283. * INFO (output) INTEGER
  13284. * = 0: successful exit
  13285. * < 0: if INFO = -i, the i-th argument had an illegal value.
  13286. * = 1,...,N:
  13287. * The QZ iteration failed. No eigenvectors have been
  13288. * calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
  13289. * should be correct for j=INFO+1,...,N.
  13290. * > N: =N+1: other than QZ iteration failed in DHGEQZ.
  13291. * =N+2: error return from DTGEVC.
  13292. *
  13293. * Further Details
  13294. * ===============
  13295. *
  13296. * Balancing a matrix pair (A,B) includes, first, permuting rows and
  13297. * columns to isolate eigenvalues, second, applying diagonal similarity
  13298. * transformation to the rows and columns to make the rows and columns
  13299. * as close in norm as possible. The computed reciprocal condition
  13300. * numbers correspond to the balanced matrix. Permuting rows and columns
  13301. * will not change the condition numbers (in exact arithmetic) but
  13302. * diagonal scaling will. For further explanation of balancing, see
  13303. * section 4.11.1.2 of LAPACK Users' Guide.
  13304. *
  13305. * An approximate error bound on the chordal distance between the i-th
  13306. * computed generalized eigenvalue w and the corresponding exact
  13307. * eigenvalue lambda is
  13308. *
  13309. * chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)
  13310. *
  13311. * An approximate error bound for the angle between the i-th computed
  13312. * eigenvector VL(i) or VR(i) is given by
  13313. *
  13314. * EPS * norm(ABNRM, BBNRM) / DIF(i).
  13315. *
  13316. * For further explanation of the reciprocal condition numbers RCONDE
  13317. * and RCONDV, see section 4.11 of LAPACK User's Guide.
  13318. *
  13319. * =====================================================================
  13320. *
  13321. * .. Parameters ..
  13322. DOUBLE PRECISION ZERO, ONE
  13323. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  13324. * ..
  13325. * .. Local Scalars ..
  13326. LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL,
  13327. $ PAIR, WANTSB, WANTSE, WANTSN, WANTSV
  13328. CHARACTER CHTEMP
  13329. INTEGER I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS,
  13330. $ ITAU, IWRK, IWRK1, J, JC, JR, M, MAXWRK,
  13331. $ MINWRK, MM
  13332. DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,
  13333. $ SMLNUM, TEMP
  13334. * ..
  13335. * .. Local Arrays ..
  13336. LOGICAL LDUMMA( 1 )
  13337. * ..
  13338. * .. External Subroutines ..
  13339. EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,
  13340. $ DLACPY, DLASCL, DLASET, DORGQR, DORMQR, DTGEVC,
  13341. $ DTGSNA, XERBLA
  13342. * ..
  13343. * .. External Functions ..
  13344. LOGICAL LSAME
  13345. INTEGER ILAENV
  13346. DOUBLE PRECISION DLAMCH, DLANGE
  13347. EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE
  13348. * ..
  13349. * .. Intrinsic Functions ..
  13350. INTRINSIC ABS, MAX, SQRT
  13351. * ..
  13352. * .. Executable Statements ..
  13353. *
  13354. * Decode the input arguments
  13355. *
  13356. IF( LSAME( JOBVL, 'N' ) ) THEN
  13357. IJOBVL = 1
  13358. ILVL = .FALSE.
  13359. ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
  13360. IJOBVL = 2
  13361. ILVL = .TRUE.
  13362. ELSE
  13363. IJOBVL = -1
  13364. ILVL = .FALSE.
  13365. END IF
  13366. *
  13367. IF( LSAME( JOBVR, 'N' ) ) THEN
  13368. IJOBVR = 1
  13369. ILVR = .FALSE.
  13370. ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
  13371. IJOBVR = 2
  13372. ILVR = .TRUE.
  13373. ELSE
  13374. IJOBVR = -1
  13375. ILVR = .FALSE.
  13376. END IF
  13377. ILV = ILVL .OR. ILVR
  13378. *
  13379. NOSCL = LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 'P' )
  13380. WANTSN = LSAME( SENSE, 'N' )
  13381. WANTSE = LSAME( SENSE, 'E' )
  13382. WANTSV = LSAME( SENSE, 'V' )
  13383. WANTSB = LSAME( SENSE, 'B' )
  13384. *
  13385. * Test the input arguments
  13386. *
  13387. INFO = 0
  13388. LQUERY = ( LWORK.EQ.-1 )
  13389. IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC,
  13390. $ 'S' ) .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) )
  13391. $ THEN
  13392. INFO = -1
  13393. ELSE IF( IJOBVL.LE.0 ) THEN
  13394. INFO = -2
  13395. ELSE IF( IJOBVR.LE.0 ) THEN
  13396. INFO = -3
  13397. ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSB .OR. WANTSV ) )
  13398. $ THEN
  13399. INFO = -4
  13400. ELSE IF( N.LT.0 ) THEN
  13401. INFO = -5
  13402. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  13403. INFO = -7
  13404. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  13405. INFO = -9
  13406. ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
  13407. INFO = -14
  13408. ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
  13409. INFO = -16
  13410. END IF
  13411. *
  13412. * Compute workspace
  13413. * (Note: Comments in the code beginning "Workspace:" describe the
  13414. * minimal amount of workspace needed at that point in the code,
  13415. * as well as the preferred amount for good performance.
  13416. * NB refers to the optimal block size for the immediately
  13417. * following subroutine, as returned by ILAENV. The workspace is
  13418. * computed assuming ILO = 1 and IHI = N, the worst case.)
  13419. *
  13420. IF( INFO.EQ.0 ) THEN
  13421. IF( N.EQ.0 ) THEN
  13422. MINWRK = 1
  13423. MAXWRK = 1
  13424. ELSE
  13425. IF( NOSCL .AND. .NOT.ILV ) THEN
  13426. MINWRK = 2*N
  13427. ELSE
  13428. MINWRK = 6*N
  13429. END IF
  13430. IF( WANTSE .OR. WANTSB ) THEN
  13431. MINWRK = 10*N
  13432. END IF
  13433. IF( WANTSV .OR. WANTSB ) THEN
  13434. MINWRK = MAX( MINWRK, 2*N*( N + 4 ) + 16 )
  13435. END IF
  13436. MAXWRK = MINWRK
  13437. MAXWRK = MAX( MAXWRK,
  13438. $ N + N*ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 ) )
  13439. MAXWRK = MAX( MAXWRK,
  13440. $ N + N*ILAENV( 1, 'DORMQR', ' ', N, 1, N, 0 ) )
  13441. IF( ILVL ) THEN
  13442. MAXWRK = MAX( MAXWRK, N +
  13443. $ N*ILAENV( 1, 'DORGQR', ' ', N, 1, N, 0 ) )
  13444. END IF
  13445. END IF
  13446. WORK( 1 ) = MAXWRK
  13447. *
  13448. IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  13449. INFO = -26
  13450. END IF
  13451. END IF
  13452. *
  13453. IF( INFO.NE.0 ) THEN
  13454. CALL XERBLA( 'DGGEVX', -INFO )
  13455. RETURN
  13456. ELSE IF( LQUERY ) THEN
  13457. RETURN
  13458. END IF
  13459. *
  13460. * Quick return if possible
  13461. *
  13462. IF( N.EQ.0 )
  13463. $ RETURN
  13464. *
  13465. *
  13466. * Get machine constants
  13467. *
  13468. EPS = DLAMCH( 'P' )
  13469. SMLNUM = DLAMCH( 'S' )
  13470. BIGNUM = ONE / SMLNUM
  13471. CALL DLABAD( SMLNUM, BIGNUM )
  13472. SMLNUM = SQRT( SMLNUM ) / EPS
  13473. BIGNUM = ONE / SMLNUM
  13474. *
  13475. * Scale A if max element outside range [SMLNUM,BIGNUM]
  13476. *
  13477. ANRM = DLANGE( 'M', N, N, A, LDA, WORK )
  13478. ILASCL = .FALSE.
  13479. IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  13480. ANRMTO = SMLNUM
  13481. ILASCL = .TRUE.
  13482. ELSE IF( ANRM.GT.BIGNUM ) THEN
  13483. ANRMTO = BIGNUM
  13484. ILASCL = .TRUE.
  13485. END IF
  13486. IF( ILASCL )
  13487. $ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
  13488. *
  13489. * Scale B if max element outside range [SMLNUM,BIGNUM]
  13490. *
  13491. BNRM = DLANGE( 'M', N, N, B, LDB, WORK )
  13492. ILBSCL = .FALSE.
  13493. IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  13494. BNRMTO = SMLNUM
  13495. ILBSCL = .TRUE.
  13496. ELSE IF( BNRM.GT.BIGNUM ) THEN
  13497. BNRMTO = BIGNUM
  13498. ILBSCL = .TRUE.
  13499. END IF
  13500. IF( ILBSCL )
  13501. $ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
  13502. *
  13503. * Permute and/or balance the matrix pair (A,B)
  13504. * (Workspace: need 6*N if BALANC = 'S' or 'B', 1 otherwise)
  13505. *
  13506. CALL DGGBAL( BALANC, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE,
  13507. $ WORK, IERR )
  13508. *
  13509. * Compute ABNRM and BBNRM
  13510. *
  13511. ABNRM = DLANGE( '1', N, N, A, LDA, WORK( 1 ) )
  13512. IF( ILASCL ) THEN
  13513. WORK( 1 ) = ABNRM
  13514. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, 1, 1, WORK( 1 ), 1,
  13515. $ IERR )
  13516. ABNRM = WORK( 1 )
  13517. END IF
  13518. *
  13519. BBNRM = DLANGE( '1', N, N, B, LDB, WORK( 1 ) )
  13520. IF( ILBSCL ) THEN
  13521. WORK( 1 ) = BBNRM
  13522. CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, 1, 1, WORK( 1 ), 1,
  13523. $ IERR )
  13524. BBNRM = WORK( 1 )
  13525. END IF
  13526. *
  13527. * Reduce B to triangular form (QR decomposition of B)
  13528. * (Workspace: need N, prefer N*NB )
  13529. *
  13530. IROWS = IHI + 1 - ILO
  13531. IF( ILV .OR. .NOT.WANTSN ) THEN
  13532. ICOLS = N + 1 - ILO
  13533. ELSE
  13534. ICOLS = IROWS
  13535. END IF
  13536. ITAU = 1
  13537. IWRK = ITAU + IROWS
  13538. CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
  13539. $ WORK( IWRK ), LWORK+1-IWRK, IERR )
  13540. *
  13541. * Apply the orthogonal transformation to A
  13542. * (Workspace: need N, prefer N*NB)
  13543. *
  13544. CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
  13545. $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
  13546. $ LWORK+1-IWRK, IERR )
  13547. *
  13548. * Initialize VL and/or VR
  13549. * (Workspace: need N, prefer N*NB)
  13550. *
  13551. IF( ILVL ) THEN
  13552. CALL DLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )
  13553. IF( IROWS.GT.1 ) THEN
  13554. CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
  13555. $ VL( ILO+1, ILO ), LDVL )
  13556. END IF
  13557. CALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
  13558. $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
  13559. END IF
  13560. *
  13561. IF( ILVR )
  13562. $ CALL DLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )
  13563. *
  13564. * Reduce to generalized Hessenberg form
  13565. * (Workspace: none needed)
  13566. *
  13567. IF( ILV .OR. .NOT.WANTSN ) THEN
  13568. *
  13569. * Eigenvectors requested -- work on whole matrix.
  13570. *
  13571. CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
  13572. $ LDVL, VR, LDVR, IERR )
  13573. ELSE
  13574. CALL DGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
  13575. $ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )
  13576. END IF
  13577. *
  13578. * Perform QZ algorithm (Compute eigenvalues, and optionally, the
  13579. * Schur forms and Schur vectors)
  13580. * (Workspace: need N)
  13581. *
  13582. IF( ILV .OR. .NOT.WANTSN ) THEN
  13583. CHTEMP = 'S'
  13584. ELSE
  13585. CHTEMP = 'E'
  13586. END IF
  13587. *
  13588. CALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
  13589. $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK,
  13590. $ LWORK, IERR )
  13591. IF( IERR.NE.0 ) THEN
  13592. IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
  13593. INFO = IERR
  13594. ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
  13595. INFO = IERR - N
  13596. ELSE
  13597. INFO = N + 1
  13598. END IF
  13599. GO TO 130
  13600. END IF
  13601. *
  13602. * Compute Eigenvectors and estimate condition numbers if desired
  13603. * (Workspace: DTGEVC: need 6*N
  13604. * DTGSNA: need 2*N*(N+2)+16 if SENSE = 'V' or 'B',
  13605. * need N otherwise )
  13606. *
  13607. IF( ILV .OR. .NOT.WANTSN ) THEN
  13608. IF( ILV ) THEN
  13609. IF( ILVL ) THEN
  13610. IF( ILVR ) THEN
  13611. CHTEMP = 'B'
  13612. ELSE
  13613. CHTEMP = 'L'
  13614. END IF
  13615. ELSE
  13616. CHTEMP = 'R'
  13617. END IF
  13618. *
  13619. CALL DTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL,
  13620. $ LDVL, VR, LDVR, N, IN, WORK, IERR )
  13621. IF( IERR.NE.0 ) THEN
  13622. INFO = N + 2
  13623. GO TO 130
  13624. END IF
  13625. END IF
  13626. *
  13627. IF( .NOT.WANTSN ) THEN
  13628. *
  13629. * compute eigenvectors (DTGEVC) and estimate condition
  13630. * numbers (DTGSNA). Note that the definition of the condition
  13631. * number is not invariant under transformation (u,v) to
  13632. * (Q*u, Z*v), where (u,v) are eigenvectors of the generalized
  13633. * Schur form (S,T), Q and Z are orthogonal matrices. In order
  13634. * to avoid using extra 2*N*N workspace, we have to recalculate
  13635. * eigenvectors and estimate one condition numbers at a time.
  13636. *
  13637. PAIR = .FALSE.
  13638. DO 20 I = 1, N
  13639. *
  13640. IF( PAIR ) THEN
  13641. PAIR = .FALSE.
  13642. GO TO 20
  13643. END IF
  13644. MM = 1
  13645. IF( I.LT.N ) THEN
  13646. IF( A( I+1, I ).NE.ZERO ) THEN
  13647. PAIR = .TRUE.
  13648. MM = 2
  13649. END IF
  13650. END IF
  13651. *
  13652. DO 10 J = 1, N
  13653. BWORK( J ) = .FALSE.
  13654. 10 CONTINUE
  13655. IF( MM.EQ.1 ) THEN
  13656. BWORK( I ) = .TRUE.
  13657. ELSE IF( MM.EQ.2 ) THEN
  13658. BWORK( I ) = .TRUE.
  13659. BWORK( I+1 ) = .TRUE.
  13660. END IF
  13661. *
  13662. IWRK = MM*N + 1
  13663. IWRK1 = IWRK + MM*N
  13664. *
  13665. * Compute a pair of left and right eigenvectors.
  13666. * (compute workspace: need up to 4*N + 6*N)
  13667. *
  13668. IF( WANTSE .OR. WANTSB ) THEN
  13669. CALL DTGEVC( 'B', 'S', BWORK, N, A, LDA, B, LDB,
  13670. $ WORK( 1 ), N, WORK( IWRK ), N, MM, M,
  13671. $ WORK( IWRK1 ), IERR )
  13672. IF( IERR.NE.0 ) THEN
  13673. INFO = N + 2
  13674. GO TO 130
  13675. END IF
  13676. END IF
  13677. *
  13678. CALL DTGSNA( SENSE, 'S', BWORK, N, A, LDA, B, LDB,
  13679. $ WORK( 1 ), N, WORK( IWRK ), N, RCONDE( I ),
  13680. $ RCONDV( I ), MM, M, WORK( IWRK1 ),
  13681. $ LWORK-IWRK1+1, IWORK, IERR )
  13682. *
  13683. 20 CONTINUE
  13684. END IF
  13685. END IF
  13686. *
  13687. * Undo balancing on VL and VR and normalization
  13688. * (Workspace: none needed)
  13689. *
  13690. IF( ILVL ) THEN
  13691. CALL DGGBAK( BALANC, 'L', N, ILO, IHI, LSCALE, RSCALE, N, VL,
  13692. $ LDVL, IERR )
  13693. *
  13694. DO 70 JC = 1, N
  13695. IF( ALPHAI( JC ).LT.ZERO )
  13696. $ GO TO 70
  13697. TEMP = ZERO
  13698. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  13699. DO 30 JR = 1, N
  13700. TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )
  13701. 30 CONTINUE
  13702. ELSE
  13703. DO 40 JR = 1, N
  13704. TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+
  13705. $ ABS( VL( JR, JC+1 ) ) )
  13706. 40 CONTINUE
  13707. END IF
  13708. IF( TEMP.LT.SMLNUM )
  13709. $ GO TO 70
  13710. TEMP = ONE / TEMP
  13711. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  13712. DO 50 JR = 1, N
  13713. VL( JR, JC ) = VL( JR, JC )*TEMP
  13714. 50 CONTINUE
  13715. ELSE
  13716. DO 60 JR = 1, N
  13717. VL( JR, JC ) = VL( JR, JC )*TEMP
  13718. VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP
  13719. 60 CONTINUE
  13720. END IF
  13721. 70 CONTINUE
  13722. END IF
  13723. IF( ILVR ) THEN
  13724. CALL DGGBAK( BALANC, 'R', N, ILO, IHI, LSCALE, RSCALE, N, VR,
  13725. $ LDVR, IERR )
  13726. DO 120 JC = 1, N
  13727. IF( ALPHAI( JC ).LT.ZERO )
  13728. $ GO TO 120