SUBROUTINE SSCLQ( M, N, A, LDA, L, LDL, WORK, IWORK, INFO ) IMPLICIT NONE INTEGER M, N, LDA, LDL, IWORK( * ) REAL A( LDA, * ), L( LDL, M ), WORK( M, * ) REAL ONE, ZERO PARAMETER ( ONE=1.0E+0, ZERO=0.0E+0 ) LOGICAL FLAG2 INTEGER COUNT, INFO, I, J COUNT = 0 10 COUNT = COUNT + 1 CALL SRLQCQR( COUNT, M, N, A, LDA, WORK(1,1), WORK(1,M+1), $ WORK(1,2*M+1), IWORK, FLAG2, INFO ) IF (INFO .EQ. -1) THEN INFO = COUNT RETURN ENDIF IF (COUNT .EQ. 1) THEN !$OMP PARALLEL DO PRIVATE(J) DO I = 1, M DO J = 1, I-1 L(J, I) = ZERO ENDDO CALL SCOPY(M-(I-1),WORK(I,M+I),1,L(I,I),1) ENDDO !$OMP END PARALLEL DO ELSE CALL STRMM('R','L','N','N',M,M,ONE,WORK(1,M+1),M,L,LDL) ENDIF IF (FLAG2 .EQV. .FALSE.) GO TO 10 RETURN END SUBROUTINE SSCLQ * SUBROUTINE SRLQCQR( COUNT, M, N, Q, LDQ, WORK, WORK2, WORK3, $ IWORK, FLAG2, INFO ) * IMPLICIT NONE * * .. Scalar Arguments .. INTEGER COUNT, M, N, LDQ, INFO, IWORK( * ) LOGICAL FLAG2 * .. * .. Array Arguments .. REAL Q( LDQ, * ), WORK( M, M ), WORK2( M, M ), $ WORK3( * ) * * ===================================================================== * * .. parameters .. REAL TWO, ONE, ZERO PARAMETER ( TWO=2.0E+0, ONE=1.0E+0, ZERO=0.0E+0 ) * .. * .. local scalars .. INTEGER IINFO, K, I, J, I0 REAL SHIFT, EPS, SLAMCH, TMP, OF, SNRM2, SDOT * .. * .. external functions .. EXTERNAL SSYRK, SPOTRF, SLAMCH, SNRM2, SDOT * .. * .. Executable Statements .. * INFO = 0 EPS = SLAMCH( 'Precision' ) OF = SLAMCH( 'O' ) I0 = 0 * FLAG2 = .TRUE. IF (COUNT .GE. 2) GO TO 10 !$OMP PARALLEL DO PRIVATE(TMP) DO K = 1, M TMP = SDOT( N, Q( K, 1 ), LDQ, Q( K, 1 ), LDQ) IF (TMP .GT. OF .OR. TMP .EQ. ZERO) THEN FLAG2 = .FALSE. ENDIF END DO !$OMP END PARALLEL DO * 10 IF (FLAG2) THEN CALL SSYRK('L','N',M,N,ONE,Q,LDQ,ZERO,WORK,M) * DO I = 1, M WORK3(I) = SQRT(WORK(I,I)) WORK3(M+I) = ONE/WORK3(I) ENDDO !$OMP PARALLEL DO PRIVATE(J) DO I = 1, M DO J = I, M WORK(J, I) = WORK(J, I)*WORK3(M+I)*WORK3(M+J) END DO END DO !$OMP END PARALLEL DO * SHIFT = ZERO * DO K = 1, 2*M !$OMP PARALLEL DO DO I = 1, M CALL SCOPY(M+1-I,WORK(I,I),1,WORK2(I,I),1) ENDDO !$OMP END PARALLEL DO IF (SHIFT .NE. ZERO) THEN DO I = 1, M WORK2(I,I) = WORK2(I,I) + SHIFT ENDDO ENDIF IINFO=0 CALL SPOTRF('L',M,WORK2,M,IINFO) IF (IINFO .EQ. 0) THEN IF (SHIFT .EQ. ZERO) THEN CALL STRCON('I','L','N',M,WORK2,M,TMP,WORK3(M+1), $ IWORK,IINFO) IF (SQRT(SQRT(SQRT(EPS))) .GT. TMP) THEN FLAG2 = .FALSE. ELSE FLAG2 = .TRUE. END IF ELSE FLAG2 = .FALSE. END IF * !$OMP PARALLEL DO PRIVATE(J) DO I = 1, M DO J = I, M WORK2( J, I ) = WORK2( J, I )*WORK3(J) END DO END DO !$OMP END PARALLEL DO CALL STRSM('L','L','N','N',M,N,ONE,WORK2,M,Q,LDQ) RETURN * ENDIF IF (I0 .EQ. IINFO) THEN SHIFT = TWO*SHIFT ELSE I0 = IINFO TMP=SHIFT-WORK2(IINFO,IINFO) IF (TMP .NE. SHIFT) THEN SHIFT=TMP ELSE IF (SHIFT .EQ. ZERO) THEN SHIFT=EPS ELSE SHIFT=(ONE+EPS)*SHIFT ENDIF ENDIF ENDIF WRITE (*,*) 'O',I0,SHIFT ENDDO * INFO = -1 RETURN * ELSE !$OMP PARALLEL DO DO K = 1, M WORK3(K) = SNRM2( N, Q( K, 1 ), LDQ ) CALL SSCAL( N, ONE/WORK3(K), Q( K, 1 ), LDQ ) END DO !$OMP END PARALLEL DO * CALL SSYRK('L','N',M,N,ONE,Q,LDQ,ZERO,WORK,M) * SHIFT = ZERO * DO K = 1, 2*M !$OMP PARALLEL DO DO I = 1, M CALL SCOPY(M+1-I,WORK(I,I),1,WORK2(I,I),1) ENDDO !$OMP END PARALLEL DO IF (SHIFT .NE. ZERO) THEN DO I = 1, M WORK2(I,I) = WORK2(I,I) + SHIFT ENDDO ENDIF IINFO=0 CALL SPOTRF('L',M,WORK2,M,IINFO) IF (IINFO .EQ. 0) THEN IF (SHIFT .EQ. ZERO) THEN CALL STRCON('I','L','N',M,WORK2,M,TMP,WORK3(M+1), $ IWORK,IINFO) IF (SQRT(SQRT(SQRT(EPS))) .GT. TMP) THEN FLAG2 = .FALSE. ELSE FLAG2 = .TRUE. END IF ELSE FLAG2 = .FALSE. END IF * CALL STRSM('L','L','N','N',M,N,ONE,WORK2,M,Q,LDQ) !$OMP PARALLEL DO PRIVATE(J) DO I = 1, M DO J = I, M WORK2( J, I ) = WORK2( J, I )*WORK3(J) END DO END DO !$OMP END PARALLEL DO RETURN * ENDIF IF (I0 .EQ. IINFO) THEN SHIFT = TWO*SHIFT ELSE I0 = IINFO TMP=SHIFT-WORK2(IINFO,IINFO) IF (TMP .NE. SHIFT) THEN SHIFT=TMP ELSE IF (SHIFT .EQ. ZERO) THEN SHIFT=EPS ELSE SHIFT=(ONE+EPS)*SHIFT ENDIF ENDIF ENDIF WRITE (*,*) 'O',I0,SHIFT ENDDO * INFO = -1 RETURN * ENDIF * END SUBROUTINE SRLQCQR