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 integer c__1 = 1;
00019 static integer c__0 = 0;
00020 static doublereal c_b35 = 1.;
00021
00022 int dgsvj1_(char *jobv, integer *m, integer *n, integer *n1,
00023 doublereal *a, integer *lda, doublereal *d__, doublereal *sva,
00024 integer *mv, doublereal *v, integer *ldv, doublereal *eps, doublereal
00025 *sfmin, doublereal *tol, integer *nsweep, doublereal *work, integer *
00026 lwork, integer *info)
00027 {
00028
00029 integer a_dim1, a_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4, i__5,
00030 i__6;
00031 doublereal d__1, d__2;
00032
00033
00034 double sqrt(doublereal), d_sign(doublereal *, doublereal *);
00035
00036
00037 doublereal bigtheta;
00038 integer pskipped, i__, p, q;
00039 doublereal t, rootsfmin, cs, sn;
00040 integer jbc;
00041 doublereal big;
00042 integer kbl, igl, ibr, jgl, mvl, nblc;
00043 doublereal aapp, aapq, aaqq;
00044 extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
00045 integer *);
00046 integer nblr, ierr;
00047 doublereal aapp0;
00048 extern doublereal dnrm2_(integer *, doublereal *, integer *);
00049 doublereal temp1, large, apoaq, aqoap;
00050 extern logical lsame_(char *, char *);
00051 doublereal theta, small;
00052 extern int dcopy_(integer *, doublereal *, integer *,
00053 doublereal *, integer *);
00054 doublereal fastr[5];
00055 extern int dswap_(integer *, doublereal *, integer *,
00056 doublereal *, integer *);
00057 logical applv, rsvec;
00058 extern int daxpy_(integer *, doublereal *, doublereal *,
00059 integer *, doublereal *, integer *), drotm_(integer *, doublereal
00060 *, integer *, doublereal *, integer *, doublereal *);
00061 logical rotok;
00062 extern int dlascl_(char *, integer *, integer *,
00063 doublereal *, doublereal *, integer *, integer *, doublereal *,
00064 integer *, integer *);
00065 extern integer idamax_(integer *, doublereal *, integer *);
00066 extern int xerbla_(char *, integer *);
00067 integer ijblsk, swband, blskip;
00068 doublereal mxaapq;
00069 extern int dlassq_(integer *, doublereal *, integer *,
00070 doublereal *, doublereal *);
00071 doublereal thsign, mxsinj;
00072 integer emptsw, notrot, iswrot;
00073 doublereal rootbig, rooteps;
00074 integer rowskip;
00075 doublereal roottol;
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 --sva;
00248 --d__;
00249 a_dim1 = *lda;
00250 a_offset = 1 + a_dim1;
00251 a -= a_offset;
00252 v_dim1 = *ldv;
00253 v_offset = 1 + v_dim1;
00254 v -= v_offset;
00255 --work;
00256
00257
00258 applv = lsame_(jobv, "A");
00259 rsvec = lsame_(jobv, "V");
00260 if (! (rsvec || applv || lsame_(jobv, "N"))) {
00261 *info = -1;
00262 } else if (*m < 0) {
00263 *info = -2;
00264 } else if (*n < 0 || *n > *m) {
00265 *info = -3;
00266 } else if (*n1 < 0) {
00267 *info = -4;
00268 } else if (*lda < *m) {
00269 *info = -6;
00270 } else if (*mv < 0) {
00271 *info = -9;
00272 } else if (*ldv < *m) {
00273 *info = -11;
00274 } else if (*tol <= *eps) {
00275 *info = -14;
00276 } else if (*nsweep < 0) {
00277 *info = -15;
00278 } else if (*lwork < *m) {
00279 *info = -17;
00280 } else {
00281 *info = 0;
00282 }
00283
00284
00285 if (*info != 0) {
00286 i__1 = -(*info);
00287 xerbla_("DGSVJ1", &i__1);
00288 return 0;
00289 }
00290
00291 if (rsvec) {
00292 mvl = *n;
00293 } else if (applv) {
00294 mvl = *mv;
00295 }
00296 rsvec = rsvec || applv;
00297 rooteps = sqrt(*eps);
00298 rootsfmin = sqrt(*sfmin);
00299 small = *sfmin / *eps;
00300 big = 1. / *sfmin;
00301 rootbig = 1. / rootsfmin;
00302 large = big / sqrt((doublereal) (*m * *n));
00303 bigtheta = 1. / rooteps;
00304 roottol = sqrt(*tol);
00305
00306
00307
00308
00309
00310 emptsw = *n1 * (*n - *n1);
00311 notrot = 0;
00312 fastr[0] = 0.;
00313
00314
00315
00316 kbl = min(8,*n);
00317 nblr = *n1 / kbl;
00318 if (nblr * kbl != *n1) {
00319 ++nblr;
00320 }
00321
00322 nblc = (*n - *n1) / kbl;
00323 if (nblc * kbl != *n - *n1) {
00324 ++nblc;
00325 }
00326
00327 i__1 = kbl;
00328 blskip = i__1 * i__1 + 1;
00329
00330 rowskip = min(5,kbl);
00331
00332 swband = 0;
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 i__1 = *nsweep;
00347 for (i__ = 1; i__ <= i__1; ++i__) {
00348
00349
00350 mxaapq = 0.;
00351 mxsinj = 0.;
00352 iswrot = 0;
00353
00354 notrot = 0;
00355 pskipped = 0;
00356
00357 i__2 = nblr;
00358 for (ibr = 1; ibr <= i__2; ++ibr) {
00359 igl = (ibr - 1) * kbl + 1;
00360
00361
00362
00363
00364 igl = (ibr - 1) * kbl + 1;
00365 i__3 = nblc;
00366 for (jbc = 1; jbc <= i__3; ++jbc) {
00367 jgl = *n1 + (jbc - 1) * kbl + 1;
00368
00369 ijblsk = 0;
00370
00371 i__5 = igl + kbl - 1;
00372 i__4 = min(i__5,*n1);
00373 for (p = igl; p <= i__4; ++p) {
00374 aapp = sva[p];
00375 if (aapp > 0.) {
00376 pskipped = 0;
00377
00378 i__6 = jgl + kbl - 1;
00379 i__5 = min(i__6,*n);
00380 for (q = jgl; q <= i__5; ++q) {
00381
00382 aaqq = sva[q];
00383 if (aaqq > 0.) {
00384 aapp0 = aapp;
00385
00386
00387
00388
00389
00390 if (aaqq >= 1.) {
00391 if (aapp >= aaqq) {
00392 rotok = small * aapp <= aaqq;
00393 } else {
00394 rotok = small * aaqq <= aapp;
00395 }
00396 if (aapp < big / aaqq) {
00397 aapq = ddot_(m, &a[p * a_dim1 + 1], &
00398 c__1, &a[q * a_dim1 + 1], &
00399 c__1) * d__[p] * d__[q] /
00400 aaqq / aapp;
00401 } else {
00402 dcopy_(m, &a[p * a_dim1 + 1], &c__1, &
00403 work[1], &c__1);
00404 dlascl_("G", &c__0, &c__0, &aapp, &
00405 d__[p], m, &c__1, &work[1],
00406 lda, &ierr);
00407 aapq = ddot_(m, &work[1], &c__1, &a[q
00408 * a_dim1 + 1], &c__1) * d__[q]
00409 / aaqq;
00410 }
00411 } else {
00412 if (aapp >= aaqq) {
00413 rotok = aapp <= aaqq / small;
00414 } else {
00415 rotok = aaqq <= aapp / small;
00416 }
00417 if (aapp > small / aaqq) {
00418 aapq = ddot_(m, &a[p * a_dim1 + 1], &
00419 c__1, &a[q * a_dim1 + 1], &
00420 c__1) * d__[p] * d__[q] /
00421 aaqq / aapp;
00422 } else {
00423 dcopy_(m, &a[q * a_dim1 + 1], &c__1, &
00424 work[1], &c__1);
00425 dlascl_("G", &c__0, &c__0, &aaqq, &
00426 d__[q], m, &c__1, &work[1],
00427 lda, &ierr);
00428 aapq = ddot_(m, &work[1], &c__1, &a[p
00429 * a_dim1 + 1], &c__1) * d__[p]
00430 / aapp;
00431 }
00432 }
00433
00434 d__1 = mxaapq, d__2 = abs(aapq);
00435 mxaapq = max(d__1,d__2);
00436
00437
00438 if (abs(aapq) > *tol) {
00439 notrot = 0;
00440
00441 pskipped = 0;
00442 ++iswrot;
00443
00444 if (rotok) {
00445
00446 aqoap = aaqq / aapp;
00447 apoaq = aapp / aaqq;
00448 theta = (d__1 = aqoap - apoaq, abs(
00449 d__1)) * -.5 / aapq;
00450 if (aaqq > aapp0) {
00451 theta = -theta;
00452 }
00453 if (abs(theta) > bigtheta) {
00454 t = .5 / theta;
00455 fastr[2] = t * d__[p] / d__[q];
00456 fastr[3] = -t * d__[q] / d__[p];
00457 drotm_(m, &a[p * a_dim1 + 1], &
00458 c__1, &a[q * a_dim1 + 1],
00459 &c__1, fastr);
00460 if (rsvec) {
00461 drotm_(&mvl, &v[p * v_dim1 + 1], &c__1, &v[q *
00462 v_dim1 + 1], &c__1, fastr);
00463 }
00464
00465 d__1 = 0., d__2 = t * apoaq *
00466 aapq + 1.;
00467 sva[q] = aaqq * sqrt((max(d__1,
00468 d__2)));
00469
00470 d__1 = 0., d__2 = 1. - t * aqoap *
00471 aapq;
00472 aapp *= sqrt((max(d__1,d__2)));
00473
00474 d__1 = mxsinj, d__2 = abs(t);
00475 mxsinj = max(d__1,d__2);
00476 } else {
00477
00478
00479
00480 thsign = -d_sign(&c_b35, &aapq);
00481 if (aaqq > aapp0) {
00482 thsign = -thsign;
00483 }
00484 t = 1. / (theta + thsign * sqrt(
00485 theta * theta + 1.));
00486 cs = sqrt(1. / (t * t + 1.));
00487 sn = t * cs;
00488
00489 d__1 = mxsinj, d__2 = abs(sn);
00490 mxsinj = max(d__1,d__2);
00491
00492 d__1 = 0., d__2 = t * apoaq *
00493 aapq + 1.;
00494 sva[q] = aaqq * sqrt((max(d__1,
00495 d__2)));
00496 aapp *= sqrt(1. - t * aqoap *
00497 aapq);
00498 apoaq = d__[p] / d__[q];
00499 aqoap = d__[q] / d__[p];
00500 if (d__[p] >= 1.) {
00501
00502 if (d__[q] >= 1.) {
00503 fastr[2] = t * apoaq;
00504 fastr[3] = -t * aqoap;
00505 d__[p] *= cs;
00506 d__[q] *= cs;
00507 drotm_(m, &a[p * a_dim1 + 1], &c__1, &a[q *
00508 a_dim1 + 1], &c__1, fastr);
00509 if (rsvec) {
00510 drotm_(&mvl, &v[p * v_dim1 + 1], &c__1, &v[
00511 q * v_dim1 + 1], &c__1, fastr);
00512 }
00513 } else {
00514 d__1 = -t * aqoap;
00515 daxpy_(m, &d__1, &a[q * a_dim1 + 1], &c__1, &a[
00516 p * a_dim1 + 1], &c__1);
00517 d__1 = cs * sn * apoaq;
00518 daxpy_(m, &d__1, &a[p * a_dim1 + 1], &c__1, &a[
00519 q * a_dim1 + 1], &c__1);
00520 if (rsvec) {
00521 d__1 = -t * aqoap;
00522 daxpy_(&mvl, &d__1, &v[q * v_dim1 + 1], &
00523 c__1, &v[p * v_dim1 + 1], &c__1);
00524 d__1 = cs * sn * apoaq;
00525 daxpy_(&mvl, &d__1, &v[p * v_dim1 + 1], &
00526 c__1, &v[q * v_dim1 + 1], &c__1);
00527 }
00528 d__[p] *= cs;
00529 d__[q] /= cs;
00530 }
00531 } else {
00532 if (d__[q] >= 1.) {
00533 d__1 = t * apoaq;
00534 daxpy_(m, &d__1, &a[p * a_dim1 + 1], &c__1, &a[
00535 q * a_dim1 + 1], &c__1);
00536 d__1 = -cs * sn * aqoap;
00537 daxpy_(m, &d__1, &a[q * a_dim1 + 1], &c__1, &a[
00538 p * a_dim1 + 1], &c__1);
00539 if (rsvec) {
00540 d__1 = t * apoaq;
00541 daxpy_(&mvl, &d__1, &v[p * v_dim1 + 1], &
00542 c__1, &v[q * v_dim1 + 1], &c__1);
00543 d__1 = -cs * sn * aqoap;
00544 daxpy_(&mvl, &d__1, &v[q * v_dim1 + 1], &
00545 c__1, &v[p * v_dim1 + 1], &c__1);
00546 }
00547 d__[p] /= cs;
00548 d__[q] *= cs;
00549 } else {
00550 if (d__[p] >= d__[q]) {
00551 d__1 = -t * aqoap;
00552 daxpy_(m, &d__1, &a[q * a_dim1 + 1], &c__1,
00553 &a[p * a_dim1 + 1], &c__1);
00554 d__1 = cs * sn * apoaq;
00555 daxpy_(m, &d__1, &a[p * a_dim1 + 1], &c__1,
00556 &a[q * a_dim1 + 1], &c__1);
00557 d__[p] *= cs;
00558 d__[q] /= cs;
00559 if (rsvec) {
00560 d__1 = -t * aqoap;
00561 daxpy_(&mvl, &d__1, &v[q * v_dim1 + 1],
00562 &c__1, &v[p * v_dim1 + 1], &
00563 c__1);
00564 d__1 = cs * sn * apoaq;
00565 daxpy_(&mvl, &d__1, &v[p * v_dim1 + 1],
00566 &c__1, &v[q * v_dim1 + 1], &
00567 c__1);
00568 }
00569 } else {
00570 d__1 = t * apoaq;
00571 daxpy_(m, &d__1, &a[p * a_dim1 + 1], &c__1,
00572 &a[q * a_dim1 + 1], &c__1);
00573 d__1 = -cs * sn * aqoap;
00574 daxpy_(m, &d__1, &a[q * a_dim1 + 1], &c__1,
00575 &a[p * a_dim1 + 1], &c__1);
00576 d__[p] /= cs;
00577 d__[q] *= cs;
00578 if (rsvec) {
00579 d__1 = t * apoaq;
00580 daxpy_(&mvl, &d__1, &v[p * v_dim1 + 1],
00581 &c__1, &v[q * v_dim1 + 1], &
00582 c__1);
00583 d__1 = -cs * sn * aqoap;
00584 daxpy_(&mvl, &d__1, &v[q * v_dim1 + 1],
00585 &c__1, &v[p * v_dim1 + 1], &
00586 c__1);
00587 }
00588 }
00589 }
00590 }
00591 }
00592 } else {
00593 if (aapp > aaqq) {
00594 dcopy_(m, &a[p * a_dim1 + 1], &
00595 c__1, &work[1], &c__1);
00596 dlascl_("G", &c__0, &c__0, &aapp,
00597 &c_b35, m, &c__1, &work[1]
00598 , lda, &ierr);
00599 dlascl_("G", &c__0, &c__0, &aaqq,
00600 &c_b35, m, &c__1, &a[q *
00601 a_dim1 + 1], lda, &ierr);
00602 temp1 = -aapq * d__[p] / d__[q];
00603 daxpy_(m, &temp1, &work[1], &c__1,
00604 &a[q * a_dim1 + 1], &
00605 c__1);
00606 dlascl_("G", &c__0, &c__0, &c_b35,
00607 &aaqq, m, &c__1, &a[q *
00608 a_dim1 + 1], lda, &ierr);
00609
00610 d__1 = 0., d__2 = 1. - aapq *
00611 aapq;
00612 sva[q] = aaqq * sqrt((max(d__1,
00613 d__2)));
00614 mxsinj = max(mxsinj,*sfmin);
00615 } else {
00616 dcopy_(m, &a[q * a_dim1 + 1], &
00617 c__1, &work[1], &c__1);
00618 dlascl_("G", &c__0, &c__0, &aaqq,
00619 &c_b35, m, &c__1, &work[1]
00620 , lda, &ierr);
00621 dlascl_("G", &c__0, &c__0, &aapp,
00622 &c_b35, m, &c__1, &a[p *
00623 a_dim1 + 1], lda, &ierr);
00624 temp1 = -aapq * d__[q] / d__[p];
00625 daxpy_(m, &temp1, &work[1], &c__1,
00626 &a[p * a_dim1 + 1], &
00627 c__1);
00628 dlascl_("G", &c__0, &c__0, &c_b35,
00629 &aapp, m, &c__1, &a[p *
00630 a_dim1 + 1], lda, &ierr);
00631
00632 d__1 = 0., d__2 = 1. - aapq *
00633 aapq;
00634 sva[p] = aapp * sqrt((max(d__1,
00635 d__2)));
00636 mxsinj = max(mxsinj,*sfmin);
00637 }
00638 }
00639
00640
00641
00642
00643
00644 d__1 = sva[q] / aaqq;
00645 if (d__1 * d__1 <= rooteps) {
00646 if (aaqq < rootbig && aaqq >
00647 rootsfmin) {
00648 sva[q] = dnrm2_(m, &a[q * a_dim1
00649 + 1], &c__1) * d__[q];
00650 } else {
00651 t = 0.;
00652 aaqq = 0.;
00653 dlassq_(m, &a[q * a_dim1 + 1], &
00654 c__1, &t, &aaqq);
00655 sva[q] = t * sqrt(aaqq) * d__[q];
00656 }
00657 }
00658
00659 d__1 = aapp / aapp0;
00660 if (d__1 * d__1 <= rooteps) {
00661 if (aapp < rootbig && aapp >
00662 rootsfmin) {
00663 aapp = dnrm2_(m, &a[p * a_dim1 +
00664 1], &c__1) * d__[p];
00665 } else {
00666 t = 0.;
00667 aapp = 0.;
00668 dlassq_(m, &a[p * a_dim1 + 1], &
00669 c__1, &t, &aapp);
00670 aapp = t * sqrt(aapp) * d__[p];
00671 }
00672 sva[p] = aapp;
00673 }
00674
00675 } else {
00676 ++notrot;
00677
00678 ++pskipped;
00679 ++ijblsk;
00680 }
00681 } else {
00682 ++notrot;
00683 ++pskipped;
00684 ++ijblsk;
00685 }
00686
00687 if (i__ <= swband && ijblsk >= blskip) {
00688 sva[p] = aapp;
00689 notrot = 0;
00690 goto L2011;
00691 }
00692 if (i__ <= swband && pskipped > rowskip) {
00693 aapp = -aapp;
00694 notrot = 0;
00695 goto L2203;
00696 }
00697
00698
00699 }
00700
00701 L2203:
00702 sva[p] = aapp;
00703
00704 } else {
00705 if (aapp == 0.) {
00706
00707 i__5 = jgl + kbl - 1;
00708 notrot = notrot + min(i__5,*n) - jgl + 1;
00709 }
00710 if (aapp < 0.) {
00711 notrot = 0;
00712 }
00713
00714 }
00715
00716 }
00717
00718
00719 }
00720
00721 L2011:
00722
00723
00724 i__4 = igl + kbl - 1;
00725 i__3 = min(i__4,*n);
00726 for (p = igl; p <= i__3; ++p) {
00727 sva[p] = (d__1 = sva[p], abs(d__1));
00728
00729 }
00730
00731
00732 }
00733
00734
00735
00736 if (sva[*n] < rootbig && sva[*n] > rootsfmin) {
00737 sva[*n] = dnrm2_(m, &a[*n * a_dim1 + 1], &c__1) * d__[*n];
00738 } else {
00739 t = 0.;
00740 aapp = 0.;
00741 dlassq_(m, &a[*n * a_dim1 + 1], &c__1, &t, &aapp);
00742 sva[*n] = t * sqrt(aapp) * d__[*n];
00743 }
00744
00745
00746
00747 if (i__ < swband && (mxaapq <= roottol || iswrot <= *n)) {
00748 swband = i__;
00749 }
00750 if (i__ > swband + 1 && mxaapq < (doublereal) (*n) * *tol && (
00751 doublereal) (*n) * mxaapq * mxsinj < *tol) {
00752 goto L1994;
00753 }
00754
00755 if (notrot >= emptsw) {
00756 goto L1994;
00757 }
00758
00759 }
00760
00761
00762
00763 *info = *nsweep - 1;
00764 goto L1995;
00765 L1994:
00766
00767
00768 *info = 0;
00769
00770 L1995:
00771
00772
00773
00774 i__1 = *n - 1;
00775 for (p = 1; p <= i__1; ++p) {
00776 i__2 = *n - p + 1;
00777 q = idamax_(&i__2, &sva[p], &c__1) + p - 1;
00778 if (p != q) {
00779 temp1 = sva[p];
00780 sva[p] = sva[q];
00781 sva[q] = temp1;
00782 temp1 = d__[p];
00783 d__[p] = d__[q];
00784 d__[q] = temp1;
00785 dswap_(m, &a[p * a_dim1 + 1], &c__1, &a[q * a_dim1 + 1], &c__1);
00786 if (rsvec) {
00787 dswap_(&mvl, &v[p * v_dim1 + 1], &c__1, &v[q * v_dim1 + 1], &
00788 c__1);
00789 }
00790 }
00791
00792 }
00793
00794 return 0;
00795
00796
00797
00798 }