sgbbrd.c
Go to the documentation of this file.
00001 /* sgbbrd.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_b8 = 0.f;
00019 static real c_b9 = 1.f;
00020 static integer c__1 = 1;
00021 
00022 /* Subroutine */ int sgbbrd_(char *vect, integer *m, integer *n, integer *ncc, 
00023          integer *kl, integer *ku, real *ab, integer *ldab, real *d__, real *
00024         e, real *q, integer *ldq, real *pt, integer *ldpt, real *c__, integer 
00025         *ldc, real *work, integer *info)
00026 {
00027     /* System generated locals */
00028     integer ab_dim1, ab_offset, c_dim1, c_offset, pt_dim1, pt_offset, q_dim1, 
00029             q_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7;
00030 
00031     /* Local variables */
00032     integer i__, j, l, j1, j2, kb;
00033     real ra, rb, rc;
00034     integer kk, ml, mn, nr, mu;
00035     real rs;
00036     integer kb1, ml0, mu0, klm, kun, nrt, klu1, inca;
00037     extern /* Subroutine */ int srot_(integer *, real *, integer *, real *, 
00038             integer *, real *, real *);
00039     extern logical lsame_(char *, char *);
00040     logical wantb, wantc;
00041     integer minmn;
00042     logical wantq;
00043     extern /* Subroutine */ int xerbla_(char *, integer *), slaset_(
00044             char *, integer *, integer *, real *, real *, real *, integer *), slartg_(real *, real *, real *, real *, real *), slargv_(
00045             integer *, real *, integer *, real *, integer *, real *, integer *
00046 ), slartv_(integer *, real *, integer *, real *, integer *, real *
00047 , real *, integer *);
00048     logical wantpt;
00049 
00050 
00051 /*  -- LAPACK routine (version 3.2) -- */
00052 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00053 /*     November 2006 */
00054 
00055 /*     .. Scalar Arguments .. */
00056 /*     .. */
00057 /*     .. Array Arguments .. */
00058 /*     .. */
00059 
00060 /*  Purpose */
00061 /*  ======= */
00062 
00063 /*  SGBBRD reduces a real general m-by-n band matrix A to upper */
00064 /*  bidiagonal form B by an orthogonal transformation: Q' * A * P = B. */
00065 
00066 /*  The routine computes B, and optionally forms Q or P', or computes */
00067 /*  Q'*C for a given matrix C. */
00068 
00069 /*  Arguments */
00070 /*  ========= */
00071 
00072 /*  VECT    (input) CHARACTER*1 */
00073 /*          Specifies whether or not the matrices Q and P' are to be */
00074 /*          formed. */
00075 /*          = 'N': do not form Q or P'; */
00076 /*          = 'Q': form Q only; */
00077 /*          = 'P': form P' only; */
00078 /*          = 'B': form both. */
00079 
00080 /*  M       (input) INTEGER */
00081 /*          The number of rows of the matrix A.  M >= 0. */
00082 
00083 /*  N       (input) INTEGER */
00084 /*          The number of columns of the matrix A.  N >= 0. */
00085 
00086 /*  NCC     (input) INTEGER */
00087 /*          The number of columns of the matrix C.  NCC >= 0. */
00088 
00089 /*  KL      (input) INTEGER */
00090 /*          The number of subdiagonals of the matrix A. KL >= 0. */
00091 
00092 /*  KU      (input) INTEGER */
00093 /*          The number of superdiagonals of the matrix A. KU >= 0. */
00094 
00095 /*  AB      (input/output) REAL array, dimension (LDAB,N) */
00096 /*          On entry, the m-by-n band matrix A, stored in rows 1 to */
00097 /*          KL+KU+1. The j-th column of A is stored in the j-th column of */
00098 /*          the array AB as follows: */
00099 /*          AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl). */
00100 /*          On exit, A is overwritten by values generated during the */
00101 /*          reduction. */
00102 
00103 /*  LDAB    (input) INTEGER */
00104 /*          The leading dimension of the array A. LDAB >= KL+KU+1. */
00105 
00106 /*  D       (output) REAL array, dimension (min(M,N)) */
00107 /*          The diagonal elements of the bidiagonal matrix B. */
00108 
00109 /*  E       (output) REAL array, dimension (min(M,N)-1) */
00110 /*          The superdiagonal elements of the bidiagonal matrix B. */
00111 
00112 /*  Q       (output) REAL array, dimension (LDQ,M) */
00113 /*          If VECT = 'Q' or 'B', the m-by-m orthogonal matrix Q. */
00114 /*          If VECT = 'N' or 'P', the array Q is not referenced. */
00115 
00116 /*  LDQ     (input) INTEGER */
00117 /*          The leading dimension of the array Q. */
00118 /*          LDQ >= max(1,M) if VECT = 'Q' or 'B'; LDQ >= 1 otherwise. */
00119 
00120 /*  PT      (output) REAL array, dimension (LDPT,N) */
00121 /*          If VECT = 'P' or 'B', the n-by-n orthogonal matrix P'. */
00122 /*          If VECT = 'N' or 'Q', the array PT is not referenced. */
00123 
00124 /*  LDPT    (input) INTEGER */
00125 /*          The leading dimension of the array PT. */
00126 /*          LDPT >= max(1,N) if VECT = 'P' or 'B'; LDPT >= 1 otherwise. */
00127 
00128 /*  C       (input/output) REAL array, dimension (LDC,NCC) */
00129 /*          On entry, an m-by-ncc matrix C. */
00130 /*          On exit, C is overwritten by Q'*C. */
00131 /*          C is not referenced if NCC = 0. */
00132 
00133 /*  LDC     (input) INTEGER */
00134 /*          The leading dimension of the array C. */
00135 /*          LDC >= max(1,M) if NCC > 0; LDC >= 1 if NCC = 0. */
00136 
00137 /*  WORK    (workspace) REAL array, dimension (2*max(M,N)) */
00138 
00139 /*  INFO    (output) INTEGER */
00140 /*          = 0:  successful exit. */
00141 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00142 
00143 /*  ===================================================================== */
00144 
00145 /*     .. Parameters .. */
00146 /*     .. */
00147 /*     .. Local Scalars .. */
00148 /*     .. */
00149 /*     .. External Subroutines .. */
00150 /*     .. */
00151 /*     .. Intrinsic Functions .. */
00152 /*     .. */
00153 /*     .. External Functions .. */
00154 /*     .. */
00155 /*     .. Executable Statements .. */
00156 
00157 /*     Test the input parameters */
00158 
00159     /* Parameter adjustments */
00160     ab_dim1 = *ldab;
00161     ab_offset = 1 + ab_dim1;
00162     ab -= ab_offset;
00163     --d__;
00164     --e;
00165     q_dim1 = *ldq;
00166     q_offset = 1 + q_dim1;
00167     q -= q_offset;
00168     pt_dim1 = *ldpt;
00169     pt_offset = 1 + pt_dim1;
00170     pt -= pt_offset;
00171     c_dim1 = *ldc;
00172     c_offset = 1 + c_dim1;
00173     c__ -= c_offset;
00174     --work;
00175 
00176     /* Function Body */
00177     wantb = lsame_(vect, "B");
00178     wantq = lsame_(vect, "Q") || wantb;
00179     wantpt = lsame_(vect, "P") || wantb;
00180     wantc = *ncc > 0;
00181     klu1 = *kl + *ku + 1;
00182     *info = 0;
00183     if (! wantq && ! wantpt && ! lsame_(vect, "N")) {
00184         *info = -1;
00185     } else if (*m < 0) {
00186         *info = -2;
00187     } else if (*n < 0) {
00188         *info = -3;
00189     } else if (*ncc < 0) {
00190         *info = -4;
00191     } else if (*kl < 0) {
00192         *info = -5;
00193     } else if (*ku < 0) {
00194         *info = -6;
00195     } else if (*ldab < klu1) {
00196         *info = -8;
00197     } else if (*ldq < 1 || wantq && *ldq < max(1,*m)) {
00198         *info = -12;
00199     } else if (*ldpt < 1 || wantpt && *ldpt < max(1,*n)) {
00200         *info = -14;
00201     } else if (*ldc < 1 || wantc && *ldc < max(1,*m)) {
00202         *info = -16;
00203     }
00204     if (*info != 0) {
00205         i__1 = -(*info);
00206         xerbla_("SGBBRD", &i__1);
00207         return 0;
00208     }
00209 
00210 /*     Initialize Q and P' to the unit matrix, if needed */
00211 
00212     if (wantq) {
00213         slaset_("Full", m, m, &c_b8, &c_b9, &q[q_offset], ldq);
00214     }
00215     if (wantpt) {
00216         slaset_("Full", n, n, &c_b8, &c_b9, &pt[pt_offset], ldpt);
00217     }
00218 
00219 /*     Quick return if possible. */
00220 
00221     if (*m == 0 || *n == 0) {
00222         return 0;
00223     }
00224 
00225     minmn = min(*m,*n);
00226 
00227     if (*kl + *ku > 1) {
00228 
00229 /*        Reduce to upper bidiagonal form if KU > 0; if KU = 0, reduce */
00230 /*        first to lower bidiagonal form and then transform to upper */
00231 /*        bidiagonal */
00232 
00233         if (*ku > 0) {
00234             ml0 = 1;
00235             mu0 = 2;
00236         } else {
00237             ml0 = 2;
00238             mu0 = 1;
00239         }
00240 
00241 /*        Wherever possible, plane rotations are generated and applied in */
00242 /*        vector operations of length NR over the index set J1:J2:KLU1. */
00243 
00244 /*        The sines of the plane rotations are stored in WORK(1:max(m,n)) */
00245 /*        and the cosines in WORK(max(m,n)+1:2*max(m,n)). */
00246 
00247         mn = max(*m,*n);
00248 /* Computing MIN */
00249         i__1 = *m - 1;
00250         klm = min(i__1,*kl);
00251 /* Computing MIN */
00252         i__1 = *n - 1;
00253         kun = min(i__1,*ku);
00254         kb = klm + kun;
00255         kb1 = kb + 1;
00256         inca = kb1 * *ldab;
00257         nr = 0;
00258         j1 = klm + 2;
00259         j2 = 1 - kun;
00260 
00261         i__1 = minmn;
00262         for (i__ = 1; i__ <= i__1; ++i__) {
00263 
00264 /*           Reduce i-th column and i-th row of matrix to bidiagonal form */
00265 
00266             ml = klm + 1;
00267             mu = kun + 1;
00268             i__2 = kb;
00269             for (kk = 1; kk <= i__2; ++kk) {
00270                 j1 += kb;
00271                 j2 += kb;
00272 
00273 /*              generate plane rotations to annihilate nonzero elements */
00274 /*              which have been created below the band */
00275 
00276                 if (nr > 0) {
00277                     slargv_(&nr, &ab[klu1 + (j1 - klm - 1) * ab_dim1], &inca, 
00278                             &work[j1], &kb1, &work[mn + j1], &kb1);
00279                 }
00280 
00281 /*              apply plane rotations from the left */
00282 
00283                 i__3 = kb;
00284                 for (l = 1; l <= i__3; ++l) {
00285                     if (j2 - klm + l - 1 > *n) {
00286                         nrt = nr - 1;
00287                     } else {
00288                         nrt = nr;
00289                     }
00290                     if (nrt > 0) {
00291                         slartv_(&nrt, &ab[klu1 - l + (j1 - klm + l - 1) * 
00292                                 ab_dim1], &inca, &ab[klu1 - l + 1 + (j1 - klm 
00293                                 + l - 1) * ab_dim1], &inca, &work[mn + j1], &
00294                                 work[j1], &kb1);
00295                     }
00296 /* L10: */
00297                 }
00298 
00299                 if (ml > ml0) {
00300                     if (ml <= *m - i__ + 1) {
00301 
00302 /*                    generate plane rotation to annihilate a(i+ml-1,i) */
00303 /*                    within the band, and apply rotation from the left */
00304 
00305                         slartg_(&ab[*ku + ml - 1 + i__ * ab_dim1], &ab[*ku + 
00306                                 ml + i__ * ab_dim1], &work[mn + i__ + ml - 1], 
00307                                  &work[i__ + ml - 1], &ra);
00308                         ab[*ku + ml - 1 + i__ * ab_dim1] = ra;
00309                         if (i__ < *n) {
00310 /* Computing MIN */
00311                             i__4 = *ku + ml - 2, i__5 = *n - i__;
00312                             i__3 = min(i__4,i__5);
00313                             i__6 = *ldab - 1;
00314                             i__7 = *ldab - 1;
00315                             srot_(&i__3, &ab[*ku + ml - 2 + (i__ + 1) * 
00316                                     ab_dim1], &i__6, &ab[*ku + ml - 1 + (i__ 
00317                                     + 1) * ab_dim1], &i__7, &work[mn + i__ + 
00318                                     ml - 1], &work[i__ + ml - 1]);
00319                         }
00320                     }
00321                     ++nr;
00322                     j1 -= kb1;
00323                 }
00324 
00325                 if (wantq) {
00326 
00327 /*                 accumulate product of plane rotations in Q */
00328 
00329                     i__3 = j2;
00330                     i__4 = kb1;
00331                     for (j = j1; i__4 < 0 ? j >= i__3 : j <= i__3; j += i__4) 
00332                             {
00333                         srot_(m, &q[(j - 1) * q_dim1 + 1], &c__1, &q[j * 
00334                                 q_dim1 + 1], &c__1, &work[mn + j], &work[j]);
00335 /* L20: */
00336                     }
00337                 }
00338 
00339                 if (wantc) {
00340 
00341 /*                 apply plane rotations to C */
00342 
00343                     i__4 = j2;
00344                     i__3 = kb1;
00345                     for (j = j1; i__3 < 0 ? j >= i__4 : j <= i__4; j += i__3) 
00346                             {
00347                         srot_(ncc, &c__[j - 1 + c_dim1], ldc, &c__[j + c_dim1]
00348 , ldc, &work[mn + j], &work[j]);
00349 /* L30: */
00350                     }
00351                 }
00352 
00353                 if (j2 + kun > *n) {
00354 
00355 /*                 adjust J2 to keep within the bounds of the matrix */
00356 
00357                     --nr;
00358                     j2 -= kb1;
00359                 }
00360 
00361                 i__3 = j2;
00362                 i__4 = kb1;
00363                 for (j = j1; i__4 < 0 ? j >= i__3 : j <= i__3; j += i__4) {
00364 
00365 /*                 create nonzero element a(j-1,j+ku) above the band */
00366 /*                 and store it in WORK(n+1:2*n) */
00367 
00368                     work[j + kun] = work[j] * ab[(j + kun) * ab_dim1 + 1];
00369                     ab[(j + kun) * ab_dim1 + 1] = work[mn + j] * ab[(j + kun) 
00370                             * ab_dim1 + 1];
00371 /* L40: */
00372                 }
00373 
00374 /*              generate plane rotations to annihilate nonzero elements */
00375 /*              which have been generated above the band */
00376 
00377                 if (nr > 0) {
00378                     slargv_(&nr, &ab[(j1 + kun - 1) * ab_dim1 + 1], &inca, &
00379                             work[j1 + kun], &kb1, &work[mn + j1 + kun], &kb1);
00380                 }
00381 
00382 /*              apply plane rotations from the right */
00383 
00384                 i__4 = kb;
00385                 for (l = 1; l <= i__4; ++l) {
00386                     if (j2 + l - 1 > *m) {
00387                         nrt = nr - 1;
00388                     } else {
00389                         nrt = nr;
00390                     }
00391                     if (nrt > 0) {
00392                         slartv_(&nrt, &ab[l + 1 + (j1 + kun - 1) * ab_dim1], &
00393                                 inca, &ab[l + (j1 + kun) * ab_dim1], &inca, &
00394                                 work[mn + j1 + kun], &work[j1 + kun], &kb1);
00395                     }
00396 /* L50: */
00397                 }
00398 
00399                 if (ml == ml0 && mu > mu0) {
00400                     if (mu <= *n - i__ + 1) {
00401 
00402 /*                    generate plane rotation to annihilate a(i,i+mu-1) */
00403 /*                    within the band, and apply rotation from the right */
00404 
00405                         slartg_(&ab[*ku - mu + 3 + (i__ + mu - 2) * ab_dim1], 
00406                                 &ab[*ku - mu + 2 + (i__ + mu - 1) * ab_dim1], 
00407                                 &work[mn + i__ + mu - 1], &work[i__ + mu - 1], 
00408                                  &ra);
00409                         ab[*ku - mu + 3 + (i__ + mu - 2) * ab_dim1] = ra;
00410 /* Computing MIN */
00411                         i__3 = *kl + mu - 2, i__5 = *m - i__;
00412                         i__4 = min(i__3,i__5);
00413                         srot_(&i__4, &ab[*ku - mu + 4 + (i__ + mu - 2) * 
00414                                 ab_dim1], &c__1, &ab[*ku - mu + 3 + (i__ + mu 
00415                                 - 1) * ab_dim1], &c__1, &work[mn + i__ + mu - 
00416                                 1], &work[i__ + mu - 1]);
00417                     }
00418                     ++nr;
00419                     j1 -= kb1;
00420                 }
00421 
00422                 if (wantpt) {
00423 
00424 /*                 accumulate product of plane rotations in P' */
00425 
00426                     i__4 = j2;
00427                     i__3 = kb1;
00428                     for (j = j1; i__3 < 0 ? j >= i__4 : j <= i__4; j += i__3) 
00429                             {
00430                         srot_(n, &pt[j + kun - 1 + pt_dim1], ldpt, &pt[j + 
00431                                 kun + pt_dim1], ldpt, &work[mn + j + kun], &
00432                                 work[j + kun]);
00433 /* L60: */
00434                     }
00435                 }
00436 
00437                 if (j2 + kb > *m) {
00438 
00439 /*                 adjust J2 to keep within the bounds of the matrix */
00440 
00441                     --nr;
00442                     j2 -= kb1;
00443                 }
00444 
00445                 i__3 = j2;
00446                 i__4 = kb1;
00447                 for (j = j1; i__4 < 0 ? j >= i__3 : j <= i__3; j += i__4) {
00448 
00449 /*                 create nonzero element a(j+kl+ku,j+ku-1) below the */
00450 /*                 band and store it in WORK(1:n) */
00451 
00452                     work[j + kb] = work[j + kun] * ab[klu1 + (j + kun) * 
00453                             ab_dim1];
00454                     ab[klu1 + (j + kun) * ab_dim1] = work[mn + j + kun] * ab[
00455                             klu1 + (j + kun) * ab_dim1];
00456 /* L70: */
00457                 }
00458 
00459                 if (ml > ml0) {
00460                     --ml;
00461                 } else {
00462                     --mu;
00463                 }
00464 /* L80: */
00465             }
00466 /* L90: */
00467         }
00468     }
00469 
00470     if (*ku == 0 && *kl > 0) {
00471 
00472 /*        A has been reduced to lower bidiagonal form */
00473 
00474 /*        Transform lower bidiagonal form to upper bidiagonal by applying */
00475 /*        plane rotations from the left, storing diagonal elements in D */
00476 /*        and off-diagonal elements in E */
00477 
00478 /* Computing MIN */
00479         i__2 = *m - 1;
00480         i__1 = min(i__2,*n);
00481         for (i__ = 1; i__ <= i__1; ++i__) {
00482             slartg_(&ab[i__ * ab_dim1 + 1], &ab[i__ * ab_dim1 + 2], &rc, &rs, 
00483                     &ra);
00484             d__[i__] = ra;
00485             if (i__ < *n) {
00486                 e[i__] = rs * ab[(i__ + 1) * ab_dim1 + 1];
00487                 ab[(i__ + 1) * ab_dim1 + 1] = rc * ab[(i__ + 1) * ab_dim1 + 1]
00488                         ;
00489             }
00490             if (wantq) {
00491                 srot_(m, &q[i__ * q_dim1 + 1], &c__1, &q[(i__ + 1) * q_dim1 + 
00492                         1], &c__1, &rc, &rs);
00493             }
00494             if (wantc) {
00495                 srot_(ncc, &c__[i__ + c_dim1], ldc, &c__[i__ + 1 + c_dim1], 
00496                         ldc, &rc, &rs);
00497             }
00498 /* L100: */
00499         }
00500         if (*m <= *n) {
00501             d__[*m] = ab[*m * ab_dim1 + 1];
00502         }
00503     } else if (*ku > 0) {
00504 
00505 /*        A has been reduced to upper bidiagonal form */
00506 
00507         if (*m < *n) {
00508 
00509 /*           Annihilate a(m,m+1) by applying plane rotations from the */
00510 /*           right, storing diagonal elements in D and off-diagonal */
00511 /*           elements in E */
00512 
00513             rb = ab[*ku + (*m + 1) * ab_dim1];
00514             for (i__ = *m; i__ >= 1; --i__) {
00515                 slartg_(&ab[*ku + 1 + i__ * ab_dim1], &rb, &rc, &rs, &ra);
00516                 d__[i__] = ra;
00517                 if (i__ > 1) {
00518                     rb = -rs * ab[*ku + i__ * ab_dim1];
00519                     e[i__ - 1] = rc * ab[*ku + i__ * ab_dim1];
00520                 }
00521                 if (wantpt) {
00522                     srot_(n, &pt[i__ + pt_dim1], ldpt, &pt[*m + 1 + pt_dim1], 
00523                             ldpt, &rc, &rs);
00524                 }
00525 /* L110: */
00526             }
00527         } else {
00528 
00529 /*           Copy off-diagonal elements to E and diagonal elements to D */
00530 
00531             i__1 = minmn - 1;
00532             for (i__ = 1; i__ <= i__1; ++i__) {
00533                 e[i__] = ab[*ku + (i__ + 1) * ab_dim1];
00534 /* L120: */
00535             }
00536             i__1 = minmn;
00537             for (i__ = 1; i__ <= i__1; ++i__) {
00538                 d__[i__] = ab[*ku + 1 + i__ * ab_dim1];
00539 /* L130: */
00540             }
00541         }
00542     } else {
00543 
00544 /*        A is diagonal. Set elements of E to zero and copy diagonal */
00545 /*        elements to D. */
00546 
00547         i__1 = minmn - 1;
00548         for (i__ = 1; i__ <= i__1; ++i__) {
00549             e[i__] = 0.f;
00550 /* L140: */
00551         }
00552         i__1 = minmn;
00553         for (i__ = 1; i__ <= i__1; ++i__) {
00554             d__[i__] = ab[i__ * ab_dim1 + 1];
00555 /* L150: */
00556         }
00557     }
00558     return 0;
00559 
00560 /*     End of SGBBRD */
00561 
00562 } /* sgbbrd_ */


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