208 SUBROUTINE cgelsy( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
209 $ WORK, LWORK, RWORK, INFO )
216 INTEGER INFO, , 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.EQ.
LQUERY = ( LWORK-1 )
275.LT.
ELSE IF( N0 ) THEN
277.LT.
ELSE IF( NRHS0 ) THEN
279.LT.
ELSE IF( LDAMAX( 1, M ) ) THEN
281.LT.
ELSE IF( LDBMAX( 1, M, N ) ) THEN
283.LT..AND.
ELSE IF( LWORK( MN+MAX( 2*MN, N+1, MN+NRHS ) )
289 CALL XERBLA( 'cgelsy', -INFO )
291 ELSE IF( LQUERY ) THEN
297.EQ.
IF( MIN( M, N, NRHS )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.GT..AND..LT.
IF( ANRMZERO ANRMSMLNUM ) THEN
316 CALL CLASCL( 'g
', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
318.GT.
ELSE IF( ANRMBIGNUM ) THEN
322 CALL CLASCL( 'g
', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
324.EQ.
ELSE IF( ANRMZERO ) THEN
328 CALL CLASET( 'f
', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
333 BNRM = CLANGE( 'm
', M, NRHS, B, LDB, RWORK )
335.GT..AND..LT.
IF( BNRMZERO BNRMSMLNUM ) THEN
339 CALL CLASCL( 'g
', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
341.GT.
ELSE IF( BNRMBIGNUM ) 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.EQ.
IF( ABS( A( 1, 1 ) )ZERO ) THEN
367 CALL CLASET( 'f
', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
374.LT.
IF( RANKMN ) 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.LE.
IF( SMAXPR*RCONDSMINPR ) 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 cgelsy(m, n, nrhs, a, lda, b, ldb, jpvt, rcond, rank, work, lwork, rwork, info)
CGELSY solves overdetermined or underdetermined systems for GE matrices