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

◆ slaqr3()

subroutine slaqr3 ( logical  wantt,
logical  wantz,
integer  n,
integer  ktop,
integer  kbot,
integer  nw,
real, dimension( ldh, * )  h,
integer  ldh,
integer  iloz,
integer  ihiz,
real, dimension( ldz, * )  z,
integer  ldz,
integer  ns,
integer  nd,
real, dimension( * )  sr,
real, dimension( * )  si,
real, dimension( ldv, * )  v,
integer  ldv,
integer  nh,
real, dimension( ldt, * )  t,
integer  ldt,
integer  nv,
real, dimension( ldwv, * )  wv,
integer  ldwv,
real, dimension( * )  work,
integer  lwork 
)

SLAQR3 performs the orthogonal similarity transformation of a Hessenberg matrix to detect and deflate fully converged eigenvalues from a trailing principal submatrix (aggressive early deflation).

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

Purpose:
    Aggressive early deflation:

    SLAQR3 accepts as input an upper Hessenberg matrix
    H and performs an orthogonal similarity transformation
    designed to detect and deflate fully converged eigenvalues from
    a trailing principal submatrix.  On output H has been over-
    written by a new Hessenberg matrix that is a perturbation of
    an orthogonal similarity transformation of H.  It is to be
    hoped that the final version of H has many zero subdiagonal
    entries.
Parameters
[in]WANTT
          WANTT is LOGICAL
          If .TRUE., then the Hessenberg matrix H is fully updated
          so that the quasi-triangular Schur factor may be
          computed (in cooperation with the calling subroutine).
          If .FALSE., then only enough of H is updated to preserve
          the eigenvalues.
[in]WANTZ
          WANTZ is LOGICAL
          If .TRUE., then the orthogonal matrix Z is updated so
          so that the orthogonal Schur factor may be computed
          (in cooperation with the calling subroutine).
          If .FALSE., then Z is not referenced.
[in]N
          N is INTEGER
          The order of the matrix H and (if WANTZ is .TRUE.) the
          order of the orthogonal matrix Z.
[in]KTOP
          KTOP is INTEGER
          It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.
          KBOT and KTOP together determine an isolated block
          along the diagonal of the Hessenberg matrix.
[in]KBOT
          KBOT is INTEGER
          It is assumed without a check that either
          KBOT = N or H(KBOT+1,KBOT)=0.  KBOT and KTOP together
          determine an isolated block along the diagonal of the
          Hessenberg matrix.
[in]NW
          NW is INTEGER
          Deflation window size.  1 <= NW <= (KBOT-KTOP+1).
[in,out]H
          H is REAL array, dimension (LDH,N)
          On input the initial N-by-N section of H stores the
          Hessenberg matrix undergoing aggressive early deflation.
          On output H has been transformed by an orthogonal
          similarity transformation, perturbed, and the returned
          to Hessenberg form that (it is to be hoped) has some
          zero subdiagonal entries.
[in]LDH
          LDH is INTEGER
          Leading dimension of H just as declared in the calling
          subroutine.  N <= LDH
[in]ILOZ
          ILOZ is INTEGER
[in]IHIZ
          IHIZ is INTEGER
          Specify the rows of Z to which transformations must be
          applied if WANTZ is .TRUE.. 1 <= ILOZ <= IHIZ <= N.
[in,out]Z
          Z is REAL array, dimension (LDZ,N)
          IF WANTZ is .TRUE., then on output, the orthogonal
          similarity transformation mentioned above has been
          accumulated into Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.
          If WANTZ is .FALSE., then Z is unreferenced.
[in]LDZ
          LDZ is INTEGER
          The leading dimension of Z just as declared in the
          calling subroutine.  1 <= LDZ.
[out]NS
          NS is INTEGER
          The number of unconverged (ie approximate) eigenvalues
          returned in SR and SI that may be used as shifts by the
          calling subroutine.
