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

## ◆ dlaqr3()

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

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

Purpose:
```    Aggressive early deflation:

DLAQR3 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 DOUBLE PRECISION 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 DOUBLE PRECISION 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 DOUBLE PRECISION array, dimension (KBOT)` [out] SI ``` SI is DOUBLE PRECISION 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 DOUBLE PRECISION 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 DOUBLE PRECISION 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 DOUBLE PRECISION 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 DOUBLE PRECISION 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; DLAQR3 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.```
Contributors:
Karen Braman and Ralph Byers, Department of Mathematics, University of Kansas, USA

Definition at line 272 of file dlaqr3.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 DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),
287 \$ V( LDV, * ), WORK( * ), WV( LDWV, * ),
288 \$ Z( LDZ, * )
289* ..
290*
291* ================================================================
292* .. Parameters ..
293 DOUBLE PRECISION ZERO, ONE
294 parameter( zero = 0.0d0, one = 1.0d0 )
295* ..
296* .. Local Scalars ..
297 DOUBLE PRECISION 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 DOUBLE PRECISION DLAMCH
306 INTEGER ILAENV
307 EXTERNAL dlamch, ilaenv
308* ..
309* .. External Subroutines ..
310 EXTERNAL dcopy, dgehrd, dgemm, dlacpy, dlahqr, dlanv2,
312* ..
313* .. Intrinsic Functions ..
314 INTRINSIC abs, dble, int, max, min, 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 DGEHRD ====
326*
327 CALL dgehrd( jw, 1, jw-1, t, ldt, work, work, -1, info )
328 lwk1 = int( work( 1 ) )
329*
330* ==== Workspace query call to DORMHR ====
331*
332 CALL dormhr( '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 DLAQR4 ====
337*
338 CALL dlaqr4( .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 ) = dble( 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 = dlamch( 'SAFE MINIMUM' )
368 safmax = one / safmin
369 ulp = dlamch( 'PRECISION' )
370 smlnum = safmin*( dble( 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 dlacpy( 'U', jw, jw, h( kwtop, kwtop ), ldh, t, ldt )
408 CALL dcopy( jw-1, h( kwtop+1, kwtop ), ldh+1, t( 2, 1 ), ldt+1 )
409*
410 CALL dlaset( 'A', jw, jw, zero, one, v, ldv )
411 nmin = ilaenv( 12, 'DLAQR3', 'SV', jw, 1, jw, lwork )
412 IF( jw.GT.nmin ) THEN
413 CALL dlaqr4( .true., .true., jw, 1, jw, t, ldt, sr( kwtop ),
414 \$ si( kwtop ), 1, jw, v, ldv, work, lwork, infqr )
415 ELSE
416 CALL dlahqr( .true., .true., jw, 1, jw, t, ldt, sr( kwtop ),
417 \$ si( kwtop ), 1, jw, v, ldv, infqr )
418 END IF
419*
420* ==== DTREXC 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* . (DTREXC can not fail in this case.) ====
459*
460 ifst = ns
461 CALL dtrexc( '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, DTREXC does the right thing with
483* . ILST in case of a rare exchange failure. ====
484*
485 ifst = ns
486 CALL dtrexc( '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*
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 dtrexc( '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 dlanv2( 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 dcopy( ns, v, ldv, work, 1 )
601 beta = work( 1 )
602 CALL dlarfg( ns, beta, work( 2 ), 1, tau )
603 work( 1 ) = one
604*
605 CALL dlaset( 'L', jw-2, jw-2, zero, zero, t( 3, 1 ), ldt )
606*
607 CALL dlarf( 'L', ns, jw, work, 1, tau, t, ldt,
608 \$ work( jw+1 ) )
609 CALL dlarf( 'R', ns, ns, work, 1, tau, t, ldt,
610 \$ work( jw+1 ) )
611 CALL dlarf( 'R', jw, ns, work, 1, tau, v, ldv,
612 \$ work( jw+1 ) )
613*
614 CALL dgehrd( 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 dlacpy( 'U', jw, jw, t, ldt, h( kwtop, kwtop ), ldh )
623 CALL dcopy( 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 dormhr( '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 dgemm( 'N', 'N', kln, jw, jw, one, h( krow, kwtop ),
643 \$ ldh, v, ldv, zero, wv, ldwv )
644 CALL dlacpy( '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 dgemm( 'C', 'N', jw, kln, jw, one, v, ldv,
653 \$ h( kwtop, kcol ), ldh, zero, t, ldt )
654 CALL dlacpy( '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 dgemm( 'N', 'N', kln, jw, jw, one, z( krow, kwtop ),
665 \$ ldz, v, ldv, zero, wv, ldwv )
666 CALL dlacpy( '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 ) = dble( lwkopt )
687*
688* ==== End of DLAQR3 ====
689*
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine dgehrd(n, ilo, ihi, a, lda, tau, work, lwork, info)
DGEHRD
Definition dgehrd.f:167
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
Definition dgemm.f:188
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:162
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
Definition dlacpy.f:103
subroutine dlahqr(wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, iloz, ihiz, z, ldz, info)
DLAHQR computes the eigenvalues and Schur factorization of an upper Hessenberg matrix,...
Definition dlahqr.f:207
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
subroutine dlanv2(a, b, c, d, rt1r, rt1i, rt2r, rt2i, cs, sn)
DLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric matrix in standard form.
Definition dlanv2.f:127
subroutine dlaqr4(wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, iloz, ihiz, z, ldz, work, lwork, info)
DLAQR4 computes the eigenvalues of a Hessenberg matrix, and optionally the matrices from the Schur de...
Definition dlaqr4.f:263
subroutine dlarf(side, m, n, v, incv, tau, c, ldc, work)
DLARF applies an elementary reflector to a general rectangular matrix.
Definition dlarf.f:124
subroutine dlarfg(n, alpha, x, incx, tau)
DLARFG generates an elementary reflector (Householder matrix).
Definition dlarfg.f:106
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition dlaset.f:110
subroutine dtrexc(compq, n, t, ldt, q, ldq, ifst, ilst, work, info)
DTREXC
Definition dtrexc.f:148
subroutine dormhr(side, trans, m, n, ilo, ihi, a, lda, tau, c, ldc, work, lwork, info)
DORMHR
Definition dormhr.f:178
Here is the call graph for this function:
Here is the caller graph for this function: