📄 hqr2.c
字号:
/* eispack/hqr2.f -- translated by f2c (version 20050501).
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
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "v3p_netlib.h"
/* Table of constant values */
static doublereal c_b49 = 0.;
/*< subroutine hqr2(nm,n,low,igh,h,wr,wi,z,ierr) >*/
/* Subroutine */ int hqr2_(integer *nm, integer *n, integer *low, integer *
igh, doublereal *h__, doublereal *wr, doublereal *wi, doublereal *z__,
integer *ierr)
{
/* System generated locals */
integer h_dim1, h_offset, z_dim1, z_offset, i__1, i__2, i__3;
doublereal d__1, d__2, d__3, d__4;
/* Builtin functions */
double sqrt(doublereal), d_sign(doublereal *, doublereal *);
/* Local variables */
integer i__, j, k, l=0, m=0;
doublereal p, q, r__=0, s=0, t, w, x, y;
integer na, ii, en, jj;
doublereal ra, sa;
integer ll, mm, nn;
doublereal vi, vr, zz;
integer mp2, itn, its, enm2;
doublereal tst1, tst2;
extern /* Subroutine */ int cdiv_(doublereal *, doublereal *, doublereal *
, doublereal *, doublereal *, doublereal *);
doublereal norm;
logical notlas;
/*< >*/
/*< double precision h(nm,n),wr(n),wi(n),z(nm,n) >*/
/*< double precision p,q,r,s,t,w,x,y,ra,sa,vi,vr,zz,norm,tst1,tst2 >*/
/*< logical notlas >*/
/* this subroutine is a translation of the algol procedure hqr2, */
/* num. math. 16, 181-204(1970) by peters and wilkinson. */
/* handbook for auto. comp., vol.ii-linear algebra, 372-395(1971). */
/* this subroutine finds the eigenvalues and eigenvectors */
/* of a real upper hessenberg matrix by the qr method. the */
/* eigenvectors of a real general matrix can also be found */
/* if elmhes and eltran or orthes and ortran have */
/* been used to reduce this general matrix to hessenberg form */
/* and to accumulate the similarity transformations. */
/* on input */
/* nm must be set to the row dimension of two-dimensional */
/* array parameters as declared in the calling program */
/* dimension statement. */
/* n is the order of the matrix. */
/* low and igh are integers determined by the balancing */
/* subroutine balanc. if balanc has not been used, */
/* set low=1, igh=n. */
/* h contains the upper hessenberg matrix. */
/* z contains the transformation matrix produced by eltran */
/* after the reduction by elmhes, or by ortran after the */
/* reduction by orthes, if performed. if the eigenvectors */
/* of the hessenberg matrix are desired, z must contain the */
/* identity matrix. */
/* on output */
/* h has been destroyed. */
/* wr and wi contain the real and imaginary parts, */
/* respectively, of the eigenvalues. the eigenvalues */
/* are unordered except that complex conjugate pairs */
/* of values appear consecutively with the eigenvalue */
/* having the positive imaginary part first. if an */
/* error exit is made, the eigenvalues should be correct */
/* for indices ierr+1,...,n. */
/* z contains the real and imaginary parts of the eigenvectors. */
/* if the i-th eigenvalue is real, the i-th column of z */
/* contains its eigenvector. if the i-th eigenvalue is complex */
/* with positive imaginary part, the i-th and (i+1)-th */
/* columns of z contain the real and imaginary parts of its */
/* eigenvector. the eigenvectors are unnormalized. if an */
/* error exit is made, none of the eigenvectors has been found. */
/* ierr is set to */
/* zero for normal return, */
/* j if the limit of 30*n iterations is exhausted */
/* while the j-th eigenvalue is being sought. */
/* calls cdiv for complex division. */
/* questions and comments should be directed to burton s. garbow, */
/* mathematics and computer science div, argonne national laboratory */
/* this version dated august 1983. */
/* ------------------------------------------------------------------ */
/*< ierr = 0 >*/
/* Parameter adjustments */
z_dim1 = *nm;
z_offset = 1 + z_dim1;
z__ -= z_offset;
--wi;
--wr;
h_dim1 = *nm;
h_offset = 1 + h_dim1;
h__ -= h_offset;
/* Function Body */
*ierr = 0;
/*< norm = 0.0d0 >*/
norm = 0.;
/*< k = 1 >*/
k = 1;
/* .......... store roots isolated by balanc */
/* and compute matrix norm .......... */
/*< do 50 i = 1, n >*/
i__1 = *n;
for (i__ = 1; i__ <= i__1; ++i__) {
/*< do 40 j = k, n >*/
i__2 = *n;
for (j = k; j <= i__2; ++j) {
/*< 40 norm = norm + dabs(h(i,j)) >*/
/* L40: */
norm += (d__1 = h__[i__ + j * h_dim1], abs(d__1));
}
/*< k = i >*/
k = i__;
/*< if (i .ge. low .and. i .le. igh) go to 50 >*/
if (i__ >= *low && i__ <= *igh) {
goto L50;
}
/*< wr(i) = h(i,i) >*/
wr[i__] = h__[i__ + i__ * h_dim1];
/*< wi(i) = 0.0d0 >*/
wi[i__] = 0.;
/*< 50 continue >*/
L50:
;
}
/*< en = igh >*/
en = *igh;
/*< t = 0.0d0 >*/
t = 0.;
/*< itn = 30*n >*/
itn = *n * 30;
/* .......... search for next eigenvalues .......... */
/*< 60 if (en .lt. low) go to 340 >*/
L60:
if (en < *low) {
goto L340;
}
/*< its = 0 >*/
its = 0;
/*< na = en - 1 >*/
na = en - 1;
/*< enm2 = na - 1 >*/
enm2 = na - 1;
/* .......... look for single small sub-diagonal element */
/* for l=en step -1 until low do -- .......... */
/*< 70 do 80 ll = low, en >*/
L70:
i__1 = en;
for (ll = *low; ll <= i__1; ++ll) {
/*< l = en + low - ll >*/
l = en + *low - ll;
/*< if (l .eq. low) go to 100 >*/
if (l == *low) {
goto L100;
}
/*< s = dabs(h(l-1,l-1)) + dabs(h(l,l)) >*/
s = (d__1 = h__[l - 1 + (l - 1) * h_dim1], abs(d__1)) + (d__2 = h__[l
+ l * h_dim1], abs(d__2));
/*< if (s .eq. 0.0d0) s = norm >*/
if (s == 0.) {
s = norm;
}
/*< tst1 = s >*/
tst1 = s;
/*< tst2 = tst1 + dabs(h(l,l-1)) >*/
tst2 = tst1 + (d__1 = h__[l + (l - 1) * h_dim1], abs(d__1));
/*< if (tst2 .eq. tst1) go to 100 >*/
if (tst2 == tst1) {
goto L100;
}
/*< 80 continue >*/
/* L80: */
}
/* .......... form shift .......... */
/*< 100 x = h(en,en) >*/
L100:
x = h__[en + en * h_dim1];
/*< if (l .eq. en) go to 270 >*/
if (l == en) {
goto L270;
}
/*< y = h(na,na) >*/
y = h__[na + na * h_dim1];
/*< w = h(en,na) * h(na,en) >*/
w = h__[en + na * h_dim1] * h__[na + en * h_dim1];
/*< if (l .eq. na) go to 280 >*/
if (l == na) {
goto L280;
}
/*< if (itn .eq. 0) go to 1000 >*/
if (itn == 0) {
goto L1000;
}
/*< if (its .ne. 10 .and. its .ne. 20) go to 130 >*/
if (its != 10 && its != 20) {
goto L130;
}
/* .......... form exceptional shift .......... */
/*< t = t + x >*/
t += x;
/*< do 120 i = low, en >*/
i__1 = en;
for (i__ = *low; i__ <= i__1; ++i__) {
/*< 120 h(i,i) = h(i,i) - x >*/
/* L120: */
h__[i__ + i__ * h_dim1] -= x;
}
/*< s = dabs(h(en,na)) + dabs(h(na,enm2)) >*/
s = (d__1 = h__[en + na * h_dim1], abs(d__1)) + (d__2 = h__[na + enm2 *
h_dim1], abs(d__2));
/*< x = 0.75d0 * s >*/
x = s * .75;
/*< y = x >*/
y = x;
/*< w = -0.4375d0 * s * s >*/
w = s * -.4375 * s;
/*< 130 its = its + 1 >*/
L130:
++its;
/*< itn = itn - 1 >*/
--itn;
/* .......... look for two consecutive small */
/* sub-diagonal elements. */
/* for m=en-2 step -1 until l do -- .......... */
/*< do 140 mm = l, enm2 >*/
i__1 = enm2;
for (mm = l; mm <= i__1; ++mm) {
/*< m = enm2 + l - mm >*/
m = enm2 + l - mm;
/*< zz = h(m,m) >*/
zz = h__[m + m * h_dim1];
/*< r = x - zz >*/
r__ = x - zz;
/*< s = y - zz >*/
s = y - zz;
/*< p = (r * s - w) / h(m+1,m) + h(m,m+1) >*/
p = (r__ * s - w) / h__[m + 1 + m * h_dim1] + h__[m + (m + 1) *
h_dim1];
/*< q = h(m+1,m+1) - zz - r - s >*/
q = h__[m + 1 + (m + 1) * h_dim1] - zz - r__ - s;
/*< r = h(m+2,m+1) >*/
r__ = h__[m + 2 + (m + 1) * h_dim1];
/*< s = dabs(p) + dabs(q) + dabs(r) >*/
s = abs(p) + abs(q) + abs(r__);
/*< p = p / s >*/
p /= s;
/*< q = q / s >*/
q /= s;
/*< r = r / s >*/
r__ /= s;
/*< if (m .eq. l) go to 150 >*/
if (m == l) {
goto L150;
}
/*< tst1 = dabs(p)*(dabs(h(m-1,m-1)) + dabs(zz) + dabs(h(m+1,m+1))) >*/
tst1 = abs(p) * ((d__1 = h__[m - 1 + (m - 1) * h_dim1], abs(d__1)) +
abs(zz) + (d__2 = h__[m + 1 + (m + 1) * h_dim1], abs(d__2)));
/*< tst2 = tst1 + dabs(h(m,m-1))*(dabs(q) + dabs(r)) >*/
tst2 = tst1 + (d__1 = h__[m + (m - 1) * h_dim1], abs(d__1)) * (abs(q)
+ abs(r__));
/*< if (tst2 .eq. tst1) go to 150 >*/
if (tst2 == tst1) {
goto L150;
}
/*< 140 continue >*/
/* L140: */
}
/*< 150 mp2 = m + 2 >*/
L150:
mp2 = m + 2;
/*< do 160 i = mp2, en >*/
i__1 = en;
for (i__ = mp2; i__ <= i__1; ++i__) {
/*< h(i,i-2) = 0.0d0 >*/
h__[i__ + (i__ - 2) * h_dim1] = 0.;
/*< if (i .eq. mp2) go to 160 >*/
if (i__ == mp2) {
goto L160;
}
/*< h(i,i-3) = 0.0d0 >*/
h__[i__ + (i__ - 3) * h_dim1] = 0.;
/*< 160 continue >*/
L160:
;
}
/* .......... double qr step involving rows l to en and */
/* columns m to en .......... */
/*< do 260 k = m, na >*/
i__1 = na;
for (k = m; k <= i__1; ++k) {
/*< notlas = k .ne. na >*/
notlas = k != na;
/*< if (k .eq. m) go to 170 >*/
if (k == m) {
goto L170;
}
/*< p = h(k,k-1) >*/
p = h__[k + (k - 1) * h_dim1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -