SUBROUTINE CSCQR( M, N, A, LDA, R, LDR, WORK, WORK2, INFO ) IMPLICIT NONE INTEGER M, N, LDA, LDR COMPLEX A( LDA, * ), R( LDR, N ), WORK( N, * ) REAL WORK2( * ) COMPLEX CONE, CZERO PARAMETER ( CONE=(1.0E+0,0.0E+0), CZERO=(0.0E+0,0.0E+0) ) LOGICAL FLAG2 INTEGER COUNT, INFO, I, J COUNT = 0 10 COUNT = COUNT + 1 CALL CRQRCQR( M, N, A, LDA, WORK(1,1), WORK(1,N+1), $ WORK(1,2*N+1), WORK2, FLAG2, INFO ) IF (INFO .EQ. -1) THEN INFO = COUNT RETURN ENDIF IF (COUNT .EQ. 1) THEN DO I = 1, N CALL CCOPY(I,WORK(1,N+I),1,R(1,I),1) DO J = I+1, N R(J, I) = CZERO ENDDO ENDDO ELSE CALL CTRMM('L','U','N','N',N,N,CONE,WORK(1,N+1),N,R,LDR) ENDIF IF (FLAG2 .EQV. .FALSE.) GO TO 10 RETURN END SUBROUTINE CSCQR * SUBROUTINE CSCQRH( COUNT, M, N, A, LDA, R, LDR, WORK, WORK2, $ INFO ) IMPLICIT NONE INTEGER COUNT, M, N, LDA, LDR COMPLEX A( LDA, * ), R( 5, LDR, N ), WORK( N, * ) REAL WORK2( * ) COMPLEX CZERO PARAMETER ( CZERO=(0.0E+0,0.0E+0) ) LOGICAL FLAG2 INTEGER INFO, I, J COUNT = 0 10 COUNT = COUNT + 1 IF (COUNT .EQ. 6) THEN INFO = COUNT RETURN ENDIF CALL CRQRCQR( M, N, A, LDA, WORK(1,1), WORK(1,N+1), $ WORK(1,2*N+1), WORK2, FLAG2, INFO ) IF (INFO .EQ. -1) RETURN DO I = 1, N CALL CCOPY(I,WORK(1,N+I),1,R(COUNT,1,I),1) DO J = I+1, N R(COUNT, J, I) = CZERO ENDDO ENDDO IF (FLAG2 .EQV. .FALSE.) GO TO 10 RETURN END SUBROUTINE CSCQRH * SUBROUTINE CRQRCQR( M, N, Q, LDQ, WORK, WORK2, WORK3, $ WORK4, FLAG2, INFO ) * IMPLICIT NONE * * .. Scalar Arguments .. INTEGER M, N, LDQ, INFO LOGICAL FLAG2 * .. * .. Array Arguments .. COMPLEX Q( LDQ, * ), WORK( N, N ), WORK2( N, N ), $ WORK3( * ) REAL WORK4( * ) * * ===================================================================== * * .. parameters .. REAL STWO, SONE, SZERO PARAMETER ( STWO=2.0E+0, SONE=1.0E+0, SZERO=0.0E+0 ) COMPLEX CONE, CZERO PARAMETER ( CONE=(1.0E+0,0.0E+0), CZERO=(0.0E+0,0.0E+0) ) * .. * .. local scalars .. INTEGER IINFO, K, I, J, I0 REAL SHIFT, EPS, SLAMCH, TMP, OF, SCNRM2 COMPLEX CDOTC * .. * .. external functions .. EXTERNAL CHERK, CPOTRF, SLAMCH, SCNRM2, CDOTC INTRINSIC REAL * .. * .. Executable Statements .. * EPS = SLAMCH( 'Precision' ) OF = SLAMCH( 'O' ) * CALL CHERK('U','C',N,M,SONE,Q,LDQ,SZERO,WORK,N) DO K = 1, N IF (REAL(WORK(K,K)) .GT. OF .OR. $ REAL(WORK(K,K)) .EQ. SZERO) THEN GO TO 10 ENDIF END DO * SHIFT = SZERO I0 = 0 * DO K = 1, 2*N DO I = 1, N CALL CCOPY(I,WORK(1,I),1,WORK2(1,I),1) ENDDO IF (SHIFT .NE. SZERO) THEN DO I = 1, N WORK2(I,I) = WORK2(I,I) + SHIFT ENDDO ENDIF CALL CPOTRF('U',N,WORK2,N,IINFO) IF (IINFO .EQ. 0) THEN IF (SHIFT .EQ. SZERO) THEN CALL CTRCON('I','U','N',N,WORK2,N,TMP,WORK3, $ WORK4(N+1),IINFO) IF (SQRT(SQRT(SQRT(EPS))) .GT. TMP) THEN FLAG2 = .FALSE. ELSE FLAG2 = .TRUE. END IF ELSE FLAG2 = .FALSE. END IF * CALL CTRSM('R','U','N','N',M,N,CONE,WORK2,N,Q,LDQ) INFO = 0 RETURN * ELSE IF (I0 .EQ. IINFO) THEN SHIFT = STWO*SHIFT ELSE I0 = IINFO TMP=SHIFT-REAL(WORK2(IINFO,IINFO)) IF (TMP .NE. SHIFT) THEN SHIFT=TMP ELSE IF (SHIFT .EQ. SZERO) THEN TMP = SZERO DO I=1,N TMP = MAX(TMP,REAL(WORK(I,I))) ENDDO SHIFT=EPS*TMP ELSE SHIFT=(SONE+EPS)*SHIFT ENDIF ENDIF ENDIF WRITE (*,*) 'S',I0,SHIFT ENDIF ENDDO * INFO = -1 RETURN 10 DO K = 1, N WORK4(K) = SCNRM2( M, Q( 1, K ), 1 ) CALL CSSCAL( M, SONE/WORK4(K), Q( 1, K ), 1 ) END DO CALL CHERK('U','C',N,M,SONE,Q,LDQ,SZERO,WORK,N) * SHIFT = SZERO I0 = 0 * DO K = 1, 2*N DO I = 1, N CALL CCOPY(I,WORK(1,I),1,WORK2(1,I),1) ENDDO IF (SHIFT .NE. SZERO) THEN DO I = 1, N WORK2(I,I) = WORK2(I,I) + SHIFT ENDDO ENDIF CALL CPOTRF('U',N,WORK2,N,IINFO) IF (IINFO .EQ. 0) THEN IF (SHIFT .EQ. SZERO) THEN CALL CTRCON('I','U','N',N,WORK2,N,TMP,WORK3, $ WORK4(N+1),IINFO) IF (SQRT(SQRT(SQRT(EPS))) .GT. TMP) THEN FLAG2 = .FALSE. ELSE FLAG2 = .TRUE. END IF ELSE FLAG2 = .FALSE. END IF * CALL CTRSM('R','U','N','N',M,N,CONE,WORK2,N,Q,LDQ) DO I = 1, N CALL CSSCAL( I, WORK4(I), WORK2( 1, I ), 1 ) END DO INFO = 0 RETURN * ELSE IF (I0 .EQ. IINFO) THEN SHIFT = STWO*SHIFT ELSE I0 = IINFO TMP=SHIFT-REAL(WORK2(IINFO,IINFO)) IF (TMP .NE. SHIFT) THEN SHIFT=TMP ELSE IF (SHIFT .EQ. SZERO) THEN SHIFT=EPS ELSE SHIFT=(SONE+EPS)*SHIFT ENDIF ENDIF ENDIF WRITE (*,*) 'S',I0,SHIFT ENDIF ENDDO * INFO = -1 RETURN * END SUBROUTINE CRQRCQR