Annotation of rpl/lapack/lapack/zgelsx.f, revision 1.1

1.1     ! bertrand    1:       SUBROUTINE ZGELSX( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
        !             2:      $                   WORK, RWORK, INFO )
        !             3: *
        !             4: *  -- LAPACK driver routine (version 3.2) --
        !             5: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
        !             6: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
        !             7: *     November 2006
        !             8: *
        !             9: *     .. Scalar Arguments ..
        !            10:       INTEGER            INFO, LDA, LDB, M, N, NRHS, RANK
        !            11:       DOUBLE PRECISION   RCOND
        !            12: *     ..
        !            13: *     .. Array Arguments ..
        !            14:       INTEGER            JPVT( * )
        !            15:       DOUBLE PRECISION   RWORK( * )
        !            16:       COMPLEX*16         A( LDA, * ), B( LDB, * ), WORK( * )
        !            17: *     ..
        !            18: *
        !            19: *  Purpose
        !            20: *  =======
        !            21: *
        !            22: *  This routine is deprecated and has been replaced by routine ZGELSY.
        !            23: *
        !            24: *  ZGELSX computes the minimum-norm solution to a complex linear least
        !            25: *  squares problem:
        !            26: *      minimize || A * X - B ||
        !            27: *  using a complete orthogonal factorization of A.  A is an M-by-N
        !            28: *  matrix which may be rank-deficient.
        !            29: *
        !            30: *  Several right hand side vectors b and solution vectors x can be
        !            31: *  handled in a single call; they are stored as the columns of the
        !            32: *  M-by-NRHS right hand side matrix B and the N-by-NRHS solution
        !            33: *  matrix X.
        !            34: *
        !            35: *  The routine first computes a QR factorization with column pivoting:
        !            36: *      A * P = Q * [ R11 R12 ]
        !            37: *                  [  0  R22 ]
        !            38: *  with R11 defined as the largest leading submatrix whose estimated
        !            39: *  condition number is less than 1/RCOND.  The order of R11, RANK,
        !            40: *  is the effective rank of A.
        !            41: *
        !            42: *  Then, R22 is considered to be negligible, and R12 is annihilated
        !            43: *  by unitary transformations from the right, arriving at the
        !            44: *  complete orthogonal factorization:
        !            45: *     A * P = Q * [ T11 0 ] * Z
        !            46: *                 [  0  0 ]
        !            47: *  The minimum-norm solution is then
        !            48: *     X = P * Z' [ inv(T11)*Q1'*B ]
        !            49: *                [        0       ]
        !            50: *  where Q1 consists of the first RANK columns of Q.
        !            51: *
        !            52: *  Arguments
        !            53: *  =========
        !            54: *
        !            55: *  M       (input) INTEGER
        !            56: *          The number of rows of the matrix A.  M >= 0.
        !            57: *
        !            58: *  N       (input) INTEGER
        !            59: *          The number of columns of the matrix A.  N >= 0.
        !            60: *
        !            61: *  NRHS    (input) INTEGER
        !            62: *          The number of right hand sides, i.e., the number of
        !            63: *          columns of matrices B and X. NRHS >= 0.
        !            64: *
        !            65: *  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
        !            66: *          On entry, the M-by-N matrix A.
        !            67: *          On exit, A has been overwritten by details of its
        !            68: *          complete orthogonal factorization.
        !            69: *
        !            70: *  LDA     (input) INTEGER
        !            71: *          The leading dimension of the array A.  LDA >= max(1,M).
        !            72: *
        !            73: *  B       (input/output) COMPLEX*16 array, dimension (LDB,NRHS)
        !            74: *          On entry, the M-by-NRHS right hand side matrix B.
        !            75: *          On exit, the N-by-NRHS solution matrix X.
        !            76: *          If m >= n and RANK = n, the residual sum-of-squares for
        !            77: *          the solution in the i-th column is given by the sum of
        !            78: *          squares of elements N+1:M in that column.
        !            79: *
        !            80: *  LDB     (input) INTEGER
        !            81: *          The leading dimension of the array B. LDB >= max(1,M,N).
        !            82: *
        !            83: *  JPVT    (input/output) INTEGER array, dimension (N)
        !            84: *          On entry, if JPVT(i) .ne. 0, the i-th column of A is an
        !            85: *          initial column, otherwise it is a free column.  Before
        !            86: *          the QR factorization of A, all initial columns are
        !            87: *          permuted to the leading positions; only the remaining
        !            88: *          free columns are moved as a result of column pivoting
        !            89: *          during the factorization.
        !            90: *          On exit, if JPVT(i) = k, then the i-th column of A*P
        !            91: *          was the k-th column of A.
        !            92: *
        !            93: *  RCOND   (input) DOUBLE PRECISION
        !            94: *          RCOND is used to determine the effective rank of A, which
        !            95: *          is defined as the order of the largest leading triangular
        !            96: *          submatrix R11 in the QR factorization with pivoting of A,
        !            97: *          whose estimated condition number < 1/RCOND.
        !            98: *
        !            99: *  RANK    (output) INTEGER
        !           100: *          The effective rank of A, i.e., the order of the submatrix
        !           101: *          R11.  This is the same as the order of the submatrix T11
        !           102: *          in the complete orthogonal factorization of A.
        !           103: *
        !           104: *  WORK    (workspace) COMPLEX*16 array, dimension
        !           105: *                      (min(M,N) + max( N, 2*min(M,N)+NRHS )),
        !           106: *
        !           107: *  RWORK   (workspace) DOUBLE PRECISION array, dimension (2*N)
        !           108: *
        !           109: *  INFO    (output) INTEGER
        !           110: *          = 0:  successful exit
        !           111: *          < 0:  if INFO = -i, the i-th argument had an illegal value
        !           112: *
        !           113: *  =====================================================================
        !           114: *
        !           115: *     .. Parameters ..
        !           116:       INTEGER            IMAX, IMIN
        !           117:       PARAMETER          ( IMAX = 1, IMIN = 2 )
        !           118:       DOUBLE PRECISION   ZERO, ONE, DONE, NTDONE
        !           119:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, DONE = ZERO,
        !           120:      $                   NTDONE = ONE )
        !           121:       COMPLEX*16         CZERO, CONE
        !           122:       PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
        !           123:      $                   CONE = ( 1.0D+0, 0.0D+0 ) )
        !           124: *     ..
        !           125: *     .. Local Scalars ..
        !           126:       INTEGER            I, IASCL, IBSCL, ISMAX, ISMIN, J, K, MN
        !           127:       DOUBLE PRECISION   ANRM, BIGNUM, BNRM, SMAX, SMAXPR, SMIN, SMINPR,
        !           128:      $                   SMLNUM
        !           129:       COMPLEX*16         C1, C2, S1, S2, T1, T2
        !           130: *     ..
        !           131: *     .. External Subroutines ..
        !           132:       EXTERNAL           XERBLA, ZGEQPF, ZLAIC1, ZLASCL, ZLASET, ZLATZM,
        !           133:      $                   ZTRSM, ZTZRQF, ZUNM2R
        !           134: *     ..
        !           135: *     .. External Functions ..
        !           136:       DOUBLE PRECISION   DLAMCH, ZLANGE
        !           137:       EXTERNAL           DLAMCH, ZLANGE
        !           138: *     ..
        !           139: *     .. Intrinsic Functions ..
        !           140:       INTRINSIC          ABS, DCONJG, MAX, MIN
        !           141: *     ..
        !           142: *     .. Executable Statements ..
        !           143: *
        !           144:       MN = MIN( M, N )
        !           145:       ISMIN = MN + 1
        !           146:       ISMAX = 2*MN + 1
        !           147: *
        !           148: *     Test the input arguments.
        !           149: *
        !           150:       INFO = 0
        !           151:       IF( M.LT.0 ) THEN
        !           152:          INFO = -1
        !           153:       ELSE IF( N.LT.0 ) THEN
        !           154:          INFO = -2
        !           155:       ELSE IF( NRHS.LT.0 ) THEN
        !           156:          INFO = -3
        !           157:       ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
        !           158:          INFO = -5
        !           159:       ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
        !           160:          INFO = -7
        !           161:       END IF
        !           162: *
        !           163:       IF( INFO.NE.0 ) THEN
        !           164:          CALL XERBLA( 'ZGELSX', -INFO )
        !           165:          RETURN
        !           166:       END IF
        !           167: *
        !           168: *     Quick return if possible
        !           169: *
        !           170:       IF( MIN( M, N, NRHS ).EQ.0 ) THEN
        !           171:          RANK = 0
        !           172:          RETURN
        !           173:       END IF
        !           174: *
        !           175: *     Get machine parameters
        !           176: *
        !           177:       SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
        !           178:       BIGNUM = ONE / SMLNUM
        !           179:       CALL DLABAD( SMLNUM, BIGNUM )
        !           180: *
        !           181: *     Scale A, B if max elements outside range [SMLNUM,BIGNUM]
        !           182: *
        !           183:       ANRM = ZLANGE( 'M', M, N, A, LDA, RWORK )
        !           184:       IASCL = 0
        !           185:       IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
        !           186: *
        !           187: *        Scale matrix norm up to SMLNUM
        !           188: *
        !           189:          CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
        !           190:          IASCL = 1
        !           191:       ELSE IF( ANRM.GT.BIGNUM ) THEN
        !           192: *
        !           193: *        Scale matrix norm down to BIGNUM
        !           194: *
        !           195:          CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
        !           196:          IASCL = 2
        !           197:       ELSE IF( ANRM.EQ.ZERO ) THEN
        !           198: *
        !           199: *        Matrix all zero. Return zero solution.
        !           200: *
        !           201:          CALL ZLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
        !           202:          RANK = 0
        !           203:          GO TO 100
        !           204:       END IF
        !           205: *
        !           206:       BNRM = ZLANGE( 'M', M, NRHS, B, LDB, RWORK )
        !           207:       IBSCL = 0
        !           208:       IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
        !           209: *
        !           210: *        Scale matrix norm up to SMLNUM
        !           211: *
        !           212:          CALL ZLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
        !           213:          IBSCL = 1
        !           214:       ELSE IF( BNRM.GT.BIGNUM ) THEN
        !           215: *
        !           216: *        Scale matrix norm down to BIGNUM
        !           217: *
        !           218:          CALL ZLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
        !           219:          IBSCL = 2
        !           220:       END IF
        !           221: *
        !           222: *     Compute QR factorization with column pivoting of A:
        !           223: *        A * P = Q * R
        !           224: *
        !           225:       CALL ZGEQPF( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ), RWORK,
        !           226:      $             INFO )
        !           227: *
        !           228: *     complex workspace MN+N. Real workspace 2*N. Details of Householder
        !           229: *     rotations stored in WORK(1:MN).
        !           230: *
        !           231: *     Determine RANK using incremental condition estimation
        !           232: *
        !           233:       WORK( ISMIN ) = CONE
        !           234:       WORK( ISMAX ) = CONE
        !           235:       SMAX = ABS( A( 1, 1 ) )
        !           236:       SMIN = SMAX
        !           237:       IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
        !           238:          RANK = 0
        !           239:          CALL ZLASET( 'F', MAX( M, N ), NRHS, CZERO, CZERO, B, LDB )
        !           240:          GO TO 100
        !           241:       ELSE
        !           242:          RANK = 1
        !           243:       END IF
        !           244: *
        !           245:    10 CONTINUE
        !           246:       IF( RANK.LT.MN ) THEN
        !           247:          I = RANK + 1
        !           248:          CALL ZLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),
        !           249:      $                A( I, I ), SMINPR, S1, C1 )
        !           250:          CALL ZLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),
        !           251:      $                A( I, I ), SMAXPR, S2, C2 )
        !           252: *
        !           253:          IF( SMAXPR*RCOND.LE.SMINPR ) THEN
        !           254:             DO 20 I = 1, RANK
        !           255:                WORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )
        !           256:                WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
        !           257:    20       CONTINUE
        !           258:             WORK( ISMIN+RANK ) = C1
        !           259:             WORK( ISMAX+RANK ) = C2
        !           260:             SMIN = SMINPR
        !           261:             SMAX = SMAXPR
        !           262:             RANK = RANK + 1
        !           263:             GO TO 10
        !           264:          END IF
        !           265:       END IF
        !           266: *
        !           267: *     Logically partition R = [ R11 R12 ]
        !           268: *                             [  0  R22 ]
        !           269: *     where R11 = R(1:RANK,1:RANK)
        !           270: *
        !           271: *     [R11,R12] = [ T11, 0 ] * Y
        !           272: *
        !           273:       IF( RANK.LT.N )
        !           274:      $   CALL ZTZRQF( RANK, N, A, LDA, WORK( MN+1 ), INFO )
        !           275: *
        !           276: *     Details of Householder rotations stored in WORK(MN+1:2*MN)
        !           277: *
        !           278: *     B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS)
        !           279: *
        !           280:       CALL ZUNM2R( 'Left', 'Conjugate transpose', M, NRHS, MN, A, LDA,
        !           281:      $             WORK( 1 ), B, LDB, WORK( 2*MN+1 ), INFO )
        !           282: *
        !           283: *     workspace NRHS
        !           284: *
        !           285: *      B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)
        !           286: *
        !           287:       CALL ZTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
        !           288:      $            NRHS, CONE, A, LDA, B, LDB )
        !           289: *
        !           290:       DO 40 I = RANK + 1, N
        !           291:          DO 30 J = 1, NRHS
        !           292:             B( I, J ) = CZERO
        !           293:    30    CONTINUE
        !           294:    40 CONTINUE
        !           295: *
        !           296: *     B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS)
        !           297: *
        !           298:       IF( RANK.LT.N ) THEN
        !           299:          DO 50 I = 1, RANK
        !           300:             CALL ZLATZM( 'Left', N-RANK+1, NRHS, A( I, RANK+1 ), LDA,
        !           301:      $                   DCONJG( WORK( MN+I ) ), B( I, 1 ),
        !           302:      $                   B( RANK+1, 1 ), LDB, WORK( 2*MN+1 ) )
        !           303:    50    CONTINUE
        !           304:       END IF
        !           305: *
        !           306: *     workspace NRHS
        !           307: *
        !           308: *     B(1:N,1:NRHS) := P * B(1:N,1:NRHS)
        !           309: *
        !           310:       DO 90 J = 1, NRHS
        !           311:          DO 60 I = 1, N
        !           312:             WORK( 2*MN+I ) = NTDONE
        !           313:    60    CONTINUE
        !           314:          DO 80 I = 1, N
        !           315:             IF( WORK( 2*MN+I ).EQ.NTDONE ) THEN
        !           316:                IF( JPVT( I ).NE.I ) THEN
        !           317:                   K = I
        !           318:                   T1 = B( K, J )
        !           319:                   T2 = B( JPVT( K ), J )
        !           320:    70             CONTINUE
        !           321:                   B( JPVT( K ), J ) = T1
        !           322:                   WORK( 2*MN+K ) = DONE
        !           323:                   T1 = T2
        !           324:                   K = JPVT( K )
        !           325:                   T2 = B( JPVT( K ), J )
        !           326:                   IF( JPVT( K ).NE.I )
        !           327:      $               GO TO 70
        !           328:                   B( I, J ) = T1
        !           329:                   WORK( 2*MN+K ) = DONE
        !           330:                END IF
        !           331:             END IF
        !           332:    80    CONTINUE
        !           333:    90 CONTINUE
        !           334: *
        !           335: *     Undo scaling
        !           336: *
        !           337:       IF( IASCL.EQ.1 ) THEN
        !           338:          CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
        !           339:          CALL ZLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
        !           340:      $                INFO )
        !           341:       ELSE IF( IASCL.EQ.2 ) THEN
        !           342:          CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
        !           343:          CALL ZLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
        !           344:      $                INFO )
        !           345:       END IF
        !           346:       IF( IBSCL.EQ.1 ) THEN
        !           347:          CALL ZLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
        !           348:       ELSE IF( IBSCL.EQ.2 ) THEN
        !           349:          CALL ZLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
        !           350:       END IF
        !           351: *
        !           352:   100 CONTINUE
        !           353: *
        !           354:       RETURN
        !           355: *
        !           356: *     End of ZGELSX
        !           357: *
        !           358:       END

CVSweb interface <joel.bertrand@systella.fr>