41
41
* > with respect to the columns of
42
42
* > Q = [ Q1 ] .
43
43
* > [ Q2 ]
44
- * > The columns of Q must be orthonormal.
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.
45
47
* >
46
- * > If the projection is zero according to Kahan's "twice is enough"
47
- * > criterion, then the zero vector is returned.
48
+ * > The projection is computed with at most two iterations of the
49
+ * > classical Gram-Schmidt algorithm, see
50
+ * > * L. Giraud, J. Langou, M. Rozložník. "On the round-off error
51
+ * > analysis of the Gram-Schmidt algorithm with reorthogonalization."
52
+ * > 2002. CERFACS Technical Report No. TR/PA/02/33. URL:
53
+ * > https://www.cerfacs.fr/algor/reports/2002/TR_PA_02_33.pdf
48
54
* >
49
55
* >\endverbatim
50
56
*
@@ -167,15 +173,18 @@ SUBROUTINE DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
167
173
* =====================================================================
168
174
*
169
175
* .. Parameters ..
170
- DOUBLE PRECISION ALPHASQ , REALONE, REALZERO
171
- PARAMETER ( ALPHASQ = 0.01D0 , REALONE = 1.0D0 ,
176
+ DOUBLE PRECISION ALPHA , REALONE, REALZERO
177
+ PARAMETER ( ALPHA = 0.01D0 , REALONE = 1.0D0 ,
172
178
$ REALZERO = 0.0D0 )
173
179
DOUBLE PRECISION NEGONE, ONE, ZERO
174
180
PARAMETER ( NEGONE = - 1.0D0 , ONE = 1.0D0 , ZERO = 0.0D0 )
175
181
* ..
176
182
* .. Local Scalars ..
177
- INTEGER I
178
- DOUBLE PRECISION NORMSQ1, NORMSQ2, SCL1, SCL2, SSQ1, SSQ2
183
+ INTEGER I, IX
184
+ REAL EPS, NORM, NORM_NEW, SCL, SSQ
185
+ * ..
186
+ * .. External Functions ..
187
+ DOUBLE PRECISION DLAMCH
179
188
* ..
180
189
* .. External Subroutines ..
181
190
EXTERNAL DGEMV, DLASSQ, XERBLA
@@ -210,17 +219,17 @@ SUBROUTINE DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
210
219
CALL XERBLA( ' DORBDB6' , - INFO )
211
220
RETURN
212
221
END IF
222
+ *
223
+ EPS = DLAMCH( ' Precision' )
213
224
*
214
225
* First, project X onto the orthogonal complement of Q's column
215
226
* space
216
227
*
217
- SCL1 = REALZERO
218
- SSQ1 = REALONE
219
- CALL DLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
220
- SCL2 = REALZERO
221
- SSQ2 = REALONE
222
- CALL DLASSQ( M2, X2, INCX2, SCL2, SSQ2 )
223
- NORMSQ1 = SCL1** 2 * SSQ1 + SCL2** 2 * SSQ2
228
+ * Christoph Conrads: In debugging mode the norm should be computed
229
+ * and an assertion added comparing the norm with one. Alas, Fortran
230
+ * never made it into 1989 when assert() was introduced into the C
231
+ * programming language.
232
+ NORM = REALONE
224
233
*
225
234
IF ( M1 .EQ. 0 ) THEN
226
235
DO I = 1 , N
@@ -238,27 +247,31 @@ SUBROUTINE DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
238
247
CALL DGEMV( ' N' , M2, N, NEGONE, Q2, LDQ2, WORK, 1 , ONE, X2,
239
248
$ INCX2 )
240
249
*
241
- SCL1 = REALZERO
242
- SSQ1 = REALONE
243
- CALL DLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
244
- SCL2 = REALZERO
245
- SSQ2 = REALONE
246
- CALL DLASSQ( M2, X2, INCX2, SCL2, SSQ2 )
247
- NORMSQ2 = SCL1** 2 * SSQ1 + SCL2** 2 * SSQ2
250
+ SCL = REALZERO
251
+ SSQ = REALZERO
252
+ CALL DLASSQ( M1, X1, INCX1, SCL, SSQ )
253
+ CALL DLASSQ( M2, X2, INCX2, SCL, SSQ )
254
+ NORM_NEW = SCL * SQRT (SSQ)
248
255
*
249
256
* If projection is sufficiently large in norm, then stop.
250
257
* If projection is zero, then stop.
251
258
* Otherwise, project again.
252
259
*
253
- IF ( NORMSQ2 .GE. ALPHASQ * NORMSQ1 ) THEN
260
+ IF ( NORM_NEW .GE. ALPHA * NORM ) THEN
254
261
RETURN
255
262
END IF
256
263
*
257
- IF ( NORMSQ2 .EQ. ZERO ) THEN
264
+ IF ( NORMSQ2 .LE. N * EPS * NORM ) THEN
265
+ DO IX = 1 , 1 + (M1-1 )* INCX1, INCX1
266
+ X1( IX ) = ZERO
267
+ END DO
268
+ DO IX = 1 , 1 + (M2-1 )* INCX2, INCX2
269
+ X2( IX ) = ZERO
270
+ END DO
258
271
RETURN
259
272
END IF
260
273
*
261
- NORMSQ1 = NORMSQ2
274
+ NORM = NORM_NEW
262
275
*
263
276
DO I = 1 , N
264
277
WORK(I) = ZERO
@@ -280,24 +293,22 @@ SUBROUTINE DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
280
293
CALL DGEMV( ' N' , M2, N, NEGONE, Q2, LDQ2, WORK, 1 , ONE, X2,
281
294
$ INCX2 )
282
295
*
283
- SCL1 = REALZERO
284
- SSQ1 = REALONE
285
- CALL DLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
286
- SCL2 = REALZERO
287
- SSQ2 = REALONE
288
- CALL DLASSQ( M1, X1, INCX1, SCL1, SSQ1 )
289
- NORMSQ2 = SCL1** 2 * SSQ1 + SCL2** 2 * SSQ2
296
+ SCL = REALZERO
297
+ SSQ = REALZERO
298
+ CALL DLASSQ( M1, X1, INCX1, SCL, SSQ )
299
+ CALL DLASSQ( M2, X2, INCX2, SCL, SSQ )
300
+ NORM_NEW = SCL * SQRT (SSQ)
290
301
*
291
302
* If second projection is sufficiently large in norm, then do
292
303
* nothing more. Alternatively, if it shrunk significantly, then
293
304
* truncate it to zero.
294
305
*
295
- IF ( NORMSQ2 .LT. ALPHASQ * NORMSQ1 ) THEN
296
- DO I = 1 , M1
297
- X1(I ) = ZERO
306
+ IF ( NORM_NEW .LT. ALPHA * NORM ) THEN
307
+ DO IX = 1 , 1 + (M1 -1 ) * INCX1, INCX1
308
+ X1(IX ) = ZERO
298
309
END DO
299
- DO I = 1 , M2
300
- X2(I ) = ZERO
310
+ DO IX = 1 , 1 + (M2 -1 ) * INCX2, INCX2
311
+ X2(IX ) = ZERO
301
312
END DO
302
313
END IF
303
314
*
@@ -306,4 +317,3 @@ SUBROUTINE DORBDB6( M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2,
306
317
* End of DORBDB6
307
318
*
308
319
END
309
-
0 commit comments