/* ../netlib/zlaein.f -- translated by f2c (version 20100827). You must link the resulting object file with libf2c: on Microsoft Windows system, link with libf2c.lib;
on Linux or Unix systems, link with .../path/to/libf2c.a -lm or, if you install libf2c.a in a standard place, with -lf2c -lm -- in that order, at the end of the command line, as in cc *.o -lf2c -lm Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., http://www.netlib.org/f2c/libf2c.zip */
#include "FLA_f2c.h" /* Table of constant values */
static integer c__1 = 1;
/* > \brief \b ZLAEIN computes a specified right or left eigenvector of an upper Hessenberg matrix by inverse iteration. */
/* =========== DOCUMENTATION =========== */
/* Online html documentation available at */
/* http://www.netlib.org/lapack/explore-html/ */
/* > \htmlonly */
/* > Download ZLAEIN + dependencies */
/* > */
/* > [TGZ] */
/* > */
/* > [ZIP] */
/* > */
/* > [TXT] */
/* > \endhtmlonly */
/* Definition: */
/* =========== */
/* SUBROUTINE ZLAEIN( RIGHTV, NOINIT, N, H, LDH, W, V, B, LDB, RWORK, */
/* EPS3, SMLNUM, INFO ) */
/* .. Scalar Arguments .. */
/* LOGICAL NOINIT, RIGHTV */
/* INTEGER INFO, LDB, LDH, N */
/* DOUBLE PRECISION EPS3, SMLNUM */
/* COMPLEX*16 W */
/* .. */
/* .. Array Arguments .. */
/* DOUBLE PRECISION RWORK( * ) */
/* COMPLEX*16 B( LDB, * ), H( LDH, * ), V( * ) */
/* .. */
/* > \par Purpose: */
/* ============= */
/* > */
/* > \verbatim */
/* > */
/* > ZLAEIN uses inverse iteration to find a right or left eigenvector */
/* > corresponding to the eigenvalue W of a complex upper Hessenberg */
/* > matrix H. */
/* > \endverbatim */
/* Arguments: */
/* ========== */
/* > \param[in] RIGHTV */
/* > \verbatim */
/* > RIGHTV is LOGICAL */
/* > = .TRUE. : compute right eigenvector;
*/
/* > = .FALSE.: compute left eigenvector. */
/* > \endverbatim */
/* > */
/* > \param[in] NOINIT */
/* > \verbatim */
/* > NOINIT is LOGICAL */
/* > = .TRUE. : no initial vector supplied in V */
/* > = .FALSE.: initial vector supplied in V. */
/* > \endverbatim */
/* > */
/* > \param[in] N */
/* > \verbatim */
/* > N is INTEGER */
/* > The order of the matrix H. N >= 0. */
/* > \endverbatim */
/* > */
/* > \param[in] H */
/* > \verbatim */
/* > H is COMPLEX*16 array, dimension (LDH,N) */
/* > The upper Hessenberg matrix H. */
/* > \endverbatim */
/* > */
/* > \param[in] LDH */
/* > \verbatim */
/* > LDH is INTEGER */
/* > The leading dimension of the array H. LDH >= max(1,N). */
/* > \endverbatim */
/* > */
/* > \param[in] W */
/* > \verbatim */
/* > W is COMPLEX*16 */
/* > The eigenvalue of H whose corresponding right or left */
/* > eigenvector is to be computed. */
/* > \endverbatim */
/* > */
/* > \param[in,out] V */
/* > \verbatim */
/* > V is COMPLEX*16 array, dimension (N) */
/* > On entry, if NOINIT = .FALSE., V must contain a starting */
/* > vector for inverse iteration;
otherwise V need not be set. */
/* > On exit, V contains the computed eigenvector, normalized so */
/* > that the component of largest magnitude has magnitude 1;
here */
/* > the magnitude of a complex number (x,y) is taken to be */
/* > |x| + |y|. */
/* > \endverbatim */
/* > */
/* > \param[out] B */
/* > \verbatim */
/* > B is COMPLEX*16 array, dimension (LDB,N) */
/* > \endverbatim */
/* > */
/* > \param[in] LDB */
/* > \verbatim */
/* > LDB is INTEGER */
/* > The leading dimension of the array B. LDB >= max(1,N). */
/* > \endverbatim */
/* > */
/* > \param[out] RWORK */
/* > \verbatim */
/* > RWORK is DOUBLE PRECISION array, dimension (N) */
/* > \endverbatim */
/* > */
/* > \param[in] EPS3 */
/* > \verbatim */
/* > EPS3 is DOUBLE PRECISION */
/* > A small machine-dependent value which is used to perturb */
/* > close eigenvalues, and to replace zero pivots. */
/* > \endverbatim */
/* > */
/* > \param[in] SMLNUM */
/* > \verbatim */
/* > SMLNUM is DOUBLE PRECISION */
/* > A machine-dependent value close to the underflow threshold. */
/* > \endverbatim */
/* > */
/* > \param[out] INFO */
/* > \verbatim */
/* > INFO is INTEGER */
/* > = 0: successful exit */
/* > = 1: inverse iteration did not converge;
V is set to the */
/* > last iterate. */
/* > \endverbatim */
/* Authors: */
/* ======== */
/* > \author Univ. of Tennessee */
/* > \author Univ. of California Berkeley */
/* > \author Univ. of Colorado Denver */
/* > \author NAG Ltd. */
/* > \date September 2012 */
/* > \ingroup complex16OTHERauxiliary */
/* ===================================================================== */
/* Subroutine */
int zlaein_(logical *rightv, logical *noinit, integer *n, doublecomplex *h__, integer *ldh, doublecomplex *w, doublecomplex *v, doublecomplex *b, integer *ldb, doublereal *rwork, doublereal *eps3, doublereal *smlnum, integer *info)
{
/* System generated locals */
integer b_dim1, b_offset, h_dim1, h_offset, i__1, i__2, i__3, i__4, i__5;
doublereal d__1, d__2, d__3, d__4;
doublecomplex z__1, z__2;
/* Builtin functions */
double sqrt(doublereal), d_imag(doublecomplex *);
/* Local variables */
integer i__, j;
doublecomplex x, ei, ej;
integer its, ierr;
doublecomplex temp;
doublereal scale;
char trans[1];
doublereal rtemp, rootn, vnorm;
extern doublereal dznrm2_(integer *, doublecomplex *, integer *);
extern /* Subroutine */
int zdscal_(integer *, doublereal *, doublecomplex *, integer *);
extern integer izamax_(integer *, doublecomplex *, integer *);
extern /* Double Complex */
VOID zladiv_(doublecomplex *, doublecomplex *, doublecomplex *);
char normin[1];
extern doublereal dzasum_(integer *, doublecomplex *, integer *);
doublereal nrmsml;
extern /* Subroutine */
int zlatrs_(char *, char *, char *, char *, integer *, doublecomplex *, integer *, doublecomplex *, doublereal *, doublereal *, integer *);
doublereal growto;
/* -- LAPACK auxiliary routine (version 3.4.2) -- */
/* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
/* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
/* September 2012 */
/* .. Scalar Arguments .. */
/* .. */
/* .. Array Arguments .. */
/* .. */
/* ===================================================================== */
/* .. Parameters .. */
/* .. */
/* .. Local Scalars .. */
/* .. */
/* .. External Functions .. */
/* .. */
/* .. External Subroutines .. */
/* .. */
/* .. Intrinsic Functions .. */
/* .. */
/* .. Statement Functions .. */
/* .. */
/* .. Statement Function definitions .. */
/* .. */
/* .. Executable Statements .. */
/* Parameter adjustments */
h_dim1 = *ldh;
h_offset = 1 + h_dim1;
h__ -= h_offset;
--v;
b_dim1 = *ldb;
b_offset = 1 + b_dim1;
b -= b_offset;
--rwork;
/* Function Body */
*info = 0;
/* GROWTO is the threshold used in the acceptance test for an */
/* eigenvector. */
rootn = sqrt((doublereal) (*n));
growto = .1 / rootn;
/* Computing MAX */
d__1 = 1.;
d__2 = *eps3 * rootn; // , expr subst
nrmsml = max(d__1,d__2) * *smlnum;
/* Form B = H - W*I (except that the subdiagonal elements are not */
/* stored). */
i__1 = *n;
for (j = 1;
j <= i__1;
++j)
{
i__2 = j - 1;
for (i__ = 1;
i__ <= i__2;
++i__)
{
i__3 = i__ + j * b_dim1;
i__4 = i__ + j * h_dim1;
b[i__3].r = h__[i__4].r;
b[i__3].i = h__[i__4].i; // , expr subst
/* L10: */
}
i__2 = j + j * b_dim1;
i__3 = j + j * h_dim1;
z__1.r = h__[i__3].r - w->r;
z__1.i = h__[i__3].i - w->i; // , expr subst
b[i__2].r = z__1.r;
b[i__2].i = z__1.i; // , expr subst
/* L20: */
}
if (*noinit)
{
/* Initialize V. */
i__1 = *n;
for (i__ = 1;
i__ <= i__1;
++i__)
{
i__2 = i__;
v[i__2].r = *eps3;
v[i__2].i = 0.; // , expr subst
/* L30: */
}
}
else
{
/* Scale supplied initial vector. */
vnorm = dznrm2_(n, &v[1], &c__1);
d__1 = *eps3 * rootn / max(vnorm,nrmsml);
zdscal_(n, &d__1, &v[1], &c__1);
}
if (*rightv)
{
/* LU decomposition with partial pivoting of B, replacing zero */
/* pivots by EPS3. */
i__1 = *n - 1;
for (i__ = 1;
i__ <= i__1;
++i__)
{
i__2 = i__ + 1 + i__ * h_dim1;
ei.r = h__[i__2].r;
ei.i = h__[i__2].i; // , expr subst
i__2 = i__ + i__ * b_dim1;
if ((d__1 = b[i__2].r, f2c_abs(d__1)) + (d__2 = d_imag(&b[i__ + i__ * b_dim1]), f2c_abs(d__2)) < (d__3 = ei.r, f2c_abs(d__3)) + (d__4 = d_imag(&ei), f2c_abs(d__4)))
{
/* Interchange rows and eliminate. */
zladiv_(&z__1, &b[i__ + i__ * b_dim1], &ei);
x.r = z__1.r;
x.i = z__1.i; // , expr subst
i__2 = i__ + i__ * b_dim1;
b[i__2].r = ei.r;
b[i__2].i = ei.i; // , expr subst
i__2 = *n;
for (j = i__ + 1;
j <= i__2;
++j)
{
i__3 = i__ + 1 + j * b_dim1;
temp.r = b[i__3].r;
temp.i = b[i__3].i; // , expr subst
i__3 = i__ + 1 + j * b_dim1;
i__4 = i__ + j * b_dim1;
z__2.r = x.r * temp.r - x.i * temp.i;
z__2.i = x.r * temp.i + x.i * temp.r; // , expr subst
z__1.r = b[i__4].r - z__2.r;
z__1.i = b[i__4].i - z__2.i; // , expr subst
b[i__3].r = z__1.r;
b[i__3].i = z__1.i; // , expr subst
i__3 = i__ + j * b_dim1;
b[i__3].r = temp.r;
b[i__3].i = temp.i; // , expr subst
/* L40: */
}
}
else
{
/* Eliminate without interchange. */
i__2 = i__ + i__ * b_dim1;
if (b[i__2].r == 0. && b[i__2].i == 0.)
{
i__3 = i__ + i__ * b_dim1;
b[i__3].r = *eps3;
b[i__3].i = 0.; // , expr subst
}
zladiv_(&z__1, &ei, &b[i__ + i__ * b_dim1]);
x.r = z__1.r;
x.i = z__1.i; // , expr subst
if (x.r != 0. || x.i != 0.)
{
i__2 = *n;
for (j = i__ + 1;
j <= i__2;
++j)
{
i__3 = i__ + 1 + j * b_dim1;
i__4 = i__ + 1 + j * b_dim1;
i__5 = i__ + j * b_dim1;
z__2.r = x.r * b[i__5].r - x.i * b[i__5].i;
z__2.i = x.r * b[i__5].i + x.i * b[i__5].r; // , expr subst
z__1.r = b[i__4].r - z__2.r;
z__1.i = b[i__4].i - z__2.i; // , expr subst
b[i__3].r = z__1.r;
b[i__3].i = z__1.i; // , expr subst
/* L50: */
}
}
}
/* L60: */
}
i__1 = *n + *n * b_dim1;
if (b[i__1].r == 0. && b[i__1].i == 0.)
{
i__2 = *n + *n * b_dim1;
b[i__2].r = *eps3;
b[i__2].i = 0.; // , expr subst
}
*(unsigned char *)trans = 'N';
}
else
{
/* UL decomposition with partial pivoting of B, replacing zero */
/* pivots by EPS3. */
for (j = *n;
j >= 2;
--j)
{
i__1 = j + (j - 1) * h_dim1;
ej.r = h__[i__1].r;
ej.i = h__[i__1].i; // , expr subst
i__1 = j + j * b_dim1;
if ((d__1 = b[i__1].r, f2c_abs(d__1)) + (d__2 = d_imag(&b[j + j * b_dim1]), f2c_abs(d__2)) < (d__3 = ej.r, f2c_abs(d__3)) + (d__4 = d_imag(&ej), f2c_abs(d__4)))
{
/* Interchange columns and eliminate. */
zladiv_(&z__1, &b[j + j * b_dim1], &ej);
x.r = z__1.r;
x.i = z__1.i; // , expr subst
i__1 = j + j * b_dim1;
b[i__1].r = ej.r;
b[i__1].i = ej.i; // , expr subst
i__1 = j - 1;
for (i__ = 1;
i__ <= i__1;
++i__)
{
i__2 = i__ + (j - 1) * b_dim1;
temp.r = b[i__2].r;
temp.i = b[i__2].i; // , expr subst
i__2 = i__ + (j - 1) * b_dim1;
i__3 = i__ + j * b_dim1;
z__2.r = x.r * temp.r - x.i * temp.i;
z__2.i = x.r * temp.i + x.i * temp.r; // , expr subst
z__1.r = b[i__3].r - z__2.r;
z__1.i = b[i__3].i - z__2.i; // , expr subst
b[i__2].r = z__1.r;
b[i__2].i = z__1.i; // , expr subst
i__2 = i__ + j * b_dim1;
b[i__2].r = temp.r;
b[i__2].i = temp.i; // , expr subst
/* L70: */
}
}
else
{
/* Eliminate without interchange. */
i__1 = j + j * b_dim1;
if (b[i__1].r == 0. && b[i__1].i == 0.)
{
i__2 = j + j * b_dim1;
b[i__2].r = *eps3;
b[i__2].i = 0.; // , expr subst
}
zladiv_(&z__1, &ej, &b[j + j * b_dim1]);
x.r = z__1.r;
x.i = z__1.i; // , expr subst
if (x.r != 0. || x.i != 0.)
{
i__1 = j - 1;
for (i__ = 1;
i__ <= i__1;
++i__)
{
i__2 = i__ + (j - 1) * b_dim1;
i__3 = i__ + (j - 1) * b_dim1;
i__4 = i__ + j * b_dim1;
z__2.r = x.r * b[i__4].r - x.i * b[i__4].i;
z__2.i = x.r * b[i__4].i + x.i * b[i__4].r; // , expr subst
z__1.r = b[i__3].r - z__2.r;
z__1.i = b[i__3].i - z__2.i; // , expr subst
b[i__2].r = z__1.r;
b[i__2].i = z__1.i; // , expr subst
/* L80: */
}
}
}
/* L90: */
}
i__1 = b_dim1 + 1;
if (b[i__1].r == 0. && b[i__1].i == 0.)
{
i__2 = b_dim1 + 1;
b[i__2].r = *eps3;
b[i__2].i = 0.; // , expr subst
}
*(unsigned char *)trans = 'C';
}
*(unsigned char *)normin = 'N';
i__1 = *n;
for (its = 1;
its <= i__1;
++its)
{
/* Solve U*x = scale*v for a right eigenvector */
/* or U**H *x = scale*v for a left eigenvector, */
/* overwriting x on v. */
zlatrs_("Upper", trans, "Nonunit", normin, n, &b[b_offset], ldb, &v[1] , &scale, &rwork[1], &ierr);
*(unsigned char *)normin = 'Y';
/* Test for sufficient growth in the norm of v. */
vnorm = dzasum_(n, &v[1], &c__1);
if (vnorm >= growto * scale)
{
goto L120;
}
/* Choose new orthogonal starting vector and try again. */
rtemp = *eps3 / (rootn + 1.);
v[1].r = *eps3;
v[1].i = 0.; // , expr subst
i__2 = *n;
for (i__ = 2;
i__ <= i__2;
++i__)
{
i__3 = i__;
v[i__3].r = rtemp;
v[i__3].i = 0.; // , expr subst
/* L100: */
}
i__2 = *n - its + 1;
i__3 = *n - its + 1;
d__1 = *eps3 * rootn;
z__1.r = v[i__3].r - d__1;
z__1.i = v[i__3].i; // , expr subst
v[i__2].r = z__1.r;
v[i__2].i = z__1.i; // , expr subst
/* L110: */
}
/* Failure to find eigenvector in N iterations. */
*info = 1;
L120: /* Normalize eigenvector. */
i__ = izamax_(n, &v[1], &c__1);
i__1 = i__;
d__3 = 1. / ((d__1 = v[i__1].r, f2c_abs(d__1)) + (d__2 = d_imag(&v[i__]), f2c_abs( d__2)));
zdscal_(n, &d__3, &v[1], &c__1);
return 0;
/* End of ZLAEIN */
}
/* zlaein_ */