root / src / lapack / double / dlasq3.f @ 1
Historique | Voir | Annoter | Télécharger (8,21 ko)
1 | 1 | equemene | SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL, |
---|---|---|---|
2 | 1 | equemene | $ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1, |
3 | 1 | equemene | $ DN2, G, TAU ) |
4 | 1 | equemene | * |
5 | 1 | equemene | * -- LAPACK routine (version 3.2.2) -- |
6 | 1 | equemene | * |
7 | 1 | equemene | * -- Contributed by Osni Marques of the Lawrence Berkeley National -- |
8 | 1 | equemene | * -- Laboratory and Beresford Parlett of the Univ. of California at -- |
9 | 1 | equemene | * -- Berkeley -- |
10 | 1 | equemene | * -- June 2010 -- |
11 | 1 | equemene | * |
12 | 1 | equemene | * -- LAPACK is a software package provided by Univ. of Tennessee, -- |
13 | 1 | equemene | * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- |
14 | 1 | equemene | * |
15 | 1 | equemene | * .. Scalar Arguments .. |
16 | 1 | equemene | LOGICAL IEEE |
17 | 1 | equemene | INTEGER I0, ITER, N0, NDIV, NFAIL, PP |
18 | 1 | equemene | DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, |
19 | 1 | equemene | $ QMAX, SIGMA, TAU |
20 | 1 | equemene | * .. |
21 | 1 | equemene | * .. Array Arguments .. |
22 | 1 | equemene | DOUBLE PRECISION Z( * ) |
23 | 1 | equemene | * .. |
24 | 1 | equemene | * |
25 | 1 | equemene | * Purpose |
26 | 1 | equemene | * ======= |
27 | 1 | equemene | * |
28 | 1 | equemene | * DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds. |
29 | 1 | equemene | * In case of failure it changes shifts, and tries again until output |
30 | 1 | equemene | * is positive. |
31 | 1 | equemene | * |
32 | 1 | equemene | * Arguments |
33 | 1 | equemene | * ========= |
34 | 1 | equemene | * |
35 | 1 | equemene | * I0 (input) INTEGER |
36 | 1 | equemene | * First index. |
37 | 1 | equemene | * |
38 | 1 | equemene | * N0 (input/output) INTEGER |
39 | 1 | equemene | * Last index. |
40 | 1 | equemene | * |
41 | 1 | equemene | * Z (input) DOUBLE PRECISION array, dimension ( 4*N ) |
42 | 1 | equemene | * Z holds the qd array. |
43 | 1 | equemene | * |
44 | 1 | equemene | * PP (input/output) INTEGER |
45 | 1 | equemene | * PP=0 for ping, PP=1 for pong. |
46 | 1 | equemene | * PP=2 indicates that flipping was applied to the Z array |
47 | 1 | equemene | * and that the initial tests for deflation should not be |
48 | 1 | equemene | * performed. |
49 | 1 | equemene | * |
50 | 1 | equemene | * DMIN (output) DOUBLE PRECISION |
51 | 1 | equemene | * Minimum value of d. |
52 | 1 | equemene | * |
53 | 1 | equemene | * SIGMA (output) DOUBLE PRECISION |
54 | 1 | equemene | * Sum of shifts used in current segment. |
55 | 1 | equemene | * |
56 | 1 | equemene | * DESIG (input/output) DOUBLE PRECISION |
57 | 1 | equemene | * Lower order part of SIGMA |
58 | 1 | equemene | * |
59 | 1 | equemene | * QMAX (input) DOUBLE PRECISION |
60 | 1 | equemene | * Maximum value of q. |
61 | 1 | equemene | * |
62 | 1 | equemene | * NFAIL (output) INTEGER |
63 | 1 | equemene | * Number of times shift was too big. |
64 | 1 | equemene | * |
65 | 1 | equemene | * ITER (output) INTEGER |
66 | 1 | equemene | * Number of iterations. |
67 | 1 | equemene | * |
68 | 1 | equemene | * NDIV (output) INTEGER |
69 | 1 | equemene | * Number of divisions. |
70 | 1 | equemene | * |
71 | 1 | equemene | * IEEE (input) LOGICAL |
72 | 1 | equemene | * Flag for IEEE or non IEEE arithmetic (passed to DLASQ5). |
73 | 1 | equemene | * |
74 | 1 | equemene | * TTYPE (input/output) INTEGER |
75 | 1 | equemene | * Shift type. |
76 | 1 | equemene | * |
77 | 1 | equemene | * DMIN1 (input/output) DOUBLE PRECISION |
78 | 1 | equemene | * |
79 | 1 | equemene | * DMIN2 (input/output) DOUBLE PRECISION |
80 | 1 | equemene | * |
81 | 1 | equemene | * DN (input/output) DOUBLE PRECISION |
82 | 1 | equemene | * |
83 | 1 | equemene | * DN1 (input/output) DOUBLE PRECISION |
84 | 1 | equemene | * |
85 | 1 | equemene | * DN2 (input/output) DOUBLE PRECISION |
86 | 1 | equemene | * |
87 | 1 | equemene | * G (input/output) DOUBLE PRECISION |
88 | 1 | equemene | * |
89 | 1 | equemene | * TAU (input/output) DOUBLE PRECISION |
90 | 1 | equemene | * |
91 | 1 | equemene | * These are passed as arguments in order to save their values |
92 | 1 | equemene | * between calls to DLASQ3. |
93 | 1 | equemene | * |
94 | 1 | equemene | * ===================================================================== |
95 | 1 | equemene | * |
96 | 1 | equemene | * .. Parameters .. |
97 | 1 | equemene | DOUBLE PRECISION CBIAS |
98 | 1 | equemene | PARAMETER ( CBIAS = 1.50D0 ) |
99 | 1 | equemene | DOUBLE PRECISION ZERO, QURTR, HALF, ONE, TWO, HUNDRD |
100 | 1 | equemene | PARAMETER ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0, |
101 | 1 | equemene | $ ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 ) |
102 | 1 | equemene | * .. |
103 | 1 | equemene | * .. Local Scalars .. |
104 | 1 | equemene | INTEGER IPN4, J4, N0IN, NN, TTYPE |
105 | 1 | equemene | DOUBLE PRECISION EPS, S, T, TEMP, TOL, TOL2 |
106 | 1 | equemene | * .. |
107 | 1 | equemene | * .. External Subroutines .. |
108 | 1 | equemene | EXTERNAL DLASQ4, DLASQ5, DLASQ6 |
109 | 1 | equemene | * .. |
110 | 1 | equemene | * .. External Function .. |
111 | 1 | equemene | DOUBLE PRECISION DLAMCH |
112 | 1 | equemene | LOGICAL DISNAN |
113 | 1 | equemene | EXTERNAL DISNAN, DLAMCH |
114 | 1 | equemene | * .. |
115 | 1 | equemene | * .. Intrinsic Functions .. |
116 | 1 | equemene | INTRINSIC ABS, MAX, MIN, SQRT |
117 | 1 | equemene | * .. |
118 | 1 | equemene | * .. Executable Statements .. |
119 | 1 | equemene | * |
120 | 1 | equemene | N0IN = N0 |
121 | 1 | equemene | EPS = DLAMCH( 'Precision' ) |
122 | 1 | equemene | TOL = EPS*HUNDRD |
123 | 1 | equemene | TOL2 = TOL**2 |
124 | 1 | equemene | * |
125 | 1 | equemene | * Check for deflation. |
126 | 1 | equemene | * |
127 | 1 | equemene | 10 CONTINUE |
128 | 1 | equemene | * |
129 | 1 | equemene | IF( N0.LT.I0 ) |
130 | 1 | equemene | $ RETURN |
131 | 1 | equemene | IF( N0.EQ.I0 ) |
132 | 1 | equemene | $ GO TO 20 |
133 | 1 | equemene | NN = 4*N0 + PP |
134 | 1 | equemene | IF( N0.EQ.( I0+1 ) ) |
135 | 1 | equemene | $ GO TO 40 |
136 | 1 | equemene | * |
137 | 1 | equemene | * Check whether E(N0-1) is negligible, 1 eigenvalue. |
138 | 1 | equemene | * |
139 | 1 | equemene | IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND. |
140 | 1 | equemene | $ Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) ) |
141 | 1 | equemene | $ GO TO 30 |
142 | 1 | equemene | * |
143 | 1 | equemene | 20 CONTINUE |
144 | 1 | equemene | * |
145 | 1 | equemene | Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA |
146 | 1 | equemene | N0 = N0 - 1 |
147 | 1 | equemene | GO TO 10 |
148 | 1 | equemene | * |
149 | 1 | equemene | * Check whether E(N0-2) is negligible, 2 eigenvalues. |
150 | 1 | equemene | * |
151 | 1 | equemene | 30 CONTINUE |
152 | 1 | equemene | * |
153 | 1 | equemene | IF( Z( NN-9 ).GT.TOL2*SIGMA .AND. |
154 | 1 | equemene | $ Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) ) |
155 | 1 | equemene | $ GO TO 50 |
156 | 1 | equemene | * |
157 | 1 | equemene | 40 CONTINUE |
158 | 1 | equemene | * |
159 | 1 | equemene | IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN |
160 | 1 | equemene | S = Z( NN-3 ) |
161 | 1 | equemene | Z( NN-3 ) = Z( NN-7 ) |
162 | 1 | equemene | Z( NN-7 ) = S |
163 | 1 | equemene | END IF |
164 | 1 | equemene | IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2 ) THEN |
165 | 1 | equemene | T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) ) |
166 | 1 | equemene | S = Z( NN-3 )*( Z( NN-5 ) / T ) |
167 | 1 | equemene | IF( S.LE.T ) THEN |
168 | 1 | equemene | S = Z( NN-3 )*( Z( NN-5 ) / |
169 | 1 | equemene | $ ( T*( ONE+SQRT( ONE+S / T ) ) ) ) |
170 | 1 | equemene | ELSE |
171 | 1 | equemene | S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) ) |
172 | 1 | equemene | END IF |
173 | 1 | equemene | T = Z( NN-7 ) + ( S+Z( NN-5 ) ) |
174 | 1 | equemene | Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T ) |
175 | 1 | equemene | Z( NN-7 ) = T |
176 | 1 | equemene | END IF |
177 | 1 | equemene | Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA |
178 | 1 | equemene | Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA |
179 | 1 | equemene | N0 = N0 - 2 |
180 | 1 | equemene | GO TO 10 |
181 | 1 | equemene | * |
182 | 1 | equemene | 50 CONTINUE |
183 | 1 | equemene | IF( PP.EQ.2 ) |
184 | 1 | equemene | $ PP = 0 |
185 | 1 | equemene | * |
186 | 1 | equemene | * Reverse the qd-array, if warranted. |
187 | 1 | equemene | * |
188 | 1 | equemene | IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN |
189 | 1 | equemene | IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN |
190 | 1 | equemene | IPN4 = 4*( I0+N0 ) |
191 | 1 | equemene | DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4 |
192 | 1 | equemene | TEMP = Z( J4-3 ) |
193 | 1 | equemene | Z( J4-3 ) = Z( IPN4-J4-3 ) |
194 | 1 | equemene | Z( IPN4-J4-3 ) = TEMP |
195 | 1 | equemene | TEMP = Z( J4-2 ) |
196 | 1 | equemene | Z( J4-2 ) = Z( IPN4-J4-2 ) |
197 | 1 | equemene | Z( IPN4-J4-2 ) = TEMP |
198 | 1 | equemene | TEMP = Z( J4-1 ) |
199 | 1 | equemene | Z( J4-1 ) = Z( IPN4-J4-5 ) |
200 | 1 | equemene | Z( IPN4-J4-5 ) = TEMP |
201 | 1 | equemene | TEMP = Z( J4 ) |
202 | 1 | equemene | Z( J4 ) = Z( IPN4-J4-4 ) |
203 | 1 | equemene | Z( IPN4-J4-4 ) = TEMP |
204 | 1 | equemene | 60 CONTINUE |
205 | 1 | equemene | IF( N0-I0.LE.4 ) THEN |
206 | 1 | equemene | Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 ) |
207 | 1 | equemene | Z( 4*N0-PP ) = Z( 4*I0-PP ) |
208 | 1 | equemene | END IF |
209 | 1 | equemene | DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) ) |
210 | 1 | equemene | Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ), |
211 | 1 | equemene | $ Z( 4*I0+PP+3 ) ) |
212 | 1 | equemene | Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ), |
213 | 1 | equemene | $ Z( 4*I0-PP+4 ) ) |
214 | 1 | equemene | QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) ) |
215 | 1 | equemene | DMIN = -ZERO |
216 | 1 | equemene | END IF |
217 | 1 | equemene | END IF |
218 | 1 | equemene | * |
219 | 1 | equemene | * Choose a shift. |
220 | 1 | equemene | * |
221 | 1 | equemene | CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1, |
222 | 1 | equemene | $ DN2, TAU, TTYPE, G ) |
223 | 1 | equemene | * |
224 | 1 | equemene | * Call dqds until DMIN > 0. |
225 | 1 | equemene | * |
226 | 1 | equemene | 70 CONTINUE |
227 | 1 | equemene | * |
228 | 1 | equemene | CALL DLASQ5( I0, N0, Z, PP, TAU, DMIN, DMIN1, DMIN2, DN, |
229 | 1 | equemene | $ DN1, DN2, IEEE ) |
230 | 1 | equemene | * |
231 | 1 | equemene | NDIV = NDIV + ( N0-I0+2 ) |
232 | 1 | equemene | ITER = ITER + 1 |
233 | 1 | equemene | * |
234 | 1 | equemene | * Check status. |
235 | 1 | equemene | * |
236 | 1 | equemene | IF( DMIN.GE.ZERO .AND. DMIN1.GT.ZERO ) THEN |
237 | 1 | equemene | * |
238 | 1 | equemene | * Success. |
239 | 1 | equemene | * |
240 | 1 | equemene | GO TO 90 |
241 | 1 | equemene | * |
242 | 1 | equemene | ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND. |
243 | 1 | equemene | $ Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND. |
244 | 1 | equemene | $ ABS( DN ).LT.TOL*SIGMA ) THEN |
245 | 1 | equemene | * |
246 | 1 | equemene | * Convergence hidden by negative DN. |
247 | 1 | equemene | * |
248 | 1 | equemene | Z( 4*( N0-1 )-PP+2 ) = ZERO |
249 | 1 | equemene | DMIN = ZERO |
250 | 1 | equemene | GO TO 90 |
251 | 1 | equemene | ELSE IF( DMIN.LT.ZERO ) THEN |
252 | 1 | equemene | * |
253 | 1 | equemene | * TAU too big. Select new TAU and try again. |
254 | 1 | equemene | * |
255 | 1 | equemene | NFAIL = NFAIL + 1 |
256 | 1 | equemene | IF( TTYPE.LT.-22 ) THEN |
257 | 1 | equemene | * |
258 | 1 | equemene | * Failed twice. Play it safe. |
259 | 1 | equemene | * |
260 | 1 | equemene | TAU = ZERO |
261 | 1 | equemene | ELSE IF( DMIN1.GT.ZERO ) THEN |
262 | 1 | equemene | * |
263 | 1 | equemene | * Late failure. Gives excellent shift. |
264 | 1 | equemene | * |
265 | 1 | equemene | TAU = ( TAU+DMIN )*( ONE-TWO*EPS ) |
266 | 1 | equemene | TTYPE = TTYPE - 11 |
267 | 1 | equemene | ELSE |
268 | 1 | equemene | * |
269 | 1 | equemene | * Early failure. Divide by 4. |
270 | 1 | equemene | * |
271 | 1 | equemene | TAU = QURTR*TAU |
272 | 1 | equemene | TTYPE = TTYPE - 12 |
273 | 1 | equemene | END IF |
274 | 1 | equemene | GO TO 70 |
275 | 1 | equemene | ELSE IF( DISNAN( DMIN ) ) THEN |
276 | 1 | equemene | * |
277 | 1 | equemene | * NaN. |
278 | 1 | equemene | * |
279 | 1 | equemene | IF( TAU.EQ.ZERO ) THEN |
280 | 1 | equemene | GO TO 80 |
281 | 1 | equemene | ELSE |
282 | 1 | equemene | TAU = ZERO |
283 | 1 | equemene | GO TO 70 |
284 | 1 | equemene | END IF |
285 | 1 | equemene | ELSE |
286 | 1 | equemene | * |
287 | 1 | equemene | * Possible underflow. Play it safe. |
288 | 1 | equemene | * |
289 | 1 | equemene | GO TO 80 |
290 | 1 | equemene | END IF |
291 | 1 | equemene | * |
292 | 1 | equemene | * Risk of underflow. |
293 | 1 | equemene | * |
294 | 1 | equemene | 80 CONTINUE |
295 | 1 | equemene | CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 ) |
296 | 1 | equemene | NDIV = NDIV + ( N0-I0+2 ) |
297 | 1 | equemene | ITER = ITER + 1 |
298 | 1 | equemene | TAU = ZERO |
299 | 1 | equemene | * |
300 | 1 | equemene | 90 CONTINUE |
301 | 1 | equemene | IF( TAU.LT.SIGMA ) THEN |
302 | 1 | equemene | DESIG = DESIG + TAU |
303 | 1 | equemene | T = SIGMA + DESIG |
304 | 1 | equemene | DESIG = DESIG - ( T-SIGMA ) |
305 | 1 | equemene | ELSE |
306 | 1 | equemene | T = SIGMA + TAU |
307 | 1 | equemene | DESIG = SIGMA - ( T-TAU ) + DESIG |
308 | 1 | equemene | END IF |
309 | 1 | equemene | SIGMA = T |
310 | 1 | equemene | * |
311 | 1 | equemene | RETURN |
312 | 1 | equemene | * |
313 | 1 | equemene | * End of DLASQ3 |
314 | 1 | equemene | * |
315 | 1 | equemene | END |