File:  [local] / rpl / lapack / lapack / dorcsd.f
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Dec 21 13:50:36 2010 UTC (13 years, 5 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Mise à jour de Lapack vers la version 3.3.0.

    1:       RECURSIVE SUBROUTINE DORCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS,
    2:      $                             SIGNS, M, P, Q, X11, LDX11, X12,
    3:      $                             LDX12, X21, LDX21, X22, LDX22, THETA,
    4:      $                             U1, LDU1, U2, LDU2, V1T, LDV1T, V2T,
    5:      $                             LDV2T, WORK, LWORK, IWORK, INFO )
    6:       IMPLICIT NONE
    7: *
    8: *  -- LAPACK routine (version 3.3.0) --
    9: *
   10: *  -- Contributed by Brian Sutton of the Randolph-Macon College --
   11: *  -- November 2010
   12: *
   13: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
   14: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--     
   15: *
   16: *     .. Scalar Arguments ..
   17:       CHARACTER          JOBU1, JOBU2, JOBV1T, JOBV2T, SIGNS, TRANS
   18:       INTEGER            INFO, LDU1, LDU2, LDV1T, LDV2T, LDX11, LDX12,
   19:      $                   LDX21, LDX22, LWORK, M, P, Q
   20: *     ..
   21: *     .. Array Arguments ..
   22:       INTEGER            IWORK( * )
   23:       DOUBLE PRECISION   THETA( * )
   24:       DOUBLE PRECISION   U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
   25:      $                   V2T( LDV2T, * ), WORK( * ), X11( LDX11, * ),
   26:      $                   X12( LDX12, * ), X21( LDX21, * ), X22( LDX22,
   27:      $                   * )
   28: *     ..
   29: *
   30: *  Purpose
   31: *  =======
   32: *
   33: *  DORCSD computes the CS decomposition of an M-by-M partitioned
   34: *  orthogonal matrix X:
   35: *
   36: *                                  [  I  0  0 |  0  0  0 ]
   37: *                                  [  0  C  0 |  0 -S  0 ]
   38: *      [ X11 | X12 ]   [ U1 |    ] [  0  0  0 |  0  0 -I ] [ V1 |    ]**T
   39: *  X = [-----------] = [---------] [---------------------] [---------]   .
   40: *      [ X21 | X22 ]   [    | U2 ] [  0  0  0 |  I  0  0 ] [    | V2 ]
   41: *                                  [  0  S  0 |  0  C  0 ]
   42: *                                  [  0  0  I |  0  0  0 ]
   43: *
   44: *  X11 is P-by-Q. The orthogonal matrices U1, U2, V1, and V2 are P-by-P,
   45: *  (M-P)-by-(M-P), Q-by-Q, and (M-Q)-by-(M-Q), respectively. C and S are
   46: *  R-by-R nonnegative diagonal matrices satisfying C^2 + S^2 = I, in
   47: *  which R = MIN(P,M-P,Q,M-Q).
   48: *
   49: *  Arguments
   50: *  =========
   51: *
   52: *  JOBU1   (input) CHARACTER
   53: *          = 'Y':      U1 is computed;
   54: *          otherwise:  U1 is not computed.
   55: *
   56: *  JOBU2   (input) CHARACTER
   57: *          = 'Y':      U2 is computed;
   58: *          otherwise:  U2 is not computed.
   59: *
   60: *  JOBV1T  (input) CHARACTER
   61: *          = 'Y':      V1T is computed;
   62: *          otherwise:  V1T is not computed.
   63: *
   64: *  JOBV2T  (input) CHARACTER
   65: *          = 'Y':      V2T is computed;
   66: *          otherwise:  V2T is not computed.
   67: *
   68: *  TRANS   (input) CHARACTER
   69: *          = 'T':      X, U1, U2, V1T, and V2T are stored in row-major
   70: *                      order;
   71: *          otherwise:  X, U1, U2, V1T, and V2T are stored in column-
   72: *                      major order.
   73: *
   74: *  SIGNS   (input) CHARACTER
   75: *          = 'O':      The lower-left block is made nonpositive (the
   76: *                      "other" convention);
   77: *          otherwise:  The upper-right block is made nonpositive (the
   78: *                      "default" convention).
   79: *
   80: *  M       (input) INTEGER
   81: *          The number of rows and columns in X.
   82: *
   83: *  P       (input) INTEGER
   84: *          The number of rows in X11 and X12. 0 <= P <= M.
   85: *
   86: *  Q       (input) INTEGER
   87: *          The number of columns in X11 and X21. 0 <= Q <= M.
   88: *
   89: *  X       (input/workspace) DOUBLE PRECISION array, dimension (LDX,M)
   90: *          On entry, the orthogonal matrix whose CSD is desired.
   91: *
   92: *  LDX     (input) INTEGER
   93: *          The leading dimension of X. LDX >= MAX(1,M).
   94: *
   95: *  THETA   (output) DOUBLE PRECISION array, dimension (R), in which R =
   96: *          MIN(P,M-P,Q,M-Q).
   97: *          C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) ) and
   98: *          S = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ).
   99: *
  100: *  U1      (output) DOUBLE PRECISION array, dimension (P)
  101: *          If JOBU1 = 'Y', U1 contains the P-by-P orthogonal matrix U1.
  102: *
  103: *  LDU1    (input) INTEGER
  104: *          The leading dimension of U1. If JOBU1 = 'Y', LDU1 >=
  105: *          MAX(1,P).
  106: *
  107: *  U2      (output) DOUBLE PRECISION array, dimension (M-P)
  108: *          If JOBU2 = 'Y', U2 contains the (M-P)-by-(M-P) orthogonal
  109: *          matrix U2.
  110: *
  111: *  LDU2    (input) INTEGER
  112: *          The leading dimension of U2. If JOBU2 = 'Y', LDU2 >=
  113: *          MAX(1,M-P).
  114: *
  115: *  V1T     (output) DOUBLE PRECISION array, dimension (Q)
  116: *          If JOBV1T = 'Y', V1T contains the Q-by-Q matrix orthogonal
  117: *          matrix V1**T.
  118: *
  119: *  LDV1T   (input) INTEGER
  120: *          The leading dimension of V1T. If JOBV1T = 'Y', LDV1T >=
  121: *          MAX(1,Q).
  122: *
  123: *  V2T     (output) DOUBLE PRECISION array, dimension (M-Q)
  124: *          If JOBV2T = 'Y', V2T contains the (M-Q)-by-(M-Q) orthogonal
  125: *          matrix V2**T.
  126: *
  127: *  LDV2T   (input) INTEGER
  128: *          The leading dimension of V2T. If JOBV2T = 'Y', LDV2T >=
  129: *          MAX(1,M-Q).
  130: *
  131: *  WORK    (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
  132: *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  133: *          If INFO > 0 on exit, WORK(2:R) contains the values PHI(1),
  134: *          ..., PHI(R-1) that, together with THETA(1), ..., THETA(R),
  135: *          define the matrix in intermediate bidiagonal-block form
  136: *          remaining after nonconvergence. INFO specifies the number
  137: *          of nonzero PHI's.
  138: *
  139: *  LWORK   (input) INTEGER
  140: *          The dimension of the array WORK.
  141: *
  142: *          If LWORK = -1, then a workspace query is assumed; the routine
  143: *          only calculates the optimal size of the WORK array, returns
  144: *          this value as the first entry of the work array, and no error
  145: *          message related to LWORK is issued by XERBLA.
  146: *
  147: *  IWORK   (workspace) INTEGER array, dimension (M-Q)
  148: *
  149: *  INFO    (output) INTEGER
  150: *          = 0:  successful exit.
  151: *          < 0:  if INFO = -i, the i-th argument had an illegal value.
  152: *          > 0:  DBBCSD did not converge. See the description of WORK
  153: *                above for details.
  154: *
  155: *  Reference
  156: *  =========
  157: *
  158: *  [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.
  159: *      Algorithms, 50(1):33-65, 2009.
  160: *
  161: *  ===================================================================
  162: *
  163: *     .. Parameters ..
  164:       DOUBLE PRECISION   REALONE
  165:       PARAMETER          ( REALONE = 1.0D0 )
  166:       DOUBLE PRECISION   NEGONE, ONE, PIOVER2, ZERO
  167:       PARAMETER          ( NEGONE = -1.0D0, ONE = 1.0D0,
  168:      $                     PIOVER2 = 1.57079632679489662D0,
  169:      $                     ZERO = 0.0D0 )
  170: *     ..
  171: *     .. Local Scalars ..
  172:       CHARACTER          TRANST, SIGNST
  173:       INTEGER            CHILDINFO, I, IB11D, IB11E, IB12D, IB12E,
  174:      $                   IB21D, IB21E, IB22D, IB22E, IBBCSD, IORBDB,
  175:      $                   IORGLQ, IORGQR, IPHI, ITAUP1, ITAUP2, ITAUQ1,
  176:      $                   ITAUQ2, J, LBBCSDWORK, LBBCSDWORKMIN,
  177:      $                   LBBCSDWORKOPT, LORBDBWORK, LORBDBWORKMIN,
  178:      $                   LORBDBWORKOPT, LORGLQWORK, LORGLQWORKMIN,
  179:      $                   LORGLQWORKOPT, LORGQRWORK, LORGQRWORKMIN,
  180:      $                   LORGQRWORKOPT, LWORKMIN, LWORKOPT
  181:       LOGICAL            COLMAJOR, DEFAULTSIGNS, LQUERY, WANTU1, WANTU2,
  182:      $                   WANTV1T, WANTV2T
  183: *     ..
  184: *     .. External Subroutines ..
  185:       EXTERNAL           DBBCSD, DLACPY, DLAPMR, DLAPMT, DLASCL, DLASET,
  186:      $                   DORBDB, DORGLQ, DORGQR, XERBLA
  187: *     ..
  188: *     .. External Functions ..
  189:       LOGICAL            LSAME
  190:       EXTERNAL           LSAME
  191: *     ..
  192: *     .. Intrinsic Functions
  193:       INTRINSIC          COS, INT, MAX, MIN, SIN
  194: *     ..
  195: *     .. Executable Statements ..
  196: *
  197: *     Test input arguments
  198: *
  199:       INFO = 0
  200:       WANTU1 = LSAME( JOBU1, 'Y' )
  201:       WANTU2 = LSAME( JOBU2, 'Y' )
  202:       WANTV1T = LSAME( JOBV1T, 'Y' )
  203:       WANTV2T = LSAME( JOBV2T, 'Y' )
  204:       COLMAJOR = .NOT. LSAME( TRANS, 'T' )
  205:       DEFAULTSIGNS = .NOT. LSAME( SIGNS, 'O' )
  206:       LQUERY = LWORK .EQ. -1
  207:       IF( M .LT. 0 ) THEN
  208:          INFO = -7
  209:       ELSE IF( P .LT. 0 .OR. P .GT. M ) THEN
  210:          INFO = -8
  211:       ELSE IF( Q .LT. 0 .OR. Q .GT. M ) THEN
  212:          INFO = -9
  213:       ELSE IF( ( COLMAJOR .AND. LDX11 .LT. MAX(1,P) ) .OR.
  214:      $         ( .NOT.COLMAJOR .AND. LDX11 .LT. MAX(1,Q) ) ) THEN
  215:          INFO = -11
  216:       ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN
  217:          INFO = -14
  218:       ELSE IF( WANTU2 .AND. LDU2 .LT. M-P ) THEN
  219:          INFO = -16
  220:       ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THEN
  221:          INFO = -18
  222:       ELSE IF( WANTV2T .AND. LDV2T .LT. M-Q ) THEN
  223:          INFO = -20
  224:       END IF
  225: *
  226: *     Work with transpose if convenient
  227: *
  228:       IF( INFO .EQ. 0 .AND. MIN( P, M-P ) .LT. MIN( Q, M-Q ) ) THEN
  229:          IF( COLMAJOR ) THEN
  230:             TRANST = 'T'
  231:          ELSE
  232:             TRANST = 'N'
  233:          END IF
  234:          IF( DEFAULTSIGNS ) THEN
  235:             SIGNST = 'O'
  236:          ELSE
  237:             SIGNST = 'D'
  238:          END IF
  239:          CALL DORCSD( JOBV1T, JOBV2T, JOBU1, JOBU2, TRANST, SIGNST, M,
  240:      $                Q, P, X11, LDX11, X21, LDX21, X12, LDX12, X22,
  241:      $                LDX22, THETA, V1T, LDV1T, V2T, LDV2T, U1, LDU1,
  242:      $                U2, LDU2, WORK, LWORK, IWORK, INFO )
  243:          RETURN
  244:       END IF
  245: *
  246: *     Work with permutation [ 0 I; I 0 ] * X * [ 0 I; I 0 ] if
  247: *     convenient
  248: *
  249:       IF( INFO .EQ. 0 .AND. M-Q .LT. Q ) THEN
  250:          IF( DEFAULTSIGNS ) THEN
  251:             SIGNST = 'O'
  252:          ELSE
  253:             SIGNST = 'D'
  254:          END IF
  255:          CALL DORCSD( JOBU2, JOBU1, JOBV2T, JOBV1T, TRANS, SIGNST, M,
  256:      $                M-P, M-Q, X22, LDX22, X21, LDX21, X12, LDX12, X11,
  257:      $                LDX11, THETA, U2, LDU2, U1, LDU1, V2T, LDV2T, V1T,
  258:      $                LDV1T, WORK, LWORK, IWORK, INFO )
  259:          RETURN
  260:       END IF
  261: *
  262: *     Compute workspace
  263: *
  264:       IF( INFO .EQ. 0 ) THEN
  265: *
  266:          IPHI = 2
  267:          ITAUP1 = IPHI + MAX( 1, Q - 1 )
  268:          ITAUP2 = ITAUP1 + MAX( 1, P )
  269:          ITAUQ1 = ITAUP2 + MAX( 1, M - P )
  270:          ITAUQ2 = ITAUQ1 + MAX( 1, Q )
  271:          IORGQR = ITAUQ2 + MAX( 1, M - Q )
  272:          CALL DORGQR( M-Q, M-Q, M-Q, 0, MAX(1,M-Q), 0, WORK, -1,
  273:      $                CHILDINFO )
  274:          LORGQRWORKOPT = INT( WORK(1) )
  275:          LORGQRWORKMIN = MAX( 1, M - Q )
  276:          IORGLQ = ITAUQ2 + MAX( 1, M - Q )
  277:          CALL DORGLQ( M-Q, M-Q, M-Q, 0, MAX(1,M-Q), 0, WORK, -1,
  278:      $                CHILDINFO )
  279:          LORGLQWORKOPT = INT( WORK(1) )
  280:          LORGLQWORKMIN = MAX( 1, M - Q )
  281:          IORBDB = ITAUQ2 + MAX( 1, M - Q )
  282:          CALL DORBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12,
  283:      $                X21, LDX21, X22, LDX22, 0, 0, 0, 0, 0, 0, WORK,
  284:      $                -1, CHILDINFO )
  285:          LORBDBWORKOPT = INT( WORK(1) )
  286:          LORBDBWORKMIN = LORBDBWORKOPT
  287:          IB11D = ITAUQ2 + MAX( 1, M - Q )
  288:          IB11E = IB11D + MAX( 1, Q )
  289:          IB12D = IB11E + MAX( 1, Q - 1 )
  290:          IB12E = IB12D + MAX( 1, Q )
  291:          IB21D = IB12E + MAX( 1, Q - 1 )
  292:          IB21E = IB21D + MAX( 1, Q )
  293:          IB22D = IB21E + MAX( 1, Q - 1 )
  294:          IB22E = IB22D + MAX( 1, Q )
  295:          IBBCSD = IB22E + MAX( 1, Q - 1 )
  296:          CALL DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, 0,
  297:      $                0, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T, 0,
  298:      $                0, 0, 0, 0, 0, 0, 0, WORK, -1, CHILDINFO )
  299:          LBBCSDWORKOPT = INT( WORK(1) )
  300:          LBBCSDWORKMIN = LBBCSDWORKOPT
  301:          LWORKOPT = MAX( IORGQR + LORGQRWORKOPT, IORGLQ + LORGLQWORKOPT,
  302:      $              IORBDB + LORBDBWORKOPT, IBBCSD + LBBCSDWORKOPT ) - 1
  303:          LWORKMIN = MAX( IORGQR + LORGQRWORKMIN, IORGLQ + LORGLQWORKMIN,
  304:      $              IORBDB + LORBDBWORKOPT, IBBCSD + LBBCSDWORKMIN ) - 1
  305:          WORK(1) = LWORKOPT
  306: *
  307:          IF( LWORK .LT. LWORKMIN .AND. .NOT. LQUERY ) THEN
  308:             INFO = -22
  309:          ELSE
  310:             LORGQRWORK = LWORK - IORGQR + 1
  311:             LORGLQWORK = LWORK - IORGLQ + 1
  312:             LORBDBWORK = LWORK - IORBDB + 1
  313:             LBBCSDWORK = LWORK - IBBCSD + 1
  314:          END IF
  315:       END IF
  316: *
  317: *     Abort if any illegal arguments
  318: *
  319:       IF( INFO .NE. 0 ) THEN
  320:          CALL XERBLA( 'DORCSD', -INFO )
  321:          RETURN
  322:       ELSE IF( LQUERY ) THEN
  323:          RETURN
  324:       END IF
  325: *
  326: *     Transform to bidiagonal block form
  327: *
  328:       CALL DORBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12, X21,
  329:      $             LDX21, X22, LDX22, THETA, WORK(IPHI), WORK(ITAUP1),
  330:      $             WORK(ITAUP2), WORK(ITAUQ1), WORK(ITAUQ2),
  331:      $             WORK(IORBDB), LORBDBWORK, CHILDINFO )
  332: *
  333: *     Accumulate Householder reflectors
  334: *
  335:       IF( COLMAJOR ) THEN
  336:          IF( WANTU1 .AND. P .GT. 0 ) THEN
  337:             CALL DLACPY( 'L', P, Q, X11, LDX11, U1, LDU1 )
  338:             CALL DORGQR( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGQR),
  339:      $                   LORGQRWORK, INFO)
  340:          END IF
  341:          IF( WANTU2 .AND. M-P .GT. 0 ) THEN
  342:             CALL DLACPY( 'L', M-P, Q, X21, LDX21, U2, LDU2 )
  343:             CALL DORGQR( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2),
  344:      $                   WORK(IORGQR), LORGQRWORK, INFO )
  345:          END IF
  346:          IF( WANTV1T .AND. Q .GT. 0 ) THEN
  347:             CALL DLACPY( 'U', Q-1, Q-1, X11(1,2), LDX11, V1T(2,2),
  348:      $                   LDV1T )
  349:             V1T(1, 1) = ONE
  350:             DO J = 2, Q
  351:                V1T(1,J) = ZERO
  352:                V1T(J,1) = ZERO
  353:             END DO
  354:             CALL DORGLQ( Q-1, Q-1, Q-1, V1T(2,2), LDV1T, WORK(ITAUQ1),
  355:      $                   WORK(IORGLQ), LORGLQWORK, INFO )
  356:          END IF
  357:          IF( WANTV2T .AND. M-Q .GT. 0 ) THEN
  358:             CALL DLACPY( 'U', P, M-Q, X12, LDX12, V2T, LDV2T )
  359:             CALL DLACPY( 'U', M-P-Q, M-P-Q, X22(Q+1,P+1), LDX22,
  360:      $                   V2T(P+1,P+1), LDV2T )
  361:             CALL DORGLQ( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2),
  362:      $                   WORK(IORGLQ), LORGLQWORK, INFO )
  363:          END IF
  364:       ELSE
  365:          IF( WANTU1 .AND. P .GT. 0 ) THEN
  366:             CALL DLACPY( 'U', Q, P, X11, LDX11, U1, LDU1 )
  367:             CALL DORGLQ( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGLQ),
  368:      $                   LORGLQWORK, INFO)
  369:          END IF
  370:          IF( WANTU2 .AND. M-P .GT. 0 ) THEN
  371:             CALL DLACPY( 'U', Q, M-P, X21, LDX21, U2, LDU2 )
  372:             CALL DORGLQ( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2),
  373:      $                   WORK(IORGLQ), LORGLQWORK, INFO )
  374:          END IF
  375:          IF( WANTV1T .AND. Q .GT. 0 ) THEN
  376:             CALL DLACPY( 'L', Q-1, Q-1, X11(2,1), LDX11, V1T(2,2),
  377:      $                   LDV1T )
  378:             V1T(1, 1) = ONE
  379:             DO J = 2, Q
  380:                V1T(1,J) = ZERO
  381:                V1T(J,1) = ZERO
  382:             END DO
  383:             CALL DORGQR( Q-1, Q-1, Q-1, V1T(2,2), LDV1T, WORK(ITAUQ1),
  384:      $                   WORK(IORGQR), LORGQRWORK, INFO )
  385:          END IF
  386:          IF( WANTV2T .AND. M-Q .GT. 0 ) THEN
  387:             CALL DLACPY( 'L', M-Q, P, X12, LDX12, V2T, LDV2T )
  388:             CALL DLACPY( 'L', M-P-Q, M-P-Q, X22(P+1,Q+1), LDX22,
  389:      $                   V2T(P+1,P+1), LDV2T )
  390:             CALL DORGQR( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2),
  391:      $                   WORK(IORGQR), LORGQRWORK, INFO )
  392:          END IF
  393:       END IF
  394: *
  395: *     Compute the CSD of the matrix in bidiagonal-block form
  396: *
  397:       CALL DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, THETA,
  398:      $             WORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T, V2T,
  399:      $             LDV2T, WORK(IB11D), WORK(IB11E), WORK(IB12D),
  400:      $             WORK(IB12E), WORK(IB21D), WORK(IB21E), WORK(IB22D),
  401:      $             WORK(IB22E), WORK(IBBCSD), LBBCSDWORK, INFO )
  402: *
  403: *     Permute rows and columns to place identity submatrices in top-
  404: *     left corner of (1,1)-block and/or bottom-right corner of (1,2)-
  405: *     block and/or bottom-right corner of (2,1)-block and/or top-left
  406: *     corner of (2,2)-block 
  407: *
  408:       IF( Q .GT. 0 .AND. WANTU2 ) THEN
  409:          DO I = 1, Q
  410:             IWORK(I) = M - P - Q + I
  411:          END DO
  412:          DO I = Q + 1, M - P
  413:             IWORK(I) = I - Q
  414:          END DO
  415:          IF( COLMAJOR ) THEN
  416:             CALL DLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK )
  417:          ELSE
  418:             CALL DLAPMR( .FALSE., M-P, M-P, U2, LDU2, IWORK )
  419:          END IF
  420:       END IF
  421:       IF( M .GT. 0 .AND. WANTV2T ) THEN
  422:          DO I = 1, P
  423:             IWORK(I) = M - P - Q + I
  424:          END DO
  425:          DO I = P + 1, M - Q
  426:             IWORK(I) = I - P
  427:          END DO
  428:          IF( .NOT. COLMAJOR ) THEN
  429:             CALL DLAPMT( .FALSE., M-Q, M-Q, V2T, LDV2T, IWORK )
  430:          ELSE
  431:             CALL DLAPMR( .FALSE., M-Q, M-Q, V2T, LDV2T, IWORK )
  432:          END IF
  433:       END IF
  434: *
  435:       RETURN
  436: *
  437: *     End DORCSD
  438: *
  439:       END
  440: 

CVSweb interface <joel.bertrand@systella.fr>