📄 chsein.c
字号:
#include "blaswrap.h"
/* -- translated by f2c (version 19990503).
You must link the resulting object file with the libraries:
-lf2c -lm (in that order)
*/
#include "f2c.h"
/* Common Block Declarations */
struct {
real ops, itcnt;
} latime_;
#define latime_1 latime_
/* Table of constant values */
static logical c_false = FALSE_;
static logical c_true = TRUE_;
/* Subroutine */ int chsein_(char *side, char *eigsrc, char *initv, logical *
select, integer *n, complex *h__, integer *ldh, complex *w, complex *
vl, integer *ldvl, complex *vr, integer *ldvr, integer *mm, integer *
m, complex *work, real *rwork, integer *ifaill, integer *ifailr,
integer *info)
{
/* System generated locals */
integer h_dim1, h_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1,
i__2, i__3;
real r__1, r__2;
complex q__1, q__2;
/* Builtin functions */
double r_imag(complex *);
/* Local variables */
static real unfl, opst;
static integer i__, k;
extern logical lsame_(char *, char *);
static integer iinfo;
static logical leftv, bothv;
static real hnorm;
static integer kl;
extern /* Subroutine */ int claein_(logical *, logical *, integer *,
complex *, integer *, complex *, complex *, complex *, integer *,
real *, real *, real *, integer *);
static integer kr, ks;
static complex wk;
extern doublereal slamch_(char *), clanhs_(char *, integer *,
complex *, integer *, real *);
extern /* Subroutine */ int xerbla_(char *, integer *);
static logical noinit;
static integer ldwork;
static logical rightv, fromqr;
static real smlnum;
static integer kln;
static real ulp, eps3;
#define h___subscr(a_1,a_2) (a_2)*h_dim1 + a_1
#define h___ref(a_1,a_2) h__[h___subscr(a_1,a_2)]
#define vl_subscr(a_1,a_2) (a_2)*vl_dim1 + a_1
#define vl_ref(a_1,a_2) vl[vl_subscr(a_1,a_2)]
#define vr_subscr(a_1,a_2) (a_2)*vr_dim1 + a_1
#define vr_ref(a_1,a_2) vr[vr_subscr(a_1,a_2)]
/* -- LAPACK routine (instrumented to count operations, version 3.0) --
Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
Courant Institute, Argonne National Lab, and Rice University
September 30, 1994
Common block to return operation count.
Purpose
=======
CHSEIN uses inverse iteration to find specified right and/or left
eigenvectors of a complex upper Hessenberg matrix H.
The right eigenvector x and the left eigenvector y of the matrix H
corresponding to an eigenvalue w are defined by:
H * x = w * x, y**h * H = w * y**h
where y**h denotes the conjugate transpose of the vector y.
Arguments
=========
SIDE (input) CHARACTER*1
= 'R': compute right eigenvectors only;
= 'L': compute left eigenvectors only;
= 'B': compute both right and left eigenvectors.
EIGSRC (input) CHARACTER*1
Specifies the source of eigenvalues supplied in W:
= 'Q': the eigenvalues were found using CHSEQR; thus, if
H has zero subdiagonal elements, and so is
block-triangular, then the j-th eigenvalue can be
assumed to be an eigenvalue of the block containing
the j-th row/column. This property allows CHSEIN to
perform inverse iteration on just one diagonal block.
= 'N': no assumptions are made on the correspondence
between eigenvalues and diagonal blocks. In this
case, CHSEIN must always perform inverse iteration
using the whole matrix H.
INITV (input) CHARACTER*1
= 'N': no initial vectors are supplied;
= 'U': user-supplied initial vectors are stored in the arrays
VL and/or VR.
SELECT (input) LOGICAL array, dimension (N)
Specifies the eigenvectors to be computed. To select the
eigenvector corresponding to the eigenvalue W(j),
SELECT(j) must be set to .TRUE..
N (input) INTEGER
The order of the matrix H. N >= 0.
H (input) COMPLEX array, dimension (LDH,N)
The upper Hessenberg matrix H.
LDH (input) INTEGER
The leading dimension of the array H. LDH >= max(1,N).
W (input/output) COMPLEX array, dimension (N)
On entry, the eigenvalues of H.
On exit, the real parts of W may have been altered since
close eigenvalues are perturbed slightly in searching for
independent eigenvectors.
VL (input/output) COMPLEX array, dimension (LDVL,MM)
On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must
contain starting vectors for the inverse iteration for the
left eigenvectors; the starting vector for each eigenvector
must be in the same column in which the eigenvector will be
stored.
On exit, if SIDE = 'L' or 'B', the left eigenvectors
specified by SELECT will be stored consecutively in the
columns of VL, in the same order as their eigenvalues.
If SIDE = 'R', VL is not referenced.
LDVL (input) INTEGER
The leading dimension of the array VL.
LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise.
VR (input/output) COMPLEX array, dimension (LDVR,MM)
On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must
contain starting vectors for the inverse iteration for the
right eigenvectors; the starting vector for each eigenvector
must be in the same column in which the eigenvector will be
stored.
On exit, if SIDE = 'R' or 'B', the right eigenvectors
specified by SELECT will be stored consecutively in the
columns of VR, in the same order as their eigenvalues.
If SIDE = 'L', VR is not referenced.
LDVR (input) INTEGER
The leading dimension of the array VR.
LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise.
MM (input) INTEGER
The number of columns in the arrays VL and/or VR. MM >= M.
M (output) INTEGER
The number of columns in the arrays VL and/or VR required to
store the eigenvectors (= the number of .TRUE. elements in
SELECT).
WORK (workspace) COMPLEX array, dimension (N*N)
RWORK (workspace) REAL array, dimension (N)
IFAILL (output) INTEGER array, dimension (MM)
If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left
eigenvector in the i-th column of VL (corresponding to the
eigenvalue w(j)) failed to converge; IFAILL(i) = 0 if the
eigenvector converged satisfactorily.
If SIDE = 'R', IFAILL is not referenced.
IFAILR (output) INTEGER array, dimension (MM)
If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right
eigenvector in the i-th column of VR (corresponding to the
eigenvalue w(j)) failed to converge; IFAILR(i) = 0 if the
eigenvector converged satisfactorily.
If SIDE = 'L', IFAILR is not referenced.
INFO (output) INTEGER
= 0: successful exit
< 0: if INFO = -i, the i-th argument had an illegal value
> 0: if INFO = i, i is the number of eigenvectors which
failed to converge; see IFAILL and IFAILR for further
details.
Further Details
===============
Each eigenvector is normalized so that the element of largest
magnitude has magnitude 1; here the magnitude of a complex number
(x,y) is taken to be |x|+|y|.
=====================================================================
Decode and test the input parameters.
Parameter adjustments */
--select;
h_dim1 = *ldh;
h_offset = 1 + h_dim1 * 1;
h__ -= h_offset;
--w;
vl_dim1 = *ldvl;
vl_offset = 1 + vl_dim1 * 1;
vl -= vl_offset;
vr_dim1 = *ldvr;
vr_offset = 1 + vr_dim1 * 1;
vr -= vr_offset;
--work;
--rwork;
--ifaill;
--ifailr;
/* Function Body */
bothv = lsame_(side, "B");
rightv = lsame_(side, "R") || bothv;
leftv = lsame_(side, "L") || bothv;
fromqr = lsame_(eigsrc, "Q");
noinit = lsame_(initv, "N");
/* Set M to the number of columns required to store the selected
eigenvectors. */
*m = 0;
i__1 = *n;
for (k = 1; k <= i__1; ++k) {
if (select[k]) {
++(*m);
}
/* L10: */
}
*info = 0;
if (! rightv && ! leftv) {
*info = -1;
} else if (! fromqr && ! lsame_(eigsrc, "N")) {
*info = -2;
} else if (! noinit && ! lsame_(initv, "U")) {
*info = -3;
} else if (*n < 0) {
*info = -5;
} else if (*ldh < max(1,*n)) {
*info = -7;
} else if (*ldvl < 1 || leftv && *ldvl < *n) {
*info = -10;
} else if (*ldvr < 1 || rightv && *ldvr < *n) {
*info = -12;
} else if (*mm < *m) {
*info = -13;
}
if (*info != 0) {
i__1 = -(*info);
xerbla_("CHSEIN", &i__1);
return 0;
}
/* **
Initialize */
opst = 0.f;
/* **
Quick return if possible. */
if (*n == 0) {
return 0;
}
/* Set machine-dependent constants. */
unfl = slamch_("Safe minimum");
ulp = slamch_("Precision");
smlnum = unfl * (*n / ulp);
ldwork = *n;
kl = 1;
kln = 0;
if (fromqr) {
kr = 0;
} else {
kr = *n;
}
ks = 1;
i__1 = *n;
for (k = 1; k <= i__1; ++k) {
if (select[k]) {
/* Compute eigenvector(s) corresponding to W(K). */
if (fromqr) {
/* If affiliation of eigenvalues is known, check whether
the matrix splits.
Determine KL and KR such that 1 <= KL <= K <= KR <= N
and H(KL,KL-1) and H(KR+1,KR) are zero (or KL = 1 or
KR = N).
Then inverse iteration can be performed with the
submatrix H(KL:N,KL:N) for a left eigenvector, and with
the submatrix H(1:KR,1:KR) for a right eigenvector. */
i__2 = kl + 1;
for (i__ = k; i__ >= i__2; --i__) {
i__3 = h___subscr(i__, i__ - 1);
if (h__[i__3].r == 0.f && h__[i__3].i == 0.f) {
goto L30;
}
/* L20: */
}
L30:
kl = i__;
if (k > kr) {
i__2 = *n - 1;
for (i__ = k; i__ <= i__2; ++i__) {
i__3 = h___subscr(i__ + 1, i__);
if (h__[i__3].r == 0.f && h__[i__3].i == 0.f) {
goto L50;
}
/* L40: */
}
L50:
kr = i__;
}
}
if (kl != kln) {
kln = kl;
/* Compute infinity-norm of submatrix H(KL:KR,KL:KR) if it
has not ben computed before. */
i__2 = kr - kl + 1;
hnorm = clanhs_("I", &i__2, &h___ref(kl, kl), ldh, &rwork[1]);
/* **
Increment op count for computing the norm of the matrix */
latime_1.ops = latime_1.ops + *n * 5 * (*n + 1) / 2 + (*n - 1
<< 2);
/* ** */
if (hnorm > 0.f) {
eps3 = hnorm * ulp;
} else {
eps3 = smlnum;
}
}
/* Perturb eigenvalue if it is close to any previous
selected eigenvalues affiliated to the submatrix
H(KL:KR,KL:KR). Close roots are modified by EPS3. */
i__2 = k;
wk.r = w[i__2].r, wk.i = w[i__2].i;
L60:
i__2 = kl;
for (i__ = k - 1; i__ >= i__2; --i__) {
i__3 = i__;
q__2.r = w[i__3].r - wk.r, q__2.i = w[i__3].i - wk.i;
q__1.r = q__2.r, q__1.i = q__2.i;
if (select[i__] && (r__1 = q__1.r, dabs(r__1)) + (r__2 =
r_imag(&q__1), dabs(r__2)) < eps3) {
q__1.r = wk.r + eps3, q__1.i = wk.i;
wk.r = q__1.r, wk.i = q__1.i;
goto L60;
}
/* L70: */
}
i__2 = k;
w[i__2].r = wk.r, w[i__2].i = wk.i;
/* **
Increment opcount for loop 70 */
opst += k - 1 << 1;
/* ** */
if (leftv) {
/* Compute left eigenvector. */
i__2 = *n - kl + 1;
claein_(&c_false, &noinit, &i__2, &h___ref(kl, kl), ldh, &wk,
&vl_ref(kl, ks), &work[1], &ldwork, &rwork[1], &eps3,
&smlnum, &iinfo);
if (iinfo > 0) {
++(*info);
ifaill[ks] = k;
} else {
ifaill[ks] = 0;
}
i__2 = kl - 1;
for (i__ = 1; i__ <= i__2; ++i__) {
i__3 = vl_subscr(i__, ks);
vl[i__3].r = 0.f, vl[i__3].i = 0.f;
/* L80: */
}
}
if (rightv) {
/* Compute right eigenvector. */
claein_(&c_true, &noinit, &kr, &h__[h_offset], ldh, &wk, &
vr_ref(1, ks), &work[1], &ldwork, &rwork[1], &eps3, &
smlnum, &iinfo);
if (iinfo > 0) {
++(*info);
ifailr[ks] = k;
} else {
ifailr[ks] = 0;
}
i__2 = *n;
for (i__ = kr + 1; i__ <= i__2; ++i__) {
i__3 = vr_subscr(i__, ks);
vr[i__3].r = 0.f, vr[i__3].i = 0.f;
/* L90: */
}
}
++ks;
}
/* L100: */
}
/* **
Compute final op count */
latime_1.ops += opst;
/* ** */
return 0;
/* End of CHSEIN */
} /* chsein_ */
#undef vr_ref
#undef vr_subscr
#undef vl_ref
#undef vl_subscr
#undef h___ref
#undef h___subscr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -