stgsja.c
来自「InsightToolkit-1.4.0(有大量的优化算法程序)」· C语言 代码 · 共 505 行 · 第 1/2 页
C
505 行
/* */
/* MAXIT INTEGER */
/* MAXIT specifies the total loops that the iterative procedure */
/* may take. If after MAXIT cycles, the routine fails to */
/* converge, we return INFO = 1. */
/* */
/* Further Details */
/* =============== */
/* */
/* STGSJA essentially uses a variant of Kogbetliantz algorithm to reduce */
/* min(L,M-K)-by-L triangular (or trapezoidal) matrix A23 and L-by-L */
/* matrix B13 to the form: */
/* */
/* U1'*A13*Q1 = C1*R1; V1'*B13*Q1 = S1*R1, */
/* */
/* where U1, V1 and Q1 are orthogonal matrix, and Z' is the transpose */
/* of Z. C1 and S1 are diagonal matrices satisfying */
/* */
/* C1**2 + S1**2 = I, */
/* */
/* and R1 is an L-by-L nonsingular upper triangular matrix. */
/* */
/* ===================================================================== */
/* Decode and test the input parameters */
initu = lsame_(jobu, "I");
wantu = initu || lsame_(jobu, "U");
initv = lsame_(jobv, "I");
wantv = initv || lsame_(jobv, "V");
initq = lsame_(jobq, "I");
wantq = initq || lsame_(jobq, "Q");
*info = 0;
if (! (initu || wantu || lsame_(jobu, "N"))) {
*info = -1;
} else if (! (initv || wantv || lsame_(jobv, "N"))) {
*info = -2;
} else if (! (initq || wantq || lsame_(jobq, "N"))) {
*info = -3;
} else if (*m < 0) {
*info = -4;
} else if (*p < 0) {
*info = -5;
} else if (*n < 0) {
*info = -6;
} else if (*lda < max(1,*m)) {
*info = -10;
} else if (*ldb < max(1,*p)) {
*info = -12;
} else if (*ldu < 1 || (wantu && *ldu < *m)) {
*info = -18;
} else if (*ldv < 1 || (wantv && *ldv < *p)) {
*info = -20;
} else if (*ldq < 1 || (wantq && *ldq < *n)) {
*info = -22;
}
if (*info != 0) {
i__1 = -(*info);
xerbla_("STGSJA", &i__1);
return;
}
/* Initialize U, V and Q, if necessary */
if (initu) {
slaset_("Full", m, m, &c_b13, &c_b14, u, ldu);
}
if (initv) {
slaset_("Full", p, p, &c_b13, &c_b14, v, ldv);
}
if (initq) {
slaset_("Full", n, n, &c_b13, &c_b14, q, ldq);
}
/* Loop until convergence */
upper = FALSE_;
for (kcycle = 1; kcycle <= 40; ++kcycle) {
upper = ! upper;
for (i = 0; i < *l; ++i) {
for (j = i + 1; j < *l; ++j) {
a1 = a2 = a3 = 0.f;
if (*k + i < *m) {
a1 = a[*k + i + (*n - *l + i) * *lda];
}
if (*k + j < *m) {
a3 = a[*k + j + (*n - *l + j) * *lda];
}
b1 = b[i + (*n - *l + i) * *ldb];
b3 = b[j + (*n - *l + j) * *ldb];
if (upper) {
if (*k + i < *m) {
a2 = a[*k + i + (*n - *l + j) * *lda];
}
b2 = b[i + (*n - *l + j) * *ldb];
} else {
if (*k + j < *m) {
a2 = a[*k + j + (*n - *l + i) * *lda];
}
b2 = b[j + (*n - *l + i) * *ldb];
}
slags2_(&upper, &a1, &a2, &a3, &b1, &b2, &b3, &csu, &snu, &csv, &snv, &csq, &snq);
/* Update (K+I)-th and (K+J)-th rows of matrix A: U'*A */
if (*k + j < *m) {
srot_(l, &a[*k + j + (*n - *l) * *lda], lda, &a[*k + i + (*n - *l) * *lda], lda, &csu, &snu);
}
/* Update I-th and J-th rows of matrix B: V'*B */
srot_(l, &b[j + (*n - *l) * *ldb], ldb, &b[i + (*n - *l) * *ldb], ldb, &csv, &snv);
/* Update (N-L+I)-th and (N-L+J)-th columns of matrices */
/* A and B: A*Q and B*Q */
i__1 = min(*k + *l,*m);
srot_(&i__1, &a[(*n - *l + j) * *lda], &c__1, &a[(*n - *l + i) * *lda], &c__1, &csq, &snq);
srot_(l, &b[(*n - *l + j) * *ldb], &c__1, &b[(*n - *l + i) * *ldb], &c__1, &csq, &snq);
if (upper) {
if (*k + i < *m) {
a[*k + i + (*n - *l + j) * *lda] = 0.f;
}
b[i + (*n - *l + j) * *ldb] = 0.f;
} else {
if (*k + j < *m) {
a[*k + j + (*n - *l + i) * *lda] = 0.f;
}
b[j + (*n - *l + i) * *ldb] = 0.f;
}
/* Update orthogonal matrices U, V, Q, if desired. */
if (wantu && *k + j < *m) {
srot_(m, &u[(*k + j) * *ldu], &c__1, &u[(*k + i) * *ldu], &c__1, &csu, &snu);
}
if (wantv) {
srot_(p, &v[j * *ldv], &c__1, &v[i * *ldv], &c__1, &csv, &snv);
}
if (wantq) {
srot_(n, &q[(*n - *l + j) * *ldq], &c__1, &q[(*n - *l + i) * *ldq], &c__1, &csq, &snq);
}
}
}
if (! upper) {
/* The matrices A13 and B13 were lower triangular at the start */
/* of the cycle, and are now upper triangular. */
/* Convergence test: test the parallelism of the corresponding */
/* rows of A and B. */
error = 0.f;
for (i = 0; i < min(*l,*m - *k); ++i) {
i__1 = *l - i;
scopy_(&i__1, &a[*k + i + (*n - *l + i) * *lda], lda, work, &c__1);
scopy_(&i__1, &b[i + (*n - *l + i) * *ldb], ldb, &work[*l], &c__1);
slapll_(&i__1, work, &c__1, &work[*l], &c__1, &ssmin);
error = max(error,ssmin);
}
if (abs(error) <= (real) (*n) * min(*tola,*tolb)) {
goto L50;
}
}
/* End of cycle loop */
}
/* The algorithm has not converged after MAXIT cycles. */
*info = 1;
*ncycle = kcycle;
return;
L50:
/* If ERROR <= N*MIN(TOLA,TOLB), then the algorithm has converged. */
/* Compute the generalized singular value pairs (ALPHA, BETA), and */
/* set the triangular matrix R to array A. */
for (i = 0; i < *k; ++i) {
alpha[i] = 1.f;
beta[i] = 0.f;
}
for (i = 0; i < min(*l,*m - *k); ++i) {
a1 = a[*k + i + (*n - *l + i) * *lda];
b1 = b[i + (*n - *l + i) * *ldb];
if (a1 != 0.f) {
gamma = b1 / a1;
/* change sign if necessary */
if (gamma < 0.f) {
i__1 = *l - i;
sscal_(&i__1, &c_b43, &b[i + (*n - *l + i) * *ldb], ldb);
if (wantv) {
sscal_(p, &c_b43, &v[i * *ldv], &c__1);
}
}
r__1 = abs(gamma);
slartg_(&r__1, &c_b14, &beta[*k + i], &alpha[*k + i], &rwk);
if (alpha[*k + i] >= beta[*k + i]) {
i__1 = *l - i;
r__1 = 1.f / alpha[*k + i];
sscal_(&i__1, &r__1, &a[*k + i + (*n - *l + i) * *lda], lda);
} else {
i__1 = *l - i;
r__1 = 1.f / beta[*k + i];
sscal_(&i__1, &r__1, &b[i + (*n - *l + i) * *ldb], ldb);
scopy_(&i__1, &b[i + (*n - *l + i) * *ldb], ldb, &a[*k + i + (*n - *l + i) * *lda], lda);
}
} else {
alpha[*k + i] = 0.f;
beta[*k + i] = 1.f;
i__1 = *l - i;
scopy_(&i__1, &b[i + (*n - *l + i) * *ldb], ldb, &a[*k + i + (*n - *l + i) * *lda], lda);
}
}
/* Post-assignment */
for (i = *m; i < *k + *l; ++i) {
alpha[i] = 0.f;
beta[i] = 1.f;
}
if (*k + *l < *n) {
for (i = *k + *l; i < *n; ++i) {
alpha[i] = 0.f;
beta[i] = 0.f;
}
}
*ncycle = kcycle;
return;
} /* stgsja_ */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?