Skip to content

Commit 59a1772

Browse files
(Last?) version of RSCL
1 parent 831ac96 commit 59a1772

File tree

3 files changed

+52
-72
lines changed

3 files changed

+52
-72
lines changed

SRC/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ CLASRC = \
260260
cppcon.o cppequ.o cpprfs.o cppsv.o cppsvx.o cpptrf.o cpptri.o cpptrs.o \
261261
cptcon.o cpteqr.o cptrfs.o cptsv.o cptsvx.o cpttrf.o cpttrs.o cptts2.o \
262262
crot.o cspcon.o cspmv.o cspr.o csprfs.o cspsv.o \
263-
cspsvx.o csptrf.o csptri.o csptrs.o csrscl.o cstedc.o \
263+
cspsvx.o csptrf.o csptri.o csptrs.o csrscl.o crscl.o cstedc.o \
264264
cstegr.o cstein.o csteqr.o \
265265
csycon.o csymv.o \
266266
csyr.o csyrfs.o csysv.o csysvx.o csytf2.o csytrf.o csytri.o csytri2.o csytri2x.o \

SRC/cgetf2.f

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,14 @@ SUBROUTINE CGETF2( M, N, A, LDA, IPIV, INFO )
126126
$ ZERO = ( 0.0E+0, 0.0E+0 ) )
127127
* ..
128128
* .. Local Scalars ..
129-
REAL SFMIN
130-
INTEGER I, J, JP
129+
INTEGER J, JP
131130
* ..
132131
* .. External Functions ..
133-
REAL SLAMCH
134132
INTEGER ICAMAX
135-
EXTERNAL SLAMCH, ICAMAX
133+
EXTERNAL ICAMAX
136134
* ..
137135
* .. External Subroutines ..
138-
EXTERNAL CGERU, CSCAL, CSWAP, XERBLA
136+
EXTERNAL CGERU, CRSCL, CSWAP, XERBLA
139137
* ..
140138
* .. Intrinsic Functions ..
141139
INTRINSIC MAX, MIN
@@ -161,10 +159,6 @@ SUBROUTINE CGETF2( M, N, A, LDA, IPIV, INFO )
161159
*
162160
IF( M.EQ.0 .OR. N.EQ.0 )
163161
$ RETURN
164-
*
165-
* Compute machine safe minimum
166-
*
167-
SFMIN = SLAMCH('S')
168162
*
169163
DO 10 J = 1, MIN( M, N )
170164
*
@@ -181,16 +175,8 @@ SUBROUTINE CGETF2( M, N, A, LDA, IPIV, INFO )
181175
*
182176
* Compute elements J+1:M of J-th column.
183177
*
184-
IF( J.LT.M ) THEN
185-
IF( ABS(A( J, J )) .GE. SFMIN ) THEN
186-
CALL CSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 )
187-
ELSE
188-
DO 20 I = 1, M-J
189-
A( J+I, J ) = A( J+I, J ) / A( J, J )
190-
20 CONTINUE
191-
END IF
192-
! CALL CRSCL( M-J, A( J, J ), A( J+1, J ), 1 )
193-
END IF
178+
IF( J.LT.M )
179+
$ CALL CRSCL( M-J, A( J, J ), A( J+1, J ), 1 )
194180
*
195181
ELSE IF( INFO.EQ.0 ) THEN
196182
*

SRC/crscl.f

Lines changed: 46 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,16 @@ SUBROUTINE CRSCL( N, A, X, INCX )
101101
PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
102102
* ..
103103
* .. Local Scalars ..
104-
REAL BIGNUM, SMLNUM, HUGE, AR, AI, ABSR, ABSI, UR
104+
REAL SAFMAX, SAFMIN, OV, AR, AI, ABSR, ABSI, UR
105105
% , UI
106-
COMPLEX INVA
107106
* ..
108107
* .. External Functions ..
109108
REAL SLAMCH
110109
COMPLEX CLADIV
111110
EXTERNAL SLAMCH, CLADIV
112111
* ..
113112
* .. External Subroutines ..
114-
EXTERNAL CSCAL, CSSCAL
113+
EXTERNAL CSCAL, CSSCAL, CSRSCL
115114
* ..
116115
* .. Intrinsic Functions ..
117116
INTRINSIC ABS
@@ -125,9 +124,9 @@ SUBROUTINE CRSCL( N, A, X, INCX )
125124
*
126125
* Get machine parameters
127126
*
128-
SMLNUM = SLAMCH( 'S' )
129-
BIGNUM = ONE / SMLNUM
130-
HUGE = SLAMCH( 'O' )
127+
SAFMIN = SLAMCH( 'S' )
128+
SAFMAX = ONE / SAFMIN
129+
OV = SLAMCH( 'O' )
131130
*
132131
* Initialize constants related to A.
133132
*
@@ -136,68 +135,63 @@ SUBROUTINE CRSCL( N, A, X, INCX )
136135
ABSR = ABS( AR )
137136
ABSI = ABS( AI )
138137
*
139-
IF( ABSI.EQ.ZERO ) THEN
138+
IF( AI.EQ.ZERO ) THEN
140139
* If alpha is real, then we can use csrscl
141140
CALL CSRSCL( N, AR, X, INCX )
142141
*
143-
ELSE IF( ABSR.EQ.ZERO ) THEN
142+
ELSE IF( AR.EQ.ZERO ) THEN
144143
* If alpha has a zero real part, then we follow the same rules as if
145144
* 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 )
154151
ELSE
155-
INVA = CMPLX( ZERO, -ONE / AI )
156-
CALL CSCAL( N, INVA, X, INCX )
152+
CALL CSCAL( N, CMPLX( ZERO, -ONE / AI ), X, INCX )
157153
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 )
164154
*
165155
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.
168157
* 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.
169163
UR = AR + AI * ( AI / AR )
170164
UI = AI + AR * ( AR / AI )
171165
*
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 )
188174
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
190192
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 )
198193
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 )
201195
END IF
202196
END IF
203197
*

0 commit comments

Comments
 (0)