Fix uninitialized variable (Reference-LAPACK PR647)

This commit is contained in:
Martin Kroeker 2022-11-20 16:36:19 +01:00 committed by GitHub
parent 9e29312c83
commit b946820502
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 74 deletions

View File

@ -41,10 +41,16 @@
*> with respect to the columns of *> with respect to the columns of
*> Q = [ Q1 ] . *> Q = [ Q1 ] .
*> [ Q2 ] *> [ Q2 ]
*> The columns of Q must be orthonormal. *> The Euclidean norm of X must be one and the columns of Q must be
*> orthonormal. The orthogonalized vector will be zero if and only if it
*> lies entirely in the range of Q.
*> *>
*> If the projection is zero according to Kahan's "twice is enough" *> The projection is computed with at most two iterations of the
*> criterion, then the zero vector is returned. *> classical Gram-Schmidt algorithm, see
*> * L. Giraud, J. Langou, M. Rozložník. "On the round-off error
*> analysis of the Gram-Schmidt algorithm with reorthogonalization."
*> 2002. CERFACS Technical Report No. TR/PA/02/33. URL:
*> https://www.cerfacs.fr/algor/reports/2002/TR_PA_02_33.pdf
*> *>
*>\endverbatim *>\endverbatim
* *
@ -167,16 +173,19 @@
* ===================================================================== * =====================================================================
* *
* .. Parameters .. * .. Parameters ..
REAL ALPHASQ, REALONE, REALZERO REAL ALPHA, REALONE, REALZERO
PARAMETER ( ALPHASQ = 0.01E0, REALONE = 1.0E0, PARAMETER ( ALPHA = 0.01E0, REALONE = 1.0E0,
$ REALZERO = 0.0E0 ) $ REALZERO = 0.0E0 )
COMPLEX NEGONE, ONE, ZERO COMPLEX NEGONE, ONE, ZERO
PARAMETER ( NEGONE = (-1.0E0,0.0E0), ONE = (1.0E0,0.0E0), PARAMETER ( NEGONE = (-1.0E0,0.0E0), ONE = (1.0E0,0.0E0),
$ ZERO = (0.0E0,0.0E0) ) $ ZERO = (0.0E0,0.0E0) )
* .. * ..
* .. Local Scalars .. * .. Local Scalars ..
INTEGER I INTEGER I, IX
REAL NORMSQ1, NORMSQ2, SCL1, SCL2, SSQ1, SSQ2 REAL EPS, NORM, NORM_NEW, SCL, SSQ
* ..
* .. External Functions ..
REAL SLAMCH
* .. * ..
* .. External Subroutines .. * .. External Subroutines ..
EXTERNAL CGEMV, CLASSQ, XERBLA EXTERNAL CGEMV, CLASSQ, XERBLA
@ -211,17 +220,17 @@
CALL XERBLA( 'CUNBDB6', -INFO ) CALL XERBLA( 'CUNBDB6', -INFO )
RETURN RETURN
END IF END IF
*
EPS = SLAMCH( 'Precision' )
* *
* First, project X onto the orthogonal complement of Q's column * First, project X onto the orthogonal complement of Q's column
* space * space
* *
SCL1 = REALZERO * Christoph Conrads: In debugging mode the norm should be computed
SSQ1 = REALONE * and an assertion added comparing the norm with one. Alas, Fortran
CALL CLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) * never made it into 1989 when assert() was introduced into the C
SCL2 = REALZERO * programming language.
SSQ2 = REALONE NORM = REALONE
CALL CLASSQ( M2, X2, INCX2, SCL2, SSQ2 )
NORMSQ1 = SCL1**2*SSQ1 + SCL2**2*SSQ2
* *
IF( M1 .EQ. 0 ) THEN IF( M1 .EQ. 0 ) THEN
DO I = 1, N DO I = 1, N
@ -239,27 +248,31 @@
CALL CGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2, CALL CGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2,
$ INCX2 ) $ INCX2 )
* *
SCL1 = REALZERO SCL = REALZERO
SSQ1 = REALONE SSQ = REALZERO
CALL CLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) CALL CLASSQ( M1, X1, INCX1, SCL, SSQ )
SCL2 = REALZERO CALL CLASSQ( M2, X2, INCX2, SCL, SSQ )
SSQ2 = REALONE NORM_NEW = SCL * SQRT(SSQ)
CALL CLASSQ( M2, X2, INCX2, SCL2, SSQ2 )
NORMSQ2 = SCL1**2*SSQ1 + SCL2**2*SSQ2
* *
* If projection is sufficiently large in norm, then stop. * If projection is sufficiently large in norm, then stop.
* If projection is zero, then stop. * If projection is zero, then stop.
* Otherwise, project again. * Otherwise, project again.
* *
IF( NORMSQ2 .GE. ALPHASQ*NORMSQ1 ) THEN IF( NORM_NEW .GE. ALPHA * NORM ) THEN
RETURN RETURN
END IF END IF
* *
IF( NORMSQ2 .EQ. ZERO ) THEN IF( NORM_NEW .LE. N * EPS * NORM ) THEN
DO IX = 1, 1 + (M1-1)*INCX1, INCX1
X1( IX ) = ZERO
END DO
DO IX = 1, 1 + (M2-1)*INCX2, INCX2
X2( IX ) = ZERO
END DO
RETURN RETURN
END IF END IF
* *
NORMSQ1 = NORMSQ2 NORM = NORM_NEW
* *
DO I = 1, N DO I = 1, N
WORK(I) = ZERO WORK(I) = ZERO
@ -281,24 +294,22 @@
CALL CGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2, CALL CGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2,
$ INCX2 ) $ INCX2 )
* *
SCL1 = REALZERO SCL = REALZERO
SSQ1 = REALONE SSQ = REALZERO
CALL CLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) CALL CLASSQ( M1, X1, INCX1, SCL, SSQ )
SCL2 = REALZERO CALL CLASSQ( M2, X2, INCX2, SCL, SSQ )
SSQ2 = REALONE NORM_NEW = SCL * SQRT(SSQ)
CALL CLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
NORMSQ2 = SCL1**2*SSQ1 + SCL2**2*SSQ2
* *
* If second projection is sufficiently large in norm, then do * If second projection is sufficiently large in norm, then do
* nothing more. Alternatively, if it shrunk significantly, then * nothing more. Alternatively, if it shrunk significantly, then
* truncate it to zero. * truncate it to zero.
* *
IF( NORMSQ2 .LT. ALPHASQ*NORMSQ1 ) THEN IF( NORM_NEW .LT. ALPHA * NORM ) THEN
DO I = 1, M1 DO IX = 1, 1 + (M1-1)*INCX1, INCX1
X1(I) = ZERO X1(IX) = ZERO
END DO END DO
DO I = 1, M2 DO IX = 1, 1 + (M2-1)*INCX2, INCX2
X2(I) = ZERO X2(IX) = ZERO
END DO END DO
END IF END IF
* *
@ -307,4 +318,3 @@
* End of CUNBDB6 * End of CUNBDB6
* *
END END

