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

zlaqp2rk.f 25 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. *> \brief \b ZLAQP2RK computes truncated QR factorization with column pivoting of a complex matrix block using Level 2 BLAS and overwrites a complex m-by-nrhs matrix B with Q**H * B.
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download ZLAQP2RK + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlaqp2rk.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlaqp2rk.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlaqp2rk.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE ZLAQP2RK( M, N, NRHS, IOFFSET, KMAX, ABSTOL, RELTOL,
  22. * $ KP1, MAXC2NRM, A, LDA, K, MAXC2NRMK,
  23. * $ RELMAXC2NRMK, JPIV, TAU, VN1, VN2, WORK,
  24. * $ INFO )
  25. * IMPLICIT NONE
  26. *
  27. * .. Scalar Arguments ..
  28. * INTEGER INFO, IOFFSET, KP1, K, KMAX, LDA, M, N, NRHS
  29. * DOUBLE PRECISION ABSTOL, MAXC2NRM, MAXC2NRMK, RELMAXC2NRMK,
  30. * $ RELTOL
  31. * ..
  32. * .. Array Arguments ..
  33. * INTEGER JPIV( * )
  34. * DOUBLE PRECISION VN1( * ), VN2( * )
  35. * COMPLEX*16 A( LDA, * ), TAU( * ), WORK( * )
  36. * $
  37. * ..
  38. *
  39. *
  40. *> \par Purpose:
  41. * =============
  42. *>
  43. *> \verbatim
  44. *>
  45. *> ZLAQP2RK computes a truncated (rank K) or full rank Householder QR
  46. *> factorization with column pivoting of the complex matrix
  47. *> block A(IOFFSET+1:M,1:N) as
  48. *>
  49. *> A * P(K) = Q(K) * R(K).
  50. *>
  51. *> The routine uses Level 2 BLAS. The block A(1:IOFFSET,1:N)
  52. *> is accordingly pivoted, but not factorized.
  53. *>
  54. *> The routine also overwrites the right-hand-sides matrix block B
  55. *> stored in A(IOFFSET+1:M,N+1:N+NRHS) with Q(K)**H * B.
  56. *> \endverbatim
  57. *
  58. * Arguments:
  59. * ==========
  60. *
  61. *> \param[in] M
  62. *> \verbatim
  63. *> M is INTEGER
  64. *> The number of rows of the matrix A. M >= 0.
  65. *> \endverbatim
  66. *>
  67. *> \param[in] N
  68. *> \verbatim
  69. *> N is INTEGER
  70. *> The number of columns of the matrix A. N >= 0.
  71. *> \endverbatim
  72. *>
  73. *> \param[in] NRHS
  74. *> \verbatim
  75. *> NRHS is INTEGER
  76. *> The number of right hand sides, i.e., the number of
  77. *> columns of the matrix B. NRHS >= 0.
  78. *> \endverbatim
  79. *>
  80. *> \param[in] IOFFSET
  81. *> \verbatim
  82. *> IOFFSET is INTEGER
  83. *> The number of rows of the matrix A that must be pivoted
  84. *> but not factorized. IOFFSET >= 0.
  85. *>
  86. *> IOFFSET also represents the number of columns of the whole
  87. *> original matrix A_orig that have been factorized
  88. *> in the previous steps.
  89. *> \endverbatim
  90. *>
  91. *> \param[in] KMAX
  92. *> \verbatim
  93. *> KMAX is INTEGER
  94. *>
  95. *> The first factorization stopping criterion. KMAX >= 0.
  96. *>
  97. *> The maximum number of columns of the matrix A to factorize,
  98. *> i.e. the maximum factorization rank.
  99. *>
  100. *> a) If KMAX >= min(M-IOFFSET,N), then this stopping
  101. *> criterion is not used, factorize columns
  102. *> depending on ABSTOL and RELTOL.
  103. *>
  104. *> b) If KMAX = 0, then this stopping criterion is
  105. *> satisfied on input and the routine exits immediately.
  106. *> This means that the factorization is not performed,
  107. *> the matrices A and B and the arrays TAU, IPIV
  108. *> are not modified.
  109. *> \endverbatim
  110. *>
  111. *> \param[in] ABSTOL
  112. *> \verbatim
  113. *> ABSTOL is DOUBLE PRECISION, cannot be NaN.
  114. *>
  115. *> The second factorization stopping criterion.
  116. *>
  117. *> The absolute tolerance (stopping threshold) for
  118. *> maximum column 2-norm of the residual matrix.
  119. *> The algorithm converges (stops the factorization) when
  120. *> the maximum column 2-norm of the residual matrix
  121. *> is less than or equal to ABSTOL.
  122. *>
  123. *> a) If ABSTOL < 0.0, then this stopping criterion is not
  124. *> used, the routine factorizes columns depending
  125. *> on KMAX and RELTOL.
  126. *> This includes the case ABSTOL = -Inf.
  127. *>
  128. *> b) If 0.0 <= ABSTOL then the input value
  129. *> of ABSTOL is used.
  130. *> \endverbatim
  131. *>
  132. *> \param[in] RELTOL
  133. *> \verbatim
  134. *> RELTOL is DOUBLE PRECISION, cannot be NaN.
  135. *>
  136. *> The third factorization stopping criterion.
  137. *>
  138. *> The tolerance (stopping threshold) for the ratio of the
  139. *> maximum column 2-norm of the residual matrix to the maximum
  140. *> column 2-norm of the original matrix A_orig. The algorithm
  141. *> converges (stops the factorization), when this ratio is
  142. *> less than or equal to RELTOL.
  143. *>
  144. *> a) If RELTOL < 0.0, then this stopping criterion is not
  145. *> used, the routine factorizes columns depending
  146. *> on KMAX and ABSTOL.
  147. *> This includes the case RELTOL = -Inf.
  148. *>
  149. *> d) If 0.0 <= RELTOL then the input value of RELTOL
  150. *> is used.
  151. *> \endverbatim
  152. *>
  153. *> \param[in] KP1
  154. *> \verbatim
  155. *> KP1 is INTEGER
  156. *> The index of the column with the maximum 2-norm in
  157. *> the whole original matrix A_orig determined in the
  158. *> main routine ZGEQP3RK. 1 <= KP1 <= N_orig_mat.
  159. *> \endverbatim
  160. *>
  161. *> \param[in] MAXC2NRM
  162. *> \verbatim
  163. *> MAXC2NRM is DOUBLE PRECISION
  164. *> The maximum column 2-norm of the whole original
  165. *> matrix A_orig computed in the main routine ZGEQP3RK.
  166. *> MAXC2NRM >= 0.
  167. *> \endverbatim
  168. *>
  169. *> \param[in,out] A
  170. *> \verbatim
  171. *> A is COMPLEX*16 array, dimension (LDA,N+NRHS)
  172. *> On entry:
  173. *> the M-by-N matrix A and M-by-NRHS matrix B, as in
  174. *>
  175. *> N NRHS
  176. *> array_A = M [ mat_A, mat_B ]
  177. *>
  178. *> On exit:
  179. *> 1. The elements in block A(IOFFSET+1:M,1:K) below
  180. *> the diagonal together with the array TAU represent
  181. *> the unitary matrix Q(K) as a product of elementary
  182. *> reflectors.
  183. *> 2. The upper triangular block of the matrix A stored
  184. *> in A(IOFFSET+1:M,1:K) is the triangular factor obtained.
  185. *> 3. The block of the matrix A stored in A(1:IOFFSET,1:N)
  186. *> has been accordingly pivoted, but not factorized.
  187. *> 4. The rest of the array A, block A(IOFFSET+1:M,K+1:N+NRHS).
  188. *> The left part A(IOFFSET+1:M,K+1:N) of this block
  189. *> contains the residual of the matrix A, and,
  190. *> if NRHS > 0, the right part of the block
  191. *> A(IOFFSET+1:M,N+1:N+NRHS) contains the block of
  192. *> the right-hand-side matrix B. Both these blocks have been
  193. *> updated by multiplication from the left by Q(K)**H.
  194. *> \endverbatim
  195. *>
  196. *> \param[in] LDA
  197. *> \verbatim
  198. *> LDA is INTEGER
  199. *> The leading dimension of the array A. LDA >= max(1,M).
  200. *> \endverbatim
  201. *>
  202. *> \param[out] K
  203. *> \verbatim
  204. *> K is INTEGER
  205. *> Factorization rank of the matrix A, i.e. the rank of
  206. *> the factor R, which is the same as the number of non-zero
  207. *> rows of the factor R. 0 <= K <= min(M-IOFFSET,KMAX,N).
  208. *>
  209. *> K also represents the number of non-zero Householder
  210. *> vectors.
  211. *> \endverbatim
  212. *>
  213. *> \param[out] MAXC2NRMK
  214. *> \verbatim
  215. *> MAXC2NRMK is DOUBLE PRECISION
  216. *> The maximum column 2-norm of the residual matrix,
  217. *> when the factorization stopped at rank K. MAXC2NRMK >= 0.
  218. *> \endverbatim
  219. *>
  220. *> \param[out] RELMAXC2NRMK
  221. *> \verbatim
  222. *> RELMAXC2NRMK is DOUBLE PRECISION
  223. *> The ratio MAXC2NRMK / MAXC2NRM of the maximum column
  224. *> 2-norm of the residual matrix (when the factorization
  225. *> stopped at rank K) to the maximum column 2-norm of the
  226. *> whole original matrix A. RELMAXC2NRMK >= 0.
  227. *> \endverbatim
  228. *>
  229. *> \param[out] JPIV
  230. *> \verbatim
  231. *> JPIV is INTEGER array, dimension (N)
  232. *> Column pivot indices, for 1 <= j <= N, column j
  233. *> of the matrix A was interchanged with column JPIV(j).
  234. *> \endverbatim
  235. *>
  236. *> \param[out] TAU
  237. *> \verbatim
  238. *> TAU is COMPLEX*16 array, dimension (min(M-IOFFSET,N))
  239. *> The scalar factors of the elementary reflectors.
  240. *> \endverbatim
  241. *>
  242. *> \param[in,out] VN1
  243. *> \verbatim
  244. *> VN1 is DOUBLE PRECISION array, dimension (N)
  245. *> The vector with the partial column norms.
  246. *> \endverbatim
  247. *>
  248. *> \param[in,out] VN2
  249. *> \verbatim
  250. *> VN2 is DOUBLE PRECISION array, dimension (N)
  251. *> The vector with the exact column norms.
  252. *> \endverbatim
  253. *>
  254. *> \param[out] WORK
  255. *> \verbatim
  256. *> WORK is COMPLEX*16 array, dimension (N-1)
  257. *> Used in ZLARF subroutine to apply an elementary
  258. *> reflector from the left.
  259. *> \endverbatim
  260. *>
  261. *> \param[out] INFO
  262. *> \verbatim
  263. *> INFO is INTEGER
  264. *> 1) INFO = 0: successful exit.
  265. *> 2) If INFO = j_1, where 1 <= j_1 <= N, then NaN was
  266. *> detected and the routine stops the computation.
  267. *> The j_1-th column of the matrix A or the j_1-th
  268. *> element of array TAU contains the first occurrence
  269. *> of NaN in the factorization step K+1 ( when K columns
  270. *> have been factorized ).
  271. *>
  272. *> On exit:
  273. *> K is set to the number of
  274. *> factorized columns without
  275. *> exception.
  276. *> MAXC2NRMK is set to NaN.
  277. *> RELMAXC2NRMK is set to NaN.
  278. *> TAU(K+1:min(M,N)) is not set and contains undefined
  279. *> elements. If j_1=K+1, TAU(K+1)
  280. *> may contain NaN.
  281. *> 3) If INFO = j_2, where N+1 <= j_2 <= 2*N, then no NaN
  282. *> was detected, but +Inf (or -Inf) was detected and
  283. *> the routine continues the computation until completion.
  284. *> The (j_2-N)-th column of the matrix A contains the first
  285. *> occurrence of +Inf (or -Inf) in the factorization
  286. *> step K+1 ( when K columns have been factorized ).
  287. *> \endverbatim
  288. *
  289. * Authors:
  290. * ========
  291. *
  292. *> \author Univ. of Tennessee
  293. *> \author Univ. of California Berkeley
  294. *> \author Univ. of Colorado Denver
  295. *> \author NAG Ltd.
  296. *
  297. *> \ingroup laqp2rk
  298. *
  299. *> \par References:
  300. * ================
  301. *> [1] A Level 3 BLAS QR factorization algorithm with column pivoting developed in 1996.
  302. *> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain.
  303. *> X. Sun, Computer Science Dept., Duke University, USA.
  304. *> C. H. Bischof, Math. and Comp. Sci. Div., Argonne National Lab, USA.
  305. *> A BLAS-3 version of the QR factorization with column pivoting.
  306. *> LAPACK Working Note 114
  307. *> \htmlonly
  308. *> <a href="https://www.netlib.org/lapack/lawnspdf/lawn114.pdf">https://www.netlib.org/lapack/lawnspdf/lawn114.pdf</a>
  309. *> \endhtmlonly
  310. *> and in
  311. *> SIAM J. Sci. Comput., 19(5):1486-1494, Sept. 1998.
  312. *> \htmlonly
  313. *> <a href="https://doi.org/10.1137/S1064827595296732">https://doi.org/10.1137/S1064827595296732</a>
  314. *> \endhtmlonly
  315. *>
  316. *> [2] A partial column norm updating strategy developed in 2006.
  317. *> Z. Drmac and Z. Bujanovic, Dept. of Math., University of Zagreb, Croatia.
  318. *> On the failure of rank revealing QR factorization software – a case study.
  319. *> LAPACK Working Note 176.
  320. *> \htmlonly
  321. *> <a href="http://www.netlib.org/lapack/lawnspdf/lawn176.pdf">http://www.netlib.org/lapack/lawnspdf/lawn176.pdf</a>
  322. *> \endhtmlonly
  323. *> and in
  324. *> ACM Trans. Math. Softw. 35, 2, Article 12 (July 2008), 28 pages.
  325. *> \htmlonly
  326. *> <a href="https://doi.org/10.1145/1377612.1377616">https://doi.org/10.1145/1377612.1377616</a>
  327. *> \endhtmlonly
  328. *
  329. *> \par Contributors:
  330. * ==================
  331. *>
  332. *> \verbatim
  333. *>
  334. *> November 2023, Igor Kozachenko, James Demmel,
  335. *> EECS Department,
  336. *> University of California, Berkeley, USA.
  337. *>
  338. *> \endverbatim
  339. *
  340. * =====================================================================
  341. SUBROUTINE ZLAQP2RK( M, N, NRHS, IOFFSET, KMAX, ABSTOL, RELTOL,
  342. $ KP1, MAXC2NRM, A, LDA, K, MAXC2NRMK,
  343. $ RELMAXC2NRMK, JPIV, TAU, VN1, VN2, WORK,
  344. $ INFO )
  345. IMPLICIT NONE
  346. *
  347. * -- LAPACK auxiliary routine --
  348. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  349. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  350. *
  351. * .. Scalar Arguments ..
  352. INTEGER INFO, IOFFSET, KP1, K, KMAX, LDA, M, N, NRHS
  353. DOUBLE PRECISION ABSTOL, MAXC2NRM, MAXC2NRMK, RELMAXC2NRMK,
  354. $ RELTOL
  355. * ..
  356. * .. Array Arguments ..
  357. INTEGER JPIV( * )
  358. DOUBLE PRECISION VN1( * ), VN2( * )
  359. COMPLEX*16 A( LDA, * ), TAU( * ), WORK( * )
  360. * ..
  361. *
  362. * =====================================================================
  363. *
  364. * .. Parameters ..
  365. DOUBLE PRECISION ZERO, ONE
  366. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  367. COMPLEX*16 CZERO, CONE
  368. PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
  369. $ CONE = ( 1.0D+0, 0.0D+0 ) )
  370. * ..
  371. * .. Local Scalars ..
  372. INTEGER I, ITEMP, J, JMAXC2NRM, KK, KP, MINMNFACT,
  373. $ MINMNUPDT
  374. DOUBLE PRECISION HUGEVAL, TAUNAN, TEMP, TEMP2, TOL3Z
  375. COMPLEX*16 AIKK
  376. * ..
  377. * .. External Subroutines ..
  378. EXTERNAL ZLARF, ZLARFG, ZSWAP
  379. * ..
  380. * .. Intrinsic Functions ..
  381. INTRINSIC ABS, DBLE, DCONJG, DIMAG, MAX, MIN, SQRT
  382. * ..
  383. * .. External Functions ..
  384. LOGICAL DISNAN
  385. INTEGER IDAMAX
  386. DOUBLE PRECISION DLAMCH, DZNRM2
  387. EXTERNAL DISNAN, DLAMCH, IDAMAX, DZNRM2
  388. * ..
  389. * .. Executable Statements ..
  390. *
  391. * Initialize INFO
  392. *
  393. INFO = 0
  394. *
  395. * MINMNFACT in the smallest dimension of the submatrix
  396. * A(IOFFSET+1:M,1:N) to be factorized.
  397. *
  398. * MINMNUPDT is the smallest dimension
  399. * of the subarray A(IOFFSET+1:M,1:N+NRHS) to be udated, which
  400. * contains the submatrices A(IOFFSET+1:M,1:N) and
  401. * B(IOFFSET+1:M,1:NRHS) as column blocks.
  402. *
  403. MINMNFACT = MIN( M-IOFFSET, N )
  404. MINMNUPDT = MIN( M-IOFFSET, N+NRHS )
  405. KMAX = MIN( KMAX, MINMNFACT )
  406. TOL3Z = SQRT( DLAMCH( 'Epsilon' ) )
  407. HUGEVAL = DLAMCH( 'Overflow' )
  408. *
  409. * Compute the factorization, KK is the lomn loop index.
  410. *
  411. DO KK = 1, KMAX
  412. *
  413. I = IOFFSET + KK
  414. *
  415. IF( I.EQ.1 ) THEN
  416. *
  417. * ============================================================
  418. *
  419. * We are at the first column of the original whole matrix A,
  420. * therefore we use the computed KP1 and MAXC2NRM from the
  421. * main routine.
  422. *
  423. KP = KP1
  424. *
  425. * ============================================================
  426. *
  427. ELSE
  428. *
  429. * ============================================================
  430. *
  431. * Determine the pivot column in KK-th step, i.e. the index
  432. * of the column with the maximum 2-norm in the
  433. * submatrix A(I:M,K:N).
  434. *
  435. KP = ( KK-1 ) + IDAMAX( N-KK+1, VN1( KK ), 1 )
  436. *
  437. * Determine the maximum column 2-norm and the relative maximum
  438. * column 2-norm of the submatrix A(I:M,KK:N) in step KK.
  439. * RELMAXC2NRMK will be computed later, after somecondition
  440. * checks on MAXC2NRMK.
  441. *
  442. MAXC2NRMK = VN1( KP )
  443. *
  444. * ============================================================
  445. *
  446. * Check if the submatrix A(I:M,KK:N) contains NaN, and set
  447. * INFO parameter to the column number, where the first NaN
  448. * is found and return from the routine.
  449. * We need to check the condition only if the
  450. * column index (same as row index) of the original whole
  451. * matrix is larger than 1, since the condition for whole
  452. * original matrix is checked in the main routine.
  453. *
  454. IF( DISNAN( MAXC2NRMK ) ) THEN
  455. *
  456. * Set K, the number of factorized columns.
  457. * that are not zero.
  458. *
  459. K = KK - 1
  460. INFO = K + KP
  461. *
  462. * Set RELMAXC2NRMK to NaN.
  463. *
  464. RELMAXC2NRMK = MAXC2NRMK
  465. *
  466. * Array TAU(K+1:MINMNFACT) is not set and contains
  467. * undefined elements.
  468. *
  469. RETURN
  470. END IF
  471. *
  472. * ============================================================
  473. *
  474. * Quick return, if the submatrix A(I:M,KK:N) is
  475. * a zero matrix.
  476. * We need to check the condition only if the
  477. * column index (same as row index) of the original whole
  478. * matrix is larger than 1, since the condition for whole
  479. * original matrix is checked in the main routine.
  480. *
  481. IF( MAXC2NRMK.EQ.ZERO ) THEN
  482. *
  483. * Set K, the number of factorized columns.
  484. * that are not zero.
  485. *
  486. K = KK - 1
  487. RELMAXC2NRMK = ZERO
  488. *
  489. * Set TAUs corresponding to the columns that were not
  490. * factorized to ZERO, i.e. set TAU(KK:MINMNFACT) to CZERO.
  491. *
  492. DO J = KK, MINMNFACT
  493. TAU( J ) = CZERO
  494. END DO
  495. *
  496. * Return from the routine.
  497. *
  498. RETURN
  499. *
  500. END IF
  501. *
  502. * ============================================================
  503. *
  504. * Check if the submatrix A(I:M,KK:N) contains Inf,
  505. * set INFO parameter to the column number, where
  506. * the first Inf is found plus N, and continue
  507. * the computation.
  508. * We need to check the condition only if the
  509. * column index (same as row index) of the original whole
  510. * matrix is larger than 1, since the condition for whole
  511. * original matrix is checked in the main routine.
  512. *
  513. IF( INFO.EQ.0 .AND. MAXC2NRMK.GT.HUGEVAL ) THEN
  514. INFO = N + KK - 1 + KP
  515. END IF
  516. *
  517. * ============================================================
  518. *
  519. * Test for the second and third stopping criteria.
  520. * NOTE: There is no need to test for ABSTOL >= ZERO, since
  521. * MAXC2NRMK is non-negative. Similarly, there is no need
  522. * to test for RELTOL >= ZERO, since RELMAXC2NRMK is
  523. * non-negative.
  524. * We need to check the condition only if the
  525. * column index (same as row index) of the original whole
  526. * matrix is larger than 1, since the condition for whole
  527. * original matrix is checked in the main routine.
  528. RELMAXC2NRMK = MAXC2NRMK / MAXC2NRM
  529. *
  530. IF( MAXC2NRMK.LE.ABSTOL .OR. RELMAXC2NRMK.LE.RELTOL ) THEN
  531. *
  532. * Set K, the number of factorized columns.
  533. *
  534. K = KK - 1
  535. *
  536. * Set TAUs corresponding to the columns that were not
  537. * factorized to ZERO, i.e. set TAU(KK:MINMNFACT) to CZERO.
  538. *
  539. DO J = KK, MINMNFACT
  540. TAU( J ) = CZERO
  541. END DO
  542. *
  543. * Return from the routine.
  544. *
  545. RETURN
  546. *
  547. END IF
  548. *
  549. * ============================================================
  550. *
  551. * End ELSE of IF(I.EQ.1)
  552. *
  553. END IF
  554. *
  555. * ===============================================================
  556. *
  557. * If the pivot column is not the first column of the
  558. * subblock A(1:M,KK:N):
  559. * 1) swap the KK-th column and the KP-th pivot column
  560. * in A(1:M,1:N);
  561. * 2) copy the KK-th element into the KP-th element of the partial
  562. * and exact 2-norm vectors VN1 and VN2. ( Swap is not needed
  563. * for VN1 and VN2 since we use the element with the index
  564. * larger than KK in the next loop step.)
  565. * 3) Save the pivot interchange with the indices relative to the
  566. * the original matrix A, not the block A(1:M,1:N).
  567. *
  568. IF( KP.NE.KK ) THEN
  569. CALL ZSWAP( M, A( 1, KP ), 1, A( 1, KK ), 1 )
  570. VN1( KP ) = VN1( KK )
  571. VN2( KP ) = VN2( KK )
  572. ITEMP = JPIV( KP )
  573. JPIV( KP ) = JPIV( KK )
  574. JPIV( KK ) = ITEMP
  575. END IF
  576. *
  577. * Generate elementary reflector H(KK) using the column A(I:M,KK),
  578. * if the column has more than one element, otherwise
  579. * the elementary reflector would be an identity matrix,
  580. * and TAU(KK) = CZERO.
  581. *
  582. IF( I.LT.M ) THEN
  583. CALL ZLARFG( M-I+1, A( I, KK ), A( I+1, KK ), 1,
  584. $ TAU( KK ) )
  585. ELSE
  586. TAU( KK ) = CZERO
  587. END IF
  588. *
  589. * Check if TAU(KK) contains NaN, set INFO parameter
  590. * to the column number where NaN is found and return from
  591. * the routine.
  592. * NOTE: There is no need to check TAU(KK) for Inf,
  593. * since ZLARFG cannot produce TAU(KK) or Householder vector
  594. * below the diagonal containing Inf. Only BETA on the diagonal,
  595. * returned by ZLARFG can contain Inf, which requires
  596. * TAU(KK) to contain NaN. Therefore, this case of generating Inf
  597. * by ZLARFG is covered by checking TAU(KK) for NaN.
  598. *
  599. IF( DISNAN( DBLE( TAU(KK) ) ) ) THEN
  600. TAUNAN = DBLE( TAU(KK) )
  601. ELSE IF( DISNAN( DIMAG( TAU(KK) ) ) ) THEN
  602. TAUNAN = DIMAG( TAU(KK) )
  603. ELSE
  604. TAUNAN = ZERO
  605. END IF
  606. *
  607. IF( DISNAN( TAUNAN ) ) THEN
  608. K = KK - 1
  609. INFO = KK
  610. *
  611. * Set MAXC2NRMK and RELMAXC2NRMK to NaN.
  612. *
  613. MAXC2NRMK = TAUNAN
  614. RELMAXC2NRMK = TAUNAN
  615. *
  616. * Array TAU(KK:MINMNFACT) is not set and contains
  617. * undefined elements, except the first element TAU(KK) = NaN.
  618. *
  619. RETURN
  620. END IF
  621. *
  622. * Apply H(KK)**H to A(I:M,KK+1:N+NRHS) from the left.
  623. * ( If M >= N, then at KK = N there is no residual matrix,
  624. * i.e. no columns of A to update, only columns of B.
  625. * If M < N, then at KK = M-IOFFSET, I = M and we have a
  626. * one-row residual matrix in A and the elementary
  627. * reflector is a unit matrix, TAU(KK) = CZERO, i.e. no update
  628. * is needed for the residual matrix in A and the
  629. * right-hand-side-matrix in B.
  630. * Therefore, we update only if
  631. * KK < MINMNUPDT = min(M-IOFFSET, N+NRHS)
  632. * condition is satisfied, not only KK < N+NRHS )
  633. *
  634. IF( KK.LT.MINMNUPDT ) THEN
  635. AIKK = A( I, KK )
  636. A( I, KK ) = CONE
  637. CALL ZLARF( 'Left', M-I+1, N+NRHS-KK, A( I, KK ), 1,
  638. $ DCONJG( TAU( KK ) ), A( I, KK+1 ), LDA,
  639. $ WORK( 1 ) )
  640. A( I, KK ) = AIKK
  641. END IF
  642. *
  643. IF( KK.LT.MINMNFACT ) THEN
  644. *
  645. * Update the partial column 2-norms for the residual matrix,
  646. * only if the residual matrix A(I+1:M,KK+1:N) exists, i.e.
  647. * when KK < min(M-IOFFSET, N).
  648. *
  649. DO J = KK + 1, N
  650. IF( VN1( J ).NE.ZERO ) THEN
  651. *
  652. * NOTE: The following lines follow from the analysis in
  653. * Lapack Working Note 176.
  654. *
  655. TEMP = ONE - ( ABS( A( I, J ) ) / VN1( J ) )**2
  656. TEMP = MAX( TEMP, ZERO )
  657. TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
  658. IF( TEMP2 .LE. TOL3Z ) THEN
  659. *
  660. * Compute the column 2-norm for the partial
  661. * column A(I+1:M,J) by explicitly computing it,
  662. * and store it in both partial 2-norm vector VN1
  663. * and exact column 2-norm vector VN2.
  664. *
  665. VN1( J ) = DZNRM2( M-I, A( I+1, J ), 1 )
  666. VN2( J ) = VN1( J )
  667. *
  668. ELSE
  669. *
  670. * Update the column 2-norm for the partial
  671. * column A(I+1:M,J) by removing one
  672. * element A(I,J) and store it in partial
  673. * 2-norm vector VN1.
  674. *
  675. VN1( J ) = VN1( J )*SQRT( TEMP )
  676. *
  677. END IF
  678. END IF
  679. END DO
  680. *
  681. END IF
  682. *
  683. * End factorization loop
  684. *
  685. END DO
  686. *
  687. * If we reached this point, all colunms have been factorized,
  688. * i.e. no condition was triggered to exit the routine.
  689. * Set the number of factorized columns.
  690. *
  691. K = KMAX
  692. *
  693. * We reached the end of the loop, i.e. all KMAX columns were
  694. * factorized, we need to set MAXC2NRMK and RELMAXC2NRMK before
  695. * we return.
  696. *
  697. IF( K.LT.MINMNFACT ) THEN
  698. *
  699. JMAXC2NRM = K + IDAMAX( N-K, VN1( K+1 ), 1 )
  700. MAXC2NRMK = VN1( JMAXC2NRM )
  701. *
  702. IF( K.EQ.0 ) THEN
  703. RELMAXC2NRMK = ONE
  704. ELSE
  705. RELMAXC2NRMK = MAXC2NRMK / MAXC2NRM
  706. END IF
  707. *
  708. ELSE
  709. MAXC2NRMK = ZERO
  710. RELMAXC2NRMK = ZERO
  711. END IF
  712. *
  713. * We reached the end of the loop, i.e. all KMAX columns were
  714. * factorized, set TAUs corresponding to the columns that were
  715. * not factorized to ZERO, i.e. TAU(K+1:MINMNFACT) set to CZERO.
  716. *
  717. DO J = K + 1, MINMNFACT
  718. TAU( J ) = CZERO
  719. END DO
  720. *
  721. RETURN
  722. *
  723. * End of ZLAQP2RK
  724. *
  725. END