dggbal.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /* dggbal.f -- translated by f2c (version 20061008).
  2. You must link the resulting object file with libf2c:
  3. on Microsoft Windows system, link with libf2c.lib;
  4. on Linux or Unix systems, link with .../path/to/libf2c.a -lm
  5. or, if you install libf2c.a in a standard place, with -lf2c -lm
  6. -- in that order, at the end of the command line, as in
  7. cc *.o -lf2c -lm
  8. Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
  9. http://www.netlib.org/f2c/libf2c.zip
  10. */
  11. #include "f2c.h"
  12. #include "blaswrap.h"
  13. /* Table of constant values */
  14. static integer c__1 = 1;
  15. static doublereal c_b35 = 10.;
  16. static doublereal c_b71 = .5;
  17. /* Subroutine */ int dggbal_(char *job, integer *n, doublereal *a, integer *
  18. lda, doublereal *b, integer *ldb, integer *ilo, integer *ihi,
  19. doublereal *lscale, doublereal *rscale, doublereal *work, integer *
  20. info)
  21. {
  22. /* System generated locals */
  23. integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
  24. doublereal d__1, d__2, d__3;
  25. /* Builtin functions */
  26. double d_lg10(doublereal *), d_sign(doublereal *, doublereal *), pow_di(
  27. doublereal *, integer *);
  28. /* Local variables */
  29. integer i__, j, k, l, m;
  30. doublereal t;
  31. integer jc;
  32. doublereal ta, tb, tc;
  33. integer ir;
  34. doublereal ew;
  35. integer it, nr, ip1, jp1, lm1;
  36. doublereal cab, rab, ewc, cor, sum;
  37. integer nrp2, icab, lcab;
  38. doublereal beta, coef;
  39. integer irab, lrab;
  40. doublereal basl, cmax;
  41. extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
  42. integer *);
  43. doublereal coef2, coef5, gamma, alpha;
  44. extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *,
  45. integer *);
  46. extern logical lsame_(char *, char *);
  47. doublereal sfmin, sfmax;
  48. extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *,
  49. doublereal *, integer *);
  50. integer iflow;
  51. extern /* Subroutine */ int daxpy_(integer *, doublereal *, doublereal *,
  52. integer *, doublereal *, integer *);
  53. integer kount;
  54. extern doublereal dlamch_(char *);
  55. doublereal pgamma;
  56. extern integer idamax_(integer *, doublereal *, integer *);
  57. extern /* Subroutine */ int xerbla_(char *, integer *);
  58. integer lsfmin, lsfmax;
  59. /* -- LAPACK routine (version 3.2) -- */
  60. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  61. /* November 2006 */
  62. /* .. Scalar Arguments .. */
  63. /* .. */
  64. /* .. Array Arguments .. */
  65. /* .. */
  66. /* Purpose */
  67. /* ======= */
  68. /* DGGBAL balances a pair of general real matrices (A,B). This */
  69. /* involves, first, permuting A and B by similarity transformations to */
  70. /* isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N */
  71. /* elements on the diagonal; and second, applying a diagonal similarity */
  72. /* transformation to rows and columns ILO to IHI to make the rows */
  73. /* and columns as close in norm as possible. Both steps are optional. */
  74. /* Balancing may reduce the 1-norm of the matrices, and improve the */
  75. /* accuracy of the computed eigenvalues and/or eigenvectors in the */
  76. /* generalized eigenvalue problem A*x = lambda*B*x. */
  77. /* Arguments */
  78. /* ========= */
  79. /* JOB (input) CHARACTER*1 */
  80. /* Specifies the operations to be performed on A and B: */
  81. /* = 'N': none: simply set ILO = 1, IHI = N, LSCALE(I) = 1.0 */
  82. /* and RSCALE(I) = 1.0 for i = 1,...,N. */
  83. /* = 'P': permute only; */
  84. /* = 'S': scale only; */
  85. /* = 'B': both permute and scale. */
  86. /* N (input) INTEGER */
  87. /* The order of the matrices A and B. N >= 0. */
  88. /* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
  89. /* On entry, the input matrix A. */
  90. /* On exit, A is overwritten by the balanced matrix. */
  91. /* If JOB = 'N', A is not referenced. */
  92. /* LDA (input) INTEGER */
  93. /* The leading dimension of the array A. LDA >= max(1,N). */
  94. /* B (input/output) DOUBLE PRECISION array, dimension (LDB,N) */
  95. /* On entry, the input matrix B. */
  96. /* On exit, B is overwritten by the balanced matrix. */
  97. /* If JOB = 'N', B is not referenced. */
  98. /* LDB (input) INTEGER */
  99. /* The leading dimension of the array B. LDB >= max(1,N). */
  100. /* ILO (output) INTEGER */
  101. /* IHI (output) INTEGER */
  102. /* ILO and IHI are set to integers such that on exit */
  103. /* A(i,j) = 0 and B(i,j) = 0 if i > j and */
  104. /* j = 1,...,ILO-1 or i = IHI+1,...,N. */
  105. /* If JOB = 'N' or 'S', ILO = 1 and IHI = N. */
  106. /* LSCALE (output) DOUBLE PRECISION array, dimension (N) */
  107. /* Details of the permutations and scaling factors applied */
  108. /* to the left side of A and B. If P(j) is the index of the */
  109. /* row interchanged with row j, and D(j) */
  110. /* is the scaling factor applied to row j, then */
  111. /* LSCALE(j) = P(j) for J = 1,...,ILO-1 */
  112. /* = D(j) for J = ILO,...,IHI */
  113. /* = P(j) for J = IHI+1,...,N. */
  114. /* The order in which the interchanges are made is N to IHI+1, */
  115. /* then 1 to ILO-1. */
  116. /* RSCALE (output) DOUBLE PRECISION array, dimension (N) */
  117. /* Details of the permutations and scaling factors applied */
  118. /* to the right side of A and B. If P(j) is the index of the */
  119. /* column interchanged with column j, and D(j) */
  120. /* is the scaling factor applied to column j, then */
  121. /* LSCALE(j) = P(j) for J = 1,...,ILO-1 */
  122. /* = D(j) for J = ILO,...,IHI */
  123. /* = P(j) for J = IHI+1,...,N. */
  124. /* The order in which the interchanges are made is N to IHI+1, */
  125. /* then 1 to ILO-1. */
  126. /* WORK (workspace) REAL array, dimension (lwork) */
  127. /* lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and */
  128. /* at least 1 when JOB = 'N' or 'P'. */
  129. /* INFO (output) INTEGER */
  130. /* = 0: successful exit */
  131. /* < 0: if INFO = -i, the i-th argument had an illegal value. */
  132. /* Further Details */
  133. /* =============== */
  134. /* See R.C. WARD, Balancing the generalized eigenvalue problem, */
  135. /* SIAM J. Sci. Stat. Comp. 2 (1981), 141-152. */
  136. /* ===================================================================== */
  137. /* .. Parameters .. */
  138. /* .. */
  139. /* .. Local Scalars .. */
  140. /* .. */
  141. /* .. External Functions .. */
  142. /* .. */
  143. /* .. External Subroutines .. */
  144. /* .. */
  145. /* .. Intrinsic Functions .. */
  146. /* .. */
  147. /* .. Executable Statements .. */
  148. /* Test the input parameters */
  149. /* Parameter adjustments */
  150. a_dim1 = *lda;
  151. a_offset = 1 + a_dim1;
  152. a -= a_offset;
  153. b_dim1 = *ldb;
  154. b_offset = 1 + b_dim1;
  155. b -= b_offset;
  156. --lscale;
  157. --rscale;
  158. --work;
  159. /* Function Body */
  160. *info = 0;
  161. if (! lsame_(job, "N") && ! lsame_(job, "P") && ! lsame_(job, "S")
  162. && ! lsame_(job, "B")) {
  163. *info = -1;
  164. } else if (*n < 0) {
  165. *info = -2;
  166. } else if (*lda < max(1,*n)) {
  167. *info = -4;
  168. } else if (*ldb < max(1,*n)) {
  169. *info = -6;
  170. }
  171. if (*info != 0) {
  172. i__1 = -(*info);
  173. xerbla_("DGGBAL", &i__1);
  174. return 0;
  175. }
  176. /* Quick return if possible */
  177. if (*n == 0) {
  178. *ilo = 1;
  179. *ihi = *n;
  180. return 0;
  181. }
  182. if (*n == 1) {
  183. *ilo = 1;
  184. *ihi = *n;
  185. lscale[1] = 1.;
  186. rscale[1] = 1.;
  187. return 0;
  188. }
  189. if (lsame_(job, "N")) {
  190. *ilo = 1;
  191. *ihi = *n;
  192. i__1 = *n;
  193. for (i__ = 1; i__ <= i__1; ++i__) {
  194. lscale[i__] = 1.;
  195. rscale[i__] = 1.;
  196. /* L10: */
  197. }
  198. return 0;
  199. }
  200. k = 1;
  201. l = *n;
  202. if (lsame_(job, "S")) {
  203. goto L190;
  204. }
  205. goto L30;
  206. /* Permute the matrices A and B to isolate the eigenvalues. */
  207. /* Find row with one nonzero in columns 1 through L */
  208. L20:
  209. l = lm1;
  210. if (l != 1) {
  211. goto L30;
  212. }
  213. rscale[1] = 1.;
  214. lscale[1] = 1.;
  215. goto L190;
  216. L30:
  217. lm1 = l - 1;
  218. for (i__ = l; i__ >= 1; --i__) {
  219. i__1 = lm1;
  220. for (j = 1; j <= i__1; ++j) {
  221. jp1 = j + 1;
  222. if (a[i__ + j * a_dim1] != 0. || b[i__ + j * b_dim1] != 0.) {
  223. goto L50;
  224. }
  225. /* L40: */
  226. }
  227. j = l;
  228. goto L70;
  229. L50:
  230. i__1 = l;
  231. for (j = jp1; j <= i__1; ++j) {
  232. if (a[i__ + j * a_dim1] != 0. || b[i__ + j * b_dim1] != 0.) {
  233. goto L80;
  234. }
  235. /* L60: */
  236. }
  237. j = jp1 - 1;
  238. L70:
  239. m = l;
  240. iflow = 1;
  241. goto L160;
  242. L80:
  243. ;
  244. }
  245. goto L100;
  246. /* Find column with one nonzero in rows K through N */
  247. L90:
  248. ++k;
  249. L100:
  250. i__1 = l;
  251. for (j = k; j <= i__1; ++j) {
  252. i__2 = lm1;
  253. for (i__ = k; i__ <= i__2; ++i__) {
  254. ip1 = i__ + 1;
  255. if (a[i__ + j * a_dim1] != 0. || b[i__ + j * b_dim1] != 0.) {
  256. goto L120;
  257. }
  258. /* L110: */
  259. }
  260. i__ = l;
  261. goto L140;
  262. L120:
  263. i__2 = l;
  264. for (i__ = ip1; i__ <= i__2; ++i__) {
  265. if (a[i__ + j * a_dim1] != 0. || b[i__ + j * b_dim1] != 0.) {
  266. goto L150;
  267. }
  268. /* L130: */
  269. }
  270. i__ = ip1 - 1;
  271. L140:
  272. m = k;
  273. iflow = 2;
  274. goto L160;
  275. L150:
  276. ;
  277. }
  278. goto L190;
  279. /* Permute rows M and I */
  280. L160:
  281. lscale[m] = (doublereal) i__;
  282. if (i__ == m) {
  283. goto L170;
  284. }
  285. i__1 = *n - k + 1;
  286. dswap_(&i__1, &a[i__ + k * a_dim1], lda, &a[m + k * a_dim1], lda);
  287. i__1 = *n - k + 1;
  288. dswap_(&i__1, &b[i__ + k * b_dim1], ldb, &b[m + k * b_dim1], ldb);
  289. /* Permute columns M and J */
  290. L170:
  291. rscale[m] = (doublereal) j;
  292. if (j == m) {
  293. goto L180;
  294. }
  295. dswap_(&l, &a[j * a_dim1 + 1], &c__1, &a[m * a_dim1 + 1], &c__1);
  296. dswap_(&l, &b[j * b_dim1 + 1], &c__1, &b[m * b_dim1 + 1], &c__1);
  297. L180:
  298. switch (iflow) {
  299. case 1: goto L20;
  300. case 2: goto L90;
  301. }
  302. L190:
  303. *ilo = k;
  304. *ihi = l;
  305. if (lsame_(job, "P")) {
  306. i__1 = *ihi;
  307. for (i__ = *ilo; i__ <= i__1; ++i__) {
  308. lscale[i__] = 1.;
  309. rscale[i__] = 1.;
  310. /* L195: */
  311. }
  312. return 0;
  313. }
  314. if (*ilo == *ihi) {
  315. return 0;
  316. }
  317. /* Balance the submatrix in rows ILO to IHI. */
  318. nr = *ihi - *ilo + 1;
  319. i__1 = *ihi;
  320. for (i__ = *ilo; i__ <= i__1; ++i__) {
  321. rscale[i__] = 0.;
  322. lscale[i__] = 0.;
  323. work[i__] = 0.;
  324. work[i__ + *n] = 0.;
  325. work[i__ + (*n << 1)] = 0.;
  326. work[i__ + *n * 3] = 0.;
  327. work[i__ + (*n << 2)] = 0.;
  328. work[i__ + *n * 5] = 0.;
  329. /* L200: */
  330. }
  331. /* Compute right side vector in resulting linear equations */
  332. basl = d_lg10(&c_b35);
  333. i__1 = *ihi;
  334. for (i__ = *ilo; i__ <= i__1; ++i__) {
  335. i__2 = *ihi;
  336. for (j = *ilo; j <= i__2; ++j) {
  337. tb = b[i__ + j * b_dim1];
  338. ta = a[i__ + j * a_dim1];
  339. if (ta == 0.) {
  340. goto L210;
  341. }
  342. d__1 = abs(ta);
  343. ta = d_lg10(&d__1) / basl;
  344. L210:
  345. if (tb == 0.) {
  346. goto L220;
  347. }
  348. d__1 = abs(tb);
  349. tb = d_lg10(&d__1) / basl;
  350. L220:
  351. work[i__ + (*n << 2)] = work[i__ + (*n << 2)] - ta - tb;
  352. work[j + *n * 5] = work[j + *n * 5] - ta - tb;
  353. /* L230: */
  354. }
  355. /* L240: */
  356. }
  357. coef = 1. / (doublereal) (nr << 1);
  358. coef2 = coef * coef;
  359. coef5 = coef2 * .5;
  360. nrp2 = nr + 2;
  361. beta = 0.;
  362. it = 1;
  363. /* Start generalized conjugate gradient iteration */
  364. L250:
  365. gamma = ddot_(&nr, &work[*ilo + (*n << 2)], &c__1, &work[*ilo + (*n << 2)]
  366. , &c__1) + ddot_(&nr, &work[*ilo + *n * 5], &c__1, &work[*ilo + *
  367. n * 5], &c__1);
  368. ew = 0.;
  369. ewc = 0.;
  370. i__1 = *ihi;
  371. for (i__ = *ilo; i__ <= i__1; ++i__) {
  372. ew += work[i__ + (*n << 2)];
  373. ewc += work[i__ + *n * 5];
  374. /* L260: */
  375. }
  376. /* Computing 2nd power */
  377. d__1 = ew;
  378. /* Computing 2nd power */
  379. d__2 = ewc;
  380. /* Computing 2nd power */
  381. d__3 = ew - ewc;
  382. gamma = coef * gamma - coef2 * (d__1 * d__1 + d__2 * d__2) - coef5 * (
  383. d__3 * d__3);
  384. if (gamma == 0.) {
  385. goto L350;
  386. }
  387. if (it != 1) {
  388. beta = gamma / pgamma;
  389. }
  390. t = coef5 * (ewc - ew * 3.);
  391. tc = coef5 * (ew - ewc * 3.);
  392. dscal_(&nr, &beta, &work[*ilo], &c__1);
  393. dscal_(&nr, &beta, &work[*ilo + *n], &c__1);
  394. daxpy_(&nr, &coef, &work[*ilo + (*n << 2)], &c__1, &work[*ilo + *n], &
  395. c__1);
  396. daxpy_(&nr, &coef, &work[*ilo + *n * 5], &c__1, &work[*ilo], &c__1);
  397. i__1 = *ihi;
  398. for (i__ = *ilo; i__ <= i__1; ++i__) {
  399. work[i__] += tc;
  400. work[i__ + *n] += t;
  401. /* L270: */
  402. }
  403. /* Apply matrix to vector */
  404. i__1 = *ihi;
  405. for (i__ = *ilo; i__ <= i__1; ++i__) {
  406. kount = 0;
  407. sum = 0.;
  408. i__2 = *ihi;
  409. for (j = *ilo; j <= i__2; ++j) {
  410. if (a[i__ + j * a_dim1] == 0.) {
  411. goto L280;
  412. }
  413. ++kount;
  414. sum += work[j];
  415. L280:
  416. if (b[i__ + j * b_dim1] == 0.) {
  417. goto L290;
  418. }
  419. ++kount;
  420. sum += work[j];
  421. L290:
  422. ;
  423. }
  424. work[i__ + (*n << 1)] = (doublereal) kount * work[i__ + *n] + sum;
  425. /* L300: */
  426. }
  427. i__1 = *ihi;
  428. for (j = *ilo; j <= i__1; ++j) {
  429. kount = 0;
  430. sum = 0.;
  431. i__2 = *ihi;
  432. for (i__ = *ilo; i__ <= i__2; ++i__) {
  433. if (a[i__ + j * a_dim1] == 0.) {
  434. goto L310;
  435. }
  436. ++kount;
  437. sum += work[i__ + *n];
  438. L310:
  439. if (b[i__ + j * b_dim1] == 0.) {
  440. goto L320;
  441. }
  442. ++kount;
  443. sum += work[i__ + *n];
  444. L320:
  445. ;
  446. }
  447. work[j + *n * 3] = (doublereal) kount * work[j] + sum;
  448. /* L330: */
  449. }
  450. sum = ddot_(&nr, &work[*ilo + *n], &c__1, &work[*ilo + (*n << 1)], &c__1)
  451. + ddot_(&nr, &work[*ilo], &c__1, &work[*ilo + *n * 3], &c__1);
  452. alpha = gamma / sum;
  453. /* Determine correction to current iteration */
  454. cmax = 0.;
  455. i__1 = *ihi;
  456. for (i__ = *ilo; i__ <= i__1; ++i__) {
  457. cor = alpha * work[i__ + *n];
  458. if (abs(cor) > cmax) {
  459. cmax = abs(cor);
  460. }
  461. lscale[i__] += cor;
  462. cor = alpha * work[i__];
  463. if (abs(cor) > cmax) {
  464. cmax = abs(cor);
  465. }
  466. rscale[i__] += cor;
  467. /* L340: */
  468. }
  469. if (cmax < .5) {
  470. goto L350;
  471. }
  472. d__1 = -alpha;
  473. daxpy_(&nr, &d__1, &work[*ilo + (*n << 1)], &c__1, &work[*ilo + (*n << 2)]
  474. , &c__1);
  475. d__1 = -alpha;
  476. daxpy_(&nr, &d__1, &work[*ilo + *n * 3], &c__1, &work[*ilo + *n * 5], &
  477. c__1);
  478. pgamma = gamma;
  479. ++it;
  480. if (it <= nrp2) {
  481. goto L250;
  482. }
  483. /* End generalized conjugate gradient iteration */
  484. L350:
  485. sfmin = dlamch_("S");
  486. sfmax = 1. / sfmin;
  487. lsfmin = (integer) (d_lg10(&sfmin) / basl + 1.);
  488. lsfmax = (integer) (d_lg10(&sfmax) / basl);
  489. i__1 = *ihi;
  490. for (i__ = *ilo; i__ <= i__1; ++i__) {
  491. i__2 = *n - *ilo + 1;
  492. irab = idamax_(&i__2, &a[i__ + *ilo * a_dim1], lda);
  493. rab = (d__1 = a[i__ + (irab + *ilo - 1) * a_dim1], abs(d__1));
  494. i__2 = *n - *ilo + 1;
  495. irab = idamax_(&i__2, &b[i__ + *ilo * b_dim1], ldb);
  496. /* Computing MAX */
  497. d__2 = rab, d__3 = (d__1 = b[i__ + (irab + *ilo - 1) * b_dim1], abs(
  498. d__1));
  499. rab = max(d__2,d__3);
  500. d__1 = rab + sfmin;
  501. lrab = (integer) (d_lg10(&d__1) / basl + 1.);
  502. ir = (integer) (lscale[i__] + d_sign(&c_b71, &lscale[i__]));
  503. /* Computing MIN */
  504. i__2 = max(ir,lsfmin), i__2 = min(i__2,lsfmax), i__3 = lsfmax - lrab;
  505. ir = min(i__2,i__3);
  506. lscale[i__] = pow_di(&c_b35, &ir);
  507. icab = idamax_(ihi, &a[i__ * a_dim1 + 1], &c__1);
  508. cab = (d__1 = a[icab + i__ * a_dim1], abs(d__1));
  509. icab = idamax_(ihi, &b[i__ * b_dim1 + 1], &c__1);
  510. /* Computing MAX */
  511. d__2 = cab, d__3 = (d__1 = b[icab + i__ * b_dim1], abs(d__1));
  512. cab = max(d__2,d__3);
  513. d__1 = cab + sfmin;
  514. lcab = (integer) (d_lg10(&d__1) / basl + 1.);
  515. jc = (integer) (rscale[i__] + d_sign(&c_b71, &rscale[i__]));
  516. /* Computing MIN */
  517. i__2 = max(jc,lsfmin), i__2 = min(i__2,lsfmax), i__3 = lsfmax - lcab;
  518. jc = min(i__2,i__3);
  519. rscale[i__] = pow_di(&c_b35, &jc);
  520. /* L360: */
  521. }
  522. /* Row scaling of matrices A and B */
  523. i__1 = *ihi;
  524. for (i__ = *ilo; i__ <= i__1; ++i__) {
  525. i__2 = *n - *ilo + 1;
  526. dscal_(&i__2, &lscale[i__], &a[i__ + *ilo * a_dim1], lda);
  527. i__2 = *n - *ilo + 1;
  528. dscal_(&i__2, &lscale[i__], &b[i__ + *ilo * b_dim1], ldb);
  529. /* L370: */
  530. }
  531. /* Column scaling of matrices A and B */
  532. i__1 = *ihi;
  533. for (j = *ilo; j <= i__1; ++j) {
  534. dscal_(ihi, &rscale[j], &a[j * a_dim1 + 1], &c__1);
  535. dscal_(ihi, &rscale[j], &b[j * b_dim1 + 1], &c__1);
  536. /* L380: */
  537. }
  538. return 0;
  539. /* End of DGGBAL */
  540. } /* dggbal_ */