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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:43