SUBROUTINE DLAEIN( RIGHTV, NOINIT, N, H, LDH, WR, WI, VR, VI, B,
$ LDB, WORK, EPS3, SMLNUM, BIGNUM, INFO )
LOGICAL NOINIT, RIGHTV
INTEGER INFO, LDB, LDH, N
DOUBLE PRECISION BIGNUM, EPS3, SMLNUM, WI, WR
DOUBLE PRECISION B( LDB, * ), H( LDH, * ), VI( * ), VR( * ),
$ WORK( * )
DOUBLE PRECISION ZERO, ONE, TENTH
PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TENTH = 1.0D-1 )
CHARACTER NORMIN, TRANS
INTEGER I, I1, I2, I3, IERR, ITS, J
DOUBLE PRECISION ABSBII, ABSBJJ, EI, EJ, GROWTO, NORM, NRMSML,
$ REC, ROOTN, SCALE, TEMP, VCRIT, VMAX, VNORM, W,
$ W1, X, XI, XR, Y
INTEGER IDAMAX
DOUBLE PRECISION DASUM, DLAPY2, DNRM2
EXTERNAL IDAMAX, DASUM, DLAPY2, DNRM2
EXTERNAL DLADIV, DLATRS, DSCAL
INTRINSIC ABS, DBLE, MAX, SQRT
INFO = 0
ROOTN = SQRT( DBLE( N ) )
GROWTO = TENTH / ROOTN
NRMSML = MAX( ONE, EPS3*ROOTN )*SMLNUM
DO 20 J = 1, N
DO 10 I = 1, J - 1
B( I, J ) = H( I, J )
10 CONTINUE
B( J, J ) = H( J, J ) - WR
20 CONTINUE
IF( WI.EQ.ZERO ) THEN
IF( NOINIT ) THEN
DO 30 I = 1, N
VR( I ) = EPS3
30 CONTINUE
ELSE
VNORM = DNRM2( N, VR, 1 )
CALL DSCAL( N, ( EPS3*ROOTN ) / MAX( VNORM, NRMSML ), VR,
$ 1 )
END IF
IF( RIGHTV ) THEN
DO 60 I = 1, N - 1
EI = H( I+1, I )
IF( ABS( B( I, I ) ).LT.ABS( EI ) ) THEN
X = B( I, I ) / EI
B( I, I ) = EI
DO 40 J = I + 1, N
TEMP = B( I+1, J )
B( I+1, J ) = B( I, J ) - X*TEMP
B( I, J ) = TEMP
40 CONTINUE
ELSE
IF( B( I, I ).EQ.ZERO )
$ B( I, I ) = EPS3
X = EI / B( I, I )
IF( X.NE.ZERO ) THEN
DO 50 J = I + 1, N
B( I+1, J ) = B( I+1, J ) - X*B( I, J )
50 CONTINUE
END IF
END IF
60 CONTINUE
IF( B( N, N ).EQ.ZERO )
$ B( N, N ) = EPS3
TRANS = 'N'
ELSE
DO 90 J = N, 2, -1
EJ = H( J, J-1 )
IF( ABS( B( J, J ) ).LT.ABS( EJ ) ) THEN
X = B( J, J ) / EJ
B( J, J ) = EJ
DO 70 I = 1, J - 1
TEMP = B( I, J-1 )
B( I, J-1 ) = B( I, J ) - X*TEMP
B( I, J ) = TEMP
70 CONTINUE
ELSE
IF( B( J, J ).EQ.ZERO )
$ B( J, J ) = EPS3
X = EJ / B( J, J )
IF( X.NE.ZERO ) THEN
DO 80 I = 1, J - 1
B( I, J-1 ) = B( I, J-1 ) - X*B( I, J )
80 CONTINUE
END IF
END IF
90 CONTINUE
IF( B( 1, 1 ).EQ.ZERO )
$ B( 1, 1 ) = EPS3
TRANS = 'T'
END IF
NORMIN = 'N'
DO 110 ITS = 1, N
CALL DLATRS( 'Upper', TRANS, 'Nonunit', NORMIN, N, B, LDB,
$ VR, SCALE, WORK, IERR )
NORMIN = 'Y'
VNORM = DASUM( N, VR, 1 )
IF( VNORM.GE.GROWTO*SCALE )
$ GO TO 120
TEMP = EPS3 / ( ROOTN+ONE )
VR( 1 ) = EPS3
DO 100 I = 2, N
VR( I ) = TEMP
100 CONTINUE
VR( N-ITS+1 ) = VR( N-ITS+1 ) - EPS3*ROOTN
110 CONTINUE
INFO = 1
120 CONTINUE
I = IDAMAX( N, VR, 1 )
CALL DSCAL( N, ONE / ABS( VR( I ) ), VR, 1 )
ELSE
IF( NOINIT ) THEN
DO 130 I = 1, N
VR( I ) = EPS3
VI( I ) = ZERO
130 CONTINUE
ELSE
NORM = DLAPY2( DNRM2( N, VR, 1 ), DNRM2( N, VI, 1 ) )
REC = ( EPS3*ROOTN ) / MAX( NORM, NRMSML )
CALL DSCAL( N, REC, VR, 1 )
CALL DSCAL( N, REC, VI, 1 )
END IF
IF( RIGHTV ) THEN
B( 2, 1 ) = -WI
DO 140 I = 2, N
B( I+1, 1 ) = ZERO
140 CONTINUE
DO 170 I = 1, N - 1
ABSBII = DLAPY2( B( I, I ), B( I+1, I ) )
EI = H( I+1, I )
IF( ABSBII.LT.ABS( EI ) ) THEN
XR = B( I, I ) / EI
XI = B( I+1, I ) / EI
B( I, I ) = EI
B( I+1, I ) = ZERO
DO 150 J = I + 1, N
TEMP = B( I+1, J )
B( I+1, J ) = B( I, J ) - XR*TEMP
B( J+1, I+1 ) = B( J+1, I ) - XI*TEMP
B( I, J ) = TEMP
B( J+1, I ) = ZERO
150 CONTINUE
B( I+2, I ) = -WI
B( I+1, I+1 ) = B( I+1, I+1 ) - XI*WI
B( I+2, I+1 ) = B( I+2, I+1 ) + XR*WI
ELSE
IF( ABSBII.EQ.ZERO ) THEN
B( I, I ) = EPS3
B( I+1, I ) = ZERO
ABSBII = EPS3
END IF
EI = ( EI / ABSBII ) / ABSBII
XR = B( I, I )*EI
XI = -B( I+1, I )*EI
DO 160 J = I + 1, N
B( I+1, J ) = B( I+1, J ) - XR*B( I, J ) +
$ XI*B( J+1, I )
B( J+1, I+1 ) = -XR*B( J+1, I ) - XI*B( I, J )
160 CONTINUE
B( I+2, I+1 ) = B( I+2, I+1 ) - WI
END IF
WORK( I ) = DASUM( N-I, B( I, I+1 ), LDB ) +
$ DASUM( N-I, B( I+2, I ), 1 )
170 CONTINUE
IF( B( N, N ).EQ.ZERO .AND. B( N+1, N ).EQ.ZERO )
$ B( N, N ) = EPS3
WORK( N ) = ZERO
I1 = N
I2 = 1
I3 = -1
ELSE
B( N+1, N ) = WI
DO 180 J = 1, N - 1
B( N+1, J ) = ZERO
180 CONTINUE
DO 210 J = N, 2, -1
EJ = H( J, J-1 )
ABSBJJ = DLAPY2( B( J, J ), B( J+1, J ) )
IF( ABSBJJ.LT.ABS( EJ ) ) THEN
XR = B( J, J ) / EJ
XI = B( J+1, J ) / EJ
B( J, J ) = EJ
B( J+1, J ) = ZERO
DO 190 I = 1, J - 1
TEMP = B( I, J-1 )
B( I, J-1 ) = B( I, J ) - XR*TEMP
B( J, I ) = B( J+1, I ) - XI*TEMP
B( I, J ) = TEMP
B( J+1, I ) = ZERO
190 CONTINUE
B( J+1, J-1 ) = WI
B( J-1, J-1 ) = B( J-1, J-1 ) + XI*WI
B( J, J-1 ) = B( J, J-1 ) - XR*WI
ELSE
IF( ABSBJJ.EQ.ZERO ) THEN
B( J, J ) = EPS3
B( J+1, J ) = ZERO
ABSBJJ = EPS3
END IF
EJ = ( EJ / ABSBJJ ) / ABSBJJ
XR = B( J, J )*EJ
XI = -B( J+1, J )*EJ
DO 200 I = 1, J - 1
B( I, J-1 ) = B( I, J-1 ) - XR*B( I, J ) +
$ XI*B( J+1, I )
B( J, I ) = -XR*B( J+1, I ) - XI*B( I, J )
200 CONTINUE
B( J, J-1 ) = B( J, J-1 ) + WI
END IF
WORK( J ) = DASUM( J-1, B( 1, J ), 1 ) +
$ DASUM( J-1, B( J+1, 1 ), LDB )
210 CONTINUE
IF( B( 1, 1 ).EQ.ZERO .AND. B( 2, 1 ).EQ.ZERO )
$ B( 1, 1 ) = EPS3
WORK( 1 ) = ZERO
I1 = 1
I2 = N
I3 = 1
END IF
DO 270 ITS = 1, N
SCALE = ONE
VMAX = ONE
VCRIT = BIGNUM
DO 250 I = I1, I2, I3
IF( WORK( I ).GT.VCRIT ) THEN
REC = ONE / VMAX
CALL DSCAL( N, REC, VR, 1 )
CALL DSCAL( N, REC, VI, 1 )
SCALE = SCALE*REC
VMAX = ONE
VCRIT = BIGNUM
END IF
XR = VR( I )
XI = VI( I )
IF( RIGHTV ) THEN
DO 220 J = I + 1, N
XR = XR - B( I, J )*VR( J ) + B( J+1, I )*VI( J )
XI = XI - B( I, J )*VI( J ) - B( J+1, I )*VR( J )
220 CONTINUE
ELSE
DO 230 J = 1, I - 1
XR = XR - B( J, I )*VR( J ) + B( I+1, J )*VI( J )
XI = XI - B( J, I )*VI( J ) - B( I+1, J )*VR( J )
230 CONTINUE
END IF
W = ABS( B( I, I ) ) + ABS( B( I+1, I ) )
IF( W.GT.SMLNUM ) THEN
IF( W.LT.ONE ) THEN
W1 = ABS( XR ) + ABS( XI )
IF( W1.GT.W*BIGNUM ) THEN
REC = ONE / W1
CALL DSCAL( N, REC, VR, 1 )
CALL DSCAL( N, REC, VI, 1 )
XR = VR( I )
XI = VI( I )
SCALE = SCALE*REC
VMAX = VMAX*REC
END IF
END IF
CALL DLADIV( XR, XI, B( I, I ), B( I+1, I ), VR( I ),
$ VI( I ) )
VMAX = MAX( ABS( VR( I ) )+ABS( VI( I ) ), VMAX )
VCRIT = BIGNUM / VMAX
ELSE
DO 240 J = 1, N
VR( J ) = ZERO
VI( J ) = ZERO
240 CONTINUE
VR( I ) = ONE
VI( I ) = ONE
SCALE = ZERO
VMAX = ONE
VCRIT = BIGNUM
END IF
250 CONTINUE
VNORM = DASUM( N, VR, 1 ) + DASUM( N, VI, 1 )
IF( VNORM.GE.GROWTO*SCALE )
$ GO TO 280
Y = EPS3 / ( ROOTN+ONE )
VR( 1 ) = EPS3
VI( 1 ) = ZERO
DO 260 I = 2, N
VR( I ) = Y
VI( I ) = ZERO
260 CONTINUE
VR( N-ITS+1 ) = VR( N-ITS+1 ) - EPS3*ROOTN
270 CONTINUE
INFO = 1
280 CONTINUE
VNORM = ZERO
DO 290 I = 1, N
VNORM = MAX( VNORM, ABS( VR( I ) )+ABS( VI( I ) ) )
290 CONTINUE
CALL DSCAL( N, ONE / VNORM, VR, 1 )
CALL DSCAL( N, ONE / VNORM, VI, 1 )
END IF
RETURN
END