View File

@ -41,10 +41,16 @@
*> with respect to the columns of *> with respect to the columns of
*> Q = [ Q1 ] . *> Q = [ Q1 ] .
*> [ Q2 ] *> [ Q2 ]
*> The columns of Q must be orthonormal. *> The Euclidean norm of X must be one and the columns of Q must be
*> orthonormal. The orthogonalized vector will be zero if and only if it
*> lies entirely in the range of Q.
*> *>
*> If the projection is zero according to Kahan's "twice is enough" *> The projection is computed with at most two iterations of the
*> criterion, then the zero vector is returned. *> classical Gram-Schmidt algorithm, see
*> * L. Giraud, J. Langou, M. Rozložník. "On the round-off error
*> analysis of the Gram-Schmidt algorithm with reorthogonalization."
*> 2002. CERFACS Technical Report No. TR/PA/02/33. URL:
*> https://www.cerfacs.fr/algor/reports/2002/TR_PA_02_33.pdf
*> *>
*>\endverbatim *>\endverbatim
* *
@ -167,15 +173,18 @@
* ===================================================================== * =====================================================================
* *
* .. Parameters .. * .. Parameters ..
REAL ALPHASQ, REALONE, REALZERO REAL ALPHA, REALONE, REALZERO
PARAMETER ( ALPHASQ = 0.01E0, REALONE = 1.0E0, PARAMETER ( ALPHA = 0.01E0, REALONE = 1.0E0,
$ REALZERO = 0.0E0 ) $ REALZERO = 0.0E0 )
REAL NEGONE, ONE, ZERO REAL NEGONE, ONE, ZERO
PARAMETER ( NEGONE = -1.0E0, ONE = 1.0E0, ZERO = 0.0E0 ) PARAMETER ( NEGONE = -1.0E0, ONE = 1.0E0, ZERO = 0.0E0 )
* .. * ..
* .. Local Scalars .. * .. Local Scalars ..
INTEGER I INTEGER I, IX
REAL NORMSQ1, NORMSQ2, SCL1, SCL2, SSQ1, SSQ2 REAL EPS, NORM, NORM_NEW, SCL, SSQ
* ..
* .. External Functions ..
REAL SLAMCH
* .. * ..
* .. External Subroutines .. * .. External Subroutines ..
EXTERNAL SGEMV, SLASSQ, XERBLA EXTERNAL SGEMV, SLASSQ, XERBLA
@ -210,17 +219,17 @@
CALL XERBLA( 'SORBDB6', -INFO ) CALL XERBLA( 'SORBDB6', -INFO )
RETURN RETURN
END IF END IF
*
EPS = SLAMCH( 'Precision' )
* *
* First, project X onto the orthogonal complement of Q's column * First, project X onto the orthogonal complement of Q's column
* space * space
* *
SCL1 = REALZERO * Christoph Conrads: In debugging mode the norm should be computed
SSQ1 = REALONE * and an assertion added comparing the norm with one. Alas, Fortran
CALL SLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) * never made it into 1989 when assert() was introduced into the C
SCL2 = REALZERO * programming language.
SSQ2 = REALONE NORM = REALONE
CALL SLASSQ( M2, X2, INCX2, SCL2, SSQ2 )
NORMSQ1 = SCL1**2*SSQ1 + SCL2**2*SSQ2
* *
IF( M1 .EQ. 0 ) THEN IF( M1 .EQ. 0 ) THEN
DO I = 1, N DO I = 1, N
@ -238,27 +247,31 @@
CALL SGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2, CALL SGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2,
$ INCX2 ) $ INCX2 )
* *
SCL1 = REALZERO SCL = REALZERO
SSQ1 = REALONE SSQ = REALZERO
CALL SLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) CALL SLASSQ( M1, X1, INCX1, SCL, SSQ )
SCL2 = REALZERO CALL SLASSQ( M2, X2, INCX2, SCL, SSQ )
SSQ2 = REALONE NORM_NEW = SCL * SQRT(SSQ)
CALL SLASSQ( M2, X2, INCX2, SCL2, SSQ2 )
NORMSQ2 = SCL1**2*SSQ1 + SCL2**2*SSQ2
* *
* If projection is sufficiently large in norm, then stop. * If projection is sufficiently large in norm, then stop.
* If projection is zero, then stop. * If projection is zero, then stop.
* Otherwise, project again. * Otherwise, project again.
* *
IF( NORMSQ2 .GE. ALPHASQ*NORMSQ1 ) THEN IF( NORM_NEW .GE. ALPHA * NORM ) THEN
RETURN RETURN
END IF END IF
* *
IF( NORMSQ2 .EQ. ZERO ) THEN IF( NORM_NEW .LE. N * EPS * NORM ) THEN
DO IX = 1, 1 + (M1-1)*INCX1, INCX1
X1( IX ) = ZERO
END DO
DO IX = 1, 1 + (M2-1)*INCX2, INCX2
X2( IX ) = ZERO
END DO
RETURN RETURN
END IF END IF
* *
NORMSQ1 = NORMSQ2 NORM = NORM_NEW
* *
DO I = 1, N DO I = 1, N
WORK(I) = ZERO WORK(I) = ZERO
@ -280,24 +293,22 @@
CALL SGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2, CALL SGEMV( 'N', M2, N, NEGONE, Q2, LDQ2, WORK, 1, ONE, X2,
$ INCX2 ) $ INCX2 )
* *
SCL1 = REALZERO SCL = REALZERO
SSQ1 = REALONE SSQ = REALZERO
CALL SLASSQ( M1, X1, INCX1, SCL1, SSQ1 ) CALL SLASSQ( M1, X1, INCX1, SCL, SSQ )
SCL2 = REALZERO CALL SLASSQ( M2, X2, INCX2, SCL, SSQ )
SSQ2 = REALONE NORM_NEW = SCL * SQRT(SSQ)
CALL SLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
NORMSQ2 = SCL1**2*SSQ1 + SCL2**2*SSQ2
* *
* If second projection is sufficiently large in norm, then do * If second projection is sufficiently large in norm, then do
* nothing more. Alternatively, if it shrunk significantly, then * nothing more. Alternatively, if it shrunk significantly, then
* truncate it to zero. * truncate it to zero.
* *
IF( NORMSQ2 .LT. ALPHASQ*NORMSQ1 ) THEN IF( NORM_NEW .LT. ALPHA * NORM ) THEN
DO I = 1, M1 DO IX = 1, 1 + (M1-1)*INCX1, INCX1
X1(I) = ZERO X1(IX) = ZERO
END DO END DO
DO I = 1, M2 DO IX = 1, 1 + (M2-1)*INCX2, INCX2
X2(I) = ZERO X2(IX) = ZERO
END DO END DO
END IF END IF
* *
@ -306,4 +317,3 @@
* End of SORBDB6 * End of SORBDB6
* *
END END