1*> \brief \b SLASQ4 computes an approximation to the smallest eigenvalue using values of d from the previous transform. Used by sbdsqr.
2*
3*  =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6*            http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download SLASQ4 + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slasq4.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slasq4.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slasq4.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18*  Definition:
19*  ===========
20*
21*       SUBROUTINE SLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,
22*                          DN1, DN2, TAU, TTYPE, G )
23*
24*       .. Scalar Arguments ..
25*       INTEGER            I0, N0, N0IN, PP, TTYPE
26*       REAL               DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, TAU
27*       ..
28*       .. Array Arguments ..
29*       REAL               Z( * )
30*       ..
31*
32*
33*> \par Purpose:
34*  =============
35*>
36*> \verbatim
37*>
38*> SLASQ4 computes an approximation TAU to the smallest eigenvalue
39*> using values of d from the previous transform.
40*> \endverbatim
41*
42*  Arguments:
43*  ==========
44*
45*> \param[in] I0
46*> \verbatim
47*>          I0 is INTEGER
48*>        First index.
49*> \endverbatim
50*>
51*> \param[in] N0
52*> \verbatim
53*>          N0 is INTEGER
54*>        Last index.
55*> \endverbatim
56*>
57*> \param[in] Z
58*> \verbatim
59*>          Z is REAL array, dimension ( 4*N0 )
60*>        Z holds the qd array.
61*> \endverbatim
62*>
63*> \param[in] PP
64*> \verbatim
65*>          PP is INTEGER
66*>        PP=0 for ping, PP=1 for pong.
67*> \endverbatim
68*>
69*> \param[in] N0IN
70*> \verbatim
71*>          N0IN is INTEGER
72*>        The value of N0 at start of EIGTEST.
73*> \endverbatim
74*>
75*> \param[in] DMIN
76*> \verbatim
77*>          DMIN is REAL
78*>        Minimum value of d.
79*> \endverbatim
80*>
81*> \param[in] DMIN1
82*> \verbatim
83*>          DMIN1 is REAL
84*>        Minimum value of d, excluding D( N0 ).
85*> \endverbatim
86*>
87*> \param[in] DMIN2
88*> \verbatim
89*>          DMIN2 is REAL
90*>        Minimum value of d, excluding D( N0 ) and D( N0-1 ).
91*> \endverbatim
92*>
93*> \param[in] DN
94*> \verbatim
95*>          DN is REAL
96*>        d(N)
97*> \endverbatim
98*>
99*> \param[in] DN1
100*> \verbatim
101*>          DN1 is REAL
102*>        d(N-1)
103*> \endverbatim
104*>
105*> \param[in] DN2
106*> \verbatim
107*>          DN2 is REAL
108*>        d(N-2)
109*> \endverbatim
110*>
111*> \param[out] TAU
112*> \verbatim
113*>          TAU is REAL
114*>        This is the shift.
115*> \endverbatim
116*>
117*> \param[out] TTYPE
118*> \verbatim
119*>          TTYPE is INTEGER
120*>        Shift type.
121*> \endverbatim
122*>
123*> \param[in,out] G
124*> \verbatim
125*>          G is REAL
126*>        G is passed as an argument in order to save its value between
127*>        calls to SLASQ4.
128*> \endverbatim
129*
130*  Authors:
131*  ========
132*
133*> \author Univ. of Tennessee
134*> \author Univ. of California Berkeley
135*> \author Univ. of Colorado Denver
136*> \author NAG Ltd.
137*
138*> \ingroup auxOTHERcomputational
139*
140*> \par Further Details:
141*  =====================
142*>
143*> \verbatim
144*>
145*>  CNST1 = 9/16
146*> \endverbatim
147*>
148*  =====================================================================
149      SUBROUTINE SLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,
150     $                   DN1, DN2, TAU, TTYPE, G )
151*
152*  -- LAPACK computational routine --
153*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
154*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
155*
156*     .. Scalar Arguments ..
157      INTEGER            I0, N0, N0IN, PP, TTYPE
158      REAL               DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, TAU
159*     ..
160*     .. Array Arguments ..
161      REAL               Z( * )
162*     ..
163*
164*  =====================================================================
165*
166*     .. Parameters ..
167      REAL               CNST1, CNST2, CNST3
168      PARAMETER          ( CNST1 = 0.5630E0, CNST2 = 1.010E0,
169     $                   CNST3 = 1.050E0 )
170      REAL               QURTR, THIRD, HALF, ZERO, ONE, TWO, HUNDRD
171      PARAMETER          ( QURTR = 0.250E0, THIRD = 0.3330E0,
172     $                   HALF = 0.50E0, ZERO = 0.0E0, ONE = 1.0E0,
173     $                   TWO = 2.0E0, HUNDRD = 100.0E0 )
174*     ..
175*     .. Local Scalars ..
176      INTEGER            I4, NN, NP
177      REAL               A2, B1, B2, GAM, GAP1, GAP2, S
178*     ..
179*     .. Intrinsic Functions ..
180      INTRINSIC          MAX, MIN, SQRT
181*     ..
182*     .. Executable Statements ..
183*
184*     A negative DMIN forces the shift to take that absolute value
185*     TTYPE records the type of shift.
186*
187      IF( DMIN.LE.ZERO ) THEN
188         TAU = -DMIN
189         TTYPE = -1
190         RETURN
191      END IF
192*
193      NN = 4*N0 + PP
194      IF( N0IN.EQ.N0 ) THEN
195*
196*        No eigenvalues deflated.
197*
198         IF( DMIN.EQ.DN .OR. DMIN.EQ.DN1 ) THEN
199*
200            B1 = SQRT( Z( NN-3 ) )*SQRT( Z( NN-5 ) )
201            B2 = SQRT( Z( NN-7 ) )*SQRT( Z( NN-9 ) )
202            A2 = Z( NN-7 ) + Z( NN-5 )
203*
204*           Cases 2 and 3.
205*
206            IF( DMIN.EQ.DN .AND. DMIN1.EQ.DN1 ) THEN
207               GAP2 = DMIN2 - A2 - DMIN2*QURTR
208               IF( GAP2.GT.ZERO .AND. GAP2.GT.B2 ) THEN
209                  GAP1 = A2 - DN - ( B2 / GAP2 )*B2
210               ELSE
211                  GAP1 = A2 - DN - ( B1+B2 )
212               END IF
213               IF( GAP1.GT.ZERO .AND. GAP1.GT.B1 ) THEN
214                  S = MAX( DN-( B1 / GAP1 )*B1, HALF*DMIN )
215                  TTYPE = -2
216               ELSE
217                  S = ZERO
218                  IF( DN.GT.B1 )
219     $               S = DN - B1
220                  IF( A2.GT.( B1+B2 ) )
221     $               S = MIN( S, A2-( B1+B2 ) )
222                  S = MAX( S, THIRD*DMIN )
223                  TTYPE = -3
224               END IF
225            ELSE
226*
227*              Case 4.
228*
229               TTYPE = -4
230               S = QURTR*DMIN
231               IF( DMIN.EQ.DN ) THEN
232                  GAM = DN
233                  A2 = ZERO
234                  IF( Z( NN-5 ) .GT. Z( NN-7 ) )
235     $               RETURN
236                  B2 = Z( NN-5 ) / Z( NN-7 )
237                  NP = NN - 9
238               ELSE
239                  NP = NN - 2*PP
240                  GAM = DN1
241                  IF( Z( NP-4 ) .GT. Z( NP-2 ) )
242     $               RETURN
243                  A2 = Z( NP-4 ) / Z( NP-2 )
244                  IF( Z( NN-9 ) .GT. Z( NN-11 ) )
245     $               RETURN
246                  B2 = Z( NN-9 ) / Z( NN-11 )
247                  NP = NN - 13
248               END IF
249*
250*              Approximate contribution to norm squared from I < NN-1.
251*
252               A2 = A2 + B2
253               DO 10 I4 = NP, 4*I0 - 1 + PP, -4
254                  IF( B2.EQ.ZERO )
255     $               GO TO 20
256                  B1 = B2
257                  IF( Z( I4 ) .GT. Z( I4-2 ) )
258     $               RETURN
259                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
260                  A2 = A2 + B2
261                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 )
262     $               GO TO 20
263   10          CONTINUE
264   20          CONTINUE
265               A2 = CNST3*A2
266*
267*              Rayleigh quotient residual bound.
268*
269               IF( A2.LT.CNST1 )
270     $            S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
271            END IF
272         ELSE IF( DMIN.EQ.DN2 ) THEN
273*
274*           Case 5.
275*
276            TTYPE = -5
277            S = QURTR*DMIN
278*
279*           Compute contribution to norm squared from I > NN-2.
280*
281            NP = NN - 2*PP
282            B1 = Z( NP-2 )
283            B2 = Z( NP-6 )
284            GAM = DN2
285            IF( Z( NP-8 ).GT.B2 .OR. Z( NP-4 ).GT.B1 )
286     $         RETURN
287            A2 = ( Z( NP-8 ) / B2 )*( ONE+Z( NP-4 ) / B1 )
288*
289*           Approximate contribution to norm squared from I < NN-2.
290*
291            IF( N0-I0.GT.2 ) THEN
292               B2 = Z( NN-13 ) / Z( NN-15 )
293               A2 = A2 + B2
294               DO 30 I4 = NN - 17, 4*I0 - 1 + PP, -4
295                  IF( B2.EQ.ZERO )
296     $               GO TO 40
297                  B1 = B2
298                  IF( Z( I4 ) .GT. Z( I4-2 ) )
299     $               RETURN
300                  B2 = B2*( Z( I4 ) / Z( I4-2 ) )
301                  A2 = A2 + B2
302                  IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 )
303     $               GO TO 40
304   30          CONTINUE
305   40          CONTINUE
306               A2 = CNST3*A2
307            END IF
308*
309            IF( A2.LT.CNST1 )
310     $         S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )
311         ELSE
312*
313*           Case 6, no information to guide us.
314*
315            IF( TTYPE.EQ.-6 ) THEN
316               G = G + THIRD*( ONE-G )
317            ELSE IF( TTYPE.EQ.-18 ) THEN
318               G = QURTR*THIRD
319            ELSE
320               G = QURTR
321            END IF
322            S = G*DMIN
323            TTYPE = -6
324         END IF
325*
326      ELSE IF( N0IN.EQ.( N0+1 ) ) THEN
327*
328*        One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN.
329*
330         IF( DMIN1.EQ.DN1 .AND. DMIN2.EQ.DN2 ) THEN
331*
332*           Cases 7 and 8.
333*
334            TTYPE = -7
335            S = THIRD*DMIN1
336            IF( Z( NN-5 ).GT.Z( NN-7 ) )
337     $         RETURN
338            B1 = Z( NN-5 ) / Z( NN-7 )
339            B2 = B1
340            IF( B2.EQ.ZERO )
341     $         GO TO 60
342            DO 50 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
343               A2 = B1
344               IF( Z( I4 ).GT.Z( I4-2 ) )
345     $            RETURN
346               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
347               B2 = B2 + B1
348               IF( HUNDRD*MAX( B1, A2 ).LT.B2 )
349     $            GO TO 60
350   50       CONTINUE
351   60       CONTINUE
352            B2 = SQRT( CNST3*B2 )
353            A2 = DMIN1 / ( ONE+B2**2 )
354            GAP2 = HALF*DMIN2 - A2
355            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
356               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
357            ELSE
358               S = MAX( S, A2*( ONE-CNST2*B2 ) )
359               TTYPE = -8
360            END IF
361         ELSE
362*
363*           Case 9.
364*
365            S = QURTR*DMIN1
366            IF( DMIN1.EQ.DN1 )
367     $         S = HALF*DMIN1
368            TTYPE = -9
369         END IF
370*
371      ELSE IF( N0IN.EQ.( N0+2 ) ) THEN
372*
373*        Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.
374*
375*        Cases 10 and 11.
376*
377         IF( DMIN2.EQ.DN2 .AND. TWO*Z( NN-5 ).LT.Z( NN-7 ) ) THEN
378            TTYPE = -10
379            S = THIRD*DMIN2
380            IF( Z( NN-5 ).GT.Z( NN-7 ) )
381     $         RETURN
382            B1 = Z( NN-5 ) / Z( NN-7 )
383            B2 = B1
384            IF( B2.EQ.ZERO )
385     $         GO TO 80
386            DO 70 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4
387               IF( Z( I4 ).GT.Z( I4-2 ) )
388     $            RETURN
389               B1 = B1*( Z( I4 ) / Z( I4-2 ) )
390               B2 = B2 + B1
391               IF( HUNDRD*B1.LT.B2 )
392     $            GO TO 80
393   70       CONTINUE
394   80       CONTINUE
395            B2 = SQRT( CNST3*B2 )
396            A2 = DMIN2 / ( ONE+B2**2 )
397            GAP2 = Z( NN-7 ) + Z( NN-9 ) -
398     $             SQRT( Z( NN-11 ) )*SQRT( Z( NN-9 ) ) - A2
399            IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN
400               S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )
401            ELSE
402               S = MAX( S, A2*( ONE-CNST2*B2 ) )
403            END IF
404         ELSE
405            S = QURTR*DMIN2
406            TTYPE = -11
407         END IF
408      ELSE IF( N0IN.GT.( N0+2 ) ) THEN
409*
410*        Case 12, more than two eigenvalues deflated. No information.
411*
412         S = ZERO
413         TTYPE = -12
414      END IF
415*
416      TAU = S
417      RETURN
418*
419*     End of SLASQ4
420*
421      END
422