[out]ND
          ND is INTEGER
          The number of converged eigenvalues uncovered by this
          subroutine.
[out]SR
          SR is REAL array, dimension (KBOT)
[out]SI
          SI is REAL array, dimension (KBOT)
          On output, the real and imaginary parts of approximate
          eigenvalues that may be used for shifts are stored in
          SR(KBOT-ND-NS+1) through SR(KBOT-ND) and
          SI(KBOT-ND-NS+1) through SI(KBOT-ND), respectively.
          The real and imaginary parts of converged eigenvalues
          are stored in SR(KBOT-ND+1) through SR(KBOT) and
          SI(KBOT-ND+1) through SI(KBOT), respectively.
[out]V
          V is REAL array, dimension (LDV,NW)
          An NW-by-NW work array.
[in]LDV
          LDV is INTEGER
          The leading dimension of V just as declared in the
          calling subroutine.  NW <= LDV
[in]NH
          NH is INTEGER
          The number of columns of T.  NH >= NW.
[out]T
          T is REAL array, dimension (LDT,NW)
[in]LDT
          LDT is INTEGER
          The leading dimension of T just as declared in the
          calling subroutine.  NW <= LDT
[in]NV
          NV is INTEGER
          The number of rows of work array WV available for
          workspace.  NV >= NW.
[out]WV
          WV is REAL array, dimension (LDWV,NW)
[in]LDWV
          LDWV is INTEGER
          The leading dimension of W just as declared in the
          calling subroutine.  NW <= LDV
[out]WORK
          WORK is REAL array, dimension (LWORK)
          On exit, WORK(1) is set to an estimate of the optimal value
          of LWORK for the given values of N, NW, KTOP and KBOT.
[in]LWORK
          LWORK is INTEGER
          The dimension of the work array WORK.  LWORK = 2*NW
          suffices, but greater efficiency may result from larger
          values of LWORK.

          If LWORK = -1, then a workspace query is assumed; SLAQR3
          only estimates the optimal workspace size for the given
          values of N, NW, KTOP and KBOT.  The estimate is returned
          in WORK(1).  No error message related to LWORK is issued
          by XERBLA.  Neither H nor Z are accessed.
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Karen Braman and Ralph Byers, Department of Mathematics, University of Kansas, USA

Definition at line 272 of file slaqr3.f.

