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.

slaqp2rk.f 25 kB

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