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

# · FORTRAN Legacy · 24549 lines · 9305 code · 8 blank · 15236 comment · 0 complexity · 2debfe568d485e45100b760897a8738e MD5 · raw file

  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
  13729. TEMP = ZERO
  13730. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  13731. DO 80 JR = 1, N
  13732. TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )
  13733. 80 CONTINUE
  13734. ELSE
  13735. DO 90 JR = 1, N
  13736. TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+
  13737. $ ABS( VR( JR, JC+1 ) ) )
  13738. 90 CONTINUE
  13739. END IF
  13740. IF( TEMP.LT.SMLNUM )
  13741. $ GO TO 120
  13742. TEMP = ONE / TEMP
  13743. IF( ALPHAI( JC ).EQ.ZERO ) THEN
  13744. DO 100 JR = 1, N
  13745. VR( JR, JC ) = VR( JR, JC )*TEMP
  13746. 100 CONTINUE
  13747. ELSE
  13748. DO 110 JR = 1, N
  13749. VR( JR, JC ) = VR( JR, JC )*TEMP
  13750. VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP
  13751. 110 CONTINUE
  13752. END IF
  13753. 120 CONTINUE
  13754. END IF
  13755. *
  13756. * Undo scaling if necessary
  13757. *
  13758. IF( ILASCL ) THEN
  13759. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )
  13760. CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )
  13761. END IF
  13762. *
  13763. IF( ILBSCL ) THEN
  13764. CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
  13765. END IF
  13766. *
  13767. 130 CONTINUE
  13768. WORK( 1 ) = MAXWRK
  13769. *
  13770. RETURN
  13771. *
  13772. * End of DGGEVX
  13773. *
  13774. END
  13775. SUBROUTINE DGGGLM( N, M, P, A, LDA, B, LDB, D, X, Y, WORK, LWORK,
  13776. $ INFO )
  13777. *
  13778. * -- LAPACK driver routine (version 3.1) --
  13779. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  13780. * November 2006
  13781. *
  13782. * .. Scalar Arguments ..
  13783. INTEGER INFO, LDA, LDB, LWORK, M, N, P
  13784. * ..
  13785. * .. Array Arguments ..
  13786. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), D( * ), WORK( * ),
  13787. $ X( * ), Y( * )
  13788. * ..
  13789. *
  13790. * Purpose
  13791. * =======
  13792. *
  13793. * DGGGLM solves a general Gauss-Markov linear model (GLM) problem:
  13794. *
  13795. * minimize || y ||_2 subject to d = A*x + B*y
  13796. * x
  13797. *
  13798. * where A is an N-by-M matrix, B is an N-by-P matrix, and d is a
  13799. * given N-vector. It is assumed that M <= N <= M+P, and
  13800. *
  13801. * rank(A) = M and rank( A B ) = N.
  13802. *
  13803. * Under these assumptions, the constrained equation is always
  13804. * consistent, and there is a unique solution x and a minimal 2-norm
  13805. * solution y, which is obtained using a generalized QR factorization
  13806. * of the matrices (A, B) given by
  13807. *
  13808. * A = Q*(R), B = Q*T*Z.
  13809. * (0)
  13810. *
  13811. * In particular, if matrix B is square nonsingular, then the problem
  13812. * GLM is equivalent to the following weighted linear least squares
  13813. * problem
  13814. *
  13815. * minimize || inv(B)*(d-A*x) ||_2
  13816. * x
  13817. *
  13818. * where inv(B) denotes the inverse of B.
  13819. *
  13820. * Arguments
  13821. * =========
  13822. *
  13823. * N (input) INTEGER
  13824. * The number of rows of the matrices A and B. N >= 0.
  13825. *
  13826. * M (input) INTEGER
  13827. * The number of columns of the matrix A. 0 <= M <= N.
  13828. *
  13829. * P (input) INTEGER
  13830. * The number of columns of the matrix B. P >= N-M.
  13831. *
  13832. * A (input/output) DOUBLE PRECISION array, dimension (LDA,M)
  13833. * On entry, the N-by-M matrix A.
  13834. * On exit, the upper triangular part of the array A contains
  13835. * the M-by-M upper triangular matrix R.
  13836. *
  13837. * LDA (input) INTEGER
  13838. * The leading dimension of the array A. LDA >= max(1,N).
  13839. *
  13840. * B (input/output) DOUBLE PRECISION array, dimension (LDB,P)
  13841. * On entry, the N-by-P matrix B.
  13842. * On exit, if N <= P, the upper triangle of the subarray
  13843. * B(1:N,P-N+1:P) contains the N-by-N upper triangular matrix T;
  13844. * if N > P, the elements on and above the (N-P)th subdiagonal
  13845. * contain the N-by-P upper trapezoidal matrix T.
  13846. *
  13847. * LDB (input) INTEGER
  13848. * The leading dimension of the array B. LDB >= max(1,N).
  13849. *
  13850. * D (input/output) DOUBLE PRECISION array, dimension (N)
  13851. * On entry, D is the left hand side of the GLM equation.
  13852. * On exit, D is destroyed.
  13853. *
  13854. * X (output) DOUBLE PRECISION array, dimension (M)
  13855. * Y (output) DOUBLE PRECISION array, dimension (P)
  13856. * On exit, X and Y are the solutions of the GLM problem.
  13857. *
  13858. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  13859. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  13860. *
  13861. * LWORK (input) INTEGER
  13862. * The dimension of the array WORK. LWORK >= max(1,N+M+P).
  13863. * For optimum performance, LWORK >= M+min(N,P)+max(N,P)*NB,
  13864. * where NB is an upper bound for the optimal blocksizes for
  13865. * DGEQRF, SGERQF, DORMQR and SORMRQ.
  13866. *
  13867. * If LWORK = -1, then a workspace query is assumed; the routine
  13868. * only calculates the optimal size of the WORK array, returns
  13869. * this value as the first entry of the WORK array, and no error
  13870. * message related to LWORK is issued by XERBLA.
  13871. *
  13872. * INFO (output) INTEGER
  13873. * = 0: successful exit.
  13874. * < 0: if INFO = -i, the i-th argument had an illegal value.
  13875. * = 1: the upper triangular factor R associated with A in the
  13876. * generalized QR factorization of the pair (A, B) is
  13877. * singular, so that rank(A) < M; the least squares
  13878. * solution could not be computed.
  13879. * = 2: the bottom (N-M) by (N-M) part of the upper trapezoidal
  13880. * factor T associated with B in the generalized QR
  13881. * factorization of the pair (A, B) is singular, so that
  13882. * rank( A B ) < N; the least squares solution could not
  13883. * be computed.
  13884. *
  13885. * ===================================================================
  13886. *
  13887. * .. Parameters ..
  13888. DOUBLE PRECISION ZERO, ONE
  13889. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  13890. * ..
  13891. * .. Local Scalars ..
  13892. LOGICAL LQUERY
  13893. INTEGER I, LOPT, LWKMIN, LWKOPT, NB, NB1, NB2, NB3,
  13894. $ NB4, NP
  13895. * ..
  13896. * .. External Subroutines ..
  13897. EXTERNAL DCOPY, DGEMV, DGGQRF, DORMQR, DORMRQ, DTRTRS,
  13898. $ XERBLA
  13899. * ..
  13900. * .. External Functions ..
  13901. INTEGER ILAENV
  13902. EXTERNAL ILAENV
  13903. * ..
  13904. * .. Intrinsic Functions ..
  13905. INTRINSIC INT, MAX, MIN
  13906. * ..
  13907. * .. Executable Statements ..
  13908. *
  13909. * Test the input parameters
  13910. *
  13911. INFO = 0
  13912. NP = MIN( N, P )
  13913. LQUERY = ( LWORK.EQ.-1 )
  13914. IF( N.LT.0 ) THEN
  13915. INFO = -1
  13916. ELSE IF( M.LT.0 .OR. M.GT.N ) THEN
  13917. INFO = -2
  13918. ELSE IF( P.LT.0 .OR. P.LT.N-M ) THEN
  13919. INFO = -3
  13920. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  13921. INFO = -5
  13922. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  13923. INFO = -7
  13924. END IF
  13925. *
  13926. * Calculate workspace
  13927. *
  13928. IF( INFO.EQ.0) THEN
  13929. IF( N.EQ.0 ) THEN
  13930. LWKMIN = 1
  13931. LWKOPT = 1
  13932. ELSE
  13933. NB1 = ILAENV( 1, 'DGEQRF', ' ', N, M, -1, -1 )
  13934. NB2 = ILAENV( 1, 'DGERQF', ' ', N, M, -1, -1 )
  13935. NB3 = ILAENV( 1, 'DORMQR', ' ', N, M, P, -1 )
  13936. NB4 = ILAENV( 1, 'DORMRQ', ' ', N, M, P, -1 )
  13937. NB = MAX( NB1, NB2, NB3, NB4 )
  13938. LWKMIN = M + N + P
  13939. LWKOPT = M + NP + MAX( N, P )*NB
  13940. END IF
  13941. WORK( 1 ) = LWKOPT
  13942. *
  13943. IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
  13944. INFO = -12
  13945. END IF
  13946. END IF
  13947. *
  13948. IF( INFO.NE.0 ) THEN
  13949. CALL XERBLA( 'DGGGLM', -INFO )
  13950. RETURN
  13951. ELSE IF( LQUERY ) THEN
  13952. RETURN
  13953. END IF
  13954. *
  13955. * Quick return if possible
  13956. *
  13957. IF( N.EQ.0 )
  13958. $ RETURN
  13959. *
  13960. * Compute the GQR factorization of matrices A and B:
  13961. *
  13962. * Q'*A = ( R11 ) M, Q'*B*Z' = ( T11 T12 ) M
  13963. * ( 0 ) N-M ( 0 T22 ) N-M
  13964. * M M+P-N N-M
  13965. *
  13966. * where R11 and T22 are upper triangular, and Q and Z are
  13967. * orthogonal.
  13968. *
  13969. CALL DGGQRF( N, M, P, A, LDA, WORK, B, LDB, WORK( M+1 ),
  13970. $ WORK( M+NP+1 ), LWORK-M-NP, INFO )
  13971. LOPT = WORK( M+NP+1 )
  13972. *
  13973. * Update left-hand-side vector d = Q'*d = ( d1 ) M
  13974. * ( d2 ) N-M
  13975. *
  13976. CALL DORMQR( 'Left', 'Transpose', N, 1, M, A, LDA, WORK, D,
  13977. $ MAX( 1, N ), WORK( M+NP+1 ), LWORK-M-NP, INFO )
  13978. LOPT = MAX( LOPT, INT( WORK( M+NP+1 ) ) )
  13979. *
  13980. * Solve T22*y2 = d2 for y2
  13981. *
  13982. IF( N.GT.M ) THEN
  13983. CALL DTRTRS( 'Upper', 'No transpose', 'Non unit', N-M, 1,
  13984. $ B( M+1, M+P-N+1 ), LDB, D( M+1 ), N-M, INFO )
  13985. *
  13986. IF( INFO.GT.0 ) THEN
  13987. INFO = 1
  13988. RETURN
  13989. END IF
  13990. *
  13991. CALL DCOPY( N-M, D( M+1 ), 1, Y( M+P-N+1 ), 1 )
  13992. END IF
  13993. *
  13994. * Set y1 = 0
  13995. *
  13996. DO 10 I = 1, M + P - N
  13997. Y( I ) = ZERO
  13998. 10 CONTINUE
  13999. *
  14000. * Update d1 = d1 - T12*y2
  14001. *
  14002. CALL DGEMV( 'No transpose', M, N-M, -ONE, B( 1, M+P-N+1 ), LDB,
  14003. $ Y( M+P-N+1 ), 1, ONE, D, 1 )
  14004. *
  14005. * Solve triangular system: R11*x = d1
  14006. *
  14007. IF( M.GT.0 ) THEN
  14008. CALL DTRTRS( 'Upper', 'No Transpose', 'Non unit', M, 1, A, LDA,
  14009. $ D, M, INFO )
  14010. *
  14011. IF( INFO.GT.0 ) THEN
  14012. INFO = 2
  14013. RETURN
  14014. END IF
  14015. *
  14016. * Copy D to X
  14017. *
  14018. CALL DCOPY( M, D, 1, X, 1 )
  14019. END IF
  14020. *
  14021. * Backward transformation y = Z'*y
  14022. *
  14023. CALL DORMRQ( 'Left', 'Transpose', P, 1, NP,
  14024. $ B( MAX( 1, N-P+1 ), 1 ), LDB, WORK( M+1 ), Y,
  14025. $ MAX( 1, P ), WORK( M+NP+1 ), LWORK-M-NP, INFO )
  14026. WORK( 1 ) = M + NP + MAX( LOPT, INT( WORK( M+NP+1 ) ) )
  14027. *
  14028. RETURN
  14029. *
  14030. * End of DGGGLM
  14031. *
  14032. END
  14033. SUBROUTINE DGGLSE( M, N, P, A, LDA, B, LDB, C, D, X, WORK, LWORK,
  14034. $ INFO )
  14035. *
  14036. * -- LAPACK driver routine (version 3.1) --
  14037. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  14038. * November 2006
  14039. *
  14040. * .. Scalar Arguments ..
  14041. INTEGER INFO, LDA, LDB, LWORK, M, N, P
  14042. * ..
  14043. * .. Array Arguments ..
  14044. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( * ), D( * ),
  14045. $ WORK( * ), X( * )
  14046. * ..
  14047. *
  14048. * Purpose
  14049. * =======
  14050. *
  14051. * DGGLSE solves the linear equality-constrained least squares (LSE)
  14052. * problem:
  14053. *
  14054. * minimize || c - A*x ||_2 subject to B*x = d
  14055. *
  14056. * where A is an M-by-N matrix, B is a P-by-N matrix, c is a given
  14057. * M-vector, and d is a given P-vector. It is assumed that
  14058. * P <= N <= M+P, and
  14059. *
  14060. * rank(B) = P and rank( (A) ) = N.
  14061. * ( (B) )
  14062. *
  14063. * These conditions ensure that the LSE problem has a unique solution,
  14064. * which is obtained using a generalized RQ factorization of the
  14065. * matrices (B, A) given by
  14066. *
  14067. * B = (0 R)*Q, A = Z*T*Q.
  14068. *
  14069. * Arguments
  14070. * =========
  14071. *
  14072. * M (input) INTEGER
  14073. * The number of rows of the matrix A. M >= 0.
  14074. *
  14075. * N (input) INTEGER
  14076. * The number of columns of the matrices A and B. N >= 0.
  14077. *
  14078. * P (input) INTEGER
  14079. * The number of rows of the matrix B. 0 <= P <= N <= M+P.
  14080. *
  14081. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  14082. * On entry, the M-by-N matrix A.
  14083. * On exit, the elements on and above the diagonal of the array
  14084. * contain the min(M,N)-by-N upper trapezoidal matrix T.
  14085. *
  14086. * LDA (input) INTEGER
  14087. * The leading dimension of the array A. LDA >= max(1,M).
  14088. *
  14089. * B (input/output) DOUBLE PRECISION array, dimension (LDB,N)
  14090. * On entry, the P-by-N matrix B.
  14091. * On exit, the upper triangle of the subarray B(1:P,N-P+1:N)
  14092. * contains the P-by-P upper triangular matrix R.
  14093. *
  14094. * LDB (input) INTEGER
  14095. * The leading dimension of the array B. LDB >= max(1,P).
  14096. *
  14097. * C (input/output) DOUBLE PRECISION array, dimension (M)
  14098. * On entry, C contains the right hand side vector for the
  14099. * least squares part of the LSE problem.
  14100. * On exit, the residual sum of squares for the solution
  14101. * is given by the sum of squares of elements N-P+1 to M of
  14102. * vector C.
  14103. *
  14104. * D (input/output) DOUBLE PRECISION array, dimension (P)
  14105. * On entry, D contains the right hand side vector for the
  14106. * constrained equation.
  14107. * On exit, D is destroyed.
  14108. *
  14109. * X (output) DOUBLE PRECISION array, dimension (N)
  14110. * On exit, X is the solution of the LSE problem.
  14111. *
  14112. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  14113. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  14114. *
  14115. * LWORK (input) INTEGER
  14116. * The dimension of the array WORK. LWORK >= max(1,M+N+P).
  14117. * For optimum performance LWORK >= P+min(M,N)+max(M,N)*NB,
  14118. * where NB is an upper bound for the optimal blocksizes for
  14119. * DGEQRF, SGERQF, DORMQR and SORMRQ.
  14120. *
  14121. * If LWORK = -1, then a workspace query is assumed; the routine
  14122. * only calculates the optimal size of the WORK array, returns
  14123. * this value as the first entry of the WORK array, and no error
  14124. * message related to LWORK is issued by XERBLA.
  14125. *
  14126. * INFO (output) INTEGER
  14127. * = 0: successful exit.
  14128. * < 0: if INFO = -i, the i-th argument had an illegal value.
  14129. * = 1: the upper triangular factor R associated with B in the
  14130. * generalized RQ factorization of the pair (B, A) is
  14131. * singular, so that rank(B) < P; the least squares
  14132. * solution could not be computed.
  14133. * = 2: the (N-P) by (N-P) part of the upper trapezoidal factor
  14134. * T associated with A in the generalized RQ factorization
  14135. * of the pair (B, A) is singular, so that
  14136. * rank( (A) ) < N; the least squares solution could not
  14137. * ( (B) )
  14138. * be computed.
  14139. *
  14140. * =====================================================================
  14141. *
  14142. * .. Parameters ..
  14143. DOUBLE PRECISION ONE
  14144. PARAMETER ( ONE = 1.0D+0 )
  14145. * ..
  14146. * .. Local Scalars ..
  14147. LOGICAL LQUERY
  14148. INTEGER LOPT, LWKMIN, LWKOPT, MN, NB, NB1, NB2, NB3,
  14149. $ NB4, NR
  14150. * ..
  14151. * .. External Subroutines ..
  14152. EXTERNAL DAXPY, DCOPY, DGEMV, DGGRQF, DORMQR, DORMRQ,
  14153. $ DTRMV, DTRTRS, XERBLA
  14154. * ..
  14155. * .. External Functions ..
  14156. INTEGER ILAENV
  14157. EXTERNAL ILAENV
  14158. * ..
  14159. * .. Intrinsic Functions ..
  14160. INTRINSIC INT, MAX, MIN
  14161. * ..
  14162. * .. Executable Statements ..
  14163. *
  14164. * Test the input parameters
  14165. *
  14166. INFO = 0
  14167. MN = MIN( M, N )
  14168. LQUERY = ( LWORK.EQ.-1 )
  14169. IF( M.LT.0 ) THEN
  14170. INFO = -1
  14171. ELSE IF( N.LT.0 ) THEN
  14172. INFO = -2
  14173. ELSE IF( P.LT.0 .OR. P.GT.N .OR. P.LT.N-M ) THEN
  14174. INFO = -3
  14175. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  14176. INFO = -5
  14177. ELSE IF( LDB.LT.MAX( 1, P ) ) THEN
  14178. INFO = -7
  14179. END IF
  14180. *
  14181. * Calculate workspace
  14182. *
  14183. IF( INFO.EQ.0) THEN
  14184. IF( N.EQ.0 ) THEN
  14185. LWKMIN = 1
  14186. LWKOPT = 1
  14187. ELSE
  14188. NB1 = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
  14189. NB2 = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )
  14190. NB3 = ILAENV( 1, 'DORMQR', ' ', M, N, P, -1 )
  14191. NB4 = ILAENV( 1, 'DORMRQ', ' ', M, N, P, -1 )
  14192. NB = MAX( NB1, NB2, NB3, NB4 )
  14193. LWKMIN = M + N + P
  14194. LWKOPT = P + MN + MAX( M, N )*NB
  14195. END IF
  14196. WORK( 1 ) = LWKOPT
  14197. *
  14198. IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
  14199. INFO = -12
  14200. END IF
  14201. END IF
  14202. *
  14203. IF( INFO.NE.0 ) THEN
  14204. CALL XERBLA( 'DGGLSE', -INFO )
  14205. RETURN
  14206. ELSE IF( LQUERY ) THEN
  14207. RETURN
  14208. END IF
  14209. *
  14210. * Quick return if possible
  14211. *
  14212. IF( N.EQ.0 )
  14213. $ RETURN
  14214. *
  14215. * Compute the GRQ factorization of matrices B and A:
  14216. *
  14217. * B*Q' = ( 0 T12 ) P Z'*A*Q' = ( R11 R12 ) N-P
  14218. * N-P P ( 0 R22 ) M+P-N
  14219. * N-P P
  14220. *
  14221. * where T12 and R11 are upper triangular, and Q and Z are
  14222. * orthogonal.
  14223. *
  14224. CALL DGGRQF( P, M, N, B, LDB, WORK, A, LDA, WORK( P+1 ),
  14225. $ WORK( P+MN+1 ), LWORK-P-MN, INFO )
  14226. LOPT = WORK( P+MN+1 )
  14227. *
  14228. * Update c = Z'*c = ( c1 ) N-P
  14229. * ( c2 ) M+P-N
  14230. *
  14231. CALL DORMQR( 'Left', 'Transpose', M, 1, MN, A, LDA, WORK( P+1 ),
  14232. $ C, MAX( 1, M ), WORK( P+MN+1 ), LWORK-P-MN, INFO )
  14233. LOPT = MAX( LOPT, INT( WORK( P+MN+1 ) ) )
  14234. *
  14235. * Solve T12*x2 = d for x2
  14236. *
  14237. IF( P.GT.0 ) THEN
  14238. CALL DTRTRS( 'Upper', 'No transpose', 'Non-unit', P, 1,
  14239. $ B( 1, N-P+1 ), LDB, D, P, INFO )
  14240. *
  14241. IF( INFO.GT.0 ) THEN
  14242. INFO = 1
  14243. RETURN
  14244. END IF
  14245. *
  14246. * Put the solution in X
  14247. *
  14248. CALL DCOPY( P, D, 1, X( N-P+1 ), 1 )
  14249. *
  14250. * Update c1
  14251. *
  14252. CALL DGEMV( 'No transpose', N-P, P, -ONE, A( 1, N-P+1 ), LDA,
  14253. $ D, 1, ONE, C, 1 )
  14254. END IF
  14255. *
  14256. * Solve R11*x1 = c1 for x1
  14257. *
  14258. IF( N.GT.P ) THEN
  14259. CALL DTRTRS( 'Upper', 'No transpose', 'Non-unit', N-P, 1,
  14260. $ A, LDA, C, N-P, INFO )
  14261. *
  14262. IF( INFO.GT.0 ) THEN
  14263. INFO = 2
  14264. RETURN
  14265. END IF
  14266. *
  14267. * Put the solutions in X
  14268. *
  14269. CALL DCOPY( N-P, C, 1, X, 1 )
  14270. END IF
  14271. *
  14272. * Compute the residual vector:
  14273. *
  14274. IF( M.LT.N ) THEN
  14275. NR = M + P - N
  14276. IF( NR.GT.0 )
  14277. $ CALL DGEMV( 'No transpose', NR, N-M, -ONE, A( N-P+1, M+1 ),
  14278. $ LDA, D( NR+1 ), 1, ONE, C( N-P+1 ), 1 )
  14279. ELSE
  14280. NR = P
  14281. END IF
  14282. IF( NR.GT.0 ) THEN
  14283. CALL DTRMV( 'Upper', 'No transpose', 'Non unit', NR,
  14284. $ A( N-P+1, N-P+1 ), LDA, D, 1 )
  14285. CALL DAXPY( NR, -ONE, D, 1, C( N-P+1 ), 1 )
  14286. END IF
  14287. *
  14288. * Backward transformation x = Q'*x
  14289. *
  14290. CALL DORMRQ( 'Left', 'Transpose', N, 1, P, B, LDB, WORK( 1 ), X,
  14291. $ N, WORK( P+MN+1 ), LWORK-P-MN, INFO )
  14292. WORK( 1 ) = P + MN + MAX( LOPT, INT( WORK( P+MN+1 ) ) )
  14293. *
  14294. RETURN
  14295. *
  14296. * End of DGGLSE
  14297. *
  14298. END
  14299. SUBROUTINE DGGSVD( JOBU, JOBV, JOBQ, M, N, P, K, L, A, LDA, B,
  14300. $ LDB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ, WORK,
  14301. $ IWORK, INFO )
  14302. *
  14303. * -- LAPACK driver routine (version 3.1) --
  14304. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  14305. * November 2006
  14306. *
  14307. * .. Scalar Arguments ..
  14308. CHARACTER JOBQ, JOBU, JOBV
  14309. INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P
  14310. * ..
  14311. * .. Array Arguments ..
  14312. INTEGER IWORK( * )
  14313. DOUBLE PRECISION A( LDA, * ), ALPHA( * ), B( LDB, * ),
  14314. $ BETA( * ), Q( LDQ, * ), U( LDU, * ),
  14315. $ V( LDV, * ), WORK( * )
  14316. * ..
  14317. *
  14318. * Purpose
  14319. * =======
  14320. *
  14321. * DGGSVD computes the generalized singular value decomposition (GSVD)
  14322. * of an M-by-N real matrix A and P-by-N real matrix B:
  14323. *
  14324. * U'*A*Q = D1*( 0 R ), V'*B*Q = D2*( 0 R )
  14325. *
  14326. * where U, V and Q are orthogonal matrices, and Z' is the transpose
  14327. * of Z. Let K+L = the effective numerical rank of the matrix (A',B')',
  14328. * then R is a K+L-by-K+L nonsingular upper triangular matrix, D1 and
  14329. * D2 are M-by-(K+L) and P-by-(K+L) "diagonal" matrices and of the
  14330. * following structures, respectively:
  14331. *
  14332. * If M-K-L >= 0,
  14333. *
  14334. * K L
  14335. * D1 = K ( I 0 )
  14336. * L ( 0 C )
  14337. * M-K-L ( 0 0 )
  14338. *
  14339. * K L
  14340. * D2 = L ( 0 S )
  14341. * P-L ( 0 0 )
  14342. *
  14343. * N-K-L K L
  14344. * ( 0 R ) = K ( 0 R11 R12 )
  14345. * L ( 0 0 R22 )
  14346. *
  14347. * where
  14348. *
  14349. * C = diag( ALPHA(K+1), ... , ALPHA(K+L) ),
  14350. * S = diag( BETA(K+1), ... , BETA(K+L) ),
  14351. * C**2 + S**2 = I.
  14352. *
  14353. * R is stored in A(1:K+L,N-K-L+1:N) on exit.
  14354. *
  14355. * If M-K-L < 0,
  14356. *
  14357. * K M-K K+L-M
  14358. * D1 = K ( I 0 0 )
  14359. * M-K ( 0 C 0 )
  14360. *
  14361. * K M-K K+L-M
  14362. * D2 = M-K ( 0 S 0 )
  14363. * K+L-M ( 0 0 I )
  14364. * P-L ( 0 0 0 )
  14365. *
  14366. * N-K-L K M-K K+L-M
  14367. * ( 0 R ) = K ( 0 R11 R12 R13 )
  14368. * M-K ( 0 0 R22 R23 )
  14369. * K+L-M ( 0 0 0 R33 )
  14370. *
  14371. * where
  14372. *
  14373. * C = diag( ALPHA(K+1), ... , ALPHA(M) ),
  14374. * S = diag( BETA(K+1), ... , BETA(M) ),
  14375. * C**2 + S**2 = I.
  14376. *
  14377. * (R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N), and R33 is stored
  14378. * ( 0 R22 R23 )
  14379. * in B(M-K+1:L,N+M-K-L+1:N) on exit.
  14380. *
  14381. * The routine computes C, S, R, and optionally the orthogonal
  14382. * transformation matrices U, V and Q.
  14383. *
  14384. * In particular, if B is an N-by-N nonsingular matrix, then the GSVD of
  14385. * A and B implicitly gives the SVD of A*inv(B):
  14386. * A*inv(B) = U*(D1*inv(D2))*V'.
  14387. * If ( A',B')' has orthonormal columns, then the GSVD of A and B is
  14388. * also equal to the CS decomposition of A and B. Furthermore, the GSVD
  14389. * can be used to derive the solution of the eigenvalue problem:
  14390. * A'*A x = lambda* B'*B x.
  14391. * In some literature, the GSVD of A and B is presented in the form
  14392. * U'*A*X = ( 0 D1 ), V'*B*X = ( 0 D2 )
  14393. * where U and V are orthogonal and X is nonsingular, D1 and D2 are
  14394. * ``diagonal''. The former GSVD form can be converted to the latter
  14395. * form by taking the nonsingular matrix X as
  14396. *
  14397. * X = Q*( I 0 )
  14398. * ( 0 inv(R) ).
  14399. *
  14400. * Arguments
  14401. * =========
  14402. *
  14403. * JOBU (input) CHARACTER*1
  14404. * = 'U': Orthogonal matrix U is computed;
  14405. * = 'N': U is not computed.
  14406. *
  14407. * JOBV (input) CHARACTER*1
  14408. * = 'V': Orthogonal matrix V is computed;
  14409. * = 'N': V is not computed.
  14410. *
  14411. * JOBQ (input) CHARACTER*1
  14412. * = 'Q': Orthogonal matrix Q is computed;
  14413. * = 'N': Q is not computed.
  14414. *
  14415. * M (input) INTEGER
  14416. * The number of rows of the matrix A. M >= 0.
  14417. *
  14418. * N (input) INTEGER
  14419. * The number of columns of the matrices A and B. N >= 0.
  14420. *
  14421. * P (input) INTEGER
  14422. * The number of rows of the matrix B. P >= 0.
  14423. *
  14424. * K (output) INTEGER
  14425. * L (output) INTEGER
  14426. * On exit, K and L specify the dimension of the subblocks
  14427. * described in the Purpose section.
  14428. * K + L = effective numerical rank of (A',B')'.
  14429. *
  14430. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  14431. * On entry, the M-by-N matrix A.
  14432. * On exit, A contains the triangular matrix R, or part of R.
  14433. * See Purpose for details.
  14434. *
  14435. * LDA (input) INTEGER
  14436. * The leading dimension of the array A. LDA >= max(1,M).
  14437. *
  14438. * B (input/output) DOUBLE PRECISION array, dimension (LDB,N)
  14439. * On entry, the P-by-N matrix B.
  14440. * On exit, B contains the triangular matrix R if M-K-L < 0.
  14441. * See Purpose for details.
  14442. *
  14443. * LDB (input) INTEGER
  14444. * The leading dimension of the array B. LDB >= max(1,P).
  14445. *
  14446. * ALPHA (output) DOUBLE PRECISION array, dimension (N)
  14447. * BETA (output) DOUBLE PRECISION array, dimension (N)
  14448. * On exit, ALPHA and BETA contain the generalized singular
  14449. * value pairs of A and B;
  14450. * ALPHA(1:K) = 1,
  14451. * BETA(1:K) = 0,
  14452. * and if M-K-L >= 0,
  14453. * ALPHA(K+1:K+L) = C,
  14454. * BETA(K+1:K+L) = S,
  14455. * or if M-K-L < 0,
  14456. * ALPHA(K+1:M)=C, ALPHA(M+1:K+L)=0
  14457. * BETA(K+1:M) =S, BETA(M+1:K+L) =1
  14458. * and
  14459. * ALPHA(K+L+1:N) = 0
  14460. * BETA(K+L+1:N) = 0
  14461. *
  14462. * U (output) DOUBLE PRECISION array, dimension (LDU,M)
  14463. * If JOBU = 'U', U contains the M-by-M orthogonal matrix U.
  14464. * If JOBU = 'N', U is not referenced.
  14465. *
  14466. * LDU (input) INTEGER
  14467. * The leading dimension of the array U. LDU >= max(1,M) if
  14468. * JOBU = 'U'; LDU >= 1 otherwise.
  14469. *
  14470. * V (output) DOUBLE PRECISION array, dimension (LDV,P)
  14471. * If JOBV = 'V', V contains the P-by-P orthogonal matrix V.
  14472. * If JOBV = 'N', V is not referenced.
  14473. *
  14474. * LDV (input) INTEGER
  14475. * The leading dimension of the array V. LDV >= max(1,P) if
  14476. * JOBV = 'V'; LDV >= 1 otherwise.
  14477. *
  14478. * Q (output) DOUBLE PRECISION array, dimension (LDQ,N)
  14479. * If JOBQ = 'Q', Q contains the N-by-N orthogonal matrix Q.
  14480. * If JOBQ = 'N', Q is not referenced.
  14481. *
  14482. * LDQ (input) INTEGER
  14483. * The leading dimension of the array Q. LDQ >= max(1,N) if
  14484. * JOBQ = 'Q'; LDQ >= 1 otherwise.
  14485. *
  14486. * WORK (workspace) DOUBLE PRECISION array,
  14487. * dimension (max(3*N,M,P)+N)
  14488. *
  14489. * IWORK (workspace/output) INTEGER array, dimension (N)
  14490. * On exit, IWORK stores the sorting information. More
  14491. * precisely, the following loop will sort ALPHA
  14492. * for I = K+1, min(M,K+L)
  14493. * swap ALPHA(I) and ALPHA(IWORK(I))
  14494. * endfor
  14495. * such that ALPHA(1) >= ALPHA(2) >= ... >= ALPHA(N).
  14496. *
  14497. * INFO (output) INTEGER
  14498. * = 0: successful exit
  14499. * < 0: if INFO = -i, the i-th argument had an illegal value.
  14500. * > 0: if INFO = 1, the Jacobi-type procedure failed to
  14501. * converge. For further details, see subroutine DTGSJA.
  14502. *
  14503. * Internal Parameters
  14504. * ===================
  14505. *
  14506. * TOLA DOUBLE PRECISION
  14507. * TOLB DOUBLE PRECISION
  14508. * TOLA and TOLB are the thresholds to determine the effective
  14509. * rank of (A',B')'. Generally, they are set to
  14510. * TOLA = MAX(M,N)*norm(A)*MAZHEPS,
  14511. * TOLB = MAX(P,N)*norm(B)*MAZHEPS.
  14512. * The size of TOLA and TOLB may affect the size of backward
  14513. * errors of the decomposition.
  14514. *
  14515. * Further Details
  14516. * ===============
  14517. *
  14518. * 2-96 Based on modifications by
  14519. * Ming Gu and Huan Ren, Computer Science Division, University of
  14520. * California at Berkeley, USA
  14521. *
  14522. * =====================================================================
  14523. *
  14524. * .. Local Scalars ..
  14525. LOGICAL WANTQ, WANTU, WANTV
  14526. INTEGER I, IBND, ISUB, J, NCYCLE
  14527. DOUBLE PRECISION ANORM, BNORM, SMAX, TEMP, TOLA, TOLB, ULP, UNFL
  14528. * ..
  14529. * .. External Functions ..
  14530. LOGICAL LSAME
  14531. DOUBLE PRECISION DLAMCH, DLANGE
  14532. EXTERNAL LSAME, DLAMCH, DLANGE
  14533. * ..
  14534. * .. External Subroutines ..
  14535. EXTERNAL DCOPY, DGGSVP, DTGSJA, XERBLA
  14536. * ..
  14537. * .. Intrinsic Functions ..
  14538. INTRINSIC MAX, MIN
  14539. * ..
  14540. * .. Executable Statements ..
  14541. *
  14542. * Test the input parameters
  14543. *
  14544. WANTU = LSAME( JOBU, 'U' )
  14545. WANTV = LSAME( JOBV, 'V' )
  14546. WANTQ = LSAME( JOBQ, 'Q' )
  14547. *
  14548. INFO = 0
  14549. IF( .NOT.( WANTU .OR. LSAME( JOBU, 'N' ) ) ) THEN
  14550. INFO = -1
  14551. ELSE IF( .NOT.( WANTV .OR. LSAME( JOBV, 'N' ) ) ) THEN
  14552. INFO = -2
  14553. ELSE IF( .NOT.( WANTQ .OR. LSAME( JOBQ, 'N' ) ) ) THEN
  14554. INFO = -3
  14555. ELSE IF( M.LT.0 ) THEN
  14556. INFO = -4
  14557. ELSE IF( N.LT.0 ) THEN
  14558. INFO = -5
  14559. ELSE IF( P.LT.0 ) THEN
  14560. INFO = -6
  14561. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  14562. INFO = -10
  14563. ELSE IF( LDB.LT.MAX( 1, P ) ) THEN
  14564. INFO = -12
  14565. ELSE IF( LDU.LT.1 .OR. ( WANTU .AND. LDU.LT.M ) ) THEN
  14566. INFO = -16
  14567. ELSE IF( LDV.LT.1 .OR. ( WANTV .AND. LDV.LT.P ) ) THEN
  14568. INFO = -18
  14569. ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THEN
  14570. INFO = -20
  14571. END IF
  14572. IF( INFO.NE.0 ) THEN
  14573. CALL XERBLA( 'DGGSVD', -INFO )
  14574. RETURN
  14575. END IF
  14576. *
  14577. * Compute the Frobenius norm of matrices A and B
  14578. *
  14579. ANORM = DLANGE( '1', M, N, A, LDA, WORK )
  14580. BNORM = DLANGE( '1', P, N, B, LDB, WORK )
  14581. *
  14582. * Get machine precision and set up threshold for determining
  14583. * the effective numerical rank of the matrices A and B.
  14584. *
  14585. ULP = DLAMCH( 'Precision' )
  14586. UNFL = DLAMCH( 'Safe Minimum' )
  14587. TOLA = MAX( M, N )*MAX( ANORM, UNFL )*ULP
  14588. TOLB = MAX( P, N )*MAX( BNORM, UNFL )*ULP
  14589. *
  14590. * Preprocessing
  14591. *
  14592. CALL DGGSVP( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB, TOLA,
  14593. $ TOLB, K, L, U, LDU, V, LDV, Q, LDQ, IWORK, WORK,
  14594. $ WORK( N+1 ), INFO )
  14595. *
  14596. * Compute the GSVD of two upper "triangular" matrices
  14597. *
  14598. CALL DTGSJA( JOBU, JOBV, JOBQ, M, P, N, K, L, A, LDA, B, LDB,
  14599. $ TOLA, TOLB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ,
  14600. $ WORK, NCYCLE, INFO )
  14601. *
  14602. * Sort the singular values and store the pivot indices in IWORK
  14603. * Copy ALPHA to WORK, then sort ALPHA in WORK
  14604. *
  14605. CALL DCOPY( N, ALPHA, 1, WORK, 1 )
  14606. IBND = MIN( L, M-K )
  14607. DO 20 I = 1, IBND
  14608. *
  14609. * Scan for largest ALPHA(K+I)
  14610. *
  14611. ISUB = I
  14612. SMAX = WORK( K+I )
  14613. DO 10 J = I + 1, IBND
  14614. TEMP = WORK( K+J )
  14615. IF( TEMP.GT.SMAX ) THEN
  14616. ISUB = J
  14617. SMAX = TEMP
  14618. END IF
  14619. 10 CONTINUE
  14620. IF( ISUB.NE.I ) THEN
  14621. WORK( K+ISUB ) = WORK( K+I )
  14622. WORK( K+I ) = SMAX
  14623. IWORK( K+I ) = K + ISUB
  14624. ELSE
  14625. IWORK( K+I ) = K + I
  14626. END IF
  14627. 20 CONTINUE
  14628. *
  14629. RETURN
  14630. *
  14631. * End of DGGSVD
  14632. *
  14633. END
  14634. SUBROUTINE DLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )
  14635. *
  14636. * -- LAPACK driver routine (version 3.1) --
  14637. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  14638. * November 2006
  14639. *
  14640. * .. Scalar Arguments ..
  14641. DOUBLE PRECISION A, B, C, CS, D, RT1I, RT1R, RT2I, RT2R, SN
  14642. * ..
  14643. *
  14644. * Purpose
  14645. * =======
  14646. *
  14647. * DLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric
  14648. * matrix in standard form:
  14649. *
  14650. * [ A B ] = [ CS -SN ] [ AA BB ] [ CS SN ]
  14651. * [ C D ] [ SN CS ] [ CC DD ] [-SN CS ]
  14652. *
  14653. * where either
  14654. * 1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or
  14655. * 2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex
  14656. * conjugate eigenvalues.
  14657. *
  14658. * Arguments
  14659. * =========
  14660. *
  14661. * A (input/output) DOUBLE PRECISION
  14662. * B (input/output) DOUBLE PRECISION
  14663. * C (input/output) DOUBLE PRECISION
  14664. * D (input/output) DOUBLE PRECISION
  14665. * On entry, the elements of the input matrix.
  14666. * On exit, they are overwritten by the elements of the
  14667. * standardised Schur form.
  14668. *
  14669. * RT1R (output) DOUBLE PRECISION
  14670. * RT1I (output) DOUBLE PRECISION
  14671. * RT2R (output) DOUBLE PRECISION
  14672. * RT2I (output) DOUBLE PRECISION
  14673. * The real and imaginary parts of the eigenvalues. If the
  14674. * eigenvalues are a complex conjugate pair, RT1I > 0.
  14675. *
  14676. * CS (output) DOUBLE PRECISION
  14677. * SN (output) DOUBLE PRECISION
  14678. * Parameters of the rotation matrix.
  14679. *
  14680. * Further Details
  14681. * ===============
  14682. *
  14683. * Modified by V. Sima, Research Institute for Informatics, Bucharest,
  14684. * Romania, to reduce the risk of cancellation errors,
  14685. * when computing real eigenvalues, and to ensure, if possible, that
  14686. * abs(RT1R) >= abs(RT2R).
  14687. *
  14688. * =====================================================================
  14689. *
  14690. * .. Parameters ..
  14691. DOUBLE PRECISION ZERO, HALF, ONE
  14692. PARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )
  14693. DOUBLE PRECISION MULTPL
  14694. PARAMETER ( MULTPL = 4.0D+0 )
  14695. * ..
  14696. * .. Local Scalars ..
  14697. DOUBLE PRECISION AA, BB, BCMAX, BCMIS, CC, CS1, DD, EPS, P, SAB,
  14698. $ SAC, SCALE, SIGMA, SN1, TAU, TEMP, Z
  14699. * ..
  14700. * .. External Functions ..
  14701. DOUBLE PRECISION DLAMCH, DLAPY2
  14702. EXTERNAL DLAMCH, DLAPY2
  14703. * ..
  14704. * .. Intrinsic Functions ..
  14705. INTRINSIC ABS, MAX, MIN, SIGN, SQRT
  14706. * ..
  14707. * .. Executable Statements ..
  14708. *
  14709. EPS = DLAMCH( 'P' )
  14710. IF( C.EQ.ZERO ) THEN
  14711. CS = ONE
  14712. SN = ZERO
  14713. GO TO 10
  14714. *
  14715. ELSE IF( B.EQ.ZERO ) THEN
  14716. *
  14717. * Swap rows and columns
  14718. *
  14719. CS = ZERO
  14720. SN = ONE
  14721. TEMP = D
  14722. D = A
  14723. A = TEMP
  14724. B = -C
  14725. C = ZERO
  14726. GO TO 10
  14727. ELSE IF( ( A-D ).EQ.ZERO .AND. SIGN( ONE, B ).NE.SIGN( ONE, C ) )
  14728. $ THEN
  14729. CS = ONE
  14730. SN = ZERO
  14731. GO TO 10
  14732. ELSE
  14733. *
  14734. TEMP = A - D
  14735. P = HALF*TEMP
  14736. BCMAX = MAX( ABS( B ), ABS( C ) )
  14737. BCMIS = MIN( ABS( B ), ABS( C ) )*SIGN( ONE, B )*SIGN( ONE, C )
  14738. SCALE = MAX( ABS( P ), BCMAX )
  14739. Z = ( P / SCALE )*P + ( BCMAX / SCALE )*BCMIS
  14740. *
  14741. * If Z is of the order of the machine accuracy, postpone the
  14742. * decision on the nature of eigenvalues
  14743. *
  14744. IF( Z.GE.MULTPL*EPS ) THEN
  14745. *
  14746. * Real eigenvalues. Compute A and D.
  14747. *
  14748. Z = P + SIGN( SQRT( SCALE )*SQRT( Z ), P )
  14749. A = D + Z
  14750. D = D - ( BCMAX / Z )*BCMIS
  14751. *
  14752. * Compute B and the rotation matrix
  14753. *
  14754. TAU = DLAPY2( C, Z )
  14755. CS = Z / TAU
  14756. SN = C / TAU
  14757. B = B - C
  14758. C = ZERO
  14759. ELSE
  14760. *
  14761. * Complex eigenvalues, or real (almost) equal eigenvalues.
  14762. * Make diagonal elements equal.
  14763. *
  14764. SIGMA = B + C
  14765. TAU = DLAPY2( SIGMA, TEMP )
  14766. CS = SQRT( HALF*( ONE+ABS( SIGMA ) / TAU ) )
  14767. SN = -( P / ( TAU*CS ) )*SIGN( ONE, SIGMA )
  14768. *
  14769. * Compute [ AA BB ] = [ A B ] [ CS -SN ]
  14770. * [ CC DD ] [ C D ] [ SN CS ]
  14771. *
  14772. AA = A*CS + B*SN
  14773. BB = -A*SN + B*CS
  14774. CC = C*CS + D*SN
  14775. DD = -C*SN + D*CS
  14776. *
  14777. * Compute [ A B ] = [ CS SN ] [ AA BB ]
  14778. * [ C D ] [-SN CS ] [ CC DD ]
  14779. *
  14780. A = AA*CS + CC*SN
  14781. B = BB*CS + DD*SN
  14782. C = -AA*SN + CC*CS
  14783. D = -BB*SN + DD*CS
  14784. *
  14785. TEMP = HALF*( A+D )
  14786. A = TEMP
  14787. D = TEMP
  14788. *
  14789. IF( C.NE.ZERO ) THEN
  14790. IF( B.NE.ZERO ) THEN
  14791. IF( SIGN( ONE, B ).EQ.SIGN( ONE, C ) ) THEN
  14792. *
  14793. * Real eigenvalues: reduce to upper triangular form
  14794. *
  14795. SAB = SQRT( ABS( B ) )
  14796. SAC = SQRT( ABS( C ) )
  14797. P = SIGN( SAB*SAC, C )
  14798. TAU = ONE / SQRT( ABS( B+C ) )
  14799. A = TEMP + P
  14800. D = TEMP - P
  14801. B = B - C
  14802. C = ZERO
  14803. CS1 = SAB*TAU
  14804. SN1 = SAC*TAU
  14805. TEMP = CS*CS1 - SN*SN1
  14806. SN = CS*SN1 + SN*CS1
  14807. CS = TEMP
  14808. END IF
  14809. ELSE
  14810. B = -C
  14811. C = ZERO
  14812. TEMP = CS
  14813. CS = -SN
  14814. SN = TEMP
  14815. END IF
  14816. END IF
  14817. END IF
  14818. *
  14819. END IF
  14820. *
  14821. 10 CONTINUE
  14822. *
  14823. * Store eigenvalues in (RT1R,RT1I) and (RT2R,RT2I).
  14824. *
  14825. RT1R = A
  14826. RT2R = D
  14827. IF( C.EQ.ZERO ) THEN
  14828. RT1I = ZERO
  14829. RT2I = ZERO
  14830. ELSE
  14831. RT1I = SQRT( ABS( B ) )*SQRT( ABS( C ) )
  14832. RT2I = -RT1I
  14833. END IF
  14834. RETURN
  14835. *
  14836. * End of DLANV2
  14837. *
  14838. END
  14839. SUBROUTINE DPBSV( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )
  14840. *
  14841. * -- LAPACK driver routine (version 3.1) --
  14842. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  14843. * November 2006
  14844. *
  14845. * .. Scalar Arguments ..
  14846. CHARACTER UPLO
  14847. INTEGER INFO, KD, LDAB, LDB, N, NRHS
  14848. * ..
  14849. * .. Array Arguments ..
  14850. DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )
  14851. * ..
  14852. *
  14853. * Purpose
  14854. * =======
  14855. *
  14856. * DPBSV computes the solution to a real system of linear equations
  14857. * A * X = B,
  14858. * where A is an N-by-N symmetric positive definite band matrix and X
  14859. * and B are N-by-NRHS matrices.
  14860. *
  14861. * The Cholesky decomposition is used to factor A as
  14862. * A = U**T * U, if UPLO = 'U', or
  14863. * A = L * L**T, if UPLO = 'L',
  14864. * where U is an upper triangular band matrix, and L is a lower
  14865. * triangular band matrix, with the same number of superdiagonals or
  14866. * subdiagonals as A. The factored form of A is then used to solve the
  14867. * system of equations A * X = B.
  14868. *
  14869. * Arguments
  14870. * =========
  14871. *
  14872. * UPLO (input) CHARACTER*1
  14873. * = 'U': Upper triangle of A is stored;
  14874. * = 'L': Lower triangle of A is stored.
  14875. *
  14876. * N (input) INTEGER
  14877. * The number of linear equations, i.e., the order of the
  14878. * matrix A. N >= 0.
  14879. *
  14880. * KD (input) INTEGER
  14881. * The number of superdiagonals of the matrix A if UPLO = 'U',
  14882. * or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  14883. *
  14884. * NRHS (input) INTEGER
  14885. * The number of right hand sides, i.e., the number of columns
  14886. * of the matrix B. NRHS >= 0.
  14887. *
  14888. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
  14889. * On entry, the upper or lower triangle of the symmetric band
  14890. * matrix A, stored in the first KD+1 rows of the array. The
  14891. * j-th column of A is stored in the j-th column of the array AB
  14892. * as follows:
  14893. * if UPLO = 'U', AB(KD+1+i-j,j) = A(i,j) for max(1,j-KD)<=i<=j;
  14894. * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(N,j+KD).
  14895. * See below for further details.
  14896. *
  14897. * On exit, if INFO = 0, the triangular factor U or L from the
  14898. * Cholesky factorization A = U**T*U or A = L*L**T of the band
  14899. * matrix A, in the same storage format as A.
  14900. *
  14901. * LDAB (input) INTEGER
  14902. * The leading dimension of the array AB. LDAB >= KD+1.
  14903. *
  14904. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  14905. * On entry, the N-by-NRHS right hand side matrix B.
  14906. * On exit, if INFO = 0, the N-by-NRHS solution matrix X.
  14907. *
  14908. * LDB (input) INTEGER
  14909. * The leading dimension of the array B. LDB >= max(1,N).
  14910. *
  14911. * INFO (output) INTEGER
  14912. * = 0: successful exit
  14913. * < 0: if INFO = -i, the i-th argument had an illegal value
  14914. * > 0: if INFO = i, the leading minor of order i of A is not
  14915. * positive definite, so the factorization could not be
  14916. * completed, and the solution has not been computed.
  14917. *
  14918. * Further Details
  14919. * ===============
  14920. *
  14921. * The band storage scheme is illustrated by the following example, when
  14922. * N = 6, KD = 2, and UPLO = 'U':
  14923. *
  14924. * On entry: On exit:
  14925. *
  14926. * * * a13 a24 a35 a46 * * u13 u24 u35 u46
  14927. * * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56
  14928. * a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66
  14929. *
  14930. * Similarly, if UPLO = 'L' the format of A is as follows:
  14931. *
  14932. * On entry: On exit:
  14933. *
  14934. * a11 a22 a33 a44 a55 a66 l11 l22 l33 l44 l55 l66
  14935. * a21 a32 a43 a54 a65 * l21 l32 l43 l54 l65 *
  14936. * a31 a42 a53 a64 * * l31 l42 l53 l64 * *
  14937. *
  14938. * Array elements marked * are not used by the routine.
  14939. *
  14940. * =====================================================================
  14941. *
  14942. * .. External Functions ..
  14943. LOGICAL LSAME
  14944. EXTERNAL LSAME
  14945. * ..
  14946. * .. External Subroutines ..
  14947. EXTERNAL DPBTRF, DPBTRS, XERBLA
  14948. * ..
  14949. * .. Intrinsic Functions ..
  14950. INTRINSIC MAX
  14951. * ..
  14952. * .. Executable Statements ..
  14953. *
  14954. * Test the input parameters.
  14955. *
  14956. INFO = 0
  14957. IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  14958. INFO = -1
  14959. ELSE IF( N.LT.0 ) THEN
  14960. INFO = -2
  14961. ELSE IF( KD.LT.0 ) THEN
  14962. INFO = -3
  14963. ELSE IF( NRHS.LT.0 ) THEN
  14964. INFO = -4
  14965. ELSE IF( LDAB.LT.KD+1 ) THEN
  14966. INFO = -6
  14967. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  14968. INFO = -8
  14969. END IF
  14970. IF( INFO.NE.0 ) THEN
  14971. CALL XERBLA( 'DPBSV ', -INFO )
  14972. RETURN
  14973. END IF
  14974. *
  14975. * Compute the Cholesky factorization A = U'*U or A = L*L'.
  14976. *
  14977. CALL DPBTRF( UPLO, N, KD, AB, LDAB, INFO )
  14978. IF( INFO.EQ.0 ) THEN
  14979. *
  14980. * Solve the system A*X = B, overwriting B with X.
  14981. *
  14982. CALL DPBTRS( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )
  14983. *
  14984. END IF
  14985. RETURN
  14986. *
  14987. * End of DPBSV
  14988. *
  14989. END
  14990. SUBROUTINE DPBSVX( FACT, UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB,
  14991. $ EQUED, S, B, LDB, X, LDX, RCOND, FERR, BERR,
  14992. $ WORK, IWORK, INFO )
  14993. *
  14994. * -- LAPACK driver routine (version 3.1) --
  14995. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  14996. * November 2006
  14997. *
  14998. * .. Scalar Arguments ..
  14999. CHARACTER EQUED, FACT, UPLO
  15000. INTEGER INFO, KD, LDAB, LDAFB, LDB, LDX, N, NRHS
  15001. DOUBLE PRECISION RCOND
  15002. * ..
  15003. * .. Array Arguments ..
  15004. INTEGER IWORK( * )
  15005. DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),
  15006. $ BERR( * ), FERR( * ), S( * ), WORK( * ),
  15007. $ X( LDX, * )
  15008. * ..
  15009. *
  15010. * Purpose
  15011. * =======
  15012. *
  15013. * DPBSVX uses the Cholesky factorization A = U**T*U or A = L*L**T to
  15014. * compute the solution to a real system of linear equations
  15015. * A * X = B,
  15016. * where A is an N-by-N symmetric positive definite band matrix and X
  15017. * and B are N-by-NRHS matrices.
  15018. *
  15019. * Error bounds on the solution and a condition estimate are also
  15020. * provided.
  15021. *
  15022. * Description
  15023. * ===========
  15024. *
  15025. * The following steps are performed:
  15026. *
  15027. * 1. If FACT = 'E', real scaling factors are computed to equilibrate
  15028. * the system:
  15029. * diag(S) * A * diag(S) * inv(diag(S)) * X = diag(S) * B
  15030. * Whether or not the system will be equilibrated depends on the
  15031. * scaling of the matrix A, but if equilibration is used, A is
  15032. * overwritten by diag(S)*A*diag(S) and B by diag(S)*B.
  15033. *
  15034. * 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to
  15035. * factor the matrix A (after equilibration if FACT = 'E') as
  15036. * A = U**T * U, if UPLO = 'U', or
  15037. * A = L * L**T, if UPLO = 'L',
  15038. * where U is an upper triangular band matrix, and L is a lower
  15039. * triangular band matrix.
  15040. *
  15041. * 3. If the leading i-by-i principal minor is not positive definite,
  15042. * then the routine returns with INFO = i. Otherwise, the factored
  15043. * form of A is used to estimate the condition number of the matrix
  15044. * A. If the reciprocal of the condition number is less than machine
  15045. * precision, INFO = N+1 is returned as a warning, but the routine
  15046. * still goes on to solve for X and compute error bounds as
  15047. * described below.
  15048. *
  15049. * 4. The system of equations is solved for X using the factored form
  15050. * of A.
  15051. *
  15052. * 5. Iterative refinement is applied to improve the computed solution
  15053. * matrix and calculate error bounds and backward error estimates
  15054. * for it.
  15055. *
  15056. * 6. If equilibration was used, the matrix X is premultiplied by
  15057. * diag(S) so that it solves the original system before
  15058. * equilibration.
  15059. *
  15060. * Arguments
  15061. * =========
  15062. *
  15063. * FACT (input) CHARACTER*1
  15064. * Specifies whether or not the factored form of the matrix A is
  15065. * supplied on entry, and if not, whether the matrix A should be
  15066. * equilibrated before it is factored.
  15067. * = 'F': On entry, AFB contains the factored form of A.
  15068. * If EQUED = 'Y', the matrix A has been equilibrated
  15069. * with scaling factors given by S. AB and AFB will not
  15070. * be modified.
  15071. * = 'N': The matrix A will be copied to AFB and factored.
  15072. * = 'E': The matrix A will be equilibrated if necessary, then
  15073. * copied to AFB and factored.
  15074. *
  15075. * UPLO (input) CHARACTER*1
  15076. * = 'U': Upper triangle of A is stored;
  15077. * = 'L': Lower triangle of A is stored.
  15078. *
  15079. * N (input) INTEGER
  15080. * The number of linear equations, i.e., the order of the
  15081. * matrix A. N >= 0.
  15082. *
  15083. * KD (input) INTEGER
  15084. * The number of superdiagonals of the matrix A if UPLO = 'U',
  15085. * or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  15086. *
  15087. * NRHS (input) INTEGER
  15088. * The number of right-hand sides, i.e., the number of columns
  15089. * of the matrices B and X. NRHS >= 0.
  15090. *
  15091. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N)
  15092. * On entry, the upper or lower triangle of the symmetric band
  15093. * matrix A, stored in the first KD+1 rows of the array, except
  15094. * if FACT = 'F' and EQUED = 'Y', then A must contain the
  15095. * equilibrated matrix diag(S)*A*diag(S). The j-th column of A
  15096. * is stored in the j-th column of the array AB as follows:
  15097. * if UPLO = 'U', AB(KD+1+i-j,j) = A(i,j) for max(1,j-KD)<=i<=j;
  15098. * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(N,j+KD).
  15099. * See below for further details.
  15100. *
  15101. * On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by
  15102. * diag(S)*A*diag(S).
  15103. *
  15104. * LDAB (input) INTEGER
  15105. * The leading dimension of the array A. LDAB >= KD+1.
  15106. *
  15107. * AFB (input or output) DOUBLE PRECISION array, dimension (LDAFB,N)
  15108. * If FACT = 'F', then AFB is an input argument and on entry
  15109. * contains the triangular factor U or L from the Cholesky
  15110. * factorization A = U**T*U or A = L*L**T of the band matrix
  15111. * A, in the same storage format as A (see AB). If EQUED = 'Y',
  15112. * then AFB is the factored form of the equilibrated matrix A.
  15113. *
  15114. * If FACT = 'N', then AFB is an output argument and on exit
  15115. * returns the triangular factor U or L from the Cholesky
  15116. * factorization A = U**T*U or A = L*L**T.
  15117. *
  15118. * If FACT = 'E', then AFB is an output argument and on exit
  15119. * returns the triangular factor U or L from the Cholesky
  15120. * factorization A = U**T*U or A = L*L**T of the equilibrated
  15121. * matrix A (see the description of A for the form of the
  15122. * equilibrated matrix).
  15123. *
  15124. * LDAFB (input) INTEGER
  15125. * The leading dimension of the array AFB. LDAFB >= KD+1.
  15126. *
  15127. * EQUED (input or output) CHARACTER*1
  15128. * Specifies the form of equilibration that was done.
  15129. * = 'N': No equilibration (always true if FACT = 'N').
  15130. * = 'Y': Equilibration was done, i.e., A has been replaced by
  15131. * diag(S) * A * diag(S).
  15132. * EQUED is an input argument if FACT = 'F'; otherwise, it is an
  15133. * output argument.
  15134. *
  15135. * S (input or output) DOUBLE PRECISION array, dimension (N)
  15136. * The scale factors for A; not accessed if EQUED = 'N'. S is
  15137. * an input argument if FACT = 'F'; otherwise, S is an output
  15138. * argument. If FACT = 'F' and EQUED = 'Y', each element of S
  15139. * must be positive.
  15140. *
  15141. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  15142. * On entry, the N-by-NRHS right hand side matrix B.
  15143. * On exit, if EQUED = 'N', B is not modified; if EQUED = 'Y',
  15144. * B is overwritten by diag(S) * B.
  15145. *
  15146. * LDB (input) INTEGER
  15147. * The leading dimension of the array B. LDB >= max(1,N).
  15148. *
  15149. * X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
  15150. * If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X to
  15151. * the original system of equations. Note that if EQUED = 'Y',
  15152. * A and B are modified on exit, and the solution to the
  15153. * equilibrated system is inv(diag(S))*X.
  15154. *
  15155. * LDX (input) INTEGER
  15156. * The leading dimension of the array X. LDX >= max(1,N).
  15157. *
  15158. * RCOND (output) DOUBLE PRECISION
  15159. * The estimate of the reciprocal condition number of the matrix
  15160. * A after equilibration (if done). If RCOND is less than the
  15161. * machine precision (in particular, if RCOND = 0), the matrix
  15162. * is singular to working precision. This condition is
  15163. * indicated by a return code of INFO > 0.
  15164. *
  15165. * FERR (output) DOUBLE PRECISION array, dimension (NRHS)
  15166. * The estimated forward error bound for each solution vector
  15167. * X(j) (the j-th column of the solution matrix X).
  15168. * If XTRUE is the true solution corresponding to X(j), FERR(j)
  15169. * is an estimated upper bound for the magnitude of the largest
  15170. * element in (X(j) - XTRUE) divided by the magnitude of the
  15171. * largest element in X(j). The estimate is as reliable as
  15172. * the estimate for RCOND, and is almost always a slight
  15173. * overestimate of the true error.
  15174. *
  15175. * BERR (output) DOUBLE PRECISION array, dimension (NRHS)
  15176. * The componentwise relative backward error of each solution
  15177. * vector X(j) (i.e., the smallest relative change in
  15178. * any element of A or B that makes X(j) an exact solution).
  15179. *
  15180. * WORK (workspace) DOUBLE PRECISION array, dimension (3*N)
  15181. *
  15182. * IWORK (workspace) INTEGER array, dimension (N)
  15183. *
  15184. * INFO (output) INTEGER
  15185. * = 0: successful exit
  15186. * < 0: if INFO = -i, the i-th argument had an illegal value
  15187. * > 0: if INFO = i, and i is
  15188. * <= N: the leading minor of order i of A is
  15189. * not positive definite, so the factorization
  15190. * could not be completed, and the solution has not
  15191. * been computed. RCOND = 0 is returned.
  15192. * = N+1: U is nonsingular, but RCOND is less than machine
  15193. * precision, meaning that the matrix is singular
  15194. * to working precision. Nevertheless, the
  15195. * solution and error bounds are computed because
  15196. * there are a number of situations where the
  15197. * computed solution can be more accurate than the
  15198. * value of RCOND would suggest.
  15199. *
  15200. * Further Details
  15201. * ===============
  15202. *
  15203. * The band storage scheme is illustrated by the following example, when
  15204. * N = 6, KD = 2, and UPLO = 'U':
  15205. *
  15206. * Two-dimensional storage of the symmetric matrix A:
  15207. *
  15208. * a11 a12 a13
  15209. * a22 a23 a24
  15210. * a33 a34 a35
  15211. * a44 a45 a46
  15212. * a55 a56
  15213. * (aij=conjg(aji)) a66
  15214. *
  15215. * Band storage of the upper triangle of A:
  15216. *
  15217. * * * a13 a24 a35 a46
  15218. * * a12 a23 a34 a45 a56
  15219. * a11 a22 a33 a44 a55 a66
  15220. *
  15221. * Similarly, if UPLO = 'L' the format of A is as follows:
  15222. *
  15223. * a11 a22 a33 a44 a55 a66
  15224. * a21 a32 a43 a54 a65 *
  15225. * a31 a42 a53 a64 * *
  15226. *
  15227. * Array elements marked * are not used by the routine.
  15228. *
  15229. * =====================================================================
  15230. *
  15231. * .. Parameters ..
  15232. DOUBLE PRECISION ZERO, ONE
  15233. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  15234. * ..
  15235. * .. Local Scalars ..
  15236. LOGICAL EQUIL, NOFACT, RCEQU, UPPER
  15237. INTEGER I, INFEQU, J, J1, J2
  15238. DOUBLE PRECISION AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM
  15239. * ..
  15240. * .. External Functions ..
  15241. LOGICAL LSAME
  15242. DOUBLE PRECISION DLAMCH, DLANSB
  15243. EXTERNAL LSAME, DLAMCH, DLANSB
  15244. * ..
  15245. * .. External Subroutines ..
  15246. EXTERNAL DCOPY, DLACPY, DLAQSB, DPBCON, DPBEQU, DPBRFS,
  15247. $ DPBTRF, DPBTRS, XERBLA
  15248. * ..
  15249. * .. Intrinsic Functions ..
  15250. INTRINSIC MAX, MIN
  15251. * ..
  15252. * .. Executable Statements ..
  15253. *
  15254. INFO = 0
  15255. NOFACT = LSAME( FACT, 'N' )
  15256. EQUIL = LSAME( FACT, 'E' )
  15257. UPPER = LSAME( UPLO, 'U' )
  15258. IF( NOFACT .OR. EQUIL ) THEN
  15259. EQUED = 'N'
  15260. RCEQU = .FALSE.
  15261. ELSE
  15262. RCEQU = LSAME( EQUED, 'Y' )
  15263. SMLNUM = DLAMCH( 'Safe minimum' )
  15264. BIGNUM = ONE / SMLNUM
  15265. END IF
  15266. *
  15267. * Test the input parameters.
  15268. *
  15269. IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )
  15270. $ THEN
  15271. INFO = -1
  15272. ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  15273. INFO = -2
  15274. ELSE IF( N.LT.0 ) THEN
  15275. INFO = -3
  15276. ELSE IF( KD.LT.0 ) THEN
  15277. INFO = -4
  15278. ELSE IF( NRHS.LT.0 ) THEN
  15279. INFO = -5
  15280. ELSE IF( LDAB.LT.KD+1 ) THEN
  15281. INFO = -7
  15282. ELSE IF( LDAFB.LT.KD+1 ) THEN
  15283. INFO = -9
  15284. ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.
  15285. $ ( RCEQU .OR. LSAME( EQUED, 'N' ) ) ) THEN
  15286. INFO = -10
  15287. ELSE
  15288. IF( RCEQU ) THEN
  15289. SMIN = BIGNUM
  15290. SMAX = ZERO
  15291. DO 10 J = 1, N
  15292. SMIN = MIN( SMIN, S( J ) )
  15293. SMAX = MAX( SMAX, S( J ) )
  15294. 10 CONTINUE
  15295. IF( SMIN.LE.ZERO ) THEN
  15296. INFO = -11
  15297. ELSE IF( N.GT.0 ) THEN
  15298. SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )
  15299. ELSE
  15300. SCOND = ONE
  15301. END IF
  15302. END IF
  15303. IF( INFO.EQ.0 ) THEN
  15304. IF( LDB.LT.MAX( 1, N ) ) THEN
  15305. INFO = -13
  15306. ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
  15307. INFO = -15
  15308. END IF
  15309. END IF
  15310. END IF
  15311. *
  15312. IF( INFO.NE.0 ) THEN
  15313. CALL XERBLA( 'DPBSVX', -INFO )
  15314. RETURN
  15315. END IF
  15316. *
  15317. IF( EQUIL ) THEN
  15318. *
  15319. * Compute row and column scalings to equilibrate the matrix A.
  15320. *
  15321. CALL DPBEQU( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, INFEQU )
  15322. IF( INFEQU.EQ.0 ) THEN
  15323. *
  15324. * Equilibrate the matrix.
  15325. *
  15326. CALL DLAQSB( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, EQUED )
  15327. RCEQU = LSAME( EQUED, 'Y' )
  15328. END IF
  15329. END IF
  15330. *
  15331. * Scale the right-hand side.
  15332. *
  15333. IF( RCEQU ) THEN
  15334. DO 30 J = 1, NRHS
  15335. DO 20 I = 1, N
  15336. B( I, J ) = S( I )*B( I, J )
  15337. 20 CONTINUE
  15338. 30 CONTINUE
  15339. END IF
  15340. *
  15341. IF( NOFACT .OR. EQUIL ) THEN
  15342. *
  15343. * Compute the Cholesky factorization A = U'*U or A = L*L'.
  15344. *
  15345. IF( UPPER ) THEN
  15346. DO 40 J = 1, N
  15347. J1 = MAX( J-KD, 1 )
  15348. CALL DCOPY( J-J1+1, AB( KD+1-J+J1, J ), 1,
  15349. $ AFB( KD+1-J+J1, J ), 1 )
  15350. 40 CONTINUE
  15351. ELSE
  15352. DO 50 J = 1, N
  15353. J2 = MIN( J+KD, N )
  15354. CALL DCOPY( J2-J+1, AB( 1, J ), 1, AFB( 1, J ), 1 )
  15355. 50 CONTINUE
  15356. END IF
  15357. *
  15358. CALL DPBTRF( UPLO, N, KD, AFB, LDAFB, INFO )
  15359. *
  15360. * Return if INFO is non-zero.
  15361. *
  15362. IF( INFO.GT.0 )THEN
  15363. RCOND = ZERO
  15364. RETURN
  15365. END IF
  15366. END IF
  15367. *
  15368. * Compute the norm of the matrix A.
  15369. *
  15370. ANORM = DLANSB( '1', UPLO, N, KD, AB, LDAB, WORK )
  15371. *
  15372. * Compute the reciprocal of the condition number of A.
  15373. *
  15374. CALL DPBCON( UPLO, N, KD, AFB, LDAFB, ANORM, RCOND, WORK, IWORK,
  15375. $ INFO )
  15376. *
  15377. * Compute the solution matrix X.
  15378. *
  15379. CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
  15380. CALL DPBTRS( UPLO, N, KD, NRHS, AFB, LDAFB, X, LDX, INFO )
  15381. *
  15382. * Use iterative refinement to improve the computed solution and
  15383. * compute error bounds and backward error estimates for it.
  15384. *
  15385. CALL DPBRFS( UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB, B, LDB, X,
  15386. $ LDX, FERR, BERR, WORK, IWORK, INFO )
  15387. *
  15388. * Transform the solution matrix X to a solution of the original
  15389. * system.
  15390. *
  15391. IF( RCEQU ) THEN
  15392. DO 70 J = 1, NRHS
  15393. DO 60 I = 1, N
  15394. X( I, J ) = S( I )*X( I, J )
  15395. 60 CONTINUE
  15396. 70 CONTINUE
  15397. DO 80 J = 1, NRHS
  15398. FERR( J ) = FERR( J ) / SCOND
  15399. 80 CONTINUE
  15400. END IF
  15401. *
  15402. * Set INFO = N+1 if the matrix is singular to working precision.
  15403. *
  15404. IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
  15405. $ INFO = N + 1
  15406. *
  15407. RETURN
  15408. *
  15409. * End of DPBSVX
  15410. *
  15411. END
  15412. SUBROUTINE DPOSV( UPLO, N, NRHS, A, LDA, B, LDB, INFO )
  15413. *
  15414. * -- LAPACK driver routine (version 3.1) --
  15415. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  15416. * November 2006
  15417. *
  15418. * .. Scalar Arguments ..
  15419. CHARACTER UPLO
  15420. INTEGER INFO, LDA, LDB, N, NRHS
  15421. * ..
  15422. * .. Array Arguments ..
  15423. DOUBLE PRECISION A( LDA, * ), B( LDB, * )
  15424. * ..
  15425. *
  15426. * Purpose
  15427. * =======
  15428. *
  15429. * DPOSV computes the solution to a real system of linear equations
  15430. * A * X = B,
  15431. * where A is an N-by-N symmetric positive definite matrix and X and B
  15432. * are N-by-NRHS matrices.
  15433. *
  15434. * The Cholesky decomposition is used to factor A as
  15435. * A = U**T* U, if UPLO = 'U', or
  15436. * A = L * L**T, if UPLO = 'L',
  15437. * where U is an upper triangular matrix and L is a lower triangular
  15438. * matrix. The factored form of A is then used to solve the system of
  15439. * equations A * X = B.
  15440. *
  15441. * Arguments
  15442. * =========
  15443. *
  15444. * UPLO (input) CHARACTER*1
  15445. * = 'U': Upper triangle of A is stored;
  15446. * = 'L': Lower triangle of A is stored.
  15447. *
  15448. * N (input) INTEGER
  15449. * The number of linear equations, i.e., the order of the
  15450. * matrix A. N >= 0.
  15451. *
  15452. * NRHS (input) INTEGER
  15453. * The number of right hand sides, i.e., the number of columns
  15454. * of the matrix B. NRHS >= 0.
  15455. *
  15456. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  15457. * On entry, the symmetric matrix A. If UPLO = 'U', the leading
  15458. * N-by-N upper triangular part of A contains the upper
  15459. * triangular part of the matrix A, and the strictly lower
  15460. * triangular part of A is not referenced. If UPLO = 'L', the
  15461. * leading N-by-N lower triangular part of A contains the lower
  15462. * triangular part of the matrix A, and the strictly upper
  15463. * triangular part of A is not referenced.
  15464. *
  15465. * On exit, if INFO = 0, the factor U or L from the Cholesky
  15466. * factorization A = U**T*U or A = L*L**T.
  15467. *
  15468. * LDA (input) INTEGER
  15469. * The leading dimension of the array A. LDA >= max(1,N).
  15470. *
  15471. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  15472. * On entry, the N-by-NRHS right hand side matrix B.
  15473. * On exit, if INFO = 0, the N-by-NRHS solution matrix X.
  15474. *
  15475. * LDB (input) INTEGER
  15476. * The leading dimension of the array B. LDB >= max(1,N).
  15477. *
  15478. * INFO (output) INTEGER
  15479. * = 0: successful exit
  15480. * < 0: if INFO = -i, the i-th argument had an illegal value
  15481. * > 0: if INFO = i, the leading minor of order i of A is not
  15482. * positive definite, so the factorization could not be
  15483. * completed, and the solution has not been computed.
  15484. *
  15485. * =====================================================================
  15486. *
  15487. * .. External Functions ..
  15488. LOGICAL LSAME
  15489. EXTERNAL LSAME
  15490. * ..
  15491. * .. External Subroutines ..
  15492. EXTERNAL DPOTRF, DPOTRS, XERBLA
  15493. * ..
  15494. * .. Intrinsic Functions ..
  15495. INTRINSIC MAX
  15496. * ..
  15497. * .. Executable Statements ..
  15498. *
  15499. * Test the input parameters.
  15500. *
  15501. INFO = 0
  15502. IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  15503. INFO = -1
  15504. ELSE IF( N.LT.0 ) THEN
  15505. INFO = -2
  15506. ELSE IF( NRHS.LT.0 ) THEN
  15507. INFO = -3
  15508. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  15509. INFO = -5
  15510. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  15511. INFO = -7
  15512. END IF
  15513. IF( INFO.NE.0 ) THEN
  15514. CALL XERBLA( 'DPOSV ', -INFO )
  15515. RETURN
  15516. END IF
  15517. *
  15518. * Compute the Cholesky factorization A = U'*U or A = L*L'.
  15519. *
  15520. CALL DPOTRF( UPLO, N, A, LDA, INFO )
  15521. IF( INFO.EQ.0 ) THEN
  15522. *
  15523. * Solve the system A*X = B, overwriting B with X.
  15524. *
  15525. CALL DPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO )
  15526. *
  15527. END IF
  15528. RETURN
  15529. *
  15530. * End of DPOSV
  15531. *
  15532. END
  15533. SUBROUTINE DPOSVX( FACT, UPLO, N, NRHS, A, LDA, AF, LDAF, EQUED,
  15534. $ S, B, LDB, X, LDX, RCOND, FERR, BERR, WORK,
  15535. $ IWORK, INFO )
  15536. *
  15537. * -- LAPACK driver routine (version 3.1) --
  15538. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  15539. * November 2006
  15540. *
  15541. * .. Scalar Arguments ..
  15542. CHARACTER EQUED, FACT, UPLO
  15543. INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS
  15544. DOUBLE PRECISION RCOND
  15545. * ..
  15546. * .. Array Arguments ..
  15547. INTEGER IWORK( * )
  15548. DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),
  15549. $ BERR( * ), FERR( * ), S( * ), WORK( * ),
  15550. $ X( LDX, * )
  15551. * ..
  15552. *
  15553. * Purpose
  15554. * =======
  15555. *
  15556. * DPOSVX uses the Cholesky factorization A = U**T*U or A = L*L**T to
  15557. * compute the solution to a real system of linear equations
  15558. * A * X = B,
  15559. * where A is an N-by-N symmetric positive definite matrix and X and B
  15560. * are N-by-NRHS matrices.
  15561. *
  15562. * Error bounds on the solution and a condition estimate are also
  15563. * provided.
  15564. *
  15565. * Description
  15566. * ===========
  15567. *
  15568. * The following steps are performed:
  15569. *
  15570. * 1. If FACT = 'E', real scaling factors are computed to equilibrate
  15571. * the system:
  15572. * diag(S) * A * diag(S) * inv(diag(S)) * X = diag(S) * B
  15573. * Whether or not the system will be equilibrated depends on the
  15574. * scaling of the matrix A, but if equilibration is used, A is
  15575. * overwritten by diag(S)*A*diag(S) and B by diag(S)*B.
  15576. *
  15577. * 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to
  15578. * factor the matrix A (after equilibration if FACT = 'E') as
  15579. * A = U**T* U, if UPLO = 'U', or
  15580. * A = L * L**T, if UPLO = 'L',
  15581. * where U is an upper triangular matrix and L is a lower triangular
  15582. * matrix.
  15583. *
  15584. * 3. If the leading i-by-i principal minor is not positive definite,
  15585. * then the routine returns with INFO = i. Otherwise, the factored
  15586. * form of A is used to estimate the condition number of the matrix
  15587. * A. If the reciprocal of the condition number is less than machine
  15588. * precision, INFO = N+1 is returned as a warning, but the routine
  15589. * still goes on to solve for X and compute error bounds as
  15590. * described below.
  15591. *
  15592. * 4. The system of equations is solved for X using the factored form
  15593. * of A.
  15594. *
  15595. * 5. Iterative refinement is applied to improve the computed solution
  15596. * matrix and calculate error bounds and backward error estimates
  15597. * for it.
  15598. *
  15599. * 6. If equilibration was used, the matrix X is premultiplied by
  15600. * diag(S) so that it solves the original system before
  15601. * equilibration.
  15602. *
  15603. * Arguments
  15604. * =========
  15605. *
  15606. * FACT (input) CHARACTER*1
  15607. * Specifies whether or not the factored form of the matrix A is
  15608. * supplied on entry, and if not, whether the matrix A should be
  15609. * equilibrated before it is factored.
  15610. * = 'F': On entry, AF contains the factored form of A.
  15611. * If EQUED = 'Y', the matrix A has been equilibrated
  15612. * with scaling factors given by S. A and AF will not
  15613. * be modified.
  15614. * = 'N': The matrix A will be copied to AF and factored.
  15615. * = 'E': The matrix A will be equilibrated if necessary, then
  15616. * copied to AF and factored.
  15617. *
  15618. * UPLO (input) CHARACTER*1
  15619. * = 'U': Upper triangle of A is stored;
  15620. * = 'L': Lower triangle of A is stored.
  15621. *
  15622. * N (input) INTEGER
  15623. * The number of linear equations, i.e., the order of the
  15624. * matrix A. N >= 0.
  15625. *
  15626. * NRHS (input) INTEGER
  15627. * The number of right hand sides, i.e., the number of columns
  15628. * of the matrices B and X. NRHS >= 0.
  15629. *
  15630. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  15631. * On entry, the symmetric matrix A, except if FACT = 'F' and
  15632. * EQUED = 'Y', then A must contain the equilibrated matrix
  15633. * diag(S)*A*diag(S). If UPLO = 'U', the leading
  15634. * N-by-N upper triangular part of A contains the upper
  15635. * triangular part of the matrix A, and the strictly lower
  15636. * triangular part of A is not referenced. If UPLO = 'L', the
  15637. * leading N-by-N lower triangular part of A contains the lower
  15638. * triangular part of the matrix A, and the strictly upper
  15639. * triangular part of A is not referenced. A is not modified if
  15640. * FACT = 'F' or 'N', or if FACT = 'E' and EQUED = 'N' on exit.
  15641. *
  15642. * On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by
  15643. * diag(S)*A*diag(S).
  15644. *
  15645. * LDA (input) INTEGER
  15646. * The leading dimension of the array A. LDA >= max(1,N).
  15647. *
  15648. * AF (input or output) DOUBLE PRECISION array, dimension (LDAF,N)
  15649. * If FACT = 'F', then AF is an input argument and on entry
  15650. * contains the triangular factor U or L from the Cholesky
  15651. * factorization A = U**T*U or A = L*L**T, in the same storage
  15652. * format as A. If EQUED .ne. 'N', then AF is the factored form
  15653. * of the equilibrated matrix diag(S)*A*diag(S).
  15654. *
  15655. * If FACT = 'N', then AF is an output argument and on exit
  15656. * returns the triangular factor U or L from the Cholesky
  15657. * factorization A = U**T*U or A = L*L**T of the original
  15658. * matrix A.
  15659. *
  15660. * If FACT = 'E', then AF is an output argument and on exit
  15661. * returns the triangular factor U or L from the Cholesky
  15662. * factorization A = U**T*U or A = L*L**T of the equilibrated
  15663. * matrix A (see the description of A for the form of the
  15664. * equilibrated matrix).
  15665. *
  15666. * LDAF (input) INTEGER
  15667. * The leading dimension of the array AF. LDAF >= max(1,N).
  15668. *
  15669. * EQUED (input or output) CHARACTER*1
  15670. * Specifies the form of equilibration that was done.
  15671. * = 'N': No equilibration (always true if FACT = 'N').
  15672. * = 'Y': Equilibration was done, i.e., A has been replaced by
  15673. * diag(S) * A * diag(S).
  15674. * EQUED is an input argument if FACT = 'F'; otherwise, it is an
  15675. * output argument.
  15676. *
  15677. * S (input or output) DOUBLE PRECISION array, dimension (N)
  15678. * The scale factors for A; not accessed if EQUED = 'N'. S is
  15679. * an input argument if FACT = 'F'; otherwise, S is an output
  15680. * argument. If FACT = 'F' and EQUED = 'Y', each element of S
  15681. * must be positive.
  15682. *
  15683. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  15684. * On entry, the N-by-NRHS right hand side matrix B.
  15685. * On exit, if EQUED = 'N', B is not modified; if EQUED = 'Y',
  15686. * B is overwritten by diag(S) * B.
  15687. *
  15688. * LDB (input) INTEGER
  15689. * The leading dimension of the array B. LDB >= max(1,N).
  15690. *
  15691. * X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
  15692. * If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X to
  15693. * the original system of equations. Note that if EQUED = 'Y',
  15694. * A and B are modified on exit, and the solution to the
  15695. * equilibrated system is inv(diag(S))*X.
  15696. *
  15697. * LDX (input) INTEGER
  15698. * The leading dimension of the array X. LDX >= max(1,N).
  15699. *
  15700. * RCOND (output) DOUBLE PRECISION
  15701. * The estimate of the reciprocal condition number of the matrix
  15702. * A after equilibration (if done). If RCOND is less than the
  15703. * machine precision (in particular, if RCOND = 0), the matrix
  15704. * is singular to working precision. This condition is
  15705. * indicated by a return code of INFO > 0.
  15706. *
  15707. * FERR (output) DOUBLE PRECISION array, dimension (NRHS)
  15708. * The estimated forward error bound for each solution vector
  15709. * X(j) (the j-th column of the solution matrix X).
  15710. * If XTRUE is the true solution corresponding to X(j), FERR(j)
  15711. * is an estimated upper bound for the magnitude of the largest
  15712. * element in (X(j) - XTRUE) divided by the magnitude of the
  15713. * largest element in X(j). The estimate is as reliable as
  15714. * the estimate for RCOND, and is almost always a slight
  15715. * overestimate of the true error.
  15716. *
  15717. * BERR (output) DOUBLE PRECISION array, dimension (NRHS)
  15718. * The componentwise relative backward error of each solution
  15719. * vector X(j) (i.e., the smallest relative change in
  15720. * any element of A or B that makes X(j) an exact solution).
  15721. *
  15722. * WORK (workspace) DOUBLE PRECISION array, dimension (3*N)
  15723. *
  15724. * IWORK (workspace) INTEGER array, dimension (N)
  15725. *
  15726. * INFO (output) INTEGER
  15727. * = 0: successful exit
  15728. * < 0: if INFO = -i, the i-th argument had an illegal value
  15729. * > 0: if INFO = i, and i is
  15730. * <= N: the leading minor of order i of A is
  15731. * not positive definite, so the factorization
  15732. * could not be completed, and the solution has not
  15733. * been computed. RCOND = 0 is returned.
  15734. * = N+1: U is nonsingular, but RCOND is less than machine
  15735. * precision, meaning that the matrix is singular
  15736. * to working precision. Nevertheless, the
  15737. * solution and error bounds are computed because
  15738. * there are a number of situations where the
  15739. * computed solution can be more accurate than the
  15740. * value of RCOND would suggest.
  15741. *
  15742. * =====================================================================
  15743. *
  15744. * .. Parameters ..
  15745. DOUBLE PRECISION ZERO, ONE
  15746. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  15747. * ..
  15748. * .. Local Scalars ..
  15749. LOGICAL EQUIL, NOFACT, RCEQU
  15750. INTEGER I, INFEQU, J
  15751. DOUBLE PRECISION AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM
  15752. * ..
  15753. * .. External Functions ..
  15754. LOGICAL LSAME
  15755. DOUBLE PRECISION DLAMCH, DLANSY
  15756. EXTERNAL LSAME, DLAMCH, DLANSY
  15757. * ..
  15758. * .. External Subroutines ..
  15759. EXTERNAL DLACPY, DLAQSY, DPOCON, DPOEQU, DPORFS, DPOTRF,
  15760. $ DPOTRS, XERBLA
  15761. * ..
  15762. * .. Intrinsic Functions ..
  15763. INTRINSIC MAX, MIN
  15764. * ..
  15765. * .. Executable Statements ..
  15766. *
  15767. INFO = 0
  15768. NOFACT = LSAME( FACT, 'N' )
  15769. EQUIL = LSAME( FACT, 'E' )
  15770. IF( NOFACT .OR. EQUIL ) THEN
  15771. EQUED = 'N'
  15772. RCEQU = .FALSE.
  15773. ELSE
  15774. RCEQU = LSAME( EQUED, 'Y' )
  15775. SMLNUM = DLAMCH( 'Safe minimum' )
  15776. BIGNUM = ONE / SMLNUM
  15777. END IF
  15778. *
  15779. * Test the input parameters.
  15780. *
  15781. IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )
  15782. $ THEN
  15783. INFO = -1
  15784. ELSE IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) )
  15785. $ THEN
  15786. INFO = -2
  15787. ELSE IF( N.LT.0 ) THEN
  15788. INFO = -3
  15789. ELSE IF( NRHS.LT.0 ) THEN
  15790. INFO = -4
  15791. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  15792. INFO = -6
  15793. ELSE IF( LDAF.LT.MAX( 1, N ) ) THEN
  15794. INFO = -8
  15795. ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.
  15796. $ ( RCEQU .OR. LSAME( EQUED, 'N' ) ) ) THEN
  15797. INFO = -9
  15798. ELSE
  15799. IF( RCEQU ) THEN
  15800. SMIN = BIGNUM
  15801. SMAX = ZERO
  15802. DO 10 J = 1, N
  15803. SMIN = MIN( SMIN, S( J ) )
  15804. SMAX = MAX( SMAX, S( J ) )
  15805. 10 CONTINUE
  15806. IF( SMIN.LE.ZERO ) THEN
  15807. INFO = -10
  15808. ELSE IF( N.GT.0 ) THEN
  15809. SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )
  15810. ELSE
  15811. SCOND = ONE
  15812. END IF
  15813. END IF
  15814. IF( INFO.EQ.0 ) THEN
  15815. IF( LDB.LT.MAX( 1, N ) ) THEN
  15816. INFO = -12
  15817. ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
  15818. INFO = -14
  15819. END IF
  15820. END IF
  15821. END IF
  15822. *
  15823. IF( INFO.NE.0 ) THEN
  15824. CALL XERBLA( 'DPOSVX', -INFO )
  15825. RETURN
  15826. END IF
  15827. *
  15828. IF( EQUIL ) THEN
  15829. *
  15830. * Compute row and column scalings to equilibrate the matrix A.
  15831. *
  15832. CALL DPOEQU( N, A, LDA, S, SCOND, AMAX, INFEQU )
  15833. IF( INFEQU.EQ.0 ) THEN
  15834. *
  15835. * Equilibrate the matrix.
  15836. *
  15837. CALL DLAQSY( UPLO, N, A, LDA, S, SCOND, AMAX, EQUED )
  15838. RCEQU = LSAME( EQUED, 'Y' )
  15839. END IF
  15840. END IF
  15841. *
  15842. * Scale the right hand side.
  15843. *
  15844. IF( RCEQU ) THEN
  15845. DO 30 J = 1, NRHS
  15846. DO 20 I = 1, N
  15847. B( I, J ) = S( I )*B( I, J )
  15848. 20 CONTINUE
  15849. 30 CONTINUE
  15850. END IF
  15851. *
  15852. IF( NOFACT .OR. EQUIL ) THEN
  15853. *
  15854. * Compute the Cholesky factorization A = U'*U or A = L*L'.
  15855. *
  15856. CALL DLACPY( UPLO, N, N, A, LDA, AF, LDAF )
  15857. CALL DPOTRF( UPLO, N, AF, LDAF, INFO )
  15858. *
  15859. * Return if INFO is non-zero.
  15860. *
  15861. IF( INFO.GT.0 )THEN
  15862. RCOND = ZERO
  15863. RETURN
  15864. END IF
  15865. END IF
  15866. *
  15867. * Compute the norm of the matrix A.
  15868. *
  15869. ANORM = DLANSY( '1', UPLO, N, A, LDA, WORK )
  15870. *
  15871. * Compute the reciprocal of the condition number of A.
  15872. *
  15873. CALL DPOCON( UPLO, N, AF, LDAF, ANORM, RCOND, WORK, IWORK, INFO )
  15874. *
  15875. * Compute the solution matrix X.
  15876. *
  15877. CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
  15878. CALL DPOTRS( UPLO, N, NRHS, AF, LDAF, X, LDX, INFO )
  15879. *
  15880. * Use iterative refinement to improve the computed solution and
  15881. * compute error bounds and backward error estimates for it.
  15882. *
  15883. CALL DPORFS( UPLO, N, NRHS, A, LDA, AF, LDAF, B, LDB, X, LDX,
  15884. $ FERR, BERR, WORK, IWORK, INFO )
  15885. *
  15886. * Transform the solution matrix X to a solution of the original
  15887. * system.
  15888. *
  15889. IF( RCEQU ) THEN
  15890. DO 50 J = 1, NRHS
  15891. DO 40 I = 1, N
  15892. X( I, J ) = S( I )*X( I, J )
  15893. 40 CONTINUE
  15894. 50 CONTINUE
  15895. DO 60 J = 1, NRHS
  15896. FERR( J ) = FERR( J ) / SCOND
  15897. 60 CONTINUE
  15898. END IF
  15899. *
  15900. * Set INFO = N+1 if the matrix is singular to working precision.
  15901. *
  15902. IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
  15903. $ INFO = N + 1
  15904. *
  15905. RETURN
  15906. *
  15907. * End of DPOSVX
  15908. *
  15909. END
  15910. SUBROUTINE DPPSV( UPLO, N, NRHS, AP, B, LDB, INFO )
  15911. *
  15912. * -- LAPACK driver routine (version 3.1) --
  15913. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  15914. * November 2006
  15915. *
  15916. * .. Scalar Arguments ..
  15917. CHARACTER UPLO
  15918. INTEGER INFO, LDB, N, NRHS
  15919. * ..
  15920. * .. Array Arguments ..
  15921. DOUBLE PRECISION AP( * ), B( LDB, * )
  15922. * ..
  15923. *
  15924. * Purpose
  15925. * =======
  15926. *
  15927. * DPPSV computes the solution to a real system of linear equations
  15928. * A * X = B,
  15929. * where A is an N-by-N symmetric positive definite matrix stored in
  15930. * packed format and X and B are N-by-NRHS matrices.
  15931. *
  15932. * The Cholesky decomposition is used to factor A as
  15933. * A = U**T* U, if UPLO = 'U', or
  15934. * A = L * L**T, if UPLO = 'L',
  15935. * where U is an upper triangular matrix and L is a lower triangular
  15936. * matrix. The factored form of A is then used to solve the system of
  15937. * equations A * X = B.
  15938. *
  15939. * Arguments
  15940. * =========
  15941. *
  15942. * UPLO (input) CHARACTER*1
  15943. * = 'U': Upper triangle of A is stored;
  15944. * = 'L': Lower triangle of A is stored.
  15945. *
  15946. * N (input) INTEGER
  15947. * The number of linear equations, i.e., the order of the
  15948. * matrix A. N >= 0.
  15949. *
  15950. * NRHS (input) INTEGER
  15951. * The number of right hand sides, i.e., the number of columns
  15952. * of the matrix B. NRHS >= 0.
  15953. *
  15954. * AP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  15955. * On entry, the upper or lower triangle of the symmetric matrix
  15956. * A, packed columnwise in a linear array. The j-th column of A
  15957. * is stored in the array AP as follows:
  15958. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  15959. * if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  15960. * See below for further details.
  15961. *
  15962. * On exit, if INFO = 0, the factor U or L from the Cholesky
  15963. * factorization A = U**T*U or A = L*L**T, in the same storage
  15964. * format as A.
  15965. *
  15966. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  15967. * On entry, the N-by-NRHS right hand side matrix B.
  15968. * On exit, if INFO = 0, the N-by-NRHS solution matrix X.
  15969. *
  15970. * LDB (input) INTEGER
  15971. * The leading dimension of the array B. LDB >= max(1,N).
  15972. *
  15973. * INFO (output) INTEGER
  15974. * = 0: successful exit
  15975. * < 0: if INFO = -i, the i-th argument had an illegal value
  15976. * > 0: if INFO = i, the leading minor of order i of A is not
  15977. * positive definite, so the factorization could not be
  15978. * completed, and the solution has not been computed.
  15979. *
  15980. * Further Details
  15981. * ===============
  15982. *
  15983. * The packed storage scheme is illustrated by the following example
  15984. * when N = 4, UPLO = 'U':
  15985. *
  15986. * Two-dimensional storage of the symmetric matrix A:
  15987. *
  15988. * a11 a12 a13 a14
  15989. * a22 a23 a24
  15990. * a33 a34 (aij = conjg(aji))
  15991. * a44
  15992. *
  15993. * Packed storage of the upper triangle of A:
  15994. *
  15995. * AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]
  15996. *
  15997. * =====================================================================
  15998. *
  15999. * .. External Functions ..
  16000. LOGICAL LSAME
  16001. EXTERNAL LSAME
  16002. * ..
  16003. * .. External Subroutines ..
  16004. EXTERNAL DPPTRF, DPPTRS, XERBLA
  16005. * ..
  16006. * .. Intrinsic Functions ..
  16007. INTRINSIC MAX
  16008. * ..
  16009. * .. Executable Statements ..
  16010. *
  16011. * Test the input parameters.
  16012. *
  16013. INFO = 0
  16014. IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  16015. INFO = -1
  16016. ELSE IF( N.LT.0 ) THEN
  16017. INFO = -2
  16018. ELSE IF( NRHS.LT.0 ) THEN
  16019. INFO = -3
  16020. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  16021. INFO = -6
  16022. END IF
  16023. IF( INFO.NE.0 ) THEN
  16024. CALL XERBLA( 'DPPSV ', -INFO )
  16025. RETURN
  16026. END IF
  16027. *
  16028. * Compute the Cholesky factorization A = U'*U or A = L*L'.
  16029. *
  16030. CALL DPPTRF( UPLO, N, AP, INFO )
  16031. IF( INFO.EQ.0 ) THEN
  16032. *
  16033. * Solve the system A*X = B, overwriting B with X.
  16034. *
  16035. CALL DPPTRS( UPLO, N, NRHS, AP, B, LDB, INFO )
  16036. *
  16037. END IF
  16038. RETURN
  16039. *
  16040. * End of DPPSV
  16041. *
  16042. END
  16043. SUBROUTINE DPPSVX( FACT, UPLO, N, NRHS, AP, AFP, EQUED, S, B, LDB,
  16044. $ X, LDX, RCOND, FERR, BERR, WORK, IWORK, INFO )
  16045. *
  16046. * -- LAPACK driver routine (version 3.1) --
  16047. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  16048. * November 2006
  16049. *
  16050. * .. Scalar Arguments ..
  16051. CHARACTER EQUED, FACT, UPLO
  16052. INTEGER INFO, LDB, LDX, N, NRHS
  16053. DOUBLE PRECISION RCOND
  16054. * ..
  16055. * .. Array Arguments ..
  16056. INTEGER IWORK( * )
  16057. DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),
  16058. $ FERR( * ), S( * ), WORK( * ), X( LDX, * )
  16059. * ..
  16060. *
  16061. * Purpose
  16062. * =======
  16063. *
  16064. * DPPSVX uses the Cholesky factorization A = U**T*U or A = L*L**T to
  16065. * compute the solution to a real system of linear equations
  16066. * A * X = B,
  16067. * where A is an N-by-N symmetric positive definite matrix stored in
  16068. * packed format and X and B are N-by-NRHS matrices.
  16069. *
  16070. * Error bounds on the solution and a condition estimate are also
  16071. * provided.
  16072. *
  16073. * Description
  16074. * ===========
  16075. *
  16076. * The following steps are performed:
  16077. *
  16078. * 1. If FACT = 'E', real scaling factors are computed to equilibrate
  16079. * the system:
  16080. * diag(S) * A * diag(S) * inv(diag(S)) * X = diag(S) * B
  16081. * Whether or not the system will be equilibrated depends on the
  16082. * scaling of the matrix A, but if equilibration is used, A is
  16083. * overwritten by diag(S)*A*diag(S) and B by diag(S)*B.
  16084. *
  16085. * 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to
  16086. * factor the matrix A (after equilibration if FACT = 'E') as
  16087. * A = U**T* U, if UPLO = 'U', or
  16088. * A = L * L**T, if UPLO = 'L',
  16089. * where U is an upper triangular matrix and L is a lower triangular
  16090. * matrix.
  16091. *
  16092. * 3. If the leading i-by-i principal minor is not positive definite,
  16093. * then the routine returns with INFO = i. Otherwise, the factored
  16094. * form of A is used to estimate the condition number of the matrix
  16095. * A. If the reciprocal of the condition number is less than machine
  16096. * precision, INFO = N+1 is returned as a warning, but the routine
  16097. * still goes on to solve for X and compute error bounds as
  16098. * described below.
  16099. *
  16100. * 4. The system of equations is solved for X using the factored form
  16101. * of A.
  16102. *
  16103. * 5. Iterative refinement is applied to improve the computed solution
  16104. * matrix and calculate error bounds and backward error estimates
  16105. * for it.
  16106. *
  16107. * 6. If equilibration was used, the matrix X is premultiplied by
  16108. * diag(S) so that it solves the original system before
  16109. * equilibration.
  16110. *
  16111. * Arguments
  16112. * =========
  16113. *
  16114. * FACT (input) CHARACTER*1
  16115. * Specifies whether or not the factored form of the matrix A is
  16116. * supplied on entry, and if not, whether the matrix A should be
  16117. * equilibrated before it is factored.
  16118. * = 'F': On entry, AFP contains the factored form of A.
  16119. * If EQUED = 'Y', the matrix A has been equilibrated
  16120. * with scaling factors given by S. AP and AFP will not
  16121. * be modified.
  16122. * = 'N': The matrix A will be copied to AFP and factored.
  16123. * = 'E': The matrix A will be equilibrated if necessary, then
  16124. * copied to AFP and factored.
  16125. *
  16126. * UPLO (input) CHARACTER*1
  16127. * = 'U': Upper triangle of A is stored;
  16128. * = 'L': Lower triangle of A is stored.
  16129. *
  16130. * N (input) INTEGER
  16131. * The number of linear equations, i.e., the order of the
  16132. * matrix A. N >= 0.
  16133. *
  16134. * NRHS (input) INTEGER
  16135. * The number of right hand sides, i.e., the number of columns
  16136. * of the matrices B and X. NRHS >= 0.
  16137. *
  16138. * AP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  16139. * On entry, the upper or lower triangle of the symmetric matrix
  16140. * A, packed columnwise in a linear array, except if FACT = 'F'
  16141. * and EQUED = 'Y', then A must contain the equilibrated matrix
  16142. * diag(S)*A*diag(S). The j-th column of A is stored in the
  16143. * array AP as follows:
  16144. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  16145. * if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  16146. * See below for further details. A is not modified if
  16147. * FACT = 'F' or 'N', or if FACT = 'E' and EQUED = 'N' on exit.
  16148. *
  16149. * On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by
  16150. * diag(S)*A*diag(S).
  16151. *
  16152. * AFP (input or output) DOUBLE PRECISION array, dimension
  16153. * (N*(N+1)/2)
  16154. * If FACT = 'F', then AFP is an input argument and on entry
  16155. * contains the triangular factor U or L from the Cholesky
  16156. * factorization A = U'*U or A = L*L', in the same storage
  16157. * format as A. If EQUED .ne. 'N', then AFP is the factored
  16158. * form of the equilibrated matrix A.
  16159. *
  16160. * If FACT = 'N', then AFP is an output argument and on exit
  16161. * returns the triangular factor U or L from the Cholesky
  16162. * factorization A = U'*U or A = L*L' of the original matrix A.
  16163. *
  16164. * If FACT = 'E', then AFP is an output argument and on exit
  16165. * returns the triangular factor U or L from the Cholesky
  16166. * factorization A = U'*U or A = L*L' of the equilibrated
  16167. * matrix A (see the description of AP for the form of the
  16168. * equilibrated matrix).
  16169. *
  16170. * EQUED (input or output) CHARACTER*1
  16171. * Specifies the form of equilibration that was done.
  16172. * = 'N': No equilibration (always true if FACT = 'N').
  16173. * = 'Y': Equilibration was done, i.e., A has been replaced by
  16174. * diag(S) * A * diag(S).
  16175. * EQUED is an input argument if FACT = 'F'; otherwise, it is an
  16176. * output argument.
  16177. *
  16178. * S (input or output) DOUBLE PRECISION array, dimension (N)
  16179. * The scale factors for A; not accessed if EQUED = 'N'. S is
  16180. * an input argument if FACT = 'F'; otherwise, S is an output
  16181. * argument. If FACT = 'F' and EQUED = 'Y', each element of S
  16182. * must be positive.
  16183. *
  16184. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  16185. * On entry, the N-by-NRHS right hand side matrix B.
  16186. * On exit, if EQUED = 'N', B is not modified; if EQUED = 'Y',
  16187. * B is overwritten by diag(S) * B.
  16188. *
  16189. * LDB (input) INTEGER
  16190. * The leading dimension of the array B. LDB >= max(1,N).
  16191. *
  16192. * X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
  16193. * If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X to
  16194. * the original system of equations. Note that if EQUED = 'Y',
  16195. * A and B are modified on exit, and the solution to the
  16196. * equilibrated system is inv(diag(S))*X.
  16197. *
  16198. * LDX (input) INTEGER
  16199. * The leading dimension of the array X. LDX >= max(1,N).
  16200. *
  16201. * RCOND (output) DOUBLE PRECISION
  16202. * The estimate of the reciprocal condition number of the matrix
  16203. * A after equilibration (if done). If RCOND is less than the
  16204. * machine precision (in particular, if RCOND = 0), the matrix
  16205. * is singular to working precision. This condition is
  16206. * indicated by a return code of INFO > 0.
  16207. *
  16208. * FERR (output) DOUBLE PRECISION array, dimension (NRHS)
  16209. * The estimated forward error bound for each solution vector
  16210. * X(j) (the j-th column of the solution matrix X).
  16211. * If XTRUE is the true solution corresponding to X(j), FERR(j)
  16212. * is an estimated upper bound for the magnitude of the largest
  16213. * element in (X(j) - XTRUE) divided by the magnitude of the
  16214. * largest element in X(j). The estimate is as reliable as
  16215. * the estimate for RCOND, and is almost always a slight
  16216. * overestimate of the true error.
  16217. *
  16218. * BERR (output) DOUBLE PRECISION array, dimension (NRHS)
  16219. * The componentwise relative backward error of each solution
  16220. * vector X(j) (i.e., the smallest relative change in
  16221. * any element of A or B that makes X(j) an exact solution).
  16222. *
  16223. * WORK (workspace) DOUBLE PRECISION array, dimension (3*N)
  16224. *
  16225. * IWORK (workspace) INTEGER array, dimension (N)
  16226. *
  16227. * INFO (output) INTEGER
  16228. * = 0: successful exit
  16229. * < 0: if INFO = -i, the i-th argument had an illegal value
  16230. * > 0: if INFO = i, and i is
  16231. * <= N: the leading minor of order i of A is
  16232. * not positive definite, so the factorization
  16233. * could not be completed, and the solution has not
  16234. * been computed. RCOND = 0 is returned.
  16235. * = N+1: U is nonsingular, but RCOND is less than machine
  16236. * precision, meaning that the matrix is singular
  16237. * to working precision. Nevertheless, the
  16238. * solution and error bounds are computed because
  16239. * there are a number of situations where the
  16240. * computed solution can be more accurate than the
  16241. * value of RCOND would suggest.
  16242. *
  16243. * Further Details
  16244. * ===============
  16245. *
  16246. * The packed storage scheme is illustrated by the following example
  16247. * when N = 4, UPLO = 'U':
  16248. *
  16249. * Two-dimensional storage of the symmetric matrix A:
  16250. *
  16251. * a11 a12 a13 a14
  16252. * a22 a23 a24
  16253. * a33 a34 (aij = conjg(aji))
  16254. * a44
  16255. *
  16256. * Packed storage of the upper triangle of A:
  16257. *
  16258. * AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]
  16259. *
  16260. * =====================================================================
  16261. *
  16262. * .. Parameters ..
  16263. DOUBLE PRECISION ZERO, ONE
  16264. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  16265. * ..
  16266. * .. Local Scalars ..
  16267. LOGICAL EQUIL, NOFACT, RCEQU
  16268. INTEGER I, INFEQU, J
  16269. DOUBLE PRECISION AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM
  16270. * ..
  16271. * .. External Functions ..
  16272. LOGICAL LSAME
  16273. DOUBLE PRECISION DLAMCH, DLANSP
  16274. EXTERNAL LSAME, DLAMCH, DLANSP
  16275. * ..
  16276. * .. External Subroutines ..
  16277. EXTERNAL DCOPY, DLACPY, DLAQSP, DPPCON, DPPEQU, DPPRFS,
  16278. $ DPPTRF, DPPTRS, XERBLA
  16279. * ..
  16280. * .. Intrinsic Functions ..
  16281. INTRINSIC MAX, MIN
  16282. * ..
  16283. * .. Executable Statements ..
  16284. *
  16285. INFO = 0
  16286. NOFACT = LSAME( FACT, 'N' )
  16287. EQUIL = LSAME( FACT, 'E' )
  16288. IF( NOFACT .OR. EQUIL ) THEN
  16289. EQUED = 'N'
  16290. RCEQU = .FALSE.
  16291. ELSE
  16292. RCEQU = LSAME( EQUED, 'Y' )
  16293. SMLNUM = DLAMCH( 'Safe minimum' )
  16294. BIGNUM = ONE / SMLNUM
  16295. END IF
  16296. *
  16297. * Test the input parameters.
  16298. *
  16299. IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )
  16300. $ THEN
  16301. INFO = -1
  16302. ELSE IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) )
  16303. $ THEN
  16304. INFO = -2
  16305. ELSE IF( N.LT.0 ) THEN
  16306. INFO = -3
  16307. ELSE IF( NRHS.LT.0 ) THEN
  16308. INFO = -4
  16309. ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.
  16310. $ ( RCEQU .OR. LSAME( EQUED, 'N' ) ) ) THEN
  16311. INFO = -7
  16312. ELSE
  16313. IF( RCEQU ) THEN
  16314. SMIN = BIGNUM
  16315. SMAX = ZERO
  16316. DO 10 J = 1, N
  16317. SMIN = MIN( SMIN, S( J ) )
  16318. SMAX = MAX( SMAX, S( J ) )
  16319. 10 CONTINUE
  16320. IF( SMIN.LE.ZERO ) THEN
  16321. INFO = -8
  16322. ELSE IF( N.GT.0 ) THEN
  16323. SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )
  16324. ELSE
  16325. SCOND = ONE
  16326. END IF
  16327. END IF
  16328. IF( INFO.EQ.0 ) THEN
  16329. IF( LDB.LT.MAX( 1, N ) ) THEN
  16330. INFO = -10
  16331. ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
  16332. INFO = -12
  16333. END IF
  16334. END IF
  16335. END IF
  16336. *
  16337. IF( INFO.NE.0 ) THEN
  16338. CALL XERBLA( 'DPPSVX', -INFO )
  16339. RETURN
  16340. END IF
  16341. *
  16342. IF( EQUIL ) THEN
  16343. *
  16344. * Compute row and column scalings to equilibrate the matrix A.
  16345. *
  16346. CALL DPPEQU( UPLO, N, AP, S, SCOND, AMAX, INFEQU )
  16347. IF( INFEQU.EQ.0 ) THEN
  16348. *
  16349. * Equilibrate the matrix.
  16350. *
  16351. CALL DLAQSP( UPLO, N, AP, S, SCOND, AMAX, EQUED )
  16352. RCEQU = LSAME( EQUED, 'Y' )
  16353. END IF
  16354. END IF
  16355. *
  16356. * Scale the right-hand side.
  16357. *
  16358. IF( RCEQU ) THEN
  16359. DO 30 J = 1, NRHS
  16360. DO 20 I = 1, N
  16361. B( I, J ) = S( I )*B( I, J )
  16362. 20 CONTINUE
  16363. 30 CONTINUE
  16364. END IF
  16365. *
  16366. IF( NOFACT .OR. EQUIL ) THEN
  16367. *
  16368. * Compute the Cholesky factorization A = U'*U or A = L*L'.
  16369. *
  16370. CALL DCOPY( N*( N+1 ) / 2, AP, 1, AFP, 1 )
  16371. CALL DPPTRF( UPLO, N, AFP, INFO )
  16372. *
  16373. * Return if INFO is non-zero.
  16374. *
  16375. IF( INFO.GT.0 )THEN
  16376. RCOND = ZERO
  16377. RETURN
  16378. END IF
  16379. END IF
  16380. *
  16381. * Compute the norm of the matrix A.
  16382. *
  16383. ANORM = DLANSP( 'I', UPLO, N, AP, WORK )
  16384. *
  16385. * Compute the reciprocal of the condition number of A.
  16386. *
  16387. CALL DPPCON( UPLO, N, AFP, ANORM, RCOND, WORK, IWORK, INFO )
  16388. *
  16389. * Compute the solution matrix X.
  16390. *
  16391. CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
  16392. CALL DPPTRS( UPLO, N, NRHS, AFP, X, LDX, INFO )
  16393. *
  16394. * Use iterative refinement to improve the computed solution and
  16395. * compute error bounds and backward error estimates for it.
  16396. *
  16397. CALL DPPRFS( UPLO, N, NRHS, AP, AFP, B, LDB, X, LDX, FERR, BERR,
  16398. $ WORK, IWORK, INFO )
  16399. *
  16400. * Transform the solution matrix X to a solution of the original
  16401. * system.
  16402. *
  16403. IF( RCEQU ) THEN
  16404. DO 50 J = 1, NRHS
  16405. DO 40 I = 1, N
  16406. X( I, J ) = S( I )*X( I, J )
  16407. 40 CONTINUE
  16408. 50 CONTINUE
  16409. DO 60 J = 1, NRHS
  16410. FERR( J ) = FERR( J ) / SCOND
  16411. 60 CONTINUE
  16412. END IF
  16413. *
  16414. * Set INFO = N+1 if the matrix is singular to working precision.
  16415. *
  16416. IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
  16417. $ INFO = N + 1
  16418. *
  16419. RETURN
  16420. *
  16421. * End of DPPSVX
  16422. *
  16423. END
  16424. SUBROUTINE DSBEV( JOBZ, UPLO, N, KD, AB, LDAB, W, Z, LDZ, WORK,
  16425. $ INFO )
  16426. *
  16427. * -- LAPACK driver routine (version 3.1) --
  16428. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  16429. * November 2006
  16430. *
  16431. * .. Scalar Arguments ..
  16432. CHARACTER JOBZ, UPLO
  16433. INTEGER INFO, KD, LDAB, LDZ, N
  16434. * ..
  16435. * .. Array Arguments ..
  16436. DOUBLE PRECISION AB( LDAB, * ), W( * ), WORK( * ), Z( LDZ, * )
  16437. * ..
  16438. *
  16439. * Purpose
  16440. * =======
  16441. *
  16442. * DSBEV computes all the eigenvalues and, optionally, eigenvectors of
  16443. * a real symmetric band matrix A.
  16444. *
  16445. * Arguments
  16446. * =========
  16447. *
  16448. * JOBZ (input) CHARACTER*1
  16449. * = 'N': Compute eigenvalues only;
  16450. * = 'V': Compute eigenvalues and eigenvectors.
  16451. *
  16452. * UPLO (input) CHARACTER*1
  16453. * = 'U': Upper triangle of A is stored;
  16454. * = 'L': Lower triangle of A is stored.
  16455. *
  16456. * N (input) INTEGER
  16457. * The order of the matrix A. N >= 0.
  16458. *
  16459. * KD (input) INTEGER
  16460. * The number of superdiagonals of the matrix A if UPLO = 'U',
  16461. * or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  16462. *
  16463. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB, N)
  16464. * On entry, the upper or lower triangle of the symmetric band
  16465. * matrix A, stored in the first KD+1 rows of the array. The
  16466. * j-th column of A is stored in the j-th column of the array AB
  16467. * as follows:
  16468. * if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
  16469. * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).
  16470. *
  16471. * On exit, AB is overwritten by values generated during the
  16472. * reduction to tridiagonal form. If UPLO = 'U', the first
  16473. * superdiagonal and the diagonal of the tridiagonal matrix T
  16474. * are returned in rows KD and KD+1 of AB, and if UPLO = 'L',
  16475. * the diagonal and first subdiagonal of T are returned in the
  16476. * first two rows of AB.
  16477. *
  16478. * LDAB (input) INTEGER
  16479. * The leading dimension of the array AB. LDAB >= KD + 1.
  16480. *
  16481. * W (output) DOUBLE PRECISION array, dimension (N)
  16482. * If INFO = 0, the eigenvalues in ascending order.
  16483. *
  16484. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  16485. * If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal
  16486. * eigenvectors of the matrix A, with the i-th column of Z
  16487. * holding the eigenvector associated with W(i).
  16488. * If JOBZ = 'N', then Z is not referenced.
  16489. *
  16490. * LDZ (input) INTEGER
  16491. * The leading dimension of the array Z. LDZ >= 1, and if
  16492. * JOBZ = 'V', LDZ >= max(1,N).
  16493. *
  16494. * WORK (workspace) DOUBLE PRECISION array, dimension (max(1,3*N-2))
  16495. *
  16496. * INFO (output) INTEGER
  16497. * = 0: successful exit
  16498. * < 0: if INFO = -i, the i-th argument had an illegal value
  16499. * > 0: if INFO = i, the algorithm failed to converge; i
  16500. * off-diagonal elements of an intermediate tridiagonal
  16501. * form did not converge to zero.
  16502. *
  16503. * =====================================================================
  16504. *
  16505. * .. Parameters ..
  16506. DOUBLE PRECISION ZERO, ONE
  16507. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  16508. * ..
  16509. * .. Local Scalars ..
  16510. LOGICAL LOWER, WANTZ
  16511. INTEGER IINFO, IMAX, INDE, INDWRK, ISCALE
  16512. DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
  16513. $ SMLNUM
  16514. * ..
  16515. * .. External Functions ..
  16516. LOGICAL LSAME
  16517. DOUBLE PRECISION DLAMCH, DLANSB
  16518. EXTERNAL LSAME, DLAMCH, DLANSB
  16519. * ..
  16520. * .. External Subroutines ..
  16521. EXTERNAL DLASCL, DSBTRD, DSCAL, DSTEQR, DSTERF, XERBLA
  16522. * ..
  16523. * .. Intrinsic Functions ..
  16524. INTRINSIC SQRT
  16525. * ..
  16526. * .. Executable Statements ..
  16527. *
  16528. * Test the input parameters.
  16529. *
  16530. WANTZ = LSAME( JOBZ, 'V' )
  16531. LOWER = LSAME( UPLO, 'L' )
  16532. *
  16533. INFO = 0
  16534. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  16535. INFO = -1
  16536. ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
  16537. INFO = -2
  16538. ELSE IF( N.LT.0 ) THEN
  16539. INFO = -3
  16540. ELSE IF( KD.LT.0 ) THEN
  16541. INFO = -4
  16542. ELSE IF( LDAB.LT.KD+1 ) THEN
  16543. INFO = -6
  16544. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  16545. INFO = -9
  16546. END IF
  16547. *
  16548. IF( INFO.NE.0 ) THEN
  16549. CALL XERBLA( 'DSBEV ', -INFO )
  16550. RETURN
  16551. END IF
  16552. *
  16553. * Quick return if possible
  16554. *
  16555. IF( N.EQ.0 )
  16556. $ RETURN
  16557. *
  16558. IF( N.EQ.1 ) THEN
  16559. IF( LOWER ) THEN
  16560. W( 1 ) = AB( 1, 1 )
  16561. ELSE
  16562. W( 1 ) = AB( KD+1, 1 )
  16563. END IF
  16564. IF( WANTZ )
  16565. $ Z( 1, 1 ) = ONE
  16566. RETURN
  16567. END IF
  16568. *
  16569. * Get machine constants.
  16570. *
  16571. SAFMIN = DLAMCH( 'Safe minimum' )
  16572. EPS = DLAMCH( 'Precision' )
  16573. SMLNUM = SAFMIN / EPS
  16574. BIGNUM = ONE / SMLNUM
  16575. RMIN = SQRT( SMLNUM )
  16576. RMAX = SQRT( BIGNUM )
  16577. *
  16578. * Scale matrix to allowable range, if necessary.
  16579. *
  16580. ANRM = DLANSB( 'M', UPLO, N, KD, AB, LDAB, WORK )
  16581. ISCALE = 0
  16582. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  16583. ISCALE = 1
  16584. SIGMA = RMIN / ANRM
  16585. ELSE IF( ANRM.GT.RMAX ) THEN
  16586. ISCALE = 1
  16587. SIGMA = RMAX / ANRM
  16588. END IF
  16589. IF( ISCALE.EQ.1 ) THEN
  16590. IF( LOWER ) THEN
  16591. CALL DLASCL( 'B', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )
  16592. ELSE
  16593. CALL DLASCL( 'Q', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )
  16594. END IF
  16595. END IF
  16596. *
  16597. * Call DSBTRD to reduce symmetric band matrix to tridiagonal form.
  16598. *
  16599. INDE = 1
  16600. INDWRK = INDE + N
  16601. CALL DSBTRD( JOBZ, UPLO, N, KD, AB, LDAB, W, WORK( INDE ), Z, LDZ,
  16602. $ WORK( INDWRK ), IINFO )
  16603. *
  16604. * For eigenvalues only, call DSTERF. For eigenvectors, call SSTEQR.
  16605. *
  16606. IF( .NOT.WANTZ ) THEN
  16607. CALL DSTERF( N, W, WORK( INDE ), INFO )
  16608. ELSE
  16609. CALL DSTEQR( JOBZ, N, W, WORK( INDE ), Z, LDZ, WORK( INDWRK ),
  16610. $ INFO )
  16611. END IF
  16612. *
  16613. * If matrix was scaled, then rescale eigenvalues appropriately.
  16614. *
  16615. IF( ISCALE.EQ.1 ) THEN
  16616. IF( INFO.EQ.0 ) THEN
  16617. IMAX = N
  16618. ELSE
  16619. IMAX = INFO - 1
  16620. END IF
  16621. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  16622. END IF
  16623. *
  16624. RETURN
  16625. *
  16626. * End of DSBEV
  16627. *
  16628. END
  16629. SUBROUTINE DSBEVD( JOBZ, UPLO, N, KD, AB, LDAB, W, Z, LDZ, WORK,
  16630. $ LWORK, IWORK, LIWORK, INFO )
  16631. *
  16632. * -- LAPACK driver routine (version 3.1) --
  16633. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  16634. * November 2006
  16635. *
  16636. * .. Scalar Arguments ..
  16637. CHARACTER JOBZ, UPLO
  16638. INTEGER INFO, KD, LDAB, LDZ, LIWORK, LWORK, N
  16639. * ..
  16640. * .. Array Arguments ..
  16641. INTEGER IWORK( * )
  16642. DOUBLE PRECISION AB( LDAB, * ), W( * ), WORK( * ), Z( LDZ, * )
  16643. * ..
  16644. *
  16645. * Purpose
  16646. * =======
  16647. *
  16648. * DSBEVD computes all the eigenvalues and, optionally, eigenvectors of
  16649. * a real symmetric band matrix A. If eigenvectors are desired, it uses
  16650. * a divide and conquer algorithm.
  16651. *
  16652. * The divide and conquer algorithm makes very mild assumptions about
  16653. * floating point arithmetic. It will work on machines with a guard
  16654. * digit in add/subtract, or on those binary machines without guard
  16655. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  16656. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  16657. * without guard digits, but we know of none.
  16658. *
  16659. * Arguments
  16660. * =========
  16661. *
  16662. * JOBZ (input) CHARACTER*1
  16663. * = 'N': Compute eigenvalues only;
  16664. * = 'V': Compute eigenvalues and eigenvectors.
  16665. *
  16666. * UPLO (input) CHARACTER*1
  16667. * = 'U': Upper triangle of A is stored;
  16668. * = 'L': Lower triangle of A is stored.
  16669. *
  16670. * N (input) INTEGER
  16671. * The order of the matrix A. N >= 0.
  16672. *
  16673. * KD (input) INTEGER
  16674. * The number of superdiagonals of the matrix A if UPLO = 'U',
  16675. * or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  16676. *
  16677. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB, N)
  16678. * On entry, the upper or lower triangle of the symmetric band
  16679. * matrix A, stored in the first KD+1 rows of the array. The
  16680. * j-th column of A is stored in the j-th column of the array AB
  16681. * as follows:
  16682. * if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
  16683. * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).
  16684. *
  16685. * On exit, AB is overwritten by values generated during the
  16686. * reduction to tridiagonal form. If UPLO = 'U', the first
  16687. * superdiagonal and the diagonal of the tridiagonal matrix T
  16688. * are returned in rows KD and KD+1 of AB, and if UPLO = 'L',
  16689. * the diagonal and first subdiagonal of T are returned in the
  16690. * first two rows of AB.
  16691. *
  16692. * LDAB (input) INTEGER
  16693. * The leading dimension of the array AB. LDAB >= KD + 1.
  16694. *
  16695. * W (output) DOUBLE PRECISION array, dimension (N)
  16696. * If INFO = 0, the eigenvalues in ascending order.
  16697. *
  16698. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  16699. * If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal
  16700. * eigenvectors of the matrix A, with the i-th column of Z
  16701. * holding the eigenvector associated with W(i).
  16702. * If JOBZ = 'N', then Z is not referenced.
  16703. *
  16704. * LDZ (input) INTEGER
  16705. * The leading dimension of the array Z. LDZ >= 1, and if
  16706. * JOBZ = 'V', LDZ >= max(1,N).
  16707. *
  16708. * WORK (workspace/output) DOUBLE PRECISION array,
  16709. * dimension (LWORK)
  16710. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  16711. *
  16712. * LWORK (input) INTEGER
  16713. * The dimension of the array WORK.
  16714. * IF N <= 1, LWORK must be at least 1.
  16715. * If JOBZ = 'N' and N > 2, LWORK must be at least 2*N.
  16716. * If JOBZ = 'V' and N > 2, LWORK must be at least
  16717. * ( 1 + 5*N + 2*N**2 ).
  16718. *
  16719. * If LWORK = -1, then a workspace query is assumed; the routine
  16720. * only calculates the optimal sizes of the WORK and IWORK
  16721. * arrays, returns these values as the first entries of the WORK
  16722. * and IWORK arrays, and no error message related to LWORK or
  16723. * LIWORK is issued by XERBLA.
  16724. *
  16725. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  16726. * On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
  16727. *
  16728. * LIWORK (input) INTEGER
  16729. * The dimension of the array LIWORK.
  16730. * If JOBZ = 'N' or N <= 1, LIWORK must be at least 1.
  16731. * If JOBZ = 'V' and N > 2, LIWORK must be at least 3 + 5*N.
  16732. *
  16733. * If LIWORK = -1, then a workspace query is assumed; the
  16734. * routine only calculates the optimal sizes of the WORK and
  16735. * IWORK arrays, returns these values as the first entries of
  16736. * the WORK and IWORK arrays, and no error message related to
  16737. * LWORK or LIWORK is issued by XERBLA.
  16738. *
  16739. * INFO (output) INTEGER
  16740. * = 0: successful exit
  16741. * < 0: if INFO = -i, the i-th argument had an illegal value
  16742. * > 0: if INFO = i, the algorithm failed to converge; i
  16743. * off-diagonal elements of an intermediate tridiagonal
  16744. * form did not converge to zero.
  16745. *
  16746. * =====================================================================
  16747. *
  16748. * .. Parameters ..
  16749. DOUBLE PRECISION ZERO, ONE
  16750. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  16751. * ..
  16752. * .. Local Scalars ..
  16753. LOGICAL LOWER, LQUERY, WANTZ
  16754. INTEGER IINFO, INDE, INDWK2, INDWRK, ISCALE, LIWMIN,
  16755. $ LLWRK2, LWMIN
  16756. DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
  16757. $ SMLNUM
  16758. * ..
  16759. * .. External Functions ..
  16760. LOGICAL LSAME
  16761. DOUBLE PRECISION DLAMCH, DLANSB
  16762. EXTERNAL LSAME, DLAMCH, DLANSB
  16763. * ..
  16764. * .. External Subroutines ..
  16765. EXTERNAL DGEMM, DLACPY, DLASCL, DSBTRD, DSCAL, DSTEDC,
  16766. $ DSTERF, XERBLA
  16767. * ..
  16768. * .. Intrinsic Functions ..
  16769. INTRINSIC SQRT
  16770. * ..
  16771. * .. Executable Statements ..
  16772. *
  16773. * Test the input parameters.
  16774. *
  16775. WANTZ = LSAME( JOBZ, 'V' )
  16776. LOWER = LSAME( UPLO, 'L' )
  16777. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  16778. *
  16779. INFO = 0
  16780. IF( N.LE.1 ) THEN
  16781. LIWMIN = 1
  16782. LWMIN = 1
  16783. ELSE
  16784. IF( WANTZ ) THEN
  16785. LIWMIN = 3 + 5*N
  16786. LWMIN = 1 + 5*N + 2*N**2
  16787. ELSE
  16788. LIWMIN = 1
  16789. LWMIN = 2*N
  16790. END IF
  16791. END IF
  16792. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  16793. INFO = -1
  16794. ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
  16795. INFO = -2
  16796. ELSE IF( N.LT.0 ) THEN
  16797. INFO = -3
  16798. ELSE IF( KD.LT.0 ) THEN
  16799. INFO = -4
  16800. ELSE IF( LDAB.LT.KD+1 ) THEN
  16801. INFO = -6
  16802. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  16803. INFO = -9
  16804. END IF
  16805. *
  16806. IF( INFO.EQ.0 ) THEN
  16807. WORK( 1 ) = LWMIN
  16808. IWORK( 1 ) = LIWMIN
  16809. *
  16810. IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  16811. INFO = -11
  16812. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  16813. INFO = -13
  16814. END IF
  16815. END IF
  16816. *
  16817. IF( INFO.NE.0 ) THEN
  16818. CALL XERBLA( 'DSBEVD', -INFO )
  16819. RETURN
  16820. ELSE IF( LQUERY ) THEN
  16821. RETURN
  16822. END IF
  16823. *
  16824. * Quick return if possible
  16825. *
  16826. IF( N.EQ.0 )
  16827. $ RETURN
  16828. *
  16829. IF( N.EQ.1 ) THEN
  16830. W( 1 ) = AB( 1, 1 )
  16831. IF( WANTZ )
  16832. $ Z( 1, 1 ) = ONE
  16833. RETURN
  16834. END IF
  16835. *
  16836. * Get machine constants.
  16837. *
  16838. SAFMIN = DLAMCH( 'Safe minimum' )
  16839. EPS = DLAMCH( 'Precision' )
  16840. SMLNUM = SAFMIN / EPS
  16841. BIGNUM = ONE / SMLNUM
  16842. RMIN = SQRT( SMLNUM )
  16843. RMAX = SQRT( BIGNUM )
  16844. *
  16845. * Scale matrix to allowable range, if necessary.
  16846. *
  16847. ANRM = DLANSB( 'M', UPLO, N, KD, AB, LDAB, WORK )
  16848. ISCALE = 0
  16849. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  16850. ISCALE = 1
  16851. SIGMA = RMIN / ANRM
  16852. ELSE IF( ANRM.GT.RMAX ) THEN
  16853. ISCALE = 1
  16854. SIGMA = RMAX / ANRM
  16855. END IF
  16856. IF( ISCALE.EQ.1 ) THEN
  16857. IF( LOWER ) THEN
  16858. CALL DLASCL( 'B', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )
  16859. ELSE
  16860. CALL DLASCL( 'Q', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )
  16861. END IF
  16862. END IF
  16863. *
  16864. * Call DSBTRD to reduce symmetric band matrix to tridiagonal form.
  16865. *
  16866. INDE = 1
  16867. INDWRK = INDE + N
  16868. INDWK2 = INDWRK + N*N
  16869. LLWRK2 = LWORK - INDWK2 + 1
  16870. CALL DSBTRD( JOBZ, UPLO, N, KD, AB, LDAB, W, WORK( INDE ), Z, LDZ,
  16871. $ WORK( INDWRK ), IINFO )
  16872. *
  16873. * For eigenvalues only, call DSTERF. For eigenvectors, call SSTEDC.
  16874. *
  16875. IF( .NOT.WANTZ ) THEN
  16876. CALL DSTERF( N, W, WORK( INDE ), INFO )
  16877. ELSE
  16878. CALL DSTEDC( 'I', N, W, WORK( INDE ), WORK( INDWRK ), N,
  16879. $ WORK( INDWK2 ), LLWRK2, IWORK, LIWORK, INFO )
  16880. CALL DGEMM( 'N', 'N', N, N, N, ONE, Z, LDZ, WORK( INDWRK ), N,
  16881. $ ZERO, WORK( INDWK2 ), N )
  16882. CALL DLACPY( 'A', N, N, WORK( INDWK2 ), N, Z, LDZ )
  16883. END IF
  16884. *
  16885. * If matrix was scaled, then rescale eigenvalues appropriately.
  16886. *
  16887. IF( ISCALE.EQ.1 )
  16888. $ CALL DSCAL( N, ONE / SIGMA, W, 1 )
  16889. *
  16890. WORK( 1 ) = LWMIN
  16891. IWORK( 1 ) = LIWMIN
  16892. RETURN
  16893. *
  16894. * End of DSBEVD
  16895. *
  16896. END
  16897. SUBROUTINE DSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, VL,
  16898. $ VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,
  16899. $ IFAIL, INFO )
  16900. *
  16901. * -- LAPACK driver routine (version 3.1) --
  16902. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  16903. * November 2006
  16904. *
  16905. * .. Scalar Arguments ..
  16906. CHARACTER JOBZ, RANGE, UPLO
  16907. INTEGER IL, INFO, IU, KD, LDAB, LDQ, LDZ, M, N
  16908. DOUBLE PRECISION ABSTOL, VL, VU
  16909. * ..
  16910. * .. Array Arguments ..
  16911. INTEGER IFAIL( * ), IWORK( * )
  16912. DOUBLE PRECISION AB( LDAB, * ), Q( LDQ, * ), W( * ), WORK( * ),
  16913. $ Z( LDZ, * )
  16914. * ..
  16915. *
  16916. * Purpose
  16917. * =======
  16918. *
  16919. * DSBEVX computes selected eigenvalues and, optionally, eigenvectors
  16920. * of a real symmetric band matrix A. Eigenvalues and eigenvectors can
  16921. * be selected by specifying either a range of values or a range of
  16922. * indices for the desired eigenvalues.
  16923. *
  16924. * Arguments
  16925. * =========
  16926. *
  16927. * JOBZ (input) CHARACTER*1
  16928. * = 'N': Compute eigenvalues only;
  16929. * = 'V': Compute eigenvalues and eigenvectors.
  16930. *
  16931. * RANGE (input) CHARACTER*1
  16932. * = 'A': all eigenvalues will be found;
  16933. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  16934. * will be found;
  16935. * = 'I': the IL-th through IU-th eigenvalues will be found.
  16936. *
  16937. * UPLO (input) CHARACTER*1
  16938. * = 'U': Upper triangle of A is stored;
  16939. * = 'L': Lower triangle of A is stored.
  16940. *
  16941. * N (input) INTEGER
  16942. * The order of the matrix A. N >= 0.
  16943. *
  16944. * KD (input) INTEGER
  16945. * The number of superdiagonals of the matrix A if UPLO = 'U',
  16946. * or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  16947. *
  16948. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB, N)
  16949. * On entry, the upper or lower triangle of the symmetric band
  16950. * matrix A, stored in the first KD+1 rows of the array. The
  16951. * j-th column of A is stored in the j-th column of the array AB
  16952. * as follows:
  16953. * if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
  16954. * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).
  16955. *
  16956. * On exit, AB is overwritten by values generated during the
  16957. * reduction to tridiagonal form. If UPLO = 'U', the first
  16958. * superdiagonal and the diagonal of the tridiagonal matrix T
  16959. * are returned in rows KD and KD+1 of AB, and if UPLO = 'L',
  16960. * the diagonal and first subdiagonal of T are returned in the
  16961. * first two rows of AB.
  16962. *
  16963. * LDAB (input) INTEGER
  16964. * The leading dimension of the array AB. LDAB >= KD + 1.
  16965. *
  16966. * Q (output) DOUBLE PRECISION array, dimension (LDQ, N)
  16967. * If JOBZ = 'V', the N-by-N orthogonal matrix used in the
  16968. * reduction to tridiagonal form.
  16969. * If JOBZ = 'N', the array Q is not referenced.
  16970. *
  16971. * LDQ (input) INTEGER
  16972. * The leading dimension of the array Q. If JOBZ = 'V', then
  16973. * LDQ >= max(1,N).
  16974. *
  16975. * VL (input) DOUBLE PRECISION
  16976. * VU (input) DOUBLE PRECISION
  16977. * If RANGE='V', the lower and upper bounds of the interval to
  16978. * be searched for eigenvalues. VL < VU.
  16979. * Not referenced if RANGE = 'A' or 'I'.
  16980. *
  16981. * IL (input) INTEGER
  16982. * IU (input) INTEGER
  16983. * If RANGE='I', the indices (in ascending order) of the
  16984. * smallest and largest eigenvalues to be returned.
  16985. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  16986. * Not referenced if RANGE = 'A' or 'V'.
  16987. *
  16988. * ABSTOL (input) DOUBLE PRECISION
  16989. * The absolute error tolerance for the eigenvalues.
  16990. * An approximate eigenvalue is accepted as converged
  16991. * when it is determined to lie in an interval [a,b]
  16992. * of width less than or equal to
  16993. *
  16994. * ABSTOL + EPS * max( |a|,|b| ) ,
  16995. *
  16996. * where EPS is the machine precision. If ABSTOL is less than
  16997. * or equal to zero, then EPS*|T| will be used in its place,
  16998. * where |T| is the 1-norm of the tridiagonal matrix obtained
  16999. * by reducing AB to tridiagonal form.
  17000. *
  17001. * Eigenvalues will be computed most accurately when ABSTOL is
  17002. * set to twice the underflow threshold 2*DLAMCH('S'), not zero.
  17003. * If this routine returns with INFO>0, indicating that some
  17004. * eigenvectors did not converge, try setting ABSTOL to
  17005. * 2*DLAMCH('S').
  17006. *
  17007. * See "Computing Small Singular Values of Bidiagonal Matrices
  17008. * with Guaranteed High Relative Accuracy," by Demmel and
  17009. * Kahan, LAPACK Working Note #3.
  17010. *
  17011. * M (output) INTEGER
  17012. * The total number of eigenvalues found. 0 <= M <= N.
  17013. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  17014. *
  17015. * W (output) DOUBLE PRECISION array, dimension (N)
  17016. * The first M elements contain the selected eigenvalues in
  17017. * ascending order.
  17018. *
  17019. * Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M))
  17020. * If JOBZ = 'V', then if INFO = 0, the first M columns of Z
  17021. * contain the orthonormal eigenvectors of the matrix A
  17022. * corresponding to the selected eigenvalues, with the i-th
  17023. * column of Z holding the eigenvector associated with W(i).
  17024. * If an eigenvector fails to converge, then that column of Z
  17025. * contains the latest approximation to the eigenvector, and the
  17026. * index of the eigenvector is returned in IFAIL.
  17027. * If JOBZ = 'N', then Z is not referenced.
  17028. * Note: the user must ensure that at least max(1,M) columns are
  17029. * supplied in the array Z; if RANGE = 'V', the exact value of M
  17030. * is not known in advance and an upper bound must be used.
  17031. *
  17032. * LDZ (input) INTEGER
  17033. * The leading dimension of the array Z. LDZ >= 1, and if
  17034. * JOBZ = 'V', LDZ >= max(1,N).
  17035. *
  17036. * WORK (workspace) DOUBLE PRECISION array, dimension (7*N)
  17037. *
  17038. * IWORK (workspace) INTEGER array, dimension (5*N)
  17039. *
  17040. * IFAIL (output) INTEGER array, dimension (N)
  17041. * If JOBZ = 'V', then if INFO = 0, the first M elements of
  17042. * IFAIL are zero. If INFO > 0, then IFAIL contains the
  17043. * indices of the eigenvectors that failed to converge.
  17044. * If JOBZ = 'N', then IFAIL is not referenced.
  17045. *
  17046. * INFO (output) INTEGER
  17047. * = 0: successful exit.
  17048. * < 0: if INFO = -i, the i-th argument had an illegal value.
  17049. * > 0: if INFO = i, then i eigenvectors failed to converge.
  17050. * Their indices are stored in array IFAIL.
  17051. *
  17052. * =====================================================================
  17053. *
  17054. * .. Parameters ..
  17055. DOUBLE PRECISION ZERO, ONE
  17056. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  17057. * ..
  17058. * .. Local Scalars ..
  17059. LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZ
  17060. CHARACTER ORDER
  17061. INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,
  17062. $ INDISP, INDIWO, INDWRK, ISCALE, ITMP1, J, JJ,
  17063. $ NSPLIT
  17064. DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
  17065. $ SIGMA, SMLNUM, TMP1, VLL, VUU
  17066. * ..
  17067. * .. External Functions ..
  17068. LOGICAL LSAME
  17069. DOUBLE PRECISION DLAMCH, DLANSB
  17070. EXTERNAL LSAME, DLAMCH, DLANSB
  17071. * ..
  17072. * .. External Subroutines ..
  17073. EXTERNAL DCOPY, DGEMV, DLACPY, DLASCL, DSBTRD, DSCAL,
  17074. $ DSTEBZ, DSTEIN, DSTEQR, DSTERF, DSWAP, XERBLA
  17075. * ..
  17076. * .. Intrinsic Functions ..
  17077. INTRINSIC MAX, MIN, SQRT
  17078. * ..
  17079. * .. Executable Statements ..
  17080. *
  17081. * Test the input parameters.
  17082. *
  17083. WANTZ = LSAME( JOBZ, 'V' )
  17084. ALLEIG = LSAME( RANGE, 'A' )
  17085. VALEIG = LSAME( RANGE, 'V' )
  17086. INDEIG = LSAME( RANGE, 'I' )
  17087. LOWER = LSAME( UPLO, 'L' )
  17088. *
  17089. INFO = 0
  17090. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  17091. INFO = -1
  17092. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  17093. INFO = -2
  17094. ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
  17095. INFO = -3
  17096. ELSE IF( N.LT.0 ) THEN
  17097. INFO = -4
  17098. ELSE IF( KD.LT.0 ) THEN
  17099. INFO = -5
  17100. ELSE IF( LDAB.LT.KD+1 ) THEN
  17101. INFO = -7
  17102. ELSE IF( WANTZ .AND. LDQ.LT.MAX( 1, N ) ) THEN
  17103. INFO = -9
  17104. ELSE
  17105. IF( VALEIG ) THEN
  17106. IF( N.GT.0 .AND. VU.LE.VL )
  17107. $ INFO = -11
  17108. ELSE IF( INDEIG ) THEN
  17109. IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
  17110. INFO = -12
  17111. ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  17112. INFO = -13
  17113. END IF
  17114. END IF
  17115. END IF
  17116. IF( INFO.EQ.0 ) THEN
  17117. IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) )
  17118. $ INFO = -18
  17119. END IF
  17120. *
  17121. IF( INFO.NE.0 ) THEN
  17122. CALL XERBLA( 'DSBEVX', -INFO )
  17123. RETURN
  17124. END IF
  17125. *
  17126. * Quick return if possible
  17127. *
  17128. M = 0
  17129. IF( N.EQ.0 )
  17130. $ RETURN
  17131. *
  17132. IF( N.EQ.1 ) THEN
  17133. M = 1
  17134. IF( LOWER ) THEN
  17135. TMP1 = AB( 1, 1 )
  17136. ELSE
  17137. TMP1 = AB( KD+1, 1 )
  17138. END IF
  17139. IF( VALEIG ) THEN
  17140. IF( .NOT.( VL.LT.TMP1 .AND. VU.GE.TMP1 ) )
  17141. $ M = 0
  17142. END IF
  17143. IF( M.EQ.1 ) THEN
  17144. W( 1 ) = TMP1
  17145. IF( WANTZ )
  17146. $ Z( 1, 1 ) = ONE
  17147. END IF
  17148. RETURN
  17149. END IF
  17150. *
  17151. * Get machine constants.
  17152. *
  17153. SAFMIN = DLAMCH( 'Safe minimum' )
  17154. EPS = DLAMCH( 'Precision' )
  17155. SMLNUM = SAFMIN / EPS
  17156. BIGNUM = ONE / SMLNUM
  17157. RMIN = SQRT( SMLNUM )
  17158. RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )
  17159. *
  17160. * Scale matrix to allowable range, if necessary.
  17161. *
  17162. ISCALE = 0
  17163. ABSTLL = ABSTOL
  17164. IF( VALEIG ) THEN
  17165. VLL = VL
  17166. VUU = VU
  17167. ELSE
  17168. VLL = ZERO
  17169. VUU = ZERO
  17170. END IF
  17171. ANRM = DLANSB( 'M', UPLO, N, KD, AB, LDAB, WORK )
  17172. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  17173. ISCALE = 1
  17174. SIGMA = RMIN / ANRM
  17175. ELSE IF( ANRM.GT.RMAX ) THEN
  17176. ISCALE = 1
  17177. SIGMA = RMAX / ANRM
  17178. END IF
  17179. IF( ISCALE.EQ.1 ) THEN
  17180. IF( LOWER ) THEN
  17181. CALL DLASCL( 'B', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )
  17182. ELSE
  17183. CALL DLASCL( 'Q', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )
  17184. END IF
  17185. IF( ABSTOL.GT.0 )
  17186. $ ABSTLL = ABSTOL*SIGMA
  17187. IF( VALEIG ) THEN
  17188. VLL = VL*SIGMA
  17189. VUU = VU*SIGMA
  17190. END IF
  17191. END IF
  17192. *
  17193. * Call DSBTRD to reduce symmetric band matrix to tridiagonal form.
  17194. *
  17195. INDD = 1
  17196. INDE = INDD + N
  17197. INDWRK = INDE + N
  17198. CALL DSBTRD( JOBZ, UPLO, N, KD, AB, LDAB, WORK( INDD ),
  17199. $ WORK( INDE ), Q, LDQ, WORK( INDWRK ), IINFO )
  17200. *
  17201. * If all eigenvalues are desired and ABSTOL is less than or equal
  17202. * to zero, then call DSTERF or SSTEQR. If this fails for some
  17203. * eigenvalue, then try DSTEBZ.
  17204. *
  17205. TEST = .FALSE.
  17206. IF (INDEIG) THEN
  17207. IF (IL.EQ.1 .AND. IU.EQ.N) THEN
  17208. TEST = .TRUE.
  17209. END IF
  17210. END IF
  17211. IF ((ALLEIG .OR. TEST) .AND. (ABSTOL.LE.ZERO)) THEN
  17212. CALL DCOPY( N, WORK( INDD ), 1, W, 1 )
  17213. INDEE = INDWRK + 2*N
  17214. IF( .NOT.WANTZ ) THEN
  17215. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  17216. CALL DSTERF( N, W, WORK( INDEE ), INFO )
  17217. ELSE
  17218. CALL DLACPY( 'A', N, N, Q, LDQ, Z, LDZ )
  17219. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  17220. CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ,
  17221. $ WORK( INDWRK ), INFO )
  17222. IF( INFO.EQ.0 ) THEN
  17223. DO 10 I = 1, N
  17224. IFAIL( I ) = 0
  17225. 10 CONTINUE
  17226. END IF
  17227. END IF
  17228. IF( INFO.EQ.0 ) THEN
  17229. M = N
  17230. GO TO 30
  17231. END IF
  17232. INFO = 0
  17233. END IF
  17234. *
  17235. * Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN.
  17236. *
  17237. IF( WANTZ ) THEN
  17238. ORDER = 'B'
  17239. ELSE
  17240. ORDER = 'E'
  17241. END IF
  17242. INDIBL = 1
  17243. INDISP = INDIBL + N
  17244. INDIWO = INDISP + N
  17245. CALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,
  17246. $ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,
  17247. $ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ),
  17248. $ IWORK( INDIWO ), INFO )
  17249. *
  17250. IF( WANTZ ) THEN
  17251. CALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,
  17252. $ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,
  17253. $ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO )
  17254. *
  17255. * Apply orthogonal matrix used in reduction to tridiagonal
  17256. * form to eigenvectors returned by DSTEIN.
  17257. *
  17258. DO 20 J = 1, M
  17259. CALL DCOPY( N, Z( 1, J ), 1, WORK( 1 ), 1 )
  17260. CALL DGEMV( 'N', N, N, ONE, Q, LDQ, WORK, 1, ZERO,
  17261. $ Z( 1, J ), 1 )
  17262. 20 CONTINUE
  17263. END IF
  17264. *
  17265. * If matrix was scaled, then rescale eigenvalues appropriately.
  17266. *
  17267. 30 CONTINUE
  17268. IF( ISCALE.EQ.1 ) THEN
  17269. IF( INFO.EQ.0 ) THEN
  17270. IMAX = M
  17271. ELSE
  17272. IMAX = INFO - 1
  17273. END IF
  17274. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  17275. END IF
  17276. *
  17277. * If eigenvalues are not in order, then sort them, along with
  17278. * eigenvectors.
  17279. *
  17280. IF( WANTZ ) THEN
  17281. DO 50 J = 1, M - 1
  17282. I = 0
  17283. TMP1 = W( J )
  17284. DO 40 JJ = J + 1, M
  17285. IF( W( JJ ).LT.TMP1 ) THEN
  17286. I = JJ
  17287. TMP1 = W( JJ )
  17288. END IF
  17289. 40 CONTINUE
  17290. *
  17291. IF( I.NE.0 ) THEN
  17292. ITMP1 = IWORK( INDIBL+I-1 )
  17293. W( I ) = W( J )
  17294. IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )
  17295. W( J ) = TMP1
  17296. IWORK( INDIBL+J-1 ) = ITMP1
  17297. CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
  17298. IF( INFO.NE.0 ) THEN
  17299. ITMP1 = IFAIL( I )
  17300. IFAIL( I ) = IFAIL( J )
  17301. IFAIL( J ) = ITMP1
  17302. END IF
  17303. END IF
  17304. 50 CONTINUE
  17305. END IF
  17306. *
  17307. RETURN
  17308. *
  17309. * End of DSBEVX
  17310. *
  17311. END
  17312. SUBROUTINE DSBGV( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, W, Z,
  17313. $ LDZ, WORK, INFO )
  17314. *
  17315. * -- LAPACK driver routine (version 3.1) --
  17316. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  17317. * November 2006
  17318. *
  17319. * .. Scalar Arguments ..
  17320. CHARACTER JOBZ, UPLO
  17321. INTEGER INFO, KA, KB, LDAB, LDBB, LDZ, N
  17322. * ..
  17323. * .. Array Arguments ..
  17324. DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), W( * ),
  17325. $ WORK( * ), Z( LDZ, * )
  17326. * ..
  17327. *
  17328. * Purpose
  17329. * =======
  17330. *
  17331. * DSBGV computes all the eigenvalues, and optionally, the eigenvectors
  17332. * of a real generalized symmetric-definite banded eigenproblem, of
  17333. * the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric
  17334. * and banded, and B is also positive definite.
  17335. *
  17336. * Arguments
  17337. * =========
  17338. *
  17339. * JOBZ (input) CHARACTER*1
  17340. * = 'N': Compute eigenvalues only;
  17341. * = 'V': Compute eigenvalues and eigenvectors.
  17342. *
  17343. * UPLO (input) CHARACTER*1
  17344. * = 'U': Upper triangles of A and B are stored;
  17345. * = 'L': Lower triangles of A and B are stored.
  17346. *
  17347. * N (input) INTEGER
  17348. * The order of the matrices A and B. N >= 0.
  17349. *
  17350. * KA (input) INTEGER
  17351. * The number of superdiagonals of the matrix A if UPLO = 'U',
  17352. * or the number of subdiagonals if UPLO = 'L'. KA >= 0.
  17353. *
  17354. * KB (input) INTEGER
  17355. * The number of superdiagonals of the matrix B if UPLO = 'U',
  17356. * or the number of subdiagonals if UPLO = 'L'. KB >= 0.
  17357. *
  17358. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB, N)
  17359. * On entry, the upper or lower triangle of the symmetric band
  17360. * matrix A, stored in the first ka+1 rows of the array. The
  17361. * j-th column of A is stored in the j-th column of the array AB
  17362. * as follows:
  17363. * if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
  17364. * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).
  17365. *
  17366. * On exit, the contents of AB are destroyed.
  17367. *
  17368. * LDAB (input) INTEGER
  17369. * The leading dimension of the array AB. LDAB >= KA+1.
  17370. *
  17371. * BB (input/output) DOUBLE PRECISION array, dimension (LDBB, N)
  17372. * On entry, the upper or lower triangle of the symmetric band
  17373. * matrix B, stored in the first kb+1 rows of the array. The
  17374. * j-th column of B is stored in the j-th column of the array BB
  17375. * as follows:
  17376. * if UPLO = 'U', BB(kb+1+i-j,j) = B(i,j) for max(1,j-kb)<=i<=j;
  17377. * if UPLO = 'L', BB(1+i-j,j) = B(i,j) for j<=i<=min(n,j+kb).
  17378. *
  17379. * On exit, the factor S from the split Cholesky factorization
  17380. * B = S**T*S, as returned by DPBSTF.
  17381. *
  17382. * LDBB (input) INTEGER
  17383. * The leading dimension of the array BB. LDBB >= KB+1.
  17384. *
  17385. * W (output) DOUBLE PRECISION array, dimension (N)
  17386. * If INFO = 0, the eigenvalues in ascending order.
  17387. *
  17388. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  17389. * If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of
  17390. * eigenvectors, with the i-th column of Z holding the
  17391. * eigenvector associated with W(i). The eigenvectors are
  17392. * normalized so that Z**T*B*Z = I.
  17393. * If JOBZ = 'N', then Z is not referenced.
  17394. *
  17395. * LDZ (input) INTEGER
  17396. * The leading dimension of the array Z. LDZ >= 1, and if
  17397. * JOBZ = 'V', LDZ >= N.
  17398. *
  17399. * WORK (workspace) DOUBLE PRECISION array, dimension (3*N)
  17400. *
  17401. * INFO (output) INTEGER
  17402. * = 0: successful exit
  17403. * < 0: if INFO = -i, the i-th argument had an illegal value
  17404. * > 0: if INFO = i, and i is:
  17405. * <= N: the algorithm failed to converge:
  17406. * i off-diagonal elements of an intermediate
  17407. * tridiagonal form did not converge to zero;
  17408. * > N: if INFO = N + i, for 1 <= i <= N, then DPBSTF
  17409. * returned INFO = i: B is not positive definite.
  17410. * The factorization of B could not be completed and
  17411. * no eigenvalues or eigenvectors were computed.
  17412. *
  17413. * =====================================================================
  17414. *
  17415. * .. Local Scalars ..
  17416. LOGICAL UPPER, WANTZ
  17417. CHARACTER VECT
  17418. INTEGER IINFO, INDE, INDWRK
  17419. * ..
  17420. * .. External Functions ..
  17421. LOGICAL LSAME
  17422. EXTERNAL LSAME
  17423. * ..
  17424. * .. External Subroutines ..
  17425. EXTERNAL DPBSTF, DSBGST, DSBTRD, DSTEQR, DSTERF, XERBLA
  17426. * ..
  17427. * .. Executable Statements ..
  17428. *
  17429. * Test the input parameters.
  17430. *
  17431. WANTZ = LSAME( JOBZ, 'V' )
  17432. UPPER = LSAME( UPLO, 'U' )
  17433. *
  17434. INFO = 0
  17435. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  17436. INFO = -1
  17437. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  17438. INFO = -2
  17439. ELSE IF( N.LT.0 ) THEN
  17440. INFO = -3
  17441. ELSE IF( KA.LT.0 ) THEN
  17442. INFO = -4
  17443. ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN
  17444. INFO = -5
  17445. ELSE IF( LDAB.LT.KA+1 ) THEN
  17446. INFO = -7
  17447. ELSE IF( LDBB.LT.KB+1 ) THEN
  17448. INFO = -9
  17449. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  17450. INFO = -12
  17451. END IF
  17452. IF( INFO.NE.0 ) THEN
  17453. CALL XERBLA( 'DSBGV ', -INFO )
  17454. RETURN
  17455. END IF
  17456. *
  17457. * Quick return if possible
  17458. *
  17459. IF( N.EQ.0 )
  17460. $ RETURN
  17461. *
  17462. * Form a split Cholesky factorization of B.
  17463. *
  17464. CALL DPBSTF( UPLO, N, KB, BB, LDBB, INFO )
  17465. IF( INFO.NE.0 ) THEN
  17466. INFO = N + INFO
  17467. RETURN
  17468. END IF
  17469. *
  17470. * Transform problem to standard eigenvalue problem.
  17471. *
  17472. INDE = 1
  17473. INDWRK = INDE + N
  17474. CALL DSBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Z, LDZ,
  17475. $ WORK( INDWRK ), IINFO )
  17476. *
  17477. * Reduce to tridiagonal form.
  17478. *
  17479. IF( WANTZ ) THEN
  17480. VECT = 'U'
  17481. ELSE
  17482. VECT = 'N'
  17483. END IF
  17484. CALL DSBTRD( VECT, UPLO, N, KA, AB, LDAB, W, WORK( INDE ), Z, LDZ,
  17485. $ WORK( INDWRK ), IINFO )
  17486. *
  17487. * For eigenvalues only, call DSTERF. For eigenvectors, call SSTEQR.
  17488. *
  17489. IF( .NOT.WANTZ ) THEN
  17490. CALL DSTERF( N, W, WORK( INDE ), INFO )
  17491. ELSE
  17492. CALL DSTEQR( JOBZ, N, W, WORK( INDE ), Z, LDZ, WORK( INDWRK ),
  17493. $ INFO )
  17494. END IF
  17495. RETURN
  17496. *
  17497. * End of DSBGV
  17498. *
  17499. END
  17500. SUBROUTINE DSBGVD( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, W,
  17501. $ Z, LDZ, WORK, LWORK, IWORK, LIWORK, INFO )
  17502. *
  17503. * -- LAPACK driver routine (version 3.1) --
  17504. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  17505. * November 2006
  17506. *
  17507. * .. Scalar Arguments ..
  17508. CHARACTER JOBZ, UPLO
  17509. INTEGER INFO, KA, KB, LDAB, LDBB, LDZ, LIWORK, LWORK, N
  17510. * ..
  17511. * .. Array Arguments ..
  17512. INTEGER IWORK( * )
  17513. DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), W( * ),
  17514. $ WORK( * ), Z( LDZ, * )
  17515. * ..
  17516. *
  17517. * Purpose
  17518. * =======
  17519. *
  17520. * DSBGVD computes all the eigenvalues, and optionally, the eigenvectors
  17521. * of a real generalized symmetric-definite banded eigenproblem, of the
  17522. * form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric and
  17523. * banded, and B is also positive definite. If eigenvectors are
  17524. * desired, it uses a divide and conquer algorithm.
  17525. *
  17526. * The divide and conquer algorithm makes very mild assumptions about
  17527. * floating point arithmetic. It will work on machines with a guard
  17528. * digit in add/subtract, or on those binary machines without guard
  17529. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  17530. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  17531. * without guard digits, but we know of none.
  17532. *
  17533. * Arguments
  17534. * =========
  17535. *
  17536. * JOBZ (input) CHARACTER*1
  17537. * = 'N': Compute eigenvalues only;
  17538. * = 'V': Compute eigenvalues and eigenvectors.
  17539. *
  17540. * UPLO (input) CHARACTER*1
  17541. * = 'U': Upper triangles of A and B are stored;
  17542. * = 'L': Lower triangles of A and B are stored.
  17543. *
  17544. * N (input) INTEGER
  17545. * The order of the matrices A and B. N >= 0.
  17546. *
  17547. * KA (input) INTEGER
  17548. * The number of superdiagonals of the matrix A if UPLO = 'U',
  17549. * or the number of subdiagonals if UPLO = 'L'. KA >= 0.
  17550. *
  17551. * KB (input) INTEGER
  17552. * The number of superdiagonals of the matrix B if UPLO = 'U',
  17553. * or the number of subdiagonals if UPLO = 'L'. KB >= 0.
  17554. *
  17555. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB, N)
  17556. * On entry, the upper or lower triangle of the symmetric band
  17557. * matrix A, stored in the first ka+1 rows of the array. The
  17558. * j-th column of A is stored in the j-th column of the array AB
  17559. * as follows:
  17560. * if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
  17561. * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).
  17562. *
  17563. * On exit, the contents of AB are destroyed.
  17564. *
  17565. * LDAB (input) INTEGER
  17566. * The leading dimension of the array AB. LDAB >= KA+1.
  17567. *
  17568. * BB (input/output) DOUBLE PRECISION array, dimension (LDBB, N)
  17569. * On entry, the upper or lower triangle of the symmetric band
  17570. * matrix B, stored in the first kb+1 rows of the array. The
  17571. * j-th column of B is stored in the j-th column of the array BB
  17572. * as follows:
  17573. * if UPLO = 'U', BB(ka+1+i-j,j) = B(i,j) for max(1,j-kb)<=i<=j;
  17574. * if UPLO = 'L', BB(1+i-j,j) = B(i,j) for j<=i<=min(n,j+kb).
  17575. *
  17576. * On exit, the factor S from the split Cholesky factorization
  17577. * B = S**T*S, as returned by DPBSTF.
  17578. *
  17579. * LDBB (input) INTEGER
  17580. * The leading dimension of the array BB. LDBB >= KB+1.
  17581. *
  17582. * W (output) DOUBLE PRECISION array, dimension (N)
  17583. * If INFO = 0, the eigenvalues in ascending order.
  17584. *
  17585. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  17586. * If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of
  17587. * eigenvectors, with the i-th column of Z holding the
  17588. * eigenvector associated with W(i). The eigenvectors are
  17589. * normalized so Z**T*B*Z = I.
  17590. * If JOBZ = 'N', then Z is not referenced.
  17591. *
  17592. * LDZ (input) INTEGER
  17593. * The leading dimension of the array Z. LDZ >= 1, and if
  17594. * JOBZ = 'V', LDZ >= max(1,N).
  17595. *
  17596. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  17597. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  17598. *
  17599. * LWORK (input) INTEGER
  17600. * The dimension of the array WORK.
  17601. * If N <= 1, LWORK >= 1.
  17602. * If JOBZ = 'N' and N > 1, LWORK >= 3*N.
  17603. * If JOBZ = 'V' and N > 1, LWORK >= 1 + 5*N + 2*N**2.
  17604. *
  17605. * If LWORK = -1, then a workspace query is assumed; the routine
  17606. * only calculates the optimal sizes of the WORK and IWORK
  17607. * arrays, returns these values as the first entries of the WORK
  17608. * and IWORK arrays, and no error message related to LWORK or
  17609. * LIWORK is issued by XERBLA.
  17610. *
  17611. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  17612. * On exit, if LIWORK > 0, IWORK(1) returns the optimal LIWORK.
  17613. *
  17614. * LIWORK (input) INTEGER
  17615. * The dimension of the array IWORK.
  17616. * If JOBZ = 'N' or N <= 1, LIWORK >= 1.
  17617. * If JOBZ = 'V' and N > 1, LIWORK >= 3 + 5*N.
  17618. *
  17619. * If LIWORK = -1, then a workspace query is assumed; the
  17620. * routine only calculates the optimal sizes of the WORK and
  17621. * IWORK arrays, returns these values as the first entries of
  17622. * the WORK and IWORK arrays, and no error message related to
  17623. * LWORK or LIWORK is issued by XERBLA.
  17624. *
  17625. * INFO (output) INTEGER
  17626. * = 0: successful exit
  17627. * < 0: if INFO = -i, the i-th argument had an illegal value
  17628. * > 0: if INFO = i, and i is:
  17629. * <= N: the algorithm failed to converge:
  17630. * i off-diagonal elements of an intermediate
  17631. * tridiagonal form did not converge to zero;
  17632. * > N: if INFO = N + i, for 1 <= i <= N, then DPBSTF
  17633. * returned INFO = i: B is not positive definite.
  17634. * The factorization of B could not be completed and
  17635. * no eigenvalues or eigenvectors were computed.
  17636. *
  17637. * Further Details
  17638. * ===============
  17639. *
  17640. * Based on contributions by
  17641. * Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA
  17642. *
  17643. * =====================================================================
  17644. *
  17645. * .. Parameters ..
  17646. DOUBLE PRECISION ONE, ZERO
  17647. PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
  17648. * ..
  17649. * .. Local Scalars ..
  17650. LOGICAL LQUERY, UPPER, WANTZ
  17651. CHARACTER VECT
  17652. INTEGER IINFO, INDE, INDWK2, INDWRK, LIWMIN, LLWRK2,
  17653. $ LWMIN
  17654. * ..
  17655. * .. External Functions ..
  17656. LOGICAL LSAME
  17657. EXTERNAL LSAME
  17658. * ..
  17659. * .. External Subroutines ..
  17660. EXTERNAL DGEMM, DLACPY, DPBSTF, DSBGST, DSBTRD, DSTEDC,
  17661. $ DSTERF, XERBLA
  17662. * ..
  17663. * .. Executable Statements ..
  17664. *
  17665. * Test the input parameters.
  17666. *
  17667. WANTZ = LSAME( JOBZ, 'V' )
  17668. UPPER = LSAME( UPLO, 'U' )
  17669. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  17670. *
  17671. INFO = 0
  17672. IF( N.LE.1 ) THEN
  17673. LIWMIN = 1
  17674. LWMIN = 1
  17675. ELSE IF( WANTZ ) THEN
  17676. LIWMIN = 3 + 5*N
  17677. LWMIN = 1 + 5*N + 2*N**2
  17678. ELSE
  17679. LIWMIN = 1
  17680. LWMIN = 2*N
  17681. END IF
  17682. *
  17683. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  17684. INFO = -1
  17685. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  17686. INFO = -2
  17687. ELSE IF( N.LT.0 ) THEN
  17688. INFO = -3
  17689. ELSE IF( KA.LT.0 ) THEN
  17690. INFO = -4
  17691. ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN
  17692. INFO = -5
  17693. ELSE IF( LDAB.LT.KA+1 ) THEN
  17694. INFO = -7
  17695. ELSE IF( LDBB.LT.KB+1 ) THEN
  17696. INFO = -9
  17697. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  17698. INFO = -12
  17699. END IF
  17700. *
  17701. IF( INFO.EQ.0 ) THEN
  17702. WORK( 1 ) = LWMIN
  17703. IWORK( 1 ) = LIWMIN
  17704. *
  17705. IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  17706. INFO = -14
  17707. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  17708. INFO = -16
  17709. END IF
  17710. END IF
  17711. *
  17712. IF( INFO.NE.0 ) THEN
  17713. CALL XERBLA( 'DSBGVD', -INFO )
  17714. RETURN
  17715. ELSE IF( LQUERY ) THEN
  17716. RETURN
  17717. END IF
  17718. *
  17719. * Quick return if possible
  17720. *
  17721. IF( N.EQ.0 )
  17722. $ RETURN
  17723. *
  17724. * Form a split Cholesky factorization of B.
  17725. *
  17726. CALL DPBSTF( UPLO, N, KB, BB, LDBB, INFO )
  17727. IF( INFO.NE.0 ) THEN
  17728. INFO = N + INFO
  17729. RETURN
  17730. END IF
  17731. *
  17732. * Transform problem to standard eigenvalue problem.
  17733. *
  17734. INDE = 1
  17735. INDWRK = INDE + N
  17736. INDWK2 = INDWRK + N*N
  17737. LLWRK2 = LWORK - INDWK2 + 1
  17738. CALL DSBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Z, LDZ,
  17739. $ WORK( INDWRK ), IINFO )
  17740. *
  17741. * Reduce to tridiagonal form.
  17742. *
  17743. IF( WANTZ ) THEN
  17744. VECT = 'U'
  17745. ELSE
  17746. VECT = 'N'
  17747. END IF
  17748. CALL DSBTRD( VECT, UPLO, N, KA, AB, LDAB, W, WORK( INDE ), Z, LDZ,
  17749. $ WORK( INDWRK ), IINFO )
  17750. *
  17751. * For eigenvalues only, call DSTERF. For eigenvectors, call SSTEDC.
  17752. *
  17753. IF( .NOT.WANTZ ) THEN
  17754. CALL DSTERF( N, W, WORK( INDE ), INFO )
  17755. ELSE
  17756. CALL DSTEDC( 'I', N, W, WORK( INDE ), WORK( INDWRK ), N,
  17757. $ WORK( INDWK2 ), LLWRK2, IWORK, LIWORK, INFO )
  17758. CALL DGEMM( 'N', 'N', N, N, N, ONE, Z, LDZ, WORK( INDWRK ), N,
  17759. $ ZERO, WORK( INDWK2 ), N )
  17760. CALL DLACPY( 'A', N, N, WORK( INDWK2 ), N, Z, LDZ )
  17761. END IF
  17762. *
  17763. WORK( 1 ) = LWMIN
  17764. IWORK( 1 ) = LIWMIN
  17765. *
  17766. RETURN
  17767. *
  17768. * End of DSBGVD
  17769. *
  17770. END
  17771. SUBROUTINE DSBGVX( JOBZ, RANGE, UPLO, N, KA, KB, AB, LDAB, BB,
  17772. $ LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,
  17773. $ LDZ, WORK, IWORK, IFAIL, INFO )
  17774. *
  17775. * -- LAPACK driver routine (version 3.1) --
  17776. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  17777. * November 2006
  17778. *
  17779. * .. Scalar Arguments ..
  17780. CHARACTER JOBZ, RANGE, UPLO
  17781. INTEGER IL, INFO, IU, KA, KB, LDAB, LDBB, LDQ, LDZ, M,
  17782. $ N
  17783. DOUBLE PRECISION ABSTOL, VL, VU
  17784. * ..
  17785. * .. Array Arguments ..
  17786. INTEGER IFAIL( * ), IWORK( * )
  17787. DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), Q( LDQ, * ),
  17788. $ W( * ), WORK( * ), Z( LDZ, * )
  17789. * ..
  17790. *
  17791. * Purpose
  17792. * =======
  17793. *
  17794. * DSBGVX computes selected eigenvalues, and optionally, eigenvectors
  17795. * of a real generalized symmetric-definite banded eigenproblem, of
  17796. * the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric
  17797. * and banded, and B is also positive definite. Eigenvalues and
  17798. * eigenvectors can be selected by specifying either all eigenvalues,
  17799. * a range of values or a range of indices for the desired eigenvalues.
  17800. *
  17801. * Arguments
  17802. * =========
  17803. *
  17804. * JOBZ (input) CHARACTER*1
  17805. * = 'N': Compute eigenvalues only;
  17806. * = 'V': Compute eigenvalues and eigenvectors.
  17807. *
  17808. * RANGE (input) CHARACTER*1
  17809. * = 'A': all eigenvalues will be found.
  17810. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  17811. * will be found.
  17812. * = 'I': the IL-th through IU-th eigenvalues will be found.
  17813. *
  17814. * UPLO (input) CHARACTER*1
  17815. * = 'U': Upper triangles of A and B are stored;
  17816. * = 'L': Lower triangles of A and B are stored.
  17817. *
  17818. * N (input) INTEGER
  17819. * The order of the matrices A and B. N >= 0.
  17820. *
  17821. * KA (input) INTEGER
  17822. * The number of superdiagonals of the matrix A if UPLO = 'U',
  17823. * or the number of subdiagonals if UPLO = 'L'. KA >= 0.
  17824. *
  17825. * KB (input) INTEGER
  17826. * The number of superdiagonals of the matrix B if UPLO = 'U',
  17827. * or the number of subdiagonals if UPLO = 'L'. KB >= 0.
  17828. *
  17829. * AB (input/output) DOUBLE PRECISION array, dimension (LDAB, N)
  17830. * On entry, the upper or lower triangle of the symmetric band
  17831. * matrix A, stored in the first ka+1 rows of the array. The
  17832. * j-th column of A is stored in the j-th column of the array AB
  17833. * as follows:
  17834. * if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
  17835. * if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).
  17836. *
  17837. * On exit, the contents of AB are destroyed.
  17838. *
  17839. * LDAB (input) INTEGER
  17840. * The leading dimension of the array AB. LDAB >= KA+1.
  17841. *
  17842. * BB (input/output) DOUBLE PRECISION array, dimension (LDBB, N)
  17843. * On entry, the upper or lower triangle of the symmetric band
  17844. * matrix B, stored in the first kb+1 rows of the array. The
  17845. * j-th column of B is stored in the j-th column of the array BB
  17846. * as follows:
  17847. * if UPLO = 'U', BB(ka+1+i-j,j) = B(i,j) for max(1,j-kb)<=i<=j;
  17848. * if UPLO = 'L', BB(1+i-j,j) = B(i,j) for j<=i<=min(n,j+kb).
  17849. *
  17850. * On exit, the factor S from the split Cholesky factorization
  17851. * B = S**T*S, as returned by DPBSTF.
  17852. *
  17853. * LDBB (input) INTEGER
  17854. * The leading dimension of the array BB. LDBB >= KB+1.
  17855. *
  17856. * Q (output) DOUBLE PRECISION array, dimension (LDQ, N)
  17857. * If JOBZ = 'V', the n-by-n matrix used in the reduction of
  17858. * A*x = (lambda)*B*x to standard form, i.e. C*x = (lambda)*x,
  17859. * and consequently C to tridiagonal form.
  17860. * If JOBZ = 'N', the array Q is not referenced.
  17861. *
  17862. * LDQ (input) INTEGER
  17863. * The leading dimension of the array Q. If JOBZ = 'N',
  17864. * LDQ >= 1. If JOBZ = 'V', LDQ >= max(1,N).
  17865. *
  17866. * VL (input) DOUBLE PRECISION
  17867. * VU (input) DOUBLE PRECISION
  17868. * If RANGE='V', the lower and upper bounds of the interval to
  17869. * be searched for eigenvalues. VL < VU.
  17870. * Not referenced if RANGE = 'A' or 'I'.
  17871. *
  17872. * IL (input) INTEGER
  17873. * IU (input) INTEGER
  17874. * If RANGE='I', the indices (in ascending order) of the
  17875. * smallest and largest eigenvalues to be returned.
  17876. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  17877. * Not referenced if RANGE = 'A' or 'V'.
  17878. *
  17879. * ABSTOL (input) DOUBLE PRECISION
  17880. * The absolute error tolerance for the eigenvalues.
  17881. * An approximate eigenvalue is accepted as converged
  17882. * when it is determined to lie in an interval [a,b]
  17883. * of width less than or equal to
  17884. *
  17885. * ABSTOL + EPS * max( |a|,|b| ) ,
  17886. *
  17887. * where EPS is the machine precision. If ABSTOL is less than
  17888. * or equal to zero, then EPS*|T| will be used in its place,
  17889. * where |T| is the 1-norm of the tridiagonal matrix obtained
  17890. * by reducing A to tridiagonal form.
  17891. *
  17892. * Eigenvalues will be computed most accurately when ABSTOL is
  17893. * set to twice the underflow threshold 2*DLAMCH('S'), not zero.
  17894. * If this routine returns with INFO>0, indicating that some
  17895. * eigenvectors did not converge, try setting ABSTOL to
  17896. * 2*DLAMCH('S').
  17897. *
  17898. * M (output) INTEGER
  17899. * The total number of eigenvalues found. 0 <= M <= N.
  17900. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  17901. *
  17902. * W (output) DOUBLE PRECISION array, dimension (N)
  17903. * If INFO = 0, the eigenvalues in ascending order.
  17904. *
  17905. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  17906. * If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of
  17907. * eigenvectors, with the i-th column of Z holding the
  17908. * eigenvector associated with W(i). The eigenvectors are
  17909. * normalized so Z**T*B*Z = I.
  17910. * If JOBZ = 'N', then Z is not referenced.
  17911. *
  17912. * LDZ (input) INTEGER
  17913. * The leading dimension of the array Z. LDZ >= 1, and if
  17914. * JOBZ = 'V', LDZ >= max(1,N).
  17915. *
  17916. * WORK (workspace/output) DOUBLE PRECISION array, dimension (7*N)
  17917. *
  17918. * IWORK (workspace/output) INTEGER array, dimension (5*N)
  17919. *
  17920. * IFAIL (output) INTEGER array, dimension (M)
  17921. * If JOBZ = 'V', then if INFO = 0, the first M elements of
  17922. * IFAIL are zero. If INFO > 0, then IFAIL contains the
  17923. * indices of the eigenvalues that failed to converge.
  17924. * If JOBZ = 'N', then IFAIL is not referenced.
  17925. *
  17926. * INFO (output) INTEGER
  17927. * = 0 : successful exit
  17928. * < 0 : if INFO = -i, the i-th argument had an illegal value
  17929. * <= N: if INFO = i, then i eigenvectors failed to converge.
  17930. * Their indices are stored in IFAIL.
  17931. * > N : DPBSTF returned an error code; i.e.,
  17932. * if INFO = N + i, for 1 <= i <= N, then the leading
  17933. * minor of order i of B is not positive definite.
  17934. * The factorization of B could not be completed and
  17935. * no eigenvalues or eigenvectors were computed.
  17936. *
  17937. * Further Details
  17938. * ===============
  17939. *
  17940. * Based on contributions by
  17941. * Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA
  17942. *
  17943. * =====================================================================
  17944. *
  17945. * .. Parameters ..
  17946. DOUBLE PRECISION ZERO, ONE
  17947. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  17948. * ..
  17949. * .. Local Scalars ..
  17950. LOGICAL ALLEIG, INDEIG, TEST, UPPER, VALEIG, WANTZ
  17951. CHARACTER ORDER, VECT
  17952. INTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, INDISP,
  17953. $ INDIWO, INDWRK, ITMP1, J, JJ, NSPLIT
  17954. DOUBLE PRECISION TMP1
  17955. * ..
  17956. * .. External Functions ..
  17957. LOGICAL LSAME
  17958. EXTERNAL LSAME
  17959. * ..
  17960. * .. External Subroutines ..
  17961. EXTERNAL DCOPY, DGEMV, DLACPY, DPBSTF, DSBGST, DSBTRD,
  17962. $ DSTEBZ, DSTEIN, DSTEQR, DSTERF, DSWAP, XERBLA
  17963. * ..
  17964. * .. Intrinsic Functions ..
  17965. INTRINSIC MIN
  17966. * ..
  17967. * .. Executable Statements ..
  17968. *
  17969. * Test the input parameters.
  17970. *
  17971. WANTZ = LSAME( JOBZ, 'V' )
  17972. UPPER = LSAME( UPLO, 'U' )
  17973. ALLEIG = LSAME( RANGE, 'A' )
  17974. VALEIG = LSAME( RANGE, 'V' )
  17975. INDEIG = LSAME( RANGE, 'I' )
  17976. *
  17977. INFO = 0
  17978. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  17979. INFO = -1
  17980. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  17981. INFO = -2
  17982. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  17983. INFO = -3
  17984. ELSE IF( N.LT.0 ) THEN
  17985. INFO = -4
  17986. ELSE IF( KA.LT.0 ) THEN
  17987. INFO = -5
  17988. ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN
  17989. INFO = -6
  17990. ELSE IF( LDAB.LT.KA+1 ) THEN
  17991. INFO = -8
  17992. ELSE IF( LDBB.LT.KB+1 ) THEN
  17993. INFO = -10
  17994. ELSE IF( LDQ.LT.1 .OR. ( WANTZ .AND. LDQ.LT.N ) ) THEN
  17995. INFO = -12
  17996. ELSE
  17997. IF( VALEIG ) THEN
  17998. IF( N.GT.0 .AND. VU.LE.VL )
  17999. $ INFO = -14
  18000. ELSE IF( INDEIG ) THEN
  18001. IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
  18002. INFO = -15
  18003. ELSE IF ( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  18004. INFO = -16
  18005. END IF
  18006. END IF
  18007. END IF
  18008. IF( INFO.EQ.0) THEN
  18009. IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  18010. INFO = -21
  18011. END IF
  18012. END IF
  18013. *
  18014. IF( INFO.NE.0 ) THEN
  18015. CALL XERBLA( 'DSBGVX', -INFO )
  18016. RETURN
  18017. END IF
  18018. *
  18019. * Quick return if possible
  18020. *
  18021. M = 0
  18022. IF( N.EQ.0 )
  18023. $ RETURN
  18024. *
  18025. * Form a split Cholesky factorization of B.
  18026. *
  18027. CALL DPBSTF( UPLO, N, KB, BB, LDBB, INFO )
  18028. IF( INFO.NE.0 ) THEN
  18029. INFO = N + INFO
  18030. RETURN
  18031. END IF
  18032. *
  18033. * Transform problem to standard eigenvalue problem.
  18034. *
  18035. CALL DSBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Q, LDQ,
  18036. $ WORK, IINFO )
  18037. *
  18038. * Reduce symmetric band matrix to tridiagonal form.
  18039. *
  18040. INDD = 1
  18041. INDE = INDD + N
  18042. INDWRK = INDE + N
  18043. IF( WANTZ ) THEN
  18044. VECT = 'U'
  18045. ELSE
  18046. VECT = 'N'
  18047. END IF
  18048. CALL DSBTRD( VECT, UPLO, N, KA, AB, LDAB, WORK( INDD ),
  18049. $ WORK( INDE ), Q, LDQ, WORK( INDWRK ), IINFO )
  18050. *
  18051. * If all eigenvalues are desired and ABSTOL is less than or equal
  18052. * to zero, then call DSTERF or SSTEQR. If this fails for some
  18053. * eigenvalue, then try DSTEBZ.
  18054. *
  18055. TEST = .FALSE.
  18056. IF( INDEIG ) THEN
  18057. IF( IL.EQ.1 .AND. IU.EQ.N ) THEN
  18058. TEST = .TRUE.
  18059. END IF
  18060. END IF
  18061. IF( ( ALLEIG .OR. TEST ) .AND. ( ABSTOL.LE.ZERO ) ) THEN
  18062. CALL DCOPY( N, WORK( INDD ), 1, W, 1 )
  18063. INDEE = INDWRK + 2*N
  18064. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  18065. IF( .NOT.WANTZ ) THEN
  18066. CALL DSTERF( N, W, WORK( INDEE ), INFO )
  18067. ELSE
  18068. CALL DLACPY( 'A', N, N, Q, LDQ, Z, LDZ )
  18069. CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ,
  18070. $ WORK( INDWRK ), INFO )
  18071. IF( INFO.EQ.0 ) THEN
  18072. DO 10 I = 1, N
  18073. IFAIL( I ) = 0
  18074. 10 CONTINUE
  18075. END IF
  18076. END IF
  18077. IF( INFO.EQ.0 ) THEN
  18078. M = N
  18079. GO TO 30
  18080. END IF
  18081. INFO = 0
  18082. END IF
  18083. *
  18084. * Otherwise, call DSTEBZ and, if eigenvectors are desired,
  18085. * call DSTEIN.
  18086. *
  18087. IF( WANTZ ) THEN
  18088. ORDER = 'B'
  18089. ELSE
  18090. ORDER = 'E'
  18091. END IF
  18092. INDIBL = 1
  18093. INDISP = INDIBL + N
  18094. INDIWO = INDISP + N
  18095. CALL DSTEBZ( RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL,
  18096. $ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,
  18097. $ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ),
  18098. $ IWORK( INDIWO ), INFO )
  18099. *
  18100. IF( WANTZ ) THEN
  18101. CALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,
  18102. $ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,
  18103. $ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO )
  18104. *
  18105. * Apply transformation matrix used in reduction to tridiagonal
  18106. * form to eigenvectors returned by DSTEIN.
  18107. *
  18108. DO 20 J = 1, M
  18109. CALL DCOPY( N, Z( 1, J ), 1, WORK( 1 ), 1 )
  18110. CALL DGEMV( 'N', N, N, ONE, Q, LDQ, WORK, 1, ZERO,
  18111. $ Z( 1, J ), 1 )
  18112. 20 CONTINUE
  18113. END IF
  18114. *
  18115. 30 CONTINUE
  18116. *
  18117. * If eigenvalues are not in order, then sort them, along with
  18118. * eigenvectors.
  18119. *
  18120. IF( WANTZ ) THEN
  18121. DO 50 J = 1, M - 1
  18122. I = 0
  18123. TMP1 = W( J )
  18124. DO 40 JJ = J + 1, M
  18125. IF( W( JJ ).LT.TMP1 ) THEN
  18126. I = JJ
  18127. TMP1 = W( JJ )
  18128. END IF
  18129. 40 CONTINUE
  18130. *
  18131. IF( I.NE.0 ) THEN
  18132. ITMP1 = IWORK( INDIBL+I-1 )
  18133. W( I ) = W( J )
  18134. IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )
  18135. W( J ) = TMP1
  18136. IWORK( INDIBL+J-1 ) = ITMP1
  18137. CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
  18138. IF( INFO.NE.0 ) THEN
  18139. ITMP1 = IFAIL( I )
  18140. IFAIL( I ) = IFAIL( J )
  18141. IFAIL( J ) = ITMP1
  18142. END IF
  18143. END IF
  18144. 50 CONTINUE
  18145. END IF
  18146. *
  18147. RETURN
  18148. *
  18149. * End of DSBGVX
  18150. *
  18151. END
  18152. SUBROUTINE DSPEV( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, INFO )
  18153. *
  18154. * -- LAPACK driver routine (version 3.1) --
  18155. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  18156. * November 2006
  18157. *
  18158. * .. Scalar Arguments ..
  18159. CHARACTER JOBZ, UPLO
  18160. INTEGER INFO, LDZ, N
  18161. * ..
  18162. * .. Array Arguments ..
  18163. DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )
  18164. * ..
  18165. *
  18166. * Purpose
  18167. * =======
  18168. *
  18169. * DSPEV computes all the eigenvalues and, optionally, eigenvectors of a
  18170. * real symmetric matrix A in packed storage.
  18171. *
  18172. * Arguments
  18173. * =========
  18174. *
  18175. * JOBZ (input) CHARACTER*1
  18176. * = 'N': Compute eigenvalues only;
  18177. * = 'V': Compute eigenvalues and eigenvectors.
  18178. *
  18179. * UPLO (input) CHARACTER*1
  18180. * = 'U': Upper triangle of A is stored;
  18181. * = 'L': Lower triangle of A is stored.
  18182. *
  18183. * N (input) INTEGER
  18184. * The order of the matrix A. N >= 0.
  18185. *
  18186. * AP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  18187. * On entry, the upper or lower triangle of the symmetric matrix
  18188. * A, packed columnwise in a linear array. The j-th column of A
  18189. * is stored in the array AP as follows:
  18190. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  18191. * if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
  18192. *
  18193. * On exit, AP is overwritten by values generated during the
  18194. * reduction to tridiagonal form. If UPLO = 'U', the diagonal
  18195. * and first superdiagonal of the tridiagonal matrix T overwrite
  18196. * the corresponding elements of A, and if UPLO = 'L', the
  18197. * diagonal and first subdiagonal of T overwrite the
  18198. * corresponding elements of A.
  18199. *
  18200. * W (output) DOUBLE PRECISION array, dimension (N)
  18201. * If INFO = 0, the eigenvalues in ascending order.
  18202. *
  18203. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  18204. * If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal
  18205. * eigenvectors of the matrix A, with the i-th column of Z
  18206. * holding the eigenvector associated with W(i).
  18207. * If JOBZ = 'N', then Z is not referenced.
  18208. *
  18209. * LDZ (input) INTEGER
  18210. * The leading dimension of the array Z. LDZ >= 1, and if
  18211. * JOBZ = 'V', LDZ >= max(1,N).
  18212. *
  18213. * WORK (workspace) DOUBLE PRECISION array, dimension (3*N)
  18214. *
  18215. * INFO (output) INTEGER
  18216. * = 0: successful exit.
  18217. * < 0: if INFO = -i, the i-th argument had an illegal value.
  18218. * > 0: if INFO = i, the algorithm failed to converge; i
  18219. * off-diagonal elements of an intermediate tridiagonal
  18220. * form did not converge to zero.
  18221. *
  18222. * =====================================================================
  18223. *
  18224. * .. Parameters ..
  18225. DOUBLE PRECISION ZERO, ONE
  18226. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  18227. * ..
  18228. * .. Local Scalars ..
  18229. LOGICAL WANTZ
  18230. INTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE
  18231. DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
  18232. $ SMLNUM
  18233. * ..
  18234. * .. External Functions ..
  18235. LOGICAL LSAME
  18236. DOUBLE PRECISION DLAMCH, DLANSP
  18237. EXTERNAL LSAME, DLAMCH, DLANSP
  18238. * ..
  18239. * .. External Subroutines ..
  18240. EXTERNAL DOPGTR, DSCAL, DSPTRD, DSTEQR, DSTERF, XERBLA
  18241. * ..
  18242. * .. Intrinsic Functions ..
  18243. INTRINSIC SQRT
  18244. * ..
  18245. * .. Executable Statements ..
  18246. *
  18247. * Test the input parameters.
  18248. *
  18249. WANTZ = LSAME( JOBZ, 'V' )
  18250. *
  18251. INFO = 0
  18252. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  18253. INFO = -1
  18254. ELSE IF( .NOT.( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) )
  18255. $ THEN
  18256. INFO = -2
  18257. ELSE IF( N.LT.0 ) THEN
  18258. INFO = -3
  18259. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  18260. INFO = -7
  18261. END IF
  18262. *
  18263. IF( INFO.NE.0 ) THEN
  18264. CALL XERBLA( 'DSPEV ', -INFO )
  18265. RETURN
  18266. END IF
  18267. *
  18268. * Quick return if possible
  18269. *
  18270. IF( N.EQ.0 )
  18271. $ RETURN
  18272. *
  18273. IF( N.EQ.1 ) THEN
  18274. W( 1 ) = AP( 1 )
  18275. IF( WANTZ )
  18276. $ Z( 1, 1 ) = ONE
  18277. RETURN
  18278. END IF
  18279. *
  18280. * Get machine constants.
  18281. *
  18282. SAFMIN = DLAMCH( 'Safe minimum' )
  18283. EPS = DLAMCH( 'Precision' )
  18284. SMLNUM = SAFMIN / EPS
  18285. BIGNUM = ONE / SMLNUM
  18286. RMIN = SQRT( SMLNUM )
  18287. RMAX = SQRT( BIGNUM )
  18288. *
  18289. * Scale matrix to allowable range, if necessary.
  18290. *
  18291. ANRM = DLANSP( 'M', UPLO, N, AP, WORK )
  18292. ISCALE = 0
  18293. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  18294. ISCALE = 1
  18295. SIGMA = RMIN / ANRM
  18296. ELSE IF( ANRM.GT.RMAX ) THEN
  18297. ISCALE = 1
  18298. SIGMA = RMAX / ANRM
  18299. END IF
  18300. IF( ISCALE.EQ.1 ) THEN
  18301. CALL DSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 )
  18302. END IF
  18303. *
  18304. * Call DSPTRD to reduce symmetric packed matrix to tridiagonal form.
  18305. *
  18306. INDE = 1
  18307. INDTAU = INDE + N
  18308. CALL DSPTRD( UPLO, N, AP, W, WORK( INDE ), WORK( INDTAU ), IINFO )
  18309. *
  18310. * For eigenvalues only, call DSTERF. For eigenvectors, first call
  18311. * DOPGTR to generate the orthogonal matrix, then call DSTEQR.
  18312. *
  18313. IF( .NOT.WANTZ ) THEN
  18314. CALL DSTERF( N, W, WORK( INDE ), INFO )
  18315. ELSE
  18316. INDWRK = INDTAU + N
  18317. CALL DOPGTR( UPLO, N, AP, WORK( INDTAU ), Z, LDZ,
  18318. $ WORK( INDWRK ), IINFO )
  18319. CALL DSTEQR( JOBZ, N, W, WORK( INDE ), Z, LDZ, WORK( INDTAU ),
  18320. $ INFO )
  18321. END IF
  18322. *
  18323. * If matrix was scaled, then rescale eigenvalues appropriately.
  18324. *
  18325. IF( ISCALE.EQ.1 ) THEN
  18326. IF( INFO.EQ.0 ) THEN
  18327. IMAX = N
  18328. ELSE
  18329. IMAX = INFO - 1
  18330. END IF
  18331. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  18332. END IF
  18333. *
  18334. RETURN
  18335. *
  18336. * End of DSPEV
  18337. *
  18338. END
  18339. SUBROUTINE DSPEVD( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, LWORK,
  18340. $ IWORK, LIWORK, INFO )
  18341. *
  18342. * -- LAPACK driver routine (version 3.1) --
  18343. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  18344. * November 2006
  18345. *
  18346. * .. Scalar Arguments ..
  18347. CHARACTER JOBZ, UPLO
  18348. INTEGER INFO, LDZ, LIWORK, LWORK, N
  18349. * ..
  18350. * .. Array Arguments ..
  18351. INTEGER IWORK( * )
  18352. DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )
  18353. * ..
  18354. *
  18355. * Purpose
  18356. * =======
  18357. *
  18358. * DSPEVD computes all the eigenvalues and, optionally, eigenvectors
  18359. * of a real symmetric matrix A in packed storage. If eigenvectors are
  18360. * desired, it uses a divide and conquer algorithm.
  18361. *
  18362. * The divide and conquer algorithm makes very mild assumptions about
  18363. * floating point arithmetic. It will work on machines with a guard
  18364. * digit in add/subtract, or on those binary machines without guard
  18365. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  18366. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  18367. * without guard digits, but we know of none.
  18368. *
  18369. * Arguments
  18370. * =========
  18371. *
  18372. * JOBZ (input) CHARACTER*1
  18373. * = 'N': Compute eigenvalues only;
  18374. * = 'V': Compute eigenvalues and eigenvectors.
  18375. *
  18376. * UPLO (input) CHARACTER*1
  18377. * = 'U': Upper triangle of A is stored;
  18378. * = 'L': Lower triangle of A is stored.
  18379. *
  18380. * N (input) INTEGER
  18381. * The order of the matrix A. N >= 0.
  18382. *
  18383. * AP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  18384. * On entry, the upper or lower triangle of the symmetric matrix
  18385. * A, packed columnwise in a linear array. The j-th column of A
  18386. * is stored in the array AP as follows:
  18387. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  18388. * if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
  18389. *
  18390. * On exit, AP is overwritten by values generated during the
  18391. * reduction to tridiagonal form. If UPLO = 'U', the diagonal
  18392. * and first superdiagonal of the tridiagonal matrix T overwrite
  18393. * the corresponding elements of A, and if UPLO = 'L', the
  18394. * diagonal and first subdiagonal of T overwrite the
  18395. * corresponding elements of A.
  18396. *
  18397. * W (output) DOUBLE PRECISION array, dimension (N)
  18398. * If INFO = 0, the eigenvalues in ascending order.
  18399. *
  18400. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  18401. * If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal
  18402. * eigenvectors of the matrix A, with the i-th column of Z
  18403. * holding the eigenvector associated with W(i).
  18404. * If JOBZ = 'N', then Z is not referenced.
  18405. *
  18406. * LDZ (input) INTEGER
  18407. * The leading dimension of the array Z. LDZ >= 1, and if
  18408. * JOBZ = 'V', LDZ >= max(1,N).
  18409. *
  18410. * WORK (workspace/output) DOUBLE PRECISION array,
  18411. * dimension (LWORK)
  18412. * On exit, if INFO = 0, WORK(1) returns the required LWORK.
  18413. *
  18414. * LWORK (input) INTEGER
  18415. * The dimension of the array WORK.
  18416. * If N <= 1, LWORK must be at least 1.
  18417. * If JOBZ = 'N' and N > 1, LWORK must be at least 2*N.
  18418. * If JOBZ = 'V' and N > 1, LWORK must be at least
  18419. * 1 + 6*N + N**2.
  18420. *
  18421. * If LWORK = -1, then a workspace query is assumed; the routine
  18422. * only calculates the required sizes of the WORK and IWORK
  18423. * arrays, returns these values as the first entries of the WORK
  18424. * and IWORK arrays, and no error message related to LWORK or
  18425. * LIWORK is issued by XERBLA.
  18426. *
  18427. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  18428. * On exit, if INFO = 0, IWORK(1) returns the required LIWORK.
  18429. *
  18430. * LIWORK (input) INTEGER
  18431. * The dimension of the array IWORK.
  18432. * If JOBZ = 'N' or N <= 1, LIWORK must be at least 1.
  18433. * If JOBZ = 'V' and N > 1, LIWORK must be at least 3 + 5*N.
  18434. *
  18435. * If LIWORK = -1, then a workspace query is assumed; the
  18436. * routine only calculates the required sizes of the WORK and
  18437. * IWORK arrays, returns these values as the first entries of
  18438. * the WORK and IWORK arrays, and no error message related to
  18439. * LWORK or LIWORK is issued by XERBLA.
  18440. *
  18441. * INFO (output) INTEGER
  18442. * = 0: successful exit
  18443. * < 0: if INFO = -i, the i-th argument had an illegal value.
  18444. * > 0: if INFO = i, the algorithm failed to converge; i
  18445. * off-diagonal elements of an intermediate tridiagonal
  18446. * form did not converge to zero.
  18447. *
  18448. * =====================================================================
  18449. *
  18450. * .. Parameters ..
  18451. DOUBLE PRECISION ZERO, ONE
  18452. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  18453. * ..
  18454. * .. Local Scalars ..
  18455. LOGICAL LQUERY, WANTZ
  18456. INTEGER IINFO, INDE, INDTAU, INDWRK, ISCALE, LIWMIN,
  18457. $ LLWORK, LWMIN
  18458. DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
  18459. $ SMLNUM
  18460. * ..
  18461. * .. External Functions ..
  18462. LOGICAL LSAME
  18463. DOUBLE PRECISION DLAMCH, DLANSP
  18464. EXTERNAL LSAME, DLAMCH, DLANSP
  18465. * ..
  18466. * .. External Subroutines ..
  18467. EXTERNAL DOPMTR, DSCAL, DSPTRD, DSTEDC, DSTERF, XERBLA
  18468. * ..
  18469. * .. Intrinsic Functions ..
  18470. INTRINSIC SQRT
  18471. * ..
  18472. * .. Executable Statements ..
  18473. *
  18474. * Test the input parameters.
  18475. *
  18476. WANTZ = LSAME( JOBZ, 'V' )
  18477. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  18478. *
  18479. INFO = 0
  18480. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  18481. INFO = -1
  18482. ELSE IF( .NOT.( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) )
  18483. $ THEN
  18484. INFO = -2
  18485. ELSE IF( N.LT.0 ) THEN
  18486. INFO = -3
  18487. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  18488. INFO = -7
  18489. END IF
  18490. *
  18491. IF( INFO.EQ.0 ) THEN
  18492. IF( N.LE.1 ) THEN
  18493. LIWMIN = 1
  18494. LWMIN = 1
  18495. ELSE
  18496. IF( WANTZ ) THEN
  18497. LIWMIN = 3 + 5*N
  18498. LWMIN = 1 + 6*N + N**2
  18499. ELSE
  18500. LIWMIN = 1
  18501. LWMIN = 2*N
  18502. END IF
  18503. END IF
  18504. IWORK( 1 ) = LIWMIN
  18505. WORK( 1 ) = LWMIN
  18506. *
  18507. IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  18508. INFO = -9
  18509. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  18510. INFO = -11
  18511. END IF
  18512. END IF
  18513. *
  18514. IF( INFO.NE.0 ) THEN
  18515. CALL XERBLA( 'DSPEVD', -INFO )
  18516. RETURN
  18517. ELSE IF( LQUERY ) THEN
  18518. RETURN
  18519. END IF
  18520. *
  18521. * Quick return if possible
  18522. *
  18523. IF( N.EQ.0 )
  18524. $ RETURN
  18525. *
  18526. IF( N.EQ.1 ) THEN
  18527. W( 1 ) = AP( 1 )
  18528. IF( WANTZ )
  18529. $ Z( 1, 1 ) = ONE
  18530. RETURN
  18531. END IF
  18532. *
  18533. * Get machine constants.
  18534. *
  18535. SAFMIN = DLAMCH( 'Safe minimum' )
  18536. EPS = DLAMCH( 'Precision' )
  18537. SMLNUM = SAFMIN / EPS
  18538. BIGNUM = ONE / SMLNUM
  18539. RMIN = SQRT( SMLNUM )
  18540. RMAX = SQRT( BIGNUM )
  18541. *
  18542. * Scale matrix to allowable range, if necessary.
  18543. *
  18544. ANRM = DLANSP( 'M', UPLO, N, AP, WORK )
  18545. ISCALE = 0
  18546. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  18547. ISCALE = 1
  18548. SIGMA = RMIN / ANRM
  18549. ELSE IF( ANRM.GT.RMAX ) THEN
  18550. ISCALE = 1
  18551. SIGMA = RMAX / ANRM
  18552. END IF
  18553. IF( ISCALE.EQ.1 ) THEN
  18554. CALL DSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 )
  18555. END IF
  18556. *
  18557. * Call DSPTRD to reduce symmetric packed matrix to tridiagonal form.
  18558. *
  18559. INDE = 1
  18560. INDTAU = INDE + N
  18561. CALL DSPTRD( UPLO, N, AP, W, WORK( INDE ), WORK( INDTAU ), IINFO )
  18562. *
  18563. * For eigenvalues only, call DSTERF. For eigenvectors, first call
  18564. * DSTEDC to generate the eigenvector matrix, WORK(INDWRK), of the
  18565. * tridiagonal matrix, then call DOPMTR to multiply it by the
  18566. * Householder transformations represented in AP.
  18567. *
  18568. IF( .NOT.WANTZ ) THEN
  18569. CALL DSTERF( N, W, WORK( INDE ), INFO )
  18570. ELSE
  18571. INDWRK = INDTAU + N
  18572. LLWORK = LWORK - INDWRK + 1
  18573. CALL DSTEDC( 'I', N, W, WORK( INDE ), Z, LDZ, WORK( INDWRK ),
  18574. $ LLWORK, IWORK, LIWORK, INFO )
  18575. CALL DOPMTR( 'L', UPLO, 'N', N, N, AP, WORK( INDTAU ), Z, LDZ,
  18576. $ WORK( INDWRK ), IINFO )
  18577. END IF
  18578. *
  18579. * If matrix was scaled, then rescale eigenvalues appropriately.
  18580. *
  18581. IF( ISCALE.EQ.1 )
  18582. $ CALL DSCAL( N, ONE / SIGMA, W, 1 )
  18583. *
  18584. WORK( 1 ) = LWMIN
  18585. IWORK( 1 ) = LIWMIN
  18586. RETURN
  18587. *
  18588. * End of DSPEVD
  18589. *
  18590. END
  18591. SUBROUTINE DSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,
  18592. $ ABSTOL, M, W, Z, LDZ, WORK, IWORK, IFAIL,
  18593. $ INFO )
  18594. *
  18595. * -- LAPACK driver routine (version 3.1) --
  18596. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  18597. * November 2006
  18598. *
  18599. * .. Scalar Arguments ..
  18600. CHARACTER JOBZ, RANGE, UPLO
  18601. INTEGER IL, INFO, IU, LDZ, M, N
  18602. DOUBLE PRECISION ABSTOL, VL, VU
  18603. * ..
  18604. * .. Array Arguments ..
  18605. INTEGER IFAIL( * ), IWORK( * )
  18606. DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )
  18607. * ..
  18608. *
  18609. * Purpose
  18610. * =======
  18611. *
  18612. * DSPEVX computes selected eigenvalues and, optionally, eigenvectors
  18613. * of a real symmetric matrix A in packed storage. Eigenvalues/vectors
  18614. * can be selected by specifying either a range of values or a range of
  18615. * indices for the desired eigenvalues.
  18616. *
  18617. * Arguments
  18618. * =========
  18619. *
  18620. * JOBZ (input) CHARACTER*1
  18621. * = 'N': Compute eigenvalues only;
  18622. * = 'V': Compute eigenvalues and eigenvectors.
  18623. *
  18624. * RANGE (input) CHARACTER*1
  18625. * = 'A': all eigenvalues will be found;
  18626. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  18627. * will be found;
  18628. * = 'I': the IL-th through IU-th eigenvalues will be found.
  18629. *
  18630. * UPLO (input) CHARACTER*1
  18631. * = 'U': Upper triangle of A is stored;
  18632. * = 'L': Lower triangle of A is stored.
  18633. *
  18634. * N (input) INTEGER
  18635. * The order of the matrix A. N >= 0.
  18636. *
  18637. * AP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  18638. * On entry, the upper or lower triangle of the symmetric matrix
  18639. * A, packed columnwise in a linear array. The j-th column of A
  18640. * is stored in the array AP as follows:
  18641. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  18642. * if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
  18643. *
  18644. * On exit, AP is overwritten by values generated during the
  18645. * reduction to tridiagonal form. If UPLO = 'U', the diagonal
  18646. * and first superdiagonal of the tridiagonal matrix T overwrite
  18647. * the corresponding elements of A, and if UPLO = 'L', the
  18648. * diagonal and first subdiagonal of T overwrite the
  18649. * corresponding elements of A.
  18650. *
  18651. * VL (input) DOUBLE PRECISION
  18652. * VU (input) DOUBLE PRECISION
  18653. * If RANGE='V', the lower and upper bounds of the interval to
  18654. * be searched for eigenvalues. VL < VU.
  18655. * Not referenced if RANGE = 'A' or 'I'.
  18656. *
  18657. * IL (input) INTEGER
  18658. * IU (input) INTEGER
  18659. * If RANGE='I', the indices (in ascending order) of the
  18660. * smallest and largest eigenvalues to be returned.
  18661. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  18662. * Not referenced if RANGE = 'A' or 'V'.
  18663. *
  18664. * ABSTOL (input) DOUBLE PRECISION
  18665. * The absolute error tolerance for the eigenvalues.
  18666. * An approximate eigenvalue is accepted as converged
  18667. * when it is determined to lie in an interval [a,b]
  18668. * of width less than or equal to
  18669. *
  18670. * ABSTOL + EPS * max( |a|,|b| ) ,
  18671. *
  18672. * where EPS is the machine precision. If ABSTOL is less than
  18673. * or equal to zero, then EPS*|T| will be used in its place,
  18674. * where |T| is the 1-norm of the tridiagonal matrix obtained
  18675. * by reducing AP to tridiagonal form.
  18676. *
  18677. * Eigenvalues will be computed most accurately when ABSTOL is
  18678. * set to twice the underflow threshold 2*DLAMCH('S'), not zero.
  18679. * If this routine returns with INFO>0, indicating that some
  18680. * eigenvectors did not converge, try setting ABSTOL to
  18681. * 2*DLAMCH('S').
  18682. *
  18683. * See "Computing Small Singular Values of Bidiagonal Matrices
  18684. * with Guaranteed High Relative Accuracy," by Demmel and
  18685. * Kahan, LAPACK Working Note #3.
  18686. *
  18687. * M (output) INTEGER
  18688. * The total number of eigenvalues found. 0 <= M <= N.
  18689. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  18690. *
  18691. * W (output) DOUBLE PRECISION array, dimension (N)
  18692. * If INFO = 0, the selected eigenvalues in ascending order.
  18693. *
  18694. * Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M))
  18695. * If JOBZ = 'V', then if INFO = 0, the first M columns of Z
  18696. * contain the orthonormal eigenvectors of the matrix A
  18697. * corresponding to the selected eigenvalues, with the i-th
  18698. * column of Z holding the eigenvector associated with W(i).
  18699. * If an eigenvector fails to converge, then that column of Z
  18700. * contains the latest approximation to the eigenvector, and the
  18701. * index of the eigenvector is returned in IFAIL.
  18702. * If JOBZ = 'N', then Z is not referenced.
  18703. * Note: the user must ensure that at least max(1,M) columns are
  18704. * supplied in the array Z; if RANGE = 'V', the exact value of M
  18705. * is not known in advance and an upper bound must be used.
  18706. *
  18707. * LDZ (input) INTEGER
  18708. * The leading dimension of the array Z. LDZ >= 1, and if
  18709. * JOBZ = 'V', LDZ >= max(1,N).
  18710. *
  18711. * WORK (workspace) DOUBLE PRECISION array, dimension (8*N)
  18712. *
  18713. * IWORK (workspace) INTEGER array, dimension (5*N)
  18714. *
  18715. * IFAIL (output) INTEGER array, dimension (N)
  18716. * If JOBZ = 'V', then if INFO = 0, the first M elements of
  18717. * IFAIL are zero. If INFO > 0, then IFAIL contains the
  18718. * indices of the eigenvectors that failed to converge.
  18719. * If JOBZ = 'N', then IFAIL is not referenced.
  18720. *
  18721. * INFO (output) INTEGER
  18722. * = 0: successful exit
  18723. * < 0: if INFO = -i, the i-th argument had an illegal value
  18724. * > 0: if INFO = i, then i eigenvectors failed to converge.
  18725. * Their indices are stored in array IFAIL.
  18726. *
  18727. * =====================================================================
  18728. *
  18729. * .. Parameters ..
  18730. DOUBLE PRECISION ZERO, ONE
  18731. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  18732. * ..
  18733. * .. Local Scalars ..
  18734. LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ
  18735. CHARACTER ORDER
  18736. INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,
  18737. $ INDISP, INDIWO, INDTAU, INDWRK, ISCALE, ITMP1,
  18738. $ J, JJ, NSPLIT
  18739. DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
  18740. $ SIGMA, SMLNUM, TMP1, VLL, VUU
  18741. * ..
  18742. * .. External Functions ..
  18743. LOGICAL LSAME
  18744. DOUBLE PRECISION DLAMCH, DLANSP
  18745. EXTERNAL LSAME, DLAMCH, DLANSP
  18746. * ..
  18747. * .. External Subroutines ..
  18748. EXTERNAL DCOPY, DOPGTR, DOPMTR, DSCAL, DSPTRD, DSTEBZ,
  18749. $ DSTEIN, DSTEQR, DSTERF, DSWAP, XERBLA
  18750. * ..
  18751. * .. Intrinsic Functions ..
  18752. INTRINSIC MAX, MIN, SQRT
  18753. * ..
  18754. * .. Executable Statements ..
  18755. *
  18756. * Test the input parameters.
  18757. *
  18758. WANTZ = LSAME( JOBZ, 'V' )
  18759. ALLEIG = LSAME( RANGE, 'A' )
  18760. VALEIG = LSAME( RANGE, 'V' )
  18761. INDEIG = LSAME( RANGE, 'I' )
  18762. *
  18763. INFO = 0
  18764. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  18765. INFO = -1
  18766. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  18767. INFO = -2
  18768. ELSE IF( .NOT.( LSAME( UPLO, 'L' ) .OR. LSAME( UPLO, 'U' ) ) )
  18769. $ THEN
  18770. INFO = -3
  18771. ELSE IF( N.LT.0 ) THEN
  18772. INFO = -4
  18773. ELSE
  18774. IF( VALEIG ) THEN
  18775. IF( N.GT.0 .AND. VU.LE.VL )
  18776. $ INFO = -7
  18777. ELSE IF( INDEIG ) THEN
  18778. IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
  18779. INFO = -8
  18780. ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  18781. INFO = -9
  18782. END IF
  18783. END IF
  18784. END IF
  18785. IF( INFO.EQ.0 ) THEN
  18786. IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) )
  18787. $ INFO = -14
  18788. END IF
  18789. *
  18790. IF( INFO.NE.0 ) THEN
  18791. CALL XERBLA( 'DSPEVX', -INFO )
  18792. RETURN
  18793. END IF
  18794. *
  18795. * Quick return if possible
  18796. *
  18797. M = 0
  18798. IF( N.EQ.0 )
  18799. $ RETURN
  18800. *
  18801. IF( N.EQ.1 ) THEN
  18802. IF( ALLEIG .OR. INDEIG ) THEN
  18803. M = 1
  18804. W( 1 ) = AP( 1 )
  18805. ELSE
  18806. IF( VL.LT.AP( 1 ) .AND. VU.GE.AP( 1 ) ) THEN
  18807. M = 1
  18808. W( 1 ) = AP( 1 )
  18809. END IF
  18810. END IF
  18811. IF( WANTZ )
  18812. $ Z( 1, 1 ) = ONE
  18813. RETURN
  18814. END IF
  18815. *
  18816. * Get machine constants.
  18817. *
  18818. SAFMIN = DLAMCH( 'Safe minimum' )
  18819. EPS = DLAMCH( 'Precision' )
  18820. SMLNUM = SAFMIN / EPS
  18821. BIGNUM = ONE / SMLNUM
  18822. RMIN = SQRT( SMLNUM )
  18823. RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )
  18824. *
  18825. * Scale matrix to allowable range, if necessary.
  18826. *
  18827. ISCALE = 0
  18828. ABSTLL = ABSTOL
  18829. IF( VALEIG ) THEN
  18830. VLL = VL
  18831. VUU = VU
  18832. ELSE
  18833. VLL = ZERO
  18834. VUU = ZERO
  18835. END IF
  18836. ANRM = DLANSP( 'M', UPLO, N, AP, WORK )
  18837. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  18838. ISCALE = 1
  18839. SIGMA = RMIN / ANRM
  18840. ELSE IF( ANRM.GT.RMAX ) THEN
  18841. ISCALE = 1
  18842. SIGMA = RMAX / ANRM
  18843. END IF
  18844. IF( ISCALE.EQ.1 ) THEN
  18845. CALL DSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 )
  18846. IF( ABSTOL.GT.0 )
  18847. $ ABSTLL = ABSTOL*SIGMA
  18848. IF( VALEIG ) THEN
  18849. VLL = VL*SIGMA
  18850. VUU = VU*SIGMA
  18851. END IF
  18852. END IF
  18853. *
  18854. * Call DSPTRD to reduce symmetric packed matrix to tridiagonal form.
  18855. *
  18856. INDTAU = 1
  18857. INDE = INDTAU + N
  18858. INDD = INDE + N
  18859. INDWRK = INDD + N
  18860. CALL DSPTRD( UPLO, N, AP, WORK( INDD ), WORK( INDE ),
  18861. $ WORK( INDTAU ), IINFO )
  18862. *
  18863. * If all eigenvalues are desired and ABSTOL is less than or equal
  18864. * to zero, then call DSTERF or DOPGTR and SSTEQR. If this fails
  18865. * for some eigenvalue, then try DSTEBZ.
  18866. *
  18867. TEST = .FALSE.
  18868. IF (INDEIG) THEN
  18869. IF (IL.EQ.1 .AND. IU.EQ.N) THEN
  18870. TEST = .TRUE.
  18871. END IF
  18872. END IF
  18873. IF ((ALLEIG .OR. TEST) .AND. (ABSTOL.LE.ZERO)) THEN
  18874. CALL DCOPY( N, WORK( INDD ), 1, W, 1 )
  18875. INDEE = INDWRK + 2*N
  18876. IF( .NOT.WANTZ ) THEN
  18877. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  18878. CALL DSTERF( N, W, WORK( INDEE ), INFO )
  18879. ELSE
  18880. CALL DOPGTR( UPLO, N, AP, WORK( INDTAU ), Z, LDZ,
  18881. $ WORK( INDWRK ), IINFO )
  18882. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  18883. CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ,
  18884. $ WORK( INDWRK ), INFO )
  18885. IF( INFO.EQ.0 ) THEN
  18886. DO 10 I = 1, N
  18887. IFAIL( I ) = 0
  18888. 10 CONTINUE
  18889. END IF
  18890. END IF
  18891. IF( INFO.EQ.0 ) THEN
  18892. M = N
  18893. GO TO 20
  18894. END IF
  18895. INFO = 0
  18896. END IF
  18897. *
  18898. * Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN.
  18899. *
  18900. IF( WANTZ ) THEN
  18901. ORDER = 'B'
  18902. ELSE
  18903. ORDER = 'E'
  18904. END IF
  18905. INDIBL = 1
  18906. INDISP = INDIBL + N
  18907. INDIWO = INDISP + N
  18908. CALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,
  18909. $ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,
  18910. $ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ),
  18911. $ IWORK( INDIWO ), INFO )
  18912. *
  18913. IF( WANTZ ) THEN
  18914. CALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,
  18915. $ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,
  18916. $ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO )
  18917. *
  18918. * Apply orthogonal matrix used in reduction to tridiagonal
  18919. * form to eigenvectors returned by DSTEIN.
  18920. *
  18921. CALL DOPMTR( 'L', UPLO, 'N', N, M, AP, WORK( INDTAU ), Z, LDZ,
  18922. $ WORK( INDWRK ), INFO )
  18923. END IF
  18924. *
  18925. * If matrix was scaled, then rescale eigenvalues appropriately.
  18926. *
  18927. 20 CONTINUE
  18928. IF( ISCALE.EQ.1 ) THEN
  18929. IF( INFO.EQ.0 ) THEN
  18930. IMAX = M
  18931. ELSE
  18932. IMAX = INFO - 1
  18933. END IF
  18934. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  18935. END IF
  18936. *
  18937. * If eigenvalues are not in order, then sort them, along with
  18938. * eigenvectors.
  18939. *
  18940. IF( WANTZ ) THEN
  18941. DO 40 J = 1, M - 1
  18942. I = 0
  18943. TMP1 = W( J )
  18944. DO 30 JJ = J + 1, M
  18945. IF( W( JJ ).LT.TMP1 ) THEN
  18946. I = JJ
  18947. TMP1 = W( JJ )
  18948. END IF
  18949. 30 CONTINUE
  18950. *
  18951. IF( I.NE.0 ) THEN
  18952. ITMP1 = IWORK( INDIBL+I-1 )
  18953. W( I ) = W( J )
  18954. IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )
  18955. W( J ) = TMP1
  18956. IWORK( INDIBL+J-1 ) = ITMP1
  18957. CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
  18958. IF( INFO.NE.0 ) THEN
  18959. ITMP1 = IFAIL( I )
  18960. IFAIL( I ) = IFAIL( J )
  18961. IFAIL( J ) = ITMP1
  18962. END IF
  18963. END IF
  18964. 40 CONTINUE
  18965. END IF
  18966. *
  18967. RETURN
  18968. *
  18969. * End of DSPEVX
  18970. *
  18971. END
  18972. SUBROUTINE DSPGV( ITYPE, JOBZ, UPLO, N, AP, BP, W, Z, LDZ, WORK,
  18973. $ INFO )
  18974. *
  18975. * -- LAPACK driver routine (version 3.1) --
  18976. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  18977. * November 2006
  18978. *
  18979. * .. Scalar Arguments ..
  18980. CHARACTER JOBZ, UPLO
  18981. INTEGER INFO, ITYPE, LDZ, N
  18982. * ..
  18983. * .. Array Arguments ..
  18984. DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),
  18985. $ Z( LDZ, * )
  18986. * ..
  18987. *
  18988. * Purpose
  18989. * =======
  18990. *
  18991. * DSPGV computes all the eigenvalues and, optionally, the eigenvectors
  18992. * of a real generalized symmetric-definite eigenproblem, of the form
  18993. * A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x.
  18994. * Here A and B are assumed to be symmetric, stored in packed format,
  18995. * and B is also positive definite.
  18996. *
  18997. * Arguments
  18998. * =========
  18999. *
  19000. * ITYPE (input) INTEGER
  19001. * Specifies the problem type to be solved:
  19002. * = 1: A*x = (lambda)*B*x
  19003. * = 2: A*B*x = (lambda)*x
  19004. * = 3: B*A*x = (lambda)*x
  19005. *
  19006. * JOBZ (input) CHARACTER*1
  19007. * = 'N': Compute eigenvalues only;
  19008. * = 'V': Compute eigenvalues and eigenvectors.
  19009. *
  19010. * UPLO (input) CHARACTER*1
  19011. * = 'U': Upper triangles of A and B are stored;
  19012. * = 'L': Lower triangles of A and B are stored.
  19013. *
  19014. * N (input) INTEGER
  19015. * The order of the matrices A and B. N >= 0.
  19016. *
  19017. * AP (input/output) DOUBLE PRECISION array, dimension
  19018. * (N*(N+1)/2)
  19019. * On entry, the upper or lower triangle of the symmetric matrix
  19020. * A, packed columnwise in a linear array. The j-th column of A
  19021. * is stored in the array AP as follows:
  19022. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  19023. * if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
  19024. *
  19025. * On exit, the contents of AP are destroyed.
  19026. *
  19027. * BP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  19028. * On entry, the upper or lower triangle of the symmetric matrix
  19029. * B, packed columnwise in a linear array. The j-th column of B
  19030. * is stored in the array BP as follows:
  19031. * if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j;
  19032. * if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n.
  19033. *
  19034. * On exit, the triangular factor U or L from the Cholesky
  19035. * factorization B = U**T*U or B = L*L**T, in the same storage
  19036. * format as B.
  19037. *
  19038. * W (output) DOUBLE PRECISION array, dimension (N)
  19039. * If INFO = 0, the eigenvalues in ascending order.
  19040. *
  19041. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  19042. * If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of
  19043. * eigenvectors. The eigenvectors are normalized as follows:
  19044. * if ITYPE = 1 or 2, Z**T*B*Z = I;
  19045. * if ITYPE = 3, Z**T*inv(B)*Z = I.
  19046. * If JOBZ = 'N', then Z is not referenced.
  19047. *
  19048. * LDZ (input) INTEGER
  19049. * The leading dimension of the array Z. LDZ >= 1, and if
  19050. * JOBZ = 'V', LDZ >= max(1,N).
  19051. *
  19052. * WORK (workspace) DOUBLE PRECISION array, dimension (3*N)
  19053. *
  19054. * INFO (output) INTEGER
  19055. * = 0: successful exit
  19056. * < 0: if INFO = -i, the i-th argument had an illegal value
  19057. * > 0: DPPTRF or DSPEV returned an error code:
  19058. * <= N: if INFO = i, DSPEV failed to converge;
  19059. * i off-diagonal elements of an intermediate
  19060. * tridiagonal form did not converge to zero.
  19061. * > N: if INFO = n + i, for 1 <= i <= n, then the leading
  19062. * minor of order i of B is not positive definite.
  19063. * The factorization of B could not be completed and
  19064. * no eigenvalues or eigenvectors were computed.
  19065. *
  19066. * =====================================================================
  19067. *
  19068. * .. Local Scalars ..
  19069. LOGICAL UPPER, WANTZ
  19070. CHARACTER TRANS
  19071. INTEGER J, NEIG
  19072. * ..
  19073. * .. External Functions ..
  19074. LOGICAL LSAME
  19075. EXTERNAL LSAME
  19076. * ..
  19077. * .. External Subroutines ..
  19078. EXTERNAL DPPTRF, DSPEV, DSPGST, DTPMV, DTPSV, XERBLA
  19079. * ..
  19080. * .. Executable Statements ..
  19081. *
  19082. * Test the input parameters.
  19083. *
  19084. WANTZ = LSAME( JOBZ, 'V' )
  19085. UPPER = LSAME( UPLO, 'U' )
  19086. *
  19087. INFO = 0
  19088. IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
  19089. INFO = -1
  19090. ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  19091. INFO = -2
  19092. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  19093. INFO = -3
  19094. ELSE IF( N.LT.0 ) THEN
  19095. INFO = -4
  19096. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  19097. INFO = -9
  19098. END IF
  19099. IF( INFO.NE.0 ) THEN
  19100. CALL XERBLA( 'DSPGV ', -INFO )
  19101. RETURN
  19102. END IF
  19103. *
  19104. * Quick return if possible
  19105. *
  19106. IF( N.EQ.0 )
  19107. $ RETURN
  19108. *
  19109. * Form a Cholesky factorization of B.
  19110. *
  19111. CALL DPPTRF( UPLO, N, BP, INFO )
  19112. IF( INFO.NE.0 ) THEN
  19113. INFO = N + INFO
  19114. RETURN
  19115. END IF
  19116. *
  19117. * Transform problem to standard eigenvalue problem and solve.
  19118. *
  19119. CALL DSPGST( ITYPE, UPLO, N, AP, BP, INFO )
  19120. CALL DSPEV( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, INFO )
  19121. *
  19122. IF( WANTZ ) THEN
  19123. *
  19124. * Backtransform eigenvectors to the original problem.
  19125. *
  19126. NEIG = N
  19127. IF( INFO.GT.0 )
  19128. $ NEIG = INFO - 1
  19129. IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
  19130. *
  19131. * For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
  19132. * backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
  19133. *
  19134. IF( UPPER ) THEN
  19135. TRANS = 'N'
  19136. ELSE
  19137. TRANS = 'T'
  19138. END IF
  19139. *
  19140. DO 10 J = 1, NEIG
  19141. CALL DTPSV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),
  19142. $ 1 )
  19143. 10 CONTINUE
  19144. *
  19145. ELSE IF( ITYPE.EQ.3 ) THEN
  19146. *
  19147. * For B*A*x=(lambda)*x;
  19148. * backtransform eigenvectors: x = L*y or U'*y
  19149. *
  19150. IF( UPPER ) THEN
  19151. TRANS = 'T'
  19152. ELSE
  19153. TRANS = 'N'
  19154. END IF
  19155. *
  19156. DO 20 J = 1, NEIG
  19157. CALL DTPMV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),
  19158. $ 1 )
  19159. 20 CONTINUE
  19160. END IF
  19161. END IF
  19162. RETURN
  19163. *
  19164. * End of DSPGV
  19165. *
  19166. END
  19167. SUBROUTINE DSPGVD( ITYPE, JOBZ, UPLO, N, AP, BP, W, Z, LDZ, WORK,
  19168. $ LWORK, IWORK, LIWORK, INFO )
  19169. *
  19170. * -- LAPACK driver routine (version 3.1) --
  19171. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  19172. * November 2006
  19173. *
  19174. * .. Scalar Arguments ..
  19175. CHARACTER JOBZ, UPLO
  19176. INTEGER INFO, ITYPE, LDZ, LIWORK, LWORK, N
  19177. * ..
  19178. * .. Array Arguments ..
  19179. INTEGER IWORK( * )
  19180. DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),
  19181. $ Z( LDZ, * )
  19182. * ..
  19183. *
  19184. * Purpose
  19185. * =======
  19186. *
  19187. * DSPGVD computes all the eigenvalues, and optionally, the eigenvectors
  19188. * of a real generalized symmetric-definite eigenproblem, of the form
  19189. * A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and
  19190. * B are assumed to be symmetric, stored in packed format, and B is also
  19191. * positive definite.
  19192. * If eigenvectors are desired, it uses a divide and conquer algorithm.
  19193. *
  19194. * The divide and conquer algorithm makes very mild assumptions about
  19195. * floating point arithmetic. It will work on machines with a guard
  19196. * digit in add/subtract, or on those binary machines without guard
  19197. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  19198. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  19199. * without guard digits, but we know of none.
  19200. *
  19201. * Arguments
  19202. * =========
  19203. *
  19204. * ITYPE (input) INTEGER
  19205. * Specifies the problem type to be solved:
  19206. * = 1: A*x = (lambda)*B*x
  19207. * = 2: A*B*x = (lambda)*x
  19208. * = 3: B*A*x = (lambda)*x
  19209. *
  19210. * JOBZ (input) CHARACTER*1
  19211. * = 'N': Compute eigenvalues only;
  19212. * = 'V': Compute eigenvalues and eigenvectors.
  19213. *
  19214. * UPLO (input) CHARACTER*1
  19215. * = 'U': Upper triangles of A and B are stored;
  19216. * = 'L': Lower triangles of A and B are stored.
  19217. *
  19218. * N (input) INTEGER
  19219. * The order of the matrices A and B. N >= 0.
  19220. *
  19221. * AP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  19222. * On entry, the upper or lower triangle of the symmetric matrix
  19223. * A, packed columnwise in a linear array. The j-th column of A
  19224. * is stored in the array AP as follows:
  19225. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  19226. * if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
  19227. *
  19228. * On exit, the contents of AP are destroyed.
  19229. *
  19230. * BP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  19231. * On entry, the upper or lower triangle of the symmetric matrix
  19232. * B, packed columnwise in a linear array. The j-th column of B
  19233. * is stored in the array BP as follows:
  19234. * if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j;
  19235. * if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n.
  19236. *
  19237. * On exit, the triangular factor U or L from the Cholesky
  19238. * factorization B = U**T*U or B = L*L**T, in the same storage
  19239. * format as B.
  19240. *
  19241. * W (output) DOUBLE PRECISION array, dimension (N)
  19242. * If INFO = 0, the eigenvalues in ascending order.
  19243. *
  19244. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  19245. * If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of
  19246. * eigenvectors. The eigenvectors are normalized as follows:
  19247. * if ITYPE = 1 or 2, Z**T*B*Z = I;
  19248. * if ITYPE = 3, Z**T*inv(B)*Z = I.
  19249. * If JOBZ = 'N', then Z is not referenced.
  19250. *
  19251. * LDZ (input) INTEGER
  19252. * The leading dimension of the array Z. LDZ >= 1, and if
  19253. * JOBZ = 'V', LDZ >= max(1,N).
  19254. *
  19255. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  19256. * On exit, if INFO = 0, WORK(1) returns the required LWORK.
  19257. *
  19258. * LWORK (input) INTEGER
  19259. * The dimension of the array WORK.
  19260. * If N <= 1, LWORK >= 1.
  19261. * If JOBZ = 'N' and N > 1, LWORK >= 2*N.
  19262. * If JOBZ = 'V' and N > 1, LWORK >= 1 + 6*N + 2*N**2.
  19263. *
  19264. * If LWORK = -1, then a workspace query is assumed; the routine
  19265. * only calculates the required sizes of the WORK and IWORK
  19266. * arrays, returns these values as the first entries of the WORK
  19267. * and IWORK arrays, and no error message related to LWORK or
  19268. * LIWORK is issued by XERBLA.
  19269. *
  19270. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  19271. * On exit, if INFO = 0, IWORK(1) returns the required LIWORK.
  19272. *
  19273. * LIWORK (input) INTEGER
  19274. * The dimension of the array IWORK.
  19275. * If JOBZ = 'N' or N <= 1, LIWORK >= 1.
  19276. * If JOBZ = 'V' and N > 1, LIWORK >= 3 + 5*N.
  19277. *
  19278. * If LIWORK = -1, then a workspace query is assumed; the
  19279. * routine only calculates the required sizes of the WORK and
  19280. * IWORK arrays, returns these values as the first entries of
  19281. * the WORK and IWORK arrays, and no error message related to
  19282. * LWORK or LIWORK is issued by XERBLA.
  19283. *
  19284. * INFO (output) INTEGER
  19285. * = 0: successful exit
  19286. * < 0: if INFO = -i, the i-th argument had an illegal value
  19287. * > 0: DPPTRF or DSPEVD returned an error code:
  19288. * <= N: if INFO = i, DSPEVD failed to converge;
  19289. * i off-diagonal elements of an intermediate
  19290. * tridiagonal form did not converge to zero;
  19291. * > N: if INFO = N + i, for 1 <= i <= N, then the leading
  19292. * minor of order i of B is not positive definite.
  19293. * The factorization of B could not be completed and
  19294. * no eigenvalues or eigenvectors were computed.
  19295. *
  19296. * Further Details
  19297. * ===============
  19298. *
  19299. * Based on contributions by
  19300. * Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA
  19301. *
  19302. * =====================================================================
  19303. *
  19304. * .. Parameters ..
  19305. DOUBLE PRECISION TWO
  19306. PARAMETER ( TWO = 2.0D+0 )
  19307. * ..
  19308. * .. Local Scalars ..
  19309. LOGICAL LQUERY, UPPER, WANTZ
  19310. CHARACTER TRANS
  19311. INTEGER J, LIWMIN, LWMIN, NEIG
  19312. * ..
  19313. * .. External Functions ..
  19314. LOGICAL LSAME
  19315. EXTERNAL LSAME
  19316. * ..
  19317. * .. External Subroutines ..
  19318. EXTERNAL DPPTRF, DSPEVD, DSPGST, DTPMV, DTPSV, XERBLA
  19319. * ..
  19320. * .. Intrinsic Functions ..
  19321. INTRINSIC DBLE, MAX
  19322. * ..
  19323. * .. Executable Statements ..
  19324. *
  19325. * Test the input parameters.
  19326. *
  19327. WANTZ = LSAME( JOBZ, 'V' )
  19328. UPPER = LSAME( UPLO, 'U' )
  19329. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  19330. *
  19331. INFO = 0
  19332. IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
  19333. INFO = -1
  19334. ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  19335. INFO = -2
  19336. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  19337. INFO = -3
  19338. ELSE IF( N.LT.0 ) THEN
  19339. INFO = -4
  19340. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  19341. INFO = -9
  19342. END IF
  19343. *
  19344. IF( INFO.EQ.0 ) THEN
  19345. IF( N.LE.1 ) THEN
  19346. LIWMIN = 1
  19347. LWMIN = 1
  19348. ELSE
  19349. IF( WANTZ ) THEN
  19350. LIWMIN = 3 + 5*N
  19351. LWMIN = 1 + 6*N + 2*N**2
  19352. ELSE
  19353. LIWMIN = 1
  19354. LWMIN = 2*N
  19355. END IF
  19356. END IF
  19357. WORK( 1 ) = LWMIN
  19358. IWORK( 1 ) = LIWMIN
  19359. *
  19360. IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  19361. INFO = -11
  19362. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  19363. INFO = -13
  19364. END IF
  19365. END IF
  19366. *
  19367. IF( INFO.NE.0 ) THEN
  19368. CALL XERBLA( 'DSPGVD', -INFO )
  19369. RETURN
  19370. ELSE IF( LQUERY ) THEN
  19371. RETURN
  19372. END IF
  19373. *
  19374. * Quick return if possible
  19375. *
  19376. IF( N.EQ.0 )
  19377. $ RETURN
  19378. *
  19379. * Form a Cholesky factorization of BP.
  19380. *
  19381. CALL DPPTRF( UPLO, N, BP, INFO )
  19382. IF( INFO.NE.0 ) THEN
  19383. INFO = N + INFO
  19384. RETURN
  19385. END IF
  19386. *
  19387. * Transform problem to standard eigenvalue problem and solve.
  19388. *
  19389. CALL DSPGST( ITYPE, UPLO, N, AP, BP, INFO )
  19390. CALL DSPEVD( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, LWORK, IWORK,
  19391. $ LIWORK, INFO )
  19392. LWMIN = MAX( DBLE( LWMIN ), DBLE( WORK( 1 ) ) )
  19393. LIWMIN = MAX( DBLE( LIWMIN ), DBLE( IWORK( 1 ) ) )
  19394. *
  19395. IF( WANTZ ) THEN
  19396. *
  19397. * Backtransform eigenvectors to the original problem.
  19398. *
  19399. NEIG = N
  19400. IF( INFO.GT.0 )
  19401. $ NEIG = INFO - 1
  19402. IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
  19403. *
  19404. * For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
  19405. * backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
  19406. *
  19407. IF( UPPER ) THEN
  19408. TRANS = 'N'
  19409. ELSE
  19410. TRANS = 'T'
  19411. END IF
  19412. *
  19413. DO 10 J = 1, NEIG
  19414. CALL DTPSV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),
  19415. $ 1 )
  19416. 10 CONTINUE
  19417. *
  19418. ELSE IF( ITYPE.EQ.3 ) THEN
  19419. *
  19420. * For B*A*x=(lambda)*x;
  19421. * backtransform eigenvectors: x = L*y or U'*y
  19422. *
  19423. IF( UPPER ) THEN
  19424. TRANS = 'T'
  19425. ELSE
  19426. TRANS = 'N'
  19427. END IF
  19428. *
  19429. DO 20 J = 1, NEIG
  19430. CALL DTPMV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),
  19431. $ 1 )
  19432. 20 CONTINUE
  19433. END IF
  19434. END IF
  19435. *
  19436. WORK( 1 ) = LWMIN
  19437. IWORK( 1 ) = LIWMIN
  19438. *
  19439. RETURN
  19440. *
  19441. * End of DSPGVD
  19442. *
  19443. END
  19444. SUBROUTINE DSPGVX( ITYPE, JOBZ, RANGE, UPLO, N, AP, BP, VL, VU,
  19445. $ IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,
  19446. $ IFAIL, INFO )
  19447. *
  19448. * -- LAPACK driver routine (version 3.1) --
  19449. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  19450. * November 2006
  19451. *
  19452. * .. Scalar Arguments ..
  19453. CHARACTER JOBZ, RANGE, UPLO
  19454. INTEGER IL, INFO, ITYPE, IU, LDZ, M, N
  19455. DOUBLE PRECISION ABSTOL, VL, VU
  19456. * ..
  19457. * .. Array Arguments ..
  19458. INTEGER IFAIL( * ), IWORK( * )
  19459. DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),
  19460. $ Z( LDZ, * )
  19461. * ..
  19462. *
  19463. * Purpose
  19464. * =======
  19465. *
  19466. * DSPGVX computes selected eigenvalues, and optionally, eigenvectors
  19467. * of a real generalized symmetric-definite eigenproblem, of the form
  19468. * A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A
  19469. * and B are assumed to be symmetric, stored in packed storage, and B
  19470. * is also positive definite. Eigenvalues and eigenvectors can be
  19471. * selected by specifying either a range of values or a range of indices
  19472. * for the desired eigenvalues.
  19473. *
  19474. * Arguments
  19475. * =========
  19476. *
  19477. * ITYPE (input) INTEGER
  19478. * Specifies the problem type to be solved:
  19479. * = 1: A*x = (lambda)*B*x
  19480. * = 2: A*B*x = (lambda)*x
  19481. * = 3: B*A*x = (lambda)*x
  19482. *
  19483. * JOBZ (input) CHARACTER*1
  19484. * = 'N': Compute eigenvalues only;
  19485. * = 'V': Compute eigenvalues and eigenvectors.
  19486. *
  19487. * RANGE (input) CHARACTER*1
  19488. * = 'A': all eigenvalues will be found.
  19489. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  19490. * will be found.
  19491. * = 'I': the IL-th through IU-th eigenvalues will be found.
  19492. *
  19493. * UPLO (input) CHARACTER*1
  19494. * = 'U': Upper triangle of A and B are stored;
  19495. * = 'L': Lower triangle of A and B are stored.
  19496. *
  19497. * N (input) INTEGER
  19498. * The order of the matrix pencil (A,B). N >= 0.
  19499. *
  19500. * AP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  19501. * On entry, the upper or lower triangle of the symmetric matrix
  19502. * A, packed columnwise in a linear array. The j-th column of A
  19503. * is stored in the array AP as follows:
  19504. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  19505. * if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
  19506. *
  19507. * On exit, the contents of AP are destroyed.
  19508. *
  19509. * BP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  19510. * On entry, the upper or lower triangle of the symmetric matrix
  19511. * B, packed columnwise in a linear array. The j-th column of B
  19512. * is stored in the array BP as follows:
  19513. * if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j;
  19514. * if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n.
  19515. *
  19516. * On exit, the triangular factor U or L from the Cholesky
  19517. * factorization B = U**T*U or B = L*L**T, in the same storage
  19518. * format as B.
  19519. *
  19520. * VL (input) DOUBLE PRECISION
  19521. * VU (input) DOUBLE PRECISION
  19522. * If RANGE='V', the lower and upper bounds of the interval to
  19523. * be searched for eigenvalues. VL < VU.
  19524. * Not referenced if RANGE = 'A' or 'I'.
  19525. *
  19526. * IL (input) INTEGER
  19527. * IU (input) INTEGER
  19528. * If RANGE='I', the indices (in ascending order) of the
  19529. * smallest and largest eigenvalues to be returned.
  19530. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  19531. * Not referenced if RANGE = 'A' or 'V'.
  19532. *
  19533. * ABSTOL (input) DOUBLE PRECISION
  19534. * The absolute error tolerance for the eigenvalues.
  19535. * An approximate eigenvalue is accepted as converged
  19536. * when it is determined to lie in an interval [a,b]
  19537. * of width less than or equal to
  19538. *
  19539. * ABSTOL + EPS * max( |a|,|b| ) ,
  19540. *
  19541. * where EPS is the machine precision. If ABSTOL is less than
  19542. * or equal to zero, then EPS*|T| will be used in its place,
  19543. * where |T| is the 1-norm of the tridiagonal matrix obtained
  19544. * by reducing A to tridiagonal form.
  19545. *
  19546. * Eigenvalues will be computed most accurately when ABSTOL is
  19547. * set to twice the underflow threshold 2*DLAMCH('S'), not zero.
  19548. * If this routine returns with INFO>0, indicating that some
  19549. * eigenvectors did not converge, try setting ABSTOL to
  19550. * 2*DLAMCH('S').
  19551. *
  19552. * M (output) INTEGER
  19553. * The total number of eigenvalues found. 0 <= M <= N.
  19554. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  19555. *
  19556. * W (output) DOUBLE PRECISION array, dimension (N)
  19557. * On normal exit, the first M elements contain the selected
  19558. * eigenvalues in ascending order.
  19559. *
  19560. * Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M))
  19561. * If JOBZ = 'N', then Z is not referenced.
  19562. * If JOBZ = 'V', then if INFO = 0, the first M columns of Z
  19563. * contain the orthonormal eigenvectors of the matrix A
  19564. * corresponding to the selected eigenvalues, with the i-th
  19565. * column of Z holding the eigenvector associated with W(i).
  19566. * The eigenvectors are normalized as follows:
  19567. * if ITYPE = 1 or 2, Z**T*B*Z = I;
  19568. * if ITYPE = 3, Z**T*inv(B)*Z = I.
  19569. *
  19570. * If an eigenvector fails to converge, then that column of Z
  19571. * contains the latest approximation to the eigenvector, and the
  19572. * index of the eigenvector is returned in IFAIL.
  19573. * Note: the user must ensure that at least max(1,M) columns are
  19574. * supplied in the array Z; if RANGE = 'V', the exact value of M
  19575. * is not known in advance and an upper bound must be used.
  19576. *
  19577. * LDZ (input) INTEGER
  19578. * The leading dimension of the array Z. LDZ >= 1, and if
  19579. * JOBZ = 'V', LDZ >= max(1,N).
  19580. *
  19581. * WORK (workspace) DOUBLE PRECISION array, dimension (8*N)
  19582. *
  19583. * IWORK (workspace) INTEGER array, dimension (5*N)
  19584. *
  19585. * IFAIL (output) INTEGER array, dimension (N)
  19586. * If JOBZ = 'V', then if INFO = 0, the first M elements of
  19587. * IFAIL are zero. If INFO > 0, then IFAIL contains the
  19588. * indices of the eigenvectors that failed to converge.
  19589. * If JOBZ = 'N', then IFAIL is not referenced.
  19590. *
  19591. * INFO (output) INTEGER
  19592. * = 0: successful exit
  19593. * < 0: if INFO = -i, the i-th argument had an illegal value
  19594. * > 0: DPPTRF or DSPEVX returned an error code:
  19595. * <= N: if INFO = i, DSPEVX failed to converge;
  19596. * i eigenvectors failed to converge. Their indices
  19597. * are stored in array IFAIL.
  19598. * > N: if INFO = N + i, for 1 <= i <= N, then the leading
  19599. * minor of order i of B is not positive definite.
  19600. * The factorization of B could not be completed and
  19601. * no eigenvalues or eigenvectors were computed.
  19602. *
  19603. * Further Details
  19604. * ===============
  19605. *
  19606. * Based on contributions by
  19607. * Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA
  19608. *
  19609. * =====================================================================
  19610. *
  19611. * .. Local Scalars ..
  19612. LOGICAL ALLEIG, INDEIG, UPPER, VALEIG, WANTZ
  19613. CHARACTER TRANS
  19614. INTEGER J
  19615. * ..
  19616. * .. External Functions ..
  19617. LOGICAL LSAME
  19618. EXTERNAL LSAME
  19619. * ..
  19620. * .. External Subroutines ..
  19621. EXTERNAL DPPTRF, DSPEVX, DSPGST, DTPMV, DTPSV, XERBLA
  19622. * ..
  19623. * .. Intrinsic Functions ..
  19624. INTRINSIC MIN
  19625. * ..
  19626. * .. Executable Statements ..
  19627. *
  19628. * Test the input parameters.
  19629. *
  19630. UPPER = LSAME( UPLO, 'U' )
  19631. WANTZ = LSAME( JOBZ, 'V' )
  19632. ALLEIG = LSAME( RANGE, 'A' )
  19633. VALEIG = LSAME( RANGE, 'V' )
  19634. INDEIG = LSAME( RANGE, 'I' )
  19635. *
  19636. INFO = 0
  19637. IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
  19638. INFO = -1
  19639. ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  19640. INFO = -2
  19641. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  19642. INFO = -3
  19643. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  19644. INFO = -4
  19645. ELSE IF( N.LT.0 ) THEN
  19646. INFO = -5
  19647. ELSE
  19648. IF( VALEIG ) THEN
  19649. IF( N.GT.0 .AND. VU.LE.VL ) THEN
  19650. INFO = -9
  19651. END IF
  19652. ELSE IF( INDEIG ) THEN
  19653. IF( IL.LT.1 ) THEN
  19654. INFO = -10
  19655. ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  19656. INFO = -11
  19657. END IF
  19658. END IF
  19659. END IF
  19660. IF( INFO.EQ.0 ) THEN
  19661. IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  19662. INFO = -16
  19663. END IF
  19664. END IF
  19665. *
  19666. IF( INFO.NE.0 ) THEN
  19667. CALL XERBLA( 'DSPGVX', -INFO )
  19668. RETURN
  19669. END IF
  19670. *
  19671. * Quick return if possible
  19672. *
  19673. M = 0
  19674. IF( N.EQ.0 )
  19675. $ RETURN
  19676. *
  19677. * Form a Cholesky factorization of B.
  19678. *
  19679. CALL DPPTRF( UPLO, N, BP, INFO )
  19680. IF( INFO.NE.0 ) THEN
  19681. INFO = N + INFO
  19682. RETURN
  19683. END IF
  19684. *
  19685. * Transform problem to standard eigenvalue problem and solve.
  19686. *
  19687. CALL DSPGST( ITYPE, UPLO, N, AP, BP, INFO )
  19688. CALL DSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, ABSTOL, M,
  19689. $ W, Z, LDZ, WORK, IWORK, IFAIL, INFO )
  19690. *
  19691. IF( WANTZ ) THEN
  19692. *
  19693. * Backtransform eigenvectors to the original problem.
  19694. *
  19695. IF( INFO.GT.0 )
  19696. $ M = INFO - 1
  19697. IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
  19698. *
  19699. * For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
  19700. * backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
  19701. *
  19702. IF( UPPER ) THEN
  19703. TRANS = 'N'
  19704. ELSE
  19705. TRANS = 'T'
  19706. END IF
  19707. *
  19708. DO 10 J = 1, M
  19709. CALL DTPSV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),
  19710. $ 1 )
  19711. 10 CONTINUE
  19712. *
  19713. ELSE IF( ITYPE.EQ.3 ) THEN
  19714. *
  19715. * For B*A*x=(lambda)*x;
  19716. * backtransform eigenvectors: x = L*y or U'*y
  19717. *
  19718. IF( UPPER ) THEN
  19719. TRANS = 'T'
  19720. ELSE
  19721. TRANS = 'N'
  19722. END IF
  19723. *
  19724. DO 20 J = 1, M
  19725. CALL DTPMV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),
  19726. $ 1 )
  19727. 20 CONTINUE
  19728. END IF
  19729. END IF
  19730. *
  19731. RETURN
  19732. *
  19733. * End of DSPGVX
  19734. *
  19735. END
  19736. SUBROUTINE DSPSV( UPLO, N, NRHS, AP, IPIV, B, LDB, INFO )
  19737. *
  19738. * -- LAPACK driver routine (version 3.1) --
  19739. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  19740. * November 2006
  19741. *
  19742. * .. Scalar Arguments ..
  19743. CHARACTER UPLO
  19744. INTEGER INFO, LDB, N, NRHS
  19745. * ..
  19746. * .. Array Arguments ..
  19747. INTEGER IPIV( * )
  19748. DOUBLE PRECISION AP( * ), B( LDB, * )
  19749. * ..
  19750. *
  19751. * Purpose
  19752. * =======
  19753. *
  19754. * DSPSV computes the solution to a real system of linear equations
  19755. * A * X = B,
  19756. * where A is an N-by-N symmetric matrix stored in packed format and X
  19757. * and B are N-by-NRHS matrices.
  19758. *
  19759. * The diagonal pivoting method is used to factor A as
  19760. * A = U * D * U**T, if UPLO = 'U', or
  19761. * A = L * D * L**T, if UPLO = 'L',
  19762. * where U (or L) is a product of permutation and unit upper (lower)
  19763. * triangular matrices, D is symmetric and block diagonal with 1-by-1
  19764. * and 2-by-2 diagonal blocks. The factored form of A is then used to
  19765. * solve the system of equations A * X = B.
  19766. *
  19767. * Arguments
  19768. * =========
  19769. *
  19770. * UPLO (input) CHARACTER*1
  19771. * = 'U': Upper triangle of A is stored;
  19772. * = 'L': Lower triangle of A is stored.
  19773. *
  19774. * N (input) INTEGER
  19775. * The number of linear equations, i.e., the order of the
  19776. * matrix A. N >= 0.
  19777. *
  19778. * NRHS (input) INTEGER
  19779. * The number of right hand sides, i.e., the number of columns
  19780. * of the matrix B. NRHS >= 0.
  19781. *
  19782. * AP (input/output) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  19783. * On entry, the upper or lower triangle of the symmetric matrix
  19784. * A, packed columnwise in a linear array. The j-th column of A
  19785. * is stored in the array AP as follows:
  19786. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  19787. * if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  19788. * See below for further details.
  19789. *
  19790. * On exit, the block diagonal matrix D and the multipliers used
  19791. * to obtain the factor U or L from the factorization
  19792. * A = U*D*U**T or A = L*D*L**T as computed by DSPTRF, stored as
  19793. * a packed triangular matrix in the same storage format as A.
  19794. *
  19795. * IPIV (output) INTEGER array, dimension (N)
  19796. * Details of the interchanges and the block structure of D, as
  19797. * determined by DSPTRF. If IPIV(k) > 0, then rows and columns
  19798. * k and IPIV(k) were interchanged, and D(k,k) is a 1-by-1
  19799. * diagonal block. If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0,
  19800. * then rows and columns k-1 and -IPIV(k) were interchanged and
  19801. * D(k-1:k,k-1:k) is a 2-by-2 diagonal block. If UPLO = 'L' and
  19802. * IPIV(k) = IPIV(k+1) < 0, then rows and columns k+1 and
  19803. * -IPIV(k) were interchanged and D(k:k+1,k:k+1) is a 2-by-2
  19804. * diagonal block.
  19805. *
  19806. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  19807. * On entry, the N-by-NRHS right hand side matrix B.
  19808. * On exit, if INFO = 0, the N-by-NRHS solution matrix X.
  19809. *
  19810. * LDB (input) INTEGER
  19811. * The leading dimension of the array B. LDB >= max(1,N).
  19812. *
  19813. * INFO (output) INTEGER
  19814. * = 0: successful exit
  19815. * < 0: if INFO = -i, the i-th argument had an illegal value
  19816. * > 0: if INFO = i, D(i,i) is exactly zero. The factorization
  19817. * has been completed, but the block diagonal matrix D is
  19818. * exactly singular, so the solution could not be
  19819. * computed.
  19820. *
  19821. * Further Details
  19822. * ===============
  19823. *
  19824. * The packed storage scheme is illustrated by the following example
  19825. * when N = 4, UPLO = 'U':
  19826. *
  19827. * Two-dimensional storage of the symmetric matrix A:
  19828. *
  19829. * a11 a12 a13 a14
  19830. * a22 a23 a24
  19831. * a33 a34 (aij = aji)
  19832. * a44
  19833. *
  19834. * Packed storage of the upper triangle of A:
  19835. *
  19836. * AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]
  19837. *
  19838. * =====================================================================
  19839. *
  19840. * .. External Functions ..
  19841. LOGICAL LSAME
  19842. EXTERNAL LSAME
  19843. * ..
  19844. * .. External Subroutines ..
  19845. EXTERNAL DSPTRF, DSPTRS, XERBLA
  19846. * ..
  19847. * .. Intrinsic Functions ..
  19848. INTRINSIC MAX
  19849. * ..
  19850. * .. Executable Statements ..
  19851. *
  19852. * Test the input parameters.
  19853. *
  19854. INFO = 0
  19855. IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  19856. INFO = -1
  19857. ELSE IF( N.LT.0 ) THEN
  19858. INFO = -2
  19859. ELSE IF( NRHS.LT.0 ) THEN
  19860. INFO = -3
  19861. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  19862. INFO = -7
  19863. END IF
  19864. IF( INFO.NE.0 ) THEN
  19865. CALL XERBLA( 'DSPSV ', -INFO )
  19866. RETURN
  19867. END IF
  19868. *
  19869. * Compute the factorization A = U*D*U' or A = L*D*L'.
  19870. *
  19871. CALL DSPTRF( UPLO, N, AP, IPIV, INFO )
  19872. IF( INFO.EQ.0 ) THEN
  19873. *
  19874. * Solve the system A*X = B, overwriting B with X.
  19875. *
  19876. CALL DSPTRS( UPLO, N, NRHS, AP, IPIV, B, LDB, INFO )
  19877. *
  19878. END IF
  19879. RETURN
  19880. *
  19881. * End of DSPSV
  19882. *
  19883. END
  19884. SUBROUTINE DSPSVX( FACT, UPLO, N, NRHS, AP, AFP, IPIV, B, LDB, X,
  19885. $ LDX, RCOND, FERR, BERR, WORK, IWORK, INFO )
  19886. *
  19887. * -- LAPACK driver routine (version 3.1) --
  19888. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  19889. * November 2006
  19890. *
  19891. * .. Scalar Arguments ..
  19892. CHARACTER FACT, UPLO
  19893. INTEGER INFO, LDB, LDX, N, NRHS
  19894. DOUBLE PRECISION RCOND
  19895. * ..
  19896. * .. Array Arguments ..
  19897. INTEGER IPIV( * ), IWORK( * )
  19898. DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),
  19899. $ FERR( * ), WORK( * ), X( LDX, * )
  19900. * ..
  19901. *
  19902. * Purpose
  19903. * =======
  19904. *
  19905. * DSPSVX uses the diagonal pivoting factorization A = U*D*U**T or
  19906. * A = L*D*L**T to compute the solution to a real system of linear
  19907. * equations A * X = B, where A is an N-by-N symmetric matrix stored
  19908. * in packed format and X and B are N-by-NRHS matrices.
  19909. *
  19910. * Error bounds on the solution and a condition estimate are also
  19911. * provided.
  19912. *
  19913. * Description
  19914. * ===========
  19915. *
  19916. * The following steps are performed:
  19917. *
  19918. * 1. If FACT = 'N', the diagonal pivoting method is used to factor A as
  19919. * A = U * D * U**T, if UPLO = 'U', or
  19920. * A = L * D * L**T, if UPLO = 'L',
  19921. * where U (or L) is a product of permutation and unit upper (lower)
  19922. * triangular matrices and D is symmetric and block diagonal with
  19923. * 1-by-1 and 2-by-2 diagonal blocks.
  19924. *
  19925. * 2. If some D(i,i)=0, so that D is exactly singular, then the routine
  19926. * returns with INFO = i. Otherwise, the factored form of A is used
  19927. * to estimate the condition number of the matrix A. If the
  19928. * reciprocal of the condition number is less than machine precision,
  19929. * INFO = N+1 is returned as a warning, but the routine still goes on
  19930. * to solve for X and compute error bounds as described below.
  19931. *
  19932. * 3. The system of equations is solved for X using the factored form
  19933. * of A.
  19934. *
  19935. * 4. Iterative refinement is applied to improve the computed solution
  19936. * matrix and calculate error bounds and backward error estimates
  19937. * for it.
  19938. *
  19939. * Arguments
  19940. * =========
  19941. *
  19942. * FACT (input) CHARACTER*1
  19943. * Specifies whether or not the factored form of A has been
  19944. * supplied on entry.
  19945. * = 'F': On entry, AFP and IPIV contain the factored form of
  19946. * A. AP, AFP and IPIV will not be modified.
  19947. * = 'N': The matrix A will be copied to AFP and factored.
  19948. *
  19949. * UPLO (input) CHARACTER*1
  19950. * = 'U': Upper triangle of A is stored;
  19951. * = 'L': Lower triangle of A is stored.
  19952. *
  19953. * N (input) INTEGER
  19954. * The number of linear equations, i.e., the order of the
  19955. * matrix A. N >= 0.
  19956. *
  19957. * NRHS (input) INTEGER
  19958. * The number of right hand sides, i.e., the number of columns
  19959. * of the matrices B and X. NRHS >= 0.
  19960. *
  19961. * AP (input) DOUBLE PRECISION array, dimension (N*(N+1)/2)
  19962. * The upper or lower triangle of the symmetric matrix A, packed
  19963. * columnwise in a linear array. The j-th column of A is stored
  19964. * in the array AP as follows:
  19965. * if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  19966. * if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
  19967. * See below for further details.
  19968. *
  19969. * AFP (input or output) DOUBLE PRECISION array, dimension
  19970. * (N*(N+1)/2)
  19971. * If FACT = 'F', then AFP is an input argument and on entry
  19972. * contains the block diagonal matrix D and the multipliers used
  19973. * to obtain the factor U or L from the factorization
  19974. * A = U*D*U**T or A = L*D*L**T as computed by DSPTRF, stored as
  19975. * a packed triangular matrix in the same storage format as A.
  19976. *
  19977. * If FACT = 'N', then AFP is an output argument and on exit
  19978. * contains the block diagonal matrix D and the multipliers used
  19979. * to obtain the factor U or L from the factorization
  19980. * A = U*D*U**T or A = L*D*L**T as computed by DSPTRF, stored as
  19981. * a packed triangular matrix in the same storage format as A.
  19982. *
  19983. * IPIV (input or output) INTEGER array, dimension (N)
  19984. * If FACT = 'F', then IPIV is an input argument and on entry
  19985. * contains details of the interchanges and the block structure
  19986. * of D, as determined by DSPTRF.
  19987. * If IPIV(k) > 0, then rows and columns k and IPIV(k) were
  19988. * interchanged and D(k,k) is a 1-by-1 diagonal block.
  19989. * If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and
  19990. * columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)
  19991. * is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) =
  19992. * IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were
  19993. * interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
  19994. *
  19995. * If FACT = 'N', then IPIV is an output argument and on exit
  19996. * contains details of the interchanges and the block structure
  19997. * of D, as determined by DSPTRF.
  19998. *
  19999. * B (input) DOUBLE PRECISION array, dimension (LDB,NRHS)
  20000. * The N-by-NRHS right hand side matrix B.
  20001. *
  20002. * LDB (input) INTEGER
  20003. * The leading dimension of the array B. LDB >= max(1,N).
  20004. *
  20005. * X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
  20006. * If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X.
  20007. *
  20008. * LDX (input) INTEGER
  20009. * The leading dimension of the array X. LDX >= max(1,N).
  20010. *
  20011. * RCOND (output) DOUBLE PRECISION
  20012. * The estimate of the reciprocal condition number of the matrix
  20013. * A. If RCOND is less than the machine precision (in
  20014. * particular, if RCOND = 0), the matrix is singular to working
  20015. * precision. This condition is indicated by a return code of
  20016. * INFO > 0.
  20017. *
  20018. * FERR (output) DOUBLE PRECISION array, dimension (NRHS)
  20019. * The estimated forward error bound for each solution vector
  20020. * X(j) (the j-th column of the solution matrix X).
  20021. * If XTRUE is the true solution corresponding to X(j), FERR(j)
  20022. * is an estimated upper bound for the magnitude of the largest
  20023. * element in (X(j) - XTRUE) divided by the magnitude of the
  20024. * largest element in X(j). The estimate is as reliable as
  20025. * the estimate for RCOND, and is almost always a slight
  20026. * overestimate of the true error.
  20027. *
  20028. * BERR (output) DOUBLE PRECISION array, dimension (NRHS)
  20029. * The componentwise relative backward error of each solution
  20030. * vector X(j) (i.e., the smallest relative change in
  20031. * any element of A or B that makes X(j) an exact solution).
  20032. *
  20033. * WORK (workspace) DOUBLE PRECISION array, dimension (3*N)
  20034. *
  20035. * IWORK (workspace) INTEGER array, dimension (N)
  20036. *
  20037. * INFO (output) INTEGER
  20038. * = 0: successful exit
  20039. * < 0: if INFO = -i, the i-th argument had an illegal value
  20040. * > 0: if INFO = i, and i is
  20041. * <= N: D(i,i) is exactly zero. The factorization
  20042. * has been completed but the factor D is exactly
  20043. * singular, so the solution and error bounds could
  20044. * not be computed. RCOND = 0 is returned.
  20045. * = N+1: D is nonsingular, but RCOND is less than machine
  20046. * precision, meaning that the matrix is singular
  20047. * to working precision. Nevertheless, the
  20048. * solution and error bounds are computed because
  20049. * there are a number of situations where the
  20050. * computed solution can be more accurate than the
  20051. * value of RCOND would suggest.
  20052. *
  20053. * Further Details
  20054. * ===============
  20055. *
  20056. * The packed storage scheme is illustrated by the following example
  20057. * when N = 4, UPLO = 'U':
  20058. *
  20059. * Two-dimensional storage of the symmetric matrix A:
  20060. *
  20061. * a11 a12 a13 a14
  20062. * a22 a23 a24
  20063. * a33 a34 (aij = aji)
  20064. * a44
  20065. *
  20066. * Packed storage of the upper triangle of A:
  20067. *
  20068. * AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]
  20069. *
  20070. * =====================================================================
  20071. *
  20072. * .. Parameters ..
  20073. DOUBLE PRECISION ZERO
  20074. PARAMETER ( ZERO = 0.0D+0 )
  20075. * ..
  20076. * .. Local Scalars ..
  20077. LOGICAL NOFACT
  20078. DOUBLE PRECISION ANORM
  20079. * ..
  20080. * .. External Functions ..
  20081. LOGICAL LSAME
  20082. DOUBLE PRECISION DLAMCH, DLANSP
  20083. EXTERNAL LSAME, DLAMCH, DLANSP
  20084. * ..
  20085. * .. External Subroutines ..
  20086. EXTERNAL DCOPY, DLACPY, DSPCON, DSPRFS, DSPTRF, DSPTRS,
  20087. $ XERBLA
  20088. * ..
  20089. * .. Intrinsic Functions ..
  20090. INTRINSIC MAX
  20091. * ..
  20092. * .. Executable Statements ..
  20093. *
  20094. * Test the input parameters.
  20095. *
  20096. INFO = 0
  20097. NOFACT = LSAME( FACT, 'N' )
  20098. IF( .NOT.NOFACT .AND. .NOT.LSAME( FACT, 'F' ) ) THEN
  20099. INFO = -1
  20100. ELSE IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) )
  20101. $ THEN
  20102. INFO = -2
  20103. ELSE IF( N.LT.0 ) THEN
  20104. INFO = -3
  20105. ELSE IF( NRHS.LT.0 ) THEN
  20106. INFO = -4
  20107. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  20108. INFO = -9
  20109. ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
  20110. INFO = -11
  20111. END IF
  20112. IF( INFO.NE.0 ) THEN
  20113. CALL XERBLA( 'DSPSVX', -INFO )
  20114. RETURN
  20115. END IF
  20116. *
  20117. IF( NOFACT ) THEN
  20118. *
  20119. * Compute the factorization A = U*D*U' or A = L*D*L'.
  20120. *
  20121. CALL DCOPY( N*( N+1 ) / 2, AP, 1, AFP, 1 )
  20122. CALL DSPTRF( UPLO, N, AFP, IPIV, INFO )
  20123. *
  20124. * Return if INFO is non-zero.
  20125. *
  20126. IF( INFO.GT.0 )THEN
  20127. RCOND = ZERO
  20128. RETURN
  20129. END IF
  20130. END IF
  20131. *
  20132. * Compute the norm of the matrix A.
  20133. *
  20134. ANORM = DLANSP( 'I', UPLO, N, AP, WORK )
  20135. *
  20136. * Compute the reciprocal of the condition number of A.
  20137. *
  20138. CALL DSPCON( UPLO, N, AFP, IPIV, ANORM, RCOND, WORK, IWORK, INFO )
  20139. *
  20140. * Compute the solution vectors X.
  20141. *
  20142. CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
  20143. CALL DSPTRS( UPLO, N, NRHS, AFP, IPIV, X, LDX, INFO )
  20144. *
  20145. * Use iterative refinement to improve the computed solutions and
  20146. * compute error bounds and backward error estimates for them.
  20147. *
  20148. CALL DSPRFS( UPLO, N, NRHS, AP, AFP, IPIV, B, LDB, X, LDX, FERR,
  20149. $ BERR, WORK, IWORK, INFO )
  20150. *
  20151. * Set INFO = N+1 if the matrix is singular to working precision.
  20152. *
  20153. IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
  20154. $ INFO = N + 1
  20155. *
  20156. RETURN
  20157. *
  20158. * End of DSPSVX
  20159. *
  20160. END
  20161. SUBROUTINE DSTEDC( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,
  20162. $ LIWORK, INFO )
  20163. *
  20164. * -- LAPACK driver routine (version 3.1) --
  20165. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  20166. * November 2006
  20167. *
  20168. * .. Scalar Arguments ..
  20169. CHARACTER COMPZ
  20170. INTEGER INFO, LDZ, LIWORK, LWORK, N
  20171. * ..
  20172. * .. Array Arguments ..
  20173. INTEGER IWORK( * )
  20174. DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
  20175. * ..
  20176. *
  20177. * Purpose
  20178. * =======
  20179. *
  20180. * DSTEDC computes all eigenvalues and, optionally, eigenvectors of a
  20181. * symmetric tridiagonal matrix using the divide and conquer method.
  20182. * The eigenvectors of a full or band real symmetric matrix can also be
  20183. * found if DSYTRD or DSPTRD or DSBTRD has been used to reduce this
  20184. * matrix to tridiagonal form.
  20185. *
  20186. * This code makes very mild assumptions about floating point
  20187. * arithmetic. It will work on machines with a guard digit in
  20188. * add/subtract, or on those binary machines without guard digits
  20189. * which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2.
  20190. * It could conceivably fail on hexadecimal or decimal machines
  20191. * without guard digits, but we know of none. See DLAED3 for details.
  20192. *
  20193. * Arguments
  20194. * =========
  20195. *
  20196. * COMPZ (input) CHARACTER*1
  20197. * = 'N': Compute eigenvalues only.
  20198. * = 'I': Compute eigenvectors of tridiagonal matrix also.
  20199. * = 'V': Compute eigenvectors of original dense symmetric
  20200. * matrix also. On entry, Z contains the orthogonal
  20201. * matrix used to reduce the original matrix to
  20202. * tridiagonal form.
  20203. *
  20204. * N (input) INTEGER
  20205. * The dimension of the symmetric tridiagonal matrix. N >= 0.
  20206. *
  20207. * D (input/output) DOUBLE PRECISION array, dimension (N)
  20208. * On entry, the diagonal elements of the tridiagonal matrix.
  20209. * On exit, if INFO = 0, the eigenvalues in ascending order.
  20210. *
  20211. * E (input/output) DOUBLE PRECISION array, dimension (N-1)
  20212. * On entry, the subdiagonal elements of the tridiagonal matrix.
  20213. * On exit, E has been destroyed.
  20214. *
  20215. * Z (input/output) DOUBLE PRECISION array, dimension (LDZ,N)
  20216. * On entry, if COMPZ = 'V', then Z contains the orthogonal
  20217. * matrix used in the reduction to tridiagonal form.
  20218. * On exit, if INFO = 0, then if COMPZ = 'V', Z contains the
  20219. * orthonormal eigenvectors of the original symmetric matrix,
  20220. * and if COMPZ = 'I', Z contains the orthonormal eigenvectors
  20221. * of the symmetric tridiagonal matrix.
  20222. * If COMPZ = 'N', then Z is not referenced.
  20223. *
  20224. * LDZ (input) INTEGER
  20225. * The leading dimension of the array Z. LDZ >= 1.
  20226. * If eigenvectors are desired, then LDZ >= max(1,N).
  20227. *
  20228. * WORK (workspace/output) DOUBLE PRECISION array,
  20229. * dimension (LWORK)
  20230. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  20231. *
  20232. * LWORK (input) INTEGER
  20233. * The dimension of the array WORK.
  20234. * If COMPZ = 'N' or N <= 1 then LWORK must be at least 1.
  20235. * If COMPZ = 'V' and N > 1 then LWORK must be at least
  20236. * ( 1 + 3*N + 2*N*lg N + 3*N**2 ),
  20237. * where lg( N ) = smallest integer k such
  20238. * that 2**k >= N.
  20239. * If COMPZ = 'I' and N > 1 then LWORK must be at least
  20240. * ( 1 + 4*N + N**2 ).
  20241. * Note that for COMPZ = 'I' or 'V', then if N is less than or
  20242. * equal to the minimum divide size, usually 25, then LWORK need
  20243. * only be max(1,2*(N-1)).
  20244. *
  20245. * If LWORK = -1, then a workspace query is assumed; the routine
  20246. * only calculates the optimal size of the WORK array, returns
  20247. * this value as the first entry of the WORK array, and no error
  20248. * message related to LWORK is issued by XERBLA.
  20249. *
  20250. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  20251. * On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
  20252. *
  20253. * LIWORK (input) INTEGER
  20254. * The dimension of the array IWORK.
  20255. * If COMPZ = 'N' or N <= 1 then LIWORK must be at least 1.
  20256. * If COMPZ = 'V' and N > 1 then LIWORK must be at least
  20257. * ( 6 + 6*N + 5*N*lg N ).
  20258. * If COMPZ = 'I' and N > 1 then LIWORK must be at least
  20259. * ( 3 + 5*N ).
  20260. * Note that for COMPZ = 'I' or 'V', then if N is less than or
  20261. * equal to the minimum divide size, usually 25, then LIWORK
  20262. * need only be 1.
  20263. *
  20264. * If LIWORK = -1, then a workspace query is assumed; the
  20265. * routine only calculates the optimal size of the IWORK array,
  20266. * returns this value as the first entry of the IWORK array, and
  20267. * no error message related to LIWORK is issued by XERBLA.
  20268. *
  20269. * INFO (output) INTEGER
  20270. * = 0: successful exit.
  20271. * < 0: if INFO = -i, the i-th argument had an illegal value.
  20272. * > 0: The algorithm failed to compute an eigenvalue while
  20273. * working on the submatrix lying in rows and columns
  20274. * INFO/(N+1) through mod(INFO,N+1).
  20275. *
  20276. * Further Details
  20277. * ===============
  20278. *
  20279. * Based on contributions by
  20280. * Jeff Rutter, Computer Science Division, University of California
  20281. * at Berkeley, USA
  20282. * Modified by Francoise Tisseur, University of Tennessee.
  20283. *
  20284. * =====================================================================
  20285. *
  20286. * .. Parameters ..
  20287. DOUBLE PRECISION ZERO, ONE, TWO
  20288. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
  20289. * ..
  20290. * .. Local Scalars ..
  20291. LOGICAL LQUERY
  20292. INTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN,
  20293. $ LWMIN, M, SMLSIZ, START, STOREZ, STRTRW
  20294. DOUBLE PRECISION EPS, ORGNRM, P, TINY
  20295. * ..
  20296. * .. External Functions ..
  20297. LOGICAL LSAME
  20298. INTEGER ILAENV
  20299. DOUBLE PRECISION DLAMCH, DLANST
  20300. EXTERNAL LSAME, ILAENV, DLAMCH, DLANST
  20301. * ..
  20302. * .. External Subroutines ..
  20303. EXTERNAL DGEMM, DLACPY, DLAED0, DLASCL, DLASET, DLASRT,
  20304. $ DSTEQR, DSTERF, DSWAP, XERBLA
  20305. * ..
  20306. * .. Intrinsic Functions ..
  20307. INTRINSIC ABS, DBLE, INT, LOG, MAX, MOD, SQRT
  20308. * ..
  20309. * .. Executable Statements ..
  20310. *
  20311. * Test the input parameters.
  20312. *
  20313. INFO = 0
  20314. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  20315. *
  20316. IF( LSAME( COMPZ, 'N' ) ) THEN
  20317. ICOMPZ = 0
  20318. ELSE IF( LSAME( COMPZ, 'V' ) ) THEN
  20319. ICOMPZ = 1
  20320. ELSE IF( LSAME( COMPZ, 'I' ) ) THEN
  20321. ICOMPZ = 2
  20322. ELSE
  20323. ICOMPZ = -1
  20324. END IF
  20325. IF( ICOMPZ.LT.0 ) THEN
  20326. INFO = -1
  20327. ELSE IF( N.LT.0 ) THEN
  20328. INFO = -2
  20329. ELSE IF( ( LDZ.LT.1 ) .OR.
  20330. $ ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1, N ) ) ) THEN
  20331. INFO = -6
  20332. END IF
  20333. *
  20334. IF( INFO.EQ.0 ) THEN
  20335. *
  20336. * Compute the workspace requirements
  20337. *
  20338. SMLSIZ = ILAENV( 9, 'DSTEDC', ' ', 0, 0, 0, 0 )
  20339. IF( N.LE.1 .OR. ICOMPZ.EQ.0 ) THEN
  20340. LIWMIN = 1
  20341. LWMIN = 1
  20342. ELSE IF( N.LE.SMLSIZ ) THEN
  20343. LIWMIN = 1
  20344. LWMIN = 2*( N - 1 )
  20345. ELSE
  20346. LGN = INT( LOG( DBLE( N ) )/LOG( TWO ) )
  20347. IF( 2**LGN.LT.N )
  20348. $ LGN = LGN + 1
  20349. IF( 2**LGN.LT.N )
  20350. $ LGN = LGN + 1
  20351. IF( ICOMPZ.EQ.1 ) THEN
  20352. LWMIN = 1 + 3*N + 2*N*LGN + 3*N**2
  20353. LIWMIN = 6 + 6*N + 5*N*LGN
  20354. ELSE IF( ICOMPZ.EQ.2 ) THEN
  20355. LWMIN = 1 + 4*N + N**2
  20356. LIWMIN = 3 + 5*N
  20357. END IF
  20358. END IF
  20359. WORK( 1 ) = LWMIN
  20360. IWORK( 1 ) = LIWMIN
  20361. *
  20362. IF( LWORK.LT.LWMIN .AND. .NOT. LQUERY ) THEN
  20363. INFO = -8
  20364. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT. LQUERY ) THEN
  20365. INFO = -10
  20366. END IF
  20367. END IF
  20368. *
  20369. IF( INFO.NE.0 ) THEN
  20370. CALL XERBLA( 'DSTEDC', -INFO )
  20371. RETURN
  20372. ELSE IF (LQUERY) THEN
  20373. RETURN
  20374. END IF
  20375. *
  20376. * Quick return if possible
  20377. *
  20378. IF( N.EQ.0 )
  20379. $ RETURN
  20380. IF( N.EQ.1 ) THEN
  20381. IF( ICOMPZ.NE.0 )
  20382. $ Z( 1, 1 ) = ONE
  20383. RETURN
  20384. END IF
  20385. *
  20386. * If the following conditional clause is removed, then the routine
  20387. * will use the Divide and Conquer routine to compute only the
  20388. * eigenvalues, which requires (3N + 3N**2) real workspace and
  20389. * (2 + 5N + 2N lg(N)) integer workspace.
  20390. * Since on many architectures DSTERF is much faster than any other
  20391. * algorithm for finding eigenvalues only, it is used here
  20392. * as the default. If the conditional clause is removed, then
  20393. * information on the size of workspace needs to be changed.
  20394. *
  20395. * If COMPZ = 'N', use DSTERF to compute the eigenvalues.
  20396. *
  20397. IF( ICOMPZ.EQ.0 ) THEN
  20398. CALL DSTERF( N, D, E, INFO )
  20399. GO TO 50
  20400. END IF
  20401. *
  20402. * If N is smaller than the minimum divide size (SMLSIZ+1), then
  20403. * solve the problem with another solver.
  20404. *
  20405. IF( N.LE.SMLSIZ ) THEN
  20406. *
  20407. CALL DSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
  20408. *
  20409. ELSE
  20410. *
  20411. * If COMPZ = 'V', the Z matrix must be stored elsewhere for later
  20412. * use.
  20413. *
  20414. IF( ICOMPZ.EQ.1 ) THEN
  20415. STOREZ = 1 + N*N
  20416. ELSE
  20417. STOREZ = 1
  20418. END IF
  20419. *
  20420. IF( ICOMPZ.EQ.2 ) THEN
  20421. CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
  20422. END IF
  20423. *
  20424. * Scale.
  20425. *
  20426. ORGNRM = DLANST( 'M', N, D, E )
  20427. IF( ORGNRM.EQ.ZERO )
  20428. $ GO TO 50
  20429. *
  20430. EPS = DLAMCH( 'Epsilon' )
  20431. *
  20432. START = 1
  20433. *
  20434. * while ( START <= N )
  20435. *
  20436. 10 CONTINUE
  20437. IF( START.LE.N ) THEN
  20438. *
  20439. * Let FINISH be the position of the next subdiagonal entry
  20440. * such that E( FINISH ) <= TINY or FINISH = N if no such
  20441. * subdiagonal exists. The matrix identified by the elements
  20442. * between START and FINISH constitutes an independent
  20443. * sub-problem.
  20444. *
  20445. FINISH = START
  20446. 20 CONTINUE
  20447. IF( FINISH.LT.N ) THEN
  20448. TINY = EPS*SQRT( ABS( D( FINISH ) ) )*
  20449. $ SQRT( ABS( D( FINISH+1 ) ) )
  20450. IF( ABS( E( FINISH ) ).GT.TINY ) THEN
  20451. FINISH = FINISH + 1
  20452. GO TO 20
  20453. END IF
  20454. END IF
  20455. *
  20456. * (Sub) Problem determined. Compute its size and solve it.
  20457. *
  20458. M = FINISH - START + 1
  20459. IF( M.EQ.1 ) THEN
  20460. START = FINISH + 1
  20461. GO TO 10
  20462. END IF
  20463. IF( M.GT.SMLSIZ ) THEN
  20464. *
  20465. * Scale.
  20466. *
  20467. ORGNRM = DLANST( 'M', M, D( START ), E( START ) )
  20468. CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, M, 1, D( START ), M,
  20469. $ INFO )
  20470. CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, M-1, 1, E( START ),
  20471. $ M-1, INFO )
  20472. *
  20473. IF( ICOMPZ.EQ.1 ) THEN
  20474. STRTRW = 1
  20475. ELSE
  20476. STRTRW = START
  20477. END IF
  20478. CALL DLAED0( ICOMPZ, N, M, D( START ), E( START ),
  20479. $ Z( STRTRW, START ), LDZ, WORK( 1 ), N,
  20480. $ WORK( STOREZ ), IWORK, INFO )
  20481. IF( INFO.NE.0 ) THEN
  20482. INFO = ( INFO / ( M+1 )+START-1 )*( N+1 ) +
  20483. $ MOD( INFO, ( M+1 ) ) + START - 1
  20484. GO TO 50
  20485. END IF
  20486. *
  20487. * Scale back.
  20488. *
  20489. CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, M, 1, D( START ), M,
  20490. $ INFO )
  20491. *
  20492. ELSE
  20493. IF( ICOMPZ.EQ.1 ) THEN
  20494. *
  20495. * Since QR won't update a Z matrix which is larger than
  20496. * the length of D, we must solve the sub-problem in a
  20497. * workspace and then multiply back into Z.
  20498. *
  20499. CALL DSTEQR( 'I', M, D( START ), E( START ), WORK, M,
  20500. $ WORK( M*M+1 ), INFO )
  20501. CALL DLACPY( 'A', N, M, Z( 1, START ), LDZ,
  20502. $ WORK( STOREZ ), N )
  20503. CALL DGEMM( 'N', 'N', N, M, M, ONE,
  20504. $ WORK( STOREZ ), N, WORK, M, ZERO,
  20505. $ Z( 1, START ), LDZ )
  20506. ELSE IF( ICOMPZ.EQ.2 ) THEN
  20507. CALL DSTEQR( 'I', M, D( START ), E( START ),
  20508. $ Z( START, START ), LDZ, WORK, INFO )
  20509. ELSE
  20510. CALL DSTERF( M, D( START ), E( START ), INFO )
  20511. END IF
  20512. IF( INFO.NE.0 ) THEN
  20513. INFO = START*( N+1 ) + FINISH
  20514. GO TO 50
  20515. END IF
  20516. END IF
  20517. *
  20518. START = FINISH + 1
  20519. GO TO 10
  20520. END IF
  20521. *
  20522. * endwhile
  20523. *
  20524. * If the problem split any number of times, then the eigenvalues
  20525. * will not be properly ordered. Here we permute the eigenvalues
  20526. * (and the associated eigenvectors) into ascending order.
  20527. *
  20528. IF( M.NE.N ) THEN
  20529. IF( ICOMPZ.EQ.0 ) THEN
  20530. *
  20531. * Use Quick Sort
  20532. *
  20533. CALL DLASRT( 'I', N, D, INFO )
  20534. *
  20535. ELSE
  20536. *
  20537. * Use Selection Sort to minimize swaps of eigenvectors
  20538. *
  20539. DO 40 II = 2, N
  20540. I = II - 1
  20541. K = I
  20542. P = D( I )
  20543. DO 30 J = II, N
  20544. IF( D( J ).LT.P ) THEN
  20545. K = J
  20546. P = D( J )
  20547. END IF
  20548. 30 CONTINUE
  20549. IF( K.NE.I ) THEN
  20550. D( K ) = D( I )
  20551. D( I ) = P
  20552. CALL DSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )
  20553. END IF
  20554. 40 CONTINUE
  20555. END IF
  20556. END IF
  20557. END IF
  20558. *
  20559. 50 CONTINUE
  20560. WORK( 1 ) = LWMIN
  20561. IWORK( 1 ) = LIWMIN
  20562. *
  20563. RETURN
  20564. *
  20565. * End of DSTEDC
  20566. *
  20567. END
  20568. SUBROUTINE DSTEV( JOBZ, N, D, E, Z, LDZ, WORK, INFO )
  20569. *
  20570. * -- LAPACK driver routine (version 3.1) --
  20571. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  20572. * November 2006
  20573. *
  20574. * .. Scalar Arguments ..
  20575. CHARACTER JOBZ
  20576. INTEGER INFO, LDZ, N
  20577. * ..
  20578. * .. Array Arguments ..
  20579. DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
  20580. * ..
  20581. *
  20582. * Purpose
  20583. * =======
  20584. *
  20585. * DSTEV computes all eigenvalues and, optionally, eigenvectors of a
  20586. * real symmetric tridiagonal matrix A.
  20587. *
  20588. * Arguments
  20589. * =========
  20590. *
  20591. * JOBZ (input) CHARACTER*1
  20592. * = 'N': Compute eigenvalues only;
  20593. * = 'V': Compute eigenvalues and eigenvectors.
  20594. *
  20595. * N (input) INTEGER
  20596. * The order of the matrix. N >= 0.
  20597. *
  20598. * D (input/output) DOUBLE PRECISION array, dimension (N)
  20599. * On entry, the n diagonal elements of the tridiagonal matrix
  20600. * A.
  20601. * On exit, if INFO = 0, the eigenvalues in ascending order.
  20602. *
  20603. * E (input/output) DOUBLE PRECISION array, dimension (N-1)
  20604. * On entry, the (n-1) subdiagonal elements of the tridiagonal
  20605. * matrix A, stored in elements 1 to N-1 of E.
  20606. * On exit, the contents of E are destroyed.
  20607. *
  20608. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  20609. * If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal
  20610. * eigenvectors of the matrix A, with the i-th column of Z
  20611. * holding the eigenvector associated with D(i).
  20612. * If JOBZ = 'N', then Z is not referenced.
  20613. *
  20614. * LDZ (input) INTEGER
  20615. * The leading dimension of the array Z. LDZ >= 1, and if
  20616. * JOBZ = 'V', LDZ >= max(1,N).
  20617. *
  20618. * WORK (workspace) DOUBLE PRECISION array, dimension (max(1,2*N-2))
  20619. * If JOBZ = 'N', WORK is not referenced.
  20620. *
  20621. * INFO (output) INTEGER
  20622. * = 0: successful exit
  20623. * < 0: if INFO = -i, the i-th argument had an illegal value
  20624. * > 0: if INFO = i, the algorithm failed to converge; i
  20625. * off-diagonal elements of E did not converge to zero.
  20626. *
  20627. * =====================================================================
  20628. *
  20629. * .. Parameters ..
  20630. DOUBLE PRECISION ZERO, ONE
  20631. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  20632. * ..
  20633. * .. Local Scalars ..
  20634. LOGICAL WANTZ
  20635. INTEGER IMAX, ISCALE
  20636. DOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,
  20637. $ TNRM
  20638. * ..
  20639. * .. External Functions ..
  20640. LOGICAL LSAME
  20641. DOUBLE PRECISION DLAMCH, DLANST
  20642. EXTERNAL LSAME, DLAMCH, DLANST
  20643. * ..
  20644. * .. External Subroutines ..
  20645. EXTERNAL DSCAL, DSTEQR, DSTERF, XERBLA
  20646. * ..
  20647. * .. Intrinsic Functions ..
  20648. INTRINSIC SQRT
  20649. * ..
  20650. * .. Executable Statements ..
  20651. *
  20652. * Test the input parameters.
  20653. *
  20654. WANTZ = LSAME( JOBZ, 'V' )
  20655. *
  20656. INFO = 0
  20657. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  20658. INFO = -1
  20659. ELSE IF( N.LT.0 ) THEN
  20660. INFO = -2
  20661. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  20662. INFO = -6
  20663. END IF
  20664. *
  20665. IF( INFO.NE.0 ) THEN
  20666. CALL XERBLA( 'DSTEV ', -INFO )
  20667. RETURN
  20668. END IF
  20669. *
  20670. * Quick return if possible
  20671. *
  20672. IF( N.EQ.0 )
  20673. $ RETURN
  20674. *
  20675. IF( N.EQ.1 ) THEN
  20676. IF( WANTZ )
  20677. $ Z( 1, 1 ) = ONE
  20678. RETURN
  20679. END IF
  20680. *
  20681. * Get machine constants.
  20682. *
  20683. SAFMIN = DLAMCH( 'Safe minimum' )
  20684. EPS = DLAMCH( 'Precision' )
  20685. SMLNUM = SAFMIN / EPS
  20686. BIGNUM = ONE / SMLNUM
  20687. RMIN = SQRT( SMLNUM )
  20688. RMAX = SQRT( BIGNUM )
  20689. *
  20690. * Scale matrix to allowable range, if necessary.
  20691. *
  20692. ISCALE = 0
  20693. TNRM = DLANST( 'M', N, D, E )
  20694. IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THEN
  20695. ISCALE = 1
  20696. SIGMA = RMIN / TNRM
  20697. ELSE IF( TNRM.GT.RMAX ) THEN
  20698. ISCALE = 1
  20699. SIGMA = RMAX / TNRM
  20700. END IF
  20701. IF( ISCALE.EQ.1 ) THEN
  20702. CALL DSCAL( N, SIGMA, D, 1 )
  20703. CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )
  20704. END IF
  20705. *
  20706. * For eigenvalues only, call DSTERF. For eigenvalues and
  20707. * eigenvectors, call DSTEQR.
  20708. *
  20709. IF( .NOT.WANTZ ) THEN
  20710. CALL DSTERF( N, D, E, INFO )
  20711. ELSE
  20712. CALL DSTEQR( 'I', N, D, E, Z, LDZ, WORK, INFO )
  20713. END IF
  20714. *
  20715. * If matrix was scaled, then rescale eigenvalues appropriately.
  20716. *
  20717. IF( ISCALE.EQ.1 ) THEN
  20718. IF( INFO.EQ.0 ) THEN
  20719. IMAX = N
  20720. ELSE
  20721. IMAX = INFO - 1
  20722. END IF
  20723. CALL DSCAL( IMAX, ONE / SIGMA, D, 1 )
  20724. END IF
  20725. *
  20726. RETURN
  20727. *
  20728. * End of DSTEV
  20729. *
  20730. END
  20731. SUBROUTINE DSTEVD( JOBZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,
  20732. $ LIWORK, INFO )
  20733. *
  20734. * -- LAPACK driver routine (version 3.1) --
  20735. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  20736. * November 2006
  20737. *
  20738. * .. Scalar Arguments ..
  20739. CHARACTER JOBZ
  20740. INTEGER INFO, LDZ, LIWORK, LWORK, N
  20741. * ..
  20742. * .. Array Arguments ..
  20743. INTEGER IWORK( * )
  20744. DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
  20745. * ..
  20746. *
  20747. * Purpose
  20748. * =======
  20749. *
  20750. * DSTEVD computes all eigenvalues and, optionally, eigenvectors of a
  20751. * real symmetric tridiagonal matrix. If eigenvectors are desired, it
  20752. * uses a divide and conquer algorithm.
  20753. *
  20754. * The divide and conquer algorithm makes very mild assumptions about
  20755. * floating point arithmetic. It will work on machines with a guard
  20756. * digit in add/subtract, or on those binary machines without guard
  20757. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  20758. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  20759. * without guard digits, but we know of none.
  20760. *
  20761. * Arguments
  20762. * =========
  20763. *
  20764. * JOBZ (input) CHARACTER*1
  20765. * = 'N': Compute eigenvalues only;
  20766. * = 'V': Compute eigenvalues and eigenvectors.
  20767. *
  20768. * N (input) INTEGER
  20769. * The order of the matrix. N >= 0.
  20770. *
  20771. * D (input/output) DOUBLE PRECISION array, dimension (N)
  20772. * On entry, the n diagonal elements of the tridiagonal matrix
  20773. * A.
  20774. * On exit, if INFO = 0, the eigenvalues in ascending order.
  20775. *
  20776. * E (input/output) DOUBLE PRECISION array, dimension (N-1)
  20777. * On entry, the (n-1) subdiagonal elements of the tridiagonal
  20778. * matrix A, stored in elements 1 to N-1 of E.
  20779. * On exit, the contents of E are destroyed.
  20780. *
  20781. * Z (output) DOUBLE PRECISION array, dimension (LDZ, N)
  20782. * If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal
  20783. * eigenvectors of the matrix A, with the i-th column of Z
  20784. * holding the eigenvector associated with D(i).
  20785. * If JOBZ = 'N', then Z is not referenced.
  20786. *
  20787. * LDZ (input) INTEGER
  20788. * The leading dimension of the array Z. LDZ >= 1, and if
  20789. * JOBZ = 'V', LDZ >= max(1,N).
  20790. *
  20791. * WORK (workspace/output) DOUBLE PRECISION array,
  20792. * dimension (LWORK)
  20793. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  20794. *
  20795. * LWORK (input) INTEGER
  20796. * The dimension of the array WORK.
  20797. * If JOBZ = 'N' or N <= 1 then LWORK must be at least 1.
  20798. * If JOBZ = 'V' and N > 1 then LWORK must be at least
  20799. * ( 1 + 4*N + N**2 ).
  20800. *
  20801. * If LWORK = -1, then a workspace query is assumed; the routine
  20802. * only calculates the optimal sizes of the WORK and IWORK
  20803. * arrays, returns these values as the first entries of the WORK
  20804. * and IWORK arrays, and no error message related to LWORK or
  20805. * LIWORK is issued by XERBLA.
  20806. *
  20807. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  20808. * On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
  20809. *
  20810. * LIWORK (input) INTEGER
  20811. * The dimension of the array IWORK.
  20812. * If JOBZ = 'N' or N <= 1 then LIWORK must be at least 1.
  20813. * If JOBZ = 'V' and N > 1 then LIWORK must be at least 3+5*N.
  20814. *
  20815. * If LIWORK = -1, then a workspace query is assumed; the
  20816. * routine only calculates the optimal sizes of the WORK and
  20817. * IWORK arrays, returns these values as the first entries of
  20818. * the WORK and IWORK arrays, and no error message related to
  20819. * LWORK or LIWORK is issued by XERBLA.
  20820. *
  20821. * INFO (output) INTEGER
  20822. * = 0: successful exit
  20823. * < 0: if INFO = -i, the i-th argument had an illegal value
  20824. * > 0: if INFO = i, the algorithm failed to converge; i
  20825. * off-diagonal elements of E did not converge to zero.
  20826. *
  20827. * =====================================================================
  20828. *
  20829. * .. Parameters ..
  20830. DOUBLE PRECISION ZERO, ONE
  20831. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  20832. * ..
  20833. * .. Local Scalars ..
  20834. LOGICAL LQUERY, WANTZ
  20835. INTEGER ISCALE, LIWMIN, LWMIN
  20836. DOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,
  20837. $ TNRM
  20838. * ..
  20839. * .. External Functions ..
  20840. LOGICAL LSAME
  20841. DOUBLE PRECISION DLAMCH, DLANST
  20842. EXTERNAL LSAME, DLAMCH, DLANST
  20843. * ..
  20844. * .. External Subroutines ..
  20845. EXTERNAL DSCAL, DSTEDC, DSTERF, XERBLA
  20846. * ..
  20847. * .. Intrinsic Functions ..
  20848. INTRINSIC SQRT
  20849. * ..
  20850. * .. Executable Statements ..
  20851. *
  20852. * Test the input parameters.
  20853. *
  20854. WANTZ = LSAME( JOBZ, 'V' )
  20855. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  20856. *
  20857. INFO = 0
  20858. LIWMIN = 1
  20859. LWMIN = 1
  20860. IF( N.GT.1 .AND. WANTZ ) THEN
  20861. LWMIN = 1 + 4*N + N**2
  20862. LIWMIN = 3 + 5*N
  20863. END IF
  20864. *
  20865. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  20866. INFO = -1
  20867. ELSE IF( N.LT.0 ) THEN
  20868. INFO = -2
  20869. ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  20870. INFO = -6
  20871. END IF
  20872. *
  20873. IF( INFO.EQ.0 ) THEN
  20874. WORK( 1 ) = LWMIN
  20875. IWORK( 1 ) = LIWMIN
  20876. *
  20877. IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  20878. INFO = -8
  20879. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  20880. INFO = -10
  20881. END IF
  20882. END IF
  20883. *
  20884. IF( INFO.NE.0 ) THEN
  20885. CALL XERBLA( 'DSTEVD', -INFO )
  20886. RETURN
  20887. ELSE IF( LQUERY ) THEN
  20888. RETURN
  20889. END IF
  20890. *
  20891. * Quick return if possible
  20892. *
  20893. IF( N.EQ.0 )
  20894. $ RETURN
  20895. *
  20896. IF( N.EQ.1 ) THEN
  20897. IF( WANTZ )
  20898. $ Z( 1, 1 ) = ONE
  20899. RETURN
  20900. END IF
  20901. *
  20902. * Get machine constants.
  20903. *
  20904. SAFMIN = DLAMCH( 'Safe minimum' )
  20905. EPS = DLAMCH( 'Precision' )
  20906. SMLNUM = SAFMIN / EPS
  20907. BIGNUM = ONE / SMLNUM
  20908. RMIN = SQRT( SMLNUM )
  20909. RMAX = SQRT( BIGNUM )
  20910. *
  20911. * Scale matrix to allowable range, if necessary.
  20912. *
  20913. ISCALE = 0
  20914. TNRM = DLANST( 'M', N, D, E )
  20915. IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THEN
  20916. ISCALE = 1
  20917. SIGMA = RMIN / TNRM
  20918. ELSE IF( TNRM.GT.RMAX ) THEN
  20919. ISCALE = 1
  20920. SIGMA = RMAX / TNRM
  20921. END IF
  20922. IF( ISCALE.EQ.1 ) THEN
  20923. CALL DSCAL( N, SIGMA, D, 1 )
  20924. CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )
  20925. END IF
  20926. *
  20927. * For eigenvalues only, call DSTERF. For eigenvalues and
  20928. * eigenvectors, call DSTEDC.
  20929. *
  20930. IF( .NOT.WANTZ ) THEN
  20931. CALL DSTERF( N, D, E, INFO )
  20932. ELSE
  20933. CALL DSTEDC( 'I', N, D, E, Z, LDZ, WORK, LWORK, IWORK, LIWORK,
  20934. $ INFO )
  20935. END IF
  20936. *
  20937. * If matrix was scaled, then rescale eigenvalues appropriately.
  20938. *
  20939. IF( ISCALE.EQ.1 )
  20940. $ CALL DSCAL( N, ONE / SIGMA, D, 1 )
  20941. *
  20942. WORK( 1 ) = LWMIN
  20943. IWORK( 1 ) = LIWMIN
  20944. *
  20945. RETURN
  20946. *
  20947. * End of DSTEVD
  20948. *
  20949. END
  20950. SUBROUTINE DSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL,
  20951. $ M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,
  20952. $ LIWORK, INFO )
  20953. *
  20954. * -- LAPACK driver routine (version 3.1) --
  20955. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  20956. * November 2006
  20957. *
  20958. * .. Scalar Arguments ..
  20959. CHARACTER JOBZ, RANGE
  20960. INTEGER IL, INFO, IU, LDZ, LIWORK, LWORK, M, N
  20961. DOUBLE PRECISION ABSTOL, VL, VU
  20962. * ..
  20963. * .. Array Arguments ..
  20964. INTEGER ISUPPZ( * ), IWORK( * )
  20965. DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )
  20966. * ..
  20967. *
  20968. * Purpose
  20969. * =======
  20970. *
  20971. * DSTEVR computes selected eigenvalues and, optionally, eigenvectors
  20972. * of a real symmetric tridiagonal matrix T. Eigenvalues and
  20973. * eigenvectors can be selected by specifying either a range of values
  20974. * or a range of indices for the desired eigenvalues.
  20975. *
  20976. * Whenever possible, DSTEVR calls DSTEMR to compute the
  20977. * eigenspectrum using Relatively Robust Representations. DSTEMR
  20978. * computes eigenvalues by the dqds algorithm, while orthogonal
  20979. * eigenvectors are computed from various "good" L D L^T representations
  20980. * (also known as Relatively Robust Representations). Gram-Schmidt
  20981. * orthogonalization is avoided as far as possible. More specifically,
  20982. * the various steps of the algorithm are as follows. For the i-th
  20983. * unreduced block of T,
  20984. * (a) Compute T - sigma_i = L_i D_i L_i^T, such that L_i D_i L_i^T
  20985. * is a relatively robust representation,
  20986. * (b) Compute the eigenvalues, lambda_j, of L_i D_i L_i^T to high
  20987. * relative accuracy by the dqds algorithm,
  20988. * (c) If there is a cluster of close eigenvalues, "choose" sigma_i
  20989. * close to the cluster, and go to step (a),
  20990. * (d) Given the approximate eigenvalue lambda_j of L_i D_i L_i^T,
  20991. * compute the corresponding eigenvector by forming a
  20992. * rank-revealing twisted factorization.
  20993. * The desired accuracy of the output can be specified by the input
  20994. * parameter ABSTOL.
  20995. *
  20996. * For more details, see "A new O(n^2) algorithm for the symmetric
  20997. * tridiagonal eigenvalue/eigenvector problem", by Inderjit Dhillon,
  20998. * Computer Science Division Technical Report No. UCB//CSD-97-971,
  20999. * UC Berkeley, May 1997.
  21000. *
  21001. *
  21002. * Note 1 : DSTEVR calls DSTEMR when the full spectrum is requested
  21003. * on machines which conform to the ieee-754 floating point standard.
  21004. * DSTEVR calls DSTEBZ and DSTEIN on non-ieee machines and
  21005. * when partial spectrum requests are made.
  21006. *
  21007. * Normal execution of DSTEMR may create NaNs and infinities and
  21008. * hence may abort due to a floating point exception in environments
  21009. * which do not handle NaNs and infinities in the ieee standard default
  21010. * manner.
  21011. *
  21012. * Arguments
  21013. * =========
  21014. *
  21015. * JOBZ (input) CHARACTER*1
  21016. * = 'N': Compute eigenvalues only;
  21017. * = 'V': Compute eigenvalues and eigenvectors.
  21018. *
  21019. * RANGE (input) CHARACTER*1
  21020. * = 'A': all eigenvalues will be found.
  21021. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  21022. * will be found.
  21023. * = 'I': the IL-th through IU-th eigenvalues will be found.
  21024. ********** For RANGE = 'V' or 'I' and IU - IL < N - 1, DSTEBZ and
  21025. ********** DSTEIN are called
  21026. *
  21027. * N (input) INTEGER
  21028. * The order of the matrix. N >= 0.
  21029. *
  21030. * D (input/output) DOUBLE PRECISION array, dimension (N)
  21031. * On entry, the n diagonal elements of the tridiagonal matrix
  21032. * A.
  21033. * On exit, D may be multiplied by a constant factor chosen
  21034. * to avoid over/underflow in computing the eigenvalues.
  21035. *
  21036. * E (input/output) DOUBLE PRECISION array, dimension (max(1,N-1))
  21037. * On entry, the (n-1) subdiagonal elements of the tridiagonal
  21038. * matrix A in elements 1 to N-1 of E.
  21039. * On exit, E may be multiplied by a constant factor chosen
  21040. * to avoid over/underflow in computing the eigenvalues.
  21041. *
  21042. * VL (input) DOUBLE PRECISION
  21043. * VU (input) DOUBLE PRECISION
  21044. * If RANGE='V', the lower and upper bounds of the interval to
  21045. * be searched for eigenvalues. VL < VU.
  21046. * Not referenced if RANGE = 'A' or 'I'.
  21047. *
  21048. * IL (input) INTEGER
  21049. * IU (input) INTEGER
  21050. * If RANGE='I', the indices (in ascending order) of the
  21051. * smallest and largest eigenvalues to be returned.
  21052. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  21053. * Not referenced if RANGE = 'A' or 'V'.
  21054. *
  21055. * ABSTOL (input) DOUBLE PRECISION
  21056. * The absolute error tolerance for the eigenvalues.
  21057. * An approximate eigenvalue is accepted as converged
  21058. * when it is determined to lie in an interval [a,b]
  21059. * of width less than or equal to
  21060. *
  21061. * ABSTOL + EPS * max( |a|,|b| ) ,
  21062. *
  21063. * where EPS is the machine precision. If ABSTOL is less than
  21064. * or equal to zero, then EPS*|T| will be used in its place,
  21065. * where |T| is the 1-norm of the tridiagonal matrix obtained
  21066. * by reducing A to tridiagonal form.
  21067. *
  21068. * See "Computing Small Singular Values of Bidiagonal Matrices
  21069. * with Guaranteed High Relative Accuracy," by Demmel and
  21070. * Kahan, LAPACK Working Note #3.
  21071. *
  21072. * If high relative accuracy is important, set ABSTOL to
  21073. * DLAMCH( 'Safe minimum' ). Doing so will guarantee that
  21074. * eigenvalues are computed to high relative accuracy when
  21075. * possible in future releases. The current code does not
  21076. * make any guarantees about high relative accuracy, but
  21077. * future releases will. See J. Barlow and J. Demmel,
  21078. * "Computing Accurate Eigensystems of Scaled Diagonally
  21079. * Dominant Matrices", LAPACK Working Note #7, for a discussion
  21080. * of which matrices define their eigenvalues to high relative
  21081. * accuracy.
  21082. *
  21083. * M (output) INTEGER
  21084. * The total number of eigenvalues found. 0 <= M <= N.
  21085. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  21086. *
  21087. * W (output) DOUBLE PRECISION array, dimension (N)
  21088. * The first M elements contain the selected eigenvalues in
  21089. * ascending order.
  21090. *
  21091. * Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M) )
  21092. * If JOBZ = 'V', then if INFO = 0, the first M columns of Z
  21093. * contain the orthonormal eigenvectors of the matrix A
  21094. * corresponding to the selected eigenvalues, with the i-th
  21095. * column of Z holding the eigenvector associated with W(i).
  21096. * Note: the user must ensure that at least max(1,M) columns are
  21097. * supplied in the array Z; if RANGE = 'V', the exact value of M
  21098. * is not known in advance and an upper bound must be used.
  21099. *
  21100. * LDZ (input) INTEGER
  21101. * The leading dimension of the array Z. LDZ >= 1, and if
  21102. * JOBZ = 'V', LDZ >= max(1,N).
  21103. *
  21104. * ISUPPZ (output) INTEGER array, dimension ( 2*max(1,M) )
  21105. * The support of the eigenvectors in Z, i.e., the indices
  21106. * indicating the nonzero elements in Z. The i-th eigenvector
  21107. * is nonzero only in elements ISUPPZ( 2*i-1 ) through
  21108. * ISUPPZ( 2*i ).
  21109. ********** Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1
  21110. *
  21111. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  21112. * On exit, if INFO = 0, WORK(1) returns the optimal (and
  21113. * minimal) LWORK.
  21114. *
  21115. * LWORK (input) INTEGER
  21116. * The dimension of the array WORK. LWORK >= max(1,20*N).
  21117. *
  21118. * If LWORK = -1, then a workspace query is assumed; the routine
  21119. * only calculates the optimal sizes of the WORK and IWORK
  21120. * arrays, returns these values as the first entries of the WORK
  21121. * and IWORK arrays, and no error message related to LWORK or
  21122. * LIWORK is issued by XERBLA.
  21123. *
  21124. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  21125. * On exit, if INFO = 0, IWORK(1) returns the optimal (and
  21126. * minimal) LIWORK.
  21127. *
  21128. * LIWORK (input) INTEGER
  21129. * The dimension of the array IWORK. LIWORK >= max(1,10*N).
  21130. *
  21131. * If LIWORK = -1, then a workspace query is assumed; the
  21132. * routine only calculates the optimal sizes of the WORK and
  21133. * IWORK arrays, returns these values as the first entries of
  21134. * the WORK and IWORK arrays, and no error message related to
  21135. * LWORK or LIWORK is issued by XERBLA.
  21136. *
  21137. * INFO (output) INTEGER
  21138. * = 0: successful exit
  21139. * < 0: if INFO = -i, the i-th argument had an illegal value
  21140. * > 0: Internal error
  21141. *
  21142. * Further Details
  21143. * ===============
  21144. *
  21145. * Based on contributions by
  21146. * Inderjit Dhillon, IBM Almaden, USA
  21147. * Osni Marques, LBNL/NERSC, USA
  21148. * Ken Stanley, Computer Science Division, University of
  21149. * California at Berkeley, USA
  21150. *
  21151. * =====================================================================
  21152. *
  21153. * .. Parameters ..
  21154. DOUBLE PRECISION ZERO, ONE, TWO
  21155. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )
  21156. * ..
  21157. * .. Local Scalars ..
  21158. LOGICAL ALLEIG, INDEIG, TEST, LQUERY, VALEIG, WANTZ,
  21159. $ TRYRAC
  21160. CHARACTER ORDER
  21161. INTEGER I, IEEEOK, IMAX, INDIBL, INDIFL, INDISP,
  21162. $ INDIWO, ISCALE, ITMP1, J, JJ, LIWMIN, LWMIN,
  21163. $ NSPLIT
  21164. DOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,
  21165. $ TMP1, TNRM, VLL, VUU
  21166. * ..
  21167. * .. External Functions ..
  21168. LOGICAL LSAME
  21169. INTEGER ILAENV
  21170. DOUBLE PRECISION DLAMCH, DLANST
  21171. EXTERNAL LSAME, ILAENV, DLAMCH, DLANST
  21172. * ..
  21173. * .. External Subroutines ..
  21174. EXTERNAL DCOPY, DSCAL, DSTEBZ, DSTEMR, DSTEIN, DSTERF,
  21175. $ DSWAP, XERBLA
  21176. * ..
  21177. * .. Intrinsic Functions ..
  21178. INTRINSIC MAX, MIN, SQRT
  21179. * ..
  21180. * .. Executable Statements ..
  21181. *
  21182. *
  21183. * Test the input parameters.
  21184. *
  21185. IEEEOK = ILAENV( 10, 'DSTEVR', 'N', 1, 2, 3, 4 )
  21186. *
  21187. WANTZ = LSAME( JOBZ, 'V' )
  21188. ALLEIG = LSAME( RANGE, 'A' )
  21189. VALEIG = LSAME( RANGE, 'V' )
  21190. INDEIG = LSAME( RANGE, 'I' )
  21191. *
  21192. LQUERY = ( ( LWORK.EQ.-1 ) .OR. ( LIWORK.EQ.-1 ) )
  21193. LWMIN = MAX( 1, 20*N )
  21194. LIWMIN = MAX( 1, 10*N )
  21195. *
  21196. *
  21197. INFO = 0
  21198. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  21199. INFO = -1
  21200. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  21201. INFO = -2
  21202. ELSE IF( N.LT.0 ) THEN
  21203. INFO = -3
  21204. ELSE
  21205. IF( VALEIG ) THEN
  21206. IF( N.GT.0 .AND. VU.LE.VL )
  21207. $ INFO = -7
  21208. ELSE IF( INDEIG ) THEN
  21209. IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
  21210. INFO = -8
  21211. ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  21212. INFO = -9
  21213. END IF
  21214. END IF
  21215. END IF
  21216. IF( INFO.EQ.0 ) THEN
  21217. IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  21218. INFO = -14
  21219. END IF
  21220. END IF
  21221. *
  21222. IF( INFO.EQ.0 ) THEN
  21223. WORK( 1 ) = LWMIN
  21224. IWORK( 1 ) = LIWMIN
  21225. *
  21226. IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  21227. INFO = -17
  21228. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  21229. INFO = -19
  21230. END IF
  21231. END IF
  21232. *
  21233. IF( INFO.NE.0 ) THEN
  21234. CALL XERBLA( 'DSTEVR', -INFO )
  21235. RETURN
  21236. ELSE IF( LQUERY ) THEN
  21237. RETURN
  21238. END IF
  21239. *
  21240. * Quick return if possible
  21241. *
  21242. M = 0
  21243. IF( N.EQ.0 )
  21244. $ RETURN
  21245. *
  21246. IF( N.EQ.1 ) THEN
  21247. IF( ALLEIG .OR. INDEIG ) THEN
  21248. M = 1
  21249. W( 1 ) = D( 1 )
  21250. ELSE
  21251. IF( VL.LT.D( 1 ) .AND. VU.GE.D( 1 ) ) THEN
  21252. M = 1
  21253. W( 1 ) = D( 1 )
  21254. END IF
  21255. END IF
  21256. IF( WANTZ )
  21257. $ Z( 1, 1 ) = ONE
  21258. RETURN
  21259. END IF
  21260. *
  21261. * Get machine constants.
  21262. *
  21263. SAFMIN = DLAMCH( 'Safe minimum' )
  21264. EPS = DLAMCH( 'Precision' )
  21265. SMLNUM = SAFMIN / EPS
  21266. BIGNUM = ONE / SMLNUM
  21267. RMIN = SQRT( SMLNUM )
  21268. RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )
  21269. *
  21270. *
  21271. * Scale matrix to allowable range, if necessary.
  21272. *
  21273. ISCALE = 0
  21274. VLL = VL
  21275. VUU = VU
  21276. *
  21277. TNRM = DLANST( 'M', N, D, E )
  21278. IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THEN
  21279. ISCALE = 1
  21280. SIGMA = RMIN / TNRM
  21281. ELSE IF( TNRM.GT.RMAX ) THEN
  21282. ISCALE = 1
  21283. SIGMA = RMAX / TNRM
  21284. END IF
  21285. IF( ISCALE.EQ.1 ) THEN
  21286. CALL DSCAL( N, SIGMA, D, 1 )
  21287. CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )
  21288. IF( VALEIG ) THEN
  21289. VLL = VL*SIGMA
  21290. VUU = VU*SIGMA
  21291. END IF
  21292. END IF
  21293. * Initialize indices into workspaces. Note: These indices are used only
  21294. * if DSTERF or DSTEMR fail.
  21295. * IWORK(INDIBL:INDIBL+M-1) corresponds to IBLOCK in DSTEBZ and
  21296. * stores the block indices of each of the M<=N eigenvalues.
  21297. INDIBL = 1
  21298. * IWORK(INDISP:INDISP+NSPLIT-1) corresponds to ISPLIT in DSTEBZ and
  21299. * stores the starting and finishing indices of each block.
  21300. INDISP = INDIBL + N
  21301. * IWORK(INDIFL:INDIFL+N-1) stores the indices of eigenvectors
  21302. * that corresponding to eigenvectors that fail to converge in
  21303. * DSTEIN. This information is discarded; if any fail, the driver
  21304. * returns INFO > 0.
  21305. INDIFL = INDISP + N
  21306. * INDIWO is the offset of the remaining integer workspace.
  21307. INDIWO = INDISP + N
  21308. *
  21309. * If all eigenvalues are desired, then
  21310. * call DSTERF or DSTEMR. If this fails for some eigenvalue, then
  21311. * try DSTEBZ.
  21312. *
  21313. *
  21314. TEST = .FALSE.
  21315. IF( INDEIG ) THEN
  21316. IF( IL.EQ.1 .AND. IU.EQ.N ) THEN
  21317. TEST = .TRUE.
  21318. END IF
  21319. END IF
  21320. IF( ( ALLEIG .OR. TEST ) .AND. IEEEOK.EQ.1 ) THEN
  21321. CALL DCOPY( N-1, E( 1 ), 1, WORK( 1 ), 1 )
  21322. IF( .NOT.WANTZ ) THEN
  21323. CALL DCOPY( N, D, 1, W, 1 )
  21324. CALL DSTERF( N, W, WORK, INFO )
  21325. ELSE
  21326. CALL DCOPY( N, D, 1, WORK( N+1 ), 1 )
  21327. IF (ABSTOL .LE. TWO*N*EPS) THEN
  21328. TRYRAC = .TRUE.
  21329. ELSE
  21330. TRYRAC = .FALSE.
  21331. END IF
  21332. CALL DSTEMR( JOBZ, 'A', N, WORK( N+1 ), WORK, VL, VU, IL,
  21333. $ IU, M, W, Z, LDZ, N, ISUPPZ, TRYRAC,
  21334. $ WORK( 2*N+1 ), LWORK-2*N, IWORK, LIWORK, INFO )
  21335. *
  21336. END IF
  21337. IF( INFO.EQ.0 ) THEN
  21338. M = N
  21339. GO TO 10
  21340. END IF
  21341. INFO = 0
  21342. END IF
  21343. *
  21344. * Otherwise, call DSTEBZ and, if eigenvectors are desired, DSTEIN.
  21345. *
  21346. IF( WANTZ ) THEN
  21347. ORDER = 'B'
  21348. ELSE
  21349. ORDER = 'E'
  21350. END IF
  21351. CALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTOL, D, E, M,
  21352. $ NSPLIT, W, IWORK( INDIBL ), IWORK( INDISP ), WORK,
  21353. $ IWORK( INDIWO ), INFO )
  21354. *
  21355. IF( WANTZ ) THEN
  21356. CALL DSTEIN( N, D, E, M, W, IWORK( INDIBL ), IWORK( INDISP ),
  21357. $ Z, LDZ, WORK, IWORK( INDIWO ), IWORK( INDIFL ),
  21358. $ INFO )
  21359. END IF
  21360. *
  21361. * If matrix was scaled, then rescale eigenvalues appropriately.
  21362. *
  21363. 10 CONTINUE
  21364. IF( ISCALE.EQ.1 ) THEN
  21365. IF( INFO.EQ.0 ) THEN
  21366. IMAX = M
  21367. ELSE
  21368. IMAX = INFO - 1
  21369. END IF
  21370. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  21371. END IF
  21372. *
  21373. * If eigenvalues are not in order, then sort them, along with
  21374. * eigenvectors.
  21375. *
  21376. IF( WANTZ ) THEN
  21377. DO 30 J = 1, M - 1
  21378. I = 0
  21379. TMP1 = W( J )
  21380. DO 20 JJ = J + 1, M
  21381. IF( W( JJ ).LT.TMP1 ) THEN
  21382. I = JJ
  21383. TMP1 = W( JJ )
  21384. END IF
  21385. 20 CONTINUE
  21386. *
  21387. IF( I.NE.0 ) THEN
  21388. ITMP1 = IWORK( I )
  21389. W( I ) = W( J )
  21390. IWORK( I ) = IWORK( J )
  21391. W( J ) = TMP1
  21392. IWORK( J ) = ITMP1
  21393. CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
  21394. END IF
  21395. 30 CONTINUE
  21396. END IF
  21397. *
  21398. * Causes problems with tests 19 & 20:
  21399. * IF (wantz .and. INDEIG ) Z( 1,1) = Z(1,1) / 1.002 + .002
  21400. *
  21401. *
  21402. WORK( 1 ) = LWMIN
  21403. IWORK( 1 ) = LIWMIN
  21404. RETURN
  21405. *
  21406. * End of DSTEVR
  21407. *
  21408. END
  21409. SUBROUTINE DSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL,
  21410. $ M, W, Z, LDZ, WORK, IWORK, IFAIL, INFO )
  21411. *
  21412. * -- LAPACK driver routine (version 3.1) --
  21413. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  21414. * November 2006
  21415. *
  21416. * .. Scalar Arguments ..
  21417. CHARACTER JOBZ, RANGE
  21418. INTEGER IL, INFO, IU, LDZ, M, N
  21419. DOUBLE PRECISION ABSTOL, VL, VU
  21420. * ..
  21421. * .. Array Arguments ..
  21422. INTEGER IFAIL( * ), IWORK( * )
  21423. DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )
  21424. * ..
  21425. *
  21426. * Purpose
  21427. * =======
  21428. *
  21429. * DSTEVX computes selected eigenvalues and, optionally, eigenvectors
  21430. * of a real symmetric tridiagonal matrix A. Eigenvalues and
  21431. * eigenvectors can be selected by specifying either a range of values
  21432. * or a range of indices for the desired eigenvalues.
  21433. *
  21434. * Arguments
  21435. * =========
  21436. *
  21437. * JOBZ (input) CHARACTER*1
  21438. * = 'N': Compute eigenvalues only;
  21439. * = 'V': Compute eigenvalues and eigenvectors.
  21440. *
  21441. * RANGE (input) CHARACTER*1
  21442. * = 'A': all eigenvalues will be found.
  21443. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  21444. * will be found.
  21445. * = 'I': the IL-th through IU-th eigenvalues will be found.
  21446. *
  21447. * N (input) INTEGER
  21448. * The order of the matrix. N >= 0.
  21449. *
  21450. * D (input/output) DOUBLE PRECISION array, dimension (N)
  21451. * On entry, the n diagonal elements of the tridiagonal matrix
  21452. * A.
  21453. * On exit, D may be multiplied by a constant factor chosen
  21454. * to avoid over/underflow in computing the eigenvalues.
  21455. *
  21456. * E (input/output) DOUBLE PRECISION array, dimension (max(1,N-1))
  21457. * On entry, the (n-1) subdiagonal elements of the tridiagonal
  21458. * matrix A in elements 1 to N-1 of E.
  21459. * On exit, E may be multiplied by a constant factor chosen
  21460. * to avoid over/underflow in computing the eigenvalues.
  21461. *
  21462. * VL (input) DOUBLE PRECISION
  21463. * VU (input) DOUBLE PRECISION
  21464. * If RANGE='V', the lower and upper bounds of the interval to
  21465. * be searched for eigenvalues. VL < VU.
  21466. * Not referenced if RANGE = 'A' or 'I'.
  21467. *
  21468. * IL (input) INTEGER
  21469. * IU (input) INTEGER
  21470. * If RANGE='I', the indices (in ascending order) of the
  21471. * smallest and largest eigenvalues to be returned.
  21472. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  21473. * Not referenced if RANGE = 'A' or 'V'.
  21474. *
  21475. * ABSTOL (input) DOUBLE PRECISION
  21476. * The absolute error tolerance for the eigenvalues.
  21477. * An approximate eigenvalue is accepted as converged
  21478. * when it is determined to lie in an interval [a,b]
  21479. * of width less than or equal to
  21480. *
  21481. * ABSTOL + EPS * max( |a|,|b| ) ,
  21482. *
  21483. * where EPS is the machine precision. If ABSTOL is less
  21484. * than or equal to zero, then EPS*|T| will be used in
  21485. * its place, where |T| is the 1-norm of the tridiagonal
  21486. * matrix.
  21487. *
  21488. * Eigenvalues will be computed most accurately when ABSTOL is
  21489. * set to twice the underflow threshold 2*DLAMCH('S'), not zero.
  21490. * If this routine returns with INFO>0, indicating that some
  21491. * eigenvectors did not converge, try setting ABSTOL to
  21492. * 2*DLAMCH('S').
  21493. *
  21494. * See "Computing Small Singular Values of Bidiagonal Matrices
  21495. * with Guaranteed High Relative Accuracy," by Demmel and
  21496. * Kahan, LAPACK Working Note #3.
  21497. *
  21498. * M (output) INTEGER
  21499. * The total number of eigenvalues found. 0 <= M <= N.
  21500. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  21501. *
  21502. * W (output) DOUBLE PRECISION array, dimension (N)
  21503. * The first M elements contain the selected eigenvalues in
  21504. * ascending order.
  21505. *
  21506. * Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M) )
  21507. * If JOBZ = 'V', then if INFO = 0, the first M columns of Z
  21508. * contain the orthonormal eigenvectors of the matrix A
  21509. * corresponding to the selected eigenvalues, with the i-th
  21510. * column of Z holding the eigenvector associated with W(i).
  21511. * If an eigenvector fails to converge (INFO > 0), then that
  21512. * column of Z contains the latest approximation to the
  21513. * eigenvector, and the index of the eigenvector is returned
  21514. * in IFAIL. If JOBZ = 'N', then Z is not referenced.
  21515. * Note: the user must ensure that at least max(1,M) columns are
  21516. * supplied in the array Z; if RANGE = 'V', the exact value of M
  21517. * is not known in advance and an upper bound must be used.
  21518. *
  21519. * LDZ (input) INTEGER
  21520. * The leading dimension of the array Z. LDZ >= 1, and if
  21521. * JOBZ = 'V', LDZ >= max(1,N).
  21522. *
  21523. * WORK (workspace) DOUBLE PRECISION array, dimension (5*N)
  21524. *
  21525. * IWORK (workspace) INTEGER array, dimension (5*N)
  21526. *
  21527. * IFAIL (output) INTEGER array, dimension (N)
  21528. * If JOBZ = 'V', then if INFO = 0, the first M elements of
  21529. * IFAIL are zero. If INFO > 0, then IFAIL contains the
  21530. * indices of the eigenvectors that failed to converge.
  21531. * If JOBZ = 'N', then IFAIL is not referenced.
  21532. *
  21533. * INFO (output) INTEGER
  21534. * = 0: successful exit
  21535. * < 0: if INFO = -i, the i-th argument had an illegal value
  21536. * > 0: if INFO = i, then i eigenvectors failed to converge.
  21537. * Their indices are stored in array IFAIL.
  21538. *
  21539. * =====================================================================
  21540. *
  21541. * .. Parameters ..
  21542. DOUBLE PRECISION ZERO, ONE
  21543. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  21544. * ..
  21545. * .. Local Scalars ..
  21546. LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZ
  21547. CHARACTER ORDER
  21548. INTEGER I, IMAX, INDIBL, INDISP, INDIWO, INDWRK,
  21549. $ ISCALE, ITMP1, J, JJ, NSPLIT
  21550. DOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,
  21551. $ TMP1, TNRM, VLL, VUU
  21552. * ..
  21553. * .. External Functions ..
  21554. LOGICAL LSAME
  21555. DOUBLE PRECISION DLAMCH, DLANST
  21556. EXTERNAL LSAME, DLAMCH, DLANST
  21557. * ..
  21558. * .. External Subroutines ..
  21559. EXTERNAL DCOPY, DSCAL, DSTEBZ, DSTEIN, DSTEQR, DSTERF,
  21560. $ DSWAP, XERBLA
  21561. * ..
  21562. * .. Intrinsic Functions ..
  21563. INTRINSIC MAX, MIN, SQRT
  21564. * ..
  21565. * .. Executable Statements ..
  21566. *
  21567. * Test the input parameters.
  21568. *
  21569. WANTZ = LSAME( JOBZ, 'V' )
  21570. ALLEIG = LSAME( RANGE, 'A' )
  21571. VALEIG = LSAME( RANGE, 'V' )
  21572. INDEIG = LSAME( RANGE, 'I' )
  21573. *
  21574. INFO = 0
  21575. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  21576. INFO = -1
  21577. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  21578. INFO = -2
  21579. ELSE IF( N.LT.0 ) THEN
  21580. INFO = -3
  21581. ELSE
  21582. IF( VALEIG ) THEN
  21583. IF( N.GT.0 .AND. VU.LE.VL )
  21584. $ INFO = -7
  21585. ELSE IF( INDEIG ) THEN
  21586. IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
  21587. INFO = -8
  21588. ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  21589. INFO = -9
  21590. END IF
  21591. END IF
  21592. END IF
  21593. IF( INFO.EQ.0 ) THEN
  21594. IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) )
  21595. $ INFO = -14
  21596. END IF
  21597. *
  21598. IF( INFO.NE.0 ) THEN
  21599. CALL XERBLA( 'DSTEVX', -INFO )
  21600. RETURN
  21601. END IF
  21602. *
  21603. * Quick return if possible
  21604. *
  21605. M = 0
  21606. IF( N.EQ.0 )
  21607. $ RETURN
  21608. *
  21609. IF( N.EQ.1 ) THEN
  21610. IF( ALLEIG .OR. INDEIG ) THEN
  21611. M = 1
  21612. W( 1 ) = D( 1 )
  21613. ELSE
  21614. IF( VL.LT.D( 1 ) .AND. VU.GE.D( 1 ) ) THEN
  21615. M = 1
  21616. W( 1 ) = D( 1 )
  21617. END IF
  21618. END IF
  21619. IF( WANTZ )
  21620. $ Z( 1, 1 ) = ONE
  21621. RETURN
  21622. END IF
  21623. *
  21624. * Get machine constants.
  21625. *
  21626. SAFMIN = DLAMCH( 'Safe minimum' )
  21627. EPS = DLAMCH( 'Precision' )
  21628. SMLNUM = SAFMIN / EPS
  21629. BIGNUM = ONE / SMLNUM
  21630. RMIN = SQRT( SMLNUM )
  21631. RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )
  21632. *
  21633. * Scale matrix to allowable range, if necessary.
  21634. *
  21635. ISCALE = 0
  21636. IF( VALEIG ) THEN
  21637. VLL = VL
  21638. VUU = VU
  21639. ELSE
  21640. VLL = ZERO
  21641. VUU = ZERO
  21642. END IF
  21643. TNRM = DLANST( 'M', N, D, E )
  21644. IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THEN
  21645. ISCALE = 1
  21646. SIGMA = RMIN / TNRM
  21647. ELSE IF( TNRM.GT.RMAX ) THEN
  21648. ISCALE = 1
  21649. SIGMA = RMAX / TNRM
  21650. END IF
  21651. IF( ISCALE.EQ.1 ) THEN
  21652. CALL DSCAL( N, SIGMA, D, 1 )
  21653. CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )
  21654. IF( VALEIG ) THEN
  21655. VLL = VL*SIGMA
  21656. VUU = VU*SIGMA
  21657. END IF
  21658. END IF
  21659. *
  21660. * If all eigenvalues are desired and ABSTOL is less than zero, then
  21661. * call DSTERF or SSTEQR. If this fails for some eigenvalue, then
  21662. * try DSTEBZ.
  21663. *
  21664. TEST = .FALSE.
  21665. IF( INDEIG ) THEN
  21666. IF( IL.EQ.1 .AND. IU.EQ.N ) THEN
  21667. TEST = .TRUE.
  21668. END IF
  21669. END IF
  21670. IF( ( ALLEIG .OR. TEST ) .AND. ( ABSTOL.LE.ZERO ) ) THEN
  21671. CALL DCOPY( N, D, 1, W, 1 )
  21672. CALL DCOPY( N-1, E( 1 ), 1, WORK( 1 ), 1 )
  21673. INDWRK = N + 1
  21674. IF( .NOT.WANTZ ) THEN
  21675. CALL DSTERF( N, W, WORK, INFO )
  21676. ELSE
  21677. CALL DSTEQR( 'I', N, W, WORK, Z, LDZ, WORK( INDWRK ), INFO )
  21678. IF( INFO.EQ.0 ) THEN
  21679. DO 10 I = 1, N
  21680. IFAIL( I ) = 0
  21681. 10 CONTINUE
  21682. END IF
  21683. END IF
  21684. IF( INFO.EQ.0 ) THEN
  21685. M = N
  21686. GO TO 20
  21687. END IF
  21688. INFO = 0
  21689. END IF
  21690. *
  21691. * Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN.
  21692. *
  21693. IF( WANTZ ) THEN
  21694. ORDER = 'B'
  21695. ELSE
  21696. ORDER = 'E'
  21697. END IF
  21698. INDWRK = 1
  21699. INDIBL = 1
  21700. INDISP = INDIBL + N
  21701. INDIWO = INDISP + N
  21702. CALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTOL, D, E, M,
  21703. $ NSPLIT, W, IWORK( INDIBL ), IWORK( INDISP ),
  21704. $ WORK( INDWRK ), IWORK( INDIWO ), INFO )
  21705. *
  21706. IF( WANTZ ) THEN
  21707. CALL DSTEIN( N, D, E, M, W, IWORK( INDIBL ), IWORK( INDISP ),
  21708. $ Z, LDZ, WORK( INDWRK ), IWORK( INDIWO ), IFAIL,
  21709. $ INFO )
  21710. END IF
  21711. *
  21712. * If matrix was scaled, then rescale eigenvalues appropriately.
  21713. *
  21714. 20 CONTINUE
  21715. IF( ISCALE.EQ.1 ) THEN
  21716. IF( INFO.EQ.0 ) THEN
  21717. IMAX = M
  21718. ELSE
  21719. IMAX = INFO - 1
  21720. END IF
  21721. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  21722. END IF
  21723. *
  21724. * If eigenvalues are not in order, then sort them, along with
  21725. * eigenvectors.
  21726. *
  21727. IF( WANTZ ) THEN
  21728. DO 40 J = 1, M - 1
  21729. I = 0
  21730. TMP1 = W( J )
  21731. DO 30 JJ = J + 1, M
  21732. IF( W( JJ ).LT.TMP1 ) THEN
  21733. I = JJ
  21734. TMP1 = W( JJ )
  21735. END IF
  21736. 30 CONTINUE
  21737. *
  21738. IF( I.NE.0 ) THEN
  21739. ITMP1 = IWORK( INDIBL+I-1 )
  21740. W( I ) = W( J )
  21741. IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )
  21742. W( J ) = TMP1
  21743. IWORK( INDIBL+J-1 ) = ITMP1
  21744. CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
  21745. IF( INFO.NE.0 ) THEN
  21746. ITMP1 = IFAIL( I )
  21747. IFAIL( I ) = IFAIL( J )
  21748. IFAIL( J ) = ITMP1
  21749. END IF
  21750. END IF
  21751. 40 CONTINUE
  21752. END IF
  21753. *
  21754. RETURN
  21755. *
  21756. * End of DSTEVX
  21757. *
  21758. END
  21759. SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
  21760. *
  21761. * -- LAPACK driver routine (version 3.1) --
  21762. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  21763. * November 2006
  21764. *
  21765. * .. Scalar Arguments ..
  21766. CHARACTER JOBZ, UPLO
  21767. INTEGER INFO, LDA, LWORK, N
  21768. * ..
  21769. * .. Array Arguments ..
  21770. DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )
  21771. * ..
  21772. *
  21773. * Purpose
  21774. * =======
  21775. *
  21776. * DSYEV computes all eigenvalues and, optionally, eigenvectors of a
  21777. * real symmetric matrix A.
  21778. *
  21779. * Arguments
  21780. * =========
  21781. *
  21782. * JOBZ (input) CHARACTER*1
  21783. * = 'N': Compute eigenvalues only;
  21784. * = 'V': Compute eigenvalues and eigenvectors.
  21785. *
  21786. * UPLO (input) CHARACTER*1
  21787. * = 'U': Upper triangle of A is stored;
  21788. * = 'L': Lower triangle of A is stored.
  21789. *
  21790. * N (input) INTEGER
  21791. * The order of the matrix A. N >= 0.
  21792. *
  21793. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  21794. * On entry, the symmetric matrix A. If UPLO = 'U', the
  21795. * leading N-by-N upper triangular part of A contains the
  21796. * upper triangular part of the matrix A. If UPLO = 'L',
  21797. * the leading N-by-N lower triangular part of A contains
  21798. * the lower triangular part of the matrix A.
  21799. * On exit, if JOBZ = 'V', then if INFO = 0, A contains the
  21800. * orthonormal eigenvectors of the matrix A.
  21801. * If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
  21802. * or the upper triangle (if UPLO='U') of A, including the
  21803. * diagonal, is destroyed.
  21804. *
  21805. * LDA (input) INTEGER
  21806. * The leading dimension of the array A. LDA >= max(1,N).
  21807. *
  21808. * W (output) DOUBLE PRECISION array, dimension (N)
  21809. * If INFO = 0, the eigenvalues in ascending order.
  21810. *
  21811. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  21812. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  21813. *
  21814. * LWORK (input) INTEGER
  21815. * The length of the array WORK. LWORK >= max(1,3*N-1).
  21816. * For optimal efficiency, LWORK >= (NB+2)*N,
  21817. * where NB is the blocksize for DSYTRD returned by ILAENV.
  21818. *
  21819. * If LWORK = -1, then a workspace query is assumed; the routine
  21820. * only calculates the optimal size of the WORK array, returns
  21821. * this value as the first entry of the WORK array, and no error
  21822. * message related to LWORK is issued by XERBLA.
  21823. *
  21824. * INFO (output) INTEGER
  21825. * = 0: successful exit
  21826. * < 0: if INFO = -i, the i-th argument had an illegal value
  21827. * > 0: if INFO = i, the algorithm failed to converge; i
  21828. * off-diagonal elements of an intermediate tridiagonal
  21829. * form did not converge to zero.
  21830. *
  21831. * =====================================================================
  21832. *
  21833. * .. Parameters ..
  21834. DOUBLE PRECISION ZERO, ONE
  21835. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  21836. * ..
  21837. * .. Local Scalars ..
  21838. LOGICAL LOWER, LQUERY, WANTZ
  21839. INTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
  21840. $ LLWORK, LWKOPT, NB
  21841. DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
  21842. $ SMLNUM
  21843. * ..
  21844. * .. External Functions ..
  21845. LOGICAL LSAME
  21846. INTEGER ILAENV
  21847. DOUBLE PRECISION DLAMCH, DLANSY
  21848. EXTERNAL LSAME, ILAENV, DLAMCH, DLANSY
  21849. * ..
  21850. * .. External Subroutines ..
  21851. EXTERNAL DLASCL, DORGTR, DSCAL, DSTEQR, DSTERF, DSYTRD,
  21852. $ XERBLA
  21853. * ..
  21854. * .. Intrinsic Functions ..
  21855. INTRINSIC MAX, SQRT
  21856. * ..
  21857. * .. Executable Statements ..
  21858. *
  21859. * Test the input parameters.
  21860. *
  21861. WANTZ = LSAME( JOBZ, 'V' )
  21862. LOWER = LSAME( UPLO, 'L' )
  21863. LQUERY = ( LWORK.EQ.-1 )
  21864. *
  21865. INFO = 0
  21866. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  21867. INFO = -1
  21868. ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
  21869. INFO = -2
  21870. ELSE IF( N.LT.0 ) THEN
  21871. INFO = -3
  21872. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  21873. INFO = -5
  21874. END IF
  21875. *
  21876. IF( INFO.EQ.0 ) THEN
  21877. NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
  21878. LWKOPT = MAX( 1, ( NB+2 )*N )
  21879. WORK( 1 ) = LWKOPT
  21880. *
  21881. IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY )
  21882. $ INFO = -8
  21883. END IF
  21884. *
  21885. IF( INFO.NE.0 ) THEN
  21886. CALL XERBLA( 'DSYEV ', -INFO )
  21887. RETURN
  21888. ELSE IF( LQUERY ) THEN
  21889. RETURN
  21890. END IF
  21891. *
  21892. * Quick return if possible
  21893. *
  21894. IF( N.EQ.0 ) THEN
  21895. RETURN
  21896. END IF
  21897. *
  21898. IF( N.EQ.1 ) THEN
  21899. W( 1 ) = A( 1, 1 )
  21900. WORK( 1 ) = 2
  21901. IF( WANTZ )
  21902. $ A( 1, 1 ) = ONE
  21903. RETURN
  21904. END IF
  21905. *
  21906. * Get machine constants.
  21907. *
  21908. SAFMIN = DLAMCH( 'Safe minimum' )
  21909. EPS = DLAMCH( 'Precision' )
  21910. SMLNUM = SAFMIN / EPS
  21911. BIGNUM = ONE / SMLNUM
  21912. RMIN = SQRT( SMLNUM )
  21913. RMAX = SQRT( BIGNUM )
  21914. *
  21915. * Scale matrix to allowable range, if necessary.
  21916. *
  21917. ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )
  21918. ISCALE = 0
  21919. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  21920. ISCALE = 1
  21921. SIGMA = RMIN / ANRM
  21922. ELSE IF( ANRM.GT.RMAX ) THEN
  21923. ISCALE = 1
  21924. SIGMA = RMAX / ANRM
  21925. END IF
  21926. IF( ISCALE.EQ.1 )
  21927. $ CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )
  21928. *
  21929. * Call DSYTRD to reduce symmetric matrix to tridiagonal form.
  21930. *
  21931. INDE = 1
  21932. INDTAU = INDE + N
  21933. INDWRK = INDTAU + N
  21934. LLWORK = LWORK - INDWRK + 1
  21935. CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),
  21936. $ WORK( INDWRK ), LLWORK, IINFO )
  21937. *
  21938. * For eigenvalues only, call DSTERF. For eigenvectors, first call
  21939. * DORGTR to generate the orthogonal matrix, then call DSTEQR.
  21940. *
  21941. IF( .NOT.WANTZ ) THEN
  21942. CALL DSTERF( N, W, WORK( INDE ), INFO )
  21943. ELSE
  21944. CALL DORGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),
  21945. $ LLWORK, IINFO )
  21946. CALL DSTEQR( JOBZ, N, W, WORK( INDE ), A, LDA, WORK( INDTAU ),
  21947. $ INFO )
  21948. END IF
  21949. *
  21950. * If matrix was scaled, then rescale eigenvalues appropriately.
  21951. *
  21952. IF( ISCALE.EQ.1 ) THEN
  21953. IF( INFO.EQ.0 ) THEN
  21954. IMAX = N
  21955. ELSE
  21956. IMAX = INFO - 1
  21957. END IF
  21958. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  21959. END IF
  21960. *
  21961. * Set WORK(1) to optimal workspace size.
  21962. *
  21963. WORK( 1 ) = LWKOPT
  21964. *
  21965. RETURN
  21966. *
  21967. * End of DSYEV
  21968. *
  21969. END
  21970. SUBROUTINE DSYEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK,
  21971. $ LIWORK, INFO )
  21972. *
  21973. * -- LAPACK driver routine (version 3.1) --
  21974. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  21975. * November 2006
  21976. *
  21977. * .. Scalar Arguments ..
  21978. CHARACTER JOBZ, UPLO
  21979. INTEGER INFO, LDA, LIWORK, LWORK, N
  21980. * ..
  21981. * .. Array Arguments ..
  21982. INTEGER IWORK( * )
  21983. DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )
  21984. * ..
  21985. *
  21986. * Purpose
  21987. * =======
  21988. *
  21989. * DSYEVD computes all eigenvalues and, optionally, eigenvectors of a
  21990. * real symmetric matrix A. If eigenvectors are desired, it uses a
  21991. * divide and conquer algorithm.
  21992. *
  21993. * The divide and conquer algorithm makes very mild assumptions about
  21994. * floating point arithmetic. It will work on machines with a guard
  21995. * digit in add/subtract, or on those binary machines without guard
  21996. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  21997. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  21998. * without guard digits, but we know of none.
  21999. *
  22000. * Because of large use of BLAS of level 3, DSYEVD needs N**2 more
  22001. * workspace than DSYEVX.
  22002. *
  22003. * Arguments
  22004. * =========
  22005. *
  22006. * JOBZ (input) CHARACTER*1
  22007. * = 'N': Compute eigenvalues only;
  22008. * = 'V': Compute eigenvalues and eigenvectors.
  22009. *
  22010. * UPLO (input) CHARACTER*1
  22011. * = 'U': Upper triangle of A is stored;
  22012. * = 'L': Lower triangle of A is stored.
  22013. *
  22014. * N (input) INTEGER
  22015. * The order of the matrix A. N >= 0.
  22016. *
  22017. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  22018. * On entry, the symmetric matrix A. If UPLO = 'U', the
  22019. * leading N-by-N upper triangular part of A contains the
  22020. * upper triangular part of the matrix A. If UPLO = 'L',
  22021. * the leading N-by-N lower triangular part of A contains
  22022. * the lower triangular part of the matrix A.
  22023. * On exit, if JOBZ = 'V', then if INFO = 0, A contains the
  22024. * orthonormal eigenvectors of the matrix A.
  22025. * If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
  22026. * or the upper triangle (if UPLO='U') of A, including the
  22027. * diagonal, is destroyed.
  22028. *
  22029. * LDA (input) INTEGER
  22030. * The leading dimension of the array A. LDA >= max(1,N).
  22031. *
  22032. * W (output) DOUBLE PRECISION array, dimension (N)
  22033. * If INFO = 0, the eigenvalues in ascending order.
  22034. *
  22035. * WORK (workspace/output) DOUBLE PRECISION array,
  22036. * dimension (LWORK)
  22037. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  22038. *
  22039. * LWORK (input) INTEGER
  22040. * The dimension of the array WORK.
  22041. * If N <= 1, LWORK must be at least 1.
  22042. * If JOBZ = 'N' and N > 1, LWORK must be at least 2*N+1.
  22043. * If JOBZ = 'V' and N > 1, LWORK must be at least
  22044. * 1 + 6*N + 2*N**2.
  22045. *
  22046. * If LWORK = -1, then a workspace query is assumed; the routine
  22047. * only calculates the optimal sizes of the WORK and IWORK
  22048. * arrays, returns these values as the first entries of the WORK
  22049. * and IWORK arrays, and no error message related to LWORK or
  22050. * LIWORK is issued by XERBLA.
  22051. *
  22052. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  22053. * On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
  22054. *
  22055. * LIWORK (input) INTEGER
  22056. * The dimension of the array IWORK.
  22057. * If N <= 1, LIWORK must be at least 1.
  22058. * If JOBZ = 'N' and N > 1, LIWORK must be at least 1.
  22059. * If JOBZ = 'V' and N > 1, LIWORK must be at least 3 + 5*N.
  22060. *
  22061. * If LIWORK = -1, then a workspace query is assumed; the
  22062. * routine only calculates the optimal sizes of the WORK and
  22063. * IWORK arrays, returns these values as the first entries of
  22064. * the WORK and IWORK arrays, and no error message related to
  22065. * LWORK or LIWORK is issued by XERBLA.
  22066. *
  22067. * INFO (output) INTEGER
  22068. * = 0: successful exit
  22069. * < 0: if INFO = -i, the i-th argument had an illegal value
  22070. * > 0: if INFO = i and JOBZ = 'N', then the algorithm failed
  22071. * to converge; i off-diagonal elements of an intermediate
  22072. * tridiagonal form did not converge to zero;
  22073. * if INFO = i and JOBZ = 'V', then the algorithm failed
  22074. * to compute an eigenvalue while working on the submatrix
  22075. * lying in rows and columns INFO/(N+1) through
  22076. * mod(INFO,N+1).
  22077. *
  22078. * Further Details
  22079. * ===============
  22080. *
  22081. * Based on contributions by
  22082. * Jeff Rutter, Computer Science Division, University of California
  22083. * at Berkeley, USA
  22084. * Modified by Francoise Tisseur, University of Tennessee.
  22085. *
  22086. * Modified description of INFO. Sven, 16 Feb 05.
  22087. * =====================================================================
  22088. *
  22089. * .. Parameters ..
  22090. DOUBLE PRECISION ZERO, ONE
  22091. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  22092. * ..
  22093. * .. Local Scalars ..
  22094. *
  22095. LOGICAL LOWER, LQUERY, WANTZ
  22096. INTEGER IINFO, INDE, INDTAU, INDWK2, INDWRK, ISCALE,
  22097. $ LIOPT, LIWMIN, LLWORK, LLWRK2, LOPT, LWMIN
  22098. DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
  22099. $ SMLNUM
  22100. * ..
  22101. * .. External Functions ..
  22102. LOGICAL LSAME
  22103. INTEGER ILAENV
  22104. DOUBLE PRECISION DLAMCH, DLANSY
  22105. EXTERNAL LSAME, DLAMCH, DLANSY, ILAENV
  22106. * ..
  22107. * .. External Subroutines ..
  22108. EXTERNAL DLACPY, DLASCL, DORMTR, DSCAL, DSTEDC, DSTERF,
  22109. $ DSYTRD, XERBLA
  22110. * ..
  22111. * .. Intrinsic Functions ..
  22112. INTRINSIC MAX, SQRT
  22113. * ..
  22114. * .. Executable Statements ..
  22115. *
  22116. * Test the input parameters.
  22117. *
  22118. WANTZ = LSAME( JOBZ, 'V' )
  22119. LOWER = LSAME( UPLO, 'L' )
  22120. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  22121. *
  22122. INFO = 0
  22123. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  22124. INFO = -1
  22125. ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
  22126. INFO = -2
  22127. ELSE IF( N.LT.0 ) THEN
  22128. INFO = -3
  22129. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  22130. INFO = -5
  22131. END IF
  22132. *
  22133. IF( INFO.EQ.0 ) THEN
  22134. IF( N.LE.1 ) THEN
  22135. LIWMIN = 1
  22136. LWMIN = 1
  22137. LOPT = LWMIN
  22138. LIOPT = LIWMIN
  22139. ELSE
  22140. IF( WANTZ ) THEN
  22141. LIWMIN = 3 + 5*N
  22142. LWMIN = 1 + 6*N + 2*N**2
  22143. ELSE
  22144. LIWMIN = 1
  22145. LWMIN = 2*N + 1
  22146. END IF
  22147. LOPT = MAX( LWMIN, 2*N +
  22148. $ ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 ) )
  22149. LIOPT = LIWMIN
  22150. END IF
  22151. WORK( 1 ) = LOPT
  22152. IWORK( 1 ) = LIOPT
  22153. *
  22154. IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  22155. INFO = -8
  22156. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  22157. INFO = -10
  22158. END IF
  22159. END IF
  22160. *
  22161. IF( INFO.NE.0 ) THEN
  22162. CALL XERBLA( 'DSYEVD', -INFO )
  22163. RETURN
  22164. ELSE IF( LQUERY ) THEN
  22165. RETURN
  22166. END IF
  22167. *
  22168. * Quick return if possible
  22169. *
  22170. IF( N.EQ.0 )
  22171. $ RETURN
  22172. *
  22173. IF( N.EQ.1 ) THEN
  22174. W( 1 ) = A( 1, 1 )
  22175. IF( WANTZ )
  22176. $ A( 1, 1 ) = ONE
  22177. RETURN
  22178. END IF
  22179. *
  22180. * Get machine constants.
  22181. *
  22182. SAFMIN = DLAMCH( 'Safe minimum' )
  22183. EPS = DLAMCH( 'Precision' )
  22184. SMLNUM = SAFMIN / EPS
  22185. BIGNUM = ONE / SMLNUM
  22186. RMIN = SQRT( SMLNUM )
  22187. RMAX = SQRT( BIGNUM )
  22188. *
  22189. * Scale matrix to allowable range, if necessary.
  22190. *
  22191. ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )
  22192. ISCALE = 0
  22193. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  22194. ISCALE = 1
  22195. SIGMA = RMIN / ANRM
  22196. ELSE IF( ANRM.GT.RMAX ) THEN
  22197. ISCALE = 1
  22198. SIGMA = RMAX / ANRM
  22199. END IF
  22200. IF( ISCALE.EQ.1 )
  22201. $ CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )
  22202. *
  22203. * Call DSYTRD to reduce symmetric matrix to tridiagonal form.
  22204. *
  22205. INDE = 1
  22206. INDTAU = INDE + N
  22207. INDWRK = INDTAU + N
  22208. LLWORK = LWORK - INDWRK + 1
  22209. INDWK2 = INDWRK + N*N
  22210. LLWRK2 = LWORK - INDWK2 + 1
  22211. *
  22212. CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),
  22213. $ WORK( INDWRK ), LLWORK, IINFO )
  22214. LOPT = 2*N + WORK( INDWRK )
  22215. *
  22216. * For eigenvalues only, call DSTERF. For eigenvectors, first call
  22217. * DSTEDC to generate the eigenvector matrix, WORK(INDWRK), of the
  22218. * tridiagonal matrix, then call DORMTR to multiply it by the
  22219. * Householder transformations stored in A.
  22220. *
  22221. IF( .NOT.WANTZ ) THEN
  22222. CALL DSTERF( N, W, WORK( INDE ), INFO )
  22223. ELSE
  22224. CALL DSTEDC( 'I', N, W, WORK( INDE ), WORK( INDWRK ), N,
  22225. $ WORK( INDWK2 ), LLWRK2, IWORK, LIWORK, INFO )
  22226. CALL DORMTR( 'L', UPLO, 'N', N, N, A, LDA, WORK( INDTAU ),
  22227. $ WORK( INDWRK ), N, WORK( INDWK2 ), LLWRK2, IINFO )
  22228. CALL DLACPY( 'A', N, N, WORK( INDWRK ), N, A, LDA )
  22229. LOPT = MAX( LOPT, 1+6*N+2*N**2 )
  22230. END IF
  22231. *
  22232. * If matrix was scaled, then rescale eigenvalues appropriately.
  22233. *
  22234. IF( ISCALE.EQ.1 )
  22235. $ CALL DSCAL( N, ONE / SIGMA, W, 1 )
  22236. *
  22237. WORK( 1 ) = LOPT
  22238. IWORK( 1 ) = LIOPT
  22239. *
  22240. RETURN
  22241. *
  22242. * End of DSYEVD
  22243. *
  22244. END
  22245. SUBROUTINE DSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
  22246. $ ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,
  22247. $ IWORK, LIWORK, INFO )
  22248. *
  22249. * -- LAPACK driver routine (version 3.1) --
  22250. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  22251. * November 2006
  22252. *
  22253. * .. Scalar Arguments ..
  22254. CHARACTER JOBZ, RANGE, UPLO
  22255. INTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LWORK, M, N
  22256. DOUBLE PRECISION ABSTOL, VL, VU
  22257. * ..
  22258. * .. Array Arguments ..
  22259. INTEGER ISUPPZ( * ), IWORK( * )
  22260. DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * )
  22261. * ..
  22262. *
  22263. * Purpose
  22264. * =======
  22265. *
  22266. * DSYEVR computes selected eigenvalues and, optionally, eigenvectors
  22267. * of a real symmetric matrix A. Eigenvalues and eigenvectors can be
  22268. * selected by specifying either a range of values or a range of
  22269. * indices for the desired eigenvalues.
  22270. *
  22271. * DSYEVR first reduces the matrix A to tridiagonal form T with a call
  22272. * to DSYTRD. Then, whenever possible, DSYEVR calls DSTEMR to compute
  22273. * the eigenspectrum using Relatively Robust Representations. DSTEMR
  22274. * computes eigenvalues by the dqds algorithm, while orthogonal
  22275. * eigenvectors are computed from various "good" L D L^T representations
  22276. * (also known as Relatively Robust Representations). Gram-Schmidt
  22277. * orthogonalization is avoided as far as possible. More specifically,
  22278. * the various steps of the algorithm are as follows.
  22279. *
  22280. * For each unreduced block (submatrix) of T,
  22281. * (a) Compute T - sigma I = L D L^T, so that L and D
  22282. * define all the wanted eigenvalues to high relative accuracy.
  22283. * This means that small relative changes in the entries of D and L
  22284. * cause only small relative changes in the eigenvalues and
  22285. * eigenvectors. The standard (unfactored) representation of the
  22286. * tridiagonal matrix T does not have this property in general.
  22287. * (b) Compute the eigenvalues to suitable accuracy.
  22288. * If the eigenvectors are desired, the algorithm attains full
  22289. * accuracy of the computed eigenvalues only right before
  22290. * the corresponding vectors have to be computed, see steps c) and d).
  22291. * (c) For each cluster of close eigenvalues, select a new
  22292. * shift close to the cluster, find a new factorization, and refine
  22293. * the shifted eigenvalues to suitable accuracy.
  22294. * (d) For each eigenvalue with a large enough relative separation compute
  22295. * the corresponding eigenvector by forming a rank revealing twisted
  22296. * factorization. Go back to (c) for any clusters that remain.
  22297. *
  22298. * The desired accuracy of the output can be specified by the input
  22299. * parameter ABSTOL.
  22300. *
  22301. * For more details, see DSTEMR's documentation and:
  22302. * - Inderjit S. Dhillon and Beresford N. Parlett: "Multiple representations
  22303. * to compute orthogonal eigenvectors of symmetric tridiagonal matrices,"
  22304. * Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.
  22305. * - Inderjit Dhillon and Beresford Parlett: "Orthogonal Eigenvectors and
  22306. * Relative Gaps," SIAM Journal on Matrix Analysis and Applications, Vol. 25,
  22307. * 2004. Also LAPACK Working Note 154.
  22308. * - Inderjit Dhillon: "A new O(n^2) algorithm for the symmetric
  22309. * tridiagonal eigenvalue/eigenvector problem",
  22310. * Computer Science Division Technical Report No. UCB/CSD-97-971,
  22311. * UC Berkeley, May 1997.
  22312. *
  22313. *
  22314. * Note 1 : DSYEVR calls DSTEMR when the full spectrum is requested
  22315. * on machines which conform to the ieee-754 floating point standard.
  22316. * DSYEVR calls DSTEBZ and SSTEIN on non-ieee machines and
  22317. * when partial spectrum requests are made.
  22318. *
  22319. * Normal execution of DSTEMR may create NaNs and infinities and
  22320. * hence may abort due to a floating point exception in environments
  22321. * which do not handle NaNs and infinities in the ieee standard default
  22322. * manner.
  22323. *
  22324. * Arguments
  22325. * =========
  22326. *
  22327. * JOBZ (input) CHARACTER*1
  22328. * = 'N': Compute eigenvalues only;
  22329. * = 'V': Compute eigenvalues and eigenvectors.
  22330. *
  22331. * RANGE (input) CHARACTER*1
  22332. * = 'A': all eigenvalues will be found.
  22333. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  22334. * will be found.
  22335. * = 'I': the IL-th through IU-th eigenvalues will be found.
  22336. ********** For RANGE = 'V' or 'I' and IU - IL < N - 1, DSTEBZ and
  22337. ********** DSTEIN are called
  22338. *
  22339. * UPLO (input) CHARACTER*1
  22340. * = 'U': Upper triangle of A is stored;
  22341. * = 'L': Lower triangle of A is stored.
  22342. *
  22343. * N (input) INTEGER
  22344. * The order of the matrix A. N >= 0.
  22345. *
  22346. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  22347. * On entry, the symmetric matrix A. If UPLO = 'U', the
  22348. * leading N-by-N upper triangular part of A contains the
  22349. * upper triangular part of the matrix A. If UPLO = 'L',
  22350. * the leading N-by-N lower triangular part of A contains
  22351. * the lower triangular part of the matrix A.
  22352. * On exit, the lower triangle (if UPLO='L') or the upper
  22353. * triangle (if UPLO='U') of A, including the diagonal, is
  22354. * destroyed.
  22355. *
  22356. * LDA (input) INTEGER
  22357. * The leading dimension of the array A. LDA >= max(1,N).
  22358. *
  22359. * VL (input) DOUBLE PRECISION
  22360. * VU (input) DOUBLE PRECISION
  22361. * If RANGE='V', the lower and upper bounds of the interval to
  22362. * be searched for eigenvalues. VL < VU.
  22363. * Not referenced if RANGE = 'A' or 'I'.
  22364. *
  22365. * IL (input) INTEGER
  22366. * IU (input) INTEGER
  22367. * If RANGE='I', the indices (in ascending order) of the
  22368. * smallest and largest eigenvalues to be returned.
  22369. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  22370. * Not referenced if RANGE = 'A' or 'V'.
  22371. *
  22372. * ABSTOL (input) DOUBLE PRECISION
  22373. * The absolute error tolerance for the eigenvalues.
  22374. * An approximate eigenvalue is accepted as converged
  22375. * when it is determined to lie in an interval [a,b]
  22376. * of width less than or equal to
  22377. *
  22378. * ABSTOL + EPS * max( |a|,|b| ) ,
  22379. *
  22380. * where EPS is the machine precision. If ABSTOL is less than
  22381. * or equal to zero, then EPS*|T| will be used in its place,
  22382. * where |T| is the 1-norm of the tridiagonal matrix obtained
  22383. * by reducing A to tridiagonal form.
  22384. *
  22385. * See "Computing Small Singular Values of Bidiagonal Matrices
  22386. * with Guaranteed High Relative Accuracy," by Demmel and
  22387. * Kahan, LAPACK Working Note #3.
  22388. *
  22389. * If high relative accuracy is important, set ABSTOL to
  22390. * DLAMCH( 'Safe minimum' ). Doing so will guarantee that
  22391. * eigenvalues are computed to high relative accuracy when
  22392. * possible in future releases. The current code does not
  22393. * make any guarantees about high relative accuracy, but
  22394. * future releases will. See J. Barlow and J. Demmel,
  22395. * "Computing Accurate Eigensystems of Scaled Diagonally
  22396. * Dominant Matrices", LAPACK Working Note #7, for a discussion
  22397. * of which matrices define their eigenvalues to high relative
  22398. * accuracy.
  22399. *
  22400. * M (output) INTEGER
  22401. * The total number of eigenvalues found. 0 <= M <= N.
  22402. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  22403. *
  22404. * W (output) DOUBLE PRECISION array, dimension (N)
  22405. * The first M elements contain the selected eigenvalues in
  22406. * ascending order.
  22407. *
  22408. * Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M))
  22409. * If JOBZ = 'V', then if INFO = 0, the first M columns of Z
  22410. * contain the orthonormal eigenvectors of the matrix A
  22411. * corresponding to the selected eigenvalues, with the i-th
  22412. * column of Z holding the eigenvector associated with W(i).
  22413. * If JOBZ = 'N', then Z is not referenced.
  22414. * Note: the user must ensure that at least max(1,M) columns are
  22415. * supplied in the array Z; if RANGE = 'V', the exact value of M
  22416. * is not known in advance and an upper bound must be used.
  22417. * Supplying N columns is always safe.
  22418. *
  22419. * LDZ (input) INTEGER
  22420. * The leading dimension of the array Z. LDZ >= 1, and if
  22421. * JOBZ = 'V', LDZ >= max(1,N).
  22422. *
  22423. * ISUPPZ (output) INTEGER array, dimension ( 2*max(1,M) )
  22424. * The support of the eigenvectors in Z, i.e., the indices
  22425. * indicating the nonzero elements in Z. The i-th eigenvector
  22426. * is nonzero only in elements ISUPPZ( 2*i-1 ) through
  22427. * ISUPPZ( 2*i ).
  22428. ********** Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1
  22429. *
  22430. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  22431. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  22432. *
  22433. * LWORK (input) INTEGER
  22434. * The dimension of the array WORK. LWORK >= max(1,26*N).
  22435. * For optimal efficiency, LWORK >= (NB+6)*N,
  22436. * where NB is the max of the blocksize for DSYTRD and DORMTR
  22437. * returned by ILAENV.
  22438. *
  22439. * If LWORK = -1, then a workspace query is assumed; the routine
  22440. * only calculates the optimal size of the WORK array, returns
  22441. * this value as the first entry of the WORK array, and no error
  22442. * message related to LWORK is issued by XERBLA.
  22443. *
  22444. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  22445. * On exit, if INFO = 0, IWORK(1) returns the optimal LWORK.
  22446. *
  22447. * LIWORK (input) INTEGER
  22448. * The dimension of the array IWORK. LIWORK >= max(1,10*N).
  22449. *
  22450. * If LIWORK = -1, then a workspace query is assumed; the
  22451. * routine only calculates the optimal size of the IWORK array,
  22452. * returns this value as the first entry of the IWORK array, and
  22453. * no error message related to LIWORK is issued by XERBLA.
  22454. *
  22455. * INFO (output) INTEGER
  22456. * = 0: successful exit
  22457. * < 0: if INFO = -i, the i-th argument had an illegal value
  22458. * > 0: Internal error
  22459. *
  22460. * Further Details
  22461. * ===============
  22462. *
  22463. * Based on contributions by
  22464. * Inderjit Dhillon, IBM Almaden, USA
  22465. * Osni Marques, LBNL/NERSC, USA
  22466. * Ken Stanley, Computer Science Division, University of
  22467. * California at Berkeley, USA
  22468. * Jason Riedy, Computer Science Division, University of
  22469. * California at Berkeley, USA
  22470. *
  22471. * =====================================================================
  22472. *
  22473. * .. Parameters ..
  22474. DOUBLE PRECISION ZERO, ONE, TWO
  22475. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 0.0D+0 )
  22476. * ..
  22477. * .. Local Scalars ..
  22478. LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, VALEIG, WANTZ,
  22479. $ TRYRAC
  22480. CHARACTER ORDER
  22481. INTEGER I, IEEEOK, IINFO, IMAX, INDD, INDDD, INDE,
  22482. $ INDEE, INDIBL, INDIFL, INDISP, INDIWO, INDTAU,
  22483. $ INDWK, INDWKN, ISCALE, J, JJ, LIWMIN,
  22484. $ LLWORK, LLWRKN, LWKOPT, LWMIN, NB, NSPLIT
  22485. DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
  22486. $ SIGMA, SMLNUM, TMP1, VLL, VUU
  22487. * ..
  22488. * .. External Functions ..
  22489. LOGICAL LSAME
  22490. INTEGER ILAENV
  22491. DOUBLE PRECISION DLAMCH, DLANSY
  22492. EXTERNAL LSAME, ILAENV, DLAMCH, DLANSY
  22493. * ..
  22494. * .. External Subroutines ..
  22495. EXTERNAL DCOPY, DORMTR, DSCAL, DSTEBZ, DSTEMR, DSTEIN,
  22496. $ DSTERF, DSWAP, DSYTRD, XERBLA
  22497. * ..
  22498. * .. Intrinsic Functions ..
  22499. INTRINSIC MAX, MIN, SQRT
  22500. * ..
  22501. * .. Executable Statements ..
  22502. *
  22503. * Test the input parameters.
  22504. *
  22505. IEEEOK = ILAENV( 10, 'DSYEVR', 'N', 1, 2, 3, 4 )
  22506. *
  22507. LOWER = LSAME( UPLO, 'L' )
  22508. WANTZ = LSAME( JOBZ, 'V' )
  22509. ALLEIG = LSAME( RANGE, 'A' )
  22510. VALEIG = LSAME( RANGE, 'V' )
  22511. INDEIG = LSAME( RANGE, 'I' )
  22512. *
  22513. LQUERY = ( ( LWORK.EQ.-1 ) .OR. ( LIWORK.EQ.-1 ) )
  22514. *
  22515. LWMIN = MAX( 1, 26*N )
  22516. LIWMIN = MAX( 1, 10*N )
  22517. *
  22518. INFO = 0
  22519. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  22520. INFO = -1
  22521. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  22522. INFO = -2
  22523. ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
  22524. INFO = -3
  22525. ELSE IF( N.LT.0 ) THEN
  22526. INFO = -4
  22527. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  22528. INFO = -6
  22529. ELSE
  22530. IF( VALEIG ) THEN
  22531. IF( N.GT.0 .AND. VU.LE.VL )
  22532. $ INFO = -8
  22533. ELSE IF( INDEIG ) THEN
  22534. IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
  22535. INFO = -9
  22536. ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  22537. INFO = -10
  22538. END IF
  22539. END IF
  22540. END IF
  22541. IF( INFO.EQ.0 ) THEN
  22542. IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  22543. INFO = -15
  22544. ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  22545. INFO = -18
  22546. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  22547. INFO = -20
  22548. END IF
  22549. END IF
  22550. *
  22551. IF( INFO.EQ.0 ) THEN
  22552. NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
  22553. NB = MAX( NB, ILAENV( 1, 'DORMTR', UPLO, N, -1, -1, -1 ) )
  22554. LWKOPT = MAX( ( NB+1 )*N, LWMIN )
  22555. WORK( 1 ) = LWKOPT
  22556. IWORK( 1 ) = LIWMIN
  22557. END IF
  22558. *
  22559. IF( INFO.NE.0 ) THEN
  22560. CALL XERBLA( 'DSYEVR', -INFO )
  22561. RETURN
  22562. ELSE IF( LQUERY ) THEN
  22563. RETURN
  22564. END IF
  22565. *
  22566. * Quick return if possible
  22567. *
  22568. M = 0
  22569. IF( N.EQ.0 ) THEN
  22570. WORK( 1 ) = 1
  22571. RETURN
  22572. END IF
  22573. *
  22574. IF( N.EQ.1 ) THEN
  22575. WORK( 1 ) = 7
  22576. IF( ALLEIG .OR. INDEIG ) THEN
  22577. M = 1
  22578. W( 1 ) = A( 1, 1 )
  22579. ELSE
  22580. IF( VL.LT.A( 1, 1 ) .AND. VU.GE.A( 1, 1 ) ) THEN
  22581. M = 1
  22582. W( 1 ) = A( 1, 1 )
  22583. END IF
  22584. END IF
  22585. IF( WANTZ )
  22586. $ Z( 1, 1 ) = ONE
  22587. RETURN
  22588. END IF
  22589. *
  22590. * Get machine constants.
  22591. *
  22592. SAFMIN = DLAMCH( 'Safe minimum' )
  22593. EPS = DLAMCH( 'Precision' )
  22594. SMLNUM = SAFMIN / EPS
  22595. BIGNUM = ONE / SMLNUM
  22596. RMIN = SQRT( SMLNUM )
  22597. RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )
  22598. *
  22599. * Scale matrix to allowable range, if necessary.
  22600. *
  22601. ISCALE = 0
  22602. ABSTLL = ABSTOL
  22603. VLL = VL
  22604. VUU = VU
  22605. ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )
  22606. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  22607. ISCALE = 1
  22608. SIGMA = RMIN / ANRM
  22609. ELSE IF( ANRM.GT.RMAX ) THEN
  22610. ISCALE = 1
  22611. SIGMA = RMAX / ANRM
  22612. END IF
  22613. IF( ISCALE.EQ.1 ) THEN
  22614. IF( LOWER ) THEN
  22615. DO 10 J = 1, N
  22616. CALL DSCAL( N-J+1, SIGMA, A( J, J ), 1 )
  22617. 10 CONTINUE
  22618. ELSE
  22619. DO 20 J = 1, N
  22620. CALL DSCAL( J, SIGMA, A( 1, J ), 1 )
  22621. 20 CONTINUE
  22622. END IF
  22623. IF( ABSTOL.GT.0 )
  22624. $ ABSTLL = ABSTOL*SIGMA
  22625. IF( VALEIG ) THEN
  22626. VLL = VL*SIGMA
  22627. VUU = VU*SIGMA
  22628. END IF
  22629. END IF
  22630. * Initialize indices into workspaces. Note: The IWORK indices are
  22631. * used only if DSTERF or DSTEMR fail.
  22632. * WORK(INDTAU:INDTAU+N-1) stores the scalar factors of the
  22633. * elementary reflectors used in DSYTRD.
  22634. INDTAU = 1
  22635. * WORK(INDD:INDD+N-1) stores the tridiagonal's diagonal entries.
  22636. INDD = INDTAU + N
  22637. * WORK(INDE:INDE+N-1) stores the off-diagonal entries of the
  22638. * tridiagonal matrix from DSYTRD.
  22639. INDE = INDD + N
  22640. * WORK(INDDD:INDDD+N-1) is a copy of the diagonal entries over
  22641. * -written by DSTEMR (the DSTERF path copies the diagonal to W).
  22642. INDDD = INDE + N
  22643. * WORK(INDEE:INDEE+N-1) is a copy of the off-diagonal entries over
  22644. * -written while computing the eigenvalues in DSTERF and DSTEMR.
  22645. INDEE = INDDD + N
  22646. * INDWK is the starting offset of the left-over workspace, and
  22647. * LLWORK is the remaining workspace size.
  22648. INDWK = INDEE + N
  22649. LLWORK = LWORK - INDWK + 1
  22650. * IWORK(INDIBL:INDIBL+M-1) corresponds to IBLOCK in DSTEBZ and
  22651. * stores the block indices of each of the M<=N eigenvalues.
  22652. INDIBL = 1
  22653. * IWORK(INDISP:INDISP+NSPLIT-1) corresponds to ISPLIT in DSTEBZ and
  22654. * stores the starting and finishing indices of each block.
  22655. INDISP = INDIBL + N
  22656. * IWORK(INDIFL:INDIFL+N-1) stores the indices of eigenvectors
  22657. * that corresponding to eigenvectors that fail to converge in
  22658. * DSTEIN. This information is discarded; if any fail, the driver
  22659. * returns INFO > 0.
  22660. INDIFL = INDISP + N
  22661. * INDIWO is the offset of the remaining integer workspace.
  22662. INDIWO = INDISP + N
  22663. *
  22664. * Call DSYTRD to reduce symmetric matrix to tridiagonal form.
  22665. *
  22666. CALL DSYTRD( UPLO, N, A, LDA, WORK( INDD ), WORK( INDE ),
  22667. $ WORK( INDTAU ), WORK( INDWK ), LLWORK, IINFO )
  22668. *
  22669. * If all eigenvalues are desired
  22670. * then call DSTERF or DSTEMR and DORMTR.
  22671. *
  22672. IF( ( ALLEIG .OR. ( INDEIG .AND. IL.EQ.1 .AND. IU.EQ.N ) ) .AND.
  22673. $ IEEEOK.EQ.1 ) THEN
  22674. IF( .NOT.WANTZ ) THEN
  22675. CALL DCOPY( N, WORK( INDD ), 1, W, 1 )
  22676. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  22677. CALL DSTERF( N, W, WORK( INDEE ), INFO )
  22678. ELSE
  22679. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  22680. CALL DCOPY( N, WORK( INDD ), 1, WORK( INDDD ), 1 )
  22681. *
  22682. IF (ABSTOL .LE. TWO*N*EPS) THEN
  22683. TRYRAC = .TRUE.
  22684. ELSE
  22685. TRYRAC = .FALSE.
  22686. END IF
  22687. CALL DSTEMR( JOBZ, 'A', N, WORK( INDDD ), WORK( INDEE ),
  22688. $ VL, VU, IL, IU, M, W, Z, LDZ, N, ISUPPZ,
  22689. $ TRYRAC, WORK( INDWK ), LWORK, IWORK, LIWORK,
  22690. $ INFO )
  22691. *
  22692. *
  22693. *
  22694. * Apply orthogonal matrix used in reduction to tridiagonal
  22695. * form to eigenvectors returned by DSTEIN.
  22696. *
  22697. IF( WANTZ .AND. INFO.EQ.0 ) THEN
  22698. INDWKN = INDE
  22699. LLWRKN = LWORK - INDWKN + 1
  22700. CALL DORMTR( 'L', UPLO, 'N', N, M, A, LDA,
  22701. $ WORK( INDTAU ), Z, LDZ, WORK( INDWKN ),
  22702. $ LLWRKN, IINFO )
  22703. END IF
  22704. END IF
  22705. *
  22706. *
  22707. IF( INFO.EQ.0 ) THEN
  22708. * Everything worked. Skip DSTEBZ/DSTEIN. IWORK(:) are
  22709. * undefined.
  22710. M = N
  22711. GO TO 30
  22712. END IF
  22713. INFO = 0
  22714. END IF
  22715. *
  22716. * Otherwise, call DSTEBZ and, if eigenvectors are desired, DSTEIN.
  22717. * Also call DSTEBZ and DSTEIN if DSTEMR fails.
  22718. *
  22719. IF( WANTZ ) THEN
  22720. ORDER = 'B'
  22721. ELSE
  22722. ORDER = 'E'
  22723. END IF
  22724. CALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,
  22725. $ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,
  22726. $ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWK ),
  22727. $ IWORK( INDIWO ), INFO )
  22728. *
  22729. IF( WANTZ ) THEN
  22730. CALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,
  22731. $ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,
  22732. $ WORK( INDWK ), IWORK( INDIWO ), IWORK( INDIFL ),
  22733. $ INFO )
  22734. *
  22735. * Apply orthogonal matrix used in reduction to tridiagonal
  22736. * form to eigenvectors returned by DSTEIN.
  22737. *
  22738. INDWKN = INDE
  22739. LLWRKN = LWORK - INDWKN + 1
  22740. CALL DORMTR( 'L', UPLO, 'N', N, M, A, LDA, WORK( INDTAU ), Z,
  22741. $ LDZ, WORK( INDWKN ), LLWRKN, IINFO )
  22742. END IF
  22743. *
  22744. * If matrix was scaled, then rescale eigenvalues appropriately.
  22745. *
  22746. * Jump here if DSTEMR/DSTEIN succeeded.
  22747. 30 CONTINUE
  22748. IF( ISCALE.EQ.1 ) THEN
  22749. IF( INFO.EQ.0 ) THEN
  22750. IMAX = M
  22751. ELSE
  22752. IMAX = INFO - 1
  22753. END IF
  22754. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  22755. END IF
  22756. *
  22757. * If eigenvalues are not in order, then sort them, along with
  22758. * eigenvectors. Note: We do not sort the IFAIL portion of IWORK.
  22759. * It may not be initialized (if DSTEMR/DSTEIN succeeded), and we do
  22760. * not return this detailed information to the user.
  22761. *
  22762. IF( WANTZ ) THEN
  22763. DO 50 J = 1, M - 1
  22764. I = 0
  22765. TMP1 = W( J )
  22766. DO 40 JJ = J + 1, M
  22767. IF( W( JJ ).LT.TMP1 ) THEN
  22768. I = JJ
  22769. TMP1 = W( JJ )
  22770. END IF
  22771. 40 CONTINUE
  22772. *
  22773. IF( I.NE.0 ) THEN
  22774. W( I ) = W( J )
  22775. W( J ) = TMP1
  22776. CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
  22777. END IF
  22778. 50 CONTINUE
  22779. END IF
  22780. *
  22781. * Set WORK(1) to optimal workspace size.
  22782. *
  22783. WORK( 1 ) = LWKOPT
  22784. IWORK( 1 ) = LIWMIN
  22785. *
  22786. RETURN
  22787. *
  22788. * End of DSYEVR
  22789. *
  22790. END
  22791. SUBROUTINE DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,
  22792. $ ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK,
  22793. $ IFAIL, INFO )
  22794. *
  22795. * -- LAPACK driver routine (version 3.1) --
  22796. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  22797. * November 2006
  22798. *
  22799. * .. Scalar Arguments ..
  22800. CHARACTER JOBZ, RANGE, UPLO
  22801. INTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, N
  22802. DOUBLE PRECISION ABSTOL, VL, VU
  22803. * ..
  22804. * .. Array Arguments ..
  22805. INTEGER IFAIL( * ), IWORK( * )
  22806. DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * )
  22807. * ..
  22808. *
  22809. * Purpose
  22810. * =======
  22811. *
  22812. * DSYEVX computes selected eigenvalues and, optionally, eigenvectors
  22813. * of a real symmetric matrix A. Eigenvalues and eigenvectors can be
  22814. * selected by specifying either a range of values or a range of indices
  22815. * for the desired eigenvalues.
  22816. *
  22817. * Arguments
  22818. * =========
  22819. *
  22820. * JOBZ (input) CHARACTER*1
  22821. * = 'N': Compute eigenvalues only;
  22822. * = 'V': Compute eigenvalues and eigenvectors.
  22823. *
  22824. * RANGE (input) CHARACTER*1
  22825. * = 'A': all eigenvalues will be found.
  22826. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  22827. * will be found.
  22828. * = 'I': the IL-th through IU-th eigenvalues will be found.
  22829. *
  22830. * UPLO (input) CHARACTER*1
  22831. * = 'U': Upper triangle of A is stored;
  22832. * = 'L': Lower triangle of A is stored.
  22833. *
  22834. * N (input) INTEGER
  22835. * The order of the matrix A. N >= 0.
  22836. *
  22837. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  22838. * On entry, the symmetric matrix A. If UPLO = 'U', the
  22839. * leading N-by-N upper triangular part of A contains the
  22840. * upper triangular part of the matrix A. If UPLO = 'L',
  22841. * the leading N-by-N lower triangular part of A contains
  22842. * the lower triangular part of the matrix A.
  22843. * On exit, the lower triangle (if UPLO='L') or the upper
  22844. * triangle (if UPLO='U') of A, including the diagonal, is
  22845. * destroyed.
  22846. *
  22847. * LDA (input) INTEGER
  22848. * The leading dimension of the array A. LDA >= max(1,N).
  22849. *
  22850. * VL (input) DOUBLE PRECISION
  22851. * VU (input) DOUBLE PRECISION
  22852. * If RANGE='V', the lower and upper bounds of the interval to
  22853. * be searched for eigenvalues. VL < VU.
  22854. * Not referenced if RANGE = 'A' or 'I'.
  22855. *
  22856. * IL (input) INTEGER
  22857. * IU (input) INTEGER
  22858. * If RANGE='I', the indices (in ascending order) of the
  22859. * smallest and largest eigenvalues to be returned.
  22860. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  22861. * Not referenced if RANGE = 'A' or 'V'.
  22862. *
  22863. * ABSTOL (input) DOUBLE PRECISION
  22864. * The absolute error tolerance for the eigenvalues.
  22865. * An approximate eigenvalue is accepted as converged
  22866. * when it is determined to lie in an interval [a,b]
  22867. * of width less than or equal to
  22868. *
  22869. * ABSTOL + EPS * max( |a|,|b| ) ,
  22870. *
  22871. * where EPS is the machine precision. If ABSTOL is less than
  22872. * or equal to zero, then EPS*|T| will be used in its place,
  22873. * where |T| is the 1-norm of the tridiagonal matrix obtained
  22874. * by reducing A to tridiagonal form.
  22875. *
  22876. * Eigenvalues will be computed most accurately when ABSTOL is
  22877. * set to twice the underflow threshold 2*DLAMCH('S'), not zero.
  22878. * If this routine returns with INFO>0, indicating that some
  22879. * eigenvectors did not converge, try setting ABSTOL to
  22880. * 2*DLAMCH('S').
  22881. *
  22882. * See "Computing Small Singular Values of Bidiagonal Matrices
  22883. * with Guaranteed High Relative Accuracy," by Demmel and
  22884. * Kahan, LAPACK Working Note #3.
  22885. *
  22886. * M (output) INTEGER
  22887. * The total number of eigenvalues found. 0 <= M <= N.
  22888. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  22889. *
  22890. * W (output) DOUBLE PRECISION array, dimension (N)
  22891. * On normal exit, the first M elements contain the selected
  22892. * eigenvalues in ascending order.
  22893. *
  22894. * Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M))
  22895. * If JOBZ = 'V', then if INFO = 0, the first M columns of Z
  22896. * contain the orthonormal eigenvectors of the matrix A
  22897. * corresponding to the selected eigenvalues, with the i-th
  22898. * column of Z holding the eigenvector associated with W(i).
  22899. * If an eigenvector fails to converge, then that column of Z
  22900. * contains the latest approximation to the eigenvector, and the
  22901. * index of the eigenvector is returned in IFAIL.
  22902. * If JOBZ = 'N', then Z is not referenced.
  22903. * Note: the user must ensure that at least max(1,M) columns are
  22904. * supplied in the array Z; if RANGE = 'V', the exact value of M
  22905. * is not known in advance and an upper bound must be used.
  22906. *
  22907. * LDZ (input) INTEGER
  22908. * The leading dimension of the array Z. LDZ >= 1, and if
  22909. * JOBZ = 'V', LDZ >= max(1,N).
  22910. *
  22911. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  22912. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  22913. *
  22914. * LWORK (input) INTEGER
  22915. * The length of the array WORK. LWORK >= 1, when N <= 1;
  22916. * otherwise 8*N.
  22917. * For optimal efficiency, LWORK >= (NB+3)*N,
  22918. * where NB is the max of the blocksize for DSYTRD and DORMTR
  22919. * returned by ILAENV.
  22920. *
  22921. * If LWORK = -1, then a workspace query is assumed; the routine
  22922. * only calculates the optimal size of the WORK array, returns
  22923. * this value as the first entry of the WORK array, and no error
  22924. * message related to LWORK is issued by XERBLA.
  22925. *
  22926. * IWORK (workspace) INTEGER array, dimension (5*N)
  22927. *
  22928. * IFAIL (output) INTEGER array, dimension (N)
  22929. * If JOBZ = 'V', then if INFO = 0, the first M elements of
  22930. * IFAIL are zero. If INFO > 0, then IFAIL contains the
  22931. * indices of the eigenvectors that failed to converge.
  22932. * If JOBZ = 'N', then IFAIL is not referenced.
  22933. *
  22934. * INFO (output) INTEGER
  22935. * = 0: successful exit
  22936. * < 0: if INFO = -i, the i-th argument had an illegal value
  22937. * > 0: if INFO = i, then i eigenvectors failed to converge.
  22938. * Their indices are stored in array IFAIL.
  22939. *
  22940. * =====================================================================
  22941. *
  22942. * .. Parameters ..
  22943. DOUBLE PRECISION ZERO, ONE
  22944. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  22945. * ..
  22946. * .. Local Scalars ..
  22947. LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
  22948. $ WANTZ
  22949. CHARACTER ORDER
  22950. INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,
  22951. $ INDISP, INDIWO, INDTAU, INDWKN, INDWRK, ISCALE,
  22952. $ ITMP1, J, JJ, LLWORK, LLWRKN, LWKMIN,
  22953. $ LWKOPT, NB, NSPLIT
  22954. DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
  22955. $ SIGMA, SMLNUM, TMP1, VLL, VUU
  22956. * ..
  22957. * .. External Functions ..
  22958. LOGICAL LSAME
  22959. INTEGER ILAENV
  22960. DOUBLE PRECISION DLAMCH, DLANSY
  22961. EXTERNAL LSAME, ILAENV, DLAMCH, DLANSY
  22962. * ..
  22963. * .. External Subroutines ..
  22964. EXTERNAL DCOPY, DLACPY, DORGTR, DORMTR, DSCAL, DSTEBZ,
  22965. $ DSTEIN, DSTEQR, DSTERF, DSWAP, DSYTRD, XERBLA
  22966. * ..
  22967. * .. Intrinsic Functions ..
  22968. INTRINSIC MAX, MIN, SQRT
  22969. * ..
  22970. * .. Executable Statements ..
  22971. *
  22972. * Test the input parameters.
  22973. *
  22974. LOWER = LSAME( UPLO, 'L' )
  22975. WANTZ = LSAME( JOBZ, 'V' )
  22976. ALLEIG = LSAME( RANGE, 'A' )
  22977. VALEIG = LSAME( RANGE, 'V' )
  22978. INDEIG = LSAME( RANGE, 'I' )
  22979. LQUERY = ( LWORK.EQ.-1 )
  22980. *
  22981. INFO = 0
  22982. IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  22983. INFO = -1
  22984. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  22985. INFO = -2
  22986. ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
  22987. INFO = -3
  22988. ELSE IF( N.LT.0 ) THEN
  22989. INFO = -4
  22990. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  22991. INFO = -6
  22992. ELSE
  22993. IF( VALEIG ) THEN
  22994. IF( N.GT.0 .AND. VU.LE.VL )
  22995. $ INFO = -8
  22996. ELSE IF( INDEIG ) THEN
  22997. IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
  22998. INFO = -9
  22999. ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  23000. INFO = -10
  23001. END IF
  23002. END IF
  23003. END IF
  23004. IF( INFO.EQ.0 ) THEN
  23005. IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
  23006. INFO = -15
  23007. END IF
  23008. END IF
  23009. *
  23010. IF( INFO.EQ.0 ) THEN
  23011. IF( N.LE.1 ) THEN
  23012. LWKMIN = 1
  23013. WORK( 1 ) = LWKMIN
  23014. ELSE
  23015. LWKMIN = 8*N
  23016. NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
  23017. NB = MAX( NB, ILAENV( 1, 'DORMTR', UPLO, N, -1, -1, -1 ) )
  23018. LWKOPT = MAX( LWKMIN, ( NB + 3 )*N )
  23019. WORK( 1 ) = LWKOPT
  23020. END IF
  23021. *
  23022. IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY )
  23023. $ INFO = -17
  23024. END IF
  23025. *
  23026. IF( INFO.NE.0 ) THEN
  23027. CALL XERBLA( 'DSYEVX', -INFO )
  23028. RETURN
  23029. ELSE IF( LQUERY ) THEN
  23030. RETURN
  23031. END IF
  23032. *
  23033. * Quick return if possible
  23034. *
  23035. M = 0
  23036. IF( N.EQ.0 ) THEN
  23037. RETURN
  23038. END IF
  23039. *
  23040. IF( N.EQ.1 ) THEN
  23041. IF( ALLEIG .OR. INDEIG ) THEN
  23042. M = 1
  23043. W( 1 ) = A( 1, 1 )
  23044. ELSE
  23045. IF( VL.LT.A( 1, 1 ) .AND. VU.GE.A( 1, 1 ) ) THEN
  23046. M = 1
  23047. W( 1 ) = A( 1, 1 )
  23048. END IF
  23049. END IF
  23050. IF( WANTZ )
  23051. $ Z( 1, 1 ) = ONE
  23052. RETURN
  23053. END IF
  23054. *
  23055. * Get machine constants.
  23056. *
  23057. SAFMIN = DLAMCH( 'Safe minimum' )
  23058. EPS = DLAMCH( 'Precision' )
  23059. SMLNUM = SAFMIN / EPS
  23060. BIGNUM = ONE / SMLNUM
  23061. RMIN = SQRT( SMLNUM )
  23062. RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )
  23063. *
  23064. * Scale matrix to allowable range, if necessary.
  23065. *
  23066. ISCALE = 0
  23067. ABSTLL = ABSTOL
  23068. IF( VALEIG ) THEN
  23069. VLL = VL
  23070. VUU = VU
  23071. END IF
  23072. ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )
  23073. IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
  23074. ISCALE = 1
  23075. SIGMA = RMIN / ANRM
  23076. ELSE IF( ANRM.GT.RMAX ) THEN
  23077. ISCALE = 1
  23078. SIGMA = RMAX / ANRM
  23079. END IF
  23080. IF( ISCALE.EQ.1 ) THEN
  23081. IF( LOWER ) THEN
  23082. DO 10 J = 1, N
  23083. CALL DSCAL( N-J+1, SIGMA, A( J, J ), 1 )
  23084. 10 CONTINUE
  23085. ELSE
  23086. DO 20 J = 1, N
  23087. CALL DSCAL( J, SIGMA, A( 1, J ), 1 )
  23088. 20 CONTINUE
  23089. END IF
  23090. IF( ABSTOL.GT.0 )
  23091. $ ABSTLL = ABSTOL*SIGMA
  23092. IF( VALEIG ) THEN
  23093. VLL = VL*SIGMA
  23094. VUU = VU*SIGMA
  23095. END IF
  23096. END IF
  23097. *
  23098. * Call DSYTRD to reduce symmetric matrix to tridiagonal form.
  23099. *
  23100. INDTAU = 1
  23101. INDE = INDTAU + N
  23102. INDD = INDE + N
  23103. INDWRK = INDD + N
  23104. LLWORK = LWORK - INDWRK + 1
  23105. CALL DSYTRD( UPLO, N, A, LDA, WORK( INDD ), WORK( INDE ),
  23106. $ WORK( INDTAU ), WORK( INDWRK ), LLWORK, IINFO )
  23107. *
  23108. * If all eigenvalues are desired and ABSTOL is less than or equal to
  23109. * zero, then call DSTERF or DORGTR and SSTEQR. If this fails for
  23110. * some eigenvalue, then try DSTEBZ.
  23111. *
  23112. TEST = .FALSE.
  23113. IF( INDEIG ) THEN
  23114. IF( IL.EQ.1 .AND. IU.EQ.N ) THEN
  23115. TEST = .TRUE.
  23116. END IF
  23117. END IF
  23118. IF( ( ALLEIG .OR. TEST ) .AND. ( ABSTOL.LE.ZERO ) ) THEN
  23119. CALL DCOPY( N, WORK( INDD ), 1, W, 1 )
  23120. INDEE = INDWRK + 2*N
  23121. IF( .NOT.WANTZ ) THEN
  23122. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  23123. CALL DSTERF( N, W, WORK( INDEE ), INFO )
  23124. ELSE
  23125. CALL DLACPY( 'A', N, N, A, LDA, Z, LDZ )
  23126. CALL DORGTR( UPLO, N, Z, LDZ, WORK( INDTAU ),
  23127. $ WORK( INDWRK ), LLWORK, IINFO )
  23128. CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )
  23129. CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ,
  23130. $ WORK( INDWRK ), INFO )
  23131. IF( INFO.EQ.0 ) THEN
  23132. DO 30 I = 1, N
  23133. IFAIL( I ) = 0
  23134. 30 CONTINUE
  23135. END IF
  23136. END IF
  23137. IF( INFO.EQ.0 ) THEN
  23138. M = N
  23139. GO TO 40
  23140. END IF
  23141. INFO = 0
  23142. END IF
  23143. *
  23144. * Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN.
  23145. *
  23146. IF( WANTZ ) THEN
  23147. ORDER = 'B'
  23148. ELSE
  23149. ORDER = 'E'
  23150. END IF
  23151. INDIBL = 1
  23152. INDISP = INDIBL + N
  23153. INDIWO = INDISP + N
  23154. CALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,
  23155. $ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,
  23156. $ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ),
  23157. $ IWORK( INDIWO ), INFO )
  23158. *
  23159. IF( WANTZ ) THEN
  23160. CALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,
  23161. $ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,
  23162. $ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO )
  23163. *
  23164. * Apply orthogonal matrix used in reduction to tridiagonal
  23165. * form to eigenvectors returned by DSTEIN.
  23166. *
  23167. INDWKN = INDE
  23168. LLWRKN = LWORK - INDWKN + 1
  23169. CALL DORMTR( 'L', UPLO, 'N', N, M, A, LDA, WORK( INDTAU ), Z,
  23170. $ LDZ, WORK( INDWKN ), LLWRKN, IINFO )
  23171. END IF
  23172. *
  23173. * If matrix was scaled, then rescale eigenvalues appropriately.
  23174. *
  23175. 40 CONTINUE
  23176. IF( ISCALE.EQ.1 ) THEN
  23177. IF( INFO.EQ.0 ) THEN
  23178. IMAX = M
  23179. ELSE
  23180. IMAX = INFO - 1
  23181. END IF
  23182. CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
  23183. END IF
  23184. *
  23185. * If eigenvalues are not in order, then sort them, along with
  23186. * eigenvectors.
  23187. *
  23188. IF( WANTZ ) THEN
  23189. DO 60 J = 1, M - 1
  23190. I = 0
  23191. TMP1 = W( J )
  23192. DO 50 JJ = J + 1, M
  23193. IF( W( JJ ).LT.TMP1 ) THEN
  23194. I = JJ
  23195. TMP1 = W( JJ )
  23196. END IF
  23197. 50 CONTINUE
  23198. *
  23199. IF( I.NE.0 ) THEN
  23200. ITMP1 = IWORK( INDIBL+I-1 )
  23201. W( I ) = W( J )
  23202. IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )
  23203. W( J ) = TMP1
  23204. IWORK( INDIBL+J-1 ) = ITMP1
  23205. CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )
  23206. IF( INFO.NE.0 ) THEN
  23207. ITMP1 = IFAIL( I )
  23208. IFAIL( I ) = IFAIL( J )
  23209. IFAIL( J ) = ITMP1
  23210. END IF
  23211. END IF
  23212. 60 CONTINUE
  23213. END IF
  23214. *
  23215. * Set WORK(1) to optimal workspace size.
  23216. *
  23217. WORK( 1 ) = LWKOPT
  23218. *
  23219. RETURN
  23220. *
  23221. * End of DSYEVX
  23222. *
  23223. END
  23224. SUBROUTINE DSYGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,
  23225. $ LWORK, INFO )
  23226. *
  23227. * -- LAPACK driver routine (version 3.1) --
  23228. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  23229. * November 2006
  23230. *
  23231. * .. Scalar Arguments ..
  23232. CHARACTER JOBZ, UPLO
  23233. INTEGER INFO, ITYPE, LDA, LDB, LWORK, N
  23234. * ..
  23235. * .. Array Arguments ..
  23236. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * )
  23237. * ..
  23238. *
  23239. * Purpose
  23240. * =======
  23241. *
  23242. * DSYGV computes all the eigenvalues, and optionally, the eigenvectors
  23243. * of a real generalized symmetric-definite eigenproblem, of the form
  23244. * A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x.
  23245. * Here A and B are assumed to be symmetric and B is also
  23246. * positive definite.
  23247. *
  23248. * Arguments
  23249. * =========
  23250. *
  23251. * ITYPE (input) INTEGER
  23252. * Specifies the problem type to be solved:
  23253. * = 1: A*x = (lambda)*B*x
  23254. * = 2: A*B*x = (lambda)*x
  23255. * = 3: B*A*x = (lambda)*x
  23256. *
  23257. * JOBZ (input) CHARACTER*1
  23258. * = 'N': Compute eigenvalues only;
  23259. * = 'V': Compute eigenvalues and eigenvectors.
  23260. *
  23261. * UPLO (input) CHARACTER*1
  23262. * = 'U': Upper triangles of A and B are stored;
  23263. * = 'L': Lower triangles of A and B are stored.
  23264. *
  23265. * N (input) INTEGER
  23266. * The order of the matrices A and B. N >= 0.
  23267. *
  23268. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  23269. * On entry, the symmetric matrix A. If UPLO = 'U', the
  23270. * leading N-by-N upper triangular part of A contains the
  23271. * upper triangular part of the matrix A. If UPLO = 'L',
  23272. * the leading N-by-N lower triangular part of A contains
  23273. * the lower triangular part of the matrix A.
  23274. *
  23275. * On exit, if JOBZ = 'V', then if INFO = 0, A contains the
  23276. * matrix Z of eigenvectors. The eigenvectors are normalized
  23277. * as follows:
  23278. * if ITYPE = 1 or 2, Z**T*B*Z = I;
  23279. * if ITYPE = 3, Z**T*inv(B)*Z = I.
  23280. * If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
  23281. * or the lower triangle (if UPLO='L') of A, including the
  23282. * diagonal, is destroyed.
  23283. *
  23284. * LDA (input) INTEGER
  23285. * The leading dimension of the array A. LDA >= max(1,N).
  23286. *
  23287. * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
  23288. * On entry, the symmetric positive definite matrix B.
  23289. * If UPLO = 'U', the leading N-by-N upper triangular part of B
  23290. * contains the upper triangular part of the matrix B.
  23291. * If UPLO = 'L', the leading N-by-N lower triangular part of B
  23292. * contains the lower triangular part of the matrix B.
  23293. *
  23294. * On exit, if INFO <= N, the part of B containing the matrix is
  23295. * overwritten by the triangular factor U or L from the Cholesky
  23296. * factorization B = U**T*U or B = L*L**T.
  23297. *
  23298. * LDB (input) INTEGER
  23299. * The leading dimension of the array B. LDB >= max(1,N).
  23300. *
  23301. * W (output) DOUBLE PRECISION array, dimension (N)
  23302. * If INFO = 0, the eigenvalues in ascending order.
  23303. *
  23304. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  23305. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  23306. *
  23307. * LWORK (input) INTEGER
  23308. * The length of the array WORK. LWORK >= max(1,3*N-1).
  23309. * For optimal efficiency, LWORK >= (NB+2)*N,
  23310. * where NB is the blocksize for DSYTRD returned by ILAENV.
  23311. *
  23312. * If LWORK = -1, then a workspace query is assumed; the routine
  23313. * only calculates the optimal size of the WORK array, returns
  23314. * this value as the first entry of the WORK array, and no error
  23315. * message related to LWORK is issued by XERBLA.
  23316. *
  23317. * INFO (output) INTEGER
  23318. * = 0: successful exit
  23319. * < 0: if INFO = -i, the i-th argument had an illegal value
  23320. * > 0: DPOTRF or DSYEV returned an error code:
  23321. * <= N: if INFO = i, DSYEV failed to converge;
  23322. * i off-diagonal elements of an intermediate
  23323. * tridiagonal form did not converge to zero;
  23324. * > N: if INFO = N + i, for 1 <= i <= N, then the leading
  23325. * minor of order i of B is not positive definite.
  23326. * The factorization of B could not be completed and
  23327. * no eigenvalues or eigenvectors were computed.
  23328. *
  23329. * =====================================================================
  23330. *
  23331. * .. Parameters ..
  23332. DOUBLE PRECISION ONE
  23333. PARAMETER ( ONE = 1.0D+0 )
  23334. * ..
  23335. * .. Local Scalars ..
  23336. LOGICAL LQUERY, UPPER, WANTZ
  23337. CHARACTER TRANS
  23338. INTEGER LWKMIN, LWKOPT, NB, NEIG
  23339. * ..
  23340. * .. External Functions ..
  23341. LOGICAL LSAME
  23342. INTEGER ILAENV
  23343. EXTERNAL LSAME, ILAENV
  23344. * ..
  23345. * .. External Subroutines ..
  23346. EXTERNAL DPOTRF, DSYEV, DSYGST, DTRMM, DTRSM, XERBLA
  23347. * ..
  23348. * .. Intrinsic Functions ..
  23349. INTRINSIC MAX
  23350. * ..
  23351. * .. Executable Statements ..
  23352. *
  23353. * Test the input parameters.
  23354. *
  23355. WANTZ = LSAME( JOBZ, 'V' )
  23356. UPPER = LSAME( UPLO, 'U' )
  23357. LQUERY = ( LWORK.EQ.-1 )
  23358. *
  23359. INFO = 0
  23360. IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
  23361. INFO = -1
  23362. ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  23363. INFO = -2
  23364. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  23365. INFO = -3
  23366. ELSE IF( N.LT.0 ) THEN
  23367. INFO = -4
  23368. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  23369. INFO = -6
  23370. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  23371. INFO = -8
  23372. END IF
  23373. *
  23374. IF( INFO.EQ.0 ) THEN
  23375. LWKMIN = MAX( 1, 3*N - 1 )
  23376. NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
  23377. LWKOPT = MAX( LWKMIN, ( NB + 2 )*N )
  23378. WORK( 1 ) = LWKOPT
  23379. *
  23380. IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
  23381. INFO = -11
  23382. END IF
  23383. END IF
  23384. *
  23385. IF( INFO.NE.0 ) THEN
  23386. CALL XERBLA( 'DSYGV ', -INFO )
  23387. RETURN
  23388. ELSE IF( LQUERY ) THEN
  23389. RETURN
  23390. END IF
  23391. *
  23392. * Quick return if possible
  23393. *
  23394. IF( N.EQ.0 )
  23395. $ RETURN
  23396. *
  23397. * Form a Cholesky factorization of B.
  23398. *
  23399. CALL DPOTRF( UPLO, N, B, LDB, INFO )
  23400. IF( INFO.NE.0 ) THEN
  23401. INFO = N + INFO
  23402. RETURN
  23403. END IF
  23404. *
  23405. * Transform problem to standard eigenvalue problem and solve.
  23406. *
  23407. CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
  23408. CALL DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
  23409. *
  23410. IF( WANTZ ) THEN
  23411. *
  23412. * Backtransform eigenvectors to the original problem.
  23413. *
  23414. NEIG = N
  23415. IF( INFO.GT.0 )
  23416. $ NEIG = INFO - 1
  23417. IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
  23418. *
  23419. * For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
  23420. * backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
  23421. *
  23422. IF( UPPER ) THEN
  23423. TRANS = 'N'
  23424. ELSE
  23425. TRANS = 'T'
  23426. END IF
  23427. *
  23428. CALL DTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
  23429. $ B, LDB, A, LDA )
  23430. *
  23431. ELSE IF( ITYPE.EQ.3 ) THEN
  23432. *
  23433. * For B*A*x=(lambda)*x;
  23434. * backtransform eigenvectors: x = L*y or U'*y
  23435. *
  23436. IF( UPPER ) THEN
  23437. TRANS = 'T'
  23438. ELSE
  23439. TRANS = 'N'
  23440. END IF
  23441. *
  23442. CALL DTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,
  23443. $ B, LDB, A, LDA )
  23444. END IF
  23445. END IF
  23446. *
  23447. WORK( 1 ) = LWKOPT
  23448. RETURN
  23449. *
  23450. * End of DSYGV
  23451. *
  23452. END
  23453. SUBROUTINE DSYGVD( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,
  23454. $ LWORK, IWORK, LIWORK, INFO )
  23455. *
  23456. * -- LAPACK driver routine (version 3.1) --
  23457. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  23458. * November 2006
  23459. *
  23460. * .. Scalar Arguments ..
  23461. CHARACTER JOBZ, UPLO
  23462. INTEGER INFO, ITYPE, LDA, LDB, LIWORK, LWORK, N
  23463. * ..
  23464. * .. Array Arguments ..
  23465. INTEGER IWORK( * )
  23466. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * )
  23467. * ..
  23468. *
  23469. * Purpose
  23470. * =======
  23471. *
  23472. * DSYGVD computes all the eigenvalues, and optionally, the eigenvectors
  23473. * of a real generalized symmetric-definite eigenproblem, of the form
  23474. * A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and
  23475. * B are assumed to be symmetric and B is also positive definite.
  23476. * If eigenvectors are desired, it uses a divide and conquer algorithm.
  23477. *
  23478. * The divide and conquer algorithm makes very mild assumptions about
  23479. * floating point arithmetic. It will work on machines with a guard
  23480. * digit in add/subtract, or on those binary machines without guard
  23481. * digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
  23482. * Cray-2. It could conceivably fail on hexadecimal or decimal machines
  23483. * without guard digits, but we know of none.
  23484. *
  23485. * Arguments
  23486. * =========
  23487. *
  23488. * ITYPE (input) INTEGER
  23489. * Specifies the problem type to be solved:
  23490. * = 1: A*x = (lambda)*B*x
  23491. * = 2: A*B*x = (lambda)*x
  23492. * = 3: B*A*x = (lambda)*x
  23493. *
  23494. * JOBZ (input) CHARACTER*1
  23495. * = 'N': Compute eigenvalues only;
  23496. * = 'V': Compute eigenvalues and eigenvectors.
  23497. *
  23498. * UPLO (input) CHARACTER*1
  23499. * = 'U': Upper triangles of A and B are stored;
  23500. * = 'L': Lower triangles of A and B are stored.
  23501. *
  23502. * N (input) INTEGER
  23503. * The order of the matrices A and B. N >= 0.
  23504. *
  23505. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  23506. * On entry, the symmetric matrix A. If UPLO = 'U', the
  23507. * leading N-by-N upper triangular part of A contains the
  23508. * upper triangular part of the matrix A. If UPLO = 'L',
  23509. * the leading N-by-N lower triangular part of A contains
  23510. * the lower triangular part of the matrix A.
  23511. *
  23512. * On exit, if JOBZ = 'V', then if INFO = 0, A contains the
  23513. * matrix Z of eigenvectors. The eigenvectors are normalized
  23514. * as follows:
  23515. * if ITYPE = 1 or 2, Z**T*B*Z = I;
  23516. * if ITYPE = 3, Z**T*inv(B)*Z = I.
  23517. * If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
  23518. * or the lower triangle (if UPLO='L') of A, including the
  23519. * diagonal, is destroyed.
  23520. *
  23521. * LDA (input) INTEGER
  23522. * The leading dimension of the array A. LDA >= max(1,N).
  23523. *
  23524. * B (input/output) DOUBLE PRECISION array, dimension (LDB, N)
  23525. * On entry, the symmetric matrix B. If UPLO = 'U', the
  23526. * leading N-by-N upper triangular part of B contains the
  23527. * upper triangular part of the matrix B. If UPLO = 'L',
  23528. * the leading N-by-N lower triangular part of B contains
  23529. * the lower triangular part of the matrix B.
  23530. *
  23531. * On exit, if INFO <= N, the part of B containing the matrix is
  23532. * overwritten by the triangular factor U or L from the Cholesky
  23533. * factorization B = U**T*U or B = L*L**T.
  23534. *
  23535. * LDB (input) INTEGER
  23536. * The leading dimension of the array B. LDB >= max(1,N).
  23537. *
  23538. * W (output) DOUBLE PRECISION array, dimension (N)
  23539. * If INFO = 0, the eigenvalues in ascending order.
  23540. *
  23541. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  23542. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  23543. *
  23544. * LWORK (input) INTEGER
  23545. * The dimension of the array WORK.
  23546. * If N <= 1, LWORK >= 1.
  23547. * If JOBZ = 'N' and N > 1, LWORK >= 2*N+1.
  23548. * If JOBZ = 'V' and N > 1, LWORK >= 1 + 6*N + 2*N**2.
  23549. *
  23550. * If LWORK = -1, then a workspace query is assumed; the routine
  23551. * only calculates the optimal sizes of the WORK and IWORK
  23552. * arrays, returns these values as the first entries of the WORK
  23553. * and IWORK arrays, and no error message related to LWORK or
  23554. * LIWORK is issued by XERBLA.
  23555. *
  23556. * IWORK (workspace/output) INTEGER array, dimension (MAX(1,LIWORK))
  23557. * On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
  23558. *
  23559. * LIWORK (input) INTEGER
  23560. * The dimension of the array IWORK.
  23561. * If N <= 1, LIWORK >= 1.
  23562. * If JOBZ = 'N' and N > 1, LIWORK >= 1.
  23563. * If JOBZ = 'V' and N > 1, LIWORK >= 3 + 5*N.
  23564. *
  23565. * If LIWORK = -1, then a workspace query is assumed; the
  23566. * routine only calculates the optimal sizes of the WORK and
  23567. * IWORK arrays, returns these values as the first entries of
  23568. * the WORK and IWORK arrays, and no error message related to
  23569. * LWORK or LIWORK is issued by XERBLA.
  23570. *
  23571. * INFO (output) INTEGER
  23572. * = 0: successful exit
  23573. * < 0: if INFO = -i, the i-th argument had an illegal value
  23574. * > 0: DPOTRF or DSYEVD returned an error code:
  23575. * <= N: if INFO = i and JOBZ = 'N', then the algorithm
  23576. * failed to converge; i off-diagonal elements of an
  23577. * intermediate tridiagonal form did not converge to
  23578. * zero;
  23579. * if INFO = i and JOBZ = 'V', then the algorithm
  23580. * failed to compute an eigenvalue while working on
  23581. * the submatrix lying in rows and columns INFO/(N+1)
  23582. * through mod(INFO,N+1);
  23583. * > N: if INFO = N + i, for 1 <= i <= N, then the leading
  23584. * minor of order i of B is not positive definite.
  23585. * The factorization of B could not be completed and
  23586. * no eigenvalues or eigenvectors were computed.
  23587. *
  23588. * Further Details
  23589. * ===============
  23590. *
  23591. * Based on contributions by
  23592. * Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA
  23593. *
  23594. * Modified so that no backsubstitution is performed if DSYEVD fails to
  23595. * converge (NEIG in old code could be greater than N causing out of
  23596. * bounds reference to A - reported by Ralf Meyer). Also corrected the
  23597. * description of INFO and the test on ITYPE. Sven, 16 Feb 05.
  23598. * =====================================================================
  23599. *
  23600. * .. Parameters ..
  23601. DOUBLE PRECISION ONE
  23602. PARAMETER ( ONE = 1.0D+0 )
  23603. * ..
  23604. * .. Local Scalars ..
  23605. LOGICAL LQUERY, UPPER, WANTZ
  23606. CHARACTER TRANS
  23607. INTEGER LIOPT, LIWMIN, LOPT, LWMIN
  23608. * ..
  23609. * .. External Functions ..
  23610. LOGICAL LSAME
  23611. EXTERNAL LSAME
  23612. * ..
  23613. * .. External Subroutines ..
  23614. EXTERNAL DPOTRF, DSYEVD, DSYGST, DTRMM, DTRSM, XERBLA
  23615. * ..
  23616. * .. Intrinsic Functions ..
  23617. INTRINSIC DBLE, MAX
  23618. * ..
  23619. * .. Executable Statements ..
  23620. *
  23621. * Test the input parameters.
  23622. *
  23623. WANTZ = LSAME( JOBZ, 'V' )
  23624. UPPER = LSAME( UPLO, 'U' )
  23625. LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  23626. *
  23627. INFO = 0
  23628. IF( N.LE.1 ) THEN
  23629. LIWMIN = 1
  23630. LWMIN = 1
  23631. ELSE IF( WANTZ ) THEN
  23632. LIWMIN = 3 + 5*N
  23633. LWMIN = 1 + 6*N + 2*N**2
  23634. ELSE
  23635. LIWMIN = 1
  23636. LWMIN = 2*N + 1
  23637. END IF
  23638. LOPT = LWMIN
  23639. LIOPT = LIWMIN
  23640. IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
  23641. INFO = -1
  23642. ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  23643. INFO = -2
  23644. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  23645. INFO = -3
  23646. ELSE IF( N.LT.0 ) THEN
  23647. INFO = -4
  23648. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  23649. INFO = -6
  23650. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  23651. INFO = -8
  23652. END IF
  23653. *
  23654. IF( INFO.EQ.0 ) THEN
  23655. WORK( 1 ) = LOPT
  23656. IWORK( 1 ) = LIOPT
  23657. *
  23658. IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
  23659. INFO = -11
  23660. ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN
  23661. INFO = -13
  23662. END IF
  23663. END IF
  23664. *
  23665. IF( INFO.NE.0 ) THEN
  23666. CALL XERBLA( 'DSYGVD', -INFO )
  23667. RETURN
  23668. ELSE IF( LQUERY ) THEN
  23669. RETURN
  23670. END IF
  23671. *
  23672. * Quick return if possible
  23673. *
  23674. IF( N.EQ.0 )
  23675. $ RETURN
  23676. *
  23677. * Form a Cholesky factorization of B.
  23678. *
  23679. CALL DPOTRF( UPLO, N, B, LDB, INFO )
  23680. IF( INFO.NE.0 ) THEN
  23681. INFO = N + INFO
  23682. RETURN
  23683. END IF
  23684. *
  23685. * Transform problem to standard eigenvalue problem and solve.
  23686. *
  23687. CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
  23688. CALL DSYEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK, LIWORK,
  23689. $ INFO )
  23690. LOPT = MAX( DBLE( LOPT ), DBLE( WORK( 1 ) ) )
  23691. LIOPT = MAX( DBLE( LIOPT ), DBLE( IWORK( 1 ) ) )
  23692. *
  23693. IF( WANTZ .AND. INFO.EQ.0 ) THEN
  23694. *
  23695. * Backtransform eigenvectors to the original problem.
  23696. *
  23697. IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
  23698. *
  23699. * For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
  23700. * backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
  23701. *
  23702. IF( UPPER ) THEN
  23703. TRANS = 'N'
  23704. ELSE
  23705. TRANS = 'T'
  23706. END IF
  23707. *
  23708. CALL DTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, N, ONE,
  23709. $ B, LDB, A, LDA )
  23710. *
  23711. ELSE IF( ITYPE.EQ.3 ) THEN
  23712. *
  23713. * For B*A*x=(lambda)*x;
  23714. * backtransform eigenvectors: x = L*y or U'*y
  23715. *
  23716. IF( UPPER ) THEN
  23717. TRANS = 'T'
  23718. ELSE
  23719. TRANS = 'N'
  23720. END IF
  23721. *
  23722. CALL DTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, N, ONE,
  23723. $ B, LDB, A, LDA )
  23724. END IF
  23725. END IF
  23726. *
  23727. WORK( 1 ) = LOPT
  23728. IWORK( 1 ) = LIOPT
  23729. *
  23730. RETURN
  23731. *
  23732. * End of DSYGVD
  23733. *
  23734. END
  23735. SUBROUTINE DSYGVX( ITYPE, JOBZ, RANGE, UPLO, N, A, LDA, B, LDB,
  23736. $ VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,
  23737. $ LWORK, IWORK, IFAIL, INFO )
  23738. *
  23739. * -- LAPACK driver routine (version 3.1) --
  23740. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  23741. * November 2006
  23742. *
  23743. * .. Scalar Arguments ..
  23744. CHARACTER JOBZ, RANGE, UPLO
  23745. INTEGER IL, INFO, ITYPE, IU, LDA, LDB, LDZ, LWORK, M, N
  23746. DOUBLE PRECISION ABSTOL, VL, VU
  23747. * ..
  23748. * .. Array Arguments ..
  23749. INTEGER IFAIL( * ), IWORK( * )
  23750. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * ),
  23751. $ Z( LDZ, * )
  23752. * ..
  23753. *
  23754. * Purpose
  23755. * =======
  23756. *
  23757. * DSYGVX computes selected eigenvalues, and optionally, eigenvectors
  23758. * of a real generalized symmetric-definite eigenproblem, of the form
  23759. * A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A
  23760. * and B are assumed to be symmetric and B is also positive definite.
  23761. * Eigenvalues and eigenvectors can be selected by specifying either a
  23762. * range of values or a range of indices for the desired eigenvalues.
  23763. *
  23764. * Arguments
  23765. * =========
  23766. *
  23767. * ITYPE (input) INTEGER
  23768. * Specifies the problem type to be solved:
  23769. * = 1: A*x = (lambda)*B*x
  23770. * = 2: A*B*x = (lambda)*x
  23771. * = 3: B*A*x = (lambda)*x
  23772. *
  23773. * JOBZ (input) CHARACTER*1
  23774. * = 'N': Compute eigenvalues only;
  23775. * = 'V': Compute eigenvalues and eigenvectors.
  23776. *
  23777. * RANGE (input) CHARACTER*1
  23778. * = 'A': all eigenvalues will be found.
  23779. * = 'V': all eigenvalues in the half-open interval (VL,VU]
  23780. * will be found.
  23781. * = 'I': the IL-th through IU-th eigenvalues will be found.
  23782. *
  23783. * UPLO (input) CHARACTER*1
  23784. * = 'U': Upper triangle of A and B are stored;
  23785. * = 'L': Lower triangle of A and B are stored.
  23786. *
  23787. * N (input) INTEGER
  23788. * The order of the matrix pencil (A,B). N >= 0.
  23789. *
  23790. * A (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  23791. * On entry, the symmetric matrix A. If UPLO = 'U', the
  23792. * leading N-by-N upper triangular part of A contains the
  23793. * upper triangular part of the matrix A. If UPLO = 'L',
  23794. * the leading N-by-N lower triangular part of A contains
  23795. * the lower triangular part of the matrix A.
  23796. *
  23797. * On exit, the lower triangle (if UPLO='L') or the upper
  23798. * triangle (if UPLO='U') of A, including the diagonal, is
  23799. * destroyed.
  23800. *
  23801. * LDA (input) INTEGER
  23802. * The leading dimension of the array A. LDA >= max(1,N).
  23803. *
  23804. * B (input/output) DOUBLE PRECISION array, dimension (LDA, N)
  23805. * On entry, the symmetric matrix B. If UPLO = 'U', the
  23806. * leading N-by-N upper triangular part of B contains the
  23807. * upper triangular part of the matrix B. If UPLO = 'L',
  23808. * the leading N-by-N lower triangular part of B contains
  23809. * the lower triangular part of the matrix B.
  23810. *
  23811. * On exit, if INFO <= N, the part of B containing the matrix is
  23812. * overwritten by the triangular factor U or L from the Cholesky
  23813. * factorization B = U**T*U or B = L*L**T.
  23814. *
  23815. * LDB (input) INTEGER
  23816. * The leading dimension of the array B. LDB >= max(1,N).
  23817. *
  23818. * VL (input) DOUBLE PRECISION
  23819. * VU (input) DOUBLE PRECISION
  23820. * If RANGE='V', the lower and upper bounds of the interval to
  23821. * be searched for eigenvalues. VL < VU.
  23822. * Not referenced if RANGE = 'A' or 'I'.
  23823. *
  23824. * IL (input) INTEGER
  23825. * IU (input) INTEGER
  23826. * If RANGE='I', the indices (in ascending order) of the
  23827. * smallest and largest eigenvalues to be returned.
  23828. * 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
  23829. * Not referenced if RANGE = 'A' or 'V'.
  23830. *
  23831. * ABSTOL (input) DOUBLE PRECISION
  23832. * The absolute error tolerance for the eigenvalues.
  23833. * An approximate eigenvalue is accepted as converged
  23834. * when it is determined to lie in an interval [a,b]
  23835. * of width less than or equal to
  23836. *
  23837. * ABSTOL + EPS * max( |a|,|b| ) ,
  23838. *
  23839. * where EPS is the machine precision. If ABSTOL is less than
  23840. * or equal to zero, then EPS*|T| will be used in its place,
  23841. * where |T| is the 1-norm of the tridiagonal matrix obtained
  23842. * by reducing A to tridiagonal form.
  23843. *
  23844. * Eigenvalues will be computed most accurately when ABSTOL is
  23845. * set to twice the underflow threshold 2*DLAMCH('S'), not zero.
  23846. * If this routine returns with INFO>0, indicating that some
  23847. * eigenvectors did not converge, try setting ABSTOL to
  23848. * 2*DLAMCH('S').
  23849. *
  23850. * M (output) INTEGER
  23851. * The total number of eigenvalues found. 0 <= M <= N.
  23852. * If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  23853. *
  23854. * W (output) DOUBLE PRECISION array, dimension (N)
  23855. * On normal exit, the first M elements contain the selected
  23856. * eigenvalues in ascending order.
  23857. *
  23858. * Z (output) DOUBLE PRECISION array, dimension (LDZ, max(1,M))
  23859. * If JOBZ = 'N', then Z is not referenced.
  23860. * If JOBZ = 'V', then if INFO = 0, the first M columns of Z
  23861. * contain the orthonormal eigenvectors of the matrix A
  23862. * corresponding to the selected eigenvalues, with the i-th
  23863. * column of Z holding the eigenvector associated with W(i).
  23864. * The eigenvectors are normalized as follows:
  23865. * if ITYPE = 1 or 2, Z**T*B*Z = I;
  23866. * if ITYPE = 3, Z**T*inv(B)*Z = I.
  23867. *
  23868. * If an eigenvector fails to converge, then that column of Z
  23869. * contains the latest approximation to the eigenvector, and the
  23870. * index of the eigenvector is returned in IFAIL.
  23871. * Note: the user must ensure that at least max(1,M) columns are
  23872. * supplied in the array Z; if RANGE = 'V', the exact value of M
  23873. * is not known in advance and an upper bound must be used.
  23874. *
  23875. * LDZ (input) INTEGER
  23876. * The leading dimension of the array Z. LDZ >= 1, and if
  23877. * JOBZ = 'V', LDZ >= max(1,N).
  23878. *
  23879. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  23880. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  23881. *
  23882. * LWORK (input) INTEGER
  23883. * The length of the array WORK. LWORK >= max(1,8*N).
  23884. * For optimal efficiency, LWORK >= (NB+3)*N,
  23885. * where NB is the blocksize for DSYTRD returned by ILAENV.
  23886. *
  23887. * If LWORK = -1, then a workspace query is assumed; the routine
  23888. * only calculates the optimal size of the WORK array, returns
  23889. * this value as the first entry of the WORK array, and no error
  23890. * message related to LWORK is issued by XERBLA.
  23891. *
  23892. * IWORK (workspace) INTEGER array, dimension (5*N)
  23893. *
  23894. * IFAIL (output) INTEGER array, dimension (N)
  23895. * If JOBZ = 'V', then if INFO = 0, the first M elements of
  23896. * IFAIL are zero. If INFO > 0, then IFAIL contains the
  23897. * indices of the eigenvectors that failed to converge.
  23898. * If JOBZ = 'N', then IFAIL is not referenced.
  23899. *
  23900. * INFO (output) INTEGER
  23901. * = 0: successful exit
  23902. * < 0: if INFO = -i, the i-th argument had an illegal value
  23903. * > 0: DPOTRF or DSYEVX returned an error code:
  23904. * <= N: if INFO = i, DSYEVX failed to converge;
  23905. * i eigenvectors failed to converge. Their indices
  23906. * are stored in array IFAIL.
  23907. * > N: if INFO = N + i, for 1 <= i <= N, then the leading
  23908. * minor of order i of B is not positive definite.
  23909. * The factorization of B could not be completed and
  23910. * no eigenvalues or eigenvectors were computed.
  23911. *
  23912. * Further Details
  23913. * ===============
  23914. *
  23915. * Based on contributions by
  23916. * Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA
  23917. *
  23918. * =====================================================================
  23919. *
  23920. * .. Parameters ..
  23921. DOUBLE PRECISION ONE
  23922. PARAMETER ( ONE = 1.0D+0 )
  23923. * ..
  23924. * .. Local Scalars ..
  23925. LOGICAL ALLEIG, INDEIG, LQUERY, UPPER, VALEIG, WANTZ
  23926. CHARACTER TRANS
  23927. INTEGER LWKMIN, LWKOPT, NB
  23928. * ..
  23929. * .. External Functions ..
  23930. LOGICAL LSAME
  23931. INTEGER ILAENV
  23932. EXTERNAL LSAME, ILAENV
  23933. * ..
  23934. * .. External Subroutines ..
  23935. EXTERNAL DPOTRF, DSYEVX, DSYGST, DTRMM, DTRSM, XERBLA
  23936. * ..
  23937. * .. Intrinsic Functions ..
  23938. INTRINSIC MAX, MIN
  23939. * ..
  23940. * .. Executable Statements ..
  23941. *
  23942. * Test the input parameters.
  23943. *
  23944. UPPER = LSAME( UPLO, 'U' )
  23945. WANTZ = LSAME( JOBZ, 'V' )
  23946. ALLEIG = LSAME( RANGE, 'A' )
  23947. VALEIG = LSAME( RANGE, 'V' )
  23948. INDEIG = LSAME( RANGE, 'I' )
  23949. LQUERY = ( LWORK.EQ.-1 )
  23950. *
  23951. INFO = 0
  23952. IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
  23953. INFO = -1
  23954. ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
  23955. INFO = -2
  23956. ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THEN
  23957. INFO = -3
  23958. ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THEN
  23959. INFO = -4
  23960. ELSE IF( N.LT.0 ) THEN
  23961. INFO = -5
  23962. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  23963. INFO = -7
  23964. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  23965. INFO = -9
  23966. ELSE
  23967. IF( VALEIG ) THEN
  23968. IF( N.GT.0 .AND. VU.LE.VL )
  23969. $ INFO = -11
  23970. ELSE IF( INDEIG ) THEN
  23971. IF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THEN
  23972. INFO = -12
  23973. ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THEN
  23974. INFO = -13
  23975. END IF
  23976. END IF
  23977. END IF
  23978. IF (INFO.EQ.0) THEN
  23979. IF (LDZ.LT.1 .OR. (WANTZ .AND. LDZ.LT.N)) THEN
  23980. INFO = -18
  23981. END IF
  23982. END IF
  23983. *
  23984. IF( INFO.EQ.0 ) THEN
  23985. LWKMIN = MAX( 1, 8*N )
  23986. NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
  23987. LWKOPT = MAX( LWKMIN, ( NB + 3 )*N )
  23988. WORK( 1 ) = LWKOPT
  23989. *
  23990. IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
  23991. INFO = -20
  23992. END IF
  23993. END IF
  23994. *
  23995. IF( INFO.NE.0 ) THEN
  23996. CALL XERBLA( 'DSYGVX', -INFO )
  23997. RETURN
  23998. ELSE IF( LQUERY ) THEN
  23999. RETURN
  24000. END IF
  24001. *
  24002. * Quick return if possible
  24003. *
  24004. M = 0
  24005. IF( N.EQ.0 ) THEN
  24006. RETURN
  24007. END IF
  24008. *
  24009. * Form a Cholesky factorization of B.
  24010. *
  24011. CALL DPOTRF( UPLO, N, B, LDB, INFO )
  24012. IF( INFO.NE.0 ) THEN
  24013. INFO = N + INFO
  24014. RETURN
  24015. END IF
  24016. *
  24017. * Transform problem to standard eigenvalue problem and solve.
  24018. *
  24019. CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )
  24020. CALL DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU, ABSTOL,
  24021. $ M, W, Z, LDZ, WORK, LWORK, IWORK, IFAIL, INFO )
  24022. *
  24023. IF( WANTZ ) THEN
  24024. *
  24025. * Backtransform eigenvectors to the original problem.
  24026. *
  24027. IF( INFO.GT.0 )
  24028. $ M = INFO - 1
  24029. IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN
  24030. *
  24031. * For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
  24032. * backtransform eigenvectors: x = inv(L)'*y or inv(U)*y
  24033. *
  24034. IF( UPPER ) THEN
  24035. TRANS = 'N'
  24036. ELSE
  24037. TRANS = 'T'
  24038. END IF
  24039. *
  24040. CALL DTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, M, ONE, B,
  24041. $ LDB, Z, LDZ )
  24042. *
  24043. ELSE IF( ITYPE.EQ.3 ) THEN
  24044. *
  24045. * For B*A*x=(lambda)*x;
  24046. * backtransform eigenvectors: x = L*y or U'*y
  24047. *
  24048. IF( UPPER ) THEN
  24049. TRANS = 'T'
  24050. ELSE
  24051. TRANS = 'N'
  24052. END IF
  24053. *
  24054. CALL DTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, M, ONE, B,
  24055. $ LDB, Z, LDZ )
  24056. END IF
  24057. END IF
  24058. *
  24059. * Set WORK(1) to optimal workspace size.
  24060. *
  24061. WORK( 1 ) = LWKOPT
  24062. *
  24063. RETURN
  24064. *
  24065. * End of DSYGVX
  24066. *
  24067. END
  24068. SUBROUTINE DSYSV( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK,
  24069. $ LWORK, INFO )
  24070. *
  24071. * -- LAPACK driver routine (version 3.1) --
  24072. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  24073. * November 2006
  24074. *
  24075. * .. Scalar Arguments ..
  24076. CHARACTER UPLO
  24077. INTEGER INFO, LDA, LDB, LWORK, N, NRHS
  24078. * ..
  24079. * .. Array Arguments ..
  24080. INTEGER IPIV( * )
  24081. DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )
  24082. * ..
  24083. *
  24084. * Purpose
  24085. * =======
  24086. *
  24087. * DSYSV computes the solution to a real system of linear equations
  24088. * A * X = B,
  24089. * where A is an N-by-N symmetric matrix and X and B are N-by-NRHS
  24090. * matrices.
  24091. *
  24092. * The diagonal pivoting method is used to factor A as
  24093. * A = U * D * U**T, if UPLO = 'U', or
  24094. * A = L * D * L**T, if UPLO = 'L',
  24095. * where U (or L) is a product of permutation and unit upper (lower)
  24096. * triangular matrices, and D is symmetric and block diagonal with
  24097. * 1-by-1 and 2-by-2 diagonal blocks. The factored form of A is then
  24098. * used to solve the system of equations A * X = B.
  24099. *
  24100. * Arguments
  24101. * =========
  24102. *
  24103. * UPLO (input) CHARACTER*1
  24104. * = 'U': Upper triangle of A is stored;
  24105. * = 'L': Lower triangle of A is stored.
  24106. *
  24107. * N (input) INTEGER
  24108. * The number of linear equations, i.e., the order of the
  24109. * matrix A. N >= 0.
  24110. *
  24111. * NRHS (input) INTEGER
  24112. * The number of right hand sides, i.e., the number of columns
  24113. * of the matrix B. NRHS >= 0.
  24114. *
  24115. * A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
  24116. * On entry, the symmetric matrix A. If UPLO = 'U', the leading
  24117. * N-by-N upper triangular part of A contains the upper
  24118. * triangular part of the matrix A, and the strictly lower
  24119. * triangular part of A is not referenced. If UPLO = 'L', the
  24120. * leading N-by-N lower triangular part of A contains the lower
  24121. * triangular part of the matrix A, and the strictly upper
  24122. * triangular part of A is not referenced.
  24123. *
  24124. * On exit, if INFO = 0, the block diagonal matrix D and the
  24125. * multipliers used to obtain the factor U or L from the
  24126. * factorization A = U*D*U**T or A = L*D*L**T as computed by
  24127. * DSYTRF.
  24128. *
  24129. * LDA (input) INTEGER
  24130. * The leading dimension of the array A. LDA >= max(1,N).
  24131. *
  24132. * IPIV (output) INTEGER array, dimension (N)
  24133. * Details of the interchanges and the block structure of D, as
  24134. * determined by DSYTRF. If IPIV(k) > 0, then rows and columns
  24135. * k and IPIV(k) were interchanged, and D(k,k) is a 1-by-1
  24136. * diagonal block. If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0,
  24137. * then rows and columns k-1 and -IPIV(k) were interchanged and
  24138. * D(k-1:k,k-1:k) is a 2-by-2 diagonal block. If UPLO = 'L' and
  24139. * IPIV(k) = IPIV(k+1) < 0, then rows and columns k+1 and
  24140. * -IPIV(k) were interchanged and D(k:k+1,k:k+1) is a 2-by-2
  24141. * diagonal block.
  24142. *
  24143. * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS)
  24144. * On entry, the N-by-NRHS right hand side matrix B.
  24145. * On exit, if INFO = 0, the N-by-NRHS solution matrix X.
  24146. *
  24147. * LDB (input) INTEGER
  24148. * The leading dimension of the array B. LDB >= max(1,N).
  24149. *
  24150. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  24151. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  24152. *
  24153. * LWORK (input) INTEGER
  24154. * The length of WORK. LWORK >= 1, and for best performance
  24155. * LWORK >= max(1,N*NB), where NB is the optimal blocksize for
  24156. * DSYTRF.
  24157. *
  24158. * If LWORK = -1, then a workspace query is assumed; the routine
  24159. * only calculates the optimal size of the WORK array, returns
  24160. * this value as the first entry of the WORK array, and no error
  24161. * message related to LWORK is issued by XERBLA.
  24162. *
  24163. * INFO (output) INTEGER
  24164. * = 0: successful exit
  24165. * < 0: if INFO = -i, the i-th argument had an illegal value
  24166. * > 0: if INFO = i, D(i,i) is exactly zero. The factorization
  24167. * has been completed, but the block diagonal matrix D is
  24168. * exactly singular, so the solution could not be computed.
  24169. *
  24170. * =====================================================================
  24171. *
  24172. * .. Local Scalars ..
  24173. LOGICAL LQUERY
  24174. INTEGER LWKOPT, NB
  24175. * ..
  24176. * .. External Functions ..
  24177. LOGICAL LSAME
  24178. INTEGER ILAENV
  24179. EXTERNAL LSAME, ILAENV
  24180. * ..
  24181. * .. External Subroutines ..
  24182. EXTERNAL DSYTRF, DSYTRS, XERBLA
  24183. * ..
  24184. * .. Intrinsic Functions ..
  24185. INTRINSIC MAX
  24186. * ..
  24187. * .. Executable Statements ..
  24188. *
  24189. * Test the input parameters.
  24190. *
  24191. INFO = 0
  24192. LQUERY = ( LWORK.EQ.-1 )
  24193. IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
  24194. INFO = -1
  24195. ELSE IF( N.LT.0 ) THEN
  24196. INFO = -2
  24197. ELSE IF( NRHS.LT.0 ) THEN
  24198. INFO = -3
  24199. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  24200. INFO = -5
  24201. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  24202. INFO = -8
  24203. ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
  24204. INFO = -10
  24205. END IF
  24206. *
  24207. IF( INFO.EQ.0 ) THEN
  24208. IF( N.EQ.0 ) THEN
  24209. LWKOPT = 1
  24210. ELSE
  24211. NB = ILAENV( 1, 'DSYTRF', UPLO, N, -1, -1, -1 )
  24212. LWKOPT = N*NB
  24213. END IF
  24214. WORK( 1 ) = LWKOPT
  24215. END IF
  24216. *
  24217. IF( INFO.NE.0 ) THEN
  24218. CALL XERBLA( 'DSYSV ', -INFO )
  24219. RETURN
  24220. ELSE IF( LQUERY ) THEN
  24221. RETURN
  24222. END IF
  24223. *
  24224. * Compute the factorization A = U*D*U' or A = L*D*L'.
  24225. *
  24226. CALL DSYTRF( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )
  24227. IF( INFO.EQ.0 ) THEN
  24228. *
  24229. * Solve the system A*X = B, overwriting B with X.
  24230. *
  24231. CALL DSYTRS( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO )
  24232. *
  24233. END IF
  24234. *
  24235. WORK( 1 ) = LWKOPT
  24236. *
  24237. RETURN
  24238. *
  24239. * End of DSYSV
  24240. *
  24241. END
  24242. SUBROUTINE DSYSVX( FACT, UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B,
  24243. $ LDB, X, LDX, RCOND, FERR, BERR, WORK, LWORK,
  24244. $ IWORK, INFO )
  24245. *
  24246. * -- LAPACK driver routine (version 3.1) --
  24247. * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  24248. * November 2006
  24249. *
  24250. * .. Scalar Arguments ..
  24251. CHARACTER FACT, UPLO
  24252. INTEGER INFO, LDA, LDAF, LDB, LDX, LWORK, N, NRHS
  24253. DOUBLE PRECISION RCOND
  24254. * ..
  24255. * .. Array Arguments ..
  24256. INTEGER IPIV( * ), IWORK( * )
  24257. DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),
  24258. $ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )
  24259. * ..
  24260. *
  24261. * Purpose
  24262. * =======
  24263. *
  24264. * DSYSVX uses the diagonal pivoting factorization to compute the
  24265. * solution to a real system of linear equations A * X = B,
  24266. * where A is an N-by-N symmetric matrix and X and B are N-by-NRHS
  24267. * matrices.
  24268. *
  24269. * Error bounds on the solution and a condition estimate are also
  24270. * provided.
  24271. *
  24272. * Description
  24273. * ===========
  24274. *
  24275. * The following steps are performed:
  24276. *
  24277. * 1. If FACT = 'N', the diagonal pivoting method is used to factor A.
  24278. * The form of the factorization is
  24279. * A = U * D * U**T, if UPLO = 'U', or
  24280. * A = L * D * L**T, if UPLO = 'L',
  24281. * where U (or L) is a product of permutation and unit upper (lower)
  24282. * triangular matrices, and D is symmetric and block diagonal with
  24283. * 1-by-1 and 2-by-2 diagonal blocks.
  24284. *
  24285. * 2. If some D(i,i)=0, so that D is exactly singular, then the routine
  24286. * returns with INFO = i. Otherwise, the factored form of A is used
  24287. * to estimate the condition number of the matrix A. If the
  24288. * reciprocal of the condition number is less than machine precision,
  24289. * INFO = N+1 is returned as a warning, but the routine still goes on
  24290. * to solve for X and compute error bounds as described below.
  24291. *
  24292. * 3. The system of equations is solved for X using the factored form
  24293. * of A.
  24294. *
  24295. * 4. Iterative refinement is applied to improve the computed solution
  24296. * matrix and calculate error bounds and backward error estimates
  24297. * for it.
  24298. *
  24299. * Arguments
  24300. * =========
  24301. *
  24302. * FACT (input) CHARACTER*1
  24303. * Specifies whether or not the factored form of A has been
  24304. * supplied on entry.
  24305. * = 'F': On entry, AF and IPIV contain the factored form of
  24306. * A. AF and IPIV will not be modified.
  24307. * = 'N': The matrix A will be copied to AF and factored.
  24308. *
  24309. * UPLO (input) CHARACTER*1
  24310. * = 'U': Upper triangle of A is stored;
  24311. * = 'L': Lower triangle of A is stored.
  24312. *
  24313. * N (input) INTEGER
  24314. * The number of linear equations, i.e., the order of the
  24315. * matrix A. N >= 0.
  24316. *
  24317. * NRHS (input) INTEGER
  24318. * The number of right hand sides, i.e., the number of columns
  24319. * of the matrices B and X. NRHS >= 0.
  24320. *
  24321. * A (input) DOUBLE PRECISION array, dimension (LDA,N)
  24322. * The symmetric matrix A. If UPLO = 'U', the leading N-by-N
  24323. * upper triangular part of A contains the upper triangular part
  24324. * of the matrix A, and the strictly lower triangular part of A
  24325. * is not referenced. If UPLO = 'L', the leading N-by-N lower
  24326. * triangular part of A contains the lower triangular part of
  24327. * the matrix A, and the strictly upper triangular part of A is
  24328. * not referenced.
  24329. *
  24330. * LDA (input) INTEGER
  24331. * The leading dimension of the array A. LDA >= max(1,N).
  24332. *
  24333. * AF (input or output) DOUBLE PRECISION array, dimension (LDAF,N)
  24334. * If FACT = 'F', then AF is an input argument and on entry
  24335. * contains the block diagonal matrix D and the multipliers used
  24336. * to obtain the factor U or L from the factorization
  24337. * A = U*D*U**T or A = L*D*L**T as computed by DSYTRF.
  24338. *
  24339. * If FACT = 'N', then AF is an output argument and on exit
  24340. * returns the block diagonal matrix D and the multipliers used
  24341. * to obtain the factor U or L from the factorization
  24342. * A = U*D*U**T or A = L*D*L**T.
  24343. *
  24344. * LDAF (input) INTEGER
  24345. * The leading dimension of the array AF. LDAF >= max(1,N).
  24346. *
  24347. * IPIV (input or output) INTEGER array, dimension (N)
  24348. * If FACT = 'F', then IPIV is an input argument and on entry
  24349. * contains details of the interchanges and the block structure
  24350. * of D, as determined by DSYTRF.
  24351. * If IPIV(k) > 0, then rows and columns k and IPIV(k) were
  24352. * interchanged and D(k,k) is a 1-by-1 diagonal block.
  24353. * If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and
  24354. * columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)
  24355. * is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) =
  24356. * IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were
  24357. * interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
  24358. *
  24359. * If FACT = 'N', then IPIV is an output argument and on exit
  24360. * contains details of the interchanges and the block structure
  24361. * of D, as determined by DSYTRF.
  24362. *
  24363. * B (input) DOUBLE PRECISION array, dimension (LDB,NRHS)
  24364. * The N-by-NRHS right hand side matrix B.
  24365. *
  24366. * LDB (input) INTEGER
  24367. * The leading dimension of the array B. LDB >= max(1,N).
  24368. *
  24369. * X (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
  24370. * If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X.
  24371. *
  24372. * LDX (input) INTEGER
  24373. * The leading dimension of the array X. LDX >= max(1,N).
  24374. *
  24375. * RCOND (output) DOUBLE PRECISION
  24376. * The estimate of the reciprocal condition number of the matrix
  24377. * A. If RCOND is less than the machine precision (in
  24378. * particular, if RCOND = 0), the matrix is singular to working
  24379. * precision. This condition is indicated by a return code of
  24380. * INFO > 0.
  24381. *
  24382. * FERR (output) DOUBLE PRECISION array, dimension (NRHS)
  24383. * The estimated forward error bound for each solution vector
  24384. * X(j) (the j-th column of the solution matrix X).
  24385. * If XTRUE is the true solution corresponding to X(j), FERR(j)
  24386. * is an estimated upper bound for the magnitude of the largest
  24387. * element in (X(j) - XTRUE) divided by the magnitude of the
  24388. * largest element in X(j). The estimate is as reliable as
  24389. * the estimate for RCOND, and is almost always a slight
  24390. * overestimate of the true error.
  24391. *
  24392. * BERR (output) DOUBLE PRECISION array, dimension (NRHS)
  24393. * The componentwise relative backward error of each solution
  24394. * vector X(j) (i.e., the smallest relative change in
  24395. * any element of A or B that makes X(j) an exact solution).
  24396. *
  24397. * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  24398. * On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  24399. *
  24400. * LWORK (input) INTEGER
  24401. * The length of WORK. LWORK >= max(1,3*N), and for best
  24402. * performance, when FACT = 'N', LWORK >= max(1,3*N,N*NB), where
  24403. * NB is the optimal blocksize for DSYTRF.
  24404. *
  24405. * If LWORK = -1, then a workspace query is assumed; the routine
  24406. * only calculates the optimal size of the WORK array, returns
  24407. * this value as the first entry of the WORK array, and no error
  24408. * message related to LWORK is issued by XERBLA.
  24409. *
  24410. * IWORK (workspace) INTEGER array, dimension (N)
  24411. *
  24412. * INFO (output) INTEGER
  24413. * = 0: successful exit
  24414. * < 0: if INFO = -i, the i-th argument had an illegal value
  24415. * > 0: if INFO = i, and i is
  24416. * <= N: D(i,i) is exactly zero. The factorization
  24417. * has been completed but the factor D is exactly
  24418. * singular, so the solution and error bounds could
  24419. * not be computed. RCOND = 0 is returned.
  24420. * = N+1: D is nonsingular, but RCOND is less than machine
  24421. * precision, meaning that the matrix is singular
  24422. * to working precision. Nevertheless, the
  24423. * solution and error bounds are computed because
  24424. * there are a number of situations where the
  24425. * computed solution can be more accurate than the
  24426. * value of RCOND would suggest.
  24427. *
  24428. * =====================================================================
  24429. *
  24430. * .. Parameters ..
  24431. DOUBLE PRECISION ZERO
  24432. PARAMETER ( ZERO = 0.0D+0 )
  24433. * ..
  24434. * .. Local Scalars ..
  24435. LOGICAL LQUERY, NOFACT
  24436. INTEGER LWKOPT, NB
  24437. DOUBLE PRECISION ANORM
  24438. * ..
  24439. * .. External Functions ..
  24440. LOGICAL LSAME
  24441. INTEGER ILAENV
  24442. DOUBLE PRECISION DLAMCH, DLANSY
  24443. EXTERNAL LSAME, ILAENV, DLAMCH, DLANSY
  24444. * ..
  24445. * .. External Subroutines ..
  24446. EXTERNAL DLACPY, DSYCON, DSYRFS, DSYTRF, DSYTRS, XERBLA
  24447. * ..
  24448. * .. Intrinsic Functions ..
  24449. INTRINSIC MAX
  24450. * ..
  24451. * .. Executable Statements ..
  24452. *
  24453. * Test the input parameters.
  24454. *
  24455. INFO = 0
  24456. NOFACT = LSAME( FACT, 'N' )
  24457. LQUERY = ( LWORK.EQ.-1 )
  24458. IF( .NOT.NOFACT .AND. .NOT.LSAME( FACT, 'F' ) ) THEN
  24459. INFO = -1
  24460. ELSE IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) )
  24461. $ THEN
  24462. INFO = -2
  24463. ELSE IF( N.LT.0 ) THEN
  24464. INFO = -3
  24465. ELSE IF( NRHS.LT.0 ) THEN
  24466. INFO = -4
  24467. ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  24468. INFO = -6
  24469. ELSE IF( LDAF.LT.MAX( 1, N ) ) THEN
  24470. INFO = -8
  24471. ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  24472. INFO = -11
  24473. ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
  24474. INFO = -13
  24475. ELSE IF( LWORK.LT.MAX( 1, 3*N ) .AND. .NOT.LQUERY ) THEN
  24476. INFO = -18
  24477. END IF
  24478. *
  24479. IF( INFO.EQ.0 ) THEN
  24480. LWKOPT = MAX( 1, 3*N )
  24481. IF( NOFACT ) THEN
  24482. NB = ILAENV( 1, 'DSYTRF', UPLO, N, -1, -1, -1 )
  24483. LWKOPT = MAX( LWKOPT, N*NB )
  24484. END IF
  24485. WORK( 1 ) = LWKOPT
  24486. END IF
  24487. *
  24488. IF( INFO.NE.0 ) THEN
  24489. CALL XERBLA( 'DSYSVX', -INFO )
  24490. RETURN
  24491. ELSE IF( LQUERY ) THEN
  24492. RETURN
  24493. END IF
  24494. *
  24495. IF( NOFACT ) THEN
  24496. *
  24497. * Compute the factorization A = U*D*U' or A = L*D*L'.
  24498. *
  24499. CALL DLACPY( UPLO, N, N, A, LDA, AF, LDAF )
  24500. CALL DSYTRF( UPLO, N, AF, LDAF, IPIV, WORK, LWORK, INFO )
  24501. *
  24502. * Return if INFO is non-zero.
  24503. *
  24504. IF( INFO.GT.0 )THEN
  24505. RCOND = ZERO
  24506. RETURN
  24507. END IF
  24508. END IF
  24509. *
  24510. * Compute the norm of the matrix A.
  24511. *
  24512. ANORM = DLANSY( 'I', UPLO, N, A, LDA, WORK )
  24513. *
  24514. * Compute the reciprocal of the condition number of A.
  24515. *
  24516. CALL DSYCON( UPLO, N, AF, LDAF, IPIV, ANORM, RCOND, WORK, IWORK,
  24517. $ INFO )
  24518. *
  24519. * Compute the solution vectors X.
  24520. *
  24521. CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
  24522. CALL DSYTRS( UPLO, N, NRHS, AF, LDAF, IPIV, X, LDX, INFO )
  24523. *
  24524. * Use iterative refinement to improve the computed solutions and
  24525. * compute error bounds and backward error estimates for them.
  24526. *
  24527. CALL DSYRFS( UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB, X,
  24528. $ LDX, FERR, BERR, WORK, IWORK, INFO )
  24529. *
  24530. * Set INFO = N+1 if the matrix is singular to working precision.
  24531. *
  24532. IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
  24533. $ INFO = N + 1
  24534. *
  24535. WORK( 1 ) = LWKOPT
  24536. *
  24537. RETURN
  24538. *
  24539. * End of DSYSVX
  24540. *
  24541. END