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 IF( iascl.EQ.1 )
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 ELSE IF( iascl.EQ.2 )
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 IF( ibscl.EQ.1 )
THEN
462 CALL zlascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
463 ELSE IF( ibscl.EQ.2 )
THEN
464 CALL zlascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
468 work( 1 ) = dcmplx( lwkopt )
subroutine dlabad(SMALL, LARGE)
DLABAD
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zcopy(N, ZX, INCX, ZY, INCY)
ZCOPY
subroutine ztrsm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
ZTRSM
subroutine zgeqp3(M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK, INFO)
ZGEQP3
subroutine zgelsy(M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK, WORK, LWORK, RWORK, INFO)
ZGELSY solves overdetermined or underdetermined systems for GE matrices
subroutine zlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
ZLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine zlaic1(JOB, J, X, SEST, W, GAMMA, SESTPR, S, C)
ZLAIC1 applies one step of incremental condition estimation.
subroutine zlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine zunmrz(SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMRZ
subroutine ztzrzf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
ZTZRZF
subroutine zunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMQR