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 real c_b36 = .5f;
00020
00021 int slatrs_(char *uplo, char *trans, char *diag, char *
00022 normin, integer *n, real *a, integer *lda, real *x, real *scale, real
00023 *cnorm, integer *info)
00024 {
00025
00026 integer a_dim1, a_offset, i__1, i__2, i__3;
00027 real r__1, r__2, r__3;
00028
00029
00030 integer i__, j;
00031 real xj, rec, tjj;
00032 integer jinc;
00033 real xbnd;
00034 integer imax;
00035 real tmax, tjjs;
00036 extern doublereal sdot_(integer *, real *, integer *, real *, integer *);
00037 real xmax, grow, sumj;
00038 extern logical lsame_(char *, char *);
00039 extern int sscal_(integer *, real *, real *, integer *);
00040 real tscal, uscal;
00041 integer jlast;
00042 extern doublereal sasum_(integer *, real *, integer *);
00043 logical upper;
00044 extern int saxpy_(integer *, real *, real *, integer *,
00045 real *, integer *), strsv_(char *, char *, char *, integer *,
00046 real *, integer *, real *, integer *);
00047 extern doublereal slamch_(char *);
00048 extern int xerbla_(char *, integer *);
00049 real bignum;
00050 extern integer isamax_(integer *, real *, integer *);
00051 logical notran;
00052 integer jfirst;
00053 real smlnum;
00054 logical nounit;
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
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 a_dim1 = *lda;
00234 a_offset = 1 + a_dim1;
00235 a -= a_offset;
00236 --x;
00237 --cnorm;
00238
00239
00240 *info = 0;
00241 upper = lsame_(uplo, "U");
00242 notran = lsame_(trans, "N");
00243 nounit = lsame_(diag, "N");
00244
00245
00246
00247 if (! upper && ! lsame_(uplo, "L")) {
00248 *info = -1;
00249 } else if (! notran && ! lsame_(trans, "T") && !
00250 lsame_(trans, "C")) {
00251 *info = -2;
00252 } else if (! nounit && ! lsame_(diag, "U")) {
00253 *info = -3;
00254 } else if (! lsame_(normin, "Y") && ! lsame_(normin,
00255 "N")) {
00256 *info = -4;
00257 } else if (*n < 0) {
00258 *info = -5;
00259 } else if (*lda < max(1,*n)) {
00260 *info = -7;
00261 }
00262 if (*info != 0) {
00263 i__1 = -(*info);
00264 xerbla_("SLATRS", &i__1);
00265 return 0;
00266 }
00267
00268
00269
00270 if (*n == 0) {
00271 return 0;
00272 }
00273
00274
00275
00276 smlnum = slamch_("Safe minimum") / slamch_("Precision");
00277 bignum = 1.f / smlnum;
00278 *scale = 1.f;
00279
00280 if (lsame_(normin, "N")) {
00281
00282
00283
00284 if (upper) {
00285
00286
00287
00288 i__1 = *n;
00289 for (j = 1; j <= i__1; ++j) {
00290 i__2 = j - 1;
00291 cnorm[j] = sasum_(&i__2, &a[j * a_dim1 + 1], &c__1);
00292
00293 }
00294 } else {
00295
00296
00297
00298 i__1 = *n - 1;
00299 for (j = 1; j <= i__1; ++j) {
00300 i__2 = *n - j;
00301 cnorm[j] = sasum_(&i__2, &a[j + 1 + j * a_dim1], &c__1);
00302
00303 }
00304 cnorm[*n] = 0.f;
00305 }
00306 }
00307
00308
00309
00310
00311 imax = isamax_(n, &cnorm[1], &c__1);
00312 tmax = cnorm[imax];
00313 if (tmax <= bignum) {
00314 tscal = 1.f;
00315 } else {
00316 tscal = 1.f / (smlnum * tmax);
00317 sscal_(n, &tscal, &cnorm[1], &c__1);
00318 }
00319
00320
00321
00322
00323 j = isamax_(n, &x[1], &c__1);
00324 xmax = (r__1 = x[j], dabs(r__1));
00325 xbnd = xmax;
00326 if (notran) {
00327
00328
00329
00330 if (upper) {
00331 jfirst = *n;
00332 jlast = 1;
00333 jinc = -1;
00334 } else {
00335 jfirst = 1;
00336 jlast = *n;
00337 jinc = 1;
00338 }
00339
00340 if (tscal != 1.f) {
00341 grow = 0.f;
00342 goto L50;
00343 }
00344
00345 if (nounit) {
00346
00347
00348
00349
00350
00351
00352 grow = 1.f / dmax(xbnd,smlnum);
00353 xbnd = grow;
00354 i__1 = jlast;
00355 i__2 = jinc;
00356 for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00357
00358
00359
00360 if (grow <= smlnum) {
00361 goto L50;
00362 }
00363
00364
00365
00366 tjj = (r__1 = a[j + j * a_dim1], dabs(r__1));
00367
00368 r__1 = xbnd, r__2 = dmin(1.f,tjj) * grow;
00369 xbnd = dmin(r__1,r__2);
00370 if (tjj + cnorm[j] >= smlnum) {
00371
00372
00373
00374 grow *= tjj / (tjj + cnorm[j]);
00375 } else {
00376
00377
00378
00379 grow = 0.f;
00380 }
00381
00382 }
00383 grow = xbnd;
00384 } else {
00385
00386
00387
00388
00389
00390
00391 r__1 = 1.f, r__2 = 1.f / dmax(xbnd,smlnum);
00392 grow = dmin(r__1,r__2);
00393 i__2 = jlast;
00394 i__1 = jinc;
00395 for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00396
00397
00398
00399 if (grow <= smlnum) {
00400 goto L50;
00401 }
00402
00403
00404
00405 grow *= 1.f / (cnorm[j] + 1.f);
00406
00407 }
00408 }
00409 L50:
00410
00411 ;
00412 } else {
00413
00414
00415
00416 if (upper) {
00417 jfirst = 1;
00418 jlast = *n;
00419 jinc = 1;
00420 } else {
00421 jfirst = *n;
00422 jlast = 1;
00423 jinc = -1;
00424 }
00425
00426 if (tscal != 1.f) {
00427 grow = 0.f;
00428 goto L80;
00429 }
00430
00431 if (nounit) {
00432
00433
00434
00435
00436
00437
00438 grow = 1.f / dmax(xbnd,smlnum);
00439 xbnd = grow;
00440 i__1 = jlast;
00441 i__2 = jinc;
00442 for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00443
00444
00445
00446 if (grow <= smlnum) {
00447 goto L80;
00448 }
00449
00450
00451
00452 xj = cnorm[j] + 1.f;
00453
00454 r__1 = grow, r__2 = xbnd / xj;
00455 grow = dmin(r__1,r__2);
00456
00457
00458
00459 tjj = (r__1 = a[j + j * a_dim1], dabs(r__1));
00460 if (xj > tjj) {
00461 xbnd *= tjj / xj;
00462 }
00463
00464 }
00465 grow = dmin(grow,xbnd);
00466 } else {
00467
00468
00469
00470
00471
00472
00473 r__1 = 1.f, r__2 = 1.f / dmax(xbnd,smlnum);
00474 grow = dmin(r__1,r__2);
00475 i__2 = jlast;
00476 i__1 = jinc;
00477 for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00478
00479
00480
00481 if (grow <= smlnum) {
00482 goto L80;
00483 }
00484
00485
00486
00487 xj = cnorm[j] + 1.f;
00488 grow /= xj;
00489
00490 }
00491 }
00492 L80:
00493 ;
00494 }
00495
00496 if (grow * tscal > smlnum) {
00497
00498
00499
00500
00501 strsv_(uplo, trans, diag, n, &a[a_offset], lda, &x[1], &c__1);
00502 } else {
00503
00504
00505
00506 if (xmax > bignum) {
00507
00508
00509
00510
00511 *scale = bignum / xmax;
00512 sscal_(n, scale, &x[1], &c__1);
00513 xmax = bignum;
00514 }
00515
00516 if (notran) {
00517
00518
00519
00520 i__1 = jlast;
00521 i__2 = jinc;
00522 for (j = jfirst; i__2 < 0 ? j >= i__1 : j <= i__1; j += i__2) {
00523
00524
00525
00526 xj = (r__1 = x[j], dabs(r__1));
00527 if (nounit) {
00528 tjjs = a[j + j * a_dim1] * tscal;
00529 } else {
00530 tjjs = tscal;
00531 if (tscal == 1.f) {
00532 goto L95;
00533 }
00534 }
00535 tjj = dabs(tjjs);
00536 if (tjj > smlnum) {
00537
00538
00539
00540 if (tjj < 1.f) {
00541 if (xj > tjj * bignum) {
00542
00543
00544
00545 rec = 1.f / xj;
00546 sscal_(n, &rec, &x[1], &c__1);
00547 *scale *= rec;
00548 xmax *= rec;
00549 }
00550 }
00551 x[j] /= tjjs;
00552 xj = (r__1 = x[j], dabs(r__1));
00553 } else if (tjj > 0.f) {
00554
00555
00556
00557 if (xj > tjj * bignum) {
00558
00559
00560
00561
00562 rec = tjj * bignum / xj;
00563 if (cnorm[j] > 1.f) {
00564
00565
00566
00567
00568 rec /= cnorm[j];
00569 }
00570 sscal_(n, &rec, &x[1], &c__1);
00571 *scale *= rec;
00572 xmax *= rec;
00573 }
00574 x[j] /= tjjs;
00575 xj = (r__1 = x[j], dabs(r__1));
00576 } else {
00577
00578
00579
00580
00581 i__3 = *n;
00582 for (i__ = 1; i__ <= i__3; ++i__) {
00583 x[i__] = 0.f;
00584
00585 }
00586 x[j] = 1.f;
00587 xj = 1.f;
00588 *scale = 0.f;
00589 xmax = 0.f;
00590 }
00591 L95:
00592
00593
00594
00595
00596 if (xj > 1.f) {
00597 rec = 1.f / xj;
00598 if (cnorm[j] > (bignum - xmax) * rec) {
00599
00600
00601
00602 rec *= .5f;
00603 sscal_(n, &rec, &x[1], &c__1);
00604 *scale *= rec;
00605 }
00606 } else if (xj * cnorm[j] > bignum - xmax) {
00607
00608
00609
00610 sscal_(n, &c_b36, &x[1], &c__1);
00611 *scale *= .5f;
00612 }
00613
00614 if (upper) {
00615 if (j > 1) {
00616
00617
00618
00619
00620 i__3 = j - 1;
00621 r__1 = -x[j] * tscal;
00622 saxpy_(&i__3, &r__1, &a[j * a_dim1 + 1], &c__1, &x[1],
00623 &c__1);
00624 i__3 = j - 1;
00625 i__ = isamax_(&i__3, &x[1], &c__1);
00626 xmax = (r__1 = x[i__], dabs(r__1));
00627 }
00628 } else {
00629 if (j < *n) {
00630
00631
00632
00633
00634 i__3 = *n - j;
00635 r__1 = -x[j] * tscal;
00636 saxpy_(&i__3, &r__1, &a[j + 1 + j * a_dim1], &c__1, &
00637 x[j + 1], &c__1);
00638 i__3 = *n - j;
00639 i__ = j + isamax_(&i__3, &x[j + 1], &c__1);
00640 xmax = (r__1 = x[i__], dabs(r__1));
00641 }
00642 }
00643
00644 }
00645
00646 } else {
00647
00648
00649
00650 i__2 = jlast;
00651 i__1 = jinc;
00652 for (j = jfirst; i__1 < 0 ? j >= i__2 : j <= i__2; j += i__1) {
00653
00654
00655
00656
00657 xj = (r__1 = x[j], dabs(r__1));
00658 uscal = tscal;
00659 rec = 1.f / dmax(xmax,1.f);
00660 if (cnorm[j] > (bignum - xj) * rec) {
00661
00662
00663
00664 rec *= .5f;
00665 if (nounit) {
00666 tjjs = a[j + j * a_dim1] * tscal;
00667 } else {
00668 tjjs = tscal;
00669 }
00670 tjj = dabs(tjjs);
00671 if (tjj > 1.f) {
00672
00673
00674
00675
00676 r__1 = 1.f, r__2 = rec * tjj;
00677 rec = dmin(r__1,r__2);
00678 uscal /= tjjs;
00679 }
00680 if (rec < 1.f) {
00681 sscal_(n, &rec, &x[1], &c__1);
00682 *scale *= rec;
00683 xmax *= rec;
00684 }
00685 }
00686
00687 sumj = 0.f;
00688 if (uscal == 1.f) {
00689
00690
00691
00692
00693 if (upper) {
00694 i__3 = j - 1;
00695 sumj = sdot_(&i__3, &a[j * a_dim1 + 1], &c__1, &x[1],
00696 &c__1);
00697 } else if (j < *n) {
00698 i__3 = *n - j;
00699 sumj = sdot_(&i__3, &a[j + 1 + j * a_dim1], &c__1, &x[
00700 j + 1], &c__1);
00701 }
00702 } else {
00703
00704
00705
00706 if (upper) {
00707 i__3 = j - 1;
00708 for (i__ = 1; i__ <= i__3; ++i__) {
00709 sumj += a[i__ + j * a_dim1] * uscal * x[i__];
00710
00711 }
00712 } else if (j < *n) {
00713 i__3 = *n;
00714 for (i__ = j + 1; i__ <= i__3; ++i__) {
00715 sumj += a[i__ + j * a_dim1] * uscal * x[i__];
00716
00717 }
00718 }
00719 }
00720
00721 if (uscal == tscal) {
00722
00723
00724
00725
00726 x[j] -= sumj;
00727 xj = (r__1 = x[j], dabs(r__1));
00728 if (nounit) {
00729 tjjs = a[j + j * a_dim1] * tscal;
00730 } else {
00731 tjjs = tscal;
00732 if (tscal == 1.f) {
00733 goto L135;
00734 }
00735 }
00736
00737
00738
00739 tjj = dabs(tjjs);
00740 if (tjj > smlnum) {
00741
00742
00743
00744 if (tjj < 1.f) {
00745 if (xj > tjj * bignum) {
00746
00747
00748
00749 rec = 1.f / xj;
00750 sscal_(n, &rec, &x[1], &c__1);
00751 *scale *= rec;
00752 xmax *= rec;
00753 }
00754 }
00755 x[j] /= tjjs;
00756 } else if (tjj > 0.f) {
00757
00758
00759
00760 if (xj > tjj * bignum) {
00761
00762
00763
00764 rec = tjj * bignum / xj;
00765 sscal_(n, &rec, &x[1], &c__1);
00766 *scale *= rec;
00767 xmax *= rec;
00768 }
00769 x[j] /= tjjs;
00770 } else {
00771
00772
00773
00774
00775 i__3 = *n;
00776 for (i__ = 1; i__ <= i__3; ++i__) {
00777 x[i__] = 0.f;
00778
00779 }
00780 x[j] = 1.f;
00781 *scale = 0.f;
00782 xmax = 0.f;
00783 }
00784 L135:
00785 ;
00786 } else {
00787
00788
00789
00790
00791 x[j] = x[j] / tjjs - sumj;
00792 }
00793
00794 r__2 = xmax, r__3 = (r__1 = x[j], dabs(r__1));
00795 xmax = dmax(r__2,r__3);
00796
00797 }
00798 }
00799 *scale /= tscal;
00800 }
00801
00802
00803
00804 if (tscal != 1.f) {
00805 r__1 = 1.f / tscal;
00806 sscal_(n, &r__1, &cnorm[1], &c__1);
00807 }
00808
00809 return 0;
00810
00811
00812
00813 }