dtrexc.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /* dtrexc.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 integer c__2 = 2;
  16. /* Subroutine */ int _starpu_dtrexc_(char *compq, integer *n, doublereal *t, integer *
  17. ldt, doublereal *q, integer *ldq, integer *ifst, integer *ilst,
  18. doublereal *work, integer *info)
  19. {
  20. /* System generated locals */
  21. integer q_dim1, q_offset, t_dim1, t_offset, i__1;
  22. /* Local variables */
  23. integer nbf, nbl, here;
  24. extern logical _starpu_lsame_(char *, char *);
  25. logical wantq;
  26. extern /* Subroutine */ int _starpu_dlaexc_(logical *, integer *, doublereal *,
  27. integer *, doublereal *, integer *, integer *, integer *, integer
  28. *, doublereal *, integer *), _starpu_xerbla_(char *, integer *);
  29. integer nbnext;
  30. /* -- LAPACK routine (version 3.2) -- */
  31. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  32. /* November 2006 */
  33. /* .. Scalar Arguments .. */
  34. /* .. */
  35. /* .. Array Arguments .. */
  36. /* .. */
  37. /* Purpose */
  38. /* ======= */
  39. /* DTREXC reorders the real Schur factorization of a real matrix */
  40. /* A = Q*T*Q**T, so that the diagonal block of T with row index IFST is */
  41. /* moved to row ILST. */
  42. /* The real Schur form T is reordered by an orthogonal similarity */
  43. /* transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors */
  44. /* is updated by postmultiplying it with Z. */
  45. /* T must be in Schur canonical form (as returned by DHSEQR), that is, */
  46. /* block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each */
  47. /* 2-by-2 diagonal block has its diagonal elements equal and its */
  48. /* off-diagonal elements of opposite sign. */
  49. /* Arguments */
  50. /* ========= */
  51. /* COMPQ (input) CHARACTER*1 */
  52. /* = 'V': update the matrix Q of Schur vectors; */
  53. /* = 'N': do not update Q. */
  54. /* N (input) INTEGER */
  55. /* The order of the matrix T. N >= 0. */
  56. /* T (input/output) DOUBLE PRECISION array, dimension (LDT,N) */
  57. /* On entry, the upper quasi-triangular matrix T, in Schur */
  58. /* Schur canonical form. */
  59. /* On exit, the reordered upper quasi-triangular matrix, again */
  60. /* in Schur canonical form. */
  61. /* LDT (input) INTEGER */
  62. /* The leading dimension of the array T. LDT >= max(1,N). */
  63. /* Q (input/output) DOUBLE PRECISION array, dimension (LDQ,N) */
  64. /* On entry, if COMPQ = 'V', the matrix Q of Schur vectors. */
  65. /* On exit, if COMPQ = 'V', Q has been postmultiplied by the */
  66. /* orthogonal transformation matrix Z which reorders T. */
  67. /* If COMPQ = 'N', Q is not referenced. */
  68. /* LDQ (input) INTEGER */
  69. /* The leading dimension of the array Q. LDQ >= max(1,N). */
  70. /* IFST (input/output) INTEGER */
  71. /* ILST (input/output) INTEGER */
  72. /* Specify the reordering of the diagonal blocks of T. */
  73. /* The block with row index IFST is moved to row ILST, by a */
  74. /* sequence of transpositions between adjacent blocks. */
  75. /* On exit, if IFST pointed on entry to the second row of a */
  76. /* 2-by-2 block, it is changed to point to the first row; ILST */
  77. /* always points to the first row of the block in its final */
  78. /* position (which may differ from its input value by +1 or -1). */
  79. /* 1 <= IFST <= N; 1 <= ILST <= N. */
  80. /* WORK (workspace) DOUBLE PRECISION array, dimension (N) */
  81. /* INFO (output) INTEGER */
  82. /* = 0: successful exit */
  83. /* < 0: if INFO = -i, the i-th argument had an illegal value */
  84. /* = 1: two adjacent blocks were too close to swap (the problem */
  85. /* is very ill-conditioned); T may have been partially */
  86. /* reordered, and ILST points to the first row of the */
  87. /* current position of the block being moved. */
  88. /* ===================================================================== */
  89. /* .. Parameters .. */
  90. /* .. */
  91. /* .. Local Scalars .. */
  92. /* .. */
  93. /* .. External Functions .. */
  94. /* .. */
  95. /* .. External Subroutines .. */
  96. /* .. */
  97. /* .. Intrinsic Functions .. */
  98. /* .. */
  99. /* .. Executable Statements .. */
  100. /* Decode and test the input arguments. */
  101. /* Parameter adjustments */
  102. t_dim1 = *ldt;
  103. t_offset = 1 + t_dim1;
  104. t -= t_offset;
  105. q_dim1 = *ldq;
  106. q_offset = 1 + q_dim1;
  107. q -= q_offset;
  108. --work;
  109. /* Function Body */
  110. *info = 0;
  111. wantq = _starpu_lsame_(compq, "V");
  112. if (! wantq && ! _starpu_lsame_(compq, "N")) {
  113. *info = -1;
  114. } else if (*n < 0) {
  115. *info = -2;
  116. } else if (*ldt < max(1,*n)) {
  117. *info = -4;
  118. } else if (*ldq < 1 || wantq && *ldq < max(1,*n)) {
  119. *info = -6;
  120. } else if (*ifst < 1 || *ifst > *n) {
  121. *info = -7;
  122. } else if (*ilst < 1 || *ilst > *n) {
  123. *info = -8;
  124. }
  125. if (*info != 0) {
  126. i__1 = -(*info);
  127. _starpu_xerbla_("DTREXC", &i__1);
  128. return 0;
  129. }
  130. /* Quick return if possible */
  131. if (*n <= 1) {
  132. return 0;
  133. }
  134. /* Determine the first row of specified block */
  135. /* and find out it is 1 by 1 or 2 by 2. */
  136. if (*ifst > 1) {
  137. if (t[*ifst + (*ifst - 1) * t_dim1] != 0.) {
  138. --(*ifst);
  139. }
  140. }
  141. nbf = 1;
  142. if (*ifst < *n) {
  143. if (t[*ifst + 1 + *ifst * t_dim1] != 0.) {
  144. nbf = 2;
  145. }
  146. }
  147. /* Determine the first row of the final block */
  148. /* and find out it is 1 by 1 or 2 by 2. */
  149. if (*ilst > 1) {
  150. if (t[*ilst + (*ilst - 1) * t_dim1] != 0.) {
  151. --(*ilst);
  152. }
  153. }
  154. nbl = 1;
  155. if (*ilst < *n) {
  156. if (t[*ilst + 1 + *ilst * t_dim1] != 0.) {
  157. nbl = 2;
  158. }
  159. }
  160. if (*ifst == *ilst) {
  161. return 0;
  162. }
  163. if (*ifst < *ilst) {
  164. /* Update ILST */
  165. if (nbf == 2 && nbl == 1) {
  166. --(*ilst);
  167. }
  168. if (nbf == 1 && nbl == 2) {
  169. ++(*ilst);
  170. }
  171. here = *ifst;
  172. L10:
  173. /* Swap block with next one below */
  174. if (nbf == 1 || nbf == 2) {
  175. /* Current block either 1 by 1 or 2 by 2 */
  176. nbnext = 1;
  177. if (here + nbf + 1 <= *n) {
  178. if (t[here + nbf + 1 + (here + nbf) * t_dim1] != 0.) {
  179. nbnext = 2;
  180. }
  181. }
  182. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &here, &
  183. nbf, &nbnext, &work[1], info);
  184. if (*info != 0) {
  185. *ilst = here;
  186. return 0;
  187. }
  188. here += nbnext;
  189. /* Test if 2 by 2 block breaks into two 1 by 1 blocks */
  190. if (nbf == 2) {
  191. if (t[here + 1 + here * t_dim1] == 0.) {
  192. nbf = 3;
  193. }
  194. }
  195. } else {
  196. /* Current block consists of two 1 by 1 blocks each of which */
  197. /* must be swapped individually */
  198. nbnext = 1;
  199. if (here + 3 <= *n) {
  200. if (t[here + 3 + (here + 2) * t_dim1] != 0.) {
  201. nbnext = 2;
  202. }
  203. }
  204. i__1 = here + 1;
  205. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &i__1, &
  206. c__1, &nbnext, &work[1], info);
  207. if (*info != 0) {
  208. *ilst = here;
  209. return 0;
  210. }
  211. if (nbnext == 1) {
  212. /* Swap two 1 by 1 blocks, no problems possible */
  213. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &
  214. here, &c__1, &nbnext, &work[1], info);
  215. ++here;
  216. } else {
  217. /* Recompute NBNEXT in case 2 by 2 split */
  218. if (t[here + 2 + (here + 1) * t_dim1] == 0.) {
  219. nbnext = 1;
  220. }
  221. if (nbnext == 2) {
  222. /* 2 by 2 Block did not split */
  223. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &
  224. here, &c__1, &nbnext, &work[1], info);
  225. if (*info != 0) {
  226. *ilst = here;
  227. return 0;
  228. }
  229. here += 2;
  230. } else {
  231. /* 2 by 2 Block did split */
  232. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &
  233. here, &c__1, &c__1, &work[1], info);
  234. i__1 = here + 1;
  235. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &
  236. i__1, &c__1, &c__1, &work[1], info);
  237. here += 2;
  238. }
  239. }
  240. }
  241. if (here < *ilst) {
  242. goto L10;
  243. }
  244. } else {
  245. here = *ifst;
  246. L20:
  247. /* Swap block with next one above */
  248. if (nbf == 1 || nbf == 2) {
  249. /* Current block either 1 by 1 or 2 by 2 */
  250. nbnext = 1;
  251. if (here >= 3) {
  252. if (t[here - 1 + (here - 2) * t_dim1] != 0.) {
  253. nbnext = 2;
  254. }
  255. }
  256. i__1 = here - nbnext;
  257. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &i__1, &
  258. nbnext, &nbf, &work[1], info);
  259. if (*info != 0) {
  260. *ilst = here;
  261. return 0;
  262. }
  263. here -= nbnext;
  264. /* Test if 2 by 2 block breaks into two 1 by 1 blocks */
  265. if (nbf == 2) {
  266. if (t[here + 1 + here * t_dim1] == 0.) {
  267. nbf = 3;
  268. }
  269. }
  270. } else {
  271. /* Current block consists of two 1 by 1 blocks each of which */
  272. /* must be swapped individually */
  273. nbnext = 1;
  274. if (here >= 3) {
  275. if (t[here - 1 + (here - 2) * t_dim1] != 0.) {
  276. nbnext = 2;
  277. }
  278. }
  279. i__1 = here - nbnext;
  280. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &i__1, &
  281. nbnext, &c__1, &work[1], info);
  282. if (*info != 0) {
  283. *ilst = here;
  284. return 0;
  285. }
  286. if (nbnext == 1) {
  287. /* Swap two 1 by 1 blocks, no problems possible */
  288. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &
  289. here, &nbnext, &c__1, &work[1], info);
  290. --here;
  291. } else {
  292. /* Recompute NBNEXT in case 2 by 2 split */
  293. if (t[here + (here - 1) * t_dim1] == 0.) {
  294. nbnext = 1;
  295. }
  296. if (nbnext == 2) {
  297. /* 2 by 2 Block did not split */
  298. i__1 = here - 1;
  299. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &
  300. i__1, &c__2, &c__1, &work[1], info);
  301. if (*info != 0) {
  302. *ilst = here;
  303. return 0;
  304. }
  305. here += -2;
  306. } else {
  307. /* 2 by 2 Block did split */
  308. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &
  309. here, &c__1, &c__1, &work[1], info);
  310. i__1 = here - 1;
  311. _starpu_dlaexc_(&wantq, n, &t[t_offset], ldt, &q[q_offset], ldq, &
  312. i__1, &c__1, &c__1, &work[1], info);
  313. here += -2;
  314. }
  315. }
  316. }
  317. if (here > *ilst) {
  318. goto L20;
  319. }
  320. }
  321. *ilst = here;
  322. return 0;
  323. /* End of DTREXC */
  324. } /* _starpu_dtrexc_ */