41
41
* > with respect to the columns of
42
42
* > Q = [ Q1 ] .
43
43
* > [ Q2 ]
44
- * > The columns of Q must be orthonormal. The orthogonalized vector will
45
- * > be zero if and only if it lies entirely in the range of Q.
44
+ * > The Euclidean norm of X must be one and the columns of Q must be
45
+ * > orthonormal. The orthogonalized vector will be zero if and only if it
46
+ * > lies entirely in the range of Q.
46
47
* >
47
48
* > The projection is computed with at most two iterations of the
48
49
* > classical Gram-Schmidt algorithm, see
@@ -172,14 +173,17 @@ SUBROUTINE SORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
172
173
* =====================================================================
173
174
*
174
175
* .. Parameters ..
175
- REAL ALPHASQ , REALZERO
176
- PARAMETER ( ALPHASQ = 0.01E0 , REALZERO = 0.0E0 )
176
+ REAL ALPHA , REALZERO
177
+ PARAMETER ( ALPHA = 0.1E0 , REALZERO = 0.0E0 )
177
178
REAL NEGONE, ONE, ZERO
178
179
PARAMETER ( NEGONE = - 1.0E0 , ONE = 1.0E0 , ZERO = 0.0E0 )
179
180
* ..
180
181
* .. Local Scalars ..
181
182
INTEGER I, IX
182
- REAL NORMSQ1, NORMSQ2, SCL1, SCL2, SSQ1, SSQ2
183
+ REAL EPS, NORM, NORM_NEW, SCL, SSQ
184
+ * ..
185
+ * .. External Functions ..
186
+ REAL SLAMCH
183
187
* ..
184
188
* .. External Subroutines ..
185
189
EXTERNAL SGEMV, SLASSQ, XERBLA
@@ -214,26 +218,17 @@ SUBROUTINE SORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
214
218
CALL XERBLA( ' SORBDB6' , - INFO )
215
219
RETURN
216
220
END IF
221
+ *
222
+ EPS = SLAMCH( ' Precision' )
217
223
*
218
224
* First, project X onto the orthogonal complement of Q's column
219
225
* space
220
226
*
221
- SCL1 = REALZERO
222
- SSQ1 = REALZERO
223
- CALL SLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
224
- SCL2 = REALZERO
225
- SSQ2 = REALZERO
226
- CALL SLASSQ( M2, X2, INCX2, SCL2, SSQ2 )
227
- NORMSQ1 = SCL1** 2 * SSQ1 + SCL2** 2 * SSQ2
228
- IF ( NORMSQ1 .EQ. 0 ) THEN
229
- DO IX = 1 , 1 + (M1-1 )* INCX1, INCX1
230
- X1( IX ) = ZERO
231
- END DO
232
- DO IX = 1 , 1 + (M2-1 )* INCX2, INCX2
233
- X2( IX ) = ZERO
234
- END DO
235
- RETURN
236
- END IF
227
+ * Christoph Conrads: In debugging mode the norm should be computed
228
+ * and an assertion added comparing the norm with one. Alas, Fortran
229
+ * never made it into 1989 when assert() was introduced into the C
230
+ * programming language.
231
+ NORM = 1.0E0
237
232
*
238
233
IF ( M1 .EQ. 0 ) THEN
239
234
DO I = 1 , N
@@ -251,23 +246,21 @@ SUBROUTINE SORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
251
246
CALL SGEMV( ' N' , M2, N, NEGONE, Q2, LDQ2, WORK, 1 , ONE, X2,
252
247
$ INCX2 )
253
248
*
254
- SCL1 = REALZERO
255
- SSQ1 = REALZERO
256
- CALL SLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
257
- SCL2 = REALZERO
258
- SSQ2 = REALZERO
259
- CALL SLASSQ( M2, X2, INCX2, SCL2, SSQ2 )
260
- NORMSQ2 = SCL1** 2 * SSQ1 + SCL2** 2 * SSQ2
249
+ SCL = REALZERO
250
+ SSQ = REALZERO
251
+ CALL SLASSQ( M1, X1, INCX1, SCL, SSQ )
252
+ CALL SLASSQ( M2, X2, INCX2, SCL, SSQ )
253
+ NORM_NEW = SCL * SQRT (SSQ)
261
254
*
262
255
* If projection is sufficiently large in norm, then stop.
263
256
* If projection is zero, then stop.
264
257
* Otherwise, project again.
265
258
*
266
- IF ( NORMSQ2 .GE. ALPHASQ * NORMSQ1 ) THEN
259
+ IF ( NORM_NEW .GE. ALPHA * NORM ) THEN
267
260
RETURN
268
261
END IF
269
262
*
270
- IF ( NORMSQ2 .EQ. ZERO ) THEN
263
+ IF ( NORMSQ2 .LE. N * EPS * NORM ) THEN
271
264
DO IX = 1 , 1 + (M1-1 )* INCX1, INCX1
272
265
X1( IX ) = ZERO
273
266
END DO
@@ -277,7 +270,7 @@ SUBROUTINE SORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
277
270
RETURN
278
271
END IF
279
272
*
280
- NORMSQ1 = NORMSQ2
273
+ NORM = NORM_NEW
281
274
*
282
275
DO I = 1 , N
283
276
WORK(I) = ZERO
@@ -299,19 +292,17 @@ SUBROUTINE SORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
299
292
CALL SGEMV( ' N' , M2, N, NEGONE, Q2, LDQ2, WORK, 1 , ONE, X2,
300
293
$ INCX2 )
301
294
*
302
- SCL1 = REALZERO
303
- SSQ1 = REALZERO
304
- CALL SLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
305
- SCL2 = REALZERO
306
- SSQ2 = REALZERO
307
- CALL SLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
308
- NORMSQ2 = SCL1** 2 * SSQ1 + SCL2** 2 * SSQ2
295
+ SCL = REALZERO
296
+ SSQ = REALZERO
297
+ CALL SLASSQ( M1, X1, INCX1, SCL, SSQ )
298
+ CALL SLASSQ( M2, X2, INCX2, SCL, SSQ )
299
+ NORM_NEW = SCL * SQRT (SSQ)
309
300
*
310
301
* If second projection is sufficiently large in norm, then do
311
302
* nothing more. Alternatively, if it shrunk significantly, then
312
303
* truncate it to zero.
313
304
*
314
- IF ( NORMSQ2 .LT. ALPHASQ * NORMSQ1 ) THEN
305
+ IF ( NORM_NEW .LT. ALPHA * NORM ) THEN
315
306
DO IX = 1 , 1 + (M1-1 )* INCX1, INCX1
316
307
X1(IX) = ZERO
317
308
END DO
0 commit comments