LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
dlaed6.f
Go to the documentation of this file.
1*> \brief \b DLAED6 used by DSTEDC. Computes one Newton step in solution of the secular equation.
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DLAED6 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed6.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed6.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed6.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, INFO )
20*
21* .. Scalar Arguments ..
22* LOGICAL ORGATI
23* INTEGER INFO, KNITER
24* DOUBLE PRECISION FINIT, RHO, TAU
25* ..
26* .. Array Arguments ..
27* DOUBLE PRECISION D( 3 ), Z( 3 )
28* ..
29*
30*
31*> \par Purpose:
32* =============
33*>
34*> \verbatim
35*>
36*> DLAED6 computes the positive or negative root (closest to the origin)
37*> of
38*> z(1) z(2) z(3)
39*> f(x) = rho + --------- + ---------- + ---------
40*> d(1)-x d(2)-x d(3)-x
41*>
42*> It is assumed that
43*>
44*> if ORGATI = .true. the root is between d(2) and d(3);
45*> otherwise it is between d(1) and d(2)
46*>
47*> This routine will be called by DLAED4 when necessary. In most cases,
48*> the root sought is the smallest in magnitude, though it might not be
49*> in some extremely rare situations.
50*> \endverbatim
51*
52* Arguments:
53* ==========
54*
55*> \param[in] KNITER
56*> \verbatim
57*> KNITER is INTEGER
58*> Refer to DLAED4 for its significance.
59*> \endverbatim
60*>
61*> \param[in] ORGATI
62*> \verbatim
63*> ORGATI is LOGICAL
64*> If ORGATI is true, the needed root is between d(2) and
65*> d(3); otherwise it is between d(1) and d(2). See
66*> DLAED4 for further details.
67*> \endverbatim
68*>
69*> \param[in] RHO
70*> \verbatim
71*> RHO is DOUBLE PRECISION
72*> Refer to the equation f(x) above.
73*> \endverbatim
74*>
75*> \param[in] D
76*> \verbatim
77*> D is DOUBLE PRECISION array, dimension (3)
78*> D satisfies d(1) < d(2) < d(3).
79*> \endverbatim
80*>
81*> \param[in] Z
82*> \verbatim
83*> Z is DOUBLE PRECISION array, dimension (3)
84*> Each of the elements in z must be positive.
85*> \endverbatim
86*>
87*> \param[in] FINIT
88*> \verbatim
89*> FINIT is DOUBLE PRECISION
90*> The value of f at 0. It is more accurate than the one
91*> evaluated inside this routine (if someone wants to do
92*> so).
93*> \endverbatim
94*>
95*> \param[out] TAU
96*> \verbatim
97*> TAU is DOUBLE PRECISION
98*> The root of the equation f(x).
99*> \endverbatim
100*>
101*> \param[out] INFO
102*> \verbatim
103*> INFO is INTEGER
104*> = 0: successful exit
105*> > 0: if INFO = 1, failure to converge
106*> \endverbatim
107*
108* Authors:
109* ========
110*
111*> \author Univ. of Tennessee
112*> \author Univ. of California Berkeley
113*> \author Univ. of Colorado Denver
114*> \author NAG Ltd.
115*
116*> \ingroup laed6
117*
118*> \par Further Details:
119* =====================
120*>
121*> \verbatim
122*>
123*> 10/02/03: This version has a few statements commented out for thread
124*> safety (machine parameters are computed on each entry). SJH.
125*>
126*> 05/10/06: Modified from a new version of Ren-Cang Li, use
127*> Gragg-Thornton-Warner cubic convergent scheme for better stability.
128*> \endverbatim
129*
130*> \par Contributors:
131* ==================
132*>
133*> Ren-Cang Li, Computer Science Division, University of California
134*> at Berkeley, USA
135*>
136* =====================================================================
137 SUBROUTINE dlaed6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU,
138 $ INFO )
139*
140* -- LAPACK computational routine --
141* -- LAPACK is a software package provided by Univ. of Tennessee, --
142* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
143*
144* .. Scalar Arguments ..
145 LOGICAL ORGATI
146 INTEGER INFO, KNITER
147 DOUBLE PRECISION FINIT, RHO, TAU
148* ..
149* .. Array Arguments ..
150 DOUBLE PRECISION D( 3 ), Z( 3 )
151* ..
152*
153* =====================================================================
154*
155* .. Parameters ..
156 INTEGER MAXIT
157 parameter( maxit = 40 )
158 DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, EIGHT
159 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0,
160 $ three = 3.0d0, four = 4.0d0, eight = 8.0d0 )
161* ..
162* .. External Functions ..
163 DOUBLE PRECISION DLAMCH
164 EXTERNAL dlamch
165* ..
166* .. Local Arrays ..
167 DOUBLE PRECISION DSCALE( 3 ), ZSCALE( 3 )
168* ..
169* .. Local Scalars ..
170 LOGICAL SCALE
171 INTEGER I, ITER, NITER
172 DOUBLE PRECISION A, B, BASE, C, DDF, DF, EPS, ERRETM, ETA, F,
173 $ fc, sclfac, sclinv, small1, small2, sminv1,
174 $ sminv2, temp, temp1, temp2, temp3, temp4,
175 $ lbd, ubd
176* ..
177* .. Intrinsic Functions ..
178 INTRINSIC abs, int, log, max, min, sqrt
179* ..
180* .. Executable Statements ..
181*
182 info = 0
183*
184 IF( orgati ) THEN
185 lbd = d(2)
186 ubd = d(3)
187 ELSE
188 lbd = d(1)
189 ubd = d(2)
190 END IF
191 IF( finit .LT. zero )THEN
192 lbd = zero
193 ELSE
194 ubd = zero
195 END IF
196*
197 niter = 1
198 tau = zero
199 IF( kniter.EQ.2 ) THEN
200 IF( orgati ) THEN
201 temp = ( d( 3 )-d( 2 ) ) / two
202 c = rho + z( 1 ) / ( ( d( 1 )-d( 2 ) )-temp )
203 a = c*( d( 2 )+d( 3 ) ) + z( 2 ) + z( 3 )
204 b = c*d( 2 )*d( 3 ) + z( 2 )*d( 3 ) + z( 3 )*d( 2 )
205 ELSE
206 temp = ( d( 1 )-d( 2 ) ) / two
207 c = rho + z( 3 ) / ( ( d( 3 )-d( 2 ) )-temp )
208 a = c*( d( 1 )+d( 2 ) ) + z( 1 ) + z( 2 )
209 b = c*d( 1 )*d( 2 ) + z( 1 )*d( 2 ) + z( 2 )*d( 1 )
210 END IF
211 temp = max( abs( a ), abs( b ), abs( c ) )
212 a = a / temp
213 b = b / temp
214 c = c / temp
215 IF( c.EQ.zero ) THEN
216 tau = b / a
217 ELSE IF( a.LE.zero ) THEN
218 tau = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
219 ELSE
220 tau = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
221 END IF
222 IF( tau .LT. lbd .OR. tau .GT. ubd )
223 $ tau = ( lbd+ubd )/two
224 IF( d(1).EQ.tau .OR. d(2).EQ.tau .OR. d(3).EQ.tau ) THEN
225 tau = zero
226 ELSE
227 temp = finit + tau*z(1)/( d(1)*( d( 1 )-tau ) ) +
228 $ tau*z(2)/( d(2)*( d( 2 )-tau ) ) +
229 $ tau*z(3)/( d(3)*( d( 3 )-tau ) )
230 IF( temp .LE. zero )THEN
231 lbd = tau
232 ELSE
233 ubd = tau
234 END IF
235 IF( abs( finit ).LE.abs( temp ) )
236 $ tau = zero
237 END IF
238 END IF
239*
240* get machine parameters for possible scaling to avoid overflow
241*
242* modified by Sven: parameters SMALL1, SMINV1, SMALL2,
243* SMINV2, EPS are not SAVEd anymore between one call to the
244* others but recomputed at each call
245*
246 eps = dlamch( 'Epsilon' )
247 base = dlamch( 'Base' )
248 small1 = base**( int( log( dlamch( 'SafMin' ) ) / log( base ) /
249 $ three ) )
250 sminv1 = one / small1
251 small2 = small1*small1
252 sminv2 = sminv1*sminv1
253*
254* Determine if scaling of inputs necessary to avoid overflow
255* when computing 1/TEMP**3
256*
257 IF( orgati ) THEN
258 temp = min( abs( d( 2 )-tau ), abs( d( 3 )-tau ) )
259 ELSE
260 temp = min( abs( d( 1 )-tau ), abs( d( 2 )-tau ) )
261 END IF
262 scale = .false.
263 IF( temp.LE.small1 ) THEN
264 scale = .true.
265 IF( temp.LE.small2 ) THEN
266*
267* Scale up by power of radix nearest 1/SAFMIN**(2/3)
268*
269 sclfac = sminv2
270 sclinv = small2
271 ELSE
272*
273* Scale up by power of radix nearest 1/SAFMIN**(1/3)
274*
275 sclfac = sminv1
276 sclinv = small1
277 END IF
278*
279* Scaling up safe because D, Z, TAU scaled elsewhere to be O(1)
280*
281 DO 10 i = 1, 3
282 dscale( i ) = d( i )*sclfac
283 zscale( i ) = z( i )*sclfac
284 10 CONTINUE
285 tau = tau*sclfac
286 lbd = lbd*sclfac
287 ubd = ubd*sclfac
288 ELSE
289*
290* Copy D and Z to DSCALE and ZSCALE
291*
292 DO 20 i = 1, 3
293 dscale( i ) = d( i )
294 zscale( i ) = z( i )
295 20 CONTINUE
296 END IF
297*
298 fc = zero
299 df = zero
300 ddf = zero
301 DO 30 i = 1, 3
302 temp = one / ( dscale( i )-tau )
303 temp1 = zscale( i )*temp
304 temp2 = temp1*temp
305 temp3 = temp2*temp
306 fc = fc + temp1 / dscale( i )
307 df = df + temp2
308 ddf = ddf + temp3
309 30 CONTINUE
310 f = finit + tau*fc
311*
312 IF( abs( f ).LE.zero )
313 $ GO TO 60
314 IF( f .LE. zero )THEN
315 lbd = tau
316 ELSE
317 ubd = tau
318 END IF
319*
320* Iteration begins -- Use Gragg-Thornton-Warner cubic convergent
321* scheme
322*
323* It is not hard to see that
324*
325* 1) Iterations will go up monotonically
326* if FINIT < 0;
327*
328* 2) Iterations will go down monotonically
329* if FINIT > 0.
330*
331 iter = niter + 1
332*
333 DO 50 niter = iter, maxit
334*
335 IF( orgati ) THEN
336 temp1 = dscale( 2 ) - tau
337 temp2 = dscale( 3 ) - tau
338 ELSE
339 temp1 = dscale( 1 ) - tau
340 temp2 = dscale( 2 ) - tau
341 END IF
342 a = ( temp1+temp2 )*f - temp1*temp2*df
343 b = temp1*temp2*f
344 c = f - ( temp1+temp2 )*df + temp1*temp2*ddf
345 temp = max( abs( a ), abs( b ), abs( c ) )
346 a = a / temp
347 b = b / temp
348 c = c / temp
349 IF( c.EQ.zero ) THEN
350 eta = b / a
351 ELSE IF( a.LE.zero ) THEN
352 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
353 ELSE
354 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
355 END IF
356 IF( f*eta.GE.zero ) THEN
357 eta = -f / df
358 END IF
359*
360 tau = tau + eta
361 IF( tau .LT. lbd .OR. tau .GT. ubd )
362 $ tau = ( lbd + ubd )/two
363*
364 fc = zero
365 erretm = zero
366 df = zero
367 ddf = zero
368 DO 40 i = 1, 3
369 IF ( ( dscale( i )-tau ).NE.zero ) THEN
370 temp = one / ( dscale( i )-tau )
371 temp1 = zscale( i )*temp
372 temp2 = temp1*temp
373 temp3 = temp2*temp
374 temp4 = temp1 / dscale( i )
375 fc = fc + temp4
376 erretm = erretm + abs( temp4 )
377 df = df + temp2
378 ddf = ddf + temp3
379 ELSE
380 GO TO 60
381 END IF
382 40 CONTINUE
383 f = finit + tau*fc
384 erretm = eight*( abs( finit )+abs( tau )*erretm ) +
385 $ abs( tau )*df
386 IF( ( abs( f ).LE.four*eps*erretm ) .OR.
387 $ ( (ubd-lbd).LE.four*eps*abs(tau) ) )
388 $ GO TO 60
389 IF( f .LE. zero )THEN
390 lbd = tau
391 ELSE
392 ubd = tau
393 END IF
394 50 CONTINUE
395 info = 1
396 60 CONTINUE
397*
398* Undo scaling
399*
400 IF( scale )
401 $ tau = tau*sclinv
402 RETURN
403*
404* End of DLAED6
405*
406 END
subroutine dlaed6(kniter, orgati, rho, d, z, finit, tau, info)
DLAED6 used by DSTEDC. Computes one Newton step in solution of the secular equation.
Definition dlaed6.f:139