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