1 SUBROUTINE dhseqr( JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z,
2 $ LDZ, WORK, LWORK, INFO )
11 INTEGER IHI, ILO, INFO, LDH, LDZ, LWORK, N
14 DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),
118 DOUBLE PRECISION ZERO, ONE, TWO
119 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0 )
120 DOUBLE PRECISION CONST
121 parameter( const = 1.5d+0 )
123 parameter( nsmax = 15, lds = nsmax )
126 LOGICAL INITZ, LQUERY, WANTT, WANTZ
127 INTEGER I, I1, I2, IERR, II, ITEMP, ITN, ITS, J, K, L,
128 $ maxb, nh, nr, ns, nv
129 DOUBLE PRECISION ABSW, OVFL, SMLNUM, TAU, TEMP, TST1, ULP, UNFL
132 DOUBLE PRECISION S( LDS, NSMAX ), V( NSMAX+1 ), VV( NSMAX+1 )
136 INTEGER IDAMAX, ILAENV
137 DOUBLE PRECISION DLAMCH, DLANHS, DLAPY2
138 EXTERNAL lsame, idamax, ilaenv, dlamch, dlanhs, dlapy2
145 INTRINSIC abs, max, min
151 wantt = lsame( job,
'S' )
152 initz = lsame( compz,
'I' )
153 wantz = initz .OR. lsame( compz,
'V' )
156 work( 1 ) = max( 1, n )
157 lquery = ( lwork.EQ.-1 )
158 IF( .NOT.lsame( job,
'E' ) .AND. .NOT.wantt )
THEN
160 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
162 ELSE IF( n.LT.0 )
THEN
164 ELSE IF( ilo.LT.1 .OR. ilo.GT.max( 1, n ) )
THEN
166 ELSE IF( ihi.LT.min( ilo, n ) .OR. ihi.GT.n )
THEN
168 ELSE IF( ldh.LT.max( 1, n ) )
THEN
170 ELSE IF( ldz.LT.1 .OR. wantz .AND. ldz.LT.max( 1, n ) )
THEN
172 ELSE IF( lwork.LT.max( 1, n ) .AND. .NOT.lquery )
THEN
176 CALL xerbla(
'DHSEQR', -info )
178 ELSE IF( lquery )
THEN
185 $
CALL dlaset(
'Full', n, n, zero, one, z, ldz )
202 IF( ilo.EQ.ihi )
THEN
203 wr( ilo ) = h( ilo, ilo )
211 DO 40 j = ilo, ihi - 2
220 ns = ilaenv( 4,
'DHSEQR', job // compz, n, ilo, ihi, -1 )
221 maxb = ilaenv( 8,
'DHSEQR', job // compz, n, ilo, ihi, -1 )
222 IF( ns.LE.2 .OR. ns.GT.nh .OR. maxb.GE.nh )
THEN
226 CALL dlahqr( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,
227 $ ihi, z, ldz, info )
230 maxb = max( 3, maxb )
231 ns = min( ns, maxb, nsmax )
238 unfl = dlamch(
'Safe minimum' )
241 ulp = dlamch(
'Precision' )
242 smlnum = unfl*( nh / ulp )
277 DO 60 k = i, l + 1, -1
278 tst1 = abs( h( k-1, k-1 ) ) + abs( h( k, k ) )
280 $ tst1 = dlanhs(
'1', i-l+1, h( l, l ), ldh, work )
281 IF( abs( h( k, k-1 ) ).LE.max( ulp*tst1, smlnum ) )
302 IF( .NOT.wantt )
THEN
307 IF( its.EQ.20 .OR. its.EQ.30 )
THEN
311 DO 80 ii = i - ns + 1, i
312 wr( ii ) = const*( abs( h( ii, ii-1 ) )+
313 $ abs( h( ii, ii ) ) )
320 CALL dlacpy(
'Full', ns, ns, h( i-ns+1, i-ns+1 ), ldh, s,
322 CALL dlahqr( .false., .false., ns, 1, ns, s, lds,
323 $ wr( i-ns+1 ), wi( i-ns+1 ), 1, ns, z, ldz,
331 wr( i-ns+ii ) = s( ii, ii )
343 DO 100 ii = 2, ns + 1
347 DO 120 j = i - ns + 1, i
348 IF( wi( j ).GE.zero )
THEN
349 IF( wi( j ).EQ.zero )
THEN
353 CALL dcopy( nv+1, v, 1, vv, 1 )
354 CALL dgemv(
'No transpose', nv+1, nv, one, h( l, l ),
355 $ ldh, vv, 1, -wr( j ), v, 1 )
357 ELSE IF( wi( j ).GT.zero )
THEN
361 CALL dcopy( nv+1, v, 1, vv, 1 )
362 CALL dgemv(
'No transpose', nv+1, nv, one, h( l, l ),
363 $ ldh, v, 1, -two*wr( j ), vv, 1 )
364 itemp = idamax( nv+1, vv, 1 )
365 temp = one / max( abs( vv( itemp ) ), smlnum )
366 CALL dscal( nv+1, temp, vv, 1 )
367 absw = dlapy2( wr( j ), wi( j ) )
368 temp = ( temp*absw )*absw
369 CALL dgemv(
'No transpose', nv+2, nv+1, one,
370 $ h( l, l ), ldh, vv, 1, temp, v, 1 )
377 itemp = idamax( nv, v, 1 )
378 temp = abs( v( itemp ) )
379 IF( temp.EQ.zero )
THEN
385 temp = max( temp, smlnum )
386 CALL dscal( nv, one / temp, v, 1 )
404 nr = min( ns+1, i-k+1 )
406 $
CALL dcopy( nr, h( k, k-1 ), 1, v, 1 )
407 CALL dlarfg( nr, v( 1 ), v( 2 ), 1, tau )
419 CALL dlarfx(
'Left', nr, i2-k+1, v, tau, h( k, k ), ldh,
425 CALL dlarfx(
'Right', min( k+nr, i )-i1+1, nr, v, tau,
426 $ h( i1, k ), ldh, work )
432 CALL dlarfx(
'Right', nh, nr, v, tau, z( ilo, k ), ldz,
449 CALL dlahqr( wantt, wantz, n, l, i, h, ldh, wr, wi, ilo, ihi, z,
462 work( 1 ) = max( 1, n )
subroutine dcopy(n, dx, incx, dy, incy)
subroutine dgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
subroutine dhseqr(JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z, LDZ, WORK, LWORK, INFO)
subroutine dlabad(SMALL, LARGE)
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
subroutine dlahqr(WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILOZ, IHIZ, Z, LDZ, INFO)
subroutine dlarfg(N, ALPHA, X, INCX, TAU)
subroutine dlarfx(SIDE, M, N, V, TAU, C, LDC, WORK)
subroutine dlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
subroutine dscal(n, da, dx, incx)
subroutine xerbla(SRNAME, INFO)