85
85
* > \verbatim
86
86
* > ILO is INTEGER
87
87
* > \endverbatim
88
+ * >
88
89
* > \param[out] IHI
89
90
* > \verbatim
90
91
* > IHI is INTEGER
154
155
* >
155
156
* > Modified by Tzu-Yi Chen, Computer Science Division, University of
156
157
* > California at Berkeley, USA
158
+ * >
159
+ * > Refactored by Evert Provoost, Department of Computer Science,
160
+ * > KU Leuven, Belgium
157
161
* > \endverbatim
158
162
* >
159
163
* =====================================================================
@@ -183,8 +187,8 @@ SUBROUTINE CGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )
183
187
PARAMETER ( FACTOR = 0.95E+0 )
184
188
* ..
185
189
* .. Local Scalars ..
186
- LOGICAL NOCONV
187
- INTEGER I, ICA, IEXC, IRA, J, K, L, M
190
+ LOGICAL NOCONV, CANSWAP
191
+ INTEGER I, ICA, IRA, J, K, L
188
192
REAL C, CA, F, G, R, RA, S, SFMAX1, SFMAX2, SFMIN1,
189
193
$ SFMIN2
190
194
* ..
@@ -195,10 +199,10 @@ SUBROUTINE CGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )
195
199
EXTERNAL SISNAN, LSAME, ICAMAX, SLAMCH, SCNRM2
196
200
* ..
197
201
* .. External Subroutines ..
198
- EXTERNAL CSSCAL, CSWAP, XERBLA
202
+ EXTERNAL XERBLA, CSSCAL, CSWAP
199
203
* ..
200
204
* .. Intrinsic Functions ..
201
- INTRINSIC ABS, AIMAG, MAX, MIN, REAL
205
+ INTRINSIC ABS, REAL , AIMAG, MAX, MIN
202
206
*
203
207
* Test the input parameters
204
208
*
@@ -216,176 +220,194 @@ SUBROUTINE CGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )
216
220
RETURN
217
221
END IF
218
222
*
219
- K = 1
220
- L = N
223
+ * Quick returns.
221
224
*
222
- IF ( N.EQ. 0 )
223
- $ GO TO 210
225
+ IF ( N.EQ. 0 ) THEN
226
+ ILO = 1
227
+ IHI = 0
228
+ RETURN
229
+ END IF
224
230
*
225
231
IF ( LSAME( JOB, ' N' ) ) THEN
226
- DO 10 I = 1 , N
232
+ DO I = 1 , N
227
233
SCALE ( I ) = ONE
228
- 10 CONTINUE
229
- GO TO 210
234
+ END DO
235
+ ILO = 1
236
+ IHI = N
237
+ RETURN
230
238
END IF
231
239
*
232
- IF ( LSAME( JOB, ' S' ) )
233
- $ GO TO 120
234
- *
235
- * Permutation to isolate eigenvalues if possible
236
- *
237
- GO TO 50
238
- *
239
- * Row and column exchange.
240
- *
241
- 20 CONTINUE
242
- SCALE ( M ) = J
243
- IF ( J.EQ. M )
244
- $ GO TO 30
245
- *
246
- CALL CSWAP( L, A( 1 , J ), 1 , A( 1 , M ), 1 )
247
- CALL CSWAP( N- K+1 , A( J, K ), LDA, A( M, K ), LDA )
248
- *
249
- 30 CONTINUE
250
- GO TO ( 40 , 80 )IEXC
251
- *
252
- * Search for rows isolating an eigenvalue and push them down.
253
- *
254
- 40 CONTINUE
255
- IF ( L.EQ. 1 )
256
- $ GO TO 210
257
- L = L - 1
258
- *
259
- 50 CONTINUE
260
- DO 70 J = L, 1 , - 1
240
+ * Permutation to isolate eigenvalues if possible.
261
241
*
262
- DO 60 I = 1 , L
263
- IF ( I.EQ. J )
264
- $ GO TO 60
265
- IF ( REAL ( A( J, I ) ).NE. ZERO .OR. AIMAG ( A( J, I ) ).NE.
266
- $ ZERO )GO TO 70
267
- 60 CONTINUE
268
- *
269
- M = L
270
- IEXC = 1
271
- GO TO 20
272
- 70 CONTINUE
273
- *
274
- GO TO 90
242
+ K = 1
243
+ L = N
275
244
*
276
- * Search for columns isolating an eigenvalue and push them left.
245
+ IF ( .NOT. LSAME( JOB, ' S ' ) ) THEN
277
246
*
278
- 80 CONTINUE
279
- K = K + 1
247
+ * Row and column exchange.
280
248
*
281
- 90 CONTINUE
282
- DO 110 J = K, L
249
+ NOCONV = .TRUE.
250
+ DO WHILE ( NOCONV )
251
+ *
252
+ * Search for rows isolating an eigenvalue and push them down.
253
+ *
254
+ NOCONV = .FALSE.
255
+ DO I = L, 1 , - 1
256
+ CANSWAP = .TRUE.
257
+ DO J = 1 , L
258
+ IF ( I.NE. J .AND. ( REAL ( A( I, J ) ).NE. ZERO .OR.
259
+ $ AIMAG ( A( I, J ) ).NE. ZERO ) ) THEN
260
+ CANSWAP = .FALSE.
261
+ EXIT
262
+ END IF
263
+ END DO
264
+ *
265
+ IF ( CANSWAP ) THEN
266
+ SCALE ( L ) = I
267
+ IF ( I.NE. L ) THEN
268
+ CALL CSWAP( L, A( 1 , I ), 1 , A( 1 , L ), 1 )
269
+ CALL CSWAP( N- K+1 , A( I, K ), LDA, A( L, K ), LDA )
270
+ END IF
271
+ NOCONV = .TRUE.
272
+ *
273
+ IF ( L.EQ. 1 ) THEN
274
+ ILO = 1
275
+ IHI = 1
276
+ RETURN
277
+ END IF
278
+ *
279
+ L = L - 1
280
+ END IF
281
+ END DO
282
+ *
283
+ END DO
284
+
285
+ NOCONV = .TRUE.
286
+ DO WHILE ( NOCONV )
287
+ *
288
+ * Search for columns isolating an eigenvalue and push them left.
289
+ *
290
+ NOCONV = .FALSE.
291
+ DO J = K, L
292
+ CANSWAP = .TRUE.
293
+ DO I = K, L
294
+ IF ( I.NE. J .AND. ( REAL ( A( I, J ) ).NE. ZERO .OR.
295
+ $ AIMAG ( A( I, J ) ).NE. ZERO ) ) THEN
296
+ CANSWAP = .FALSE.
297
+ EXIT
298
+ END IF
299
+ END DO
300
+ *
301
+ IF ( CANSWAP ) THEN
302
+ SCALE ( K ) = J
303
+ IF ( J.NE. K ) THEN
304
+ CALL CSWAP( L, A( 1 , J ), 1 , A( 1 , K ), 1 )
305
+ CALL CSWAP( N- K+1 , A( J, K ), LDA, A( K, K ), LDA )
306
+ END IF
307
+ NOCONV = .TRUE.
308
+ *
309
+ K = K + 1
310
+ END IF
311
+ END DO
312
+ *
313
+ END DO
283
314
*
284
- DO 100 I = K, L
285
- IF ( I.EQ. J )
286
- $ GO TO 100
287
- IF ( REAL ( A( I, J ) ).NE. ZERO .OR. AIMAG ( A( I, J ) ).NE.
288
- $ ZERO )GO TO 110
289
- 100 CONTINUE
315
+ END IF
290
316
*
291
- M = K
292
- IEXC = 2
293
- GO TO 20
294
- 110 CONTINUE
317
+ * Initialize SCALE for non-permuted submatrix.
295
318
*
296
- 120 CONTINUE
297
- DO 130 I = K, L
319
+ DO I = K, L
298
320
SCALE ( I ) = ONE
299
- 130 CONTINUE
321
+ END DO
300
322
*
301
- IF ( LSAME( JOB, ' P' ) )
302
- $ GO TO 210
323
+ * If we only had to permute, we are done.
324
+ *
325
+ IF ( LSAME( JOB, ' P' ) ) THEN
326
+ ILO = K
327
+ IHI = L
328
+ RETURN
329
+ END IF
303
330
*
304
331
* Balance the submatrix in rows K to L.
305
332
*
306
- * Iterative loop for norm reduction
333
+ * Iterative loop for norm reduction.
307
334
*
308
335
SFMIN1 = SLAMCH( ' S' ) / SLAMCH( ' P' )
309
336
SFMAX1 = ONE / SFMIN1
310
337
SFMIN2 = SFMIN1* SCLFAC
311
338
SFMAX2 = ONE / SFMIN2
312
- 140 CONTINUE
313
- NOCONV = .FALSE.
314
- *
315
- DO 200 I = K, L
316
- *
317
- C = SCNRM2( L- K+1 , A( K, I ), 1 )
318
- R = SCNRM2( L- K+1 , A( I , K ), LDA )
319
- ICA = ICAMAX( L, A( 1 , I ), 1 )
320
- CA = ABS ( A( ICA, I ) )
321
- IRA = ICAMAX( N- K+1 , A( I, K ), LDA )
322
- RA = ABS ( A( I, IRA+ K-1 ) )
323
- *
324
- * Guard against zero C or R due to underflow.
325
- *
326
- IF ( C.EQ. ZERO .OR. R.EQ. ZERO )
327
- $ GO TO 200
328
- G = R / SCLFAC
329
- F = ONE
330
- S = C + R
331
- 160 CONTINUE
332
- IF ( C.GE. G .OR. MAX ( F, C, CA ).GE. SFMAX2 .OR.
333
- $ MIN ( R, G, RA ).LE. SFMIN2 )GO TO 170
334
- IF ( SISNAN( C+ F+ CA+ R+ G+ RA ) ) THEN
335
339
*
336
- * Exit if NaN to avoid infinite loop
340
+ NOCONV = .TRUE.
341
+ DO WHILE ( NOCONV )
342
+ NOCONV = .FALSE.
337
343
*
338
- INFO = - 3
339
- CALL XERBLA( ' CGEBAL' , - INFO )
340
- RETURN
341
- END IF
342
- F = F* SCLFAC
343
- C = C* SCLFAC
344
- CA = CA* SCLFAC
345
- R = R / SCLFAC
346
- G = G / SCLFAC
347
- RA = RA / SCLFAC
348
- GO TO 160
349
- *
350
- 170 CONTINUE
351
- G = C / SCLFAC
352
- 180 CONTINUE
353
- IF ( G.LT. R .OR. MAX ( R, RA ).GE. SFMAX2 .OR.
354
- $ MIN ( F, C, G, CA ).LE. SFMIN2 )GO TO 190
355
- F = F / SCLFAC
356
- C = C / SCLFAC
357
- G = G / SCLFAC
358
- CA = CA / SCLFAC
359
- R = R* SCLFAC
360
- RA = RA* SCLFAC
361
- GO TO 180
362
- *
363
- * Now balance.
364
- *
365
- 190 CONTINUE
366
- IF ( ( C+ R ).GE. FACTOR* S )
367
- $ GO TO 200
368
- IF ( F.LT. ONE .AND. SCALE ( I ).LT. ONE ) THEN
369
- IF ( F* SCALE ( I ).LE. SFMIN1 )
370
- $ GO TO 200
371
- END IF
372
- IF ( F.GT. ONE .AND. SCALE ( I ).GT. ONE ) THEN
373
- IF ( SCALE ( I ).GE. SFMAX1 / F )
374
- $ GO TO 200
375
- END IF
376
- G = ONE / F
377
- SCALE ( I ) = SCALE ( I )* F
378
- NOCONV = .TRUE.
344
+ DO I = K, L
379
345
*
380
- CALL CSSCAL( N- K+1 , G, A( I, K ), LDA )
381
- CALL CSSCAL( L, F, A( 1 , I ), 1 )
346
+ C = SCNRM2( L- K+1 , A( K, I ), 1 )
347
+ R = SCNRM2( L- K+1 , A( I, K ), LDA )
348
+ ICA = ICAMAX( L, A( 1 , I ), 1 )
349
+ CA = ABS ( A( ICA, I ) )
350
+ IRA = ICAMAX( N- K+1 , A( I, K ), LDA )
351
+ RA = ABS ( A( I, IRA+ K-1 ) )
382
352
*
383
- 200 CONTINUE
353
+ * Guard against zero C or R due to underflow.
354
+ *
355
+ IF ( C.EQ. ZERO .OR. R.EQ. ZERO ) CYCLE
356
+ *
357
+ * Exit if NaN to avoid infinite loop
384
358
*
385
- IF ( NOCONV )
386
- $ GO TO 140
359
+ IF ( SISNAN( C+ CA+ R+ RA ) ) THEN
360
+ INFO = - 3
361
+ CALL XERBLA( ' CGEBAL' , - INFO )
362
+ RETURN
363
+ END IF
364
+ *
365
+ G = R / SCLFAC
366
+ F = ONE
367
+ S = C + R
368
+ *
369
+ DO WHILE ( C.LT. G .AND. MAX ( F, C, CA ).LT. SFMAX2 .AND.
370
+ $ MIN ( R, G, RA ).GT. SFMIN2 )
371
+ F = F* SCLFAC
372
+ C = C* SCLFAC
373
+ CA = CA* SCLFAC
374
+ R = R / SCLFAC
375
+ G = G / SCLFAC
376
+ RA = RA / SCLFAC
377
+ END DO
378
+ *
379
+ G = C / SCLFAC
380
+ *
381
+ DO WHILE ( G.GE. R .AND. MAX ( R, RA ).LT. SFMAX2 .AND.
382
+ $ MIN ( F, C, G, CA ).GT. SFMIN2 )
383
+ F = F / SCLFAC
384
+ C = C / SCLFAC
385
+ G = G / SCLFAC
386
+ CA = CA / SCLFAC
387
+ R = R* SCLFAC
388
+ RA = RA* SCLFAC
389
+ END DO
390
+ *
391
+ * Now balance.
392
+ *
393
+ IF ( ( C+ R ).GE. FACTOR* S ) CYCLE
394
+ IF ( F.LT. ONE .AND. SCALE ( I ).LT. ONE ) THEN
395
+ IF ( F* SCALE ( I ).LE. SFMIN1 ) CYCLE
396
+ END IF
397
+ IF ( F.GT. ONE .AND. SCALE ( I ).GT. ONE ) THEN
398
+ IF ( SCALE ( I ).GE. SFMAX1 / F ) CYCLE
399
+ END IF
400
+ G = ONE / F
401
+ SCALE ( I ) = SCALE ( I )* F
402
+ NOCONV = .TRUE.
403
+ *
404
+ CALL CSSCAL( N- K+1 , G, A( I, K ), LDA )
405
+ CALL CSSCAL( L, F, A( 1 , I ), 1 )
406
+ *
407
+ END DO
408
+ *
409
+ END DO
387
410
*
388
- 210 CONTINUE
389
411
ILO = K
390
412
IHI = L
391
413
*
0 commit comments