ScaLAPACK 2.1  2.1
ScaLAPACK: Scalable Linear Algebra PACKage
pcgeqpf.f
Go to the documentation of this file.
1  SUBROUTINE pcgeqpf( M, N, A, IA, JA, DESCA, IPIV, TAU, WORK,
2  $ LWORK, RWORK, LRWORK, INFO )
3 *
4 * -- ScaLAPACK routine (version 2.1) --
5 * University of Tennessee, Knoxville, Oak Ridge National Laboratory,
6 * and University of California, Berkeley.
7 * November 20, 2019
8 *
9 * .. Scalar Arguments ..
10  INTEGER IA, JA, INFO, LRWORK, LWORK, M, N
11 * ..
12 * .. Array Arguments ..
13  INTEGER DESCA( * ), IPIV( * )
14  REAL RWORK( * )
15  COMPLEX A( * ), TAU( * ), WORK( * )
16 * ..
17 *
18 * Purpose
19 * =======
20 *
21 * PCGEQPF computes a QR factorization with column pivoting of a
22 * M-by-N distributed matrix sub( A ) = A(IA:IA+M-1,JA:JA+N-1):
23 *
24 * sub( A ) * P = Q * R.
25 *
26 * Notes
27 * =====
28 *
29 * Each global data object is described by an associated description
30 * vector. This vector stores the information required to establish
31 * the mapping between an object element and its corresponding process
32 * and memory location.
33 *
34 * Let A be a generic term for any 2D block cyclicly distributed array.
35 * Such a global array has an associated description vector DESCA.
36 * In the following comments, the character _ should be read as
37 * "of the global array".
38 *
39 * NOTATION STORED IN EXPLANATION
40 * --------------- -------------- --------------------------------------
41 * DTYPE_A(global) DESCA( DTYPE_ )The descriptor type. In this case,
42 * DTYPE_A = 1.
43 * CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating
44 * the BLACS process grid A is distribu-
45 * ted over. The context itself is glo-
46 * bal, but the handle (the integer
47 * value) may vary.
48 * M_A (global) DESCA( M_ ) The number of rows in the global
49 * array A.
50 * N_A (global) DESCA( N_ ) The number of columns in the global
51 * array A.
52 * MB_A (global) DESCA( MB_ ) The blocking factor used to distribute
53 * the rows of the array.
54 * NB_A (global) DESCA( NB_ ) The blocking factor used to distribute
55 * the columns of the array.
56 * RSRC_A (global) DESCA( RSRC_ ) The process row over which the first
57 * row of the array A is distributed.
58 * CSRC_A (global) DESCA( CSRC_ ) The process column over which the
59 * first column of the array A is
60 * distributed.
61 * LLD_A (local) DESCA( LLD_ ) The leading dimension of the local
62 * array. LLD_A >= MAX(1,LOCr(M_A)).
63 *
64 * Let K be the number of rows or columns of a distributed matrix,
65 * and assume that its process grid has dimension p x q.
66 * LOCr( K ) denotes the number of elements of K that a process
67 * would receive if K were distributed over the p processes of its
68 * process column.
69 * Similarly, LOCc( K ) denotes the number of elements of K that a
70 * process would receive if K were distributed over the q processes of
71 * its process row.
72 * The values of LOCr() and LOCc() may be determined via a call to the
73 * ScaLAPACK tool function, NUMROC:
74 * LOCr( M ) = NUMROC( M, MB_A, MYROW, RSRC_A, NPROW ),
75 * LOCc( N ) = NUMROC( N, NB_A, MYCOL, CSRC_A, NPCOL ).
76 * An upper bound for these quantities may be computed by:
77 * LOCr( M ) <= ceil( ceil(M/MB_A)/NPROW )*MB_A
78 * LOCc( N ) <= ceil( ceil(N/NB_A)/NPCOL )*NB_A
79 *
80 * Arguments
81 * =========
82 *
83 * M (global input) INTEGER
84 * The number of rows to be operated on, i.e. the number of rows
85 * of the distributed submatrix sub( A ). M >= 0.
86 *
87 * N (global input) INTEGER
88 * The number of columns to be operated on, i.e. the number of
89 * columns of the distributed submatrix sub( A ). N >= 0.
90 *
91 * A (local input/local output) COMPLEX pointer into the
92 * local memory to an array of dimension (LLD_A, LOCc(JA+N-1)).
93 * On entry, the local pieces of the M-by-N distributed matrix
94 * sub( A ) which is to be factored. On exit, the elements on
95 * and above the diagonal of sub( A ) contain the min(M,N) by N
96 * upper trapezoidal matrix R (R is upper triangular if M >= N);
97 * the elements below the diagonal, with the array TAU, repre-
98 * sent the unitary matrix Q as a product of elementary
99 * reflectors (see Further Details).
100 *
101 * IA (global input) INTEGER
102 * The row index in the global array A indicating the first
103 * row of sub( A ).
104 *
105 * JA (global input) INTEGER
106 * The column index in the global array A indicating the
107 * first column of sub( A ).
108 *
109 * DESCA (global and local input) INTEGER array of dimension DLEN_.
110 * The array descriptor for the distributed matrix A.
111 *
112 * IPIV (local output) INTEGER array, dimension LOCc(JA+N-1).
113 * On exit, if IPIV(I) = K, the local i-th column of sub( A )*P
114 * was the global K-th column of sub( A ). IPIV is tied to the
115 * distributed matrix A.
116 *
117 * TAU (local output) COMPLEX, array, dimension
118 * LOCc(JA+MIN(M,N)-1). This array contains the scalar factors
119 * TAU of the elementary reflectors. TAU is tied to the
120 * distributed matrix A.
121 *
122 * WORK (local workspace/local output) COMPLEX array,
123 * dimension (LWORK)
124 * On exit, WORK(1) returns the minimal and optimal LWORK.
125 *
126 * LWORK (local or global input) INTEGER
127 * The dimension of the array WORK.
128 * LWORK is local input and must be at least
129 * LWORK >= MAX(3,Mp0 + Nq0).
130 *
131 * If LWORK = -1, then LWORK is global input and a workspace
132 * query is assumed; the routine only calculates the minimum
133 * and optimal size for all work arrays. Each of these
134 * values is returned in the first entry of the corresponding
135 * work array, and no error message is issued by PXERBLA.
136 *
137 * RWORK (local workspace/local output) REAL array,
138 * dimension (LRWORK)
139 * On exit, RWORK(1) returns the minimal and optimal LRWORK.
140 *
141 * LRWORK (local or global input) INTEGER
142 * The dimension of the array RWORK.
143 * LRWORK is local input and must be at least
144 * LRWORK >= LOCc(JA+N-1)+Nq0.
145 *
146 * IROFF = MOD( IA-1, MB_A ), ICOFF = MOD( JA-1, NB_A ),
147 * IAROW = INDXG2P( IA, MB_A, MYROW, RSRC_A, NPROW ),
148 * IACOL = INDXG2P( JA, NB_A, MYCOL, CSRC_A, NPCOL ),
149 * Mp0 = NUMROC( M+IROFF, MB_A, MYROW, IAROW, NPROW ),
150 * Nq0 = NUMROC( N+ICOFF, NB_A, MYCOL, IACOL, NPCOL ),
151 * LOCc(JA+N-1) = NUMROC( JA+N-1, NB_A, MYCOL, CSRC_A, NPCOL )
152 *
153 * and NUMROC, INDXG2P are ScaLAPACK tool functions;
154 * MYROW, MYCOL, NPROW and NPCOL can be determined by calling
155 * the subroutine BLACS_GRIDINFO.
156 *
157 * If LRWORK = -1, then LRWORK is global input and a workspace
158 * query is assumed; the routine only calculates the minimum
159 * and optimal size for all work arrays. Each of these
160 * values is returned in the first entry of the corresponding
161 * work array, and no error message is issued by PXERBLA.
162 *
163 *
164 * INFO (global output) INTEGER
165 * = 0: successful exit
166 * < 0: If the i-th argument is an array and the j-entry had
167 * an illegal value, then INFO = -(i*100+j), if the i-th
168 * argument is a scalar and had an illegal value, then
169 * INFO = -i.
170 *
171 * Further Details
172 * ===============
173 *
174 * The matrix Q is represented as a product of elementary reflectors
175 *
176 * Q = H(1) H(2) . . . H(n)
177 *
178 * Each H(i) has the form
179 *
180 * H = I - tau * v * v'
181 *
182 * where tau is a complex scalar, and v is a complex vector with
183 * v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
184 * A(ia+i-1:ia+m-1,ja+i-1).
185 *
186 * The matrix P is represented in jpvt as follows: If
187 * jpvt(j) = i
188 * then the jth column of P is the ith canonical unit vector.
189 *
190 * References
191 * ==========
192 *
193 * For modifications introduced in Scalapack 2.1
194 * LAWN 295
195 * New robust ScaLAPACK routine for computing the QR factorization with column pivoting
196 * Zvonimir Bujanovic, Zlatko Drmac
197 * http://www.netlib.org/lapack/lawnspdf/lawn295.pdf
198 *
199 * =====================================================================
200 *
201 * .. Parameters ..
202  INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
203  $ lld_, mb_, m_, nb_, n_, rsrc_
204  parameter( block_cyclic_2d = 1, dlen_ = 9, dtype_ = 1,
205  $ ctxt_ = 2, m_ = 3, n_ = 4, mb_ = 5, nb_ = 6,
206  $ rsrc_ = 7, csrc_ = 8, lld_ = 9 )
207  REAL ONE, ZERO
208  parameter( one = 1.0e+0, zero = 0.0e+0 )
209 * ..
210 * .. Local Scalars ..
211  LOGICAL LQUERY
212  INTEGER I, IACOL, IAROW, ICOFF, ICTXT, ICURROW,
213  $ icurcol, ii, iia, ioffa, ipcol, iroff, itemp,
214  $ j, jb, jj, jja, jjpvt, jn, kb, k, kk, kstart,
215  $ kstep, lda, ll, lrwmin, lwmin, mn, mp, mycol,
216  $ myrow, npcol, nprow, nq, nq0, pvt
217  REAL TEMP, TEMP2, TOL3Z
218  COMPLEX AJJ, ALPHA
219 * ..
220 * .. Local Arrays ..
221  INTEGER DESCN( DLEN_ ), IDUM1( 2 ), IDUM2( 2 )
222 * ..
223 * .. External Subroutines ..
224  EXTERNAL blacs_gridinfo, ccopy, cgebr2d, cgebs2d,
225  $ cgerv2d, cgesd2d, chk1mat, clarfg,
226  $ cswap, descset, igerv2d, igesd2d, infog1l,
228  $ pclarfg, psamax, pscnrm2, pxerbla
229 * ..
230 * .. External Functions ..
231  INTEGER ICEIL, INDXG2P, NUMROC
232  EXTERNAL iceil, indxg2p, numroc
233  REAL SLAMCH
234  EXTERNAL slamch
235 * ..
236 * .. Intrinsic Functions ..
237  INTRINSIC abs, cmplx, conjg, ifix, max, min, mod, sqrt
238 * ..
239 * .. Executable Statements ..
240 *
241 * Get grid parameters
242 *
243  ictxt = desca( ctxt_ )
244  CALL blacs_gridinfo( ictxt, nprow, npcol, myrow, mycol )
245 *
246 * Test the input parameters
247 *
248  info = 0
249  IF( nprow.EQ.-1 ) THEN
250  info = -(600+ctxt_)
251  ELSE
252  CALL chk1mat( m, 1, n, 2, ia, ja, desca, 6, info )
253  IF( info.EQ.0 ) THEN
254  iroff = mod( ia-1, desca( mb_ ) )
255  icoff = mod( ja-1, desca( nb_ ) )
256  iarow = indxg2p( ia, desca( mb_ ), myrow, desca( rsrc_ ),
257  $ nprow )
258  iacol = indxg2p( ja, desca( nb_ ), mycol, desca( csrc_ ),
259  $ npcol )
260  mp = numroc( m+iroff, desca( mb_ ), myrow, iarow, nprow )
261  nq = numroc( n+icoff, desca( nb_ ), mycol, iacol, npcol )
262  nq0 = numroc( ja+n-1, desca( nb_ ), mycol, desca( csrc_ ),
263  $ npcol )
264  lwmin = max( 3, mp + nq )
265  lrwmin = nq0 + nq
266 *
267  work( 1 ) = cmplx( real( lwmin ) )
268  rwork( 1 ) = real( lrwmin )
269  lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 )
270  IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
271  info = -10
272  ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
273  info = -12
274  END IF
275  END IF
276  IF( lwork.EQ.-1 ) THEN
277  idum1( 1 ) = -1
278  ELSE
279  idum1( 1 ) = 1
280  END IF
281  idum2( 1 ) = 10
282  IF( lrwork.EQ.-1 ) THEN
283  idum1( 2 ) = -1
284  ELSE
285  idum1( 2 ) = 1
286  END IF
287  idum2( 2 ) = 12
288  CALL pchk1mat( m, 1, n, 2, ia, ja, desca, 6, 2, idum1, idum2,
289  $ info )
290  END IF
291 *
292  IF( info.NE.0 ) THEN
293  CALL pxerbla( ictxt, 'PCGEQPF', -info )
294  RETURN
295  ELSE IF( lquery ) THEN
296  RETURN
297  END IF
298 *
299 * Quick return if possible
300 *
301  IF( m.EQ.0 .OR. n.EQ.0 )
302  $ RETURN
303 *
304  CALL infog2l( ia, ja, desca, nprow, npcol, myrow, mycol, iia, jja,
305  $ iarow, iacol )
306  IF( myrow.EQ.iarow )
307  $ mp = mp - iroff
308  IF( mycol.EQ.iacol )
309  $ nq = nq - icoff
310  mn = min( m, n )
311  tol3z = sqrt( slamch('Epsilon') )
312 *
313 * Initialize the array of pivots
314 *
315  lda = desca( lld_ )
316  jn = min( iceil( ja, desca( nb_ ) ) * desca( nb_ ), ja+n-1 )
317  kstep = npcol * desca( nb_ )
318 *
319  IF( mycol.EQ.iacol ) THEN
320 *
321 * Handle first block separately
322 *
323  jb = jn - ja + 1
324  DO 10 ll = jja, jja+jb-1
325  ipiv( ll ) = ja + ll - jja
326  10 CONTINUE
327  kstart = jn + kstep - desca( nb_ )
328 *
329 * Loop over remaining block of columns
330 *
331  DO 30 kk = jja+jb, jja+nq-1, desca( nb_ )
332  kb = min( jja+nq-kk, desca( nb_ ) )
333  DO 20 ll = kk, kk+kb-1
334  ipiv( ll ) = kstart+ll-kk+1
335  20 CONTINUE
336  kstart = kstart + kstep
337  30 CONTINUE
338  ELSE
339  kstart = jn + ( mod( mycol-iacol+npcol, npcol )-1 )*
340  $ desca( nb_ )
341  DO 50 kk = jja, jja+nq-1, desca( nb_ )
342  kb = min( jja+nq-kk, desca( nb_ ) )
343  DO 40 ll = kk, kk+kb-1
344  ipiv( ll ) = kstart+ll-kk+1
345  40 CONTINUE
346  kstart = kstart + kstep
347  50 CONTINUE
348  END IF
349 *
350 * Initialize partial column norms, handle first block separately
351 *
352  CALL descset( descn, 1, desca( n_ ), 1, desca( nb_ ), myrow,
353  $ desca( csrc_ ), ictxt, 1 )
354 *
355  jj = jja
356  IF( mycol.EQ.iacol ) THEN
357  DO 60 kk = 0, jb-1
358  CALL pscnrm2( m, rwork( jj+kk ), a, ia, ja+kk, desca, 1 )
359  rwork( nq+jj+kk ) = rwork( jj+kk )
360  60 CONTINUE
361  jj = jj + jb
362  END IF
363  icurcol = mod( iacol+1, npcol )
364 *
365 * Loop over the remaining blocks of columns
366 *
367  DO 80 j = jn+1, ja+n-1, desca( nb_ )
368  jb = min( ja+n-j, desca( nb_ ) )
369 *
370  IF( mycol.EQ.icurcol ) THEN
371  DO 70 kk = 0, jb-1
372  CALL pscnrm2( m, rwork( jj+kk ), a, ia, j+kk, desca, 1 )
373  rwork( nq+jj+kk ) = rwork( jj+kk )
374  70 CONTINUE
375  jj = jj + jb
376  END IF
377  icurcol = mod( icurcol+1, npcol )
378  80 CONTINUE
379 *
380 * Compute factorization
381 *
382  DO 120 j = ja, ja+mn-1
383  i = ia + j - ja
384 *
385  CALL infog1l( j, desca( nb_ ), npcol, mycol, desca( csrc_ ),
386  $ jj, icurcol )
387  k = ja + n - j
388  IF( k.GT.1 ) THEN
389  CALL psamax( k, temp, pvt, rwork, 1, j, descn,
390  $ descn( m_ ) )
391  ELSE
392  pvt = j
393  END IF
394  IF( j.NE.pvt ) THEN
395  CALL infog1l( pvt, desca( nb_ ), npcol, mycol,
396  $ desca( csrc_ ), jjpvt, ipcol )
397  IF( icurcol.EQ.ipcol ) THEN
398  IF( mycol.EQ.icurcol ) THEN
399  CALL cswap( mp, a( iia+(jj-1)*lda ), 1,
400  $ a( iia+(jjpvt-1)*lda ), 1 )
401  itemp = ipiv( jjpvt )
402  ipiv( jjpvt ) = ipiv( jj )
403  ipiv( jj ) = itemp
404  rwork( jjpvt ) = rwork( jj )
405  rwork( nq+jjpvt ) = rwork( nq+jj )
406  END IF
407  ELSE
408  IF( mycol.EQ.icurcol ) THEN
409 *
410  CALL cgesd2d( ictxt, mp, 1, a( iia+(jj-1)*lda ), lda,
411  $ myrow, ipcol )
412  work( 1 ) = cmplx( real( ipiv( jj ) ) )
413  work( 2 ) = cmplx( rwork( jj ) )
414  work( 3 ) = cmplx( rwork( jj + nq ) )
415  CALL cgesd2d( ictxt, 3, 1, work, 3, myrow, ipcol )
416 *
417  CALL cgerv2d( ictxt, mp, 1, a( iia+(jj-1)*lda ), lda,
418  $ myrow, ipcol )
419  CALL igerv2d( ictxt, 1, 1, ipiv( jj ), 1, myrow,
420  $ ipcol )
421 *
422  ELSE IF( mycol.EQ.ipcol ) THEN
423 *
424  CALL cgesd2d( ictxt, mp, 1, a( iia+(jjpvt-1)*lda ),
425  $ lda, myrow, icurcol )
426  CALL igesd2d( ictxt, 1, 1, ipiv( jjpvt ), 1, myrow,
427  $ icurcol )
428 *
429  CALL cgerv2d( ictxt, mp, 1, a( iia+(jjpvt-1)*lda ),
430  $ lda, myrow, icurcol )
431  CALL cgerv2d( ictxt, 3, 1, work, 3, myrow, icurcol )
432  ipiv( jjpvt ) = ifix( real( work( 1 ) ) )
433  rwork( jjpvt ) = real( work( 2 ) )
434  rwork( jjpvt+nq ) = real( work( 3 ) )
435 *
436  END IF
437 *
438  END IF
439 *
440  END IF
441 *
442 * Generate elementary reflector H(i)
443 *
444  CALL infog1l( i, desca( mb_ ), nprow, myrow, desca( rsrc_ ),
445  $ ii, icurrow )
446  IF( desca( m_ ).EQ.1 ) THEN
447  IF( myrow.EQ.icurrow ) THEN
448  IF( mycol.EQ.icurcol ) THEN
449  ioffa = ii+(jj-1)*desca( lld_ )
450  ajj = a( ioffa )
451  CALL clarfg( 1, ajj, a( ioffa ), 1, tau( jj ) )
452  IF( n.GT.1 ) THEN
453  alpha = cmplx( one ) - conjg( tau( jj ) )
454  CALL cgebs2d( ictxt, 'Rowwise', ' ', 1, 1, alpha,
455  $ 1 )
456  CALL cscal( nq-jj, alpha, a( ioffa+desca( lld_ ) ),
457  $ desca( lld_ ) )
458  END IF
459  CALL cgebs2d( ictxt, 'Columnwise', ' ', 1, 1,
460  $ tau( jj ), 1 )
461  a( ioffa ) = ajj
462  ELSE
463  IF( n.GT.1 ) THEN
464  CALL cgebr2d( ictxt, 'Rowwise', ' ', 1, 1, alpha,
465  $ 1, icurrow, icurcol )
466  CALL cscal( nq-jj+1, alpha, a( i ), desca( lld_ ) )
467  END IF
468  END IF
469  ELSE IF( mycol.EQ.icurcol ) THEN
470  CALL cgebr2d( ictxt, 'Columnwise', ' ', 1, 1, tau( jj ),
471  $ 1, icurrow, icurcol )
472  END IF
473 *
474  ELSE
475 *
476  CALL pclarfg( m-j+ja, ajj, i, j, a, min( i+1, ia+m-1 ), j,
477  $ desca, 1, tau )
478  IF( j.LT.ja+n-1 ) THEN
479 *
480 * Apply H(i) to A(ia+j-ja:ia+m-1,j+1:ja+n-1) from the left
481 *
482  CALL pcelset( a, i, j, desca, cmplx( one ) )
483  CALL pclarfc( 'Left', m-j+ja, ja+n-1-j, a, i, j, desca,
484  $ 1, tau, a, i, j+1, desca, work )
485  END IF
486  CALL pcelset( a, i, j, desca, ajj )
487 *
488  END IF
489 *
490 * Update partial columns norms
491 *
492  IF( mycol.EQ.icurcol )
493  $ jj = jj + 1
494  IF( mod( j, desca( nb_ ) ).EQ.0 )
495  $ icurcol = mod( icurcol+1, npcol )
496  IF( (jja+nq-jj).GT.0 ) THEN
497  IF( myrow.EQ.icurrow ) THEN
498  CALL cgebs2d( ictxt, 'Columnwise', ' ', 1, jja+nq-jj,
499  $ a( ii+( min( jja+nq-1, jj )-1 )*lda ),
500  $ lda )
501  CALL ccopy( jja+nq-jj, a( ii+( min( jja+nq-1, jj )
502  $ -1)*lda ), lda, work( min( jja+nq-1, jj ) ),
503  $ 1 )
504  ELSE
505  CALL cgebr2d( ictxt, 'Columnwise', ' ', jja+nq-jj, 1,
506  $ work( min( jja+nq-1, jj ) ), max( 1, nq ),
507  $ icurrow, mycol )
508  END IF
509  END IF
510 *
511  jn = min( iceil( j+1, desca( nb_ ) ) * desca( nb_ ),
512  $ ja + n - 1 )
513  IF( mycol.EQ.icurcol ) THEN
514  DO 90 ll = jj, jj + jn - j - 1
515  IF( rwork( ll ).NE.zero ) THEN
516  temp = abs( work( ll ) ) / rwork( ll )
517  temp = max( zero, ( one+temp )*( one-temp ) )
518  temp2 = temp * ( rwork( ll ) / rwork( nq+ll ) )**2
519  IF( temp2.LE.tol3z ) THEN
520  IF( ia+m-1.GT.i ) THEN
521  CALL pscnrm2( ia+m-i-1, rwork( ll ), a,
522  $ i+1, j+ll-jj+1, desca, 1 )
523  rwork( nq+ll ) = rwork( ll )
524  ELSE
525  rwork( ll ) = zero
526  rwork( nq+ll ) = zero
527  END IF
528  ELSE
529  rwork( ll ) = rwork( ll ) * sqrt( temp )
530  END IF
531  END IF
532  90 CONTINUE
533  jj = jj + jn - j
534  END IF
535  icurcol = mod( icurcol+1, npcol )
536 *
537  DO 110 k = jn+1, ja+n-1, desca( nb_ )
538  kb = min( ja+n-k, desca( nb_ ) )
539 *
540  IF( mycol.EQ.icurcol ) THEN
541  DO 100 ll = jj, jj+kb-1
542  IF( rwork(ll).NE.zero ) THEN
543  temp = abs( work( ll ) ) / rwork( ll )
544  temp = max( zero, ( one+temp )*( one-temp ) )
545  temp2 = temp * ( rwork( ll ) / rwork( nq+ll ) )**2
546  IF( temp2.LE.tol3z ) THEN
547  IF( ia+m-1.GT.i ) THEN
548  CALL pscnrm2( ia+m-i-1, rwork( ll ), a,
549  $ i+1, k+ll-jj, desca, 1 )
550  rwork( nq+ll ) = rwork( ll )
551  ELSE
552  rwork( ll ) = zero
553  rwork( nq+ll ) = zero
554  END IF
555  ELSE
556  rwork( ll ) = rwork( ll ) * sqrt( temp )
557  END IF
558  END IF
559  100 CONTINUE
560  jj = jj + kb
561  END IF
562  icurcol = mod( icurcol+1, npcol )
563 *
564  110 CONTINUE
565 *
566  120 CONTINUE
567 *
568  work( 1 ) = cmplx( real( lwmin ) )
569  rwork( 1 ) = real( lrwmin )
570 *
571  RETURN
572 *
573 * End of PCGEQPF
574 *
575  END
cmplx
float cmplx[2]
Definition: pblas.h:132
max
#define max(A, B)
Definition: pcgemr.c:180
pclarfg
subroutine pclarfg(N, ALPHA, IAX, JAX, X, IX, JX, DESCX, INCX, TAU)
Definition: pclarfg.f:3
infog1l
subroutine infog1l(GINDX, NB, NPROCS, MYROC, ISRCPROC, LINDX, ROCSRC)
Definition: infog1l.f:3
pcgeqpf
subroutine pcgeqpf(M, N, A, IA, JA, DESCA, IPIV, TAU, WORK, LWORK, RWORK, LRWORK, INFO)
Definition: pcgeqpf.f:3
infog2l
subroutine infog2l(GRINDX, GCINDX, DESC, NPROW, NPCOL, MYROW, MYCOL, LRINDX, LCINDX, RSRC, CSRC)
Definition: infog2l.f:3
pclarfc
subroutine pclarfc(SIDE, M, N, V, IV, JV, DESCV, INCV, TAU, C, IC, JC, DESCC, WORK)
Definition: pclarfc.f:3
pchk1mat
subroutine pchk1mat(MA, MAPOS0, NA, NAPOS0, IA, JA, DESCA, DESCAPOS0, NEXTRA, EX, EXPOS, INFO)
Definition: pchkxmat.f:3
pcelset
subroutine pcelset(A, IA, JA, DESCA, ALPHA)
Definition: pcelset.f:2
descset
subroutine descset(DESC, M, N, MB, NB, IRSRC, ICSRC, ICTXT, LLD)
Definition: descset.f:3
chk1mat
subroutine chk1mat(MA, MAPOS0, NA, NAPOS0, IA, JA, DESCA, DESCAPOS0, INFO)
Definition: chk1mat.f:3
pxerbla
subroutine pxerbla(ICTXT, SRNAME, INFO)
Definition: pxerbla.f:2
min
#define min(A, B)
Definition: pcgemr.c:181