sgsvts.c
Go to the documentation of this file.
00001 /* sgsvts.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
00017 
00018 static real c_b17 = 1.f;
00019 static real c_b18 = 0.f;
00020 static real c_b44 = -1.f;
00021 static integer c__1 = 1;
00022 
00023 /* Subroutine */ int sgsvts_(integer *m, integer *p, integer *n, real *a, 
00024         real *af, integer *lda, real *b, real *bf, integer *ldb, real *u, 
00025         integer *ldu, real *v, integer *ldv, real *q, integer *ldq, real *
00026         alpha, real *beta, real *r__, integer *ldr, integer *iwork, real *
00027         work, integer *lwork, real *rwork, real *result)
00028 {
00029     /* System generated locals */
00030     integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, bf_dim1, 
00031             bf_offset, q_dim1, q_offset, r_dim1, r_offset, u_dim1, u_offset, 
00032             v_dim1, v_offset, i__1, i__2;
00033     real r__1;
00034 
00035     /* Local variables */
00036     integer i__, j, k, l;
00037     real ulp;
00038     integer info;
00039     real unfl, temp, resid;
00040     extern /* Subroutine */ int sgemm_(char *, char *, integer *, integer *, 
00041             integer *, real *, real *, integer *, real *, integer *, real *, 
00042             real *, integer *);
00043     real anorm, bnorm;
00044     extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *, 
00045             integer *), ssyrk_(char *, char *, integer *, integer *, real *, 
00046             real *, integer *, real *, real *, integer *);
00047     extern doublereal slamch_(char *), slange_(char *, integer *, 
00048             integer *, real *, integer *, real *);
00049     extern /* Subroutine */ int slacpy_(char *, integer *, integer *, real *, 
00050             integer *, real *, integer *), slaset_(char *, integer *, 
00051             integer *, real *, real *, real *, integer *), sggsvd_(
00052             char *, char *, char *, integer *, integer *, integer *, integer *
00053 , integer *, real *, integer *, real *, integer *, real *, real *, 
00054              real *, integer *, real *, integer *, real *, integer *, real *, 
00055             integer *, integer *);
00056     extern doublereal slansy_(char *, char *, integer *, real *, integer *, 
00057             real *);
00058     real ulpinv;
00059 
00060 
00061 /*  -- LAPACK test routine (version 3.1) -- */
00062 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00063 /*     November 2006 */
00064 
00065 /*     .. Scalar Arguments .. */
00066 /*     .. */
00067 /*     .. Array Arguments .. */
00068 /*     .. */
00069 
00070 /*  Purpose */
00071 /*  ======= */
00072 
00073 /*  SGSVTS tests SGGSVD, which computes the GSVD of an M-by-N matrix A */
00074 /*  and a P-by-N matrix B: */
00075 /*               U'*A*Q = D1*R and V'*B*Q = D2*R. */
00076 
00077 /*  Arguments */
00078 /*  ========= */
00079 
00080 /*  M       (input) INTEGER */
00081 /*          The number of rows of the matrix A.  M >= 0. */
00082 
00083 /*  P       (input) INTEGER */
00084 /*          The number of rows of the matrix B.  P >= 0. */
00085 
00086 /*  N       (input) INTEGER */
00087 /*          The number of columns of the matrices A and B.  N >= 0. */
00088 
00089 /*  A       (input) REAL array, dimension (LDA,M) */
00090 /*          The M-by-N matrix A. */
00091 
00092 /*  AF      (output) REAL array, dimension (LDA,N) */
00093 /*          Details of the GSVD of A and B, as returned by SGGSVD, */
00094 /*          see SGGSVD for further details. */
00095 
00096 /*  LDA     (input) INTEGER */
00097 /*          The leading dimension of the arrays A and AF. */
00098 /*          LDA >= max( 1,M ). */
00099 
00100 /*  B       (input) REAL array, dimension (LDB,P) */
00101 /*          On entry, the P-by-N matrix B. */
00102 
00103 /*  BF      (output) REAL array, dimension (LDB,N) */
00104 /*          Details of the GSVD of A and B, as returned by SGGSVD, */
00105 /*          see SGGSVD for further details. */
00106 
00107 /*  LDB     (input) INTEGER */
00108 /*          The leading dimension of the arrays B and BF. */
00109 /*          LDB >= max(1,P). */
00110 
00111 /*  U       (output) REAL array, dimension(LDU,M) */
00112 /*          The M by M orthogonal matrix U. */
00113 
00114 /*  LDU     (input) INTEGER */
00115 /*          The leading dimension of the array U. LDU >= max(1,M). */
00116 
00117 /*  V       (output) REAL array, dimension(LDV,M) */
00118 /*          The P by P orthogonal matrix V. */
00119 
00120 /*  LDV     (input) INTEGER */
00121 /*          The leading dimension of the array V. LDV >= max(1,P). */
00122 
00123 /*  Q       (output) REAL array, dimension(LDQ,N) */
00124 /*          The N by N orthogonal matrix Q. */
00125 
00126 /*  LDQ     (input) INTEGER */
00127 /*          The leading dimension of the array Q. LDQ >= max(1,N). */
00128 
00129 /*  ALPHA   (output) REAL array, dimension (N) */
00130 /*  BETA    (output) REAL array, dimension (N) */
00131 /*          The generalized singular value pairs of A and B, the */
00132 /*          ``diagonal'' matrices D1 and D2 are constructed from */
00133 /*          ALPHA and BETA, see subroutine SGGSVD for details. */
00134 
00135 /*  R       (output) REAL array, dimension(LDQ,N) */
00136 /*          The upper triangular matrix R. */
00137 
00138 /*  LDR     (input) INTEGER */
00139 /*          The leading dimension of the array R. LDR >= max(1,N). */
00140 
00141 /*  IWORK   (workspace) INTEGER array, dimension (N) */
00142 
00143 /*  WORK    (workspace) REAL array, dimension (LWORK) */
00144 
00145 /*  LWORK   (input) INTEGER */
00146 /*          The dimension of the array WORK, */
00147 /*          LWORK >= max(M,P,N)*max(M,P,N). */
00148 
00149 /*  RWORK   (workspace) REAL array, dimension (max(M,P,N)) */
00150 
00151 /*  RESULT  (output) REAL array, dimension (6) */
00152 /*          The test ratios: */
00153 /*          RESULT(1) = norm( U'*A*Q - D1*R ) / ( MAX(M,N)*norm(A)*ULP) */
00154 /*          RESULT(2) = norm( V'*B*Q - D2*R ) / ( MAX(P,N)*norm(B)*ULP) */
00155 /*          RESULT(3) = norm( I - U'*U ) / ( M*ULP ) */
00156 /*          RESULT(4) = norm( I - V'*V ) / ( P*ULP ) */
00157 /*          RESULT(5) = norm( I - Q'*Q ) / ( N*ULP ) */
00158 /*          RESULT(6) = 0        if ALPHA is in decreasing order; */
00159 /*                    = ULPINV   otherwise. */
00160 
00161 /*  ===================================================================== */
00162 
00163 /*     .. Parameters .. */
00164 /*     .. */
00165 /*     .. Local Scalars .. */
00166 /*     .. */
00167 /*     .. External Functions .. */
00168 /*     .. */
00169 /*     .. External Subroutines .. */
00170 /*     .. */
00171 /*     .. Intrinsic Functions .. */
00172 /*     .. */
00173 /*     .. Executable Statements .. */
00174 
00175     /* Parameter adjustments */
00176     af_dim1 = *lda;
00177     af_offset = 1 + af_dim1;
00178     af -= af_offset;
00179     a_dim1 = *lda;
00180     a_offset = 1 + a_dim1;
00181     a -= a_offset;
00182     bf_dim1 = *ldb;
00183     bf_offset = 1 + bf_dim1;
00184     bf -= bf_offset;
00185     b_dim1 = *ldb;
00186     b_offset = 1 + b_dim1;
00187     b -= b_offset;
00188     u_dim1 = *ldu;
00189     u_offset = 1 + u_dim1;
00190     u -= u_offset;
00191     v_dim1 = *ldv;
00192     v_offset = 1 + v_dim1;
00193     v -= v_offset;
00194     q_dim1 = *ldq;
00195     q_offset = 1 + q_dim1;
00196     q -= q_offset;
00197     --alpha;
00198     --beta;
00199     r_dim1 = *ldr;
00200     r_offset = 1 + r_dim1;
00201     r__ -= r_offset;
00202     --iwork;
00203     --work;
00204     --rwork;
00205     --result;
00206 
00207     /* Function Body */
00208     ulp = slamch_("Precision");
00209     ulpinv = 1.f / ulp;
00210     unfl = slamch_("Safe minimum");
00211 
00212 /*     Copy the matrix A to the array AF. */
00213 
00214     slacpy_("Full", m, n, &a[a_offset], lda, &af[af_offset], lda);
00215     slacpy_("Full", p, n, &b[b_offset], ldb, &bf[bf_offset], ldb);
00216 
00217 /* Computing MAX */
00218     r__1 = slange_("1", m, n, &a[a_offset], lda, &rwork[1]);
00219     anorm = dmax(r__1,unfl);
00220 /* Computing MAX */
00221     r__1 = slange_("1", p, n, &b[b_offset], ldb, &rwork[1]);
00222     bnorm = dmax(r__1,unfl);
00223 
00224 /*     Factorize the matrices A and B in the arrays AF and BF. */
00225 
00226     sggsvd_("U", "V", "Q", m, n, p, &k, &l, &af[af_offset], lda, &bf[
00227             bf_offset], ldb, &alpha[1], &beta[1], &u[u_offset], ldu, &v[
00228             v_offset], ldv, &q[q_offset], ldq, &work[1], &iwork[1], &info);
00229 
00230 /*     Copy R */
00231 
00232 /* Computing MIN */
00233     i__2 = k + l;
00234     i__1 = min(i__2,*m);
00235     for (i__ = 1; i__ <= i__1; ++i__) {
00236         i__2 = k + l;
00237         for (j = i__; j <= i__2; ++j) {
00238             r__[i__ + j * r_dim1] = af[i__ + (*n - k - l + j) * af_dim1];
00239 /* L10: */
00240         }
00241 /* L20: */
00242     }
00243 
00244     if (*m - k - l < 0) {
00245         i__1 = k + l;
00246         for (i__ = *m + 1; i__ <= i__1; ++i__) {
00247             i__2 = k + l;
00248             for (j = i__; j <= i__2; ++j) {
00249                 r__[i__ + j * r_dim1] = bf[i__ - k + (*n - k - l + j) * 
00250                         bf_dim1];
00251 /* L30: */
00252             }
00253 /* L40: */
00254         }
00255     }
00256 
00257 /*     Compute A:= U'*A*Q - D1*R */
00258 
00259     sgemm_("No transpose", "No transpose", m, n, n, &c_b17, &a[a_offset], lda, 
00260              &q[q_offset], ldq, &c_b18, &work[1], lda)
00261             ;
00262 
00263     sgemm_("Transpose", "No transpose", m, n, m, &c_b17, &u[u_offset], ldu, &
00264             work[1], lda, &c_b18, &a[a_offset], lda);
00265 
00266     i__1 = k;
00267     for (i__ = 1; i__ <= i__1; ++i__) {
00268         i__2 = k + l;
00269         for (j = i__; j <= i__2; ++j) {
00270             a[i__ + (*n - k - l + j) * a_dim1] -= r__[i__ + j * r_dim1];
00271 /* L50: */
00272         }
00273 /* L60: */
00274     }
00275 
00276 /* Computing MIN */
00277     i__2 = k + l;
00278     i__1 = min(i__2,*m);
00279     for (i__ = k + 1; i__ <= i__1; ++i__) {
00280         i__2 = k + l;
00281         for (j = i__; j <= i__2; ++j) {
00282             a[i__ + (*n - k - l + j) * a_dim1] -= alpha[i__] * r__[i__ + j * 
00283                     r_dim1];
00284 /* L70: */
00285         }
00286 /* L80: */
00287     }
00288 
00289 /*     Compute norm( U'*A*Q - D1*R ) / ( MAX(1,M,N)*norm(A)*ULP ) . */
00290 
00291     resid = slange_("1", m, n, &a[a_offset], lda, &rwork[1]);
00292 
00293     if (anorm > 0.f) {
00294 /* Computing MAX */
00295         i__1 = max(1,*m);
00296         result[1] = resid / (real) max(i__1,*n) / anorm / ulp;
00297     } else {
00298         result[1] = 0.f;
00299     }
00300 
00301 /*     Compute B := V'*B*Q - D2*R */
00302 
00303     sgemm_("No transpose", "No transpose", p, n, n, &c_b17, &b[b_offset], ldb, 
00304              &q[q_offset], ldq, &c_b18, &work[1], ldb)
00305             ;
00306 
00307     sgemm_("Transpose", "No transpose", p, n, p, &c_b17, &v[v_offset], ldv, &
00308             work[1], ldb, &c_b18, &b[b_offset], ldb);
00309 
00310     i__1 = l;
00311     for (i__ = 1; i__ <= i__1; ++i__) {
00312         i__2 = l;
00313         for (j = i__; j <= i__2; ++j) {
00314             b[i__ + (*n - l + j) * b_dim1] -= beta[k + i__] * r__[k + i__ + (
00315                     k + j) * r_dim1];
00316 /* L90: */
00317         }
00318 /* L100: */
00319     }
00320 
00321 /*     Compute norm( V'*B*Q - D2*R ) / ( MAX(P,N)*norm(B)*ULP ) . */
00322 
00323     resid = slange_("1", p, n, &b[b_offset], ldb, &rwork[1]);
00324     if (bnorm > 0.f) {
00325 /* Computing MAX */
00326         i__1 = max(1,*p);
00327         result[2] = resid / (real) max(i__1,*n) / bnorm / ulp;
00328     } else {
00329         result[2] = 0.f;
00330     }
00331 
00332 /*     Compute I - U'*U */
00333 
00334     slaset_("Full", m, m, &c_b18, &c_b17, &work[1], ldq);
00335     ssyrk_("Upper", "Transpose", m, m, &c_b44, &u[u_offset], ldu, &c_b17, &
00336             work[1], ldu);
00337 
00338 /*     Compute norm( I - U'*U ) / ( M * ULP ) . */
00339 
00340     resid = slansy_("1", "Upper", m, &work[1], ldu, &rwork[1]);
00341     result[3] = resid / (real) max(1,*m) / ulp;
00342 
00343 /*     Compute I - V'*V */
00344 
00345     slaset_("Full", p, p, &c_b18, &c_b17, &work[1], ldv);
00346     ssyrk_("Upper", "Transpose", p, p, &c_b44, &v[v_offset], ldv, &c_b17, &
00347             work[1], ldv);
00348 
00349 /*     Compute norm( I - V'*V ) / ( P * ULP ) . */
00350 
00351     resid = slansy_("1", "Upper", p, &work[1], ldv, &rwork[1]);
00352     result[4] = resid / (real) max(1,*p) / ulp;
00353 
00354 /*     Compute I - Q'*Q */
00355 
00356     slaset_("Full", n, n, &c_b18, &c_b17, &work[1], ldq);
00357     ssyrk_("Upper", "Transpose", n, n, &c_b44, &q[q_offset], ldq, &c_b17, &
00358             work[1], ldq);
00359 
00360 /*     Compute norm( I - Q'*Q ) / ( N * ULP ) . */
00361 
00362     resid = slansy_("1", "Upper", n, &work[1], ldq, &rwork[1]);
00363     result[5] = resid / (real) max(1,*n) / ulp;
00364 
00365 /*     Check sorting */
00366 
00367     scopy_(n, &alpha[1], &c__1, &work[1], &c__1);
00368 /* Computing MIN */
00369     i__2 = k + l;
00370     i__1 = min(i__2,*m);
00371     for (i__ = k + 1; i__ <= i__1; ++i__) {
00372         j = iwork[i__];
00373         if (i__ != j) {
00374             temp = work[i__];
00375             work[i__] = work[j];
00376             work[j] = temp;
00377         }
00378 /* L110: */
00379     }
00380 
00381     result[6] = 0.f;
00382 /* Computing MIN */
00383     i__2 = k + l;
00384     i__1 = min(i__2,*m) - 1;
00385     for (i__ = k + 1; i__ <= i__1; ++i__) {
00386         if (work[i__] < work[i__ + 1]) {
00387             result[6] = ulpinv;
00388         }
00389 /* L120: */
00390     }
00391 
00392     return 0;
00393 
00394 /*     End of SGSVTS */
00395 
00396 } /* sgsvts_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:09