📄 slasd2.c
字号:
i__1 = n;
for (i__ = nlp2; i__ <= i__1; ++i__) {
idxq[i__] += nlp1;
/* L50: */
}
/* DSIGMA, IDXC, IDXC, and the first column of U2
are used as storage space. */
i__1 = n;
for (i__ = 2; i__ <= i__1; ++i__) {
dsigma[i__] = d__[idxq[i__]];
u2_ref(i__, 1) = z__[idxq[i__]];
idxc[i__] = coltyp[idxq[i__]];
/* L60: */
}
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__] = u2_ref(idxi, 1);
coltyp[i__] = idxc[idxi];
/* L70: */
}
/* Calculate the allowable deflation tolerance */
latime_1.ops += 2.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 * 8.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;
coltyp[j] = 4;
if (j == n) {
goto L120;
}
} else {
jprev = j;
goto L90;
}
/* L80: */
}
L90:
j = jprev;
L100:
++j;
if (j > n) {
goto L110;
}
if ((r__1 = z__[j], dabs(r__1)) <= tol) {
/* Deflate due to small z component. */
--k2;
idxp[k2] = j;
coltyp[j] = 4;
} 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);
c__ /= tau;
s = -s / tau;
z__[j] = tau;
z__[jprev] = 0.f;
/* Apply back the Givens rotation to the left and right
singular vector matrices. */
idxjp = idxq[idx[jprev] + 1];
idxj = idxq[idx[j] + 1];
if (idxjp <= nlp1) {
--idxjp;
}
if (idxj <= nlp1) {
--idxj;
}
latime_1.ops += 12.f;
srot_(&n, &u_ref(1, idxjp), &c__1, &u_ref(1, idxj), &c__1, &c__, &
s);
srot_(&m, &vt_ref(idxjp, 1), ldvt, &vt_ref(idxj, 1), ldvt, &c__, &
s);
if (coltyp[j] != coltyp[jprev]) {
coltyp[j] = 3;
}
coltyp[jprev] = 4;
--k2;
idxp[k2] = jprev;
jprev = j;
} else {
++(*k);
u2_ref(*k, 1) = z__[jprev];
dsigma[*k] = d__[jprev];
idxp[*k] = jprev;
jprev = j;
}
}
goto L100;
L110:
/* Record the last singular value. */
++(*k);
u2_ref(*k, 1) = z__[jprev];
dsigma[*k] = d__[jprev];
idxp[*k] = jprev;
L120:
/* Count up the total number of the various types of columns, then
form a permutation which positions the four column types into
four groups of uniform structure (although one or more of these
groups may be empty). */
for (j = 1; j <= 4; ++j) {
ctot[j - 1] = 0;
/* L130: */
}
i__1 = n;
for (j = 2; j <= i__1; ++j) {
ct = coltyp[j];
++ctot[ct - 1];
/* L140: */
}
/* PSM(*) = Position in SubMatrix (of types 1 through 4) */
psm[0] = 2;
psm[1] = ctot[0] + 2;
psm[2] = psm[1] + ctot[1];
psm[3] = psm[2] + ctot[2];
/* Fill out the IDXC array so that the permutation which it induces
will place all type-1 columns first, all type-2 columns next,
then all type-3's, and finally all type-4's, starting from the
second column. This applies similarly to the rows of VT. */
i__1 = n;
for (j = 2; j <= i__1; ++j) {
jp = idxp[j];
ct = coltyp[jp];
idxc[psm[ct - 1]] = j;
++psm[ct - 1];
/* L150: */
}
/* Sort the singular values and corresponding singular vectors into
DSIGMA, U2, and VT2 respectively. The singular values/vectors
which were not deflated go into the first K slots of DSIGMA, U2,
and VT2 respectively, while those which were deflated go into the
last N - K slots, except that the first column/row will be treated
separately. */
i__1 = n;
for (j = 2; j <= i__1; ++j) {
jp = idxp[j];
dsigma[j] = d__[jp];
idxj = idxq[idx[idxp[idxc[j]]] + 1];
if (idxj <= nlp1) {
--idxj;
}
scopy_(&n, &u_ref(1, idxj), &c__1, &u2_ref(1, j), &c__1);
scopy_(&m, &vt_ref(idxj, 1), ldvt, &vt2_ref(j, 1), ldvt2);
/* L160: */
}
/* Determine DSIGMA(1), DSIGMA(2) and Z(1) */
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];
}
} else {
if (dabs(z1) <= tol) {
z__[1] = tol;
} else {
z__[1] = z1;
}
}
/* Move the rest of the updating row to Z. */
i__1 = *k - 1;
scopy_(&i__1, &u2_ref(2, 1), &c__1, &z__[2], &c__1);
/* Determine the first column of U2, the first row of VT2 and the
last row of VT. */
slaset_("A", &n, &c__1, &c_b30, &c_b30, &u2[u2_offset], ldu2);
u2_ref(nlp1, 1) = 1.f;
if (m > n) {
latime_1.ops += (real) (nlp1 << 1);
i__1 = nlp1;
for (i__ = 1; i__ <= i__1; ++i__) {
vt_ref(m, i__) = -s * vt_ref(nlp1, i__);
vt2_ref(1, i__) = c__ * vt_ref(nlp1, i__);
/* L170: */
}
latime_1.ops += (real) (m - nlp2 + 1 << 1);
i__1 = m;
for (i__ = nlp2; i__ <= i__1; ++i__) {
vt2_ref(1, i__) = s * vt_ref(m, i__);
vt_ref(m, i__) = c__ * vt_ref(m, i__);
/* L180: */
}
} else {
scopy_(&m, &vt_ref(nlp1, 1), ldvt, &vt2_ref(1, 1), ldvt2);
}
if (m > n) {
scopy_(&m, &vt_ref(m, 1), ldvt, &vt2_ref(m, 1), ldvt2);
}
/* The deflated singular values and their corresponding vectors go
into the back of D, U, and V respectively. */
if (n > *k) {
i__1 = n - *k;
scopy_(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
i__1 = n - *k;
slacpy_("A", &n, &i__1, &u2_ref(1, *k + 1), ldu2, &u_ref(1, *k + 1),
ldu);
i__1 = n - *k;
slacpy_("A", &i__1, &m, &vt2_ref(*k + 1, 1), ldvt2, &vt_ref(*k + 1, 1)
, ldvt);
}
/* Copy CTOT into COLTYP for referencing in SLASD3. */
for (j = 1; j <= 4; ++j) {
coltyp[j] = ctot[j - 1];
/* L190: */
}
return 0;
/* End of SLASD2 */
} /* slasd2_ */
#undef vt2_ref
#undef vt_ref
#undef u2_ref
#undef u_ref
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -