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_b13 = 0.;
00019 static doublereal c_b14 = 1.;
00020 static integer c__1 = 1;
00021 static doublereal c_b43 = -1.;
00022
00023 int dtgsja_(char *jobu, char *jobv, char *jobq, integer *m,
00024 integer *p, integer *n, integer *k, integer *l, doublereal *a,
00025 integer *lda, doublereal *b, integer *ldb, doublereal *tola,
00026 doublereal *tolb, doublereal *alpha, doublereal *beta, doublereal *u,
00027 integer *ldu, doublereal *v, integer *ldv, doublereal *q, integer *
00028 ldq, doublereal *work, integer *ncycle, integer *info)
00029 {
00030
00031 integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, u_dim1,
00032 u_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4;
00033 doublereal d__1;
00034
00035
00036 integer i__, j;
00037 doublereal a1, a2, a3, b1, b2, b3, csq, csu, csv, snq, rwk, snu, snv;
00038 extern int drot_(integer *, doublereal *, integer *,
00039 doublereal *, integer *, doublereal *, doublereal *);
00040 doublereal gamma;
00041 extern int dscal_(integer *, doublereal *, doublereal *,
00042 integer *);
00043 extern logical lsame_(char *, char *);
00044 extern int dcopy_(integer *, doublereal *, integer *,
00045 doublereal *, integer *);
00046 logical initq, initu, initv, wantq, upper;
00047 doublereal error, ssmin;
00048 logical wantu, wantv;
00049 extern int dlags2_(logical *, doublereal *, doublereal *,
00050 doublereal *, doublereal *, doublereal *, doublereal *,
00051 doublereal *, doublereal *, doublereal *, doublereal *,
00052 doublereal *, doublereal *), dlapll_(integer *, doublereal *,
00053 integer *, doublereal *, integer *, doublereal *);
00054 integer kcycle;
00055 extern int dlartg_(doublereal *, doublereal *,
00056 doublereal *, doublereal *, doublereal *), dlaset_(char *,
00057 integer *, integer *, doublereal *, doublereal *, doublereal *,
00058 integer *), xerbla_(char *, 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
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 a_dim1 = *lda;
00326 a_offset = 1 + a_dim1;
00327 a -= a_offset;
00328 b_dim1 = *ldb;
00329 b_offset = 1 + b_dim1;
00330 b -= b_offset;
00331 --alpha;
00332 --beta;
00333 u_dim1 = *ldu;
00334 u_offset = 1 + u_dim1;
00335 u -= u_offset;
00336 v_dim1 = *ldv;
00337 v_offset = 1 + v_dim1;
00338 v -= v_offset;
00339 q_dim1 = *ldq;
00340 q_offset = 1 + q_dim1;
00341 q -= q_offset;
00342 --work;
00343
00344
00345 initu = lsame_(jobu, "I");
00346 wantu = initu || lsame_(jobu, "U");
00347
00348 initv = lsame_(jobv, "I");
00349 wantv = initv || lsame_(jobv, "V");
00350
00351 initq = lsame_(jobq, "I");
00352 wantq = initq || lsame_(jobq, "Q");
00353
00354 *info = 0;
00355 if (! (initu || wantu || lsame_(jobu, "N"))) {
00356 *info = -1;
00357 } else if (! (initv || wantv || lsame_(jobv, "N")))
00358 {
00359 *info = -2;
00360 } else if (! (initq || wantq || lsame_(jobq, "N")))
00361 {
00362 *info = -3;
00363 } else if (*m < 0) {
00364 *info = -4;
00365 } else if (*p < 0) {
00366 *info = -5;
00367 } else if (*n < 0) {
00368 *info = -6;
00369 } else if (*lda < max(1,*m)) {
00370 *info = -10;
00371 } else if (*ldb < max(1,*p)) {
00372 *info = -12;
00373 } else if (*ldu < 1 || wantu && *ldu < *m) {
00374 *info = -18;
00375 } else if (*ldv < 1 || wantv && *ldv < *p) {
00376 *info = -20;
00377 } else if (*ldq < 1 || wantq && *ldq < *n) {
00378 *info = -22;
00379 }
00380 if (*info != 0) {
00381 i__1 = -(*info);
00382 xerbla_("DTGSJA", &i__1);
00383 return 0;
00384 }
00385
00386
00387
00388 if (initu) {
00389 dlaset_("Full", m, m, &c_b13, &c_b14, &u[u_offset], ldu);
00390 }
00391 if (initv) {
00392 dlaset_("Full", p, p, &c_b13, &c_b14, &v[v_offset], ldv);
00393 }
00394 if (initq) {
00395 dlaset_("Full", n, n, &c_b13, &c_b14, &q[q_offset], ldq);
00396 }
00397
00398
00399
00400 upper = FALSE_;
00401 for (kcycle = 1; kcycle <= 40; ++kcycle) {
00402
00403 upper = ! upper;
00404
00405 i__1 = *l - 1;
00406 for (i__ = 1; i__ <= i__1; ++i__) {
00407 i__2 = *l;
00408 for (j = i__ + 1; j <= i__2; ++j) {
00409
00410 a1 = 0.;
00411 a2 = 0.;
00412 a3 = 0.;
00413 if (*k + i__ <= *m) {
00414 a1 = a[*k + i__ + (*n - *l + i__) * a_dim1];
00415 }
00416 if (*k + j <= *m) {
00417 a3 = a[*k + j + (*n - *l + j) * a_dim1];
00418 }
00419
00420 b1 = b[i__ + (*n - *l + i__) * b_dim1];
00421 b3 = b[j + (*n - *l + j) * b_dim1];
00422
00423 if (upper) {
00424 if (*k + i__ <= *m) {
00425 a2 = a[*k + i__ + (*n - *l + j) * a_dim1];
00426 }
00427 b2 = b[i__ + (*n - *l + j) * b_dim1];
00428 } else {
00429 if (*k + j <= *m) {
00430 a2 = a[*k + j + (*n - *l + i__) * a_dim1];
00431 }
00432 b2 = b[j + (*n - *l + i__) * b_dim1];
00433 }
00434
00435 dlags2_(&upper, &a1, &a2, &a3, &b1, &b2, &b3, &csu, &snu, &
00436 csv, &snv, &csq, &snq);
00437
00438
00439
00440 if (*k + j <= *m) {
00441 drot_(l, &a[*k + j + (*n - *l + 1) * a_dim1], lda, &a[*k
00442 + i__ + (*n - *l + 1) * a_dim1], lda, &csu, &snu);
00443 }
00444
00445
00446
00447 drot_(l, &b[j + (*n - *l + 1) * b_dim1], ldb, &b[i__ + (*n - *
00448 l + 1) * b_dim1], ldb, &csv, &snv);
00449
00450
00451
00452
00453
00454 i__4 = *k + *l;
00455 i__3 = min(i__4,*m);
00456 drot_(&i__3, &a[(*n - *l + j) * a_dim1 + 1], &c__1, &a[(*n - *
00457 l + i__) * a_dim1 + 1], &c__1, &csq, &snq);
00458
00459 drot_(l, &b[(*n - *l + j) * b_dim1 + 1], &c__1, &b[(*n - *l +
00460 i__) * b_dim1 + 1], &c__1, &csq, &snq);
00461
00462 if (upper) {
00463 if (*k + i__ <= *m) {
00464 a[*k + i__ + (*n - *l + j) * a_dim1] = 0.;
00465 }
00466 b[i__ + (*n - *l + j) * b_dim1] = 0.;
00467 } else {
00468 if (*k + j <= *m) {
00469 a[*k + j + (*n - *l + i__) * a_dim1] = 0.;
00470 }
00471 b[j + (*n - *l + i__) * b_dim1] = 0.;
00472 }
00473
00474
00475
00476 if (wantu && *k + j <= *m) {
00477 drot_(m, &u[(*k + j) * u_dim1 + 1], &c__1, &u[(*k + i__) *
00478 u_dim1 + 1], &c__1, &csu, &snu);
00479 }
00480
00481 if (wantv) {
00482 drot_(p, &v[j * v_dim1 + 1], &c__1, &v[i__ * v_dim1 + 1],
00483 &c__1, &csv, &snv);
00484 }
00485
00486 if (wantq) {
00487 drot_(n, &q[(*n - *l + j) * q_dim1 + 1], &c__1, &q[(*n - *
00488 l + i__) * q_dim1 + 1], &c__1, &csq, &snq);
00489 }
00490
00491
00492 }
00493
00494 }
00495
00496 if (! upper) {
00497
00498
00499
00500
00501
00502
00503
00504 error = 0.;
00505
00506 i__2 = *l, i__3 = *m - *k;
00507 i__1 = min(i__2,i__3);
00508 for (i__ = 1; i__ <= i__1; ++i__) {
00509 i__2 = *l - i__ + 1;
00510 dcopy_(&i__2, &a[*k + i__ + (*n - *l + i__) * a_dim1], lda, &
00511 work[1], &c__1);
00512 i__2 = *l - i__ + 1;
00513 dcopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &work[*
00514 l + 1], &c__1);
00515 i__2 = *l - i__ + 1;
00516 dlapll_(&i__2, &work[1], &c__1, &work[*l + 1], &c__1, &ssmin);
00517 error = max(error,ssmin);
00518
00519 }
00520
00521 if (abs(error) <= min(*tola,*tolb)) {
00522 goto L50;
00523 }
00524 }
00525
00526
00527
00528
00529 }
00530
00531
00532
00533 *info = 1;
00534 goto L100;
00535
00536 L50:
00537
00538
00539
00540
00541
00542 i__1 = *k;
00543 for (i__ = 1; i__ <= i__1; ++i__) {
00544 alpha[i__] = 1.;
00545 beta[i__] = 0.;
00546
00547 }
00548
00549
00550 i__2 = *l, i__3 = *m - *k;
00551 i__1 = min(i__2,i__3);
00552 for (i__ = 1; i__ <= i__1; ++i__) {
00553
00554 a1 = a[*k + i__ + (*n - *l + i__) * a_dim1];
00555 b1 = b[i__ + (*n - *l + i__) * b_dim1];
00556
00557 if (a1 != 0.) {
00558 gamma = b1 / a1;
00559
00560
00561
00562 if (gamma < 0.) {
00563 i__2 = *l - i__ + 1;
00564 dscal_(&i__2, &c_b43, &b[i__ + (*n - *l + i__) * b_dim1], ldb)
00565 ;
00566 if (wantv) {
00567 dscal_(p, &c_b43, &v[i__ * v_dim1 + 1], &c__1);
00568 }
00569 }
00570
00571 d__1 = abs(gamma);
00572 dlartg_(&d__1, &c_b14, &beta[*k + i__], &alpha[*k + i__], &rwk);
00573
00574 if (alpha[*k + i__] >= beta[*k + i__]) {
00575 i__2 = *l - i__ + 1;
00576 d__1 = 1. / alpha[*k + i__];
00577 dscal_(&i__2, &d__1, &a[*k + i__ + (*n - *l + i__) * a_dim1],
00578 lda);
00579 } else {
00580 i__2 = *l - i__ + 1;
00581 d__1 = 1. / beta[*k + i__];
00582 dscal_(&i__2, &d__1, &b[i__ + (*n - *l + i__) * b_dim1], ldb);
00583 i__2 = *l - i__ + 1;
00584 dcopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &a[*k
00585 + i__ + (*n - *l + i__) * a_dim1], lda);
00586 }
00587
00588 } else {
00589
00590 alpha[*k + i__] = 0.;
00591 beta[*k + i__] = 1.;
00592 i__2 = *l - i__ + 1;
00593 dcopy_(&i__2, &b[i__ + (*n - *l + i__) * b_dim1], ldb, &a[*k +
00594 i__ + (*n - *l + i__) * a_dim1], lda);
00595
00596 }
00597
00598
00599 }
00600
00601
00602
00603 i__1 = *k + *l;
00604 for (i__ = *m + 1; i__ <= i__1; ++i__) {
00605 alpha[i__] = 0.;
00606 beta[i__] = 1.;
00607
00608 }
00609
00610 if (*k + *l < *n) {
00611 i__1 = *n;
00612 for (i__ = *k + *l + 1; i__ <= i__1; ++i__) {
00613 alpha[i__] = 0.;
00614 beta[i__] = 0.;
00615
00616 }
00617 }
00618
00619 L100:
00620 *ncycle = kcycle;
00621 return 0;
00622
00623
00624
00625 }