📄 slasq4.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_
/* Subroutine */ int slasq4_(integer *i0, integer *n0, real *z__, integer *pp,
integer *n0in, real *dmin__, real *dmin1, real *dmin2, real *dn,
real *dn1, real *dn2, real *tau, integer *ttype)
{
/* Initialized data */
static real g = 0.f;
/* System generated locals */
integer i__1;
real r__1, r__2;
/* Builtin functions */
double sqrt(doublereal);
/* Local variables */
static real s, a2, b1, b2;
static integer i4, nn, np;
static real gam, gap1, gap2;
/* -- LAPACK auxiliary routine (instrumented to count ops, version 3.0) --
Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
Courant Institute, Argonne National Lab, and Rice University
May 17, 2000
Purpose
=======
SLASQ4 computes an approximation TAU to the smallest eigenvalue
using values of d from the previous transform.
I0 (input) INTEGER
First index.
N0 (input) INTEGER
Last index.
Z (input) REAL array, dimension ( 4*N )
Z holds the qd array.
PP (input) INTEGER
PP=0 for ping, PP=1 for pong.
NOIN (input) INTEGER
The value of N0 at start of EIGTEST.
DMIN (input) REAL
Minimum value of d.
DMIN1 (input) REAL
Minimum value of d, excluding D( N0 ).
DMIN2 (input) REAL
Minimum value of d, excluding D( N0 ) and D( N0-1 ).
DN (input) REAL
d(N)
DN1 (input) REAL
d(N-1)
DN2 (input) REAL
d(N-2)
TAU (output) REAL
This is the shift.
TTYPE (output) INTEGER
Shift type.
Further Details
===============
CNST1 = 9/16
=====================================================================
Parameter adjustments */
--z__;
/* Function Body
A negative DMIN forces the shift to take that absolute value
TTYPE records the type of shift. */
if (*dmin__ <= 0.f) {
*tau = -(*dmin__);
*ttype = -1;
return 0;
}
nn = (*n0 << 2) + *pp;
if (*n0in == *n0) {
/* No eigenvalues deflated. */
if (*dmin__ == *dn || *dmin__ == *dn1) {
latime_1.ops += 7.f;
b1 = sqrt(z__[nn - 3]) * sqrt(z__[nn - 5]);
b2 = sqrt(z__[nn - 7]) * sqrt(z__[nn - 9]);
a2 = z__[nn - 7] + z__[nn - 5];
/* Cases 2 and 3. */
if (*dmin__ == *dn && *dmin1 == *dn1) {
latime_1.ops += 3.f;
gap2 = *dmin2 - a2 - *dmin2 * .25f;
if (gap2 > 0.f && gap2 > b2) {
latime_1.ops += 4.f;
gap1 = a2 - *dn - b2 / gap2 * b2;
} else {
latime_1.ops += 3.f;
gap1 = a2 - *dn - (b1 + b2);
}
if (gap1 > 0.f && gap1 > b1) {
latime_1.ops += 4.f;
/* Computing MAX */
r__1 = *dn - b1 / gap1 * b1, r__2 = *dmin__ * .5f;
s = dmax(r__1,r__2);
*ttype = -2;
} else {
latime_1.ops += 2.f;
s = 0.f;
if (*dn > b1) {
s = *dn - b1;
}
if (a2 > b1 + b2) {
/* Computing MIN */
r__1 = s, r__2 = a2 - (b1 + b2);
s = dmin(r__1,r__2);
}
/* Computing MAX */
r__1 = s, r__2 = *dmin__ * .333f;
s = dmax(r__1,r__2);
*ttype = -3;
}
} else {
/* Case 4. */
*ttype = -4;
latime_1.ops += 1.f;
s = *dmin__ * .25f;
if (*dmin__ == *dn) {
latime_1.ops += 1.f;
gam = *dn;
a2 = 0.f;
if (z__[nn - 5] > z__[nn - 7]) {
return 0;
}
b2 = z__[nn - 5] / z__[nn - 7];
np = nn - 9;
} else {
latime_1.ops += 2.f;
np = nn - (*pp << 1);
b2 = z__[np - 2];
gam = *dn1;
if (z__[np - 4] > z__[np - 2]) {
return 0;
}
a2 = z__[np - 4] / z__[np - 2];
if (z__[nn - 9] > z__[nn - 11]) {
return 0;
}
b2 = z__[nn - 9] / z__[nn - 11];
np = nn - 13;
}
/* Approximate contribution to norm squared from I < NN-1. */
a2 += b2;
i__1 = (*i0 << 2) - 1 + *pp;
for (i4 = np; i4 >= i__1; i4 += -4) {
latime_1.ops += 5.f;
if (b2 == 0.f) {
goto L20;
}
b1 = b2;
if (z__[i4] > z__[i4 - 2]) {
return 0;
}
b2 *= z__[i4] / z__[i4 - 2];
a2 += b2;
if (dmax(b2,b1) * 100.f < a2 || .563f < a2) {
goto L20;
}
/* L10: */
}
L20:
latime_1.ops += 1.f;
a2 *= 1.05f;
/* Rayleigh quotient residual bound. */
latime_1.ops += 5.f;
if (a2 < .563f) {
s = gam * (1.f - sqrt(a2)) / (a2 + 1.f);
}
}
} else if (*dmin__ == *dn2) {
/* Case 5. */
*ttype = -5;
latime_1.ops += 1.f;
s = *dmin__ * .25f;
/* Compute contribution to norm squared from I > NN-2. */
latime_1.ops += 4.f;
np = nn - (*pp << 1);
b1 = z__[np - 2];
b2 = z__[np - 6];
gam = *dn2;
if (z__[np - 8] > b2 || z__[np - 4] > b1) {
return 0;
}
a2 = z__[np - 8] / b2 * (z__[np - 4] / b1 + 1.f);
/* Approximate contribution to norm squared from I < NN-2. */
if (*n0 - *i0 > 2) {
latime_1.ops += 3.f;
b2 = z__[nn - 13] / z__[nn - 15];
a2 += b2;
i__1 = (*i0 << 2) - 1 + *pp;
for (i4 = nn - 17; i4 >= i__1; i4 += -4) {
latime_1.ops += 5.f;
if (b2 == 0.f) {
goto L40;
}
b1 = b2;
if (z__[i4] > z__[i4 - 2]) {
return 0;
}
b2 *= z__[i4] / z__[i4 - 2];
a2 += b2;
if (dmax(b2,b1) * 100.f < a2 || .563f < a2) {
goto L40;
}
/* L30: */
}
L40:
a2 *= 1.05f;
}
latime_1.ops += 5.f;
if (a2 < .563f) {
s = gam * (1.f - sqrt(a2)) / (a2 + 1.f);
}
} else {
/* Case 6, no information to guide us. */
if (*ttype == -6) {
latime_1.ops += 3.f;
g += (1.f - g) * .333f;
} else if (*ttype == -18) {
latime_1.ops += 1.f;
g = .083250000000000005f;
} else {
g = .25f;
}
latime_1.ops += 1.f;
s = g * *dmin__;
*ttype = -6;
}
} else if (*n0in == *n0 + 1) {
/* One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN. */
if (*dmin1 == *dn1 && *dmin2 == *dn2) {
/* Cases 7 and 8. */
*ttype = -7;
latime_1.ops += 2.f;
s = *dmin1 * .333f;
if (z__[nn - 5] > z__[nn - 7]) {
return 0;
}
b1 = z__[nn - 5] / z__[nn - 7];
b2 = b1;
if (b2 == 0.f) {
goto L60;
}
i__1 = (*i0 << 2) - 1 + *pp;
for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
latime_1.ops += 4.f;
a2 = b1;
if (z__[i4] > z__[i4 - 2]) {
return 0;
}
b1 *= z__[i4] / z__[i4 - 2];
b2 += b1;
if (dmax(b1,a2) * 100.f < b2) {
goto L60;
}
/* L50: */
}
L60:
latime_1.ops += 8.f;
b2 = sqrt(b2 * 1.05f);
/* Computing 2nd power */
r__1 = b2;
a2 = *dmin1 / (r__1 * r__1 + 1.f);
gap2 = *dmin2 * .5f - a2;
if (gap2 > 0.f && gap2 > b2 * a2) {
latime_1.ops += 7.f;
/* Computing MAX */
r__1 = s, r__2 = a2 * (1.f - a2 * 1.01f * (b2 / gap2) * b2);
s = dmax(r__1,r__2);
} else {
latime_1.ops += 4.f;
/* Computing MAX */
r__1 = s, r__2 = a2 * (1.f - b2 * 1.01f);
s = dmax(r__1,r__2);
*ttype = -8;
}
} else {
/* Case 9. */
latime_1.ops += 2.f;
s = *dmin1 * .25f;
if (*dmin1 == *dn1) {
s = *dmin1 * .5f;
}
*ttype = -9;
}
} else if (*n0in == *n0 + 2) {
/* Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.
Cases 10 and 11. */
latime_1.ops += 1.f;
if (*dmin2 == *dn2 && z__[nn - 5] * 2.f < z__[nn - 7]) {
*ttype = -10;
latime_1.ops += 1.f;
s = *dmin2 * .333f;
if (z__[nn - 5] > z__[nn - 7]) {
return 0;
}
b1 = z__[nn - 5] / z__[nn - 7];
b2 = b1;
if (b2 == 0.f) {
goto L80;
}
i__1 = (*i0 << 2) - 1 + *pp;
for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
latime_1.ops += 4.f;
if (z__[i4] > z__[i4 - 2]) {
return 0;
}
b1 *= z__[i4] / z__[i4 - 2];
b2 += b1;
if (b1 * 100.f < b2) {
goto L80;
}
/* L70: */
}
L80:
latime_1.ops += 12.f;
b2 = sqrt(b2 * 1.05f);
/* Computing 2nd power */
r__1 = b2;
a2 = *dmin2 / (r__1 * r__1 + 1.f);
gap2 = z__[nn - 7] + z__[nn - 9] - sqrt(z__[nn - 11]) * sqrt(z__[
nn - 9]) - a2;
if (gap2 > 0.f && gap2 > b2 * a2) {
latime_1.ops += 7.f;
/* Computing MAX */
r__1 = s, r__2 = a2 * (1.f - a2 * 1.01f * (b2 / gap2) * b2);
s = dmax(r__1,r__2);
} else {
latime_1.ops += 4.f;
/* Computing MAX */
r__1 = s, r__2 = a2 * (1.f - b2 * 1.01f);
s = dmax(r__1,r__2);
}
} else {
latime_1.ops += 1.f;
s = *dmin2 * .25f;
*ttype = -11;
}
} else if (*n0in > *n0 + 2) {
/* Case 12, more than two eigenvalues deflated. No information. */
s = 0.f;
*ttype = -12;
}
*tau = s;
return 0;
/* End of SLASQ4 */
} /* slasq4_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -