comparison libcruft/lapack/slamc2.f @ 7789:82be108cc558

First attempt at single precision tyeps * * * corrections to qrupdate single precision routines * * * prefer demotion to single over promotion to double * * * Add single precision support to log2 function * * * Trivial PROJECT file update * * * Cache optimized hermitian/transpose methods * * * Add tests for tranpose/hermitian and ChangeLog entry for new transpose code
author David Bateman <dbateman@free.fr>
date Sun, 27 Apr 2008 22:34:17 +0200
parents
children
comparison
equal deleted inserted replaced
7788:45f5faba05a2 7789:82be108cc558
1 SUBROUTINE SLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX )
2 *
3 * -- LAPACK auxiliary routine (version 3.1) --
4 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
5 * November 2006
6 *
7 * .. Scalar Arguments ..
8 LOGICAL RND
9 INTEGER BETA, EMAX, EMIN, T
10 REAL EPS, RMAX, RMIN
11 * ..
12 *
13 * Purpose
14 * =======
15 *
16 * SLAMC2 determines the machine parameters specified in its argument
17 * list.
18 *
19 * Arguments
20 * =========
21 *
22 * BETA (output) INTEGER
23 * The base of the machine.
24 *
25 * T (output) INTEGER
26 * The number of ( BETA ) digits in the mantissa.
27 *
28 * RND (output) LOGICAL
29 * Specifies whether proper rounding ( RND = .TRUE. ) or
30 * chopping ( RND = .FALSE. ) occurs in addition. This may not
31 * be a reliable guide to the way in which the machine performs
32 * its arithmetic.
33 *
34 * EPS (output) REAL
35 * The smallest positive number such that
36 *
37 * fl( 1.0 - EPS ) .LT. 1.0,
38 *
39 * where fl denotes the computed value.
40 *
41 * EMIN (output) INTEGER
42 * The minimum exponent before (gradual) underflow occurs.
43 *
44 * RMIN (output) REAL
45 * The smallest normalized number for the machine, given by
46 * BASE**( EMIN - 1 ), where BASE is the floating point value
47 * of BETA.
48 *
49 * EMAX (output) INTEGER
50 * The maximum exponent before overflow occurs.
51 *
52 * RMAX (output) REAL
53 * The largest positive number for the machine, given by
54 * BASE**EMAX * ( 1 - EPS ), where BASE is the floating point
55 * value of BETA.
56 *
57 * Further Details
58 * ===============
59 *
60 * The computation of EPS is based on a routine PARANOIA by
61 * W. Kahan of the University of California at Berkeley.
62 *
63 * =====================================================================
64 *
65 * .. Local Scalars ..
66 LOGICAL FIRST, IEEE, IWARN, LIEEE1, LRND
67 INTEGER GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT,
68 $ NGNMIN, NGPMIN
69 REAL A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE,
70 $ SIXTH, SMALL, THIRD, TWO, ZERO
71 * ..
72 * .. External Functions ..
73 REAL SLAMC3
74 EXTERNAL SLAMC3
75 * ..
76 * .. External Subroutines ..
77 EXTERNAL SLAMC1, SLAMC4, SLAMC5
78 * ..
79 * .. Intrinsic Functions ..
80 INTRINSIC ABS, MAX, MIN
81 * ..
82 * .. Save statement ..
83 SAVE FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX,
84 $ LRMIN, LT
85 * ..
86 * .. Data statements ..
87 DATA FIRST / .TRUE. / , IWARN / .FALSE. /
88 * ..
89 * .. Executable Statements ..
90 *
91 IF( FIRST ) THEN
92 ZERO = 0
93 ONE = 1
94 TWO = 2
95 *
96 * LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of
97 * BETA, T, RND, EPS, EMIN and RMIN.
98 *
99 * Throughout this routine we use the function SLAMC3 to ensure
100 * that relevant values are stored and not held in registers, or
101 * are not affected by optimizers.
102 *
103 * SLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1.
104 *
105 CALL SLAMC1( LBETA, LT, LRND, LIEEE1 )
106 *
107 * Start to find EPS.
108 *
109 B = LBETA
110 A = B**( -LT )
111 LEPS = A
112 *
113 * Try some tricks to see whether or not this is the correct EPS.
114 *
115 B = TWO / 3
116 HALF = ONE / 2
117 SIXTH = SLAMC3( B, -HALF )
118 THIRD = SLAMC3( SIXTH, SIXTH )
119 B = SLAMC3( THIRD, -HALF )
120 B = SLAMC3( B, SIXTH )
121 B = ABS( B )
122 IF( B.LT.LEPS )
123 $ B = LEPS
124 *
125 LEPS = 1
126 *
127 *+ WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP
128 10 CONTINUE
129 IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN
130 LEPS = B
131 C = SLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) )
132 C = SLAMC3( HALF, -C )
133 B = SLAMC3( HALF, C )
134 C = SLAMC3( HALF, -B )
135 B = SLAMC3( HALF, C )
136 GO TO 10
137 END IF
138 *+ END WHILE
139 *
140 IF( A.LT.LEPS )
141 $ LEPS = A
142 *
143 * Computation of EPS complete.
144 *
145 * Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)).
146 * Keep dividing A by BETA until (gradual) underflow occurs. This
147 * is detected when we cannot recover the previous A.
148 *
149 RBASE = ONE / LBETA
150 SMALL = ONE
151 DO 20 I = 1, 3
152 SMALL = SLAMC3( SMALL*RBASE, ZERO )
153 20 CONTINUE
154 A = SLAMC3( ONE, SMALL )
155 CALL SLAMC4( NGPMIN, ONE, LBETA )
156 CALL SLAMC4( NGNMIN, -ONE, LBETA )
157 CALL SLAMC4( GPMIN, A, LBETA )
158 CALL SLAMC4( GNMIN, -A, LBETA )
159 IEEE = .FALSE.
160 *
161 IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN
162 IF( NGPMIN.EQ.GPMIN ) THEN
163 LEMIN = NGPMIN
164 * ( Non twos-complement machines, no gradual underflow;
165 * e.g., VAX )
166 ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN
167 LEMIN = NGPMIN - 1 + LT
168 IEEE = .TRUE.
169 * ( Non twos-complement machines, with gradual underflow;
170 * e.g., IEEE standard followers )
171 ELSE
172 LEMIN = MIN( NGPMIN, GPMIN )
173 * ( A guess; no known machine )
174 IWARN = .TRUE.
175 END IF
176 *
177 ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN
178 IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN
179 LEMIN = MAX( NGPMIN, NGNMIN )
180 * ( Twos-complement machines, no gradual underflow;
181 * e.g., CYBER 205 )
182 ELSE
183 LEMIN = MIN( NGPMIN, NGNMIN )
184 * ( A guess; no known machine )
185 IWARN = .TRUE.
186 END IF
187 *
188 ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND.
189 $ ( GPMIN.EQ.GNMIN ) ) THEN
190 IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN
191 LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT
192 * ( Twos-complement machines with gradual underflow;
193 * no known machine )
194 ELSE
195 LEMIN = MIN( NGPMIN, NGNMIN )
196 * ( A guess; no known machine )
197 IWARN = .TRUE.
198 END IF
199 *
200 ELSE
201 LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN )
202 * ( A guess; no known machine )
203 IWARN = .TRUE.
204 END IF
205 FIRST = .FALSE.
206 ***
207 * Comment out this if block if EMIN is ok
208 IF( IWARN ) THEN
209 FIRST = .TRUE.
210 WRITE( 6, FMT = 9999 )LEMIN
211 END IF
212 ***
213 *
214 * Assume IEEE arithmetic if we found denormalised numbers above,
215 * or if arithmetic seems to round in the IEEE style, determined
216 * in routine SLAMC1. A true IEEE machine should have both things
217 * true; however, faulty machines may have one or the other.
218 *
219 IEEE = IEEE .OR. LIEEE1
220 *
221 * Compute RMIN by successive division by BETA. We could compute
222 * RMIN as BASE**( EMIN - 1 ), but some machines underflow during
223 * this computation.
224 *
225 LRMIN = 1
226 DO 30 I = 1, 1 - LEMIN
227 LRMIN = SLAMC3( LRMIN*RBASE, ZERO )
228 30 CONTINUE
229 *
230 * Finally, call SLAMC5 to compute EMAX and RMAX.
231 *
232 CALL SLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX )
233 END IF
234 *
235 BETA = LBETA
236 T = LT
237 RND = LRND
238 EPS = LEPS
239 EMIN = LEMIN
240 RMIN = LRMIN
241 EMAX = LEMAX
242 RMAX = LRMAX
243 *
244 RETURN
245 *
246 9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-',
247 $ ' EMIN = ', I8, /
248 $ ' If, after inspection, the value EMIN looks',
249 $ ' acceptable please comment out ',
250 $ / ' the IF block as marked within the code of routine',
251 $ ' SLAMC2,', / ' otherwise supply EMIN explicitly.', / )
252 *
253 * End of SLAMC2
254 *
255 END