275*
276* -- LAPACK auxiliary routine --
277* -- LAPACK is a software package provided by Univ. of Tennessee, --
278* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
279*
280* .. Scalar Arguments ..
281 INTEGER IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,
282 $ LDZ, LWORK, N, ND, NH, NS, NV, NW
283 LOGICAL WANTT, WANTZ
284* ..
285* .. Array Arguments ..
286 REAL H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),
287 $ V( LDV, * ), WORK( * ), WV( LDWV, * ),
288 $ Z( LDZ, * )
289* ..
290*
291* ================================================================
292* .. Parameters ..
293 REAL ZERO, ONE
294 parameter( zero = 0.0e0, one = 1.0e0 )
295* ..
296* .. Local Scalars ..
297 REAL AA, BB, BETA, CC, CS, DD, EVI, EVK, FOO, S,
298 $ SAFMAX, SAFMIN, SMLNUM, SN, TAU, ULP
299 INTEGER I, IFST, ILST, INFO, INFQR, J, JW, K, KCOL,
300 $ KEND, KLN, KROW, KWTOP, LTOP, LWK1, LWK2, LWK3,
301 $ LWKOPT, NMIN
302 LOGICAL BULGE, SORTED
303* ..
304* .. External Functions ..
305 REAL SLAMCH, SROUNDUP_LWORK
306 INTEGER ILAENV
307 EXTERNAL slamch, sroundup_lwork, ilaenv
308* ..
309* .. External Subroutines ..
310 EXTERNAL scopy, sgehrd, sgemm, slacpy, slahqr, slanv2,
312* ..
313* .. Intrinsic Functions ..
314 INTRINSIC abs, int, max, min, real, sqrt
315* ..
316* .. Executable Statements ..
317*
318* ==== Estimate optimal workspace. ====
319*
320 jw = min( nw, kbot-ktop+1 )
321 IF( jw.LE.2 ) THEN
322 lwkopt = 1
323 ELSE
324*
325* ==== Workspace query call to SGEHRD ====
326*
327 CALL sgehrd( jw, 1, jw-1, t, ldt, work, work, -1, info )
328 lwk1 = int( work( 1 ) )
329*
330* ==== Workspace query call to SORMHR ====
331*
332 CALL sormhr( 'R', 'N', jw, jw, 1, jw-1, t, ldt, work, v, ldv,
333 $ work, -1, info )
334 lwk2 = int( work( 1 ) )
335*
336* ==== Workspace query call to SLAQR4 ====
337*
338 CALL slaqr4( .true., .true., jw, 1, jw, t, ldt, sr, si, 1, jw,
339 $ v, ldv, work, -1, infqr )
340 lwk3 = int( work( 1 ) )
341*
342* ==== Optimal workspace ====
343*
344 lwkopt = max( jw+max( lwk1, lwk2 ), lwk3 )
345 END IF
346*
347* ==== Quick return in case of workspace query. ====
348*
349 IF( lwork.EQ.-1 ) THEN
350 work( 1 ) = sroundup_lwork( lwkopt )
351 RETURN
352 END IF
353*
354* ==== Nothing to do ...
355* ... for an empty active block ... ====
356 ns = 0
357 nd = 0
358 work( 1 ) = one
359 IF( ktop.GT.kbot )
360 $ RETURN
361* ... nor for an empty deflation window. ====
362 IF( nw.LT.1 )
363 $ RETURN
364*
365* ==== Machine constants ====
366*
367 safmin = slamch( 'SAFE MINIMUM' )
368 safmax = one / safmin
369 ulp = slamch( 'PRECISION' )
370 smlnum = safmin*( real( n ) / ulp )
371*
372* ==== Setup deflation window ====
373*
374 jw = min( nw, kbot-ktop+1 )
375 kwtop = kbot - jw + 1
376 IF( kwtop.EQ.ktop ) THEN
377 s = zero
378 ELSE
379 s = h( kwtop, kwtop-1 )
380 END IF
381*
382 IF( kbot.EQ.kwtop ) THEN
383*
384* ==== 1-by-1 deflation window: not much to do ====
385*
386 sr( kwtop ) = h( kwtop, kwtop )
387 si( kwtop ) = zero
388 ns = 1
389 nd = 0
390 IF( abs( s ).LE.max( smlnum, ulp*abs( h( kwtop, kwtop ) ) ) )
391 $ THEN
392 ns = 0
393 nd = 1
394 IF( kwtop.GT.ktop )
395 $ h( kwtop, kwtop-1 ) = zero
396 END IF
397 work( 1 ) = one
398 RETURN
399 END IF
400*
401* ==== Convert to spike-triangular form. (In case of a
402* . rare QR failure, this routine continues to do
403* . aggressive early deflation using that part of
404* . the deflation window that converged using INFQR
405* . here and there to keep track.) ====
406*
407 CALL slacpy( 'U', jw, jw, h( kwtop, kwtop ), ldh, t, ldt )
408 CALL scopy( jw-1, h( kwtop+1, kwtop ), ldh+1, t( 2, 1 ), ldt+1 )
409*
410 CALL slaset( 'A', jw, jw, zero, one, v, ldv )
411 nmin = ilaenv( 12, 'SLAQR3', 'SV', jw, 1, jw, lwork )
412 IF( jw.GT.nmin ) THEN
413 CALL slaqr4( .true., .true., jw, 1, jw, t, ldt, sr( kwtop ),
414 $ si( kwtop ), 1, jw, v, ldv, work, lwork, infqr )
415 ELSE
416 CALL slahqr( .true., .true., jw, 1, jw, t, ldt, sr( kwtop ),
417 $ si( kwtop ), 1, jw, v, ldv, infqr )
418 END IF
419*
420* ==== STREXC needs a clean margin near the diagonal ====
421*
422 DO 10 j = 1, jw - 3
423 t( j+2, j ) = zero
424 t( j+3, j ) = zero
425 10 CONTINUE
426 IF( jw.GT.2 )
427 $ t( jw, jw-2 ) = zero
428*
429* ==== Deflation detection loop ====
430*
431 ns = jw
432 ilst = infqr + 1
433 20 CONTINUE
434 IF( ilst.LE.ns ) THEN
435 IF( ns.EQ.1 ) THEN
436 bulge = .false.
437 ELSE
438 bulge = t( ns, ns-1 ).NE.zero
439 END IF
440*
441* ==== Small spike tip test for deflation ====
442*
443 IF( .NOT. bulge ) THEN
444*
445* ==== Real eigenvalue ====
446*
447 foo = abs( t( ns, ns ) )
448 IF( foo.EQ.zero )
449 $ foo = abs( s )
450 IF( abs( s*v( 1, ns ) ).LE.max( smlnum, ulp*foo ) ) THEN
451*
452* ==== Deflatable ====
453*
454 ns = ns - 1
455 ELSE
456*
457* ==== Undeflatable. Move it up out of the way.
458* . (STREXC can not fail in this case.) ====
459*
460 ifst = ns
461 CALL strexc( 'V', jw, t, ldt, v, ldv, ifst, ilst, work,
462 $ info )
463 ilst = ilst + 1
464 END IF
465 ELSE
466*
467* ==== Complex conjugate pair ====
468*
469 foo = abs( t( ns, ns ) ) + sqrt( abs( t( ns, ns-1 ) ) )*
470 $ sqrt( abs( t( ns-1, ns ) ) )
471 IF( foo.EQ.zero )
472 $ foo = abs( s )
473 IF( max( abs( s*v( 1, ns ) ), abs( s*v( 1, ns-1 ) ) ).LE.
474 $ max( smlnum, ulp*foo ) ) THEN
475*
476* ==== Deflatable ====
477*
478 ns = ns - 2
479 ELSE
480*
481* ==== Undeflatable. Move them up out of the way.
482* . Fortunately, STREXC does the right thing with
483* . ILST in case of a rare exchange failure. ====
484*
485 ifst = ns
486 CALL strexc( 'V', jw, t, ldt, v, ldv, ifst, ilst, work,
487 $ info )
488 ilst = ilst + 2
489 END IF
490 END IF
491*
492* ==== End deflation detection loop ====
493*
494 GO TO 20
495 END IF
496*
497* ==== Return to Hessenberg form ====
498*
499 IF( ns.EQ.0 )
500 $ s = zero
501*
502 IF( ns.LT.jw ) THEN
503*
504* ==== sorting diagonal blocks of T improves accuracy for
505* . graded matrices. Bubble sort deals well with
506* . exchange failures. ====
507*
508 sorted = .false.
509 i = ns + 1
510 30 CONTINUE
511 IF( sorted )
512 $ GO TO 50
513 sorted = .true.
514*
515 kend = i - 1
516 i = infqr + 1
517 IF( i.EQ.ns ) THEN
518 k = i + 1
519 ELSE IF( t( i+1, i ).EQ.zero ) THEN
520 k = i + 1
521 ELSE
522 k = i + 2
523 END IF
524 40 CONTINUE
525 IF( k.LE.kend ) THEN
526 IF( k.EQ.i+1 ) THEN
527 evi = abs( t( i, i ) )
528 ELSE
529 evi = abs( t( i, i ) ) + sqrt( abs( t( i+1, i ) ) )*
530 $ sqrt( abs( t( i, i+1 ) ) )
531 END IF
532*
533 IF( k.EQ.kend ) THEN
534 evk = abs( t( k, k ) )
535 ELSE IF( t( k+1, k ).EQ.zero ) THEN
536 evk = abs( t( k, k ) )
537 ELSE
538 evk = abs( t( k, k ) ) + sqrt( abs( t( k+1, k ) ) )*
539 $ sqrt( abs( t( k, k+1 ) ) )
540 END IF
541*
542 IF( evi.GE.evk ) THEN
543 i = k
544 ELSE
545 sorted = .false.
546 ifst = i
547 ilst = k
548 CALL strexc( 'V', jw, t, ldt, v, ldv, ifst, ilst, work,
549 $ info )
550 IF( info.EQ.0 ) THEN
551 i = ilst
552 ELSE
553 i = k
554 END IF
555 END IF
556 IF( i.EQ.kend ) THEN
557 k = i + 1
558 ELSE IF( t( i+1, i ).EQ.zero ) THEN
559 k = i + 1
560 ELSE
561 k = i + 2
562 END IF
563 GO TO 40
564 END IF
565 GO TO 30
566 50 CONTINUE
567 END IF
568*
569* ==== Restore shift/eigenvalue array from T ====
570*
571 i = jw
572 60 CONTINUE
573 IF( i.GE.infqr+1 ) THEN
574 IF( i.EQ.infqr+1 ) THEN
575 sr( kwtop+i-1 ) = t( i, i )
576 si( kwtop+i-1 ) = zero
577 i = i - 1
578 ELSE IF( t( i, i-1 ).EQ.zero ) THEN
579 sr( kwtop+i-1 ) = t( i, i )
580 si( kwtop+i-1 ) = zero
581 i = i - 1
582 ELSE
583 aa = t( i-1, i-1 )
584 cc = t( i, i-1 )
585 bb = t( i-1, i )
586 dd = t( i, i )
587 CALL slanv2( aa, bb, cc, dd, sr( kwtop+i-2 ),
588 $ si( kwtop+i-2 ), sr( kwtop+i-1 ),
589 $ si( kwtop+i-1 ), cs, sn )
590 i = i - 2
591 END IF
592 GO TO 60
593 END IF
594*
595 IF( ns.LT.jw .OR. s.EQ.zero ) THEN
596 IF( ns.GT.1 .AND. s.NE.zero ) THEN
597*
598* ==== Reflect spike back into lower triangle ====
599*
600 CALL scopy( ns, v, ldv, work, 1 )
601 beta = work( 1 )
602 CALL slarfg( ns, beta, work( 2 ), 1, tau )
603 work( 1 ) = one
604*
605 CALL slaset( 'L', jw-2, jw-2, zero, zero, t( 3, 1 ), ldt )
606*
607 CALL slarf( 'L', ns, jw, work, 1, tau, t, ldt,
608 $ work( jw+1 ) )
609 CALL slarf( 'R', ns, ns, work, 1, tau, t, ldt,
610 $ work( jw+1 ) )
611 CALL slarf( 'R', jw, ns, work, 1, tau, v, ldv,
612 $ work( jw+1 ) )
613*
614 CALL sgehrd( jw, 1, ns, t, ldt, work, work( jw+1 ),
615 $ lwork-jw, info )
616 END IF
617*
618* ==== Copy updated reduced window into place ====
619*
620 IF( kwtop.GT.1 )
621 $ h( kwtop, kwtop-1 ) = s*v( 1, 1 )
622 CALL slacpy( 'U', jw, jw, t, ldt, h( kwtop, kwtop ), ldh )
623 CALL scopy( jw-1, t( 2, 1 ), ldt+1, h( kwtop+1, kwtop ),
624 $ ldh+1 )
625*
626* ==== Accumulate orthogonal matrix in order update
627* . H and Z, if requested. ====
628*
629 IF( ns.GT.1 .AND. s.NE.zero )
630 $ CALL sormhr( 'R', 'N', jw, ns, 1, ns, t, ldt, work, v, ldv,
631 $ work( jw+1 ), lwork-jw, info )
632*
633* ==== Update vertical slab in H ====
634*
635 IF( wantt ) THEN
636 ltop = 1
637 ELSE
638 ltop = ktop
639 END IF
640 DO 70 krow = ltop, kwtop - 1, nv
641 kln = min( nv, kwtop-krow )
642 CALL sgemm( 'N', 'N', kln, jw, jw, one, h( krow, kwtop ),
643 $ ldh, v, ldv, zero, wv, ldwv )
644 CALL slacpy( 'A', kln, jw, wv, ldwv, h( krow, kwtop ), ldh )
645 70 CONTINUE
646*
647* ==== Update horizontal slab in H ====
648*
649 IF( wantt ) THEN
650 DO 80 kcol = kbot + 1, n, nh
651 kln = min( nh, n-kcol+1 )
652 CALL sgemm( 'C', 'N', jw, kln, jw, one, v, ldv,
653 $ h( kwtop, kcol ), ldh, zero, t, ldt )
654 CALL slacpy( 'A', jw, kln, t, ldt, h( kwtop, kcol ),
655 $ ldh )
656 80 CONTINUE
657 END IF
658*
659* ==== Update vertical slab in Z ====
660*
661 IF( wantz ) THEN
662 DO 90 krow = iloz, ihiz, nv
663 kln = min( nv, ihiz-krow+1 )
664 CALL sgemm( 'N', 'N', kln, jw, jw, one, z( krow, kwtop ),
665 $ ldz, v, ldv, zero, wv, ldwv )
666 CALL slacpy( 'A', kln, jw, wv, ldwv, z( krow, kwtop ),
667 $ ldz )
668 90 CONTINUE
669 END IF
670 END IF
671*
672* ==== Return the number of deflations ... ====
673*
674 nd = jw - ns
675*
676* ==== ... and the number of shifts. (Subtracting
677* . INFQR from the spike length takes care
678* . of the case of a rare QR failure while
679* . calculating eigenvalues of the deflation
680* . window.) ====
681*
682 ns = ns - infqr
683*
684* ==== Return optimal workspace. ====
685*
686 work( 1 ) = sroundup_lwork( lwkopt )
687*
688* ==== End of SLAQR3 ====
689*
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
Definition scopy.f:82
subroutine sgehrd(n, ilo, ihi, a, lda, tau, work, lwork, info)
SGEHRD
Definition sgehrd.f:167
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
Definition sgemm.f:188
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:162
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
Definition slacpy.f:103
subroutine slahqr(wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, iloz, ihiz, z, ldz, info)
SLAHQR computes the eigenvalues and Schur factorization of an upper Hessenberg matrix,...
Definition slahqr.f:207
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
subroutine slanv2(a, b, c, d, rt1r, rt1i, rt2r, rt2i, cs, sn)
SLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric matrix in standard form.
Definition slanv2.f:127
subroutine slaqr4(wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, iloz, ihiz, z, ldz, work, lwork, info)
SLAQR4 computes the eigenvalues of a Hessenberg matrix, and optionally the matrices from the Schur de...
Definition slaqr4.f:265
subroutine slarf(side, m, n, v, incv, tau, c, ldc, work)
SLARF applies an elementary reflector to a general rectangular matrix.
Definition slarf.f:124
subroutine slarfg(n, alpha, x, incx, tau)
SLARFG generates an elementary reflector (Householder matrix).
Definition slarfg.f:106
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition slaset.f:110
real function sroundup_lwork(lwork)
SROUNDUP_LWORK
subroutine strexc(compq, n, t, ldt, q, ldq, ifst, ilst, work, info)
STREXC
Definition strexc.f:148
subroutine sormhr(side, trans, m, n, ilo, ihi, a, lda, tau, c, ldc, work, lwork, info)
SORMHR
Definition sormhr.f:179
Here is the call graph for this function:
Here is the caller graph for this function: