Statistiques
| Révision :

root / src / lapack / double / dlaed6.f @ 10

Historique | Voir | Annoter | Télécharger (9,39 ko)

1 1 pfleura2
      SUBROUTINE DLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, INFO )
2 1 pfleura2
*
3 1 pfleura2
*  -- LAPACK routine (version 3.2) --
4 1 pfleura2
*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
5 1 pfleura2
*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
6 1 pfleura2
*     February 2007
7 1 pfleura2
*
8 1 pfleura2
*     .. Scalar Arguments ..
9 1 pfleura2
      LOGICAL            ORGATI
10 1 pfleura2
      INTEGER            INFO, KNITER
11 1 pfleura2
      DOUBLE PRECISION   FINIT, RHO, TAU
12 1 pfleura2
*     ..
13 1 pfleura2
*     .. Array Arguments ..
14 1 pfleura2
      DOUBLE PRECISION   D( 3 ), Z( 3 )
15 1 pfleura2
*     ..
16 1 pfleura2
*
17 1 pfleura2
*  Purpose
18 1 pfleura2
*  =======
19 1 pfleura2
*
20 1 pfleura2
*  DLAED6 computes the positive or negative root (closest to the origin)
21 1 pfleura2
*  of
22 1 pfleura2
*                   z(1)        z(2)        z(3)
23 1 pfleura2
*  f(x) =   rho + --------- + ---------- + ---------
24 1 pfleura2
*                  d(1)-x      d(2)-x      d(3)-x
25 1 pfleura2
*
26 1 pfleura2
*  It is assumed that
27 1 pfleura2
*
28 1 pfleura2
*        if ORGATI = .true. the root is between d(2) and d(3);
29 1 pfleura2
*        otherwise it is between d(1) and d(2)
30 1 pfleura2
*
31 1 pfleura2
*  This routine will be called by DLAED4 when necessary. In most cases,
32 1 pfleura2
*  the root sought is the smallest in magnitude, though it might not be
33 1 pfleura2
*  in some extremely rare situations.
34 1 pfleura2
*
35 1 pfleura2
*  Arguments
36 1 pfleura2
*  =========
37 1 pfleura2
*
38 1 pfleura2
*  KNITER       (input) INTEGER
39 1 pfleura2
*               Refer to DLAED4 for its significance.
40 1 pfleura2
*
41 1 pfleura2
*  ORGATI       (input) LOGICAL
42 1 pfleura2
*               If ORGATI is true, the needed root is between d(2) and
43 1 pfleura2
*               d(3); otherwise it is between d(1) and d(2).  See
44 1 pfleura2
*               DLAED4 for further details.
45 1 pfleura2
*
46 1 pfleura2
*  RHO          (input) DOUBLE PRECISION
47 1 pfleura2
*               Refer to the equation f(x) above.
48 1 pfleura2
*
49 1 pfleura2
*  D            (input) DOUBLE PRECISION array, dimension (3)
50 1 pfleura2
*               D satisfies d(1) < d(2) < d(3).
51 1 pfleura2
*
52 1 pfleura2
*  Z            (input) DOUBLE PRECISION array, dimension (3)
53 1 pfleura2
*               Each of the elements in z must be positive.
54 1 pfleura2
*
55 1 pfleura2
*  FINIT        (input) DOUBLE PRECISION
56 1 pfleura2
*               The value of f at 0. It is more accurate than the one
57 1 pfleura2
*               evaluated inside this routine (if someone wants to do
58 1 pfleura2
*               so).
59 1 pfleura2
*
60 1 pfleura2
*  TAU          (output) DOUBLE PRECISION
61 1 pfleura2
*               The root of the equation f(x).
62 1 pfleura2
*
63 1 pfleura2
*  INFO         (output) INTEGER
64 1 pfleura2
*               = 0: successful exit
65 1 pfleura2
*               > 0: if INFO = 1, failure to converge
66 1 pfleura2
*
67 1 pfleura2
*  Further Details
68 1 pfleura2
*  ===============
69 1 pfleura2
*
70 1 pfleura2
*  30/06/99: Based on contributions by
71 1 pfleura2
*     Ren-Cang Li, Computer Science Division, University of California
72 1 pfleura2
*     at Berkeley, USA
73 1 pfleura2
*
74 1 pfleura2
*  10/02/03: This version has a few statements commented out for thread
75 1 pfleura2
*  safety (machine parameters are computed on each entry). SJH.
76 1 pfleura2
*
77 1 pfleura2
*  05/10/06: Modified from a new version of Ren-Cang Li, use
78 1 pfleura2
*     Gragg-Thornton-Warner cubic convergent scheme for better stability.
79 1 pfleura2
*
80 1 pfleura2
*  =====================================================================
81 1 pfleura2
*
82 1 pfleura2
*     .. Parameters ..
83 1 pfleura2
      INTEGER            MAXIT
84 1 pfleura2
      PARAMETER          ( MAXIT = 40 )
85 1 pfleura2
      DOUBLE PRECISION   ZERO, ONE, TWO, THREE, FOUR, EIGHT
86 1 pfleura2
      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
87 1 pfleura2
     $                   THREE = 3.0D0, FOUR = 4.0D0, EIGHT = 8.0D0 )
88 1 pfleura2
*     ..
89 1 pfleura2
*     .. External Functions ..
90 1 pfleura2
      DOUBLE PRECISION   DLAMCH
91 1 pfleura2
      EXTERNAL           DLAMCH
92 1 pfleura2
*     ..
93 1 pfleura2
*     .. Local Arrays ..
94 1 pfleura2
      DOUBLE PRECISION   DSCALE( 3 ), ZSCALE( 3 )
95 1 pfleura2
*     ..
96 1 pfleura2
*     .. Local Scalars ..
97 1 pfleura2
      LOGICAL            SCALE
98 1 pfleura2
      INTEGER            I, ITER, NITER
99 1 pfleura2
      DOUBLE PRECISION   A, B, BASE, C, DDF, DF, EPS, ERRETM, ETA, F,
100 1 pfleura2
     $                   FC, SCLFAC, SCLINV, SMALL1, SMALL2, SMINV1,
101 1 pfleura2
     $                   SMINV2, TEMP, TEMP1, TEMP2, TEMP3, TEMP4,
102 1 pfleura2
     $                   LBD, UBD
103 1 pfleura2
*     ..
104 1 pfleura2
*     .. Intrinsic Functions ..
105 1 pfleura2
      INTRINSIC          ABS, INT, LOG, MAX, MIN, SQRT
106 1 pfleura2
*     ..
107 1 pfleura2
*     .. Executable Statements ..
108 1 pfleura2
*
109 1 pfleura2
      INFO = 0
110 1 pfleura2
*
111 1 pfleura2
      IF( ORGATI ) THEN
112 1 pfleura2
         LBD = D(2)
113 1 pfleura2
         UBD = D(3)
114 1 pfleura2
      ELSE
115 1 pfleura2
         LBD = D(1)
116 1 pfleura2
         UBD = D(2)
117 1 pfleura2
      END IF
118 1 pfleura2
      IF( FINIT .LT. ZERO )THEN
119 1 pfleura2
         LBD = ZERO
120 1 pfleura2
      ELSE
121 1 pfleura2
         UBD = ZERO
122 1 pfleura2
      END IF
123 1 pfleura2
*
124 1 pfleura2
      NITER = 1
125 1 pfleura2
      TAU = ZERO
126 1 pfleura2
      IF( KNITER.EQ.2 ) THEN
127 1 pfleura2
         IF( ORGATI ) THEN
128 1 pfleura2
            TEMP = ( D( 3 )-D( 2 ) ) / TWO
129 1 pfleura2
            C = RHO + Z( 1 ) / ( ( D( 1 )-D( 2 ) )-TEMP )
130 1 pfleura2
            A = C*( D( 2 )+D( 3 ) ) + Z( 2 ) + Z( 3 )
131 1 pfleura2
            B = C*D( 2 )*D( 3 ) + Z( 2 )*D( 3 ) + Z( 3 )*D( 2 )
132 1 pfleura2
         ELSE
133 1 pfleura2
            TEMP = ( D( 1 )-D( 2 ) ) / TWO
134 1 pfleura2
            C = RHO + Z( 3 ) / ( ( D( 3 )-D( 2 ) )-TEMP )
135 1 pfleura2
            A = C*( D( 1 )+D( 2 ) ) + Z( 1 ) + Z( 2 )
136 1 pfleura2
            B = C*D( 1 )*D( 2 ) + Z( 1 )*D( 2 ) + Z( 2 )*D( 1 )
137 1 pfleura2
         END IF
138 1 pfleura2
         TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
139 1 pfleura2
         A = A / TEMP
140 1 pfleura2
         B = B / TEMP
141 1 pfleura2
         C = C / TEMP
142 1 pfleura2
         IF( C.EQ.ZERO ) THEN
143 1 pfleura2
            TAU = B / A
144 1 pfleura2
         ELSE IF( A.LE.ZERO ) THEN
145 1 pfleura2
            TAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
146 1 pfleura2
         ELSE
147 1 pfleura2
            TAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
148 1 pfleura2
         END IF
149 1 pfleura2
         IF( TAU .LT. LBD .OR. TAU .GT. UBD )
150 1 pfleura2
     $      TAU = ( LBD+UBD )/TWO
151 1 pfleura2
         IF( D(1).EQ.TAU .OR. D(2).EQ.TAU .OR. D(3).EQ.TAU ) THEN
152 1 pfleura2
            TAU = ZERO
153 1 pfleura2
         ELSE
154 1 pfleura2
            TEMP = FINIT + TAU*Z(1)/( D(1)*( D( 1 )-TAU ) ) +
155 1 pfleura2
     $                     TAU*Z(2)/( D(2)*( D( 2 )-TAU ) ) +
156 1 pfleura2
     $                     TAU*Z(3)/( D(3)*( D( 3 )-TAU ) )
157 1 pfleura2
            IF( TEMP .LE. ZERO )THEN
158 1 pfleura2
               LBD = TAU
159 1 pfleura2
            ELSE
160 1 pfleura2
               UBD = TAU
161 1 pfleura2
            END IF
162 1 pfleura2
            IF( ABS( FINIT ).LE.ABS( TEMP ) )
163 1 pfleura2
     $         TAU = ZERO
164 1 pfleura2
         END IF
165 1 pfleura2
      END IF
166 1 pfleura2
*
167 1 pfleura2
*     get machine parameters for possible scaling to avoid overflow
168 1 pfleura2
*
169 1 pfleura2
*     modified by Sven: parameters SMALL1, SMINV1, SMALL2,
170 1 pfleura2
*     SMINV2, EPS are not SAVEd anymore between one call to the
171 1 pfleura2
*     others but recomputed at each call
172 1 pfleura2
*
173 1 pfleura2
      EPS = DLAMCH( 'Epsilon' )
174 1 pfleura2
      BASE = DLAMCH( 'Base' )
175 1 pfleura2
      SMALL1 = BASE**( INT( LOG( DLAMCH( 'SafMin' ) ) / LOG( BASE ) /
176 1 pfleura2
     $         THREE ) )
177 1 pfleura2
      SMINV1 = ONE / SMALL1
178 1 pfleura2
      SMALL2 = SMALL1*SMALL1
179 1 pfleura2
      SMINV2 = SMINV1*SMINV1
180 1 pfleura2
*
181 1 pfleura2
*     Determine if scaling of inputs necessary to avoid overflow
182 1 pfleura2
*     when computing 1/TEMP**3
183 1 pfleura2
*
184 1 pfleura2
      IF( ORGATI ) THEN
185 1 pfleura2
         TEMP = MIN( ABS( D( 2 )-TAU ), ABS( D( 3 )-TAU ) )
186 1 pfleura2
      ELSE
187 1 pfleura2
         TEMP = MIN( ABS( D( 1 )-TAU ), ABS( D( 2 )-TAU ) )
188 1 pfleura2
      END IF
189 1 pfleura2
      SCALE = .FALSE.
190 1 pfleura2
      IF( TEMP.LE.SMALL1 ) THEN
191 1 pfleura2
         SCALE = .TRUE.
192 1 pfleura2
         IF( TEMP.LE.SMALL2 ) THEN
193 1 pfleura2
*
194 1 pfleura2
*        Scale up by power of radix nearest 1/SAFMIN**(2/3)
195 1 pfleura2
*
196 1 pfleura2
            SCLFAC = SMINV2
197 1 pfleura2
            SCLINV = SMALL2
198 1 pfleura2
         ELSE
199 1 pfleura2
*
200 1 pfleura2
*        Scale up by power of radix nearest 1/SAFMIN**(1/3)
201 1 pfleura2
*
202 1 pfleura2
            SCLFAC = SMINV1
203 1 pfleura2
            SCLINV = SMALL1
204 1 pfleura2
         END IF
205 1 pfleura2
*
206 1 pfleura2
*        Scaling up safe because D, Z, TAU scaled elsewhere to be O(1)
207 1 pfleura2
*
208 1 pfleura2
         DO 10 I = 1, 3
209 1 pfleura2
            DSCALE( I ) = D( I )*SCLFAC
210 1 pfleura2
            ZSCALE( I ) = Z( I )*SCLFAC
211 1 pfleura2
   10    CONTINUE
212 1 pfleura2
         TAU = TAU*SCLFAC
213 1 pfleura2
         LBD = LBD*SCLFAC
214 1 pfleura2
         UBD = UBD*SCLFAC
215 1 pfleura2
      ELSE
216 1 pfleura2
*
217 1 pfleura2
*        Copy D and Z to DSCALE and ZSCALE
218 1 pfleura2
*
219 1 pfleura2
         DO 20 I = 1, 3
220 1 pfleura2
            DSCALE( I ) = D( I )
221 1 pfleura2
            ZSCALE( I ) = Z( I )
222 1 pfleura2
   20    CONTINUE
223 1 pfleura2
      END IF
224 1 pfleura2
*
225 1 pfleura2
      FC = ZERO
226 1 pfleura2
      DF = ZERO
227 1 pfleura2
      DDF = ZERO
228 1 pfleura2
      DO 30 I = 1, 3
229 1 pfleura2
         TEMP = ONE / ( DSCALE( I )-TAU )
230 1 pfleura2
         TEMP1 = ZSCALE( I )*TEMP
231 1 pfleura2
         TEMP2 = TEMP1*TEMP
232 1 pfleura2
         TEMP3 = TEMP2*TEMP
233 1 pfleura2
         FC = FC + TEMP1 / DSCALE( I )
234 1 pfleura2
         DF = DF + TEMP2
235 1 pfleura2
         DDF = DDF + TEMP3
236 1 pfleura2
   30 CONTINUE
237 1 pfleura2
      F = FINIT + TAU*FC
238 1 pfleura2
*
239 1 pfleura2
      IF( ABS( F ).LE.ZERO )
240 1 pfleura2
     $   GO TO 60
241 1 pfleura2
      IF( F .LE. ZERO )THEN
242 1 pfleura2
         LBD = TAU
243 1 pfleura2
      ELSE
244 1 pfleura2
         UBD = TAU
245 1 pfleura2
      END IF
246 1 pfleura2
*
247 1 pfleura2
*        Iteration begins -- Use Gragg-Thornton-Warner cubic convergent
248 1 pfleura2
*                            scheme
249 1 pfleura2
*
250 1 pfleura2
*     It is not hard to see that
251 1 pfleura2
*
252 1 pfleura2
*           1) Iterations will go up monotonically
253 1 pfleura2
*              if FINIT < 0;
254 1 pfleura2
*
255 1 pfleura2
*           2) Iterations will go down monotonically
256 1 pfleura2
*              if FINIT > 0.
257 1 pfleura2
*
258 1 pfleura2
      ITER = NITER + 1
259 1 pfleura2
*
260 1 pfleura2
      DO 50 NITER = ITER, MAXIT
