@@ -350,11 +350,10 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
350350*
351351* .. Local Scalars ..
352352 LOGICAL WANTU1, WANTU2, WANTX, LQUERY
353- INTEGER I, J, K, K1, LMAX, Z, LDG, LDX, LDVT, LWKOPT
353+ INTEGER I, J, K, K1, LMAX, IG, IG11, IG21, IG22,
354+ $ IVT, IVT12, LDG, LDX, LDVT, LWKOPT
354355 DOUBLE PRECISION BASE, NAN, NORMA, NORMB, NORMG, TOL, ULP, UNFL,
355356 $ THETA, IOTA, W
356- * .. Local Arrays ..
357- DOUBLE PRECISION G( M + P, N ), VT( N, N )
358357* ..
359358* .. External Functions ..
360359 LOGICAL LSAME
@@ -438,12 +437,15 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
438437*
439438 SWAPPED = .FALSE.
440439 L = 0
441- LMAX = MIN ( M + P, N )
442- Z = ( M + P ) * N
443- G = WORK( 1 )
444440 LDG = M + P
445- VT = 0
446441 LDVT = N
442+ LMAX = MIN ( M + P, N )
443+ IG = 1
444+ IG11 = 1
445+ IG21 = M + 1
446+ IG22 = LDG * M + M + 1
447+ IVT = LDG * N + 2
448+ IVT12 = IVT + LDVT * M
447449 THETA = NAN
448450 IOTA = NAN
449451 W = NAN
@@ -453,21 +455,23 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
453455 IF ( INFO.EQ. 0 ) THEN
454456 LWKOPT = 0
455457*
456- CALL DGEQP3( M+ P, N, G, LDG, IWORK, ALPHA, WORK, - 1 , INFO )
458+ CALL DGEQP3( M + P, N, WORK( IG ), LDG, IWORK, ALPHA, WORK, - 1 ,
459+ $ INFO )
457460 LWKOPT = MAX ( LWKOPT, INT ( WORK( 1 ) ) )
458461 LWKOPT = INT ( WORK( 1 ) )
459462*
460- CALL DORGQR( M + P, LMAX, LMAX, G, LDG, ALPHA, WORK, - 1 , INFO )
463+ CALL DORGQR( M + P, LMAX, LMAX, WORK( IG ), LDG, ALPHA, WORK,
464+ $ - 1 , INFO )
461465 LWKOPT = MAX ( LWKOPT, INT ( WORK( 1 ) ) )
462466*
463467 CALL DORCSD2BY1( JOBU1, JOBU2, JOBX, M + P, M, LMAX,
464- $ G , LDG, G , LDG,
468+ $ WORK( IG ) , LDG, WORK( IG ) , LDG,
465469 $ ALPHA,
466- $ U1, LDU1, U2, LDU2, VT , LDVT,
470+ $ U1, LDU1, U2, LDU2, WORK( IVT ) , LDVT,
467471 $ WORK, - 1 , IWORK, INFO )
468472 LWKOPT = MAX ( LWKOPT, INT ( WORK( 1 ) ) )
469473* The matrix (A, B) must be stored sequentially for DORGQR
470- LWKOPT = LWKOPT + Z
474+ LWKOPT = LWKOPT + IVT
471475* 2-by-1 CSD matrix V1 must be stored
472476 IF ( WANTX ) THEN
473477 LWKOPT = LWKOPT + LDVT* N
@@ -484,9 +488,7 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
484488 RETURN
485489 ENDIF
486490* Finish initialization
487- IF ( WANTX ) THEN
488- VT = WORK( Z + 1 )
489- ELSE
491+ IF ( .NOT. WANTX ) THEN
490492 LDVT = 0
491493 END IF
492494*
@@ -506,8 +508,8 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
506508*
507509* Copy matrices A, B into the (M+P) x N matrix G
508510*
509- CALL DLACPY( ' A' , M, N, A, LDA, G( 1 , 1 ), LDG )
510- CALL DLACPY( ' A' , P, N, B, LDB, G( M + 1 , 1 ), LDG )
511+ CALL DLACPY( ' A' , M, N, A, LDA, WORK( IG11 ), LDG )
512+ CALL DLACPY( ' A' , P, N, B, LDB, WORK( IG21 ), LDG )
511513*
512514* DEBUG
513515*
@@ -533,16 +535,16 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
533535*
534536* Compute the QR factorization with column pivoting GΠ = Q1 R1
535537*
536- CALL DGEQP3( M + P, N, G , LDG, IWORK, ALPHA,
537- $ WORK( Z + 1 ), LWORK - Z , INFO )
538+ CALL DGEQP3( M + P, N, WORK( IG ) , LDG, IWORK, ALPHA,
539+ $ WORK( IVT ), LWORK - IVT + 1 , INFO )
538540 IF ( INFO.NE. 0 ) THEN
539541 RETURN
540542 END IF
541543*
542544* Determine the rank of G
543545*
544546 DO I = 1 , MIN ( M + P, N )
545- IF ( ABS ( G( I, I ) ).LE. TOL ) THEN
547+ IF ( ABS ( WORK( (I -1 ) * LDG + I ) ).LE. TOL ) THEN
546548 EXIT
547549 END IF
548550 L = L + 1
@@ -566,11 +568,11 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
566568*
567569 IF ( WANTX ) THEN
568570 IF ( L.LE. M ) THEN
569- CALL DLACPY( ' U' , L, N, G , LDG, A, LDA )
571+ CALL DLACPY( ' U' , L, N, WORK( IG ) , LDG, A, LDA )
570572 CALL DLASET( ' L' , L - 1 , N, 0.0D0 , 0.0D0 , A( 2 , 1 ), LDA )
571573 ELSE
572- CALL DLACPY( ' U' , M, N, G , LDG, A, LDA )
573- CALL DLACPY( ' U' , L - M, N - M, G( M +1 ,M +1 ), LDG, B, LDB )
574+ CALL DLACPY( ' U' , M, N, WORK( IG ) , LDG, A, LDA )
575+ CALL DLACPY( ' U' , L - M, N - M, WORK( IG22 ), LDG, B, LDB )
574576*
575577 CALL DLASET( ' L' , M - 1 , N, 0.0D0 , 0.0D0 , A( 2 , 1 ), LDA )
576578 CALL DLASET( ' L' , L- M-1 , N, 0.0D0 , 0.0D0 , B( 2 , 1 ), LDB )
@@ -579,8 +581,8 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
579581*
580582* Explicitly form Q1 so that we can compute the CS decomposition
581583*
582- CALL DORGQR( M + P, L, L, G , LDG, ALPHA,
583- $ WORK( Z + 1 ), LWORK - Z , INFO )
584+ CALL DORGQR( M + P, L, L, WORK( IG ) , LDG, ALPHA,
585+ $ WORK( IVT ), LWORK - IVT + 1 , INFO )
584586 IF ( INFO.NE. 0 ) THEN
585587 RETURN
586588 END IF
@@ -595,10 +597,10 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
595597 K = MIN ( M, P, L, M + P - L )
596598 K1 = MAX ( L - P, 0 )
597599 CALL DORCSD2BY1( JOBU1, JOBU2, JOBX, M + P, M, L,
598- $ G( 1 , 1 ), LDG, G( M + 1 , 1 ), LDG,
600+ $ WORK( IG11 ), LDG, WORK( IG21 ), LDG,
599601 $ ALPHA,
600- $ U1, LDU1, U2, LDU2, VT , LDVT,
601- $ WORK( Z + LDVT* N + 1 ), LWORK - Z - LDVT* N,
602+ $ U1, LDU1, U2, LDU2, WORK( IVT ) , LDVT,
603+ $ WORK( IVT + LDVT* N ), LWORK - IVT - LDVT* N + 1 ,
602604 $ IWORK( N + 1 ), INFO )
603605 IF ( INFO.NE. 0 ) THEN
604606 RETURN
@@ -614,14 +616,14 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
614616 LDX = L
615617 IF ( L.LE. M ) THEN
616618 CALL DGEMM( ' N' , ' N' , L, N, L,
617- $ 1.0D0 , VT , LDVT, A, LDA,
619+ $ 1.0D0 , WORK( IVT ) , LDVT, A, LDA,
618620 $ 0.0D0 , WORK( 2 ), LDX )
619621 ELSE
620622 CALL DGEMM( ' N' , ' N' , L, N, M,
621- $ 1.0D0 , VT( 1 , 1 ), LDVT, A, LDA,
623+ $ 1.0D0 , WORK( IVT ), LDVT, A, LDA,
622624 $ 0.0D0 , WORK( 2 ), LDX )
623625 CALL DGEMM( ' N' , ' N' , L, N - M, L - M,
624- $ 1.0D0 , VT( 1 , M + 1 ), LDVT, B, LDB,
626+ $ 1.0D0 , WORK( IVT12 ), LDVT, B, LDB,
625627 $ 1.0D0 , WORK( L* M + 2 ), LDX )
626628 END IF
627629* Revert column permutation Π by permuting the columns of X
@@ -640,7 +642,7 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
640642 ALPHA( I ) = 0.0D0
641643 BETA( I ) = 1.0D0
642644 IF ( WANTX ) THEN
643- WORK( Z + I + 1 ) = 1.0D0
645+ WORK( IVT + I ) = 1.0D0
644646 END IF
645647 ELSE
646648* iota comes in the greek alphabet after theta
@@ -651,13 +653,13 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
651653 ALPHA( I ) = ( SIN ( IOTA ) / TAN ( THETA ) ) / W
652654 BETA( I ) = SIN ( IOTA )
653655 IF ( WANTX ) THEN
654- WORK( Z + I + 1 ) = SIN ( THETA ) / SIN ( IOTA )
656+ WORK( IVT + I ) = SIN ( THETA ) / SIN ( IOTA )
655657 END IF
656658 ELSE
657659 ALPHA( I ) = COS ( IOTA )
658660 BETA( I ) = SIN ( IOTA )
659661 IF ( WANTX ) THEN
660- WORK( Z + I + 1 ) = COS ( THETA ) / COS ( IOTA ) / W
662+ WORK( IVT + I ) = COS ( THETA ) / COS ( IOTA ) / W
661663 END IF
662664 END IF
663665 END IF
@@ -670,7 +672,7 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
670672 END DO
671673 DO I = 1 , K
672674 WORK( LDX* J + I + K1 + 1 ) =
673- $ WORK( LDX* J + I + K1 + 1 ) * WORK( Z + I + 1 )
675+ $ WORK( LDX* J + I + K1 + 1 ) * WORK( IVT + I )
674676 END DO
675677 END DO
676678 END IF
0 commit comments