208 SUBROUTINE cgelsy( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
209 $ WORK, LWORK, RWORK, INFO )
216 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
222 COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
229 parameter( imax = 1, imin = 2 )
231 parameter( zero = 0.0e+0, one = 1.0e+0 )
233 parameter( czero = ( 0.0e+0, 0.0e+0 ),
234 $ cone = ( 1.0e+0, 0.0e+0 ) )
238 INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKOPT, MN,
239 $ nb, nb1, nb2, nb3, nb4
240 REAL ANRM, BIGNUM, BNRM, SMAX, SMAXPR, SMIN, SMINPR,
242 COMPLEX C1, C2, S1, S2
251 EXTERNAL clange, ilaenv, slamch
265 nb1 = ilaenv( 1,
'CGEQRF',
' ', m, n, -1, -1 )
266 nb2 = ilaenv( 1,
'CGERQF',
' ', m, n, -1, -1 )
267 nb3 = ilaenv( 1,
'CUNMQR',
' ', m, n, nrhs, -1 )
268 nb4 = ilaenv( 1,
'CUNMRQ',
' ', m, n, nrhs, -1 )
269 nb =
max( nb1, nb2, nb3, nb4 )
270 lwkopt =
max( 1, mn+2*n+nb*(n+1), 2*mn+nb*nrhs )
271 work( 1 ) =
cmplx( lwkopt )
272 lquery = ( lwork.EQ.-1 )
275 ELSE IF( n.LT.0 )
THEN
277 ELSE IF( nrhs.LT.0 )
THEN
279 ELSE IF( lda.LT.
max( 1, m ) )
THEN
281 ELSE IF( ldb.LT.
max( 1, m, n ) )
THEN
283 ELSE IF( lwork.LT.( mn+
max( 2*mn, n+1, mn+nrhs ) ) .AND.
289 CALL xerbla(
'CGELSY', -info )
291 ELSE IF( lquery )
THEN
297 IF(
min( m, n, nrhs ).EQ.0 )
THEN
304 smlnum = slamch(
'S' ) / slamch(
'P' )
305 bignum = one / smlnum
306 CALL slabad( smlnum, bignum )
310 anrm = clange(
'M', m, n, a, lda, rwork )
312 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
316 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
318 ELSE IF( anrm.GT.bignum )
THEN
322 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
324 ELSE IF( anrm.EQ.zero )
THEN
328 CALL claset(
'F',
max( m, n ), nrhs, czero, czero, b, ldb )
333 bnrm = clange(
'M', m, nrhs, b, ldb, rwork )
335 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
339 CALL clascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
341 ELSE IF( bnrm.GT.bignum )
THEN
345 CALL clascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
352 CALL cgeqp3( m, n, a, lda, jpvt, work( 1 ), work( mn+1 ),
353 $ lwork-mn, rwork, info )
354 wsize = mn + real( work( mn+1 ) )
363 smax = abs( a( 1, 1 ) )
365 IF( abs( a( 1, 1 ) ).EQ.zero )
THEN
367 CALL claset(
'F',
max( m, n ), nrhs, czero, czero, b, ldb )
374 IF( rank.LT.mn )
THEN
376 CALL claic1( imin, rank, work( ismin ), smin, a( 1, i ),
377 $ a( i, i ), sminpr, s1, c1 )
378 CALL claic1( imax, rank, work( ismax ), smax, a( 1, i ),
379 $ a( i, i ), smaxpr, s2, c2 )
381 IF( smaxpr*rcond.LE.sminpr )
THEN
383 work( ismin+i-1 ) = s1*work( ismin+i-1 )
384 work( ismax+i-1 ) = s2*work( ismax+i-1 )
386 work( ismin+rank ) = c1
387 work( ismax+rank ) = c2
404 $
CALL ctzrzf( rank, n, a, lda, work( mn+1 ), work( 2*mn+1 ),
412 CALL cunmqr(
'Left',
'Conjugate transpose', m, nrhs, mn, a, lda,
413 $ work( 1 ), b, ldb, work( 2*mn+1 ), lwork-2*mn, info )
414 wsize =
max( wsize, 2*mn+real( work( 2*mn+1 ) ) )
420 CALL ctrsm(
'Left',
'Upper',
'No transpose',
'Non-unit', rank,
421 $ nrhs, cone, a, lda, b, ldb )
424 DO 30 i = rank + 1, n
432 CALL cunmrz(
'Left',
'Conjugate transpose', n, nrhs, rank,
433 $ n-rank, a, lda, work( mn+1 ), b, ldb,
434 $ work( 2*mn+1 ), lwork-2*mn, info )
443 work( jpvt( i ) ) = b( i, j )
445 CALL ccopy( n, work( 1 ), 1, b( 1, j ), 1 )
452 IF( iascl.EQ.1 )
THEN
453 CALL clascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
454 CALL clascl(
'U', 0, 0, smlnum, anrm, rank, rank, a, lda,
456 ELSE IF( iascl.EQ.2 )
THEN
457 CALL clascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
458 CALL clascl(
'U', 0, 0, bignum, anrm, rank, rank, a, lda,
461 IF( ibscl.EQ.1 )
THEN
462 CALL clascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
463 ELSE IF( ibscl.EQ.2 )
THEN
464 CALL clascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
468 work( 1 ) =
cmplx( lwkopt )