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_b35 = 10.f;
00020 static real c_b71 = .5f;
00021
00022 int sggbal_(char *job, integer *n, real *a, integer *lda,
00023 real *b, integer *ldb, integer *ilo, integer *ihi, real *lscale, real
00024 *rscale, real *work, integer *info)
00025 {
00026
00027 integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
00028 real r__1, r__2, r__3;
00029
00030
00031 double r_lg10(real *), r_sign(real *, real *), pow_ri(real *, integer *);
00032
00033
00034 integer i__, j, k, l, m;
00035 real t;
00036 integer jc;
00037 real ta, tb, tc;
00038 integer ir;
00039 real ew;
00040 integer it, nr, ip1, jp1, lm1;
00041 real cab, rab, ewc, cor, sum;
00042 integer nrp2, icab, lcab;
00043 real beta, coef;
00044 integer irab, lrab;
00045 real basl, cmax;
00046 extern doublereal sdot_(integer *, real *, integer *, real *, integer *);
00047 real coef2, coef5, gamma, alpha;
00048 extern logical lsame_(char *, char *);
00049 extern int sscal_(integer *, real *, real *, integer *);
00050 real sfmin, sfmax;
00051 integer iflow;
00052 extern int sswap_(integer *, real *, integer *, real *,
00053 integer *);
00054 integer kount;
00055 extern int saxpy_(integer *, real *, real *, integer *,
00056 real *, integer *);
00057 real pgamma;
00058 extern doublereal slamch_(char *);
00059 extern int xerbla_(char *, integer *);
00060 extern integer isamax_(integer *, real *, integer *);
00061 integer lsfmin, lsfmax;
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 a_dim1 = *lda;
00178 a_offset = 1 + a_dim1;
00179 a -= a_offset;
00180 b_dim1 = *ldb;
00181 b_offset = 1 + b_dim1;
00182 b -= b_offset;
00183 --lscale;
00184 --rscale;
00185 --work;
00186
00187
00188 *info = 0;
00189 if (! lsame_(job, "N") && ! lsame_(job, "P") && ! lsame_(job, "S")
00190 && ! lsame_(job, "B")) {
00191 *info = -1;
00192 } else if (*n < 0) {
00193 *info = -2;
00194 } else if (*lda < max(1,*n)) {
00195 *info = -4;
00196 } else if (*ldb < max(1,*n)) {
00197 *info = -6;
00198 }
00199 if (*info != 0) {
00200 i__1 = -(*info);
00201 xerbla_("SGGBAL", &i__1);
00202 return 0;
00203 }
00204
00205
00206
00207 if (*n == 0) {
00208 *ilo = 1;
00209 *ihi = *n;
00210 return 0;
00211 }
00212
00213 if (*n == 1) {
00214 *ilo = 1;
00215 *ihi = *n;
00216 lscale[1] = 1.f;
00217 rscale[1] = 1.f;
00218 return 0;
00219 }
00220
00221 if (lsame_(job, "N")) {
00222 *ilo = 1;
00223 *ihi = *n;
00224 i__1 = *n;
00225 for (i__ = 1; i__ <= i__1; ++i__) {
00226 lscale[i__] = 1.f;
00227 rscale[i__] = 1.f;
00228
00229 }
00230 return 0;
00231 }
00232
00233 k = 1;
00234 l = *n;
00235 if (lsame_(job, "S")) {
00236 goto L190;
00237 }
00238
00239 goto L30;
00240
00241
00242
00243
00244
00245 L20:
00246 l = lm1;
00247 if (l != 1) {
00248 goto L30;
00249 }
00250
00251 rscale[1] = 1.f;
00252 lscale[1] = 1.f;
00253 goto L190;
00254
00255 L30:
00256 lm1 = l - 1;
00257 for (i__ = l; i__ >= 1; --i__) {
00258 i__1 = lm1;
00259 for (j = 1; j <= i__1; ++j) {
00260 jp1 = j + 1;
00261 if (a[i__ + j * a_dim1] != 0.f || b[i__ + j * b_dim1] != 0.f) {
00262 goto L50;
00263 }
00264
00265 }
00266 j = l;
00267 goto L70;
00268
00269 L50:
00270 i__1 = l;
00271 for (j = jp1; j <= i__1; ++j) {
00272 if (a[i__ + j * a_dim1] != 0.f || b[i__ + j * b_dim1] != 0.f) {
00273 goto L80;
00274 }
00275
00276 }
00277 j = jp1 - 1;
00278
00279 L70:
00280 m = l;
00281 iflow = 1;
00282 goto L160;
00283 L80:
00284 ;
00285 }
00286 goto L100;
00287
00288
00289
00290 L90:
00291 ++k;
00292
00293 L100:
00294 i__1 = l;
00295 for (j = k; j <= i__1; ++j) {
00296 i__2 = lm1;
00297 for (i__ = k; i__ <= i__2; ++i__) {
00298 ip1 = i__ + 1;
00299 if (a[i__ + j * a_dim1] != 0.f || b[i__ + j * b_dim1] != 0.f) {
00300 goto L120;
00301 }
00302
00303 }
00304 i__ = l;
00305 goto L140;
00306 L120:
00307 i__2 = l;
00308 for (i__ = ip1; i__ <= i__2; ++i__) {
00309 if (a[i__ + j * a_dim1] != 0.f || b[i__ + j * b_dim1] != 0.f) {
00310 goto L150;
00311 }
00312
00313 }
00314 i__ = ip1 - 1;
00315 L140:
00316 m = k;
00317 iflow = 2;
00318 goto L160;
00319 L150:
00320 ;
00321 }
00322 goto L190;
00323
00324
00325
00326 L160:
00327 lscale[m] = (real) i__;
00328 if (i__ == m) {
00329 goto L170;
00330 }
00331 i__1 = *n - k + 1;
00332 sswap_(&i__1, &a[i__ + k * a_dim1], lda, &a[m + k * a_dim1], lda);
00333 i__1 = *n - k + 1;
00334 sswap_(&i__1, &b[i__ + k * b_dim1], ldb, &b[m + k * b_dim1], ldb);
00335
00336
00337
00338 L170:
00339 rscale[m] = (real) j;
00340 if (j == m) {
00341 goto L180;
00342 }
00343 sswap_(&l, &a[j * a_dim1 + 1], &c__1, &a[m * a_dim1 + 1], &c__1);
00344 sswap_(&l, &b[j * b_dim1 + 1], &c__1, &b[m * b_dim1 + 1], &c__1);
00345
00346 L180:
00347 switch (iflow) {
00348 case 1: goto L20;
00349 case 2: goto L90;
00350 }
00351
00352 L190:
00353 *ilo = k;
00354 *ihi = l;
00355
00356 if (lsame_(job, "P")) {
00357 i__1 = *ihi;
00358 for (i__ = *ilo; i__ <= i__1; ++i__) {
00359 lscale[i__] = 1.f;
00360 rscale[i__] = 1.f;
00361
00362 }
00363 return 0;
00364 }
00365
00366 if (*ilo == *ihi) {
00367 return 0;
00368 }
00369
00370
00371
00372 nr = *ihi - *ilo + 1;
00373 i__1 = *ihi;
00374 for (i__ = *ilo; i__ <= i__1; ++i__) {
00375 rscale[i__] = 0.f;
00376 lscale[i__] = 0.f;
00377
00378 work[i__] = 0.f;
00379 work[i__ + *n] = 0.f;
00380 work[i__ + (*n << 1)] = 0.f;
00381 work[i__ + *n * 3] = 0.f;
00382 work[i__ + (*n << 2)] = 0.f;
00383 work[i__ + *n * 5] = 0.f;
00384
00385 }
00386
00387
00388
00389 basl = r_lg10(&c_b35);
00390 i__1 = *ihi;
00391 for (i__ = *ilo; i__ <= i__1; ++i__) {
00392 i__2 = *ihi;
00393 for (j = *ilo; j <= i__2; ++j) {
00394 tb = b[i__ + j * b_dim1];
00395 ta = a[i__ + j * a_dim1];
00396 if (ta == 0.f) {
00397 goto L210;
00398 }
00399 r__1 = dabs(ta);
00400 ta = r_lg10(&r__1) / basl;
00401 L210:
00402 if (tb == 0.f) {
00403 goto L220;
00404 }
00405 r__1 = dabs(tb);
00406 tb = r_lg10(&r__1) / basl;
00407 L220:
00408 work[i__ + (*n << 2)] = work[i__ + (*n << 2)] - ta - tb;
00409 work[j + *n * 5] = work[j + *n * 5] - ta - tb;
00410
00411 }
00412
00413 }
00414
00415 coef = 1.f / (real) (nr << 1);
00416 coef2 = coef * coef;
00417 coef5 = coef2 * .5f;
00418 nrp2 = nr + 2;
00419 beta = 0.f;
00420 it = 1;
00421
00422
00423
00424 L250:
00425
00426 gamma = sdot_(&nr, &work[*ilo + (*n << 2)], &c__1, &work[*ilo + (*n << 2)]
00427 , &c__1) + sdot_(&nr, &work[*ilo + *n * 5], &c__1, &work[*ilo + *
00428 n * 5], &c__1);
00429
00430 ew = 0.f;
00431 ewc = 0.f;
00432 i__1 = *ihi;
00433 for (i__ = *ilo; i__ <= i__1; ++i__) {
00434 ew += work[i__ + (*n << 2)];
00435 ewc += work[i__ + *n * 5];
00436
00437 }
00438
00439
00440 r__1 = ew;
00441
00442 r__2 = ewc;
00443
00444 r__3 = ew - ewc;
00445 gamma = coef * gamma - coef2 * (r__1 * r__1 + r__2 * r__2) - coef5 * (
00446 r__3 * r__3);
00447 if (gamma == 0.f) {
00448 goto L350;
00449 }
00450 if (it != 1) {
00451 beta = gamma / pgamma;
00452 }
00453 t = coef5 * (ewc - ew * 3.f);
00454 tc = coef5 * (ew - ewc * 3.f);
00455
00456 sscal_(&nr, &beta, &work[*ilo], &c__1);
00457 sscal_(&nr, &beta, &work[*ilo + *n], &c__1);
00458
00459 saxpy_(&nr, &coef, &work[*ilo + (*n << 2)], &c__1, &work[*ilo + *n], &
00460 c__1);
00461 saxpy_(&nr, &coef, &work[*ilo + *n * 5], &c__1, &work[*ilo], &c__1);
00462
00463 i__1 = *ihi;
00464 for (i__ = *ilo; i__ <= i__1; ++i__) {
00465 work[i__] += tc;
00466 work[i__ + *n] += t;
00467
00468 }
00469
00470
00471
00472 i__1 = *ihi;
00473 for (i__ = *ilo; i__ <= i__1; ++i__) {
00474 kount = 0;
00475 sum = 0.f;
00476 i__2 = *ihi;
00477 for (j = *ilo; j <= i__2; ++j) {
00478 if (a[i__ + j * a_dim1] == 0.f) {
00479 goto L280;
00480 }
00481 ++kount;
00482 sum += work[j];
00483 L280:
00484 if (b[i__ + j * b_dim1] == 0.f) {
00485 goto L290;
00486 }
00487 ++kount;
00488 sum += work[j];
00489 L290:
00490 ;
00491 }
00492 work[i__ + (*n << 1)] = (real) kount * work[i__ + *n] + sum;
00493
00494 }
00495
00496 i__1 = *ihi;
00497 for (j = *ilo; j <= i__1; ++j) {
00498 kount = 0;
00499 sum = 0.f;
00500 i__2 = *ihi;
00501 for (i__ = *ilo; i__ <= i__2; ++i__) {
00502 if (a[i__ + j * a_dim1] == 0.f) {
00503 goto L310;
00504 }
00505 ++kount;
00506 sum += work[i__ + *n];
00507 L310:
00508 if (b[i__ + j * b_dim1] == 0.f) {
00509 goto L320;
00510 }
00511 ++kount;
00512 sum += work[i__ + *n];
00513 L320:
00514 ;
00515 }
00516 work[j + *n * 3] = (real) kount * work[j] + sum;
00517
00518 }
00519
00520 sum = sdot_(&nr, &work[*ilo + *n], &c__1, &work[*ilo + (*n << 1)], &c__1)
00521 + sdot_(&nr, &work[*ilo], &c__1, &work[*ilo + *n * 3], &c__1);
00522 alpha = gamma / sum;
00523
00524
00525
00526 cmax = 0.f;
00527 i__1 = *ihi;
00528 for (i__ = *ilo; i__ <= i__1; ++i__) {
00529 cor = alpha * work[i__ + *n];
00530 if (dabs(cor) > cmax) {
00531 cmax = dabs(cor);
00532 }
00533 lscale[i__] += cor;
00534 cor = alpha * work[i__];
00535 if (dabs(cor) > cmax) {
00536 cmax = dabs(cor);
00537 }
00538 rscale[i__] += cor;
00539
00540 }
00541 if (cmax < .5f) {
00542 goto L350;
00543 }
00544
00545 r__1 = -alpha;
00546 saxpy_(&nr, &r__1, &work[*ilo + (*n << 1)], &c__1, &work[*ilo + (*n << 2)]
00547 , &c__1);
00548 r__1 = -alpha;
00549 saxpy_(&nr, &r__1, &work[*ilo + *n * 3], &c__1, &work[*ilo + *n * 5], &
00550 c__1);
00551
00552 pgamma = gamma;
00553 ++it;
00554 if (it <= nrp2) {
00555 goto L250;
00556 }
00557
00558
00559
00560 L350:
00561 sfmin = slamch_("S");
00562 sfmax = 1.f / sfmin;
00563 lsfmin = (integer) (r_lg10(&sfmin) / basl + 1.f);
00564 lsfmax = (integer) (r_lg10(&sfmax) / basl);
00565 i__1 = *ihi;
00566 for (i__ = *ilo; i__ <= i__1; ++i__) {
00567 i__2 = *n - *ilo + 1;
00568 irab = isamax_(&i__2, &a[i__ + *ilo * a_dim1], lda);
00569 rab = (r__1 = a[i__ + (irab + *ilo - 1) * a_dim1], dabs(r__1));
00570 i__2 = *n - *ilo + 1;
00571 irab = isamax_(&i__2, &b[i__ + *ilo * b_dim1], ldb);
00572
00573 r__2 = rab, r__3 = (r__1 = b[i__ + (irab + *ilo - 1) * b_dim1], dabs(
00574 r__1));
00575 rab = dmax(r__2,r__3);
00576 r__1 = rab + sfmin;
00577 lrab = (integer) (r_lg10(&r__1) / basl + 1.f);
00578 ir = lscale[i__] + r_sign(&c_b71, &lscale[i__]);
00579
00580 i__2 = max(ir,lsfmin), i__2 = min(i__2,lsfmax), i__3 = lsfmax - lrab;
00581 ir = min(i__2,i__3);
00582 lscale[i__] = pow_ri(&c_b35, &ir);
00583 icab = isamax_(ihi, &a[i__ * a_dim1 + 1], &c__1);
00584 cab = (r__1 = a[icab + i__ * a_dim1], dabs(r__1));
00585 icab = isamax_(ihi, &b[i__ * b_dim1 + 1], &c__1);
00586
00587 r__2 = cab, r__3 = (r__1 = b[icab + i__ * b_dim1], dabs(r__1));
00588 cab = dmax(r__2,r__3);
00589 r__1 = cab + sfmin;
00590 lcab = (integer) (r_lg10(&r__1) / basl + 1.f);
00591 jc = rscale[i__] + r_sign(&c_b71, &rscale[i__]);
00592
00593 i__2 = max(jc,lsfmin), i__2 = min(i__2,lsfmax), i__3 = lsfmax - lcab;
00594 jc = min(i__2,i__3);
00595 rscale[i__] = pow_ri(&c_b35, &jc);
00596
00597 }
00598
00599
00600
00601 i__1 = *ihi;
00602 for (i__ = *ilo; i__ <= i__1; ++i__) {
00603 i__2 = *n - *ilo + 1;
00604 sscal_(&i__2, &lscale[i__], &a[i__ + *ilo * a_dim1], lda);
00605 i__2 = *n - *ilo + 1;
00606 sscal_(&i__2, &lscale[i__], &b[i__ + *ilo * b_dim1], ldb);
00607
00608 }
00609
00610
00611
00612 i__1 = *ihi;
00613 for (j = *ilo; j <= i__1; ++j) {
00614 sscal_(ihi, &rscale[j], &a[j * a_dim1 + 1], &c__1);
00615 sscal_(ihi, &rscale[j], &b[j * b_dim1 + 1], &c__1);
00616
00617 }
00618
00619 return 0;
00620
00621
00622
00623 }