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,196 @@ 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
240
+ * Permutation to isolate eigenvalues if possible.
241
+ *
242
+ K = 1
243
+ L = N
244
+ *
245
+ IF ( .NOT. LSAME( JOB, ' S' ) ) THEN
246
+ *
247
+ * Row and column exchange.
248
+ *
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
314
+ *
315
+ END IF
234
316
*
235
- * Permutation to isolate eigenvalues if possible
317
+ * Initialize SCALE for non-permuted submatrix.
236
318
*
237
- GO TO 50
319
+ DO I = K, L
320
+ SCALE ( I ) = ONE
321
+ END DO
238
322
*
239
- * Row and column exchange .
323
+ * If we only had to permute, we are done .
240
324
*
241
- 20 CONTINUE
242
- SCALE ( M ) = J
243
- IF ( J.EQ. M )
244
- $ GO TO 30
325
+ IF ( LSAME( JOB, ' P' ) ) THEN
326
+ ILO = K
327
+ IHI = L
328
+ RETURN
329
+ END IF
245
330
*
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 )
331
+ * Balance the submatrix in rows K to L.
248
332
*
249
- 30 CONTINUE
250
- GO TO ( 40 , 80 )IEXC
333
+ * Iterative loop for norm reduction.
251
334
*
252
- * Search for rows isolating an eigenvalue and push them down.
335
+ SFMIN1 = SLAMCH( ' S' ) / SLAMCH( ' P' )
336
+ SFMAX1 = ONE / SFMIN1
337
+ SFMIN2 = SFMIN1* SCLFAC
338
+ SFMAX2 = ONE / SFMIN2
253
339
*
254
- 40 CONTINUE
255
- IF ( L.EQ. 1 )
256
- $ GO TO 210
257
- L = L - 1
340
+ NOCONV = .TRUE.
341
+ DO WHILE ( NOCONV )
342
+ NOCONV = .FALSE.
258
343
*
259
- 50 CONTINUE
260
- DO 70 J = L, 1 , - 1
344
+ DO I = K, L
261
345
*
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
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 ) )
268
352
*
269
- M = L
270
- IEXC = 1
271
- GO TO 20
272
- 70 CONTINUE
353
+ * Guard against zero C or R due to underflow.
273
354
*
274
- GO TO 90
355
+ IF ( C .EQ. ZERO .OR. R .EQ. ZERO ) CYCLE
275
356
*
276
- * Search for columns isolating an eigenvalue and push them left.
357
+ G = R / SCLFAC
358
+ F = ONE
359
+ S = C + R
277
360
*
278
- 80 CONTINUE
279
- K = K + 1
361
+ DO WHILE ( C .LT. G .AND. MAX ( F, C, CA ) .LT. SFMAX2 .AND.
362
+ $ MIN ( R, G, RA ) .GT. SFMIN2 )
280
363
*
281
- 90 CONTINUE
282
- DO 110 J = K, L
364
+ IF ( SISNAN( C+ F+ CA+ R+ G+ RA ) ) THEN
283
365
*
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
366
+ * Exit if NaN to avoid infinite loop
290
367
*
291
- M = K
292
- IEXC = 2
293
- GO TO 20
294
- 110 CONTINUE
368
+ INFO = - 3
369
+ CALL XERBLA( ' CGEBAL ' , - INFO )
370
+ RETURN
371
+ END IF
295
372
*
296
- 120 CONTINUE
297
- DO 130 I = K, L
298
- SCALE ( I ) = ONE
299
- 130 CONTINUE
373
+ F = F* SCLFAC
374
+ C = C* SCLFAC
375
+ CA = CA* SCLFAC
376
+ R = R / SCLFAC
377
+ G = G / SCLFAC
378
+ RA = RA / SCLFAC
379
+ END DO
300
380
*
301
- IF ( LSAME( JOB, ' P' ) )
302
- $ GO TO 210
381
+ G = C / SCLFAC
303
382
*
304
- * Balance the submatrix in rows K to L.
383
+ DO WHILE ( G.GE. R .AND. MAX ( R, RA ).LT. SFMAX2 .AND.
384
+ $ MIN ( F, C, G, CA ).GT. SFMIN2 )
385
+ F = F / SCLFAC
386
+ C = C / SCLFAC
387
+ G = G / SCLFAC
388
+ CA = CA / SCLFAC
389
+ R = R* SCLFAC
390
+ RA = RA* SCLFAC
391
+ END DO
305
392
*
306
- * Iterative loop for norm reduction
393
+ * Now balance.
307
394
*
308
- SFMIN1 = SLAMCH( ' S' ) / SLAMCH( ' P' )
309
- SFMAX1 = ONE / SFMIN1
310
- SFMIN2 = SFMIN1* SCLFAC
311
- 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
- *
336
- * Exit if NaN to avoid infinite loop
337
- *
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.
395
+ IF ( ( C+ R ).GE. FACTOR* S ) CYCLE
396
+ IF ( F.LT. ONE .AND. SCALE ( I ).LT. ONE ) THEN
397
+ IF ( F* SCALE ( I ).LE. SFMIN1 ) CYCLE
398
+ END IF
399
+ IF ( F.GT. ONE .AND. SCALE ( I ).GT. ONE ) THEN
400
+ IF ( SCALE ( I ).GE. SFMAX1 / F ) CYCLE
401
+ END IF
402
+ G = ONE / F
403
+ SCALE ( I ) = SCALE ( I )* F
404
+ NOCONV = .TRUE.
379
405
*
380
- CALL CSSCAL( N- K+1 , G, A( I, K ), LDA )
381
- CALL CSSCAL( L, F, A( 1 , I ), 1 )
406
+ CALL CSSCAL( N- K+1 , G, A( I, K ), LDA )
407
+ CALL CSSCAL( L, F, A( 1 , I ), 1 )
382
408
*
383
- 200 CONTINUE
409
+ END DO
384
410
*
385
- IF ( NOCONV )
386
- $ GO TO 140
411
+ END DO
387
412
*
388
- 210 CONTINUE
389
413
ILO = K
390
414
IHI = L
391
415
*
0 commit comments