zungbr.c
Go to the documentation of this file.
00001 /* zungbr.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 integer c__1 = 1;
00019 static integer c_n1 = -1;
00020 
00021 /* Subroutine */ int zungbr_(char *vect, integer *m, integer *n, integer *k, 
00022         doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
00023         work, integer *lwork, integer *info)
00024 {
00025     /* System generated locals */
00026     integer a_dim1, a_offset, i__1, i__2, i__3;
00027 
00028     /* Local variables */
00029     integer i__, j, nb, mn;
00030     extern logical lsame_(char *, char *);
00031     integer iinfo;
00032     logical wantq;
00033     extern /* Subroutine */ int xerbla_(char *, integer *);
00034     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00035             integer *, integer *);
00036     integer lwkopt;
00037     logical lquery;
00038     extern /* Subroutine */ int zunglq_(integer *, integer *, integer *, 
00039             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00040             integer *, integer *), zungqr_(integer *, integer *, integer *, 
00041             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00042             integer *, integer *);
00043 
00044 
00045 /*  -- LAPACK routine (version 3.2) -- */
00046 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00047 /*     November 2006 */
00048 
00049 /*     .. Scalar Arguments .. */
00050 /*     .. */
00051 /*     .. Array Arguments .. */
00052 /*     .. */
00053 
00054 /*  Purpose */
00055 /*  ======= */
00056 
00057 /*  ZUNGBR generates one of the complex unitary matrices Q or P**H */
00058 /*  determined by ZGEBRD when reducing a complex matrix A to bidiagonal */
00059 /*  form: A = Q * B * P**H.  Q and P**H are defined as products of */
00060 /*  elementary reflectors H(i) or G(i) respectively. */
00061 
00062 /*  If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q */
00063 /*  is of order M: */
00064 /*  if m >= k, Q = H(1) H(2) . . . H(k) and ZUNGBR returns the first n */
00065 /*  columns of Q, where m >= n >= k; */
00066 /*  if m < k, Q = H(1) H(2) . . . H(m-1) and ZUNGBR returns Q as an */
00067 /*  M-by-M matrix. */
00068 
00069 /*  If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**H */
00070 /*  is of order N: */
00071 /*  if k < n, P**H = G(k) . . . G(2) G(1) and ZUNGBR returns the first m */
00072 /*  rows of P**H, where n >= m >= k; */
00073 /*  if k >= n, P**H = G(n-1) . . . G(2) G(1) and ZUNGBR returns P**H as */
00074 /*  an N-by-N matrix. */
00075 
00076 /*  Arguments */
00077 /*  ========= */
00078 
00079 /*  VECT    (input) CHARACTER*1 */
00080 /*          Specifies whether the matrix Q or the matrix P**H is */
00081 /*          required, as defined in the transformation applied by ZGEBRD: */
00082 /*          = 'Q':  generate Q; */
00083 /*          = 'P':  generate P**H. */
00084 
00085 /*  M       (input) INTEGER */
00086 /*          The number of rows of the matrix Q or P**H to be returned. */
00087 /*          M >= 0. */
00088 
00089 /*  N       (input) INTEGER */
00090 /*          The number of columns of the matrix Q or P**H to be returned. */
00091 /*          N >= 0. */
00092 /*          If VECT = 'Q', M >= N >= min(M,K); */
00093 /*          if VECT = 'P', N >= M >= min(N,K). */
00094 
00095 /*  K       (input) INTEGER */
00096 /*          If VECT = 'Q', the number of columns in the original M-by-K */
00097 /*          matrix reduced by ZGEBRD. */
00098 /*          If VECT = 'P', the number of rows in the original K-by-N */
00099 /*          matrix reduced by ZGEBRD. */
00100 /*          K >= 0. */
00101 
00102 /*  A       (input/output) COMPLEX*16 array, dimension (LDA,N) */
00103 /*          On entry, the vectors which define the elementary reflectors, */
00104 /*          as returned by ZGEBRD. */
00105 /*          On exit, the M-by-N matrix Q or P**H. */
00106 
00107 /*  LDA     (input) INTEGER */
00108 /*          The leading dimension of the array A. LDA >= M. */
00109 
00110 /*  TAU     (input) COMPLEX*16 array, dimension */
00111 /*                                (min(M,K)) if VECT = 'Q' */
00112 /*                                (min(N,K)) if VECT = 'P' */
00113 /*          TAU(i) must contain the scalar factor of the elementary */
00114 /*          reflector H(i) or G(i), which determines Q or P**H, as */
00115 /*          returned by ZGEBRD in its array argument TAUQ or TAUP. */
00116 
00117 /*  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK)) */
00118 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
00119 
00120 /*  LWORK   (input) INTEGER */
00121 /*          The dimension of the array WORK. LWORK >= max(1,min(M,N)). */
00122 /*          For optimum performance LWORK >= min(M,N)*NB, where NB */
00123 /*          is the optimal blocksize. */
00124 
00125 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00126 /*          only calculates the optimal size of the WORK array, returns */
00127 /*          this value as the first entry of the WORK array, and no error */
00128 /*          message related to LWORK is issued by XERBLA. */
00129 
00130 /*  INFO    (output) INTEGER */
00131 /*          = 0:  successful exit */
00132 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00133 
00134 /*  ===================================================================== */
00135 
00136 /*     .. Parameters .. */
00137 /*     .. */
00138 /*     .. Local Scalars .. */
00139 /*     .. */
00140 /*     .. External Functions .. */
00141 /*     .. */
00142 /*     .. External Subroutines .. */
00143 /*     .. */
00144 /*     .. Intrinsic Functions .. */
00145 /*     .. */
00146 /*     .. Executable Statements .. */
00147 
00148 /*     Test the input arguments */
00149 
00150     /* Parameter adjustments */
00151     a_dim1 = *lda;
00152     a_offset = 1 + a_dim1;
00153     a -= a_offset;
00154     --tau;
00155     --work;
00156 
00157     /* Function Body */
00158     *info = 0;
00159     wantq = lsame_(vect, "Q");
00160     mn = min(*m,*n);
00161     lquery = *lwork == -1;
00162     if (! wantq && ! lsame_(vect, "P")) {
00163         *info = -1;
00164     } else if (*m < 0) {
00165         *info = -2;
00166     } else if (*n < 0 || wantq && (*n > *m || *n < min(*m,*k)) || ! wantq && (
00167             *m > *n || *m < min(*n,*k))) {
00168         *info = -3;
00169     } else if (*k < 0) {
00170         *info = -4;
00171     } else if (*lda < max(1,*m)) {
00172         *info = -6;
00173     } else if (*lwork < max(1,mn) && ! lquery) {
00174         *info = -9;
00175     }
00176 
00177     if (*info == 0) {
00178         if (wantq) {
00179             nb = ilaenv_(&c__1, "ZUNGQR", " ", m, n, k, &c_n1);
00180         } else {
00181             nb = ilaenv_(&c__1, "ZUNGLQ", " ", m, n, k, &c_n1);
00182         }
00183         lwkopt = max(1,mn) * nb;
00184         work[1].r = (doublereal) lwkopt, work[1].i = 0.;
00185     }
00186 
00187     if (*info != 0) {
00188         i__1 = -(*info);
00189         xerbla_("ZUNGBR", &i__1);
00190         return 0;
00191     } else if (lquery) {
00192         return 0;
00193     }
00194 
00195 /*     Quick return if possible */
00196 
00197     if (*m == 0 || *n == 0) {
00198         work[1].r = 1., work[1].i = 0.;
00199         return 0;
00200     }
00201 
00202     if (wantq) {
00203 
00204 /*        Form Q, determined by a call to ZGEBRD to reduce an m-by-k */
00205 /*        matrix */
00206 
00207         if (*m >= *k) {
00208 
00209 /*           If m >= k, assume m >= n >= k */
00210 
00211             zungqr_(m, n, k, &a[a_offset], lda, &tau[1], &work[1], lwork, &
00212                     iinfo);
00213 
00214         } else {
00215 
00216 /*           If m < k, assume m = n */
00217 
00218 /*           Shift the vectors which define the elementary reflectors one */
00219 /*           column to the right, and set the first row and column of Q */
00220 /*           to those of the unit matrix */
00221 
00222             for (j = *m; j >= 2; --j) {
00223                 i__1 = j * a_dim1 + 1;
00224                 a[i__1].r = 0., a[i__1].i = 0.;
00225                 i__1 = *m;
00226                 for (i__ = j + 1; i__ <= i__1; ++i__) {
00227                     i__2 = i__ + j * a_dim1;
00228                     i__3 = i__ + (j - 1) * a_dim1;
00229                     a[i__2].r = a[i__3].r, a[i__2].i = a[i__3].i;
00230 /* L10: */
00231                 }
00232 /* L20: */
00233             }
00234             i__1 = a_dim1 + 1;
00235             a[i__1].r = 1., a[i__1].i = 0.;
00236             i__1 = *m;
00237             for (i__ = 2; i__ <= i__1; ++i__) {
00238                 i__2 = i__ + a_dim1;
00239                 a[i__2].r = 0., a[i__2].i = 0.;
00240 /* L30: */
00241             }
00242             if (*m > 1) {
00243 
00244 /*              Form Q(2:m,2:m) */
00245 
00246                 i__1 = *m - 1;
00247                 i__2 = *m - 1;
00248                 i__3 = *m - 1;
00249                 zungqr_(&i__1, &i__2, &i__3, &a[(a_dim1 << 1) + 2], lda, &tau[
00250                         1], &work[1], lwork, &iinfo);
00251             }
00252         }
00253     } else {
00254 
00255 /*        Form P', determined by a call to ZGEBRD to reduce a k-by-n */
00256 /*        matrix */
00257 
00258         if (*k < *n) {
00259 
00260 /*           If k < n, assume k <= m <= n */
00261 
00262             zunglq_(m, n, k, &a[a_offset], lda, &tau[1], &work[1], lwork, &
00263                     iinfo);
00264 
00265         } else {
00266 
00267 /*           If k >= n, assume m = n */
00268 
00269 /*           Shift the vectors which define the elementary reflectors one */
00270 /*           row downward, and set the first row and column of P' to */
00271 /*           those of the unit matrix */
00272 
00273             i__1 = a_dim1 + 1;
00274             a[i__1].r = 1., a[i__1].i = 0.;
00275             i__1 = *n;
00276             for (i__ = 2; i__ <= i__1; ++i__) {
00277                 i__2 = i__ + a_dim1;
00278                 a[i__2].r = 0., a[i__2].i = 0.;
00279 /* L40: */
00280             }
00281             i__1 = *n;
00282             for (j = 2; j <= i__1; ++j) {
00283                 for (i__ = j - 1; i__ >= 2; --i__) {
00284                     i__2 = i__ + j * a_dim1;
00285                     i__3 = i__ - 1 + j * a_dim1;
00286                     a[i__2].r = a[i__3].r, a[i__2].i = a[i__3].i;
00287 /* L50: */
00288                 }
00289                 i__2 = j * a_dim1 + 1;
00290                 a[i__2].r = 0., a[i__2].i = 0.;
00291 /* L60: */
00292             }
00293             if (*n > 1) {
00294 
00295 /*              Form P'(2:n,2:n) */
00296 
00297                 i__1 = *n - 1;
00298                 i__2 = *n - 1;
00299                 i__3 = *n - 1;
00300                 zunglq_(&i__1, &i__2, &i__3, &a[(a_dim1 << 1) + 2], lda, &tau[
00301                         1], &work[1], lwork, &iinfo);
00302             }
00303         }
00304     }
00305     work[1].r = (doublereal) lwkopt, work[1].i = 0.;
00306     return 0;
00307 
00308 /*     End of ZUNGBR */
00309 
00310 } /* zungbr_ */


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