00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016
00017
00018 static doublecomplex c_b1 = {0.,0.};
00019 static doublecomplex c_b2 = {1.,0.};
00020
00021 int zggsvp_(char *jobu, char *jobv, char *jobq, integer *m,
00022 integer *p, integer *n, doublecomplex *a, integer *lda, doublecomplex
00023 *b, integer *ldb, doublereal *tola, doublereal *tolb, integer *k,
00024 integer *l, doublecomplex *u, integer *ldu, doublecomplex *v, integer
00025 *ldv, doublecomplex *q, integer *ldq, integer *iwork, doublereal *
00026 rwork, doublecomplex *tau, doublecomplex *work, integer *info)
00027 {
00028
00029 integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, u_dim1,
00030 u_offset, v_dim1, v_offset, i__1, i__2, i__3;
00031 doublereal d__1, d__2;
00032
00033
00034 double d_imag(doublecomplex *);
00035
00036
00037 integer i__, j;
00038 extern logical lsame_(char *, char *);
00039 logical wantq, wantu, wantv;
00040 extern int zgeqr2_(integer *, integer *, doublecomplex *,
00041 integer *, doublecomplex *, doublecomplex *, integer *), zgerq2_(
00042 integer *, integer *, doublecomplex *, integer *, doublecomplex *,
00043 doublecomplex *, integer *), zung2r_(integer *, integer *,
00044 integer *, doublecomplex *, integer *, doublecomplex *,
00045 doublecomplex *, integer *), zunm2r_(char *, char *, integer *,
00046 integer *, integer *, doublecomplex *, integer *, doublecomplex *,
00047 doublecomplex *, integer *, doublecomplex *, integer *), zunmr2_(char *, char *, integer *, integer *, integer *,
00048 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00049 integer *, doublecomplex *, integer *), xerbla_(
00050 char *, integer *), zgeqpf_(integer *, integer *,
00051 doublecomplex *, integer *, integer *, doublecomplex *,
00052 doublecomplex *, doublereal *, integer *), zlacpy_(char *,
00053 integer *, integer *, doublecomplex *, integer *, doublecomplex *,
00054 integer *);
00055 logical forwrd;
00056 extern int zlaset_(char *, integer *, integer *,
00057 doublecomplex *, doublecomplex *, doublecomplex *, integer *), zlapmt_(logical *, integer *, integer *, doublecomplex *,
00058 integer *, integer *);
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 a_dim1 = *lda;
00219 a_offset = 1 + a_dim1;
00220 a -= a_offset;
00221 b_dim1 = *ldb;
00222 b_offset = 1 + b_dim1;
00223 b -= b_offset;
00224 u_dim1 = *ldu;
00225 u_offset = 1 + u_dim1;
00226 u -= u_offset;
00227 v_dim1 = *ldv;
00228 v_offset = 1 + v_dim1;
00229 v -= v_offset;
00230 q_dim1 = *ldq;
00231 q_offset = 1 + q_dim1;
00232 q -= q_offset;
00233 --iwork;
00234 --rwork;
00235 --tau;
00236 --work;
00237
00238
00239 wantu = lsame_(jobu, "U");
00240 wantv = lsame_(jobv, "V");
00241 wantq = lsame_(jobq, "Q");
00242 forwrd = TRUE_;
00243
00244 *info = 0;
00245 if (! (wantu || lsame_(jobu, "N"))) {
00246 *info = -1;
00247 } else if (! (wantv || lsame_(jobv, "N"))) {
00248 *info = -2;
00249 } else if (! (wantq || lsame_(jobq, "N"))) {
00250 *info = -3;
00251 } else if (*m < 0) {
00252 *info = -4;
00253 } else if (*p < 0) {
00254 *info = -5;
00255 } else if (*n < 0) {
00256 *info = -6;
00257 } else if (*lda < max(1,*m)) {
00258 *info = -8;
00259 } else if (*ldb < max(1,*p)) {
00260 *info = -10;
00261 } else if (*ldu < 1 || wantu && *ldu < *m) {
00262 *info = -16;
00263 } else if (*ldv < 1 || wantv && *ldv < *p) {
00264 *info = -18;
00265 } else if (*ldq < 1 || wantq && *ldq < *n) {
00266 *info = -20;
00267 }
00268 if (*info != 0) {
00269 i__1 = -(*info);
00270 xerbla_("ZGGSVP", &i__1);
00271 return 0;
00272 }
00273
00274
00275
00276
00277 i__1 = *n;
00278 for (i__ = 1; i__ <= i__1; ++i__) {
00279 iwork[i__] = 0;
00280
00281 }
00282 zgeqpf_(p, n, &b[b_offset], ldb, &iwork[1], &tau[1], &work[1], &rwork[1],
00283 info);
00284
00285
00286
00287 zlapmt_(&forwrd, m, n, &a[a_offset], lda, &iwork[1]);
00288
00289
00290
00291 *l = 0;
00292 i__1 = min(*p,*n);
00293 for (i__ = 1; i__ <= i__1; ++i__) {
00294 i__2 = i__ + i__ * b_dim1;
00295 if ((d__1 = b[i__2].r, abs(d__1)) + (d__2 = d_imag(&b[i__ + i__ *
00296 b_dim1]), abs(d__2)) > *tolb) {
00297 ++(*l);
00298 }
00299
00300 }
00301
00302 if (wantv) {
00303
00304
00305
00306 zlaset_("Full", p, p, &c_b1, &c_b1, &v[v_offset], ldv);
00307 if (*p > 1) {
00308 i__1 = *p - 1;
00309 zlacpy_("Lower", &i__1, n, &b[b_dim1 + 2], ldb, &v[v_dim1 + 2],
00310 ldv);
00311 }
00312 i__1 = min(*p,*n);
00313 zung2r_(p, p, &i__1, &v[v_offset], ldv, &tau[1], &work[1], info);
00314 }
00315
00316
00317
00318 i__1 = *l - 1;
00319 for (j = 1; j <= i__1; ++j) {
00320 i__2 = *l;
00321 for (i__ = j + 1; i__ <= i__2; ++i__) {
00322 i__3 = i__ + j * b_dim1;
00323 b[i__3].r = 0., b[i__3].i = 0.;
00324
00325 }
00326
00327 }
00328 if (*p > *l) {
00329 i__1 = *p - *l;
00330 zlaset_("Full", &i__1, n, &c_b1, &c_b1, &b[*l + 1 + b_dim1], ldb);
00331 }
00332
00333 if (wantq) {
00334
00335
00336
00337 zlaset_("Full", n, n, &c_b1, &c_b2, &q[q_offset], ldq);
00338 zlapmt_(&forwrd, n, n, &q[q_offset], ldq, &iwork[1]);
00339 }
00340
00341 if (*p >= *l && *n != *l) {
00342
00343
00344
00345 zgerq2_(l, n, &b[b_offset], ldb, &tau[1], &work[1], info);
00346
00347
00348
00349 zunmr2_("Right", "Conjugate transpose", m, n, l, &b[b_offset], ldb, &
00350 tau[1], &a[a_offset], lda, &work[1], info);
00351 if (wantq) {
00352
00353
00354
00355 zunmr2_("Right", "Conjugate transpose", n, n, l, &b[b_offset],
00356 ldb, &tau[1], &q[q_offset], ldq, &work[1], info);
00357 }
00358
00359
00360
00361 i__1 = *n - *l;
00362 zlaset_("Full", l, &i__1, &c_b1, &c_b1, &b[b_offset], ldb);
00363 i__1 = *n;
00364 for (j = *n - *l + 1; j <= i__1; ++j) {
00365 i__2 = *l;
00366 for (i__ = j - *n + *l + 1; i__ <= i__2; ++i__) {
00367 i__3 = i__ + j * b_dim1;
00368 b[i__3].r = 0., b[i__3].i = 0.;
00369
00370 }
00371
00372 }
00373
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 i__1 = *n - *l;
00385 for (i__ = 1; i__ <= i__1; ++i__) {
00386 iwork[i__] = 0;
00387
00388 }
00389 i__1 = *n - *l;
00390 zgeqpf_(m, &i__1, &a[a_offset], lda, &iwork[1], &tau[1], &work[1], &rwork[
00391 1], info);
00392
00393
00394
00395 *k = 0;
00396
00397 i__2 = *m, i__3 = *n - *l;
00398 i__1 = min(i__2,i__3);
00399 for (i__ = 1; i__ <= i__1; ++i__) {
00400 i__2 = i__ + i__ * a_dim1;
00401 if ((d__1 = a[i__2].r, abs(d__1)) + (d__2 = d_imag(&a[i__ + i__ *
00402 a_dim1]), abs(d__2)) > *tola) {
00403 ++(*k);
00404 }
00405
00406 }
00407
00408
00409
00410
00411 i__2 = *m, i__3 = *n - *l;
00412 i__1 = min(i__2,i__3);
00413 zunm2r_("Left", "Conjugate transpose", m, l, &i__1, &a[a_offset], lda, &
00414 tau[1], &a[(*n - *l + 1) * a_dim1 + 1], lda, &work[1], info);
00415
00416 if (wantu) {
00417
00418
00419
00420 zlaset_("Full", m, m, &c_b1, &c_b1, &u[u_offset], ldu);
00421 if (*m > 1) {
00422 i__1 = *m - 1;
00423 i__2 = *n - *l;
00424 zlacpy_("Lower", &i__1, &i__2, &a[a_dim1 + 2], lda, &u[u_dim1 + 2]
00425 , ldu);
00426 }
00427
00428 i__2 = *m, i__3 = *n - *l;
00429 i__1 = min(i__2,i__3);
00430 zung2r_(m, m, &i__1, &u[u_offset], ldu, &tau[1], &work[1], info);
00431 }
00432
00433 if (wantq) {
00434
00435
00436
00437 i__1 = *n - *l;
00438 zlapmt_(&forwrd, n, &i__1, &q[q_offset], ldq, &iwork[1]);
00439 }
00440
00441
00442
00443
00444 i__1 = *k - 1;
00445 for (j = 1; j <= i__1; ++j) {
00446 i__2 = *k;
00447 for (i__ = j + 1; i__ <= i__2; ++i__) {
00448 i__3 = i__ + j * a_dim1;
00449 a[i__3].r = 0., a[i__3].i = 0.;
00450
00451 }
00452
00453 }
00454 if (*m > *k) {
00455 i__1 = *m - *k;
00456 i__2 = *n - *l;
00457 zlaset_("Full", &i__1, &i__2, &c_b1, &c_b1, &a[*k + 1 + a_dim1], lda);
00458 }
00459
00460 if (*n - *l > *k) {
00461
00462
00463
00464 i__1 = *n - *l;
00465 zgerq2_(k, &i__1, &a[a_offset], lda, &tau[1], &work[1], info);
00466
00467 if (wantq) {
00468
00469
00470
00471 i__1 = *n - *l;
00472 zunmr2_("Right", "Conjugate transpose", n, &i__1, k, &a[a_offset],
00473 lda, &tau[1], &q[q_offset], ldq, &work[1], info);
00474 }
00475
00476
00477
00478 i__1 = *n - *l - *k;
00479 zlaset_("Full", k, &i__1, &c_b1, &c_b1, &a[a_offset], lda);
00480 i__1 = *n - *l;
00481 for (j = *n - *l - *k + 1; j <= i__1; ++j) {
00482 i__2 = *k;
00483 for (i__ = j - *n + *l + *k + 1; i__ <= i__2; ++i__) {
00484 i__3 = i__ + j * a_dim1;
00485 a[i__3].r = 0., a[i__3].i = 0.;
00486
00487 }
00488
00489 }
00490
00491 }
00492
00493 if (*m > *k) {
00494
00495
00496
00497 i__1 = *m - *k;
00498 zgeqr2_(&i__1, l, &a[*k + 1 + (*n - *l + 1) * a_dim1], lda, &tau[1], &
00499 work[1], info);
00500
00501 if (wantu) {
00502
00503
00504
00505 i__1 = *m - *k;
00506
00507 i__3 = *m - *k;
00508 i__2 = min(i__3,*l);
00509 zunm2r_("Right", "No transpose", m, &i__1, &i__2, &a[*k + 1 + (*n
00510 - *l + 1) * a_dim1], lda, &tau[1], &u[(*k + 1) * u_dim1 +
00511 1], ldu, &work[1], info);
00512 }
00513
00514
00515
00516 i__1 = *n;
00517 for (j = *n - *l + 1; j <= i__1; ++j) {
00518 i__2 = *m;
00519 for (i__ = j - *n + *k + *l + 1; i__ <= i__2; ++i__) {
00520 i__3 = i__ + j * a_dim1;
00521 a[i__3].r = 0., a[i__3].i = 0.;
00522
00523 }
00524
00525 }
00526
00527 }
00528
00529 return 0;
00530
00531
00532
00533 }