208 SUBROUTINE zgelsy( 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
217 DOUBLE PRECISION RCOND
221 DOUBLE PRECISION RWORK( * )
222 COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( * )
229 parameter( imax = 1, imin = 2 )
230 DOUBLE PRECISION ZERO, ONE
231 parameter( zero = 0.0d+0, one = 1.0d+0 )
232 COMPLEX*16 CZERO, CONE
233 parameter( czero = ( 0.0d+0, 0.0d+0 ),
234 $ cone = ( 1.0d+0, 0.0d+0 ) )
238 INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKOPT, MN,
239 $ nb, nb1, nb2, nb3, nb4
240 DOUBLE PRECISION ANRM, BIGNUM, BNRM, SMAX, SMAXPR, SMIN, SMINPR,
242 COMPLEX*16 C1, C2, S1, S2
250 DOUBLE PRECISION DLAMCH, ZLANGE
251 EXTERNAL ilaenv, dlamch, zlange
254 INTRINSIC abs, dble, dcmplx,
max,
min
265 nb1 = ilaenv( 1,
'ZGEQRF',
' ', m, n, -1, -1 )
266 nb2 = ilaenv( 1,
'ZGERQF',
' ', m, n, -1, -1 )
267 nb3 = ilaenv( 1,
'ZUNMQR',
' ', m, n, nrhs, -1 )
268 nb4 = ilaenv( 1,
'ZUNMRQ',
' ', 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 ) = dcmplx( 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. .NOT.
289 CALL xerbla(
'ZGELSY', -info )
291 ELSE IF( lquery )
THEN
297 IF(
min( m, n, nrhs ).EQ.0 )
THEN
304 smlnum = dlamch(
'S' ) / dlamch(
'P' )
305 bignum = one / smlnum
306 CALL dlabad( smlnum, bignum )
310 anrm = zlange(
'M', m, n, a, lda, rwork )
312 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
316 CALL zlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
318 ELSE IF( anrm.GT.bignum )
THEN
322 CALL zlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
324 ELSE IF( anrm.EQ.zero )
THEN
328 CALL zlaset(
'F',
max( m, n ), nrhs, czero, czero, b, ldb )
333 bnrm = zlange(
'M', m, nrhs, b, ldb, rwork )
335 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
339 CALL zlascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
341 ELSE IF( bnrm.GT.bignum )
THEN
345 CALL zlascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
352 CALL zgeqp3( m, n, a, lda, jpvt, work( 1 ), work( mn+1 ),
353 $ lwork-mn, rwork, info )
354 wsize = mn + dble( work( mn+1 ) )
363 smax = abs( a( 1, 1 ) )
365 IF( abs( a( 1, 1 ) ).EQ.zero )
THEN
367 CALL zlaset(
'F',
max( m, n ), nrhs, czero, czero, b, ldb )
374 IF( rank.LT.mn )
THEN
376 CALL zlaic1( imin, rank, work( ismin ), smin, a( 1, i ),
377 $ a( i, i ), sminpr, s1, c1 )
378 CALL zlaic1( 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 ztzrzf( rank, n, a, lda, work( mn+1 ), work( 2*mn+1 ),
412 CALL zunmqr(
'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+dble( work( 2*mn+1 ) ) )
420 CALL ztrsm(
'Left', 'upper
', 'no transpose
', 'non-unit
', RANK,
421 $ NRHS, CONE, A, LDA, B, LDB )
424 DO 30 I = RANK + 1, N
432 CALL ZUNMRZ( '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 ZCOPY( N, WORK( 1 ), 1, B( 1, J ), 1 )
452.EQ.
IF( IASCL1 ) THEN
453 CALL ZLASCL( 'g
', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
454 CALL ZLASCL( 'u
', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
456.EQ.
ELSE IF( IASCL2 ) THEN
457 CALL ZLASCL( 'g
', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
458 CALL ZLASCL( 'u
', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
461.EQ.
IF( IBSCL1 ) THEN
462 CALL ZLASCL( 'g
', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
463.EQ.
ELSE IF( IBSCL2 ) THEN
464 CALL ZLASCL( 'g
', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
468 WORK( 1 ) = DCMPLX( LWKOPT )