5
6
7
8
9
10
11
12 INTEGER INFO, LDZ, M, N
13 DOUBLE PRECISION ORFAC
14
15
16 INTEGER IBLOCK( * ), IFAIL( * ), ISPLIT( * ),
17 $ IWORK( * )
18 DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 DOUBLE PRECISION ZERO, ONE, TEN, ODM1
114 parameter( zero = 0.0d+0, one = 1.0d+0, ten = 1.0d+1,
115 $ odm1 = 1.0d-1 )
116 INTEGER MAXITS, EXTRA
117 parameter( maxits = 5, extra = 2 )
118
119
120 INTEGER B1, BLKSIZ, BN, GPIND, I, IINFO, INDRV1,
121 $ INDRV2, INDRV3, INDRV4, INDRV5, ITS, J, J1,
122 $ JBLK, JMAX, NBLK, NRMCHK
123 DOUBLE PRECISION EPS, EPS1, NRM, ONENRM, ORTOL, PERTOL, SCL,
124 $ SEP, STPCRT, TOL, XJ, XJM, ZTR
125
126
127 INTEGER ISEED( 4 )
128
129
130 INTEGER IDAMAX
131 DOUBLE PRECISION DASUM, DDOT, DLAMCH, DNRM2
132 EXTERNAL idamax, dasum, ddot,
dlamch, dnrm2
133
134
135 EXTERNAL daxpy, dcopy, dlagtf, dlagts, dlarnv, dscal,
136 $ xerbla
137
138
139 INTRINSIC abs,
max, sqrt
140
141
142
143
144
145 info = 0
146 DO 10 i = 1, m
147 ifail( i ) = 0
148 10 CONTINUE
149
150 IF( n.LT.0 ) THEN
151 info = -1
152 ELSE IF( m.LT.0 .OR. m.GT.n ) THEN
153 info = -4
154 ELSE IF( orfac.LT.zero ) THEN
155 info = -8
156 ELSE IF( ldz.LT.
max( 1, n ) )
THEN
157 info = -10
158 ELSE
159 DO 20 j = 2, m
160 IF( iblock( j ).LT.iblock( j-1 ) ) THEN
161 info = -6
162 GO TO 30
163 END IF
164 IF( iblock( j ).EQ.iblock( j-1 ) .AND. w( j ).LT.w( j-1 ) )
165 $ THEN
166 info = -5
167 GO TO 30
168 END IF
169 20 CONTINUE
170 30 CONTINUE
171 END IF
172
173 IF( info.NE.0 ) THEN
174 CALL xerbla( 'DSTEIN2', -info )
175 RETURN
176 END IF
177
178
179
180 IF( n.EQ.0 .OR. m.EQ.0 ) THEN
181 RETURN
182 ELSE IF( n.EQ.1 ) THEN
183 z( 1, 1 ) = one
184 RETURN
185 END IF
186
187
188
189 eps =
dlamch(
'Precision' )
190
191
192
193 DO 40 i = 1, 4
194 iseed( i ) = 1
195 40 CONTINUE
196
197
198
199 indrv1 = 0
200 indrv2 = indrv1 + n
201 indrv3 = indrv2 + n
202 indrv4 = indrv3 + n
203 indrv5 = indrv4 + n
204
205
206
207 j1 = 1
208 DO 160 nblk = 1, iblock( m )
209
210
211
212 IF( nblk.EQ.1 ) THEN
213 b1 = 1
214 ELSE
215 b1 = isplit( nblk-1 ) + 1
216 END IF
217 bn = isplit( nblk )
218 blksiz = bn - b1 + 1
219 IF( blksiz.EQ.1 )
220 $ GO TO 60
221 gpind = j1
222
223
224
225 onenrm = abs( d( b1 ) ) + abs( e( b1 ) )
226 onenrm =
max( onenrm, abs( d( bn ) )+abs( e( bn-1 ) ) )
227 DO 50 i = b1 + 1, bn - 1
228 onenrm =
max( onenrm, abs( d( i ) )+abs( e( i-1 ) )+
229 $ abs( e( i ) ) )
230 50 CONTINUE
231 ortol = orfac*onenrm
232
233 stpcrt = sqrt( odm1 / blksiz )
234
235
236
237 60 CONTINUE
238 jblk = 0
239 DO 150 j = j1, m
240 IF( iblock( j ).NE.nblk ) THEN
241 j1 = j
242 GO TO 160
243 END IF
244 jblk = jblk + 1
245 xj = w( j )
246
247
248
249 IF( blksiz.EQ.1 ) THEN
250 work( indrv1+1 ) = one
251 GO TO 120
252 END IF
253
254
255
256
257 IF( jblk.GT.1 ) THEN
258 eps1 = abs( eps*xj )
259 pertol = ten*eps1
260 sep = xj - xjm
261 IF( sep.LT.pertol )
262 $ xj = xjm + pertol
263 END IF
264
265 its = 0
266 nrmchk = 0
267
268
269
270 CALL dlarnv( 2, iseed, blksiz, work( indrv1+1 ) )
271
272
273
274 CALL dcopy( blksiz, d( b1 ), 1, work( indrv4+1 ), 1 )
275 CALL dcopy( blksiz-1, e( b1 ), 1, work( indrv2+2 ), 1 )
276 CALL dcopy( blksiz-1, e( b1 ), 1, work( indrv3+1 ), 1 )
277
278
279
280 tol = zero
281 CALL dlagtf( blksiz, work( indrv4+1 ), xj, work( indrv2+2 ),
282 $ work( indrv3+1 ), tol, work( indrv5+1 ), iwork,
283 $ iinfo )
284
285
286
287 70 CONTINUE
288 its = its + 1
289 IF( its.GT.maxits )
290 $ GO TO 100
291
292
293
294 scl = blksiz*onenrm*
max( eps,
295 $ abs( work( indrv4+blksiz ) ) ) /
296 $ dasum( blksiz, work( indrv1+1 ), 1 )
297 CALL dscal( blksiz, scl, work( indrv1+1 ), 1 )
298
299
300
301 CALL dlagts( -1, blksiz, work( indrv4+1 ), work( indrv2+2 ),
302 $ work( indrv3+1 ), work( indrv5+1 ), iwork,
303 $ work( indrv1+1 ), tol, iinfo )
304
305
306
307
308 IF( jblk.EQ.1 )
309 $ GO TO 90
310 IF( abs( xj-xjm ).GT.ortol )
311 $ gpind = j
312
313 IF( gpind.NE.j ) THEN
314 DO 80 i = gpind, j - 1
315 ztr = -ddot( blksiz, work( indrv1+1 ), 1, z( b1, i ),
316 $ 1 )
317 CALL daxpy( blksiz, ztr, z( b1, i ), 1,
318 $ work( indrv1+1 ), 1 )
319 80 CONTINUE
320 END IF
321
322
323
324 90 CONTINUE
325 jmax = idamax( blksiz, work( indrv1+1 ), 1 )
326 nrm = abs( work( indrv1+jmax ) )
327
328
329
330
331 IF( nrm.LT.stpcrt )
332 $ GO TO 70
333 nrmchk = nrmchk + 1
334 IF( nrmchk.LT.extra+1 )
335 $ GO TO 70
336
337 GO TO 110
338
339
340
341
342 100 CONTINUE
343 info = info + 1
344 ifail( info ) = j
345
346
347
348 110 CONTINUE
349 scl = one / dnrm2( blksiz, work( indrv1+1 ), 1 )
350 jmax = idamax( blksiz, work( indrv1+1 ), 1 )
351 IF( work( indrv1+jmax ).LT.zero )
352 $ scl = -scl
353 CALL dscal( blksiz, scl, work( indrv1+1 ), 1 )
354 120 CONTINUE
355 DO 130 i = 1, n
356 z( i, j ) = zero
357 130 CONTINUE
358 DO 140 i = 1, blksiz
359 z( b1+i-1, j ) = work( indrv1+i )
360 140 CONTINUE
361
362
363
364
365 xjm = xj
366
367 150 CONTINUE
368 160 CONTINUE
369
370 RETURN
371
372
373