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.

dlaqp3rk.f 35 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. *> \brief \b DLAQP3RK computes a step of truncated QR factorization with column pivoting of a real m-by-n matrix A using Level 3 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 DLAQP3RK + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqp3rk.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqp3rk.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqp3rk.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE DLAQP3RK( M, N, NRHS, IOFFSET, NB, ABSTOL,
  22. * $ RELTOL, KP1, MAXC2NRM, A, LDA, DONE, KB,
  23. * $ MAXC2NRMK, RELMAXC2NRMK, JPIV, TAU,
  24. * $ VN1, VN2, AUXV, F, LDF, IWORK, INFO )
  25. * IMPLICIT NONE
  26. * LOGICAL DONE
  27. * INTEGER INFO, IOFFSET, KB, KP1, LDA, LDF, M, N,
  28. * $ NB, NRHS
  29. * DOUBLE PRECISION ABSTOL, MAXC2NRM, MAXC2NRMK, RELMAXC2NRMK,
  30. * $ RELTOL
  31. *
  32. * .. Scalar Arguments ..
  33. * LOGICAL DONE
  34. * INTEGER KB, LDA, LDF, M, N, NB, NRHS, IOFFSET
  35. * DOUBLE PRECISION ABSTOL, MAXC2NRM, MAXC2NRMK, RELMAXC2NRMK,
  36. * $ RELTOL
  37. * ..
  38. * .. Array Arguments ..
  39. * INTEGER IWORK( * ), JPIV( * )
  40. * DOUBLE PRECISION A( LDA, * ), AUXV( * ), F( LDF, * ), TAU( * ),
  41. * $ VN1( * ), VN2( * )
  42. * ..
  43. *
  44. *
  45. *> \par Purpose:
  46. * =============
  47. *>
  48. *> \verbatim
  49. *>
  50. *> DLAQP3RK computes a step of truncated QR factorization with column
  51. *> pivoting of a real M-by-N matrix A block A(IOFFSET+1:M,1:N)
  52. *> by using Level 3 BLAS as
  53. *>
  54. *> A * P(KB) = Q(KB) * R(KB).
  55. *>
  56. *> The routine tries to factorize NB columns from A starting from
  57. *> the row IOFFSET+1 and updates the residual matrix with BLAS 3
  58. *> xGEMM. The number of actually factorized columns is returned
  59. *> is smaller than NB.
  60. *>
  61. *> Block A(1:IOFFSET,1:N) is accordingly pivoted, but not factorized.
  62. *>
  63. *> The routine also overwrites the right-hand-sides B matrix stored
  64. *> in A(IOFFSET+1:M,1:N+1:N+NRHS) with Q(KB)**T * B.
  65. *>
  66. *> Cases when the number of factorized columns KB < NB:
  67. *>
  68. *> (1) In some cases, due to catastrophic cancellations, it cannot
  69. *> factorize all NB columns and need to update the residual matrix.
  70. *> Hence, the actual number of factorized columns in the block returned
  71. *> in KB is smaller than NB. The logical DONE is returned as FALSE.
  72. *> The factorization of the whole original matrix A_orig must proceed
  73. *> with the next block.
  74. *>
  75. *> (2) Whenever the stopping criterion ABSTOL or RELTOL is satisfied,
  76. *> the factorization of the whole original matrix A_orig is stopped,
  77. *> the logical DONE is returned as TRUE. The number of factorized
  78. *> columns which is smaller than NB is returned in KB.
  79. *>
  80. *> (3) In case both stopping criteria ABSTOL or RELTOL are not used,
  81. *> and when the residual matrix is a zero matrix in some factorization
  82. *> step KB, the factorization of the whole original matrix A_orig is
  83. *> stopped, the logical DONE is returned as TRUE. The number of
  84. *> factorized columns which is smaller than NB is returned in KB.
  85. *>
  86. *> (4) Whenever NaN is detected in the matrix A or in the array TAU,
  87. *> the factorization of the whole original matrix A_orig is stopped,
  88. *> the logical DONE is returned as TRUE. The number of factorized
  89. *> columns which is smaller than NB is returned in KB. The INFO
  90. *> parameter is set to the column index of the first NaN occurrence.
  91. *>
  92. *> \endverbatim
  93. *
  94. * Arguments:
  95. * ==========
  96. *
  97. *> \param[in] M
  98. *> \verbatim
  99. *> M is INTEGER
  100. *> The number of rows of the matrix A. M >= 0.
  101. *> \endverbatim
  102. *>
  103. *> \param[in] N
  104. *> \verbatim
  105. *> N is INTEGER
  106. *> The number of columns of the matrix A. N >= 0
  107. *> \endverbatim
  108. *>
  109. *> \param[in] NRHS
  110. *> \verbatim
  111. *> NRHS is INTEGER
  112. *> The number of right hand sides, i.e., the number of
  113. *> columns of the matrix B. NRHS >= 0.
  114. *> \endverbatim
  115. *>
  116. *> \param[in] IOFFSET
  117. *> \verbatim
  118. *> IOFFSET is INTEGER
  119. *> The number of rows of the matrix A that must be pivoted
  120. *> but not factorized. IOFFSET >= 0.
  121. *>
  122. *> IOFFSET also represents the number of columns of the whole
  123. *> original matrix A_orig that have been factorized
  124. *> in the previous steps.
  125. *> \endverbatim
  126. *>
  127. *> \param[in] NB
  128. *> \verbatim
  129. *> NB is INTEGER
  130. *> Factorization block size, i.e the number of columns
  131. *> to factorize in the matrix A. 0 <= NB
  132. *>
  133. *> If NB = 0, then the routine exits immediately.
  134. *> This means that the factorization is not performed,
  135. *> the matrices A and B and the arrays TAU, IPIV
  136. *> are not modified.
  137. *> \endverbatim
  138. *>
  139. *> \param[in] ABSTOL
  140. *> \verbatim
  141. *> ABSTOL is DOUBLE PRECISION, cannot be NaN.
  142. *>
  143. *> The absolute tolerance (stopping threshold) for
  144. *> maximum column 2-norm of the residual matrix.
  145. *> The algorithm converges (stops the factorization) when
  146. *> the maximum column 2-norm of the residual matrix
  147. *> is less than or equal to ABSTOL.
  148. *>
  149. *> a) If ABSTOL < 0.0, then this stopping criterion is not
  150. *> used, the routine factorizes columns depending
  151. *> on NB and RELTOL.
  152. *> This includes the case ABSTOL = -Inf.
  153. *>
  154. *> b) If 0.0 <= ABSTOL then the input value
  155. *> of ABSTOL is used.
  156. *> \endverbatim
  157. *>
  158. *> \param[in] RELTOL
  159. *> \verbatim
  160. *> RELTOL is DOUBLE PRECISION, cannot be NaN.
  161. *>
  162. *> The tolerance (stopping threshold) for the ratio of the
  163. *> maximum column 2-norm of the residual matrix to the maximum
  164. *> column 2-norm of the original matrix A_orig. The algorithm
  165. *> converges (stops the factorization), when this ratio is
  166. *> less than or equal to RELTOL.
  167. *>
  168. *> a) If RELTOL < 0.0, then this stopping criterion is not
  169. *> used, the routine factorizes columns depending
  170. *> on NB and ABSTOL.
  171. *> This includes the case RELTOL = -Inf.
  172. *>
  173. *> d) If 0.0 <= RELTOL then the input value of RELTOL
  174. *> is used.
  175. *> \endverbatim
  176. *>
  177. *> \param[in] KP1
  178. *> \verbatim
  179. *> KP1 is INTEGER
  180. *> The index of the column with the maximum 2-norm in
  181. *> the whole original matrix A_orig determined in the
  182. *> main routine DGEQP3RK. 1 <= KP1 <= N_orig.
  183. *> \endverbatim
  184. *>
  185. *> \param[in] MAXC2NRM
  186. *> \verbatim
  187. *> MAXC2NRM is DOUBLE PRECISION
  188. *> The maximum column 2-norm of the whole original
  189. *> matrix A_orig computed in the main routine DGEQP3RK.
  190. *> MAXC2NRM >= 0.
  191. *> \endverbatim
  192. *>
  193. *> \param[in,out] A
  194. *> \verbatim
  195. *> A is DOUBLE PRECISION array, dimension (LDA,N+NRHS)
  196. *> On entry:
  197. *> the M-by-N matrix A and M-by-NRHS matrix B, as in
  198. *>
  199. *> N NRHS
  200. *> array_A = M [ mat_A, mat_B ]
  201. *>
  202. *> On exit:
  203. *> 1. The elements in block A(IOFFSET+1:M,1:KB) below
  204. *> the diagonal together with the array TAU represent
  205. *> the orthogonal matrix Q(KB) as a product of elementary
  206. *> reflectors.
  207. *> 2. The upper triangular block of the matrix A stored
  208. *> in A(IOFFSET+1:M,1:KB) is the triangular factor obtained.
  209. *> 3. The block of the matrix A stored in A(1:IOFFSET,1:N)
  210. *> has been accordingly pivoted, but not factorized.
  211. *> 4. The rest of the array A, block A(IOFFSET+1:M,KB+1:N+NRHS).
  212. *> The left part A(IOFFSET+1:M,KB+1:N) of this block
  213. *> contains the residual of the matrix A, and,
  214. *> if NRHS > 0, the right part of the block
  215. *> A(IOFFSET+1:M,N+1:N+NRHS) contains the block of
  216. *> the right-hand-side matrix B. Both these blocks have been
  217. *> updated by multiplication from the left by Q(KB)**T.
  218. *> \endverbatim
  219. *>
  220. *> \param[in] LDA
  221. *> \verbatim
  222. *> LDA is INTEGER
  223. *> The leading dimension of the array A. LDA >= max(1,M).
  224. *> \endverbatim
  225. *>
  226. *> \param[out]
  227. *> \verbatim
  228. *> DONE is LOGICAL
  229. *> TRUE: a) if the factorization completed before processing
  230. *> all min(M-IOFFSET,NB,N) columns due to ABSTOL
  231. *> or RELTOL criterion,
  232. *> b) if the factorization completed before processing
  233. *> all min(M-IOFFSET,NB,N) columns due to the
  234. *> residual matrix being a ZERO matrix.
  235. *> c) when NaN was detected in the matrix A
  236. *> or in the array TAU.
  237. *> FALSE: otherwise.
  238. *> \endverbatim
  239. *>
  240. *> \param[out] KB
  241. *> \verbatim
  242. *> KB is INTEGER
  243. *> Factorization rank of the matrix A, i.e. the rank of
  244. *> the factor R, which is the same as the number of non-zero
  245. *> rows of the factor R. 0 <= KB <= min(M-IOFFSET,NB,N).
  246. *>
  247. *> KB also represents the number of non-zero Householder
  248. *> vectors.
  249. *> \endverbatim
  250. *>
  251. *> \param[out] MAXC2NRMK
  252. *> \verbatim
  253. *> MAXC2NRMK is DOUBLE PRECISION
  254. *> The maximum column 2-norm of the residual matrix,
  255. *> when the factorization stopped at rank KB. MAXC2NRMK >= 0.
  256. *> \endverbatim
  257. *>
  258. *> \param[out] RELMAXC2NRMK
  259. *> \verbatim
  260. *> RELMAXC2NRMK is DOUBLE PRECISION
  261. *> The ratio MAXC2NRMK / MAXC2NRM of the maximum column
  262. *> 2-norm of the residual matrix (when the factorization
  263. *> stopped at rank KB) to the maximum column 2-norm of the
  264. *> original matrix A_orig. RELMAXC2NRMK >= 0.
  265. *> \endverbatim
  266. *>
  267. *> \param[out] JPIV
  268. *> \verbatim
  269. *> JPIV is INTEGER array, dimension (N)
  270. *> Column pivot indices, for 1 <= j <= N, column j
  271. *> of the matrix A was interchanged with column JPIV(j).
  272. *> \endverbatim
  273. *>
  274. *> \param[out] TAU
  275. *> \verbatim
  276. *> TAU is DOUBLE PRECISION array, dimension (min(M-IOFFSET,N))
  277. *> The scalar factors of the elementary reflectors.
  278. *> \endverbatim
  279. *>
  280. *> \param[in,out] VN1
  281. *> \verbatim
  282. *> VN1 is DOUBLE PRECISION array, dimension (N)
  283. *> The vector with the partial column norms.
  284. *> \endverbatim
  285. *>
  286. *> \param[in,out] VN2
  287. *> \verbatim
  288. *> VN2 is DOUBLE PRECISION array, dimension (N)
  289. *> The vector with the exact column norms.
  290. *> \endverbatim
  291. *>
  292. *> \param[out] AUXV
  293. *> \verbatim
  294. *> AUXV is DOUBLE PRECISION array, dimension (NB)
  295. *> Auxiliary vector.
  296. *> \endverbatim
  297. *>
  298. *> \param[out] F
  299. *> \verbatim
  300. *> F is DOUBLE PRECISION array, dimension (LDF,NB)
  301. *> Matrix F**T = L*(Y**T)*A.
  302. *> \endverbatim
  303. *>
  304. *> \param[in] LDF
  305. *> \verbatim
  306. *> LDF is INTEGER
  307. *> The leading dimension of the array F. LDF >= max(1,N+NRHS).
  308. *> \endverbatim
  309. *>
  310. *> \param[out] IWORK
  311. *> \verbatim
  312. *> IWORK is INTEGER array, dimension (N-1).
  313. *> Is a work array. ( IWORK is used to store indices
  314. *> of "bad" columns for norm downdating in the residual
  315. *> matrix ).
  316. *> \endverbatim
  317. *>
  318. *> \param[out] INFO
  319. *> \verbatim
  320. *> INFO is INTEGER
  321. *> 1) INFO = 0: successful exit.
  322. *> 2) If INFO = j_1, where 1 <= j_1 <= N, then NaN was
  323. *> detected and the routine stops the computation.
  324. *> The j_1-th column of the matrix A or the j_1-th
  325. *> element of array TAU contains the first occurrence
  326. *> of NaN in the factorization step KB+1 ( when KB columns
  327. *> have been factorized ).
  328. *>
  329. *> On exit:
  330. *> KB is set to the number of
  331. *> factorized columns without
  332. *> exception.
  333. *> MAXC2NRMK is set to NaN.
  334. *> RELMAXC2NRMK is set to NaN.
  335. *> TAU(KB+1:min(M,N)) is not set and contains undefined
  336. *> elements. If j_1=KB+1, TAU(KB+1)
  337. *> may contain NaN.
  338. *> 3) If INFO = j_2, where N+1 <= j_2 <= 2*N, then no NaN
  339. *> was detected, but +Inf (or -Inf) was detected and
  340. *> the routine continues the computation until completion.
  341. *> The (j_2-N)-th column of the matrix A contains the first
  342. *> occurrence of +Inf (or -Inf) in the actorization
  343. *> step KB+1 ( when KB columns have been factorized ).
  344. *> \endverbatim
  345. *
  346. * Authors:
  347. * ========
  348. *
  349. *> \author Univ. of Tennessee
  350. *> \author Univ. of California Berkeley
  351. *> \author Univ. of Colorado Denver
  352. *> \author NAG Ltd.
  353. *
  354. *> \ingroup laqp3rk
  355. *
  356. *> \par References:
  357. * ================
  358. *> [1] A Level 3 BLAS QR factorization algorithm with column pivoting developed in 1996.
  359. *> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain.
  360. *> X. Sun, Computer Science Dept., Duke University, USA.
  361. *> C. H. Bischof, Math. and Comp. Sci. Div., Argonne National Lab, USA.
  362. *> A BLAS-3 version of the QR factorization with column pivoting.
  363. *> LAPACK Working Note 114
  364. *> \htmlonly
  365. *> <a href="https://www.netlib.org/lapack/lawnspdf/lawn114.pdf">https://www.netlib.org/lapack/lawnspdf/lawn114.pdf</a>
  366. *> \endhtmlonly
  367. *> and in
  368. *> SIAM J. Sci. Comput., 19(5):1486-1494, Sept. 1998.
  369. *> \htmlonly
  370. *> <a href="https://doi.org/10.1137/S1064827595296732">https://doi.org/10.1137/S1064827595296732</a>
  371. *> \endhtmlonly
  372. *>
  373. *> [2] A partial column norm updating strategy developed in 2006.
  374. *> Z. Drmac and Z. Bujanovic, Dept. of Math., University of Zagreb, Croatia.
  375. *> On the failure of rank revealing QR factorization software – a case study.
  376. *> LAPACK Working Note 176.
  377. *> \htmlonly
  378. *> <a href="http://www.netlib.org/lapack/lawnspdf/lawn176.pdf">http://www.netlib.org/lapack/lawnspdf/lawn176.pdf</a>
  379. *> \endhtmlonly
  380. *> and in
  381. *> ACM Trans. Math. Softw. 35, 2, Article 12 (July 2008), 28 pages.
  382. *> \htmlonly
  383. *> <a href="https://doi.org/10.1145/1377612.1377616">https://doi.org/10.1145/1377612.1377616</a>
  384. *> \endhtmlonly
  385. *
  386. *> \par Contributors:
  387. * ==================
  388. *>
  389. *> \verbatim
  390. *>
  391. *> November 2023, Igor Kozachenko, James Demmel,
  392. *> EECS Department,
  393. *> University of California, Berkeley, USA.
  394. *>
  395. *> \endverbatim
  396. *
  397. * =====================================================================
  398. SUBROUTINE DLAQP3RK( M, N, NRHS, IOFFSET, NB, ABSTOL,
  399. $ RELTOL, KP1, MAXC2NRM, A, LDA, DONE, KB,
  400. $ MAXC2NRMK, RELMAXC2NRMK, JPIV, TAU,
  401. $ VN1, VN2, AUXV, F, LDF, IWORK, INFO )
  402. IMPLICIT NONE
  403. *
  404. * -- LAPACK auxiliary routine --
  405. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  406. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  407. *
  408. * .. Scalar Arguments ..
  409. LOGICAL DONE
  410. INTEGER INFO, IOFFSET, KB, KP1, LDA, LDF, M, N,
  411. $ NB, NRHS
  412. DOUBLE PRECISION ABSTOL, MAXC2NRM, MAXC2NRMK, RELMAXC2NRMK,
  413. $ RELTOL
  414. * ..
  415. * .. Array Arguments ..
  416. INTEGER IWORK( * ), JPIV( * )
  417. DOUBLE PRECISION A( LDA, * ), AUXV( * ), F( LDF, * ), TAU( * ),
  418. $ VN1( * ), VN2( * )
  419. * ..
  420. *
  421. * =====================================================================
  422. *
  423. * .. Parameters ..
  424. DOUBLE PRECISION ZERO, ONE
  425. PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  426. * ..
  427. * .. Local Scalars ..
  428. INTEGER ITEMP, J, K, MINMNFACT, MINMNUPDT,
  429. $ LSTICC, KP, I, IF
  430. DOUBLE PRECISION AIK, HUGEVAL, TEMP, TEMP2, TOL3Z
  431. * ..
  432. * .. External Subroutines ..
  433. EXTERNAL DGEMM, DGEMV, DLARFG, DSWAP
  434. * ..
  435. * .. Intrinsic Functions ..
  436. INTRINSIC ABS, MAX, MIN, SQRT
  437. * ..
  438. * .. External Functions ..
  439. LOGICAL DISNAN
  440. INTEGER IDAMAX
  441. DOUBLE PRECISION DLAMCH, DNRM2
  442. EXTERNAL DISNAN, DLAMCH, IDAMAX, DNRM2
  443. * ..
  444. * .. Executable Statements ..
  445. *
  446. * Initialize INFO
  447. *
  448. INFO = 0
  449. *
  450. * MINMNFACT in the smallest dimension of the submatrix
  451. * A(IOFFSET+1:M,1:N) to be factorized.
  452. *
  453. MINMNFACT = MIN( M-IOFFSET, N )
  454. MINMNUPDT = MIN( M-IOFFSET, N+NRHS )
  455. NB = MIN( NB, MINMNFACT )
  456. TOL3Z = SQRT( DLAMCH( 'Epsilon' ) )
  457. HUGEVAL = DLAMCH( 'Overflow' )
  458. *
  459. * Compute factorization in a while loop over NB columns,
  460. * K is the column index in the block A(1:M,1:N).
  461. *
  462. K = 0
  463. LSTICC = 0
  464. DONE = .FALSE.
  465. *
  466. DO WHILE ( K.LT.NB .AND. LSTICC.EQ.0 )
  467. K = K + 1
  468. I = IOFFSET + K
  469. *
  470. IF( I.EQ.1 ) THEN
  471. *
  472. * We are at the first column of the original whole matrix A_orig,
  473. * therefore we use the computed KP1 and MAXC2NRM from the
  474. * main routine.
  475. *
  476. KP = KP1
  477. *
  478. ELSE
  479. *
  480. * Determine the pivot column in K-th step, i.e. the index
  481. * of the column with the maximum 2-norm in the
  482. * submatrix A(I:M,K:N).
  483. *
  484. KP = ( K-1 ) + IDAMAX( N-K+1, VN1( K ), 1 )
  485. *
  486. * Determine the maximum column 2-norm and the relative maximum
  487. * column 2-norm of the submatrix A(I:M,K:N) in step K.
  488. *
  489. MAXC2NRMK = VN1( KP )
  490. *
  491. * ============================================================
  492. *
  493. * Check if the submatrix A(I:M,K:N) contains NaN, set
  494. * INFO parameter to the column number, where the first NaN
  495. * is found and return from the routine.
  496. * We need to check the condition only if the
  497. * column index (same as row index) of the original whole
  498. * matrix is larger than 1, since the condition for whole
  499. * original matrix is checked in the main routine.
  500. *
  501. IF( DISNAN( MAXC2NRMK ) ) THEN
  502. *
  503. DONE = .TRUE.
  504. *
  505. * Set KB, the number of factorized partial columns
  506. * that are non-zero in each step in the block,
  507. * i.e. the rank of the factor R.
  508. * Set IF, the number of processed rows in the block, which
  509. * is the same as the number of processed rows in
  510. * the original whole matrix A_orig.
  511. *
  512. KB = K - 1
  513. IF = I - 1
  514. INFO = KB + KP
  515. *
  516. * Set RELMAXC2NRMK to NaN.
  517. *
  518. RELMAXC2NRMK = MAXC2NRMK
  519. *
  520. * There is no need to apply the block reflector to the
  521. * residual of the matrix A stored in A(KB+1:M,KB+1:N),
  522. * since the submatrix contains NaN and we stop
  523. * the computation.
  524. * But, we need to apply the block reflector to the residual
  525. * right hand sides stored in A(KB+1:M,N+1:N+NRHS), if the
  526. * residual right hand sides exist. This occurs
  527. * when ( NRHS != 0 AND KB <= (M-IOFFSET) ):
  528. *
  529. * A(I+1:M,N+1:N+NRHS) := A(I+1:M,N+1:N+NRHS) -
  530. * A(I+1:M,1:KB) * F(N+1:N+NRHS,1:KB)**T.
  531. IF( NRHS.GT.0 .AND. KB.LT.(M-IOFFSET) ) THEN
  532. CALL DGEMM( 'No transpose', 'Transpose',
  533. $ M-IF, NRHS, KB, -ONE, A( IF+1, 1 ), LDA,
  534. $ F( N+1, 1 ), LDF, ONE, A( IF+1, N+1 ), LDA )
  535. END IF
  536. *
  537. * There is no need to recompute the 2-norm of the
  538. * difficult columns, since we stop the factorization.
  539. *
  540. * Array TAU(KF+1:MINMNFACT) is not set and contains
  541. * undefined elements.
  542. *
  543. * Return from the routine.
  544. *
  545. RETURN
  546. END IF
  547. *
  548. * Quick return, if the submatrix A(I:M,K:N) is
  549. * a zero matrix. We need to check it only if the column index
  550. * (same as row index) is larger than 1, since the condition
  551. * for the whole original matrix A_orig is checked in the main
  552. * routine.
  553. *
  554. IF( MAXC2NRMK.EQ.ZERO ) THEN
  555. *
  556. DONE = .TRUE.
  557. *
  558. * Set KB, the number of factorized partial columns
  559. * that are non-zero in each step in the block,
  560. * i.e. the rank of the factor R.
  561. * Set IF, the number of processed rows in the block, which
  562. * is the same as the number of processed rows in
  563. * the original whole matrix A_orig.
  564. *
  565. KB = K - 1
  566. IF = I - 1
  567. RELMAXC2NRMK = ZERO
  568. *
  569. * There is no need to apply the block reflector to the
  570. * residual of the matrix A stored in A(KB+1:M,KB+1:N),
  571. * since the submatrix is zero and we stop the computation.
  572. * But, we need to apply the block reflector to the residual
  573. * right hand sides stored in A(KB+1:M,N+1:N+NRHS), if the
  574. * residual right hand sides exist. This occurs
  575. * when ( NRHS != 0 AND KB <= (M-IOFFSET) ):
  576. *
  577. * A(I+1:M,N+1:N+NRHS) := A(I+1:M,N+1:N+NRHS) -
  578. * A(I+1:M,1:KB) * F(N+1:N+NRHS,1:KB)**T.
  579. *
  580. IF( NRHS.GT.0 .AND. KB.LT.(M-IOFFSET) ) THEN
  581. CALL DGEMM( 'No transpose', 'Transpose',
  582. $ M-IF, NRHS, KB, -ONE, A( IF+1, 1 ), LDA,
  583. $ F( N+1, 1 ), LDF, ONE, A( IF+1, N+1 ), LDA )
  584. END IF
  585. *
  586. * There is no need to recompute the 2-norm of the
  587. * difficult columns, since we stop the factorization.
  588. *
  589. * Set TAUs corresponding to the columns that were not
  590. * factorized to ZERO, i.e. set TAU(KB+1:MINMNFACT) = ZERO,
  591. * which is equivalent to seting TAU(K:MINMNFACT) = ZERO.
  592. *
  593. DO J = K, MINMNFACT
  594. TAU( J ) = ZERO
  595. END DO
  596. *
  597. * Return from the routine.
  598. *
  599. RETURN
  600. *
  601. END IF
  602. *
  603. * ============================================================
  604. *
  605. * Check if the submatrix A(I:M,K:N) contains Inf,
  606. * set INFO parameter to the column number, where
  607. * the first Inf is found plus N, and continue
  608. * the computation.
  609. * We need to check the condition only if the
  610. * column index (same as row index) of the original whole
  611. * matrix is larger than 1, since the condition for whole
  612. * original matrix is checked in the main routine.
  613. *
  614. IF( INFO.EQ.0 .AND. MAXC2NRMK.GT.HUGEVAL ) THEN
  615. INFO = N + K - 1 + KP
  616. END IF
  617. *
  618. * ============================================================
  619. *
  620. * Test for the second and third tolerance stopping criteria.
  621. * NOTE: There is no need to test for ABSTOL.GE.ZERO, since
  622. * MAXC2NRMK is non-negative. Similarly, there is no need
  623. * to test for RELTOL.GE.ZERO, since RELMAXC2NRMK is
  624. * non-negative.
  625. * We need to check the condition only if the
  626. * column index (same as row index) of the original whole
  627. * matrix is larger than 1, since the condition for whole
  628. * original matrix is checked in the main routine.
  629. *
  630. RELMAXC2NRMK = MAXC2NRMK / MAXC2NRM
  631. *
  632. IF( MAXC2NRMK.LE.ABSTOL .OR. RELMAXC2NRMK.LE.RELTOL ) THEN
  633. *
  634. DONE = .TRUE.
  635. *
  636. * Set KB, the number of factorized partial columns
  637. * that are non-zero in each step in the block,
  638. * i.e. the rank of the factor R.
  639. * Set IF, the number of processed rows in the block, which
  640. * is the same as the number of processed rows in
  641. * the original whole matrix A_orig;
  642. *
  643. KB = K - 1
  644. IF = I - 1
  645. *
  646. * Apply the block reflector to the residual of the
  647. * matrix A and the residual of the right hand sides B, if
  648. * the residual matrix and and/or the residual of the right
  649. * hand sides exist, i.e. if the submatrix
  650. * A(I+1:M,KB+1:N+NRHS) exists. This occurs when
  651. * KB < MINMNUPDT = min( M-IOFFSET, N+NRHS ):
  652. *
  653. * A(IF+1:M,K+1:N+NRHS) := A(IF+1:M,KB+1:N+NRHS) -
  654. * A(IF+1:M,1:KB) * F(KB+1:N+NRHS,1:KB)**T.
  655. *
  656. IF( KB.LT.MINMNUPDT ) THEN
  657. CALL DGEMM( 'No transpose', 'Transpose',
  658. $ M-IF, N+NRHS-KB, KB,-ONE, A( IF+1, 1 ), LDA,
  659. $ F( KB+1, 1 ), LDF, ONE, A( IF+1, KB+1 ), LDA )
  660. END IF
  661. *
  662. * There is no need to recompute the 2-norm of the
  663. * difficult columns, since we stop the factorization.
  664. *
  665. * Set TAUs corresponding to the columns that were not
  666. * factorized to ZERO, i.e. set TAU(KB+1:MINMNFACT) = ZERO,
  667. * which is equivalent to seting TAU(K:MINMNFACT) = ZERO.
  668. *
  669. DO J = K, MINMNFACT
  670. TAU( J ) = ZERO
  671. END DO
  672. *
  673. * Return from the routine.
  674. *
  675. RETURN
  676. *
  677. END IF
  678. *
  679. * ============================================================
  680. *
  681. * End ELSE of IF(I.EQ.1)
  682. *
  683. END IF
  684. *
  685. * ===============================================================
  686. *
  687. * If the pivot column is not the first column of the
  688. * subblock A(1:M,K:N):
  689. * 1) swap the K-th column and the KP-th pivot column
  690. * in A(1:M,1:N);
  691. * 2) swap the K-th row and the KP-th row in F(1:N,1:K-1)
  692. * 3) copy the K-th element into the KP-th element of the partial
  693. * and exact 2-norm vectors VN1 and VN2. (Swap is not needed
  694. * for VN1 and VN2 since we use the element with the index
  695. * larger than K in the next loop step.)
  696. * 4) Save the pivot interchange with the indices relative to the
  697. * the original matrix A_orig, not the block A(1:M,1:N).
  698. *
  699. IF( KP.NE.K ) THEN
  700. CALL DSWAP( M, A( 1, KP ), 1, A( 1, K ), 1 )
  701. CALL DSWAP( K-1, F( KP, 1 ), LDF, F( K, 1 ), LDF )
  702. VN1( KP ) = VN1( K )
  703. VN2( KP ) = VN2( K )
  704. ITEMP = JPIV( KP )
  705. JPIV( KP ) = JPIV( K )
  706. JPIV( K ) = ITEMP
  707. END IF
  708. *
  709. * Apply previous Householder reflectors to column K:
  710. * A(I:M,K) := A(I:M,K) - A(I:M,1:K-1)*F(K,1:K-1)**T.
  711. *
  712. IF( K.GT.1 ) THEN
  713. CALL DGEMV( 'No transpose', M-I+1, K-1, -ONE, A( I, 1 ),
  714. $ LDA, F( K, 1 ), LDF, ONE, A( I, K ), 1 )
  715. END IF
  716. *
  717. * Generate elementary reflector H(k) using the column A(I:M,K).
  718. *
  719. IF( I.LT.M ) THEN
  720. CALL DLARFG( M-I+1, A( I, K ), A( I+1, K ), 1, TAU( K ) )
  721. ELSE
  722. TAU( K ) = ZERO
  723. END IF
  724. *
  725. * Check if TAU(K) contains NaN, set INFO parameter
  726. * to the column number where NaN is found and return from
  727. * the routine.
  728. * NOTE: There is no need to check TAU(K) for Inf,
  729. * since DLARFG cannot produce TAU(K) or Householder vector
  730. * below the diagonal containing Inf. Only BETA on the diagonal,
  731. * returned by DLARFG can contain Inf, which requires
  732. * TAU(K) to contain NaN. Therefore, this case of generating Inf
  733. * by DLARFG is covered by checking TAU(K) for NaN.
  734. *
  735. IF( DISNAN( TAU(K) ) ) THEN
  736. *
  737. DONE = .TRUE.
  738. *
  739. * Set KB, the number of factorized partial columns
  740. * that are non-zero in each step in the block,
  741. * i.e. the rank of the factor R.
  742. * Set IF, the number of processed rows in the block, which
  743. * is the same as the number of processed rows in
  744. * the original whole matrix A_orig.
  745. *
  746. KB = K - 1
  747. IF = I - 1
  748. INFO = K
  749. *
  750. * Set MAXC2NRMK and RELMAXC2NRMK to NaN.
  751. *
  752. MAXC2NRMK = TAU( K )
  753. RELMAXC2NRMK = TAU( K )
  754. *
  755. * There is no need to apply the block reflector to the
  756. * residual of the matrix A stored in A(KB+1:M,KB+1:N),
  757. * since the submatrix contains NaN and we stop
  758. * the computation.
  759. * But, we need to apply the block reflector to the residual
  760. * right hand sides stored in A(KB+1:M,N+1:N+NRHS), if the
  761. * residual right hand sides exist. This occurs
  762. * when ( NRHS != 0 AND KB <= (M-IOFFSET) ):
  763. *
  764. * A(I+1:M,N+1:N+NRHS) := A(I+1:M,N+1:N+NRHS) -
  765. * A(I+1:M,1:KB) * F(N+1:N+NRHS,1:KB)**T.
  766. *
  767. IF( NRHS.GT.0 .AND. KB.LT.(M-IOFFSET) ) THEN
  768. CALL DGEMM( 'No transpose', 'Transpose',
  769. $ M-IF, NRHS, KB, -ONE, A( IF+1, 1 ), LDA,
  770. $ F( N+1, 1 ), LDF, ONE, A( IF+1, N+1 ), LDA )
  771. END IF
  772. *
  773. * There is no need to recompute the 2-norm of the
  774. * difficult columns, since we stop the factorization.
  775. *
  776. * Array TAU(KF+1:MINMNFACT) is not set and contains
  777. * undefined elements.
  778. *
  779. * Return from the routine.
  780. *
  781. RETURN
  782. END IF
  783. *
  784. * ===============================================================
  785. *
  786. AIK = A( I, K )
  787. A( I, K ) = ONE
  788. *
  789. * ===============================================================
  790. *
  791. * Compute the current K-th column of F:
  792. * 1) F(K+1:N,K) := tau(K) * A(I:M,K+1:N)**T * A(I:M,K).
  793. *
  794. IF( K.LT.N+NRHS ) THEN
  795. CALL DGEMV( 'Transpose', M-I+1, N+NRHS-K,
  796. $ TAU( K ), A( I, K+1 ), LDA, A( I, K ), 1,
  797. $ ZERO, F( K+1, K ), 1 )
  798. END IF
  799. *
  800. * 2) Zero out elements above and on the diagonal of the
  801. * column K in matrix F, i.e elements F(1:K,K).
  802. *
  803. DO J = 1, K
  804. F( J, K ) = ZERO
  805. END DO
  806. *
  807. * 3) Incremental updating of the K-th column of F:
  808. * F(1:N,K) := F(1:N,K) - tau(K) * F(1:N,1:K-1) * A(I:M,1:K-1)**T
  809. * * A(I:M,K).
  810. *
  811. IF( K.GT.1 ) THEN
  812. CALL DGEMV( 'Transpose', M-I+1, K-1, -TAU( K ),
  813. $ A( I, 1 ), LDA, A( I, K ), 1, ZERO,
  814. $ AUXV( 1 ), 1 )
  815. *
  816. CALL DGEMV( 'No transpose', N+NRHS, K-1, ONE,
  817. $ F( 1, 1 ), LDF, AUXV( 1 ), 1, ONE,
  818. $ F( 1, K ), 1 )
  819. END IF
  820. *
  821. * ===============================================================
  822. *
  823. * Update the current I-th row of A:
  824. * A(I,K+1:N+NRHS) := A(I,K+1:N+NRHS)
  825. * - A(I,1:K)*F(K+1:N+NRHS,1:K)**T.
  826. *
  827. IF( K.LT.N+NRHS ) THEN
  828. CALL DGEMV( 'No transpose', N+NRHS-K, K, -ONE,
  829. $ F( K+1, 1 ), LDF, A( I, 1 ), LDA, ONE,
  830. $ A( I, K+1 ), LDA )
  831. END IF
  832. *
  833. A( I, K ) = AIK
  834. *
  835. * Update the partial column 2-norms for the residual matrix,
  836. * only if the residual matrix A(I+1:M,K+1:N) exists, i.e.
  837. * when K < MINMNFACT = min( M-IOFFSET, N ).
  838. *
  839. IF( K.LT.MINMNFACT ) THEN
  840. *
  841. DO J = K + 1, N
  842. IF( VN1( J ).NE.ZERO ) THEN
  843. *
  844. * NOTE: The following lines follow from the analysis in
  845. * Lapack Working Note 176.
  846. *
  847. TEMP = ABS( A( I, J ) ) / VN1( J )
  848. TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )
  849. TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2
  850. IF( TEMP2.LE.TOL3Z ) THEN
  851. *
  852. * At J-index, we have a difficult column for the
  853. * update of the 2-norm. Save the index of the previous
  854. * difficult column in IWORK(J-1).
  855. * NOTE: ILSTCC > 1, threfore we can use IWORK only
  856. * with N-1 elements, where the elements are
  857. * shifted by 1 to the left.
  858. *
  859. IWORK( J-1 ) = LSTICC
  860. *
  861. * Set the index of the last difficult column LSTICC.
  862. *
  863. LSTICC = J
  864. *
  865. ELSE
  866. VN1( J ) = VN1( J )*SQRT( TEMP )
  867. END IF
  868. END IF
  869. END DO
  870. *
  871. END IF
  872. *
  873. * End of while loop.
  874. *
  875. END DO
  876. *
  877. * Now, afler the loop:
  878. * Set KB, the number of factorized columns in the block;
  879. * Set IF, the number of processed rows in the block, which
  880. * is the same as the number of processed rows in
  881. * the original whole matrix A_orig, IF = IOFFSET + KB.
  882. *
  883. KB = K
  884. IF = I
  885. *
  886. * Apply the block reflector to the residual of the matrix A
  887. * and the residual of the right hand sides B, if the residual
  888. * matrix and and/or the residual of the right hand sides
  889. * exist, i.e. if the submatrix A(I+1:M,KB+1:N+NRHS) exists.
  890. * This occurs when KB < MINMNUPDT = min( M-IOFFSET, N+NRHS ):
  891. *
  892. * A(IF+1:M,K+1:N+NRHS) := A(IF+1:M,KB+1:N+NRHS) -
  893. * A(IF+1:M,1:KB) * F(KB+1:N+NRHS,1:KB)**T.
  894. *
  895. IF( KB.LT.MINMNUPDT ) THEN
  896. CALL DGEMM( 'No transpose', 'Transpose',
  897. $ M-IF, N+NRHS-KB, KB, -ONE, A( IF+1, 1 ), LDA,
  898. $ F( KB+1, 1 ), LDF, ONE, A( IF+1, KB+1 ), LDA )
  899. END IF
  900. *
  901. * Recompute the 2-norm of the difficult columns.
  902. * Loop over the index of the difficult columns from the largest
  903. * to the smallest index.
  904. *
  905. DO WHILE( LSTICC.GT.0 )
  906. *
  907. * LSTICC is the index of the last difficult column is greater
  908. * than 1.
  909. * ITEMP is the index of the previous difficult column.
  910. *
  911. ITEMP = IWORK( LSTICC-1 )
  912. *
  913. * Compute the 2-norm explicilty for the last difficult column and
  914. * save it in the partial and exact 2-norm vectors VN1 and VN2.
  915. *
  916. * NOTE: The computation of VN1( LSTICC ) relies on the fact that
  917. * DNRM2 does not fail on vectors with norm below the value of
  918. * SQRT(DLAMCH('S'))
  919. *
  920. VN1( LSTICC ) = DNRM2( M-IF, A( IF+1, LSTICC ), 1 )
  921. VN2( LSTICC ) = VN1( LSTICC )
  922. *
  923. * Downdate the index of the last difficult column to
  924. * the index of the previous difficult column.
  925. *
  926. LSTICC = ITEMP
  927. *
  928. END DO
  929. *
  930. RETURN
  931. *
  932. * End of DLAQP3RK
  933. *
  934. END