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
254 INTRINSIC abs, max, min, real, cmplx
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 )
subroutine slabad(SMALL, LARGE)
SLABAD
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine ccopy(N, CX, INCX, CY, INCY)
CCOPY
subroutine ctrsm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
CTRSM
subroutine cgeqp3(M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK, INFO)
CGEQP3
subroutine cgelsy(M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK, WORK, LWORK, RWORK, INFO)
CGELSY solves overdetermined or underdetermined systems for GE matrices
subroutine claset(UPLO, M, N, ALPHA, BETA, A, LDA)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine clascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine claic1(JOB, J, X, SEST, W, GAMMA, SESTPR, S, C)
CLAIC1 applies one step of incremental condition estimation.
subroutine ctzrzf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CTZRZF
subroutine cunmrz(SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMRZ
subroutine cunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMQR