208 SUBROUTINE cgelsy( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND,
210 $ WORK, LWORK, RWORK, INFO )
217 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
223 COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
230 PARAMETER ( IMAX = 1, imin = 2 )
232 parameter( zero = 0.0e+0, one = 1.0e+0 )
234 parameter( czero = ( 0.0e+0, 0.0e+0 ),
235 $ cone = ( 1.0e+0, 0.0e+0 ) )
239 INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKOPT, MN,
240 $ nb, nb1, nb2, nb3, nb4
241 REAL ANRM, BIGNUM, BNRM, SMAX, SMAXPR, SMIN, SMINPR,
243 COMPLEX C1, C2, S1, S2
253 EXTERNAL clange, ilaenv, slamch
256 INTRINSIC abs, max, min, real, cmplx
267 nb1 = ilaenv( 1,
'CGEQRF',
' ', m, n, -1, -1 )
268 nb2 = ilaenv( 1,
'CGERQF',
' ', m, n, -1, -1 )
269 nb3 = ilaenv( 1,
'CUNMQR',
' ', m, n, nrhs, -1 )
270 nb4 = ilaenv( 1,
'CUNMRQ',
' ', m, n, nrhs, -1 )
271 nb = max( nb1, nb2, nb3, nb4 )
272 lwkopt = max( 1, mn+2*n+nb*(n+1), 2*mn+nb*nrhs )
273 work( 1 ) = cmplx( lwkopt )
274 lquery = ( lwork.EQ.-1 )
277 ELSE IF( n.LT.0 )
THEN
279 ELSE IF( nrhs.LT.0 )
THEN
281 ELSE IF( lda.LT.max( 1, m ) )
THEN
283 ELSE IF( ldb.LT.max( 1, m, n ) )
THEN
285 ELSE IF( lwork.LT.( mn+max( 2*mn, n+1, mn+nrhs ) ) .AND.
291 CALL xerbla(
'CGELSY', -info )
293 ELSE IF( lquery )
THEN
299 IF( min( m, n, nrhs ).EQ.0 )
THEN
306 smlnum = slamch(
'S' ) / slamch(
'P' )
307 bignum = one / smlnum
311 anrm = clange(
'M', m, n, a, lda, rwork )
313 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
317 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
319 ELSE IF( anrm.GT.bignum )
THEN
323 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
325 ELSE IF( anrm.EQ.zero )
THEN
329 CALL claset(
'F', max( m, n ), nrhs, czero, czero, b, ldb )
334 bnrm = clange(
'M', m, nrhs, b, ldb, rwork )
336 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
340 CALL clascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb,
343 ELSE IF( bnrm.GT.bignum )
THEN
347 CALL clascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb,
355 CALL cgeqp3( m, n, a, lda, jpvt, work( 1 ), work( mn+1 ),
356 $ lwork-mn, rwork, info )
357 wsize = real( mn ) + real( work( mn+1 ) )
366 smax = abs( a( 1, 1 ) )
368 IF( abs( a( 1, 1 ) ).EQ.zero )
THEN
370 CALL claset(
'F', max( m, n ), nrhs, czero, czero, b, ldb )
377 IF( rank.LT.mn )
THEN
379 CALL claic1( imin, rank, work( ismin ), smin, a( 1, i ),
380 $ a( i, i ), sminpr, s1, c1 )
381 CALL claic1( imax, rank, work( ismax ), smax, a( 1, i ),
382 $ a( i, i ), smaxpr, s2, c2 )
384 IF( smaxpr*rcond.LE.sminpr )
THEN
386 work( ismin+i-1 ) = s1*work( ismin+i-1 )
387 work( ismax+i-1 ) = s2*work( ismax+i-1 )
389 work( ismin+rank ) = c1
390 work( ismax+rank ) = c2
407 $
CALL ctzrzf( rank, n, a, lda, work( mn+1 ), work( 2*mn+1 ),
415 CALL cunmqr(
'Left',
'Conjugate transpose', m, nrhs, mn, a,
417 $ work( 1 ), b, ldb, work( 2*mn+1 ), lwork-2*mn, info )
418 wsize = max( wsize, real( 2*mn )+real( work( 2*mn+1 ) ) )
424 CALL ctrsm(
'Left',
'Upper',
'No transpose',
'Non-unit', rank,
425 $ nrhs, cone, a, lda, b, ldb )
428 DO 30 i = rank + 1, n
436 CALL cunmrz(
'Left',
'Conjugate transpose', n, nrhs, rank,
437 $ n-rank, a, lda, work( mn+1 ), b, ldb,
438 $ work( 2*mn+1 ), lwork-2*mn, info )
447 work( jpvt( i ) ) = b( i, j )
449 CALL ccopy( n, work( 1 ), 1, b( 1, j ), 1 )
456 IF( iascl.EQ.1 )
THEN
457 CALL clascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb,
459 CALL clascl(
'U', 0, 0, smlnum, anrm, rank, rank, a, lda,
461 ELSE IF( iascl.EQ.2 )
THEN
462 CALL clascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb,
464 CALL clascl(
'U', 0, 0, bignum, anrm, rank, rank, a, lda,
467 IF( ibscl.EQ.1 )
THEN
468 CALL clascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb,
470 ELSE IF( ibscl.EQ.2 )
THEN
471 CALL clascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb,
476 work( 1 ) = cmplx( lwkopt )