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.

sgeqp3rk.f 39 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083
  1. *> \brief \b SGEQP3RK computes a truncated Householder QR factorization with column pivoting of a real m-by-n matrix A by 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 SGEQP3RK + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sgeqp3rk.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sgeqp3rk.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sgeqp3rk.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE SGEQP3RK( M, N, NRHS, KMAX, ABSTOL, RELTOL, A, LDA,
  22. * $ K, MAXC2NRMK, RELMAXC2NRMK, JPIV, TAU,
  23. * $ WORK, LWORK, IWORK, INFO )
  24. * IMPLICIT NONE
  25. *
  26. * .. Scalar Arguments ..
  27. * INTEGER INFO, K, KMAX, LDA, LWORK, M, N, NRHS
  28. * REAL ABSTOL, MAXC2NRMK, RELMAXC2NRMK, RELTOL
  29. * ..
  30. * .. Array Arguments ..
  31. * INTEGER IWORK( * ), JPIV( * )
  32. * REAL A( LDA, * ), TAU( * ), WORK( * )
  33. * ..
  34. *
  35. *
  36. *> \par Purpose:
  37. * =============
  38. *>
  39. *> \verbatim
  40. *>
  41. *> SGEQP3RK performs two tasks simultaneously:
  42. *>
  43. *> Task 1: The routine computes a truncated (rank K) or full rank
  44. *> Householder QR factorization with column pivoting of a real
  45. *> M-by-N matrix A using Level 3 BLAS. K is the number of columns
  46. *> that were factorized, i.e. factorization rank of the
  47. *> factor R, K <= min(M,N).
  48. *>
  49. *> A * P(K) = Q(K) * R(K) =
  50. *>
  51. *> = Q(K) * ( R11(K) R12(K) ) = Q(K) * ( R(K)_approx )
  52. *> ( 0 R22(K) ) ( 0 R(K)_residual ),
  53. *>
  54. *> where:
  55. *>
  56. *> P(K) is an N-by-N permutation matrix;
  57. *> Q(K) is an M-by-M orthogonal matrix;
  58. *> R(K)_approx = ( R11(K), R12(K) ) is a rank K approximation of the
  59. *> full rank factor R with K-by-K upper-triangular
  60. *> R11(K) and K-by-N rectangular R12(K). The diagonal
  61. *> entries of R11(K) appear in non-increasing order
  62. *> of absolute value, and absolute values of all of
  63. *> them exceed the maximum column 2-norm of R22(K)
  64. *> up to roundoff error.
  65. *> R(K)_residual = R22(K) is the residual of a rank K approximation
  66. *> of the full rank factor R. It is a
  67. *> an (M-K)-by-(N-K) rectangular matrix;
  68. *> 0 is a an (M-K)-by-K zero matrix.
  69. *>
  70. *> Task 2: At the same time, the routine overwrites a real M-by-NRHS
  71. *> matrix B with Q(K)**T * B using Level 3 BLAS.
  72. *>
  73. *> =====================================================================
  74. *>
  75. *> The matrices A and B are stored on input in the array A as
  76. *> the left and right blocks A(1:M,1:N) and A(1:M, N+1:N+NRHS)
  77. *> respectively.
  78. *>
  79. *> N NRHS
  80. *> array_A = M [ mat_A, mat_B ]
  81. *>
  82. *> The truncation criteria (i.e. when to stop the factorization)
  83. *> can be any of the following:
  84. *>
  85. *> 1) The input parameter KMAX, the maximum number of columns
  86. *> KMAX to factorize, i.e. the factorization rank is limited
  87. *> to KMAX. If KMAX >= min(M,N), the criterion is not used.
  88. *>
  89. *> 2) The input parameter ABSTOL, the absolute tolerance for
  90. *> the maximum column 2-norm of the residual matrix R22(K). This
  91. *> means that the factorization stops if this norm is less or
  92. *> equal to ABSTOL. If ABSTOL < 0.0, the criterion is not used.
  93. *>
  94. *> 3) The input parameter RELTOL, the tolerance for the maximum
  95. *> column 2-norm matrix of the residual matrix R22(K) divided
  96. *> by the maximum column 2-norm of the original matrix A, which
  97. *> is equal to abs(R(1,1)). This means that the factorization stops
  98. *> when the ratio of the maximum column 2-norm of R22(K) to
  99. *> the maximum column 2-norm of A is less than or equal to RELTOL.
  100. *> If RELTOL < 0.0, the criterion is not used.
  101. *>
  102. *> 4) In case both stopping criteria ABSTOL or RELTOL are not used,
  103. *> and when the residual matrix R22(K) is a zero matrix in some
  104. *> factorization step K. ( This stopping criterion is implicit. )
  105. *>
  106. *> The algorithm stops when any of these conditions is first
  107. *> satisfied, otherwise the whole matrix A is factorized.
  108. *>
  109. *> To factorize the whole matrix A, use the values
  110. *> KMAX >= min(M,N), ABSTOL < 0.0 and RELTOL < 0.0.
  111. *>
  112. *> The routine returns:
  113. *> a) Q(K), R(K)_approx = ( R11(K), R12(K) ),
  114. *> R(K)_residual = R22(K), P(K), i.e. the resulting matrices
  115. *> of the factorization; P(K) is represented by JPIV,
  116. *> ( if K = min(M,N), R(K)_approx is the full factor R,
  117. *> and there is no residual matrix R(K)_residual);
  118. *> b) K, the number of columns that were factorized,
  119. *> i.e. factorization rank;
  120. *> c) MAXC2NRMK, the maximum column 2-norm of the residual
  121. *> matrix R(K)_residual = R22(K),
  122. *> ( if K = min(M,N), MAXC2NRMK = 0.0 );
  123. *> d) RELMAXC2NRMK equals MAXC2NRMK divided by MAXC2NRM, the maximum
  124. *> column 2-norm of the original matrix A, which is equal
  125. *> to abs(R(1,1)), ( if K = min(M,N), RELMAXC2NRMK = 0.0 );
  126. *> e) Q(K)**T * B, the matrix B with the orthogonal
  127. *> transformation Q(K)**T applied on the left.
  128. *>
  129. *> The N-by-N permutation matrix P(K) is stored in a compact form in
  130. *> the integer array JPIV. For 1 <= j <= N, column j
  131. *> of the matrix A was interchanged with column JPIV(j).
  132. *>
  133. *> The M-by-M orthogonal matrix Q is represented as a product
  134. *> of elementary Householder reflectors
  135. *>
  136. *> Q(K) = H(1) * H(2) * . . . * H(K),
  137. *>
  138. *> where K is the number of columns that were factorized.
  139. *>
  140. *> Each H(j) has the form
  141. *>
  142. *> H(j) = I - tau * v * v**T,
  143. *>
  144. *> where 1 <= j <= K and
  145. *> I is an M-by-M identity matrix,
  146. *> tau is a real scalar,
  147. *> v is a real vector with v(1:j-1) = 0 and v(j) = 1.
  148. *>
  149. *> v(j+1:M) is stored on exit in A(j+1:M,j) and tau in TAU(j).
  150. *>
  151. *> See the Further Details section for more information.
  152. *> \endverbatim
  153. *
  154. * Arguments:
  155. * ==========
  156. *
  157. *> \param[in] M
  158. *> \verbatim
  159. *> M is INTEGER
  160. *> The number of rows of the matrix A. M >= 0.
  161. *> \endverbatim
  162. *>
  163. *> \param[in] N
  164. *> \verbatim
  165. *> N is INTEGER
  166. *> The number of columns of the matrix A. N >= 0.
  167. *> \endverbatim
  168. *>
  169. *> \param[in] NRHS
  170. *> \verbatim
  171. *> NRHS is INTEGER
  172. *> The number of right hand sides, i.e. the number of
  173. *> columns of the matrix B. NRHS >= 0.
  174. *> \endverbatim
  175. *>
  176. *> \param[in] KMAX
  177. *> \verbatim
  178. *> KMAX is INTEGER
  179. *>
  180. *> The first factorization stopping criterion. KMAX >= 0.
  181. *>
  182. *> The maximum number of columns of the matrix A to factorize,
  183. *> i.e. the maximum factorization rank.
  184. *>
  185. *> a) If KMAX >= min(M,N), then this stopping criterion
  186. *> is not used, the routine factorizes columns
  187. *> depending on ABSTOL and RELTOL.
  188. *>
  189. *> b) If KMAX = 0, then this stopping criterion is
  190. *> satisfied on input and the routine exits immediately.
  191. *> This means that the factorization is not performed,
  192. *> the matrices A and B are not modified, and
  193. *> the matrix A is itself the residual.
  194. *> \endverbatim
  195. *>
  196. *> \param[in] ABSTOL
  197. *> \verbatim
  198. *> ABSTOL is REAL
  199. *>
  200. *> The second factorization stopping criterion, cannot be NaN.
  201. *>
  202. *> The absolute tolerance (stopping threshold) for
  203. *> maximum column 2-norm of the residual matrix R22(K).
  204. *> The algorithm converges (stops the factorization) when
  205. *> the maximum column 2-norm of the residual matrix R22(K)
  206. *> is less than or equal to ABSTOL. Let SAFMIN = SLAMCH('S').
  207. *>
  208. *> a) If ABSTOL is NaN, then no computation is performed
  209. *> and an error message ( INFO = -5 ) is issued
  210. *> by XERBLA.
  211. *>
  212. *> b) If ABSTOL < 0.0, then this stopping criterion is not
  213. *> used, the routine factorizes columns depending
  214. *> on KMAX and RELTOL.
  215. *> This includes the case ABSTOL = -Inf.
  216. *>
  217. *> c) If 0.0 <= ABSTOL < 2*SAFMIN, then ABSTOL = 2*SAFMIN
  218. *> is used. This includes the case ABSTOL = -0.0.
  219. *>
  220. *> d) If 2*SAFMIN <= ABSTOL then the input value
  221. *> of ABSTOL is used.
  222. *>
  223. *> Let MAXC2NRM be the maximum column 2-norm of the
  224. *> whole original matrix A.
  225. *> If ABSTOL chosen above is >= MAXC2NRM, then this
  226. *> stopping criterion is satisfied on input and routine exits
  227. *> immediately after MAXC2NRM is computed. The routine
  228. *> returns MAXC2NRM in MAXC2NORMK,
  229. *> and 1.0 in RELMAXC2NORMK.
  230. *> This includes the case ABSTOL = +Inf. This means that the
  231. *> factorization is not performed, the matrices A and B are not
  232. *> modified, and the matrix A is itself the residual.
  233. *> \endverbatim
  234. *>
  235. *> \param[in] RELTOL
  236. *> \verbatim
  237. *> RELTOL is REAL
  238. *>
  239. *> The third factorization stopping criterion, cannot be NaN.
  240. *>
  241. *> The tolerance (stopping threshold) for the ratio
  242. *> abs(R(K+1,K+1))/abs(R(1,1)) of the maximum column 2-norm of
  243. *> the residual matrix R22(K) to the maximum column 2-norm of
  244. *> the original matrix A. The algorithm converges (stops the
  245. *> factorization), when abs(R(K+1,K+1))/abs(R(1,1)) A is less
  246. *> than or equal to RELTOL. Let EPS = SLAMCH('E').
  247. *>
  248. *> a) If RELTOL is NaN, then no computation is performed
  249. *> and an error message ( INFO = -6 ) is issued
  250. *> by XERBLA.
  251. *>
  252. *> b) If RELTOL < 0.0, then this stopping criterion is not
  253. *> used, the routine factorizes columns depending
  254. *> on KMAX and ABSTOL.
  255. *> This includes the case RELTOL = -Inf.
  256. *>
  257. *> c) If 0.0 <= RELTOL < EPS, then RELTOL = EPS is used.
  258. *> This includes the case RELTOL = -0.0.
  259. *>
  260. *> d) If EPS <= RELTOL then the input value of RELTOL
  261. *> is used.
  262. *>
  263. *> Let MAXC2NRM be the maximum column 2-norm of the
  264. *> whole original matrix A.
  265. *> If RELTOL chosen above is >= 1.0, then this stopping
  266. *> criterion is satisfied on input and routine exits
  267. *> immediately after MAXC2NRM is computed.
  268. *> The routine returns MAXC2NRM in MAXC2NORMK,
  269. *> and 1.0 in RELMAXC2NORMK.
  270. *> This includes the case RELTOL = +Inf. This means that the
  271. *> factorization is not performed, the matrices A and B are not
  272. *> modified, and the matrix A is itself the residual.
  273. *>
  274. *> NOTE: We recommend that RELTOL satisfy
  275. *> min( max(M,N)*EPS, sqrt(EPS) ) <= RELTOL
  276. *> \endverbatim
  277. *>
  278. *> \param[in,out] A
  279. *> \verbatim
  280. *> A is REAL array, dimension (LDA,N+NRHS)
  281. *>
  282. *> On entry:
  283. *>
  284. *> a) The subarray A(1:M,1:N) contains the M-by-N matrix A.
  285. *> b) The subarray A(1:M,N+1:N+NRHS) contains the M-by-NRHS
  286. *> matrix B.
  287. *>
  288. *> N NRHS
  289. *> array_A = M [ mat_A, mat_B ]
  290. *>
  291. *> On exit:
  292. *>
  293. *> a) The subarray A(1:M,1:N) contains parts of the factors
  294. *> of the matrix A:
  295. *>
  296. *> 1) If K = 0, A(1:M,1:N) contains the original matrix A.
  297. *> 2) If K > 0, A(1:M,1:N) contains parts of the
  298. *> factors:
  299. *>
  300. *> 1. The elements below the diagonal of the subarray
  301. *> A(1:M,1:K) together with TAU(1:K) represent the
  302. *> orthogonal matrix Q(K) as a product of K Householder
  303. *> elementary reflectors.
  304. *>
  305. *> 2. The elements on and above the diagonal of
  306. *> the subarray A(1:K,1:N) contain K-by-N
  307. *> upper-trapezoidal matrix
  308. *> R(K)_approx = ( R11(K), R12(K) ).
  309. *> NOTE: If K=min(M,N), i.e. full rank factorization,
  310. *> then R_approx(K) is the full factor R which
  311. *> is upper-trapezoidal. If, in addition, M>=N,
  312. *> then R is upper-triangular.
  313. *>
  314. *> 3. The subarray A(K+1:M,K+1:N) contains (M-K)-by-(N-K)
  315. *> rectangular matrix R(K)_residual = R22(K).
  316. *>
  317. *> b) If NRHS > 0, the subarray A(1:M,N+1:N+NRHS) contains
  318. *> the M-by-NRHS product Q(K)**T * B.
  319. *> \endverbatim
  320. *>
  321. *> \param[in] LDA
  322. *> \verbatim
  323. *> LDA is INTEGER
  324. *> The leading dimension of the array A. LDA >= max(1,M).
  325. *> This is the leading dimension for both matrices, A and B.
  326. *> \endverbatim
  327. *>
  328. *> \param[out] K
  329. *> \verbatim
  330. *> K is INTEGER
  331. *> Factorization rank of the matrix A, i.e. the rank of
  332. *> the factor R, which is the same as the number of non-zero
  333. *> rows of the factor R. 0 <= K <= min(M,KMAX,N).
  334. *>
  335. *> K also represents the number of non-zero Householder
  336. *> vectors.
  337. *>
  338. *> NOTE: If K = 0, a) the arrays A and B are not modified;
  339. *> b) the array TAU(1:min(M,N)) is set to ZERO,
  340. *> if the matrix A does not contain NaN,
  341. *> otherwise the elements TAU(1:min(M,N))
  342. *> are undefined;
  343. *> c) the elements of the array JPIV are set
  344. *> as follows: for j = 1:N, JPIV(j) = j.
  345. *> \endverbatim
  346. *>
  347. *> \param[out] MAXC2NRMK
  348. *> \verbatim
  349. *> MAXC2NRMK is REAL
  350. *> The maximum column 2-norm of the residual matrix R22(K),
  351. *> when the factorization stopped at rank K. MAXC2NRMK >= 0.
  352. *>
  353. *> a) If K = 0, i.e. the factorization was not performed,
  354. *> the matrix A was not modified and is itself a residual
  355. *> matrix, then MAXC2NRMK equals the maximum column 2-norm
  356. *> of the original matrix A.
  357. *>
  358. *> b) If 0 < K < min(M,N), then MAXC2NRMK is returned.
  359. *>
  360. *> c) If K = min(M,N), i.e. the whole matrix A was
  361. *> factorized and there is no residual matrix,
  362. *> then MAXC2NRMK = 0.0.
  363. *>
  364. *> NOTE: MAXC2NRMK in the factorization step K would equal
  365. *> R(K+1,K+1) in the next factorization step K+1.
  366. *> \endverbatim
  367. *>
  368. *> \param[out] RELMAXC2NRMK
  369. *> \verbatim
  370. *> RELMAXC2NRMK is REAL
  371. *> The ratio MAXC2NRMK / MAXC2NRM of the maximum column
  372. *> 2-norm of the residual matrix R22(K) (when the factorization
  373. *> stopped at rank K) to the maximum column 2-norm of the
  374. *> whole original matrix A. RELMAXC2NRMK >= 0.
  375. *>
  376. *> a) If K = 0, i.e. the factorization was not performed,
  377. *> the matrix A was not modified and is itself a residual
  378. *> matrix, then RELMAXC2NRMK = 1.0.
  379. *>
  380. *> b) If 0 < K < min(M,N), then
  381. *> RELMAXC2NRMK = MAXC2NRMK / MAXC2NRM is returned.
  382. *>
  383. *> c) If K = min(M,N), i.e. the whole matrix A was
  384. *> factorized and there is no residual matrix,
  385. *> then RELMAXC2NRMK = 0.0.
  386. *>
  387. *> NOTE: RELMAXC2NRMK in the factorization step K would equal
  388. *> abs(R(K+1,K+1))/abs(R(1,1)) in the next factorization
  389. *> step K+1.
  390. *> \endverbatim
  391. *>
  392. *> \param[out] JPIV
  393. *> \verbatim
  394. *> JPIV is INTEGER array, dimension (N)
  395. *> Column pivot indices. For 1 <= j <= N, column j
  396. *> of the matrix A was interchanged with column JPIV(j).
  397. *>
  398. *> The elements of the array JPIV(1:N) are always set
  399. *> by the routine, for example, even when no columns
  400. *> were factorized, i.e. when K = 0, the elements are
  401. *> set as JPIV(j) = j for j = 1:N.
  402. *> \endverbatim
  403. *>
  404. *> \param[out] TAU
  405. *> \verbatim
  406. *> TAU is REAL array, dimension (min(M,N))
  407. *> The scalar factors of the elementary reflectors.
  408. *>
  409. *> If 0 < K <= min(M,N), only the elements TAU(1:K) of
  410. *> the array TAU are modified by the factorization.
  411. *> After the factorization computed, if no NaN was found
  412. *> during the factorization, the remaining elements
  413. *> TAU(K+1:min(M,N)) are set to zero, otherwise the
  414. *> elements TAU(K+1:min(M,N)) are not set and therefore
  415. *> undefined.
  416. *> ( If K = 0, all elements of TAU are set to zero, if
  417. *> the matrix A does not contain NaN. )
  418. *> \endverbatim
  419. *>
  420. *> \param[out] WORK
  421. *> \verbatim
  422. *> WORK is REAL array, dimension (MAX(1,LWORK))
  423. *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  424. *> \endverbatim
  425. *>
  426. *> \param[in] LWORK
  427. *> \verbatim
  428. *> LWORK is INTEGER
  429. *> The dimension of the array WORK.
  430. *> LWORK >= 1, if MIN(M,N) = 0, and
  431. *> LWORK >= (3*N+NRHS-1), otherwise.
  432. *> For optimal performance LWORK >= (2*N + NB*( N+NRHS+1 )),
  433. *> where NB is the optimal block size for SGEQP3RK returned
  434. *> by ILAENV. Minimal block size MINNB=2.
  435. *>
  436. *> NOTE: The decision, whether to use unblocked BLAS 2
  437. *> or blocked BLAS 3 code is based not only on the dimension
  438. *> LWORK of the availbale workspace WORK, but also also on the
  439. *> matrix A dimension N via crossover point NX returned
  440. *> by ILAENV. (For N less than NX, unblocked code should be
  441. *> used.)
  442. *>
  443. *> If LWORK = -1, then a workspace query is assumed;
  444. *> the routine only calculates the optimal size of the WORK
  445. *> array, returns this value as the first entry of the WORK
  446. *> array, and no error message related to LWORK is issued
  447. *> by XERBLA.
  448. *> \endverbatim
  449. *>
  450. *> \param[out] IWORK
  451. *> \verbatim
  452. *> IWORK is INTEGER array, dimension (N-1).
  453. *> Is a work array. ( IWORK is used to store indices
  454. *> of "bad" columns for norm downdating in the residual
  455. *> matrix in the blocked step auxiliary subroutine SLAQP3RK ).
  456. *> \endverbatim
  457. *>
  458. *> \param[out] INFO
  459. *> \verbatim
  460. *> INFO is INTEGER
  461. *> 1) INFO = 0: successful exit.
  462. *> 2) INFO < 0: if INFO = -i, the i-th argument had an
  463. *> illegal value.
  464. *> 3) If INFO = j_1, where 1 <= j_1 <= N, then NaN was
  465. *> detected and the routine stops the computation.
  466. *> The j_1-th column of the matrix A or the j_1-th
  467. *> element of array TAU contains the first occurrence
  468. *> of NaN in the factorization step K+1 ( when K columns
  469. *> have been factorized ).
  470. *>
  471. *> On exit:
  472. *> K is set to the number of
  473. *> factorized columns without
  474. *> exception.
  475. *> MAXC2NRMK is set to NaN.
  476. *> RELMAXC2NRMK is set to NaN.
  477. *> TAU(K+1:min(M,N)) is not set and contains undefined
  478. *> elements. If j_1=K+1, TAU(K+1)
  479. *> may contain NaN.
  480. *> 4) If INFO = j_2, where N+1 <= j_2 <= 2*N, then no NaN
  481. *> was detected, but +Inf (or -Inf) was detected and
  482. *> the routine continues the computation until completion.
  483. *> The (j_2-N)-th column of the matrix A contains the first
  484. *> occurrence of +Inf (or -Inf) in the factorization
  485. *> step K+1 ( when K columns have been factorized ).
  486. *> \endverbatim
  487. *
  488. * Authors:
  489. * ========
  490. *
  491. *> \author Univ. of Tennessee
  492. *> \author Univ. of California Berkeley
  493. *> \author Univ. of Colorado Denver
  494. *> \author NAG Ltd.
  495. *
  496. *> \ingroup geqp3rk
  497. *
  498. *> \par Further Details:
  499. * =====================
  500. *
  501. *> \verbatim
  502. *> SGEQP3RK is based on the same BLAS3 Householder QR factorization
  503. *> algorithm with column pivoting as in SGEQP3 routine which uses
  504. *> SLARFG routine to generate Householder reflectors
  505. *> for QR factorization.
  506. *>
  507. *> We can also write:
  508. *>
  509. *> A = A_approx(K) + A_residual(K)
  510. *>
  511. *> The low rank approximation matrix A(K)_approx from
  512. *> the truncated QR factorization of rank K of the matrix A is:
  513. *>
  514. *> A(K)_approx = Q(K) * ( R(K)_approx ) * P(K)**T
  515. *> ( 0 0 )
  516. *>
  517. *> = Q(K) * ( R11(K) R12(K) ) * P(K)**T
  518. *> ( 0 0 )
  519. *>
  520. *> The residual A_residual(K) of the matrix A is:
  521. *>
  522. *> A_residual(K) = Q(K) * ( 0 0 ) * P(K)**T =
  523. *> ( 0 R(K)_residual )
  524. *>
  525. *> = Q(K) * ( 0 0 ) * P(K)**T
  526. *> ( 0 R22(K) )
  527. *>
  528. *> The truncated (rank K) factorization guarantees that
  529. *> the maximum column 2-norm of A_residual(K) is less than
  530. *> or equal to MAXC2NRMK up to roundoff error.
  531. *>
  532. *> NOTE: An approximation of the null vectors
  533. *> of A can be easily computed from R11(K)
  534. *> and R12(K):
  535. *>
  536. *> Null( A(K) )_approx = P * ( inv(R11(K)) * R12(K) )
  537. *> ( -I )
  538. *>
  539. *> \endverbatim
  540. *
  541. *> \par References:
  542. * ================
  543. *> [1] A Level 3 BLAS QR factorization algorithm with column pivoting developed in 1996.
  544. *> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain.
  545. *> X. Sun, Computer Science Dept., Duke University, USA.
  546. *> C. H. Bischof, Math. and Comp. Sci. Div., Argonne National Lab, USA.
  547. *> A BLAS-3 version of the QR factorization with column pivoting.
  548. *> LAPACK Working Note 114
  549. *> \htmlonly
  550. *> <a href="https://www.netlib.org/lapack/lawnspdf/lawn114.pdf">https://www.netlib.org/lapack/lawnspdf/lawn114.pdf</a>
  551. *> \endhtmlonly
  552. *> and in
  553. *> SIAM J. Sci. Comput., 19(5):1486-1494, Sept. 1998.
  554. *> \htmlonly
  555. *> <a href="https://doi.org/10.1137/S1064827595296732">https://doi.org/10.1137/S1064827595296732</a>
  556. *> \endhtmlonly
  557. *>
  558. *> [2] A partial column norm updating strategy developed in 2006.
  559. *> Z. Drmac and Z. Bujanovic, Dept. of Math., University of Zagreb, Croatia.
  560. *> On the failure of rank revealing QR factorization software – a case study.
  561. *> LAPACK Working Note 176.
  562. *> \htmlonly
  563. *> <a href="http://www.netlib.org/lapack/lawnspdf/lawn176.pdf">http://www.netlib.org/lapack/lawnspdf/lawn176.pdf</a>
  564. *> \endhtmlonly
  565. *> and in
  566. *> ACM Trans. Math. Softw. 35, 2, Article 12 (July 2008), 28 pages.
  567. *> \htmlonly
  568. *> <a href="https://doi.org/10.1145/1377612.1377616">https://doi.org/10.1145/1377612.1377616</a>
  569. *> \endhtmlonly
  570. *
  571. *> \par Contributors:
  572. * ==================
  573. *>
  574. *> \verbatim
  575. *>
  576. *> November 2023, Igor Kozachenko, James Demmel,
  577. *> EECS Department,
  578. *> University of California, Berkeley, USA.
  579. *>
  580. *> \endverbatim
  581. *
  582. * =====================================================================
  583. SUBROUTINE SGEQP3RK( M, N, NRHS, KMAX, ABSTOL, RELTOL, A, LDA,
  584. $ K, MAXC2NRMK, RELMAXC2NRMK, JPIV, TAU,
  585. $ WORK, LWORK, IWORK, INFO )
  586. IMPLICIT NONE
  587. *
  588. * -- LAPACK computational routine --
  589. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  590. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  591. *
  592. * .. Scalar Arguments ..
  593. INTEGER INFO, K, KF, KMAX, LDA, LWORK, M, N, NRHS
  594. REAL ABSTOL, MAXC2NRMK, RELMAXC2NRMK, RELTOL
  595. * ..
  596. * .. Array Arguments ..
  597. INTEGER IWORK( * ), JPIV( * )
  598. REAL A( LDA, * ), TAU( * ), WORK( * )
  599. * ..
  600. *
  601. * =====================================================================
  602. *
  603. * .. Parameters ..
  604. INTEGER INB, INBMIN, IXOVER
  605. PARAMETER ( INB = 1, INBMIN = 2, IXOVER = 3 )
  606. REAL ZERO, ONE, TWO
  607. PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0, TWO = 2.0E+0 )
  608. * ..
  609. * .. Local Scalars ..
  610. LOGICAL LQUERY, DONE
  611. INTEGER IINFO, IOFFSET, IWS, J, JB, JBF, JMAXB, JMAX,
  612. $ JMAXC2NRM, KP1, LWKOPT, MINMN, N_SUB, NB,
  613. $ NBMIN, NX
  614. REAL EPS, HUGEVAL, MAXC2NRM, SAFMIN
  615. * ..
  616. * .. External Subroutines ..
  617. EXTERNAL SLAQP2RK, SLAQP3RK, XERBLA
  618. * ..
  619. * .. External Functions ..
  620. LOGICAL SISNAN
  621. INTEGER ISAMAX, ILAENV
  622. REAL SLAMCH, SNRM2, SROUNDUP_LWORK
  623. EXTERNAL SISNAN, SLAMCH, SNRM2, ISAMAX, ILAENV,
  624. $ SROUNDUP_LWORK
  625. * ..
  626. * .. Intrinsic Functions ..
  627. INTRINSIC REAL, MAX, MIN
  628. * ..
  629. * .. Executable Statements ..
  630. *
  631. * Test input arguments
  632. * ====================
  633. *
  634. INFO = 0
  635. LQUERY = ( LWORK.EQ.-1 )
  636. IF( M.LT.0 ) THEN
  637. INFO = -1
  638. ELSE IF( N.LT.0 ) THEN
  639. INFO = -2
  640. ELSE IF( NRHS.LT.0 ) THEN
  641. INFO = -3
  642. ELSE IF( KMAX.LT.0 ) THEN
  643. INFO = -4
  644. ELSE IF( SISNAN( ABSTOL ) ) THEN
  645. INFO = -5
  646. ELSE IF( SISNAN( RELTOL ) ) THEN
  647. INFO = -6
  648. ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
  649. INFO = -8
  650. END IF
  651. *
  652. * If the input parameters M, N, NRHS, KMAX, LDA are valid:
  653. * a) Test the input workspace size LWORK for the minimum
  654. * size requirement IWS.
  655. * b) Determine the optimal block size NB and optimal
  656. * workspace size LWKOPT to be returned in WORK(1)
  657. * in case of (1) LWORK < IWS, (2) LQUERY = .TRUE.,
  658. * (3) when routine exits.
  659. * Here, IWS is the miminum workspace required for unblocked
  660. * code.
  661. *
  662. IF( INFO.EQ.0 ) THEN
  663. MINMN = MIN( M, N )
  664. IF( MINMN.EQ.0 ) THEN
  665. IWS = 1
  666. LWKOPT = 1
  667. ELSE
  668. *
  669. * Minimal workspace size in case of using only unblocked
  670. * BLAS 2 code in SLAQP2RK.
  671. * 1) SGEQP3RK and SLAQP2RK: 2*N to store full and partial
  672. * column 2-norms.
  673. * 2) SLAQP2RK: N+NRHS-1 to use in WORK array that is used
  674. * in SLARF subroutine inside SLAQP2RK to apply an
  675. * elementary reflector from the left.
  676. * TOTAL_WORK_SIZE = 3*N + NRHS - 1
  677. *
  678. IWS = 3*N + NRHS - 1
  679. *
  680. * Assign to NB optimal block size.
  681. *
  682. NB = ILAENV( INB, 'SGEQP3RK', ' ', M, N, -1, -1 )
  683. *
  684. * A formula for the optimal workspace size in case of using
  685. * both unblocked BLAS 2 in SLAQP2RK and blocked BLAS 3 code
  686. * in SLAQP3RK.
  687. * 1) SGEQP3RK, SLAQP2RK, SLAQP3RK: 2*N to store full and
  688. * partial column 2-norms.
  689. * 2) SLAQP2RK: N+NRHS-1 to use in WORK array that is used
  690. * in SLARF subroutine to apply an elementary reflector
  691. * from the left.
  692. * 3) SLAQP3RK: NB*(N+NRHS) to use in the work array F that
  693. * is used to apply a block reflector from
  694. * the left.
  695. * 4) SLAQP3RK: NB to use in the auxilixary array AUX.
  696. * Sizes (2) and ((3) + (4)) should intersect, therefore
  697. * TOTAL_WORK_SIZE = 2*N + NB*( N+NRHS+1 ), given NBMIN=2.
  698. *
  699. LWKOPT = 2*N + NB*( N+NRHS+1 )
  700. END IF
  701. WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
  702. *
  703. IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THEN
  704. INFO = -15
  705. END IF
  706. END IF
  707. *
  708. * NOTE: The optimal workspace size is returned in WORK(1), if
  709. * the input parameters M, N, NRHS, KMAX, LDA are valid.
  710. *
  711. IF( INFO.NE.0 ) THEN
  712. CALL XERBLA( 'SGEQP3RK', -INFO )
  713. RETURN
  714. ELSE IF( LQUERY ) THEN
  715. RETURN
  716. END IF
  717. *
  718. * Quick return if possible for M=0 or N=0.
  719. *
  720. IF( MINMN.EQ.0 ) THEN
  721. K = 0
  722. MAXC2NRMK = ZERO
  723. RELMAXC2NRMK = ZERO
  724. WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
  725. RETURN
  726. END IF
  727. *
  728. * ==================================================================
  729. *
  730. * Initialize column pivot array JPIV.
  731. *
  732. DO J = 1, N
  733. JPIV( J ) = J
  734. END DO
  735. *
  736. * ==================================================================
  737. *
  738. * Initialize storage for partial and exact column 2-norms.
  739. * a) The elements WORK(1:N) are used to store partial column
  740. * 2-norms of the matrix A, and may decrease in each computation
  741. * step; initialize to the values of complete columns 2-norms.
  742. * b) The elements WORK(N+1:2*N) are used to store complete column
  743. * 2-norms of the matrix A, they are not changed during the
  744. * computation; initialize the values of complete columns 2-norms.
  745. *
  746. DO J = 1, N
  747. WORK( J ) = SNRM2( M, A( 1, J ), 1 )
  748. WORK( N+J ) = WORK( J )
  749. END DO
  750. *
  751. * ==================================================================
  752. *
  753. * Compute the pivot column index and the maximum column 2-norm
  754. * for the whole original matrix stored in A(1:M,1:N).
  755. *
  756. KP1 = ISAMAX( N, WORK( 1 ), 1 )
  757. MAXC2NRM = WORK( KP1 )
  758. *
  759. * ==================================================================.
  760. *
  761. IF( SISNAN( MAXC2NRM ) ) THEN
  762. *
  763. * Check if the matrix A contains NaN, set INFO parameter
  764. * to the column number where the first NaN is found and return
  765. * from the routine.
  766. *
  767. K = 0
  768. INFO = KP1
  769. *
  770. * Set MAXC2NRMK and RELMAXC2NRMK to NaN.
  771. *
  772. MAXC2NRMK = MAXC2NRM
  773. RELMAXC2NRMK = MAXC2NRM
  774. *
  775. * Array TAU is not set and contains undefined elements.
  776. *
  777. WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
  778. RETURN
  779. END IF
  780. *
  781. * ===================================================================
  782. *
  783. IF( MAXC2NRM.EQ.ZERO ) THEN
  784. *
  785. * Check is the matrix A is a zero matrix, set array TAU and
  786. * return from the routine.
  787. *
  788. K = 0
  789. MAXC2NRMK = ZERO
  790. RELMAXC2NRMK = ZERO
  791. *
  792. DO J = 1, MINMN
  793. TAU( J ) = ZERO
  794. END DO
  795. *
  796. WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
  797. RETURN
  798. *
  799. END IF
  800. *
  801. * ===================================================================
  802. *
  803. HUGEVAL = SLAMCH( 'Overflow' )
  804. *
  805. IF( MAXC2NRM.GT.HUGEVAL ) THEN
  806. *
  807. * Check if the matrix A contains +Inf or -Inf, set INFO parameter
  808. * to the column number, where the first +/-Inf is found plus N,
  809. * and continue the computation.
  810. *
  811. INFO = N + KP1
  812. *
  813. END IF
  814. *
  815. * ==================================================================
  816. *
  817. * Quick return if possible for the case when the first
  818. * stopping criterion is satisfied, i.e. KMAX = 0.
  819. *
  820. IF( KMAX.EQ.0 ) THEN
  821. K = 0
  822. MAXC2NRMK = MAXC2NRM
  823. RELMAXC2NRMK = ONE
  824. DO J = 1, MINMN
  825. TAU( J ) = ZERO
  826. END DO
  827. WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
  828. RETURN
  829. END IF
  830. *
  831. * ==================================================================
  832. *
  833. EPS = SLAMCH('Epsilon')
  834. *
  835. * Adjust ABSTOL
  836. *
  837. IF( ABSTOL.GE.ZERO ) THEN
  838. SAFMIN = SLAMCH('Safe minimum')
  839. ABSTOL = MAX( ABSTOL, TWO*SAFMIN )
  840. END IF
  841. *
  842. * Adjust RELTOL
  843. *
  844. IF( RELTOL.GE.ZERO ) THEN
  845. RELTOL = MAX( RELTOL, EPS )
  846. END IF
  847. *
  848. * ===================================================================
  849. *
  850. * JMAX is the maximum index of the column to be factorized,
  851. * which is also limited by the first stopping criterion KMAX.
  852. *
  853. JMAX = MIN( KMAX, MINMN )
  854. *
  855. * ===================================================================
  856. *
  857. * Quick return if possible for the case when the second or third
  858. * stopping criterion for the whole original matrix is satified,
  859. * i.e. MAXC2NRM <= ABSTOL or RELMAXC2NRM <= RELTOL
  860. * (which is ONE <= RELTOL).
  861. *
  862. IF( MAXC2NRM.LE.ABSTOL .OR. ONE.LE.RELTOL ) THEN
  863. *
  864. K = 0
  865. MAXC2NRMK = MAXC2NRM
  866. RELMAXC2NRMK = ONE
  867. *
  868. DO J = 1, MINMN
  869. TAU( J ) = ZERO
  870. END DO
  871. *
  872. WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
  873. RETURN
  874. END IF
  875. *
  876. * ==================================================================
  877. * Factorize columns
  878. * ==================================================================
  879. *
  880. * Determine the block size.
  881. *
  882. NBMIN = 2
  883. NX = 0
  884. *
  885. IF( ( NB.GT.1 ) .AND. ( NB.LT.MINMN ) ) THEN
  886. *
  887. * Determine when to cross over from blocked to unblocked code.
  888. * (for N less than NX, unblocked code should be used).
  889. *
  890. NX = MAX( 0, ILAENV( IXOVER, 'SGEQP3RK', ' ', M, N, -1, -1 ))
  891. *
  892. IF( NX.LT.MINMN ) THEN
  893. *
  894. * Determine if workspace is large enough for blocked code.
  895. *
  896. IF( LWORK.LT.LWKOPT ) THEN
  897. *
  898. * Not enough workspace to use optimal block size that
  899. * is currently stored in NB.
  900. * Reduce NB and determine the minimum value of NB.
  901. *
  902. NB = ( LWORK-2*N ) / ( N+1 )
  903. NBMIN = MAX( 2, ILAENV( INBMIN, 'SGEQP3RK', ' ', M, N,
  904. $ -1, -1 ) )
  905. *
  906. END IF
  907. END IF
  908. END IF
  909. *
  910. * ==================================================================
  911. *
  912. * DONE is the boolean flag to rerpresent the case when the
  913. * factorization completed in the block factorization routine,
  914. * before the end of the block.
  915. *
  916. DONE = .FALSE.
  917. *
  918. * J is the column index.
  919. *
  920. J = 1
  921. *
  922. * (1) Use blocked code initially.
  923. *
  924. * JMAXB is the maximum column index of the block, when the
  925. * blocked code is used, is also limited by the first stopping
  926. * criterion KMAX.
  927. *
  928. JMAXB = MIN( KMAX, MINMN - NX )
  929. *
  930. IF( NB.GE.NBMIN .AND. NB.LT.JMAX .AND. JMAXB.GT.0 ) THEN
  931. *
  932. * Loop over the column blocks of the matrix A(1:M,1:JMAXB). Here:
  933. * J is the column index of a column block;
  934. * JB is the column block size to pass to block factorization
  935. * routine in a loop step;
  936. * JBF is the number of columns that were actually factorized
  937. * that was returned by the block factorization routine
  938. * in a loop step, JBF <= JB;
  939. * N_SUB is the number of columns in the submatrix;
  940. * IOFFSET is the number of rows that should not be factorized.
  941. *
  942. DO WHILE( J.LE.JMAXB )
  943. *
  944. JB = MIN( NB, JMAXB-J+1 )
  945. N_SUB = N-J+1
  946. IOFFSET = J-1
  947. *
  948. * Factorize JB columns among the columns A(J:N).
  949. *
  950. CALL SLAQP3RK( M, N_SUB, NRHS, IOFFSET, JB, ABSTOL,
  951. $ RELTOL, KP1, MAXC2NRM, A( 1, J ), LDA,
  952. $ DONE, JBF, MAXC2NRMK, RELMAXC2NRMK,
  953. $ JPIV( J ), TAU( J ),
  954. $ WORK( J ), WORK( N+J ),
  955. $ WORK( 2*N+1 ), WORK( 2*N+JB+1 ),
  956. $ N+NRHS-J+1, IWORK, IINFO )
  957. *
  958. * Set INFO on the first occurence of Inf.
  959. *
  960. IF( IINFO.GT.N_SUB .AND. INFO.EQ.0 ) THEN
  961. INFO = 2*IOFFSET + IINFO
  962. END IF
  963. *
  964. IF( DONE ) THEN
  965. *
  966. * Either the submatrix is zero before the end of the
  967. * column block, or ABSTOL or RELTOL criterion is
  968. * satisfied before the end of the column block, we can
  969. * return from the routine. Perform the following before
  970. * returning:
  971. * a) Set the number of factorized columns K,
  972. * K = IOFFSET + JBF from the last call of blocked
  973. * routine.
  974. * NOTE: 1) MAXC2NRMK and RELMAXC2NRMK are returned
  975. * by the block factorization routine;
  976. * 2) The remaining TAUs are set to ZERO by the
  977. * block factorization routine.
  978. *
  979. K = IOFFSET + JBF
  980. *
  981. * Set INFO on the first occurrence of NaN, NaN takes
  982. * prcedence over Inf.
  983. *
  984. IF( IINFO.LE.N_SUB .AND. IINFO.GT.0 ) THEN
  985. INFO = IOFFSET + IINFO
  986. END IF
  987. *
  988. * Return from the routine.
  989. *
  990. WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
  991. *
  992. RETURN
  993. *
  994. END IF
  995. *
  996. J = J + JBF
  997. *
  998. END DO
  999. *
  1000. END IF
  1001. *
  1002. * Use unblocked code to factor the last or only block.
  1003. * J = JMAX+1 means we factorized the maximum possible number of
  1004. * columns, that is in ELSE clause we need to compute
  1005. * the MAXC2NORM and RELMAXC2NORM to return after we processed
  1006. * the blocks.
  1007. *
  1008. IF( J.LE.JMAX ) THEN
  1009. *
  1010. * N_SUB is the number of columns in the submatrix;
  1011. * IOFFSET is the number of rows that should not be factorized.
  1012. *
  1013. N_SUB = N-J+1
  1014. IOFFSET = J-1
  1015. *
  1016. CALL SLAQP2RK( M, N_SUB, NRHS, IOFFSET, JMAX-J+1,
  1017. $ ABSTOL, RELTOL, KP1, MAXC2NRM, A( 1, J ), LDA,
  1018. $ KF, MAXC2NRMK, RELMAXC2NRMK, JPIV( J ),
  1019. $ TAU( J ), WORK( J ), WORK( N+J ),
  1020. $ WORK( 2*N+1 ), IINFO )
  1021. *
  1022. * ABSTOL or RELTOL criterion is satisfied when the number of
  1023. * the factorized columns KF is smaller then the number
  1024. * of columns JMAX-J+1 supplied to be factorized by the
  1025. * unblocked routine, we can return from
  1026. * the routine. Perform the following before returning:
  1027. * a) Set the number of factorized columns K,
  1028. * b) MAXC2NRMK and RELMAXC2NRMK are returned by the
  1029. * unblocked factorization routine above.
  1030. *
  1031. K = J - 1 + KF
  1032. *
  1033. * Set INFO on the first exception occurence.
  1034. *
  1035. * Set INFO on the first exception occurence of Inf or NaN,
  1036. * (NaN takes precedence over Inf).
  1037. *
  1038. IF( IINFO.GT.N_SUB .AND. INFO.EQ.0 ) THEN
  1039. INFO = 2*IOFFSET + IINFO
  1040. ELSE IF( IINFO.LE.N_SUB .AND. IINFO.GT.0 ) THEN
  1041. INFO = IOFFSET + IINFO
  1042. END IF
  1043. *
  1044. ELSE
  1045. *
  1046. * Compute the return values for blocked code.
  1047. *
  1048. * Set the number of factorized columns if the unblocked routine
  1049. * was not called.
  1050. *
  1051. K = JMAX
  1052. *
  1053. * If there exits a residual matrix after the blocked code:
  1054. * 1) compute the values of MAXC2NRMK, RELMAXC2NRMK of the
  1055. * residual matrix, otherwise set them to ZERO;
  1056. * 2) Set TAU(K+1:MINMN) to ZERO.
  1057. *
  1058. IF( K.LT.MINMN ) THEN
  1059. JMAXC2NRM = K + ISAMAX( N-K, WORK( K+1 ), 1 )
  1060. MAXC2NRMK = WORK( JMAXC2NRM )
  1061. IF( K.EQ.0 ) THEN
  1062. RELMAXC2NRMK = ONE
  1063. ELSE
  1064. RELMAXC2NRMK = MAXC2NRMK / MAXC2NRM
  1065. END IF
  1066. *
  1067. DO J = K + 1, MINMN
  1068. TAU( J ) = ZERO
  1069. END DO
  1070. *
  1071. END IF
  1072. *
  1073. * END IF( J.LE.JMAX ) THEN
  1074. *
  1075. END IF
  1076. *
  1077. WORK( 1 ) = SROUNDUP_LWORK( LWKOPT )
  1078. *
  1079. RETURN
  1080. *
  1081. * End of SGEQP3RK
  1082. *
  1083. END