dtrsm.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /* dtrsm.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. /* Subroutine */ int dtrsm_(char *side, char *uplo, char *transa, char *diag,
  14. integer *m, integer *n, doublereal *alpha, doublereal *a, integer *
  15. lda, doublereal *b, integer *ldb)
  16. {
  17. /* System generated locals */
  18. integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
  19. /* Local variables */
  20. integer i__, j, k, info;
  21. doublereal temp;
  22. logical lside;
  23. extern logical lsame_(char *, char *);
  24. integer nrowa;
  25. logical upper;
  26. extern /* Subroutine */ int xerbla_(char *, integer *);
  27. logical nounit;
  28. /* .. Scalar Arguments .. */
  29. /* .. */
  30. /* .. Array Arguments .. */
  31. /* .. */
  32. /* Purpose */
  33. /* ======= */
  34. /* DTRSM solves one of the matrix equations */
  35. /* op( A )*X = alpha*B, or X*op( A ) = alpha*B, */
  36. /* where alpha is a scalar, X and B are m by n matrices, A is a unit, or */
  37. /* non-unit, upper or lower triangular matrix and op( A ) is one of */
  38. /* op( A ) = A or op( A ) = A'. */
  39. /* The matrix X is overwritten on B. */
  40. /* Arguments */
  41. /* ========== */
  42. /* SIDE - CHARACTER*1. */
  43. /* On entry, SIDE specifies whether op( A ) appears on the left */
  44. /* or right of X as follows: */
  45. /* SIDE = 'L' or 'l' op( A )*X = alpha*B. */
  46. /* SIDE = 'R' or 'r' X*op( A ) = alpha*B. */
  47. /* Unchanged on exit. */
  48. /* UPLO - CHARACTER*1. */
  49. /* On entry, UPLO specifies whether the matrix A is an upper or */
  50. /* lower triangular matrix as follows: */
  51. /* UPLO = 'U' or 'u' A is an upper triangular matrix. */
  52. /* UPLO = 'L' or 'l' A is a lower triangular matrix. */
  53. /* Unchanged on exit. */
  54. /* TRANSA - CHARACTER*1. */
  55. /* On entry, TRANSA specifies the form of op( A ) to be used in */
  56. /* the matrix multiplication as follows: */
  57. /* TRANSA = 'N' or 'n' op( A ) = A. */
  58. /* TRANSA = 'T' or 't' op( A ) = A'. */
  59. /* TRANSA = 'C' or 'c' op( A ) = A'. */
  60. /* Unchanged on exit. */
  61. /* DIAG - CHARACTER*1. */
  62. /* On entry, DIAG specifies whether or not A is unit triangular */
  63. /* as follows: */
  64. /* DIAG = 'U' or 'u' A is assumed to be unit triangular. */
  65. /* DIAG = 'N' or 'n' A is not assumed to be unit */
  66. /* triangular. */
  67. /* Unchanged on exit. */
  68. /* M - INTEGER. */
  69. /* On entry, M specifies the number of rows of B. M must be at */
  70. /* least zero. */
  71. /* Unchanged on exit. */
  72. /* N - INTEGER. */
  73. /* On entry, N specifies the number of columns of B. N must be */
  74. /* at least zero. */
  75. /* Unchanged on exit. */
  76. /* ALPHA - DOUBLE PRECISION. */
  77. /* On entry, ALPHA specifies the scalar alpha. When alpha is */
  78. /* zero then A is not referenced and B need not be set before */
  79. /* entry. */
  80. /* Unchanged on exit. */
  81. /* A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m */
  82. /* when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. */
  83. /* Before entry with UPLO = 'U' or 'u', the leading k by k */
  84. /* upper triangular part of the array A must contain the upper */
  85. /* triangular matrix and the strictly lower triangular part of */
  86. /* A is not referenced. */
  87. /* Before entry with UPLO = 'L' or 'l', the leading k by k */
  88. /* lower triangular part of the array A must contain the lower */
  89. /* triangular matrix and the strictly upper triangular part of */
  90. /* A is not referenced. */
  91. /* Note that when DIAG = 'U' or 'u', the diagonal elements of */
  92. /* A are not referenced either, but are assumed to be unity. */
  93. /* Unchanged on exit. */
  94. /* LDA - INTEGER. */
  95. /* On entry, LDA specifies the first dimension of A as declared */
  96. /* in the calling (sub) program. When SIDE = 'L' or 'l' then */
  97. /* LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' */
  98. /* then LDA must be at least max( 1, n ). */
  99. /* Unchanged on exit. */
  100. /* B - DOUBLE PRECISION array of DIMENSION ( LDB, n ). */
  101. /* Before entry, the leading m by n part of the array B must */
  102. /* contain the right-hand side matrix B, and on exit is */
  103. /* overwritten by the solution matrix X. */
  104. /* LDB - INTEGER. */
  105. /* On entry, LDB specifies the first dimension of B as declared */
  106. /* in the calling (sub) program. LDB must be at least */
  107. /* max( 1, m ). */
  108. /* Unchanged on exit. */
  109. /* Level 3 Blas routine. */
  110. /* -- Written on 8-February-1989. */
  111. /* Jack Dongarra, Argonne National Laboratory. */
  112. /* Iain Duff, AERE Harwell. */
  113. /* Jeremy Du Croz, Numerical Algorithms Group Ltd. */
  114. /* Sven Hammarling, Numerical Algorithms Group Ltd. */
  115. /* .. External Functions .. */
  116. /* .. */
  117. /* .. External Subroutines .. */
  118. /* .. */
  119. /* .. Intrinsic Functions .. */
  120. /* .. */
  121. /* .. Local Scalars .. */
  122. /* .. */
  123. /* .. Parameters .. */
  124. /* .. */
  125. /* Test the input parameters. */
  126. /* Parameter adjustments */
  127. a_dim1 = *lda;
  128. a_offset = 1 + a_dim1;
  129. a -= a_offset;
  130. b_dim1 = *ldb;
  131. b_offset = 1 + b_dim1;
  132. b -= b_offset;
  133. /* Function Body */
  134. lside = lsame_(side, "L");
  135. if (lside) {
  136. nrowa = *m;
  137. } else {
  138. nrowa = *n;
  139. }
  140. nounit = lsame_(diag, "N");
  141. upper = lsame_(uplo, "U");
  142. info = 0;
  143. if (! lside && ! lsame_(side, "R")) {
  144. info = 1;
  145. } else if (! upper && ! lsame_(uplo, "L")) {
  146. info = 2;
  147. } else if (! lsame_(transa, "N") && ! lsame_(transa,
  148. "T") && ! lsame_(transa, "C")) {
  149. info = 3;
  150. } else if (! lsame_(diag, "U") && ! lsame_(diag,
  151. "N")) {
  152. info = 4;
  153. } else if (*m < 0) {
  154. info = 5;
  155. } else if (*n < 0) {
  156. info = 6;
  157. } else if (*lda < max(1,nrowa)) {
  158. info = 9;
  159. } else if (*ldb < max(1,*m)) {
  160. info = 11;
  161. }
  162. if (info != 0) {
  163. xerbla_("DTRSM ", &info);
  164. return 0;
  165. }
  166. /* Quick return if possible. */
  167. if (*m == 0 || *n == 0) {
  168. return 0;
  169. }
  170. /* And when alpha.eq.zero. */
  171. if (*alpha == 0.) {
  172. i__1 = *n;
  173. for (j = 1; j <= i__1; ++j) {
  174. i__2 = *m;
  175. for (i__ = 1; i__ <= i__2; ++i__) {
  176. b[i__ + j * b_dim1] = 0.;
  177. /* L10: */
  178. }
  179. /* L20: */
  180. }
  181. return 0;
  182. }
  183. /* Start the operations. */
  184. if (lside) {
  185. if (lsame_(transa, "N")) {
  186. /* Form B := alpha*inv( A )*B. */
  187. if (upper) {
  188. i__1 = *n;
  189. for (j = 1; j <= i__1; ++j) {
  190. if (*alpha != 1.) {
  191. i__2 = *m;
  192. for (i__ = 1; i__ <= i__2; ++i__) {
  193. b[i__ + j * b_dim1] = *alpha * b[i__ + j * b_dim1]
  194. ;
  195. /* L30: */
  196. }
  197. }
  198. for (k = *m; k >= 1; --k) {
  199. if (b[k + j * b_dim1] != 0.) {
  200. if (nounit) {
  201. b[k + j * b_dim1] /= a[k + k * a_dim1];
  202. }
  203. i__2 = k - 1;
  204. for (i__ = 1; i__ <= i__2; ++i__) {
  205. b[i__ + j * b_dim1] -= b[k + j * b_dim1] * a[
  206. i__ + k * a_dim1];
  207. /* L40: */
  208. }
  209. }
  210. /* L50: */
  211. }
  212. /* L60: */
  213. }
  214. } else {
  215. i__1 = *n;
  216. for (j = 1; j <= i__1; ++j) {
  217. if (*alpha != 1.) {
  218. i__2 = *m;
  219. for (i__ = 1; i__ <= i__2; ++i__) {
  220. b[i__ + j * b_dim1] = *alpha * b[i__ + j * b_dim1]
  221. ;
  222. /* L70: */
  223. }
  224. }
  225. i__2 = *m;
  226. for (k = 1; k <= i__2; ++k) {
  227. if (b[k + j * b_dim1] != 0.) {
  228. if (nounit) {
  229. b[k + j * b_dim1] /= a[k + k * a_dim1];
  230. }
  231. i__3 = *m;
  232. for (i__ = k + 1; i__ <= i__3; ++i__) {
  233. b[i__ + j * b_dim1] -= b[k + j * b_dim1] * a[
  234. i__ + k * a_dim1];
  235. /* L80: */
  236. }
  237. }
  238. /* L90: */
  239. }
  240. /* L100: */
  241. }
  242. }
  243. } else {
  244. /* Form B := alpha*inv( A' )*B. */
  245. if (upper) {
  246. i__1 = *n;
  247. for (j = 1; j <= i__1; ++j) {
  248. i__2 = *m;
  249. for (i__ = 1; i__ <= i__2; ++i__) {
  250. temp = *alpha * b[i__ + j * b_dim1];
  251. i__3 = i__ - 1;
  252. for (k = 1; k <= i__3; ++k) {
  253. temp -= a[k + i__ * a_dim1] * b[k + j * b_dim1];
  254. /* L110: */
  255. }
  256. if (nounit) {
  257. temp /= a[i__ + i__ * a_dim1];
  258. }
  259. b[i__ + j * b_dim1] = temp;
  260. /* L120: */
  261. }
  262. /* L130: */
  263. }
  264. } else {
  265. i__1 = *n;
  266. for (j = 1; j <= i__1; ++j) {
  267. for (i__ = *m; i__ >= 1; --i__) {
  268. temp = *alpha * b[i__ + j * b_dim1];
  269. i__2 = *m;
  270. for (k = i__ + 1; k <= i__2; ++k) {
  271. temp -= a[k + i__ * a_dim1] * b[k + j * b_dim1];
  272. /* L140: */
  273. }
  274. if (nounit) {
  275. temp /= a[i__ + i__ * a_dim1];
  276. }
  277. b[i__ + j * b_dim1] = temp;
  278. /* L150: */
  279. }
  280. /* L160: */
  281. }
  282. }
  283. }
  284. } else {
  285. if (lsame_(transa, "N")) {
  286. /* Form B := alpha*B*inv( A ). */
  287. if (upper) {
  288. i__1 = *n;
  289. for (j = 1; j <= i__1; ++j) {
  290. if (*alpha != 1.) {
  291. i__2 = *m;
  292. for (i__ = 1; i__ <= i__2; ++i__) {
  293. b[i__ + j * b_dim1] = *alpha * b[i__ + j * b_dim1]
  294. ;
  295. /* L170: */
  296. }
  297. }
  298. i__2 = j - 1;
  299. for (k = 1; k <= i__2; ++k) {
  300. if (a[k + j * a_dim1] != 0.) {
  301. i__3 = *m;
  302. for (i__ = 1; i__ <= i__3; ++i__) {
  303. b[i__ + j * b_dim1] -= a[k + j * a_dim1] * b[
  304. i__ + k * b_dim1];
  305. /* L180: */
  306. }
  307. }
  308. /* L190: */
  309. }
  310. if (nounit) {
  311. temp = 1. / a[j + j * a_dim1];
  312. i__2 = *m;
  313. for (i__ = 1; i__ <= i__2; ++i__) {
  314. b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
  315. /* L200: */
  316. }
  317. }
  318. /* L210: */
  319. }
  320. } else {
  321. for (j = *n; j >= 1; --j) {
  322. if (*alpha != 1.) {
  323. i__1 = *m;
  324. for (i__ = 1; i__ <= i__1; ++i__) {
  325. b[i__ + j * b_dim1] = *alpha * b[i__ + j * b_dim1]
  326. ;
  327. /* L220: */
  328. }
  329. }
  330. i__1 = *n;
  331. for (k = j + 1; k <= i__1; ++k) {
  332. if (a[k + j * a_dim1] != 0.) {
  333. i__2 = *m;
  334. for (i__ = 1; i__ <= i__2; ++i__) {
  335. b[i__ + j * b_dim1] -= a[k + j * a_dim1] * b[
  336. i__ + k * b_dim1];
  337. /* L230: */
  338. }
  339. }
  340. /* L240: */
  341. }
  342. if (nounit) {
  343. temp = 1. / a[j + j * a_dim1];
  344. i__1 = *m;
  345. for (i__ = 1; i__ <= i__1; ++i__) {
  346. b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
  347. /* L250: */
  348. }
  349. }
  350. /* L260: */
  351. }
  352. }
  353. } else {
  354. /* Form B := alpha*B*inv( A' ). */
  355. if (upper) {
  356. for (k = *n; k >= 1; --k) {
  357. if (nounit) {
  358. temp = 1. / a[k + k * a_dim1];
  359. i__1 = *m;
  360. for (i__ = 1; i__ <= i__1; ++i__) {
  361. b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
  362. /* L270: */
  363. }
  364. }
  365. i__1 = k - 1;
  366. for (j = 1; j <= i__1; ++j) {
  367. if (a[j + k * a_dim1] != 0.) {
  368. temp = a[j + k * a_dim1];
  369. i__2 = *m;
  370. for (i__ = 1; i__ <= i__2; ++i__) {
  371. b[i__ + j * b_dim1] -= temp * b[i__ + k *
  372. b_dim1];
  373. /* L280: */
  374. }
  375. }
  376. /* L290: */
  377. }
  378. if (*alpha != 1.) {
  379. i__1 = *m;
  380. for (i__ = 1; i__ <= i__1; ++i__) {
  381. b[i__ + k * b_dim1] = *alpha * b[i__ + k * b_dim1]
  382. ;
  383. /* L300: */
  384. }
  385. }
  386. /* L310: */
  387. }
  388. } else {
  389. i__1 = *n;
  390. for (k = 1; k <= i__1; ++k) {
  391. if (nounit) {
  392. temp = 1. / a[k + k * a_dim1];
  393. i__2 = *m;
  394. for (i__ = 1; i__ <= i__2; ++i__) {
  395. b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
  396. /* L320: */
  397. }
  398. }
  399. i__2 = *n;
  400. for (j = k + 1; j <= i__2; ++j) {
  401. if (a[j + k * a_dim1] != 0.) {
  402. temp = a[j + k * a_dim1];
  403. i__3 = *m;
  404. for (i__ = 1; i__ <= i__3; ++i__) {
  405. b[i__ + j * b_dim1] -= temp * b[i__ + k *
  406. b_dim1];
  407. /* L330: */
  408. }
  409. }
  410. /* L340: */
  411. }
  412. if (*alpha != 1.) {
  413. i__2 = *m;
  414. for (i__ = 1; i__ <= i__2; ++i__) {
  415. b[i__ + k * b_dim1] = *alpha * b[i__ + k * b_dim1]
  416. ;
  417. /* L350: */
  418. }
  419. }
  420. /* L360: */
  421. }
  422. }
  423. }
  424. }
  425. return 0;
  426. /* End of DTRSM . */
  427. } /* dtrsm_ */