File:
[local] /
rpl /
lapack /
lapack /
dlasd4.f
Revision
1.16:
download - view:
text,
annotated -
select for diffs -
revision graph
Mon Jan 27 09:28:22 2014 UTC (10 years, 7 months ago) by
bertrand
Branches:
MAIN
CVS tags:
rpl-4_1_24,
rpl-4_1_23,
rpl-4_1_22,
rpl-4_1_21,
rpl-4_1_20,
rpl-4_1_19,
rpl-4_1_18,
rpl-4_1_17,
HEAD
Cohérence.
1: *> \brief \b DLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modification to a positive diagonal matrix. Used by dbdsdc.
2: *
3: * =========== DOCUMENTATION ===========
4: *
5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
7: *
8: *> \htmlonly
9: *> Download DLASD4 + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd4.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd4.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd4.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE DLASD4( N, I, D, Z, DELTA, RHO, SIGMA, WORK, INFO )
22: *
23: * .. Scalar Arguments ..
24: * INTEGER I, INFO, N
25: * DOUBLE PRECISION RHO, SIGMA
26: * ..
27: * .. Array Arguments ..
28: * DOUBLE PRECISION D( * ), DELTA( * ), WORK( * ), Z( * )
29: * ..
30: *
31: *
32: *> \par Purpose:
33: * =============
34: *>
35: *> \verbatim
36: *>
37: *> This subroutine computes the square root of the I-th updated
38: *> eigenvalue of a positive symmetric rank-one modification to
39: *> a positive diagonal matrix whose entries are given as the squares
40: *> of the corresponding entries in the array d, and that
41: *>
42: *> 0 <= D(i) < D(j) for i < j
43: *>
44: *> and that RHO > 0. This is arranged by the calling routine, and is
45: *> no loss in generality. The rank-one modified system is thus
46: *>
47: *> diag( D ) * diag( D ) + RHO * Z * Z_transpose.
48: *>
49: *> where we assume the Euclidean norm of Z is 1.
50: *>
51: *> The method consists of approximating the rational functions in the
52: *> secular equation by simpler interpolating rational functions.
53: *> \endverbatim
54: *
55: * Arguments:
56: * ==========
57: *
58: *> \param[in] N
59: *> \verbatim
60: *> N is INTEGER
61: *> The length of all arrays.
62: *> \endverbatim
63: *>
64: *> \param[in] I
65: *> \verbatim
66: *> I is INTEGER
67: *> The index of the eigenvalue to be computed. 1 <= I <= N.
68: *> \endverbatim
69: *>
70: *> \param[in] D
71: *> \verbatim
72: *> D is DOUBLE PRECISION array, dimension ( N )
73: *> The original eigenvalues. It is assumed that they are in
74: *> order, 0 <= D(I) < D(J) for I < J.
75: *> \endverbatim
76: *>
77: *> \param[in] Z
78: *> \verbatim
79: *> Z is DOUBLE PRECISION array, dimension ( N )
80: *> The components of the updating vector.
81: *> \endverbatim
82: *>
83: *> \param[out] DELTA
84: *> \verbatim
85: *> DELTA is DOUBLE PRECISION array, dimension ( N )
86: *> If N .ne. 1, DELTA contains (D(j) - sigma_I) in its j-th
87: *> component. If N = 1, then DELTA(1) = 1. The vector DELTA
88: *> contains the information necessary to construct the
89: *> (singular) eigenvectors.
90: *> \endverbatim
91: *>
92: *> \param[in] RHO
93: *> \verbatim
94: *> RHO is DOUBLE PRECISION
95: *> The scalar in the symmetric updating formula.
96: *> \endverbatim
97: *>
98: *> \param[out] SIGMA
99: *> \verbatim
100: *> SIGMA is DOUBLE PRECISION
101: *> The computed sigma_I, the I-th updated eigenvalue.
102: *> \endverbatim
103: *>
104: *> \param[out] WORK
105: *> \verbatim
106: *> WORK is DOUBLE PRECISION array, dimension ( N )
107: *> If N .ne. 1, WORK contains (D(j) + sigma_I) in its j-th
108: *> component. If N = 1, then WORK( 1 ) = 1.
109: *> \endverbatim
110: *>
111: *> \param[out] INFO
112: *> \verbatim
113: *> INFO is INTEGER
114: *> = 0: successful exit
115: *> > 0: if INFO = 1, the updating process failed.
116: *> \endverbatim
117: *
118: *> \par Internal Parameters:
119: * =========================
120: *>
121: *> \verbatim
122: *> Logical variable ORGATI (origin-at-i?) is used for distinguishing
123: *> whether D(i) or D(i+1) is treated as the origin.
124: *>
125: *> ORGATI = .true. origin at i
126: *> ORGATI = .false. origin at i+1
127: *>
128: *> Logical variable SWTCH3 (switch-for-3-poles?) is for noting
129: *> if we are working with THREE poles!
130: *>
131: *> MAXIT is the maximum number of iterations allowed for each
132: *> eigenvalue.
133: *> \endverbatim
134: *
135: * Authors:
136: * ========
137: *
138: *> \author Univ. of Tennessee
139: *> \author Univ. of California Berkeley
140: *> \author Univ. of Colorado Denver
141: *> \author NAG Ltd.
142: *
143: *> \date November 2013
144: *
145: *> \ingroup auxOTHERauxiliary
146: *
147: *> \par Contributors:
148: * ==================
149: *>
150: *> Ren-Cang Li, Computer Science Division, University of California
151: *> at Berkeley, USA
152: *>
153: * =====================================================================
154: SUBROUTINE DLASD4( N, I, D, Z, DELTA, RHO, SIGMA, WORK, INFO )
155: *
156: * -- LAPACK auxiliary routine (version 3.5.0) --
157: * -- LAPACK is a software package provided by Univ. of Tennessee, --
158: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
159: * November 2013
160: *
161: * .. Scalar Arguments ..
162: INTEGER I, INFO, N
163: DOUBLE PRECISION RHO, SIGMA
164: * ..
165: * .. Array Arguments ..
166: DOUBLE PRECISION D( * ), DELTA( * ), WORK( * ), Z( * )
167: * ..
168: *
169: * =====================================================================
170: *
171: * .. Parameters ..
172: INTEGER MAXIT
173: PARAMETER ( MAXIT = 400 )
174: DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, EIGHT, TEN
175: PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
176: $ THREE = 3.0D+0, FOUR = 4.0D+0, EIGHT = 8.0D+0,
177: $ TEN = 10.0D+0 )
178: * ..
179: * .. Local Scalars ..
180: LOGICAL ORGATI, SWTCH, SWTCH3, GEOMAVG
181: INTEGER II, IIM1, IIP1, IP1, ITER, J, NITER
182: DOUBLE PRECISION A, B, C, DELSQ, DELSQ2, SQ2, DPHI, DPSI, DTIIM,
183: $ DTIIP, DTIPSQ, DTISQ, DTNSQ, DTNSQ1, DW, EPS,
184: $ ERRETM, ETA, PHI, PREW, PSI, RHOINV, SGLB,
185: $ SGUB, TAU, TAU2, TEMP, TEMP1, TEMP2, W
186: * ..
187: * .. Local Arrays ..
188: DOUBLE PRECISION DD( 3 ), ZZ( 3 )
189: * ..
190: * .. External Subroutines ..
191: EXTERNAL DLAED6, DLASD5
192: * ..
193: * .. External Functions ..
194: DOUBLE PRECISION DLAMCH
195: EXTERNAL DLAMCH
196: * ..
197: * .. Intrinsic Functions ..
198: INTRINSIC ABS, MAX, MIN, SQRT
199: * ..
200: * .. Executable Statements ..
201: *
202: * Since this routine is called in an inner loop, we do no argument
203: * checking.
204: *
205: * Quick return for N=1 and 2.
206: *
207: INFO = 0
208: IF( N.EQ.1 ) THEN
209: *
210: * Presumably, I=1 upon entry
211: *
212: SIGMA = SQRT( D( 1 )*D( 1 )+RHO*Z( 1 )*Z( 1 ) )
213: DELTA( 1 ) = ONE
214: WORK( 1 ) = ONE
215: RETURN
216: END IF
217: IF( N.EQ.2 ) THEN
218: CALL DLASD5( I, D, Z, DELTA, RHO, SIGMA, WORK )
219: RETURN
220: END IF
221: *
222: * Compute machine epsilon
223: *
224: EPS = DLAMCH( 'Epsilon' )
225: RHOINV = ONE / RHO
226: TAU2= ZERO
227: *
228: * The case I = N
229: *
230: IF( I.EQ.N ) THEN
231: *
232: * Initialize some basic variables
233: *
234: II = N - 1
235: NITER = 1
236: *
237: * Calculate initial guess
238: *
239: TEMP = RHO / TWO
240: *
241: * If ||Z||_2 is not one, then TEMP should be set to
242: * RHO * ||Z||_2^2 / TWO
243: *
244: TEMP1 = TEMP / ( D( N )+SQRT( D( N )*D( N )+TEMP ) )
245: DO 10 J = 1, N
246: WORK( J ) = D( J ) + D( N ) + TEMP1
247: DELTA( J ) = ( D( J )-D( N ) ) - TEMP1
248: 10 CONTINUE
249: *
250: PSI = ZERO
251: DO 20 J = 1, N - 2
252: PSI = PSI + Z( J )*Z( J ) / ( DELTA( J )*WORK( J ) )
253: 20 CONTINUE
254: *
255: C = RHOINV + PSI
256: W = C + Z( II )*Z( II ) / ( DELTA( II )*WORK( II ) ) +
257: $ Z( N )*Z( N ) / ( DELTA( N )*WORK( N ) )
258: *
259: IF( W.LE.ZERO ) THEN
260: TEMP1 = SQRT( D( N )*D( N )+RHO )
261: TEMP = Z( N-1 )*Z( N-1 ) / ( ( D( N-1 )+TEMP1 )*
262: $ ( D( N )-D( N-1 )+RHO / ( D( N )+TEMP1 ) ) ) +
263: $ Z( N )*Z( N ) / RHO
264: *
265: * The following TAU2 is to approximate
266: * SIGMA_n^2 - D( N )*D( N )
267: *
268: IF( C.LE.TEMP ) THEN
269: TAU = RHO
270: ELSE
271: DELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )
272: A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )
273: B = Z( N )*Z( N )*DELSQ
274: IF( A.LT.ZERO ) THEN
275: TAU2 = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )
276: ELSE
277: TAU2 = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )
278: END IF
279: TAU = TAU2 / ( D( N )+SQRT( D( N )*D( N )+TAU2 ) )
280: END IF
281: *
282: * It can be proved that
283: * D(N)^2+RHO/2 <= SIGMA_n^2 < D(N)^2+TAU2 <= D(N)^2+RHO
284: *
285: ELSE
286: DELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )
287: A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )
288: B = Z( N )*Z( N )*DELSQ
289: *
290: * The following TAU2 is to approximate
291: * SIGMA_n^2 - D( N )*D( N )
292: *
293: IF( A.LT.ZERO ) THEN
294: TAU2 = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )
295: ELSE
296: TAU2 = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )
297: END IF
298: TAU = TAU2 / ( D( N )+SQRT( D( N )*D( N )+TAU2 ) )
299:
300: *
301: * It can be proved that
302: * D(N)^2 < D(N)^2+TAU2 < SIGMA(N)^2 < D(N)^2+RHO/2
303: *
304: END IF
305: *
306: * The following TAU is to approximate SIGMA_n - D( N )
307: *
308: * TAU = TAU2 / ( D( N )+SQRT( D( N )*D( N )+TAU2 ) )
309: *
310: SIGMA = D( N ) + TAU
311: DO 30 J = 1, N
312: DELTA( J ) = ( D( J )-D( N ) ) - TAU
313: WORK( J ) = D( J ) + D( N ) + TAU
314: 30 CONTINUE
315: *
316: * Evaluate PSI and the derivative DPSI
317: *
318: DPSI = ZERO
319: PSI = ZERO
320: ERRETM = ZERO
321: DO 40 J = 1, II
322: TEMP = Z( J ) / ( DELTA( J )*WORK( J ) )
323: PSI = PSI + Z( J )*TEMP
324: DPSI = DPSI + TEMP*TEMP
325: ERRETM = ERRETM + PSI
326: 40 CONTINUE
327: ERRETM = ABS( ERRETM )
328: *
329: * Evaluate PHI and the derivative DPHI
330: *
331: TEMP = Z( N ) / ( DELTA( N )*WORK( N ) )
332: PHI = Z( N )*TEMP
333: DPHI = TEMP*TEMP
334: ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV
335: * $ + ABS( TAU2 )*( DPSI+DPHI )
336: *
337: W = RHOINV + PHI + PSI
338: *
339: * Test for convergence
340: *
341: IF( ABS( W ).LE.EPS*ERRETM ) THEN
342: GO TO 240
343: END IF
344: *
345: * Calculate the new step
346: *
347: NITER = NITER + 1
348: DTNSQ1 = WORK( N-1 )*DELTA( N-1 )
349: DTNSQ = WORK( N )*DELTA( N )
350: C = W - DTNSQ1*DPSI - DTNSQ*DPHI
351: A = ( DTNSQ+DTNSQ1 )*W - DTNSQ*DTNSQ1*( DPSI+DPHI )
352: B = DTNSQ*DTNSQ1*W
353: IF( C.LT.ZERO )
354: $ C = ABS( C )
355: IF( C.EQ.ZERO ) THEN
356: ETA = RHO - SIGMA*SIGMA
357: ELSE IF( A.GE.ZERO ) THEN
358: ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
359: ELSE
360: ETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )
361: END IF
362: *
363: * Note, eta should be positive if w is negative, and
364: * eta should be negative otherwise. However,
365: * if for some reason caused by roundoff, eta*w > 0,
366: * we simply use one Newton step instead. This way
367: * will guarantee eta*w < 0.
368: *
369: IF( W*ETA.GT.ZERO )
370: $ ETA = -W / ( DPSI+DPHI )
371: TEMP = ETA - DTNSQ
372: IF( TEMP.GT.RHO )
373: $ ETA = RHO + DTNSQ
374: *
375: ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )
376: TAU = TAU + ETA
377: SIGMA = SIGMA + ETA
378: *
379: DO 50 J = 1, N
380: DELTA( J ) = DELTA( J ) - ETA
381: WORK( J ) = WORK( J ) + ETA
382: 50 CONTINUE
383: *
384: * Evaluate PSI and the derivative DPSI
385: *
386: DPSI = ZERO
387: PSI = ZERO
388: ERRETM = ZERO
389: DO 60 J = 1, II
390: TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
391: PSI = PSI + Z( J )*TEMP
392: DPSI = DPSI + TEMP*TEMP
393: ERRETM = ERRETM + PSI
394: 60 CONTINUE
395: ERRETM = ABS( ERRETM )
396: *
397: * Evaluate PHI and the derivative DPHI
398: *
399: TAU2 = WORK( N )*DELTA( N )
400: TEMP = Z( N ) / TAU2
401: PHI = Z( N )*TEMP
402: DPHI = TEMP*TEMP
403: ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV
404: * $ + ABS( TAU2 )*( DPSI+DPHI )
405: *
406: W = RHOINV + PHI + PSI
407: *
408: * Main loop to update the values of the array DELTA
409: *
410: ITER = NITER + 1
411: *
412: DO 90 NITER = ITER, MAXIT
413: *
414: * Test for convergence
415: *
416: IF( ABS( W ).LE.EPS*ERRETM ) THEN
417: GO TO 240
418: END IF
419: *
420: * Calculate the new step
421: *
422: DTNSQ1 = WORK( N-1 )*DELTA( N-1 )
423: DTNSQ = WORK( N )*DELTA( N )
424: C = W - DTNSQ1*DPSI - DTNSQ*DPHI
425: A = ( DTNSQ+DTNSQ1 )*W - DTNSQ1*DTNSQ*( DPSI+DPHI )
426: B = DTNSQ1*DTNSQ*W
427: IF( A.GE.ZERO ) THEN
428: ETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
429: ELSE
430: ETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )
431: END IF
432: *
433: * Note, eta should be positive if w is negative, and
434: * eta should be negative otherwise. However,
435: * if for some reason caused by roundoff, eta*w > 0,
436: * we simply use one Newton step instead. This way
437: * will guarantee eta*w < 0.
438: *
439: IF( W*ETA.GT.ZERO )
440: $ ETA = -W / ( DPSI+DPHI )
441: TEMP = ETA - DTNSQ
442: IF( TEMP.LE.ZERO )
443: $ ETA = ETA / TWO
444: *
445: ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )
446: TAU = TAU + ETA
447: SIGMA = SIGMA + ETA
448: *
449: DO 70 J = 1, N
450: DELTA( J ) = DELTA( J ) - ETA
451: WORK( J ) = WORK( J ) + ETA
452: 70 CONTINUE
453: *
454: * Evaluate PSI and the derivative DPSI
455: *
456: DPSI = ZERO
457: PSI = ZERO
458: ERRETM = ZERO
459: DO 80 J = 1, II
460: TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
461: PSI = PSI + Z( J )*TEMP
462: DPSI = DPSI + TEMP*TEMP
463: ERRETM = ERRETM + PSI
464: 80 CONTINUE
465: ERRETM = ABS( ERRETM )
466: *
467: * Evaluate PHI and the derivative DPHI
468: *
469: TAU2 = WORK( N )*DELTA( N )
470: TEMP = Z( N ) / TAU2
471: PHI = Z( N )*TEMP
472: DPHI = TEMP*TEMP
473: ERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV
474: * $ + ABS( TAU2 )*( DPSI+DPHI )
475: *
476: W = RHOINV + PHI + PSI
477: 90 CONTINUE
478: *
479: * Return with INFO = 1, NITER = MAXIT and not converged
480: *
481: INFO = 1
482: GO TO 240
483: *
484: * End for the case I = N
485: *
486: ELSE
487: *
488: * The case for I < N
489: *
490: NITER = 1
491: IP1 = I + 1
492: *
493: * Calculate initial guess
494: *
495: DELSQ = ( D( IP1 )-D( I ) )*( D( IP1 )+D( I ) )
496: DELSQ2 = DELSQ / TWO
497: SQ2=SQRT( ( D( I )*D( I )+D( IP1 )*D( IP1 ) ) / TWO )
498: TEMP = DELSQ2 / ( D( I )+SQ2 )
499: DO 100 J = 1, N
500: WORK( J ) = D( J ) + D( I ) + TEMP
501: DELTA( J ) = ( D( J )-D( I ) ) - TEMP
502: 100 CONTINUE
503: *
504: PSI = ZERO
505: DO 110 J = 1, I - 1
506: PSI = PSI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )
507: 110 CONTINUE
508: *
509: PHI = ZERO
510: DO 120 J = N, I + 2, -1
511: PHI = PHI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )
512: 120 CONTINUE
513: C = RHOINV + PSI + PHI
514: W = C + Z( I )*Z( I ) / ( WORK( I )*DELTA( I ) ) +
515: $ Z( IP1 )*Z( IP1 ) / ( WORK( IP1 )*DELTA( IP1 ) )
516: *
517: GEOMAVG = .FALSE.
518: IF( W.GT.ZERO ) THEN
519: *
520: * d(i)^2 < the ith sigma^2 < (d(i)^2+d(i+1)^2)/2
521: *
522: * We choose d(i) as origin.
523: *
524: ORGATI = .TRUE.
525: II = I
526: SGLB = ZERO
527: SGUB = DELSQ2 / ( D( I )+SQ2 )
528: A = C*DELSQ + Z( I )*Z( I ) + Z( IP1 )*Z( IP1 )
529: B = Z( I )*Z( I )*DELSQ
530: IF( A.GT.ZERO ) THEN
531: TAU2 = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
532: ELSE
533: TAU2 = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
534: END IF
535: *
536: * TAU2 now is an estimation of SIGMA^2 - D( I )^2. The
537: * following, however, is the corresponding estimation of
538: * SIGMA - D( I ).
539: *
540: TAU = TAU2 / ( D( I )+SQRT( D( I )*D( I )+TAU2 ) )
541: TEMP = SQRT(EPS)
542: IF( (D(I).LE.TEMP*D(IP1)).AND.(ABS(Z(I)).LE.TEMP)
543: $ .AND.(D(I).GT.ZERO) ) THEN
544: TAU = MIN( TEN*D(I), SGUB )
545: GEOMAVG = .TRUE.
546: END IF
547: ELSE
548: *
549: * (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2
550: *
551: * We choose d(i+1) as origin.
552: *
553: ORGATI = .FALSE.
554: II = IP1
555: SGLB = -DELSQ2 / ( D( II )+SQ2 )
556: SGUB = ZERO
557: A = C*DELSQ - Z( I )*Z( I ) - Z( IP1 )*Z( IP1 )
558: B = Z( IP1 )*Z( IP1 )*DELSQ
559: IF( A.LT.ZERO ) THEN
560: TAU2 = TWO*B / ( A-SQRT( ABS( A*A+FOUR*B*C ) ) )
561: ELSE
562: TAU2 = -( A+SQRT( ABS( A*A+FOUR*B*C ) ) ) / ( TWO*C )
563: END IF
564: *
565: * TAU2 now is an estimation of SIGMA^2 - D( IP1 )^2. The
566: * following, however, is the corresponding estimation of
567: * SIGMA - D( IP1 ).
568: *
569: TAU = TAU2 / ( D( IP1 )+SQRT( ABS( D( IP1 )*D( IP1 )+
570: $ TAU2 ) ) )
571: END IF
572: *
573: SIGMA = D( II ) + TAU
574: DO 130 J = 1, N
575: WORK( J ) = D( J ) + D( II ) + TAU
576: DELTA( J ) = ( D( J )-D( II ) ) - TAU
577: 130 CONTINUE
578: IIM1 = II - 1
579: IIP1 = II + 1
580: *
581: * Evaluate PSI and the derivative DPSI
582: *
583: DPSI = ZERO
584: PSI = ZERO
585: ERRETM = ZERO
586: DO 150 J = 1, IIM1
587: TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
588: PSI = PSI + Z( J )*TEMP
589: DPSI = DPSI + TEMP*TEMP
590: ERRETM = ERRETM + PSI
591: 150 CONTINUE
592: ERRETM = ABS( ERRETM )
593: *
594: * Evaluate PHI and the derivative DPHI
595: *
596: DPHI = ZERO
597: PHI = ZERO
598: DO 160 J = N, IIP1, -1
599: TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
600: PHI = PHI + Z( J )*TEMP
601: DPHI = DPHI + TEMP*TEMP
602: ERRETM = ERRETM + PHI
603: 160 CONTINUE
604: *
605: W = RHOINV + PHI + PSI
606: *
607: * W is the value of the secular function with
608: * its ii-th element removed.
609: *
610: SWTCH3 = .FALSE.
611: IF( ORGATI ) THEN
612: IF( W.LT.ZERO )
613: $ SWTCH3 = .TRUE.
614: ELSE
615: IF( W.GT.ZERO )
616: $ SWTCH3 = .TRUE.
617: END IF
618: IF( II.EQ.1 .OR. II.EQ.N )
619: $ SWTCH3 = .FALSE.
620: *
621: TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
622: DW = DPSI + DPHI + TEMP*TEMP
623: TEMP = Z( II )*TEMP
624: W = W + TEMP
625: ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV
626: $ + THREE*ABS( TEMP )
627: * $ + ABS( TAU2 )*DW
628: *
629: * Test for convergence
630: *
631: IF( ABS( W ).LE.EPS*ERRETM ) THEN
632: GO TO 240
633: END IF
634: *
635: IF( W.LE.ZERO ) THEN
636: SGLB = MAX( SGLB, TAU )
637: ELSE
638: SGUB = MIN( SGUB, TAU )
639: END IF
640: *
641: * Calculate the new step
642: *
643: NITER = NITER + 1
644: IF( .NOT.SWTCH3 ) THEN
645: DTIPSQ = WORK( IP1 )*DELTA( IP1 )
646: DTISQ = WORK( I )*DELTA( I )
647: IF( ORGATI ) THEN
648: C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
649: ELSE
650: C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
651: END IF
652: A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
653: B = DTIPSQ*DTISQ*W
654: IF( C.EQ.ZERO ) THEN
655: IF( A.EQ.ZERO ) THEN
656: IF( ORGATI ) THEN
657: A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*( DPSI+DPHI )
658: ELSE
659: A = Z( IP1 )*Z( IP1 ) + DTISQ*DTISQ*( DPSI+DPHI )
660: END IF
661: END IF
662: ETA = B / A
663: ELSE IF( A.LE.ZERO ) THEN
664: ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
665: ELSE
666: ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
667: END IF
668: ELSE
669: *
670: * Interpolation using THREE most relevant poles
671: *
672: DTIIM = WORK( IIM1 )*DELTA( IIM1 )
673: DTIIP = WORK( IIP1 )*DELTA( IIP1 )
674: TEMP = RHOINV + PSI + PHI
675: IF( ORGATI ) THEN
676: TEMP1 = Z( IIM1 ) / DTIIM
677: TEMP1 = TEMP1*TEMP1
678: C = ( TEMP - DTIIP*( DPSI+DPHI ) ) -
679: $ ( D( IIM1 )-D( IIP1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
680: ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
681: IF( DPSI.LT.TEMP1 ) THEN
682: ZZ( 3 ) = DTIIP*DTIIP*DPHI
683: ELSE
684: ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
685: END IF
686: ELSE
687: TEMP1 = Z( IIP1 ) / DTIIP
688: TEMP1 = TEMP1*TEMP1
689: C = ( TEMP - DTIIM*( DPSI+DPHI ) ) -
690: $ ( D( IIP1 )-D( IIM1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1
691: IF( DPHI.LT.TEMP1 ) THEN
692: ZZ( 1 ) = DTIIM*DTIIM*DPSI
693: ELSE
694: ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
695: END IF
696: ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
697: END IF
698: ZZ( 2 ) = Z( II )*Z( II )
699: DD( 1 ) = DTIIM
700: DD( 2 ) = DELTA( II )*WORK( II )
701: DD( 3 ) = DTIIP
702: CALL DLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
703: *
704: IF( INFO.NE.0 ) THEN
705: *
706: * If INFO is not 0, i.e., DLAED6 failed, switch back
707: * to 2 pole interpolation.
708: *
709: SWTCH3 = .FALSE.
710: INFO = 0
711: DTIPSQ = WORK( IP1 )*DELTA( IP1 )
712: DTISQ = WORK( I )*DELTA( I )
713: IF( ORGATI ) THEN
714: C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
715: ELSE
716: C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
717: END IF
718: A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
719: B = DTIPSQ*DTISQ*W
720: IF( C.EQ.ZERO ) THEN
721: IF( A.EQ.ZERO ) THEN
722: IF( ORGATI ) THEN
723: A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*( DPSI+DPHI )
724: ELSE
725: A = Z( IP1 )*Z( IP1 ) + DTISQ*DTISQ*( DPSI+DPHI)
726: END IF
727: END IF
728: ETA = B / A
729: ELSE IF( A.LE.ZERO ) THEN
730: ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
731: ELSE
732: ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
733: END IF
734: END IF
735: END IF
736: *
737: * Note, eta should be positive if w is negative, and
738: * eta should be negative otherwise. However,
739: * if for some reason caused by roundoff, eta*w > 0,
740: * we simply use one Newton step instead. This way
741: * will guarantee eta*w < 0.
742: *
743: IF( W*ETA.GE.ZERO )
744: $ ETA = -W / DW
745: *
746: ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
747: TEMP = TAU + ETA
748: IF( TEMP.GT.SGUB .OR. TEMP.LT.SGLB ) THEN
749: IF( W.LT.ZERO ) THEN
750: ETA = ( SGUB-TAU ) / TWO
751: ELSE
752: ETA = ( SGLB-TAU ) / TWO
753: END IF
754: IF( GEOMAVG ) THEN
755: IF( W .LT. ZERO ) THEN
756: IF( TAU .GT. ZERO ) THEN
757: ETA = SQRT(SGUB*TAU)-TAU
758: END IF
759: ELSE
760: IF( SGLB .GT. ZERO ) THEN
761: ETA = SQRT(SGLB*TAU)-TAU
762: END IF
763: END IF
764: END IF
765: END IF
766: *
767: PREW = W
768: *
769: TAU = TAU + ETA
770: SIGMA = SIGMA + ETA
771: *
772: DO 170 J = 1, N
773: WORK( J ) = WORK( J ) + ETA
774: DELTA( J ) = DELTA( J ) - ETA
775: 170 CONTINUE
776: *
777: * Evaluate PSI and the derivative DPSI
778: *
779: DPSI = ZERO
780: PSI = ZERO
781: ERRETM = ZERO
782: DO 180 J = 1, IIM1
783: TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
784: PSI = PSI + Z( J )*TEMP
785: DPSI = DPSI + TEMP*TEMP
786: ERRETM = ERRETM + PSI
787: 180 CONTINUE
788: ERRETM = ABS( ERRETM )
789: *
790: * Evaluate PHI and the derivative DPHI
791: *
792: DPHI = ZERO
793: PHI = ZERO
794: DO 190 J = N, IIP1, -1
795: TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
796: PHI = PHI + Z( J )*TEMP
797: DPHI = DPHI + TEMP*TEMP
798: ERRETM = ERRETM + PHI
799: 190 CONTINUE
800: *
801: TAU2 = WORK( II )*DELTA( II )
802: TEMP = Z( II ) / TAU2
803: DW = DPSI + DPHI + TEMP*TEMP
804: TEMP = Z( II )*TEMP
805: W = RHOINV + PHI + PSI + TEMP
806: ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV
807: $ + THREE*ABS( TEMP )
808: * $ + ABS( TAU2 )*DW
809: *
810: SWTCH = .FALSE.
811: IF( ORGATI ) THEN
812: IF( -W.GT.ABS( PREW ) / TEN )
813: $ SWTCH = .TRUE.
814: ELSE
815: IF( W.GT.ABS( PREW ) / TEN )
816: $ SWTCH = .TRUE.
817: END IF
818: *
819: * Main loop to update the values of the array DELTA and WORK
820: *
821: ITER = NITER + 1
822: *
823: DO 230 NITER = ITER, MAXIT
824: *
825: * Test for convergence
826: *
827: IF( ABS( W ).LE.EPS*ERRETM ) THEN
828: * $ .OR. (SGUB-SGLB).LE.EIGHT*ABS(SGUB+SGLB) ) THEN
829: GO TO 240
830: END IF
831: *
832: IF( W.LE.ZERO ) THEN
833: SGLB = MAX( SGLB, TAU )
834: ELSE
835: SGUB = MIN( SGUB, TAU )
836: END IF
837: *
838: * Calculate the new step
839: *
840: IF( .NOT.SWTCH3 ) THEN
841: DTIPSQ = WORK( IP1 )*DELTA( IP1 )
842: DTISQ = WORK( I )*DELTA( I )
843: IF( .NOT.SWTCH ) THEN
844: IF( ORGATI ) THEN
845: C = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2
846: ELSE
847: C = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2
848: END IF
849: ELSE
850: TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
851: IF( ORGATI ) THEN
852: DPSI = DPSI + TEMP*TEMP
853: ELSE
854: DPHI = DPHI + TEMP*TEMP
855: END IF
856: C = W - DTISQ*DPSI - DTIPSQ*DPHI
857: END IF
858: A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
859: B = DTIPSQ*DTISQ*W
860: IF( C.EQ.ZERO ) THEN
861: IF( A.EQ.ZERO ) THEN
862: IF( .NOT.SWTCH ) THEN
863: IF( ORGATI ) THEN
864: A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*
865: $ ( DPSI+DPHI )
866: ELSE
867: A = Z( IP1 )*Z( IP1 ) +
868: $ DTISQ*DTISQ*( DPSI+DPHI )
869: END IF
870: ELSE
871: A = DTISQ*DTISQ*DPSI + DTIPSQ*DTIPSQ*DPHI
872: END IF
873: END IF
874: ETA = B / A
875: ELSE IF( A.LE.ZERO ) THEN
876: ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
877: ELSE
878: ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
879: END IF
880: ELSE
881: *
882: * Interpolation using THREE most relevant poles
883: *
884: DTIIM = WORK( IIM1 )*DELTA( IIM1 )
885: DTIIP = WORK( IIP1 )*DELTA( IIP1 )
886: TEMP = RHOINV + PSI + PHI
887: IF( SWTCH ) THEN
888: C = TEMP - DTIIM*DPSI - DTIIP*DPHI
889: ZZ( 1 ) = DTIIM*DTIIM*DPSI
890: ZZ( 3 ) = DTIIP*DTIIP*DPHI
891: ELSE
892: IF( ORGATI ) THEN
893: TEMP1 = Z( IIM1 ) / DTIIM
894: TEMP1 = TEMP1*TEMP1
895: TEMP2 = ( D( IIM1 )-D( IIP1 ) )*
896: $ ( D( IIM1 )+D( IIP1 ) )*TEMP1
897: C = TEMP - DTIIP*( DPSI+DPHI ) - TEMP2
898: ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )
899: IF( DPSI.LT.TEMP1 ) THEN
900: ZZ( 3 ) = DTIIP*DTIIP*DPHI
901: ELSE
902: ZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )
903: END IF
904: ELSE
905: TEMP1 = Z( IIP1 ) / DTIIP
906: TEMP1 = TEMP1*TEMP1
907: TEMP2 = ( D( IIP1 )-D( IIM1 ) )*
908: $ ( D( IIM1 )+D( IIP1 ) )*TEMP1
909: C = TEMP - DTIIM*( DPSI+DPHI ) - TEMP2
910: IF( DPHI.LT.TEMP1 ) THEN
911: ZZ( 1 ) = DTIIM*DTIIM*DPSI
912: ELSE
913: ZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )
914: END IF
915: ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )
916: END IF
917: END IF
918: DD( 1 ) = DTIIM
919: DD( 2 ) = DELTA( II )*WORK( II )
920: DD( 3 ) = DTIIP
921: CALL DLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )
922: *
923: IF( INFO.NE.0 ) THEN
924: *
925: * If INFO is not 0, i.e., DLAED6 failed, switch
926: * back to two pole interpolation
927: *
928: SWTCH3 = .FALSE.
929: INFO = 0
930: DTIPSQ = WORK( IP1 )*DELTA( IP1 )
931: DTISQ = WORK( I )*DELTA( I )
932: IF( .NOT.SWTCH ) THEN
933: IF( ORGATI ) THEN
934: C = W - DTIPSQ*DW + DELSQ*( Z( I )/DTISQ )**2
935: ELSE
936: C = W - DTISQ*DW - DELSQ*( Z( IP1 )/DTIPSQ )**2
937: END IF
938: ELSE
939: TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )
940: IF( ORGATI ) THEN
941: DPSI = DPSI + TEMP*TEMP
942: ELSE
943: DPHI = DPHI + TEMP*TEMP
944: END IF
945: C = W - DTISQ*DPSI - DTIPSQ*DPHI
946: END IF
947: A = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DW
948: B = DTIPSQ*DTISQ*W
949: IF( C.EQ.ZERO ) THEN
950: IF( A.EQ.ZERO ) THEN
951: IF( .NOT.SWTCH ) THEN
952: IF( ORGATI ) THEN
953: A = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*
954: $ ( DPSI+DPHI )
955: ELSE
956: A = Z( IP1 )*Z( IP1 ) +
957: $ DTISQ*DTISQ*( DPSI+DPHI )
958: END IF
959: ELSE
960: A = DTISQ*DTISQ*DPSI + DTIPSQ*DTIPSQ*DPHI
961: END IF
962: END IF
963: ETA = B / A
964: ELSE IF( A.LE.ZERO ) THEN
965: ETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )
966: ELSE
967: ETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )
968: END IF
969: END IF
970: END IF
971: *
972: * Note, eta should be positive if w is negative, and
973: * eta should be negative otherwise. However,
974: * if for some reason caused by roundoff, eta*w > 0,
975: * we simply use one Newton step instead. This way
976: * will guarantee eta*w < 0.
977: *
978: IF( W*ETA.GE.ZERO )
979: $ ETA = -W / DW
980: *
981: ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )
982: TEMP=TAU+ETA
983: IF( TEMP.GT.SGUB .OR. TEMP.LT.SGLB ) THEN
984: IF( W.LT.ZERO ) THEN
985: ETA = ( SGUB-TAU ) / TWO
986: ELSE
987: ETA = ( SGLB-TAU ) / TWO
988: END IF
989: IF( GEOMAVG ) THEN
990: IF( W .LT. ZERO ) THEN
991: IF( TAU .GT. ZERO ) THEN
992: ETA = SQRT(SGUB*TAU)-TAU
993: END IF
994: ELSE
995: IF( SGLB .GT. ZERO ) THEN
996: ETA = SQRT(SGLB*TAU)-TAU
997: END IF
998: END IF
999: END IF
1000: END IF
1001: *
1002: PREW = W
1003: *
1004: TAU = TAU + ETA
1005: SIGMA = SIGMA + ETA
1006: *
1007: DO 200 J = 1, N
1008: WORK( J ) = WORK( J ) + ETA
1009: DELTA( J ) = DELTA( J ) - ETA
1010: 200 CONTINUE
1011: *
1012: * Evaluate PSI and the derivative DPSI
1013: *
1014: DPSI = ZERO
1015: PSI = ZERO
1016: ERRETM = ZERO
1017: DO 210 J = 1, IIM1
1018: TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
1019: PSI = PSI + Z( J )*TEMP
1020: DPSI = DPSI + TEMP*TEMP
1021: ERRETM = ERRETM + PSI
1022: 210 CONTINUE
1023: ERRETM = ABS( ERRETM )
1024: *
1025: * Evaluate PHI and the derivative DPHI
1026: *
1027: DPHI = ZERO
1028: PHI = ZERO
1029: DO 220 J = N, IIP1, -1
1030: TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )
1031: PHI = PHI + Z( J )*TEMP
1032: DPHI = DPHI + TEMP*TEMP
1033: ERRETM = ERRETM + PHI
1034: 220 CONTINUE
1035: *
1036: TAU2 = WORK( II )*DELTA( II )
1037: TEMP = Z( II ) / TAU2
1038: DW = DPSI + DPHI + TEMP*TEMP
1039: TEMP = Z( II )*TEMP
1040: W = RHOINV + PHI + PSI + TEMP
1041: ERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV
1042: $ + THREE*ABS( TEMP )
1043: * $ + ABS( TAU2 )*DW
1044: *
1045: IF( W*PREW.GT.ZERO .AND. ABS( W ).GT.ABS( PREW ) / TEN )
1046: $ SWTCH = .NOT.SWTCH
1047: *
1048: 230 CONTINUE
1049: *
1050: * Return with INFO = 1, NITER = MAXIT and not converged
1051: *
1052: INFO = 1
1053: *
1054: END IF
1055: *
1056: 240 CONTINUE
1057: RETURN
1058: *
1059: * End of DLASD4
1060: *
1061: END
CVSweb interface <joel.bertrand@systella.fr>