@@ -350,11 +350,10 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
350
350
*
351
351
* .. Local Scalars ..
352
352
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
354
355
DOUBLE PRECISION BASE, NAN, NORMA, NORMB, NORMG, TOL, ULP, UNFL,
355
356
$ THETA, IOTA, W
356
- * .. Local Arrays ..
357
- DOUBLE PRECISION G( M + P, N ), VT( N, N )
358
357
* ..
359
358
* .. External Functions ..
360
359
LOGICAL LSAME
@@ -438,12 +437,15 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
438
437
*
439
438
SWAPPED = .FALSE.
440
439
L = 0
441
- LMAX = MIN ( M + P, N )
442
- Z = ( M + P ) * N
443
- G = WORK( 1 )
444
440
LDG = M + P
445
- VT = 0
446
441
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
447
449
THETA = NAN
448
450
IOTA = NAN
449
451
W = NAN
@@ -453,21 +455,23 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
453
455
IF ( INFO.EQ. 0 ) THEN
454
456
LWKOPT = 0
455
457
*
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 )
457
460
LWKOPT = MAX ( LWKOPT, INT ( WORK( 1 ) ) )
458
461
LWKOPT = INT ( WORK( 1 ) )
459
462
*
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 )
461
465
LWKOPT = MAX ( LWKOPT, INT ( WORK( 1 ) ) )
462
466
*
463
467
CALL DORCSD2BY1( JOBU1, JOBU2, JOBX, M + P, M, LMAX,
464
- $ G , LDG, G , LDG,
468
+ $ WORK( IG ) , LDG, WORK( IG ) , LDG,
465
469
$ ALPHA,
466
- $ U1, LDU1, U2, LDU2, VT , LDVT,
470
+ $ U1, LDU1, U2, LDU2, WORK( IVT ) , LDVT,
467
471
$ WORK, - 1 , IWORK, INFO )
468
472
LWKOPT = MAX ( LWKOPT, INT ( WORK( 1 ) ) )
469
473
* The matrix (A, B) must be stored sequentially for DORGQR
470
- LWKOPT = LWKOPT + Z
474
+ LWKOPT = LWKOPT + IVT
471
475
* 2-by-1 CSD matrix V1 must be stored
472
476
IF ( WANTX ) THEN
473
477
LWKOPT = LWKOPT + LDVT* N
@@ -484,9 +488,7 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
484
488
RETURN
485
489
ENDIF
486
490
* Finish initialization
487
- IF ( WANTX ) THEN
488
- VT = WORK( Z + 1 )
489
- ELSE
491
+ IF ( .NOT. WANTX ) THEN
490
492
LDVT = 0
491
493
END IF
492
494
*
@@ -506,8 +508,8 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
506
508
*
507
509
* Copy matrices A, B into the (M+P) x N matrix G
508
510
*
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 )
511
513
*
512
514
* DEBUG
513
515
*
@@ -533,16 +535,16 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
533
535
*
534
536
* Compute the QR factorization with column pivoting GΠ = Q1 R1
535
537
*
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 )
538
540
IF ( INFO.NE. 0 ) THEN
539
541
RETURN
540
542
END IF
541
543
*
542
544
* Determine the rank of G
543
545
*
544
546
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
546
548
EXIT
547
549
END IF
548
550
L = L + 1
@@ -566,11 +568,11 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
566
568
*
567
569
IF ( WANTX ) THEN
568
570
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 )
570
572
CALL DLASET( ' L' , L - 1 , N, 0.0D0 , 0.0D0 , A( 2 , 1 ), LDA )
571
573
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 )
574
576
*
575
577
CALL DLASET( ' L' , M - 1 , N, 0.0D0 , 0.0D0 , A( 2 , 1 ), LDA )
576
578
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,
579
581
*
580
582
* Explicitly form Q1 so that we can compute the CS decomposition
581
583
*
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 )
584
586
IF ( INFO.NE. 0 ) THEN
585
587
RETURN
586
588
END IF
@@ -595,10 +597,10 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
595
597
K = MIN ( M, P, L, M + P - L )
596
598
K1 = MAX ( L - P, 0 )
597
599
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,
599
601
$ 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 ,
602
604
$ IWORK( N + 1 ), INFO )
603
605
IF ( INFO.NE. 0 ) THEN
604
606
RETURN
@@ -614,14 +616,14 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
614
616
LDX = L
615
617
IF ( L.LE. M ) THEN
616
618
CALL DGEMM( ' N' , ' N' , L, N, L,
617
- $ 1.0D0 , VT , LDVT, A, LDA,
619
+ $ 1.0D0 , WORK( IVT ) , LDVT, A, LDA,
618
620
$ 0.0D0 , WORK( 2 ), LDX )
619
621
ELSE
620
622
CALL DGEMM( ' N' , ' N' , L, N, M,
621
- $ 1.0D0 , VT( 1 , 1 ), LDVT, A, LDA,
623
+ $ 1.0D0 , WORK( IVT ), LDVT, A, LDA,
622
624
$ 0.0D0 , WORK( 2 ), LDX )
623
625
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,
625
627
$ 1.0D0 , WORK( L* M + 2 ), LDX )
626
628
END IF
627
629
* Revert column permutation Π by permuting the columns of X
@@ -640,7 +642,7 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
640
642
ALPHA( I ) = 0.0D0
641
643
BETA( I ) = 1.0D0
642
644
IF ( WANTX ) THEN
643
- WORK( Z + I + 1 ) = 1.0D0
645
+ WORK( IVT + I ) = 1.0D0
644
646
END IF
645
647
ELSE
646
648
* iota comes in the greek alphabet after theta
@@ -651,13 +653,13 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
651
653
ALPHA( I ) = ( SIN ( IOTA ) / TAN ( THETA ) ) / W
652
654
BETA( I ) = SIN ( IOTA )
653
655
IF ( WANTX ) THEN
654
- WORK( Z + I + 1 ) = SIN ( THETA ) / SIN ( IOTA )
656
+ WORK( IVT + I ) = SIN ( THETA ) / SIN ( IOTA )
655
657
END IF
656
658
ELSE
657
659
ALPHA( I ) = COS ( IOTA )
658
660
BETA( I ) = SIN ( IOTA )
659
661
IF ( WANTX ) THEN
660
- WORK( Z + I + 1 ) = COS ( THETA ) / COS ( IOTA ) / W
662
+ WORK( IVT + I ) = COS ( THETA ) / COS ( IOTA ) / W
661
663
END IF
662
664
END IF
663
665
END IF
@@ -670,7 +672,7 @@ RECURSIVE SUBROUTINE DGGQRCS( JOBU1, JOBU2, JOBX, M, N, P, L,
670
672
END DO
671
673
DO I = 1 , K
672
674
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 )
674
676
END DO
675
677
END DO
676
678
END IF
0 commit comments