Skip to content

Commit 2382be4

Browse files
Merge pull request #926 from weslleyspereira/fix-nan-propag-gecon
GECON returns 1 if RCOND is NaN
2 parents 6261d62 + 68eafc6 commit 2382be4

File tree

4 files changed

+124
-24
lines changed

4 files changed

+124
-24
lines changed

SRC/cgecon.f

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,15 @@
105105
*> \verbatim
106106
*> INFO is INTEGER
107107
*> = 0: successful exit
108-
*> < 0: if INFO = -i, the i-th argument had an illegal value
109-
*> =-5: if ANORM is NAN or negative.
108+
*> < 0: if INFO = -i, the i-th argument had an illegal value.
109+
*> NaNs are illegal values for ANORM, and they propagate to
110+
*> the output parameter RCOND.
111+
*> Infinity is illegal for ANORM, and it propagates to the output
112+
*> parameter RCOND as 0.
113+
*> = 1: if RCOND = NaN, or
114+
*> RCOND = Inf, or
115+
*> the computed norm of the inverse of A is 0.
116+
*> In the latter, RCOND = 0 is returned.
110117
*> \endverbatim
111118
*
112119
* Authors:
@@ -147,7 +154,7 @@ SUBROUTINE CGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
147154
LOGICAL ONENRM
148155
CHARACTER NORMIN
149156
INTEGER IX, KASE, KASE1
150-
REAL AINVNM, SCALE, SL, SMLNUM, SU
157+
REAL AINVNM, SCALE, SL, SMLNUM, SU, HUGEVAL
151158
COMPLEX ZDUM
152159
* ..
153160
* .. Local Arrays ..
@@ -172,6 +179,8 @@ SUBROUTINE CGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
172179
CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
173180
* ..
174181
* .. Executable Statements ..
182+
*
183+
HUGEVAL = SLAMCH( 'Overflow' )
175184
*
176185
* Test the input parameters.
177186
*
@@ -183,7 +192,7 @@ SUBROUTINE CGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
183192
INFO = -2
184193
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
185194
INFO = -4
186-
ELSE IF( ANORM.LT.ZERO .OR. SISNAN( ANORM ) ) THEN
195+
ELSE IF( ANORM.LT.ZERO ) THEN
187196
INFO = -5
188197
END IF
189198
IF( INFO.NE.0 ) THEN
@@ -199,6 +208,13 @@ SUBROUTINE CGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
199208
RETURN
200209
ELSE IF( ANORM.EQ.ZERO ) THEN
201210
RETURN
211+
ELSE IF( SISNAN( ANORM ) ) THEN
212+
RCOND = ANORM
213+
INFO = -5
214+
RETURN
215+
ELSE IF( ANORM.GT.HUGEVAL ) THEN
216+
INFO = -5
217+
RETURN
202218
END IF
203219
*
204220
SMLNUM = SLAMCH( 'Safe minimum' )
@@ -256,8 +272,17 @@ SUBROUTINE CGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
256272
*
257273
* Compute the estimate of the reciprocal condition number.
258274
*
259-
IF( AINVNM.NE.ZERO )
260-
$ RCOND = ( ONE / AINVNM ) / ANORM
275+
IF( AINVNM.NE.ZERO ) THEN
276+
RCOND = ( ONE / AINVNM ) / ANORM
277+
ELSE
278+
INFO = 1
279+
RETURN
280+
END IF
281+
*
282+
* Check for NaNs and Infs
283+
*
284+
IF( SISNAN( RCOND ) .OR. RCOND.GT.HUGEVAL )
285+
$ INFO = 1
261286
*
262287
20 CONTINUE
263288
RETURN

SRC/dgecon.f

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,15 @@
105105
*> \verbatim
106106
*> INFO is INTEGER
107107
*> = 0: successful exit
108-
*> < 0: if INFO = -i, the i-th argument had an illegal value
109-
*> =-5: if ANORM is NAN or negative.
108+
*> < 0: if INFO = -i, the i-th argument had an illegal value.
109+
*> NaNs are illegal values for ANORM, and they propagate to
110+
*> the output parameter RCOND.
111+
*> Infinity is illegal for ANORM, and it propagates to the output
112+
*> parameter RCOND as 0.
113+
*> = 1: if RCOND = NaN, or
114+
*> RCOND = Inf, or
115+
*> the computed norm of the inverse of A is 0.
116+
*> In the latter, RCOND = 0 is returned.
110117
*> \endverbatim
111118
*
112119
* Authors:
@@ -147,7 +154,7 @@ SUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
147154
LOGICAL ONENRM
148155
CHARACTER NORMIN
149156
INTEGER IX, KASE, KASE1
150-
DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU
157+
DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU, HUGEVAL
151158
* ..
152159
* .. Local Arrays ..
153160
INTEGER ISAVE( 3 )
@@ -165,6 +172,8 @@ SUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
165172
INTRINSIC ABS, MAX
166173
* ..
167174
* .. Executable Statements ..
175+
*
176+
HUGEVAL = DLAMCH( 'Overflow' )
168177
*
169178
* Test the input parameters.
170179
*
@@ -176,7 +185,7 @@ SUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
176185
INFO = -2
177186
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
178187
INFO = -4
179-
ELSE IF( ANORM.LT.ZERO .OR. DISNAN( ANORM ) ) THEN
188+
ELSE IF( ANORM.LT.ZERO ) THEN
180189
INFO = -5
181190
END IF
182191
IF( INFO.NE.0 ) THEN
@@ -192,6 +201,13 @@ SUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
192201
RETURN
193202
ELSE IF( ANORM.EQ.ZERO ) THEN
194203
RETURN
204+
ELSE IF( DISNAN( ANORM ) ) THEN
205+
RCOND = ANORM
206+
INFO = -5
207+
RETURN
208+
ELSE IF( ANORM.GT.HUGEVAL ) THEN
209+
INFO = -5
210+
RETURN
195211
END IF
196212
*
197213
SMLNUM = DLAMCH( 'Safe minimum' )
@@ -248,8 +264,17 @@ SUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
248264
*
249265
* Compute the estimate of the reciprocal condition number.
250266
*
251-
IF( AINVNM.NE.ZERO )
252-
$ RCOND = ( ONE / AINVNM ) / ANORM
267+
IF( AINVNM.NE.ZERO ) THEN
268+
RCOND = ( ONE / AINVNM ) / ANORM
269+
ELSE
270+
INFO = 1
271+
RETURN
272+
END IF
273+
*
274+
* Check for NaNs and Infs
275+
*
276+
IF( DISNAN( RCOND ) .OR. RCOND.GT.HUGEVAL )
277+
$ INFO = 1
253278
*
254279
20 CONTINUE
255280
RETURN

SRC/sgecon.f

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,15 @@
105105
*> \verbatim
106106
*> INFO is INTEGER
107107
*> = 0: successful exit
108-
*> < 0: if INFO = -i, the i-th argument had an illegal value
109-
*> =-5: if ANORM is NAN or negative.
108+
*> < 0: if INFO = -i, the i-th argument had an illegal value.
109+
*> NaNs are illegal values for ANORM, and they propagate to
110+
*> the output parameter RCOND.
111+
*> Infinity is illegal for ANORM, and it propagates to the output
112+
*> parameter RCOND as 0.
113+
*> = 1: if RCOND = NaN, or
114+
*> RCOND = Inf, or
115+
*> the computed norm of the inverse of A is 0.
116+
*> In the latter, RCOND = 0 is returned.
110117
*> \endverbatim
111118
*
112119
* Authors:
@@ -147,7 +154,7 @@ SUBROUTINE SGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
147154
LOGICAL ONENRM
148155
CHARACTER NORMIN
149156
INTEGER IX, KASE, KASE1
150-
REAL AINVNM, SCALE, SL, SMLNUM, SU
157+
REAL AINVNM, SCALE, SL, SMLNUM, SU, HUGEVAL
151158
* ..
152159
* .. Local Arrays ..
153160
INTEGER ISAVE( 3 )
@@ -165,6 +172,8 @@ SUBROUTINE SGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
165172
INTRINSIC ABS, MAX
166173
* ..
167174
* .. Executable Statements ..
175+
*
176+
HUGEVAL = SLAMCH( 'Overflow' )
168177
*
169178
* Test the input parameters.
170179
*
@@ -176,7 +185,7 @@ SUBROUTINE SGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
176185
INFO = -2
177186
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
178187
INFO = -4
179-
ELSE IF( ANORM.LT.ZERO .OR. SISNAN( ANORM ) ) THEN
188+
ELSE IF( ANORM.LT.ZERO ) THEN
180189
INFO = -5
181190
END IF
182191
IF( INFO.NE.0 ) THEN
@@ -192,6 +201,13 @@ SUBROUTINE SGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
192201
RETURN
193202
ELSE IF( ANORM.EQ.ZERO ) THEN
194203
RETURN
204+
ELSE IF( SISNAN( ANORM ) ) THEN
205+
RCOND = ANORM
206+
INFO = -5
207+
RETURN
208+
ELSE IF( ANORM.GT.HUGEVAL ) THEN
209+
INFO = -5
210+
RETURN
195211
END IF
196212
*
197213
SMLNUM = SLAMCH( 'Safe minimum' )
@@ -248,8 +264,17 @@ SUBROUTINE SGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,
248264
*
249265
* Compute the estimate of the reciprocal condition number.
250266
*
251-
IF( AINVNM.NE.ZERO )
252-
$ RCOND = ( ONE / AINVNM ) / ANORM
267+
IF( AINVNM.NE.ZERO ) THEN
268+
RCOND = ( ONE / AINVNM ) / ANORM
269+
ELSE
270+
INFO = 1
271+
RETURN
272+
END IF
273+
*
274+
* Check for NaNs and Infs
275+
*
276+
IF( SISNAN( RCOND ) .OR. RCOND.GT.HUGEVAL )
277+
$ INFO = 1
253278
*
254279
20 CONTINUE
255280
RETURN

SRC/zgecon.f

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,15 @@
105105
*> \verbatim
106106
*> INFO is INTEGER
107107
*> = 0: successful exit
108-
*> < 0: if INFO = -i, the i-th argument had an illegal value
109-
*> =-5: if ANORM is NAN or negative.
108+
*> < 0: if INFO = -i, the i-th argument had an illegal value.
109+
*> NaNs are illegal values for ANORM, and they propagate to
110+
*> the output parameter RCOND.
111+
*> Infinity is illegal for ANORM, and it propagates to the output
112+
*> parameter RCOND as 0.
113+
*> = 1: if RCOND = NaN, or
114+
*> RCOND = Inf, or
115+
*> the computed norm of the inverse of A is 0.
116+
*> In the latter, RCOND = 0 is returned.
110117
*> \endverbatim
111118
*
112119
* Authors:
@@ -147,7 +154,7 @@ SUBROUTINE ZGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
147154
LOGICAL ONENRM
148155
CHARACTER NORMIN
149156
INTEGER IX, KASE, KASE1
150-
DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU
157+
DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU, HUGEVAL
151158
COMPLEX*16 ZDUM
152159
* ..
153160
* .. Local Arrays ..
@@ -172,6 +179,8 @@ SUBROUTINE ZGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
172179
CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
173180
* ..
174181
* .. Executable Statements ..
182+
*
183+
HUGEVAL = DLAMCH( 'Overflow' )
175184
*
176185
* Test the input parameters.
177186
*
@@ -183,7 +192,7 @@ SUBROUTINE ZGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
183192
INFO = -2
184193
ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
185194
INFO = -4
186-
ELSE IF( ANORM.LT.ZERO .OR. DISNAN( ANORM ) ) THEN
195+
ELSE IF( ANORM.LT.ZERO ) THEN
187196
INFO = -5
188197
END IF
189198
IF( INFO.NE.0 ) THEN
@@ -199,6 +208,13 @@ SUBROUTINE ZGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
199208
RETURN
200209
ELSE IF( ANORM.EQ.ZERO ) THEN
201210
RETURN
211+
ELSE IF( DISNAN( ANORM ) ) THEN
212+
RCOND = ANORM
213+
INFO = -5
214+
RETURN
215+
ELSE IF( ANORM.GT.HUGEVAL ) THEN
216+
INFO = -5
217+
RETURN
202218
END IF
203219
*
204220
SMLNUM = DLAMCH( 'Safe minimum' )
@@ -256,8 +272,17 @@ SUBROUTINE ZGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, RWORK,
256272
*
257273
* Compute the estimate of the reciprocal condition number.
258274
*
259-
IF( AINVNM.NE.ZERO )
260-
$ RCOND = ( ONE / AINVNM ) / ANORM
275+
IF( AINVNM.NE.ZERO ) THEN
276+
RCOND = ( ONE / AINVNM ) / ANORM
277+
ELSE
278+
INFO = 1
279+
RETURN
280+
END IF
281+
*
282+
* Check for NaNs and Infs
283+
*
284+
IF( DISNAN( RCOND ) .OR. RCOND.GT.HUGEVAL )
285+
$ INFO = 1
261286
*
262287
20 CONTINUE
263288
RETURN

0 commit comments

Comments
 (0)