LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ slarrj()

subroutine slarrj ( integer n,
real, dimension( * ) d,
real, dimension( * ) e2,
integer ifirst,
integer ilast,
real rtol,
integer offset,
real, dimension( * ) w,
real, dimension( * ) werr,
real, dimension( * ) work,
integer, dimension( * ) iwork,
real pivmin,
real spdiam,
integer info )

SLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.

Download SLARRJ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Given the initial eigenvalue approximations of T, SLARRJ
!> does  bisection to refine the eigenvalues of T,
!> W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial
!> guesses for these eigenvalues are input in W, the corresponding estimate
!> of the error in these guesses in WERR. During bisection, intervals
!> [left, right] are maintained by storing their mid-points and
!> semi-widths in the arrays W and WERR respectively.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The N diagonal elements of T.
!> 
[in]E2
!>          E2 is REAL array, dimension (N-1)
!>          The Squares of the (N-1) subdiagonal elements of T.
!> 
[in]IFIRST
!>          IFIRST is INTEGER
!>          The index of the first eigenvalue to be computed.
!> 
[in]ILAST
!>          ILAST is INTEGER
!>          The index of the last eigenvalue to be computed.
!> 
[in]RTOL
!>          RTOL is REAL
!>          Tolerance for the convergence of the bisection intervals.
!>          An interval [LEFT,RIGHT] has converged if
!>          RIGHT-LEFT < RTOL*MAX(|LEFT|,|RIGHT|).
!> 
[in]OFFSET
!>          OFFSET is INTEGER
!>          Offset for the arrays W and WERR, i.e., the IFIRST-OFFSET
!>          through ILAST-OFFSET elements of these arrays are to be used.
!> 
[in,out]W
!>          W is REAL array, dimension (N)
!>          On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are
!>          estimates of the eigenvalues of L D L^T indexed IFIRST through
!>          ILAST.
!>          On output, these estimates are refined.
!> 
[in,out]WERR
!>          WERR is REAL array, dimension (N)
!>          On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are
!>          the errors in the estimates of the corresponding elements in W.
!>          On output, these errors are refined.
!> 
[out]WORK
!>          WORK is REAL array, dimension (2*N)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (2*N)
!>          Workspace.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot in the Sturm sequence for T.
!> 
[in]SPDIAM
!>          SPDIAM is REAL
!>          The spectral diameter of T.
!> 
[out]INFO
!>          INFO is INTEGER
!>          Error flag.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Beresford Parlett, University of California, Berkeley, USA
Jim Demmel, University of California, Berkeley, USA
Inderjit Dhillon, University of Texas, Austin, USA
Osni Marques, LBNL/NERSC, USA
Christof Voemel, University of California, Berkeley, USA

Definition at line 163 of file slarrj.f.

