@@ -101,17 +101,16 @@ SUBROUTINE CRSCL( N, A, X, INCX )
101
101
PARAMETER ( ZERO = 0.0E+0 , ONE = 1.0E+0 )
102
102
* ..
103
103
* .. Local Scalars ..
104
- REAL BIGNUM, SMLNUM, HUGE , AR, AI, ABSR, ABSI, UR
104
+ REAL SAFMAX, SAFMIN, OV , AR, AI, ABSR, ABSI, UR
105
105
% , UI
106
- COMPLEX INVA
107
106
* ..
108
107
* .. External Functions ..
109
108
REAL SLAMCH
110
109
COMPLEX CLADIV
111
110
EXTERNAL SLAMCH, CLADIV
112
111
* ..
113
112
* .. External Subroutines ..
114
- EXTERNAL CSCAL, CSSCAL
113
+ EXTERNAL CSCAL, CSSCAL, CSRSCL
115
114
* ..
116
115
* .. Intrinsic Functions ..
117
116
INTRINSIC ABS
@@ -125,9 +124,9 @@ SUBROUTINE CRSCL( N, A, X, INCX )
125
124
*
126
125
* Get machine parameters
127
126
*
128
- SMLNUM = SLAMCH( ' S' )
129
- BIGNUM = ONE / SMLNUM
130
- HUGE = SLAMCH( ' O' )
127
+ SAFMIN = SLAMCH( ' S' )
128
+ SAFMAX = ONE / SAFMIN
129
+ OV = SLAMCH( ' O' )
131
130
*
132
131
* Initialize constants related to A.
133
132
*
@@ -136,68 +135,63 @@ SUBROUTINE CRSCL( N, A, X, INCX )
136
135
ABSR = ABS ( AR )
137
136
ABSI = ABS ( AI )
138
137
*
139
- IF ( ABSI .EQ. ZERO ) THEN
138
+ IF ( AI .EQ. ZERO ) THEN
140
139
* If alpha is real, then we can use csrscl
141
140
CALL CSRSCL( N, AR, X, INCX )
142
141
*
143
- ELSE IF ( ABSR .EQ. ZERO ) THEN
142
+ ELSE IF ( AR .EQ. ZERO ) THEN
144
143
* If alpha has a zero real part, then we follow the same rules as if
145
144
* alpha were real.
146
- IF ( ABSI.GT. BIGNUM ) THEN
147
- INVA = CMPLX ( ZERO, - BIGNUM / AI )
148
- CALL CSSCAL( N, SMLNUM, X, INCX )
149
- CALL CSCAL( N, INVA, X, INCX )
150
- ELSE IF ( ABSI.LT. SMLNUM ) THEN
151
- INVA = CMPLX ( ZERO, - SMLNUM / AI )
152
- CALL CSCAL( N, INVA, X, INCX )
153
- CALL CSSCAL( N, BIGNUM, X, INCX )
145
+ IF ( ABSI.GT. SAFMAX ) THEN
146
+ CALL CSSCAL( N, SAFMIN, X, INCX )
147
+ CALL CSCAL( N, CMPLX ( ZERO, - SAFMAX / AI ), X, INCX )
148
+ ELSE IF ( ABSI.LT. SAFMIN ) THEN
149
+ CALL CSCAL( N, CMPLX ( ZERO, - SAFMIN / AI ), X, INCX )
150
+ CALL CSSCAL( N, SAFMAX, X, INCX )
154
151
ELSE
155
- INVA = CMPLX ( ZERO, - ONE / AI )
156
- CALL CSCAL( N, INVA, X, INCX )
152
+ CALL CSCAL( N, CMPLX ( ZERO, - ONE / AI ), X, INCX )
157
153
END IF
158
- *
159
- ELSE IF ( (ABSR.GE. BIGNUM).OR. (ABSI.GE. BIGNUM) ) THEN
160
- * Either real or imaginary part is too large.
161
- INVA = CLADIV( CMPLX ( BIGNUM, ZERO ), A )
162
- CALL CSSCAL( N, SMLNUM, X, INCX )
163
- CALL CSCAL( N, INVA, X, INCX )
164
154
*
165
155
ELSE
166
- * The following numbers can be computed without NaNs and zeros.
167
- * They do not overflow simultaneously.
156
+ * The following numbers can be computed.
168
157
* They are the inverse of the real and imaginary parts of 1/alpha.
158
+ * Note that a and b are always different from zero.
159
+ * NaNs are only possible if either:
160
+ * 1. alphaR or alphaI is NaN.
161
+ * 2. alphaR and alphaI are both infinite, in which case it makes sense
162
+ * to propagate a NaN.
169
163
UR = AR + AI * ( AI / AR )
170
164
UI = AI + AR * ( AR / AI )
171
165
*
172
- IF ( (ABS ( UR ).LT. SMLNUM).OR. (ABS ( UI ).LT. SMLNUM) ) THEN
173
- INVA = CMPLX ( SMLNUM / UR, - SMLNUM / UI )
174
- CALL CSCAL( N, INVA, X, INCX )
175
- CALL CSSCAL( N, BIGNUM, X, INCX )
176
- ELSE IF ( ABS ( UR ).GT. HUGE ) THEN
177
- IF ( ABSR.GE. ABSI ) THEN
178
- UR = (SMLNUM * AR) + AI * (SMLNUM * (AI / AR))
179
- ELSE
180
- UR = (SMLNUM * AR) + AI * ((SMLNUM * AI) / AR)
181
- END IF
182
- INVA = CMPLX ( ONE / UR, - BIGNUM / UI )
183
- CALL CSSCAL( N, SMLNUM, X, INCX )
184
- CALL CSCAL( N, INVA, X, INCX )
185
- ELSE IF ( ABS ( UI ).GT. HUGE ) THEN
186
- IF ( ABSI.GE. ABSR ) THEN
187
- UI = (SMLNUM * AI) + AR * (SMLNUM * (AR / AI))
166
+ IF ( (ABS ( UR ).LT. SAFMIN).OR. (ABS ( UI ).LT. SAFMIN) ) THEN
167
+ * This means that both alphaR and alphaI are very small.
168
+ CALL CSCAL( N, CMPLX ( SAFMIN / UR, - SAFMIN / UI ), X, INCX )
169
+ CALL CSSCAL( N, SAFMAX, X, INCX )
170
+ ELSE IF ( (ABS ( UR ).GT. SAFMAX).OR. (ABS ( UI ).GT. SAFMAX) ) THEN
171
+ IF ( (ABSR.GT. OV).OR. (ABSI.GT. OV) ) THEN
172
+ * This means that a and b are both Inf. No need for scaling.
173
+ CALL CSCAL( N, CMPLX ( ONE / UR, - ONE / UI ), X, INCX )
188
174
ELSE
189
- UI = (SMLNUM * AI) + AR * ((SMLNUM * AR) / AI)
175
+ CALL CSSCAL( N, SAFMIN, X, INCX )
176
+ IF ( (ABS ( UR ).GT. OV).OR. (ABS ( UI ).GT. OV) ) THEN
177
+ * Infs were generated. We do proper scaling to avoid them.
178
+ IF ( ABSR.GE. ABSI ) THEN
179
+ * ABS( UR ) <= ABS( UI )
180
+ UR = (SAFMIN * AR) + SAFMIN * (AI * ( AI / AR ))
181
+ UI = (SAFMIN * AI) + AR * ( (SAFMIN * AR) / AI )
182
+ ELSE
183
+ * ABS( UR ) > ABS( UI )
184
+ UR = (SAFMIN * AR) + AI * ( (SAFMIN * AI) / AR )
185
+ UI = (SAFMIN * AI) + SAFMIN * (AR * ( AR / AI ))
186
+ END IF
187
+ CALL CSCAL( N, CMPLX ( ONE / UR, - ONE / UI ), X, INCX )
188
+ ELSE
189
+ CALL CSCAL( N, CMPLX ( SAFMAX / UR, - SAFMAX / UI ),
190
+ $ X, INCX )
191
+ END IF
190
192
END IF
191
- INVA = CMPLX ( BIGNUM / UR, - ONE / UI )
192
- CALL CSSCAL( N, SMLNUM, X, INCX )
193
- CALL CSCAL( N, INVA, X, INCX )
194
- ELSE IF ( (ABS ( UR ).GT. BIGNUM).OR. (ABS ( UI ).GT. BIGNUM) ) THEN
195
- INVA = CMPLX ( BIGNUM / UR, - BIGNUM / UI )
196
- CALL CSSCAL( N, SMLNUM, X, INCX )
197
- CALL CSCAL( N, INVA, X, INCX )
198
193
ELSE
199
- INVA = CMPLX ( ONE / UR, - ONE / UI )
200
- CALL CSCAL( N, INVA, X, INCX )
194
+ CALL CSCAL( N, CMPLX ( ONE / UR, - ONE / UI ), X, INCX )
201
195
END IF
202
196
END IF
203
197
*
0 commit comments