dlasy2.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /* dlasy2.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__4 = 4;
  15. static integer c__1 = 1;
  16. static integer c__16 = 16;
  17. static integer c__0 = 0;
  18. /* Subroutine */ int _starpu_dlasy2_(logical *ltranl, logical *ltranr, integer *isgn,
  19. integer *n1, integer *n2, doublereal *tl, integer *ldtl, doublereal *
  20. tr, integer *ldtr, doublereal *b, integer *ldb, doublereal *scale,
  21. doublereal *x, integer *ldx, doublereal *xnorm, integer *info)
  22. {
  23. /* Initialized data */
  24. static integer locu12[4] = { 3,4,1,2 };
  25. static integer locl21[4] = { 2,1,4,3 };
  26. static integer locu22[4] = { 4,3,2,1 };
  27. static logical xswpiv[4] = { FALSE_,FALSE_,TRUE_,TRUE_ };
  28. static logical bswpiv[4] = { FALSE_,TRUE_,FALSE_,TRUE_ };
  29. /* System generated locals */
  30. integer b_dim1, b_offset, tl_dim1, tl_offset, tr_dim1, tr_offset, x_dim1,
  31. x_offset;
  32. doublereal d__1, d__2, d__3, d__4, d__5, d__6, d__7, d__8;
  33. /* Local variables */
  34. integer i__, j, k;
  35. doublereal x2[2], l21, u11, u12;
  36. integer ip, jp;
  37. doublereal u22, t16[16] /* was [4][4] */, gam, bet, eps, sgn, tmp[4],
  38. tau1, btmp[4], smin;
  39. integer ipiv;
  40. doublereal temp;
  41. integer jpiv[4];
  42. doublereal xmax;
  43. integer ipsv, jpsv;
  44. logical bswap;
  45. extern /* Subroutine */ int _starpu_dcopy_(integer *, doublereal *, integer *,
  46. doublereal *, integer *), _starpu_dswap_(integer *, doublereal *, integer
  47. *, doublereal *, integer *);
  48. logical xswap;
  49. extern doublereal _starpu_dlamch_(char *);
  50. extern integer _starpu_idamax_(integer *, doublereal *, integer *);
  51. doublereal smlnum;
  52. /* -- LAPACK auxiliary routine (version 3.2) -- */
  53. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  54. /* November 2006 */
  55. /* .. Scalar Arguments .. */
  56. /* .. */
  57. /* .. Array Arguments .. */
  58. /* .. */
  59. /* Purpose */
  60. /* ======= */
  61. /* DLASY2 solves for the N1 by N2 matrix X, 1 <= N1,N2 <= 2, in */
  62. /* op(TL)*X + ISGN*X*op(TR) = SCALE*B, */
  63. /* where TL is N1 by N1, TR is N2 by N2, B is N1 by N2, and ISGN = 1 or */
  64. /* -1. op(T) = T or T', where T' denotes the transpose of T. */
  65. /* Arguments */
  66. /* ========= */
  67. /* LTRANL (input) LOGICAL */
  68. /* On entry, LTRANL specifies the op(TL): */
  69. /* = .FALSE., op(TL) = TL, */
  70. /* = .TRUE., op(TL) = TL'. */
  71. /* LTRANR (input) LOGICAL */
  72. /* On entry, LTRANR specifies the op(TR): */
  73. /* = .FALSE., op(TR) = TR, */
  74. /* = .TRUE., op(TR) = TR'. */
  75. /* ISGN (input) INTEGER */
  76. /* On entry, ISGN specifies the sign of the equation */
  77. /* as described before. ISGN may only be 1 or -1. */
  78. /* N1 (input) INTEGER */
  79. /* On entry, N1 specifies the order of matrix TL. */
  80. /* N1 may only be 0, 1 or 2. */
  81. /* N2 (input) INTEGER */
  82. /* On entry, N2 specifies the order of matrix TR. */
  83. /* N2 may only be 0, 1 or 2. */
  84. /* TL (input) DOUBLE PRECISION array, dimension (LDTL,2) */
  85. /* On entry, TL contains an N1 by N1 matrix. */
  86. /* LDTL (input) INTEGER */
  87. /* The leading dimension of the matrix TL. LDTL >= max(1,N1). */
  88. /* TR (input) DOUBLE PRECISION array, dimension (LDTR,2) */
  89. /* On entry, TR contains an N2 by N2 matrix. */
  90. /* LDTR (input) INTEGER */
  91. /* The leading dimension of the matrix TR. LDTR >= max(1,N2). */
  92. /* B (input) DOUBLE PRECISION array, dimension (LDB,2) */
  93. /* On entry, the N1 by N2 matrix B contains the right-hand */
  94. /* side of the equation. */
  95. /* LDB (input) INTEGER */
  96. /* The leading dimension of the matrix B. LDB >= max(1,N1). */
  97. /* SCALE (output) DOUBLE PRECISION */
  98. /* On exit, SCALE contains the scale factor. SCALE is chosen */
  99. /* less than or equal to 1 to prevent the solution overflowing. */
  100. /* X (output) DOUBLE PRECISION array, dimension (LDX,2) */
  101. /* On exit, X contains the N1 by N2 solution. */
  102. /* LDX (input) INTEGER */
  103. /* The leading dimension of the matrix X. LDX >= max(1,N1). */
  104. /* XNORM (output) DOUBLE PRECISION */
  105. /* On exit, XNORM is the infinity-norm of the solution. */
  106. /* INFO (output) INTEGER */
  107. /* On exit, INFO is set to */
  108. /* 0: successful exit. */
  109. /* 1: TL and TR have too close eigenvalues, so TL or */
  110. /* TR is perturbed to get a nonsingular equation. */
  111. /* NOTE: In the interests of speed, this routine does not */
  112. /* check the inputs for errors. */
  113. /* ===================================================================== */
  114. /* .. Parameters .. */
  115. /* .. */
  116. /* .. Local Scalars .. */
  117. /* .. */
  118. /* .. Local Arrays .. */
  119. /* .. */
  120. /* .. External Functions .. */
  121. /* .. */
  122. /* .. External Subroutines .. */
  123. /* .. */
  124. /* .. Intrinsic Functions .. */
  125. /* .. */
  126. /* .. Data statements .. */
  127. /* Parameter adjustments */
  128. tl_dim1 = *ldtl;
  129. tl_offset = 1 + tl_dim1;
  130. tl -= tl_offset;
  131. tr_dim1 = *ldtr;
  132. tr_offset = 1 + tr_dim1;
  133. tr -= tr_offset;
  134. b_dim1 = *ldb;
  135. b_offset = 1 + b_dim1;
  136. b -= b_offset;
  137. x_dim1 = *ldx;
  138. x_offset = 1 + x_dim1;
  139. x -= x_offset;
  140. /* Function Body */
  141. /* .. */
  142. /* .. Executable Statements .. */
  143. /* Do not check the input parameters for errors */
  144. *info = 0;
  145. /* Quick return if possible */
  146. if (*n1 == 0 || *n2 == 0) {
  147. return 0;
  148. }
  149. /* Set constants to control overflow */
  150. eps = _starpu_dlamch_("P");
  151. smlnum = _starpu_dlamch_("S") / eps;
  152. sgn = (doublereal) (*isgn);
  153. k = *n1 + *n1 + *n2 - 2;
  154. switch (k) {
  155. case 1: goto L10;
  156. case 2: goto L20;
  157. case 3: goto L30;
  158. case 4: goto L50;
  159. }
  160. /* 1 by 1: TL11*X + SGN*X*TR11 = B11 */
  161. L10:
  162. tau1 = tl[tl_dim1 + 1] + sgn * tr[tr_dim1 + 1];
  163. bet = abs(tau1);
  164. if (bet <= smlnum) {
  165. tau1 = smlnum;
  166. bet = smlnum;
  167. *info = 1;
  168. }
  169. *scale = 1.;
  170. gam = (d__1 = b[b_dim1 + 1], abs(d__1));
  171. if (smlnum * gam > bet) {
  172. *scale = 1. / gam;
  173. }
  174. x[x_dim1 + 1] = b[b_dim1 + 1] * *scale / tau1;
  175. *xnorm = (d__1 = x[x_dim1 + 1], abs(d__1));
  176. return 0;
  177. /* 1 by 2: */
  178. /* TL11*[X11 X12] + ISGN*[X11 X12]*op[TR11 TR12] = [B11 B12] */
  179. /* [TR21 TR22] */
  180. L20:
  181. /* Computing MAX */
  182. /* Computing MAX */
  183. d__7 = (d__1 = tl[tl_dim1 + 1], abs(d__1)), d__8 = (d__2 = tr[tr_dim1 + 1]
  184. , abs(d__2)), d__7 = max(d__7,d__8), d__8 = (d__3 = tr[(tr_dim1 <<
  185. 1) + 1], abs(d__3)), d__7 = max(d__7,d__8), d__8 = (d__4 = tr[
  186. tr_dim1 + 2], abs(d__4)), d__7 = max(d__7,d__8), d__8 = (d__5 =
  187. tr[(tr_dim1 << 1) + 2], abs(d__5));
  188. d__6 = eps * max(d__7,d__8);
  189. smin = max(d__6,smlnum);
  190. tmp[0] = tl[tl_dim1 + 1] + sgn * tr[tr_dim1 + 1];
  191. tmp[3] = tl[tl_dim1 + 1] + sgn * tr[(tr_dim1 << 1) + 2];
  192. if (*ltranr) {
  193. tmp[1] = sgn * tr[tr_dim1 + 2];
  194. tmp[2] = sgn * tr[(tr_dim1 << 1) + 1];
  195. } else {
  196. tmp[1] = sgn * tr[(tr_dim1 << 1) + 1];
  197. tmp[2] = sgn * tr[tr_dim1 + 2];
  198. }
  199. btmp[0] = b[b_dim1 + 1];
  200. btmp[1] = b[(b_dim1 << 1) + 1];
  201. goto L40;
  202. /* 2 by 1: */
  203. /* op[TL11 TL12]*[X11] + ISGN* [X11]*TR11 = [B11] */
  204. /* [TL21 TL22] [X21] [X21] [B21] */
  205. L30:
  206. /* Computing MAX */
  207. /* Computing MAX */
  208. d__7 = (d__1 = tr[tr_dim1 + 1], abs(d__1)), d__8 = (d__2 = tl[tl_dim1 + 1]
  209. , abs(d__2)), d__7 = max(d__7,d__8), d__8 = (d__3 = tl[(tl_dim1 <<
  210. 1) + 1], abs(d__3)), d__7 = max(d__7,d__8), d__8 = (d__4 = tl[
  211. tl_dim1 + 2], abs(d__4)), d__7 = max(d__7,d__8), d__8 = (d__5 =
  212. tl[(tl_dim1 << 1) + 2], abs(d__5));
  213. d__6 = eps * max(d__7,d__8);
  214. smin = max(d__6,smlnum);
  215. tmp[0] = tl[tl_dim1 + 1] + sgn * tr[tr_dim1 + 1];
  216. tmp[3] = tl[(tl_dim1 << 1) + 2] + sgn * tr[tr_dim1 + 1];
  217. if (*ltranl) {
  218. tmp[1] = tl[(tl_dim1 << 1) + 1];
  219. tmp[2] = tl[tl_dim1 + 2];
  220. } else {
  221. tmp[1] = tl[tl_dim1 + 2];
  222. tmp[2] = tl[(tl_dim1 << 1) + 1];
  223. }
  224. btmp[0] = b[b_dim1 + 1];
  225. btmp[1] = b[b_dim1 + 2];
  226. L40:
  227. /* Solve 2 by 2 system using complete pivoting. */
  228. /* Set pivots less than SMIN to SMIN. */
  229. ipiv = _starpu_idamax_(&c__4, tmp, &c__1);
  230. u11 = tmp[ipiv - 1];
  231. if (abs(u11) <= smin) {
  232. *info = 1;
  233. u11 = smin;
  234. }
  235. u12 = tmp[locu12[ipiv - 1] - 1];
  236. l21 = tmp[locl21[ipiv - 1] - 1] / u11;
  237. u22 = tmp[locu22[ipiv - 1] - 1] - u12 * l21;
  238. xswap = xswpiv[ipiv - 1];
  239. bswap = bswpiv[ipiv - 1];
  240. if (abs(u22) <= smin) {
  241. *info = 1;
  242. u22 = smin;
  243. }
  244. if (bswap) {
  245. temp = btmp[1];
  246. btmp[1] = btmp[0] - l21 * temp;
  247. btmp[0] = temp;
  248. } else {
  249. btmp[1] -= l21 * btmp[0];
  250. }
  251. *scale = 1.;
  252. if (smlnum * 2. * abs(btmp[1]) > abs(u22) || smlnum * 2. * abs(btmp[0]) >
  253. abs(u11)) {
  254. /* Computing MAX */
  255. d__1 = abs(btmp[0]), d__2 = abs(btmp[1]);
  256. *scale = .5 / max(d__1,d__2);
  257. btmp[0] *= *scale;
  258. btmp[1] *= *scale;
  259. }
  260. x2[1] = btmp[1] / u22;
  261. x2[0] = btmp[0] / u11 - u12 / u11 * x2[1];
  262. if (xswap) {
  263. temp = x2[1];
  264. x2[1] = x2[0];
  265. x2[0] = temp;
  266. }
  267. x[x_dim1 + 1] = x2[0];
  268. if (*n1 == 1) {
  269. x[(x_dim1 << 1) + 1] = x2[1];
  270. *xnorm = (d__1 = x[x_dim1 + 1], abs(d__1)) + (d__2 = x[(x_dim1 << 1)
  271. + 1], abs(d__2));
  272. } else {
  273. x[x_dim1 + 2] = x2[1];
  274. /* Computing MAX */
  275. d__3 = (d__1 = x[x_dim1 + 1], abs(d__1)), d__4 = (d__2 = x[x_dim1 + 2]
  276. , abs(d__2));
  277. *xnorm = max(d__3,d__4);
  278. }
  279. return 0;
  280. /* 2 by 2: */
  281. /* op[TL11 TL12]*[X11 X12] +ISGN* [X11 X12]*op[TR11 TR12] = [B11 B12] */
  282. /* [TL21 TL22] [X21 X22] [X21 X22] [TR21 TR22] [B21 B22] */
  283. /* Solve equivalent 4 by 4 system using complete pivoting. */
  284. /* Set pivots less than SMIN to SMIN. */
  285. L50:
  286. /* Computing MAX */
  287. d__5 = (d__1 = tr[tr_dim1 + 1], abs(d__1)), d__6 = (d__2 = tr[(tr_dim1 <<
  288. 1) + 1], abs(d__2)), d__5 = max(d__5,d__6), d__6 = (d__3 = tr[
  289. tr_dim1 + 2], abs(d__3)), d__5 = max(d__5,d__6), d__6 = (d__4 =
  290. tr[(tr_dim1 << 1) + 2], abs(d__4));
  291. smin = max(d__5,d__6);
  292. /* Computing MAX */
  293. d__5 = smin, d__6 = (d__1 = tl[tl_dim1 + 1], abs(d__1)), d__5 = max(d__5,
  294. d__6), d__6 = (d__2 = tl[(tl_dim1 << 1) + 1], abs(d__2)), d__5 =
  295. max(d__5,d__6), d__6 = (d__3 = tl[tl_dim1 + 2], abs(d__3)), d__5 =
  296. max(d__5,d__6), d__6 = (d__4 = tl[(tl_dim1 << 1) + 2], abs(d__4))
  297. ;
  298. smin = max(d__5,d__6);
  299. /* Computing MAX */
  300. d__1 = eps * smin;
  301. smin = max(d__1,smlnum);
  302. btmp[0] = 0.;
  303. _starpu_dcopy_(&c__16, btmp, &c__0, t16, &c__1);
  304. t16[0] = tl[tl_dim1 + 1] + sgn * tr[tr_dim1 + 1];
  305. t16[5] = tl[(tl_dim1 << 1) + 2] + sgn * tr[tr_dim1 + 1];
  306. t16[10] = tl[tl_dim1 + 1] + sgn * tr[(tr_dim1 << 1) + 2];
  307. t16[15] = tl[(tl_dim1 << 1) + 2] + sgn * tr[(tr_dim1 << 1) + 2];
  308. if (*ltranl) {
  309. t16[4] = tl[tl_dim1 + 2];
  310. t16[1] = tl[(tl_dim1 << 1) + 1];
  311. t16[14] = tl[tl_dim1 + 2];
  312. t16[11] = tl[(tl_dim1 << 1) + 1];
  313. } else {
  314. t16[4] = tl[(tl_dim1 << 1) + 1];
  315. t16[1] = tl[tl_dim1 + 2];
  316. t16[14] = tl[(tl_dim1 << 1) + 1];
  317. t16[11] = tl[tl_dim1 + 2];
  318. }
  319. if (*ltranr) {
  320. t16[8] = sgn * tr[(tr_dim1 << 1) + 1];
  321. t16[13] = sgn * tr[(tr_dim1 << 1) + 1];
  322. t16[2] = sgn * tr[tr_dim1 + 2];
  323. t16[7] = sgn * tr[tr_dim1 + 2];
  324. } else {
  325. t16[8] = sgn * tr[tr_dim1 + 2];
  326. t16[13] = sgn * tr[tr_dim1 + 2];
  327. t16[2] = sgn * tr[(tr_dim1 << 1) + 1];
  328. t16[7] = sgn * tr[(tr_dim1 << 1) + 1];
  329. }
  330. btmp[0] = b[b_dim1 + 1];
  331. btmp[1] = b[b_dim1 + 2];
  332. btmp[2] = b[(b_dim1 << 1) + 1];
  333. btmp[3] = b[(b_dim1 << 1) + 2];
  334. /* Perform elimination */
  335. for (i__ = 1; i__ <= 3; ++i__) {
  336. xmax = 0.;
  337. for (ip = i__; ip <= 4; ++ip) {
  338. for (jp = i__; jp <= 4; ++jp) {
  339. if ((d__1 = t16[ip + (jp << 2) - 5], abs(d__1)) >= xmax) {
  340. xmax = (d__1 = t16[ip + (jp << 2) - 5], abs(d__1));
  341. ipsv = ip;
  342. jpsv = jp;
  343. }
  344. /* L60: */
  345. }
  346. /* L70: */
  347. }
  348. if (ipsv != i__) {
  349. _starpu_dswap_(&c__4, &t16[ipsv - 1], &c__4, &t16[i__ - 1], &c__4);
  350. temp = btmp[i__ - 1];
  351. btmp[i__ - 1] = btmp[ipsv - 1];
  352. btmp[ipsv - 1] = temp;
  353. }
  354. if (jpsv != i__) {
  355. _starpu_dswap_(&c__4, &t16[(jpsv << 2) - 4], &c__1, &t16[(i__ << 2) - 4],
  356. &c__1);
  357. }
  358. jpiv[i__ - 1] = jpsv;
  359. if ((d__1 = t16[i__ + (i__ << 2) - 5], abs(d__1)) < smin) {
  360. *info = 1;
  361. t16[i__ + (i__ << 2) - 5] = smin;
  362. }
  363. for (j = i__ + 1; j <= 4; ++j) {
  364. t16[j + (i__ << 2) - 5] /= t16[i__ + (i__ << 2) - 5];
  365. btmp[j - 1] -= t16[j + (i__ << 2) - 5] * btmp[i__ - 1];
  366. for (k = i__ + 1; k <= 4; ++k) {
  367. t16[j + (k << 2) - 5] -= t16[j + (i__ << 2) - 5] * t16[i__ + (
  368. k << 2) - 5];
  369. /* L80: */
  370. }
  371. /* L90: */
  372. }
  373. /* L100: */
  374. }
  375. if (abs(t16[15]) < smin) {
  376. t16[15] = smin;
  377. }
  378. *scale = 1.;
  379. if (smlnum * 8. * abs(btmp[0]) > abs(t16[0]) || smlnum * 8. * abs(btmp[1])
  380. > abs(t16[5]) || smlnum * 8. * abs(btmp[2]) > abs(t16[10]) ||
  381. smlnum * 8. * abs(btmp[3]) > abs(t16[15])) {
  382. /* Computing MAX */
  383. d__1 = abs(btmp[0]), d__2 = abs(btmp[1]), d__1 = max(d__1,d__2), d__2
  384. = abs(btmp[2]), d__1 = max(d__1,d__2), d__2 = abs(btmp[3]);
  385. *scale = .125 / max(d__1,d__2);
  386. btmp[0] *= *scale;
  387. btmp[1] *= *scale;
  388. btmp[2] *= *scale;
  389. btmp[3] *= *scale;
  390. }
  391. for (i__ = 1; i__ <= 4; ++i__) {
  392. k = 5 - i__;
  393. temp = 1. / t16[k + (k << 2) - 5];
  394. tmp[k - 1] = btmp[k - 1] * temp;
  395. for (j = k + 1; j <= 4; ++j) {
  396. tmp[k - 1] -= temp * t16[k + (j << 2) - 5] * tmp[j - 1];
  397. /* L110: */
  398. }
  399. /* L120: */
  400. }
  401. for (i__ = 1; i__ <= 3; ++i__) {
  402. if (jpiv[4 - i__ - 1] != 4 - i__) {
  403. temp = tmp[4 - i__ - 1];
  404. tmp[4 - i__ - 1] = tmp[jpiv[4 - i__ - 1] - 1];
  405. tmp[jpiv[4 - i__ - 1] - 1] = temp;
  406. }
  407. /* L130: */
  408. }
  409. x[x_dim1 + 1] = tmp[0];
  410. x[x_dim1 + 2] = tmp[1];
  411. x[(x_dim1 << 1) + 1] = tmp[2];
  412. x[(x_dim1 << 1) + 2] = tmp[3];
  413. /* Computing MAX */
  414. d__1 = abs(tmp[0]) + abs(tmp[2]), d__2 = abs(tmp[1]) + abs(tmp[3]);
  415. *xnorm = max(d__1,d__2);
  416. return 0;
  417. /* End of DLASY2 */
  418. } /* _starpu_dlasy2_ */