261 1 pfleura2
*
262 1 pfleura2
         IF( ORGATI ) THEN
263 1 pfleura2
            TEMP1 = DSCALE( 2 ) - TAU
264 1 pfleura2
            TEMP2 = DSCALE( 3 ) - TAU
265 1 pfleura2
         ELSE
266 1 pfleura2
            TEMP1 = DSCALE( 1 ) - TAU
267 1 pfleura2
            TEMP2 = DSCALE( 2 ) - TAU
268 1 pfleura2
         END IF
269 1 pfleura2
         A = ( TEMP1+TEMP2 )*F - TEMP1*TEMP2*DF
270 1 pfleura2
         B = TEMP1*TEMP2*F
271 1 pfleura2
         C = F - ( TEMP1+TEMP2 )*DF + TEMP1*TEMP2*DDF
272 1 pfleura2
         TEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )
273 1 pfleura2
         A = A / TEMP
274 1 pfleura2
         B = B / TEMP
275 1 pfleura2
         C = C / TEMP
276 1 pfleura2
         IF( C.EQ.ZERO ) THEN
277 1 pfleura2
            ETA = B / A
278 1 pfleura2
         ELSE IF( A.LE.ZERO ) THEN
279 1 pfleura2
            ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
280 1 pfleura2
         ELSE
281 1 pfleura2
            ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
282 1 pfleura2
         END IF
283 1 pfleura2
         IF( F*ETA.GE.ZERO ) THEN
284 1 pfleura2
            ETA = -F / DF
285 1 pfleura2
         END IF
286 1 pfleura2
*
287 1 pfleura2
         TAU = TAU + ETA
288 1 pfleura2
         IF( TAU .LT. LBD .OR. TAU .GT. UBD )
289 1 pfleura2
     $      TAU = ( LBD + UBD )/TWO
290 1 pfleura2
*
291 1 pfleura2
         FC = ZERO
292 1 pfleura2
         ERRETM = ZERO
293 1 pfleura2
         DF = ZERO
294 1 pfleura2
         DDF = ZERO
295 1 pfleura2
         DO 40 I = 1, 3
296 1 pfleura2
            TEMP = ONE / ( DSCALE( I )-TAU )
297 1 pfleura2
            TEMP1 = ZSCALE( I )*TEMP
298 1 pfleura2
            TEMP2 = TEMP1*TEMP
299 1 pfleura2
            TEMP3 = TEMP2*TEMP
300 1 pfleura2
            TEMP4 = TEMP1 / DSCALE( I )
301 1 pfleura2
            FC = FC + TEMP4
302 1 pfleura2
            ERRETM = ERRETM + ABS( TEMP4 )
303 1 pfleura2
            DF = DF + TEMP2
304 1 pfleura2
            DDF = DDF + TEMP3
305 1 pfleura2
   40    CONTINUE
306 1 pfleura2
         F = FINIT + TAU*FC
307 1 pfleura2
         ERRETM = EIGHT*( ABS( FINIT )+ABS( TAU )*ERRETM ) +
308 1 pfleura2
     $            ABS( TAU )*DF
309 1 pfleura2
         IF( ABS( F ).LE.EPS*ERRETM )
310 1 pfleura2
     $      GO TO 60
311 1 pfleura2
         IF( F .LE. ZERO )THEN
312 1 pfleura2
            LBD = TAU
313 1 pfleura2
         ELSE
314 1 pfleura2
            UBD = TAU
315 1 pfleura2
         END IF
316 1 pfleura2
   50 CONTINUE
317 1 pfleura2
      INFO = 1
318 1 pfleura2
   60 CONTINUE
319 1 pfleura2
*
320 1 pfleura2
*     Undo scaling
321 1 pfleura2
*
322 1 pfleura2
      IF( SCALE )
323 1 pfleura2
     $   TAU = TAU*SCLINV
324 1 pfleura2
      RETURN
325 1 pfleura2
*
326 1 pfleura2
*     End of DLAED6
327 1 pfleura2
*
328 1 pfleura2
      END