📄 slasd7.c
字号:
tau = vf[nlp1];
for (i__ = *nl; i__ >= 1; --i__) {
z__[i__ + 1] = *alpha * vl[i__];
vl[i__] = 0.f;
vf[i__ + 1] = vf[i__];
d__[i__ + 1] = d__[i__];
idxq[i__ + 1] = idxq[i__] + 1;
/* L10: */
}
vf[1] = tau;
/* Generate the second part of the vector Z. */
latime_1.ops += (real) (m - nlp2 + 1);
i__1 = m;
for (i__ = nlp2; i__ <= i__1; ++i__) {
z__[i__] = *beta * vf[i__];
vf[i__] = 0.f;
/* L20: */
}
/* Sort the singular values into increasing order */
i__1 = n;
for (i__ = nlp2; i__ <= i__1; ++i__) {
idxq[i__] += nlp1;
/* L30: */
}
/* DSIGMA, IDXC, IDXC, and ZW are used as storage space. */
i__1 = n;
for (i__ = 2; i__ <= i__1; ++i__) {
dsigma[i__] = d__[idxq[i__]];
zw[i__] = z__[idxq[i__]];
vfw[i__] = vf[idxq[i__]];
vlw[i__] = vl[idxq[i__]];
/* L40: */
}
slamrg_(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
i__1 = n;
for (i__ = 2; i__ <= i__1; ++i__) {
idxi = idx[i__] + 1;
d__[i__] = dsigma[idxi];
z__[i__] = zw[idxi];
vf[i__] = vfw[idxi];
vl[i__] = vlw[idxi];
/* L50: */
}
/* Calculate the allowable deflation tolerence */
latime_1.ops += 3.f;
eps = slamch_("Epsilon");
/* Computing MAX */
r__1 = dabs(*alpha), r__2 = dabs(*beta);
tol = dmax(r__1,r__2);
/* Computing MAX */
r__2 = (r__1 = d__[n], dabs(r__1));
tol = eps * 64.f * dmax(r__2,tol);
/* There are 2 kinds of deflation -- first a value in the z-vector
is small, second two (or more) singular values are very close
together (their difference is small).
If the value in the z-vector is small, we simply permute the
array so that the corresponding singular value is moved to the
end.
If two values in the D-vector are close, we perform a two-sided
rotation designed to make one of the corresponding z-vector
entries zero, and then permute the array so that the deflated
singular value is moved to the end.
If there are multiple singular values then the problem deflates.
Here the number of equal singular values are found. As each equal
singular value is found, an elementary reflector is computed to
rotate the corresponding singular subspace so that the
corresponding components of Z are zero in this new basis. */
*k = 1;
k2 = n + 1;
i__1 = n;
for (j = 2; j <= i__1; ++j) {
if ((r__1 = z__[j], dabs(r__1)) <= tol) {
/* Deflate due to small z component. */
--k2;
idxp[k2] = j;
if (j == n) {
goto L100;
}
} else {
jprev = j;
goto L70;
}
/* L60: */
}
L70:
j = jprev;
L80:
++j;
if (j > n) {
goto L90;
}
if ((r__1 = z__[j], dabs(r__1)) <= tol) {
/* Deflate due to small z component. */
--k2;
idxp[k2] = j;
} else {
/* Check if singular values are close enough to allow deflation. */
latime_1.ops += 1.f;
if ((r__1 = d__[j] - d__[jprev], dabs(r__1)) <= tol) {
/* Deflation is possible. */
*s = z__[jprev];
*c__ = z__[j];
/* Find sqrt(a**2+b**2) without overflow or
destructive underflow. */
latime_1.ops += 7.f;
tau = slapy2_(c__, s);
z__[j] = tau;
z__[jprev] = 0.f;
*c__ /= tau;
*s = -(*s) / tau;
/* Record the appropriate Givens rotation */
if (*icompq == 1) {
++(*givptr);
idxjp = idxq[idx[jprev] + 1];
idxj = idxq[idx[j] + 1];
if (idxjp <= nlp1) {
--idxjp;
}
if (idxj <= nlp1) {
--idxj;
}
givcol_ref(*givptr, 2) = idxjp;
givcol_ref(*givptr, 1) = idxj;
givnum_ref(*givptr, 2) = *c__;
givnum_ref(*givptr, 1) = *s;
}
latime_1.ops += 12.f;
srot_(&c__1, &vf[jprev], &c__1, &vf[j], &c__1, c__, s);
srot_(&c__1, &vl[jprev], &c__1, &vl[j], &c__1, c__, s);
--k2;
idxp[k2] = jprev;
jprev = j;
} else {
++(*k);
zw[*k] = z__[jprev];
dsigma[*k] = d__[jprev];
idxp[*k] = jprev;
jprev = j;
}
}
goto L80;
L90:
/* Record the last singular value. */
++(*k);
zw[*k] = z__[jprev];
dsigma[*k] = d__[jprev];
idxp[*k] = jprev;
L100:
/* Sort the singular values into DSIGMA. The singular values which
were not deflated go into the first K slots of DSIGMA, except
that DSIGMA(1) is treated separately. */
i__1 = n;
for (j = 2; j <= i__1; ++j) {
jp = idxp[j];
dsigma[j] = d__[jp];
vfw[j] = vf[jp];
vlw[j] = vl[jp];
/* L110: */
}
if (*icompq == 1) {
i__1 = n;
for (j = 2; j <= i__1; ++j) {
jp = idxp[j];
perm[j] = idxq[idx[jp] + 1];
if (perm[j] <= nlp1) {
--perm[j];
}
/* L120: */
}
}
/* The deflated singular values go back into the last N - K slots of
D. */
i__1 = n - *k;
scopy_(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
/* Determine DSIGMA(1), DSIGMA(2), Z(1), VF(1), VL(1), VF(M), and
VL(M). */
latime_1.ops += 1.f;
dsigma[1] = 0.f;
hlftol = tol / 2.f;
if (dabs(dsigma[2]) <= hlftol) {
dsigma[2] = hlftol;
}
if (m > n) {
latime_1.ops += 5.f;
z__[1] = slapy2_(&z1, &z__[m]);
if (z__[1] <= tol) {
*c__ = 1.f;
*s = 0.f;
z__[1] = tol;
} else {
latime_1.ops += 2.f;
*c__ = z1 / z__[1];
*s = -z__[m] / z__[1];
}
latime_1.ops += 12.f;
srot_(&c__1, &vf[m], &c__1, &vf[1], &c__1, c__, s);
srot_(&c__1, &vl[m], &c__1, &vl[1], &c__1, c__, s);
} else {
if (dabs(z1) <= tol) {
z__[1] = tol;
} else {
z__[1] = z1;
}
}
/* Restore Z, VF, and VL. */
i__1 = *k - 1;
scopy_(&i__1, &zw[2], &c__1, &z__[2], &c__1);
i__1 = n - 1;
scopy_(&i__1, &vfw[2], &c__1, &vf[2], &c__1);
i__1 = n - 1;
scopy_(&i__1, &vlw[2], &c__1, &vl[2], &c__1);
return 0;
/* End of SLASD7 */
} /* slasd7_ */
#undef givnum_ref
#undef givcol_ref
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -