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 doublereal c_b12 = 0.;
00019 static doublereal c_b22 = 1.;
00020
00021 int dggsvp_(char *jobu, char *jobv, char *jobq, integer *m,
00022 integer *p, integer *n, doublereal *a, integer *lda, doublereal *b,
00023 integer *ldb, doublereal *tola, doublereal *tolb, integer *k, integer
00024 *l, doublereal *u, integer *ldu, doublereal *v, integer *ldv,
00025 doublereal *q, integer *ldq, integer *iwork, doublereal *tau,
00026 doublereal *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;
00032
00033
00034 integer i__, j;
00035 extern logical lsame_(char *, char *);
00036 logical wantq, wantu, wantv;
00037 extern int dgeqr2_(integer *, integer *, doublereal *,
00038 integer *, doublereal *, doublereal *, integer *), dgerq2_(
00039 integer *, integer *, doublereal *, integer *, doublereal *,
00040 doublereal *, integer *), dorg2r_(integer *, integer *, integer *,
00041 doublereal *, integer *, doublereal *, doublereal *, integer *),
00042 dorm2r_(char *, char *, integer *, integer *, integer *,
00043 doublereal *, integer *, doublereal *, doublereal *, integer *,
00044 doublereal *, integer *), dormr2_(char *, char *,
00045 integer *, integer *, integer *, doublereal *, integer *,
00046 doublereal *, doublereal *, integer *, doublereal *, integer *), dgeqpf_(integer *, integer *, doublereal *,
00047 integer *, integer *, doublereal *, doublereal *, integer *),
00048 dlacpy_(char *, integer *, integer *, doublereal *, integer *,
00049 doublereal *, integer *), dlaset_(char *, integer *,
00050 integer *, doublereal *, doublereal *, doublereal *, integer *), xerbla_(char *, integer *), dlapmt_(logical *,
00051 integer *, integer *, doublereal *, integer *, integer *);
00052 logical forwrd;
00053
00054
00055
00056
00057
00058
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 a_dim1 = *lda;
00208 a_offset = 1 + a_dim1;
00209 a -= a_offset;
00210 b_dim1 = *ldb;
00211 b_offset = 1 + b_dim1;
00212 b -= b_offset;
00213 u_dim1 = *ldu;
00214 u_offset = 1 + u_dim1;
00215 u -= u_offset;
00216 v_dim1 = *ldv;
00217 v_offset = 1 + v_dim1;
00218 v -= v_offset;
00219 q_dim1 = *ldq;
00220 q_offset = 1 + q_dim1;
00221 q -= q_offset;
00222 --iwork;
00223 --tau;
00224 --work;
00225
00226
00227 wantu = lsame_(jobu, "U");
00228 wantv = lsame_(jobv, "V");
00229 wantq = lsame_(jobq, "Q");
00230 forwrd = TRUE_;
00231
00232 *info = 0;
00233 if (! (wantu || lsame_(jobu, "N"))) {
00234 *info = -1;
00235 } else if (! (wantv || lsame_(jobv, "N"))) {
00236 *info = -2;
00237 } else if (! (wantq || lsame_(jobq, "N"))) {
00238 *info = -3;
00239 } else if (*m < 0) {
00240 *info = -4;
00241 } else if (*p < 0) {
00242 *info = -5;
00243 } else if (*n < 0) {
00244 *info = -6;
00245 } else if (*lda < max(1,*m)) {
00246 *info = -8;
00247 } else if (*ldb < max(1,*p)) {
00248 *info = -10;
00249 } else if (*ldu < 1 || wantu && *ldu < *m) {
00250 *info = -16;
00251 } else if (*ldv < 1 || wantv && *ldv < *p) {
00252 *info = -18;
00253 } else if (*ldq < 1 || wantq && *ldq < *n) {
00254 *info = -20;
00255 }
00256 if (*info != 0) {
00257 i__1 = -(*info);
00258 xerbla_("DGGSVP", &i__1);
00259 return 0;
00260 }
00261
00262
00263
00264
00265 i__1 = *n;
00266 for (i__ = 1; i__ <= i__1; ++i__) {
00267 iwork[i__] = 0;
00268
00269 }
00270 dgeqpf_(p, n, &b[b_offset], ldb, &iwork[1], &tau[1], &work[1], info);
00271
00272
00273
00274 dlapmt_(&forwrd, m, n, &a[a_offset], lda, &iwork[1]);
00275
00276
00277
00278 *l = 0;
00279 i__1 = min(*p,*n);
00280 for (i__ = 1; i__ <= i__1; ++i__) {
00281 if ((d__1 = b[i__ + i__ * b_dim1], abs(d__1)) > *tolb) {
00282 ++(*l);
00283 }
00284
00285 }
00286
00287 if (wantv) {
00288
00289
00290
00291 dlaset_("Full", p, p, &c_b12, &c_b12, &v[v_offset], ldv);
00292 if (*p > 1) {
00293 i__1 = *p - 1;
00294 dlacpy_("Lower", &i__1, n, &b[b_dim1 + 2], ldb, &v[v_dim1 + 2],
00295 ldv);
00296 }
00297 i__1 = min(*p,*n);
00298 dorg2r_(p, p, &i__1, &v[v_offset], ldv, &tau[1], &work[1], info);
00299 }
00300
00301
00302
00303 i__1 = *l - 1;
00304 for (j = 1; j <= i__1; ++j) {
00305 i__2 = *l;
00306 for (i__ = j + 1; i__ <= i__2; ++i__) {
00307 b[i__ + j * b_dim1] = 0.;
00308
00309 }
00310
00311 }
00312 if (*p > *l) {
00313 i__1 = *p - *l;
00314 dlaset_("Full", &i__1, n, &c_b12, &c_b12, &b[*l + 1 + b_dim1], ldb);
00315 }
00316
00317 if (wantq) {
00318
00319
00320
00321 dlaset_("Full", n, n, &c_b12, &c_b22, &q[q_offset], ldq);
00322 dlapmt_(&forwrd, n, n, &q[q_offset], ldq, &iwork[1]);
00323 }
00324
00325 if (*p >= *l && *n != *l) {
00326
00327
00328
00329 dgerq2_(l, n, &b[b_offset], ldb, &tau[1], &work[1], info);
00330
00331
00332
00333 dormr2_("Right", "Transpose", m, n, l, &b[b_offset], ldb, &tau[1], &a[
00334 a_offset], lda, &work[1], info);
00335
00336 if (wantq) {
00337
00338
00339
00340 dormr2_("Right", "Transpose", n, n, l, &b[b_offset], ldb, &tau[1],
00341 &q[q_offset], ldq, &work[1], info);
00342 }
00343
00344
00345
00346 i__1 = *n - *l;
00347 dlaset_("Full", l, &i__1, &c_b12, &c_b12, &b[b_offset], ldb);
00348 i__1 = *n;
00349 for (j = *n - *l + 1; j <= i__1; ++j) {
00350 i__2 = *l;
00351 for (i__ = j - *n + *l + 1; i__ <= i__2; ++i__) {
00352 b[i__ + j * b_dim1] = 0.;
00353
00354 }
00355
00356 }
00357
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 i__1 = *n - *l;
00369 for (i__ = 1; i__ <= i__1; ++i__) {
00370 iwork[i__] = 0;
00371
00372 }
00373 i__1 = *n - *l;
00374 dgeqpf_(m, &i__1, &a[a_offset], lda, &iwork[1], &tau[1], &work[1], info);
00375
00376
00377
00378 *k = 0;
00379
00380 i__2 = *m, i__3 = *n - *l;
00381 i__1 = min(i__2,i__3);
00382 for (i__ = 1; i__ <= i__1; ++i__) {
00383 if ((d__1 = a[i__ + i__ * a_dim1], abs(d__1)) > *tola) {
00384 ++(*k);
00385 }
00386
00387 }
00388
00389
00390
00391
00392 i__2 = *m, i__3 = *n - *l;
00393 i__1 = min(i__2,i__3);
00394 dorm2r_("Left", "Transpose", m, l, &i__1, &a[a_offset], lda, &tau[1], &a[(
00395 *n - *l + 1) * a_dim1 + 1], lda, &work[1], info);
00396
00397 if (wantu) {
00398
00399
00400
00401 dlaset_("Full", m, m, &c_b12, &c_b12, &u[u_offset], ldu);
00402 if (*m > 1) {
00403 i__1 = *m - 1;
00404 i__2 = *n - *l;
00405 dlacpy_("Lower", &i__1, &i__2, &a[a_dim1 + 2], lda, &u[u_dim1 + 2]
00406 , ldu);
00407 }
00408
00409 i__2 = *m, i__3 = *n - *l;
00410 i__1 = min(i__2,i__3);
00411 dorg2r_(m, m, &i__1, &u[u_offset], ldu, &tau[1], &work[1], info);
00412 }
00413
00414 if (wantq) {
00415
00416
00417
00418 i__1 = *n - *l;
00419 dlapmt_(&forwrd, n, &i__1, &q[q_offset], ldq, &iwork[1]);
00420 }
00421
00422
00423
00424
00425 i__1 = *k - 1;
00426 for (j = 1; j <= i__1; ++j) {
00427 i__2 = *k;
00428 for (i__ = j + 1; i__ <= i__2; ++i__) {
00429 a[i__ + j * a_dim1] = 0.;
00430
00431 }
00432
00433 }
00434 if (*m > *k) {
00435 i__1 = *m - *k;
00436 i__2 = *n - *l;
00437 dlaset_("Full", &i__1, &i__2, &c_b12, &c_b12, &a[*k + 1 + a_dim1],
00438 lda);
00439 }
00440
00441 if (*n - *l > *k) {
00442
00443
00444
00445 i__1 = *n - *l;
00446 dgerq2_(k, &i__1, &a[a_offset], lda, &tau[1], &work[1], info);
00447
00448 if (wantq) {
00449
00450
00451
00452 i__1 = *n - *l;
00453 dormr2_("Right", "Transpose", n, &i__1, k, &a[a_offset], lda, &
00454 tau[1], &q[q_offset], ldq, &work[1], info);
00455 }
00456
00457
00458
00459 i__1 = *n - *l - *k;
00460 dlaset_("Full", k, &i__1, &c_b12, &c_b12, &a[a_offset], lda);
00461 i__1 = *n - *l;
00462 for (j = *n - *l - *k + 1; j <= i__1; ++j) {
00463 i__2 = *k;
00464 for (i__ = j - *n + *l + *k + 1; i__ <= i__2; ++i__) {
00465 a[i__ + j * a_dim1] = 0.;
00466
00467 }
00468
00469 }
00470
00471 }
00472
00473 if (*m > *k) {
00474
00475
00476
00477 i__1 = *m - *k;
00478 dgeqr2_(&i__1, l, &a[*k + 1 + (*n - *l + 1) * a_dim1], lda, &tau[1], &
00479 work[1], info);
00480
00481 if (wantu) {
00482
00483
00484
00485 i__1 = *m - *k;
00486
00487 i__3 = *m - *k;
00488 i__2 = min(i__3,*l);
00489 dorm2r_("Right", "No transpose", m, &i__1, &i__2, &a[*k + 1 + (*n
00490 - *l + 1) * a_dim1], lda, &tau[1], &u[(*k + 1) * u_dim1 +
00491 1], ldu, &work[1], info);
00492 }
00493
00494
00495
00496 i__1 = *n;
00497 for (j = *n - *l + 1; j <= i__1; ++j) {
00498 i__2 = *m;
00499 for (i__ = j - *n + *k + *l + 1; i__ <= i__2; ++i__) {
00500 a[i__ + j * a_dim1] = 0.;
00501
00502 }
00503
00504 }
00505
00506 }
00507
00508 return 0;
00509
00510
00511
00512 }