166*
167* -- LAPACK auxiliary routine --
168* -- LAPACK is a software package provided by Univ. of Tennessee, --
169* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
170*
171* .. Scalar Arguments ..
172 INTEGER IFIRST, ILAST, INFO, N, OFFSET
173 REAL PIVMIN, RTOL, SPDIAM
174* ..
175* .. Array Arguments ..
176 INTEGER IWORK( * )
177 REAL D( * ), E2( * ), W( * ),
178 $ WERR( * ), WORK( * )
179* ..
180*
181* =====================================================================
182*
183* .. Parameters ..
184 REAL ZERO, ONE, TWO, HALF
185 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0,
186 $ half = 0.5e0 )
187 INTEGER MAXITR
188* ..
189* .. Local Scalars ..
190 INTEGER CNT, I, I1, I2, II, ITER, J, K, NEXT, NINT,
191 $ OLNINT, P, PREV, SAVI1
192 REAL DPLUS, FAC, LEFT, MID, RIGHT, S, TMP, WIDTH
193*
194* ..
195* .. Intrinsic Functions ..
196 INTRINSIC abs, max
197* ..
198* .. Executable Statements ..
199*
200 info = 0
201*
202* Quick return if possible
203*
204 IF( n.LE.0 ) THEN
205 RETURN
206 END IF
207*
208 maxitr = int( ( log( spdiam+pivmin )-log( pivmin ) ) /
209 $ log( two ) ) + 2
210*
211* Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ].
212* The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while
213* Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 )
214* for an unconverged interval is set to the index of the next unconverged
215* interval, and is -1 or 0 for a converged interval. Thus a linked
216* list of unconverged intervals is set up.
217*
218
219 i1 = ifirst
220 i2 = ilast
221* The number of unconverged intervals
222 nint = 0
223* The last unconverged interval found
224 prev = 0
225 DO 75 i = i1, i2
226 k = 2*i
227 ii = i - offset
228 left = w( ii ) - werr( ii )
229 mid = w(ii)
230 right = w( ii ) + werr( ii )
231 width = right - mid
232 tmp = max( abs( left ), abs( right ) )
233
234* The following test prevents the test of converged intervals
235 IF( width.LT.rtol*tmp ) THEN
236* This interval has already converged and does not need refinement.
237* (Note that the gaps might change through refining the
238* eigenvalues, however, they can only get bigger.)
239* Remove it from the list.
240 iwork( k-1 ) = -1
241* Make sure that I1 always points to the first unconverged interval
242 IF((i.EQ.i1).AND.(i.LT.i2)) i1 = i + 1
243 IF((prev.GE.i1).AND.(i.LE.i2)) iwork( 2*prev-1 ) = i + 1
244 ELSE
245* unconverged interval found
246 prev = i
247* Make sure that [LEFT,RIGHT] contains the desired eigenvalue
248*
249* Do while( CNT(LEFT).GT.I-1 )
250*
251 fac = one
252 20 CONTINUE
253 cnt = 0
254 s = left
255 dplus = d( 1 ) - s
256 IF( dplus.LT.zero ) cnt = cnt + 1
257 DO 30 j = 2, n
258 dplus = d( j ) - s - e2( j-1 )/dplus
259 IF( dplus.LT.zero ) cnt = cnt + 1
260 30 CONTINUE
261 IF( cnt.GT.i-1 ) THEN
262 left = left - werr( ii )*fac
263 fac = two*fac
264 GO TO 20
265 END IF
266*
267* Do while( CNT(RIGHT).LT.I )
268*
269 fac = one
270 50 CONTINUE
271 cnt = 0
272 s = right
273 dplus = d( 1 ) - s
274 IF( dplus.LT.zero ) cnt = cnt + 1
275 DO 60 j = 2, n
276 dplus = d( j ) - s - e2( j-1 )/dplus
277 IF( dplus.LT.zero ) cnt = cnt + 1
278 60 CONTINUE
279 IF( cnt.LT.i ) THEN
280 right = right + werr( ii )*fac
281 fac = two*fac
282 GO TO 50
283 END IF
284 nint = nint + 1
285 iwork( k-1 ) = i + 1
286 iwork( k ) = cnt
287 END IF
288 work( k-1 ) = left
289 work( k ) = right
290 75 CONTINUE
291
292
293 savi1 = i1
294*
295* Do while( NINT.GT.0 ), i.e. there are still unconverged intervals
296* and while (ITER.LT.MAXITR)
297*
298 iter = 0
299 80 CONTINUE
300 prev = i1 - 1
301 i = i1
302 olnint = nint
303
304 DO 100 p = 1, olnint
305 k = 2*i
306 ii = i - offset
307 next = iwork( k-1 )
308 left = work( k-1 )
309 right = work( k )
310 mid = half*( left + right )
311
312* semiwidth of interval
313 width = right - mid
314 tmp = max( abs( left ), abs( right ) )
315
316 IF( ( width.LT.rtol*tmp ) .OR.
317 $ (iter.EQ.maxitr) )THEN
318* reduce number of unconverged intervals
319 nint = nint - 1
320* Mark interval as converged.
321 iwork( k-1 ) = 0
322 IF( i1.EQ.i ) THEN
323 i1 = next
324 ELSE
325* Prev holds the last unconverged interval previously examined
326 IF(prev.GE.i1) iwork( 2*prev-1 ) = next
327 END IF
328 i = next
329 GO TO 100
330 END IF
331 prev = i
332*
333* Perform one bisection step
334*
335 cnt = 0
336 s = mid
337 dplus = d( 1 ) - s
338 IF( dplus.LT.zero ) cnt = cnt + 1
339 DO 90 j = 2, n
340 dplus = d( j ) - s - e2( j-1 )/dplus
341 IF( dplus.LT.zero ) cnt = cnt + 1
342 90 CONTINUE
343 IF( cnt.LE.i-1 ) THEN
344 work( k-1 ) = mid
345 ELSE
346 work( k ) = mid
347 END IF
348 i = next
349
350 100 CONTINUE
351 iter = iter + 1
352* do another loop if there are still unconverged intervals
353* However, in the last iteration, all intervals are accepted
354* since this is the best we can do.
355 IF( ( nint.GT.0 ).AND.(iter.LE.maxitr) ) GO TO 80
356*
357*
358* At this point, all the intervals have converged
359 DO 110 i = savi1, ilast
360 k = 2*i
361 ii = i - offset
362* All intervals marked by '0' have been refined.
363 IF( iwork( k-1 ).EQ.0 ) THEN
364 w( ii ) = half*( work( k-1 )+work( k ) )
365 werr( ii ) = work( k ) - w( ii )
366 END IF
367 110 CONTINUE
368*
369
370 RETURN
371*
372* End of SLARRJ
373*
Here is the caller graph for this function: