dgtsv.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /* dgtsv.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 dgtsv_(integer *n, integer *nrhs, doublereal *dl,
  14. doublereal *d__, doublereal *du, doublereal *b, integer *ldb, integer
  15. *info)
  16. {
  17. /* System generated locals */
  18. integer b_dim1, b_offset, i__1, i__2;
  19. doublereal d__1, d__2;
  20. /* Local variables */
  21. integer i__, j;
  22. doublereal fact, temp;
  23. extern /* Subroutine */ int xerbla_(char *, integer *);
  24. /* -- LAPACK routine (version 3.2) -- */
  25. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  26. /* November 2006 */
  27. /* .. Scalar Arguments .. */
  28. /* .. */
  29. /* .. Array Arguments .. */
  30. /* .. */
  31. /* Purpose */
  32. /* ======= */
  33. /* DGTSV solves the equation */
  34. /* A*X = B, */
  35. /* where A is an n by n tridiagonal matrix, by Gaussian elimination with */
  36. /* partial pivoting. */
  37. /* Note that the equation A'*X = B may be solved by interchanging the */
  38. /* order of the arguments DU and DL. */
  39. /* Arguments */
  40. /* ========= */
  41. /* N (input) INTEGER */
  42. /* The order of the matrix A. N >= 0. */
  43. /* NRHS (input) INTEGER */
  44. /* The number of right hand sides, i.e., the number of columns */
  45. /* of the matrix B. NRHS >= 0. */
  46. /* DL (input/output) DOUBLE PRECISION array, dimension (N-1) */
  47. /* On entry, DL must contain the (n-1) sub-diagonal elements of */
  48. /* A. */
  49. /* On exit, DL is overwritten by the (n-2) elements of the */
  50. /* second super-diagonal of the upper triangular matrix U from */
  51. /* the LU factorization of A, in DL(1), ..., DL(n-2). */
  52. /* D (input/output) DOUBLE PRECISION array, dimension (N) */
  53. /* On entry, D must contain the diagonal elements of A. */
  54. /* On exit, D is overwritten by the n diagonal elements of U. */
  55. /* DU (input/output) DOUBLE PRECISION array, dimension (N-1) */
  56. /* On entry, DU must contain the (n-1) super-diagonal elements */
  57. /* of A. */
  58. /* On exit, DU is overwritten by the (n-1) elements of the first */
  59. /* super-diagonal of U. */
  60. /* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) */
  61. /* On entry, the N by NRHS matrix of right hand side matrix B. */
  62. /* On exit, if INFO = 0, the N by NRHS solution matrix X. */
  63. /* LDB (input) INTEGER */
  64. /* The leading dimension of the array B. LDB >= max(1,N). */
  65. /* INFO (output) INTEGER */
  66. /* = 0: successful exit */
  67. /* < 0: if INFO = -i, the i-th argument had an illegal value */
  68. /* > 0: if INFO = i, U(i,i) is exactly zero, and the solution */
  69. /* has not been computed. The factorization has not been */
  70. /* completed unless i = N. */
  71. /* ===================================================================== */
  72. /* .. Parameters .. */
  73. /* .. */
  74. /* .. Local Scalars .. */
  75. /* .. */
  76. /* .. Intrinsic Functions .. */
  77. /* .. */
  78. /* .. External Subroutines .. */
  79. /* .. */
  80. /* .. Executable Statements .. */
  81. /* Parameter adjustments */
  82. --dl;
  83. --d__;
  84. --du;
  85. b_dim1 = *ldb;
  86. b_offset = 1 + b_dim1;
  87. b -= b_offset;
  88. /* Function Body */
  89. *info = 0;
  90. if (*n < 0) {
  91. *info = -1;
  92. } else if (*nrhs < 0) {
  93. *info = -2;
  94. } else if (*ldb < max(1,*n)) {
  95. *info = -7;
  96. }
  97. if (*info != 0) {
  98. i__1 = -(*info);
  99. xerbla_("DGTSV ", &i__1);
  100. return 0;
  101. }
  102. if (*n == 0) {
  103. return 0;
  104. }
  105. if (*nrhs == 1) {
  106. i__1 = *n - 2;
  107. for (i__ = 1; i__ <= i__1; ++i__) {
  108. if ((d__1 = d__[i__], abs(d__1)) >= (d__2 = dl[i__], abs(d__2))) {
  109. /* No row interchange required */
  110. if (d__[i__] != 0.) {
  111. fact = dl[i__] / d__[i__];
  112. d__[i__ + 1] -= fact * du[i__];
  113. b[i__ + 1 + b_dim1] -= fact * b[i__ + b_dim1];
  114. } else {
  115. *info = i__;
  116. return 0;
  117. }
  118. dl[i__] = 0.;
  119. } else {
  120. /* Interchange rows I and I+1 */
  121. fact = d__[i__] / dl[i__];
  122. d__[i__] = dl[i__];
  123. temp = d__[i__ + 1];
  124. d__[i__ + 1] = du[i__] - fact * temp;
  125. dl[i__] = du[i__ + 1];
  126. du[i__ + 1] = -fact * dl[i__];
  127. du[i__] = temp;
  128. temp = b[i__ + b_dim1];
  129. b[i__ + b_dim1] = b[i__ + 1 + b_dim1];
  130. b[i__ + 1 + b_dim1] = temp - fact * b[i__ + 1 + b_dim1];
  131. }
  132. /* L10: */
  133. }
  134. if (*n > 1) {
  135. i__ = *n - 1;
  136. if ((d__1 = d__[i__], abs(d__1)) >= (d__2 = dl[i__], abs(d__2))) {
  137. if (d__[i__] != 0.) {
  138. fact = dl[i__] / d__[i__];
  139. d__[i__ + 1] -= fact * du[i__];
  140. b[i__ + 1 + b_dim1] -= fact * b[i__ + b_dim1];
  141. } else {
  142. *info = i__;
  143. return 0;
  144. }
  145. } else {
  146. fact = d__[i__] / dl[i__];
  147. d__[i__] = dl[i__];
  148. temp = d__[i__ + 1];
  149. d__[i__ + 1] = du[i__] - fact * temp;
  150. du[i__] = temp;
  151. temp = b[i__ + b_dim1];
  152. b[i__ + b_dim1] = b[i__ + 1 + b_dim1];
  153. b[i__ + 1 + b_dim1] = temp - fact * b[i__ + 1 + b_dim1];
  154. }
  155. }
  156. if (d__[*n] == 0.) {
  157. *info = *n;
  158. return 0;
  159. }
  160. } else {
  161. i__1 = *n - 2;
  162. for (i__ = 1; i__ <= i__1; ++i__) {
  163. if ((d__1 = d__[i__], abs(d__1)) >= (d__2 = dl[i__], abs(d__2))) {
  164. /* No row interchange required */
  165. if (d__[i__] != 0.) {
  166. fact = dl[i__] / d__[i__];
  167. d__[i__ + 1] -= fact * du[i__];
  168. i__2 = *nrhs;
  169. for (j = 1; j <= i__2; ++j) {
  170. b[i__ + 1 + j * b_dim1] -= fact * b[i__ + j * b_dim1];
  171. /* L20: */
  172. }
  173. } else {
  174. *info = i__;
  175. return 0;
  176. }
  177. dl[i__] = 0.;
  178. } else {
  179. /* Interchange rows I and I+1 */
  180. fact = d__[i__] / dl[i__];
  181. d__[i__] = dl[i__];
  182. temp = d__[i__ + 1];
  183. d__[i__ + 1] = du[i__] - fact * temp;
  184. dl[i__] = du[i__ + 1];
  185. du[i__ + 1] = -fact * dl[i__];
  186. du[i__] = temp;
  187. i__2 = *nrhs;
  188. for (j = 1; j <= i__2; ++j) {
  189. temp = b[i__ + j * b_dim1];
  190. b[i__ + j * b_dim1] = b[i__ + 1 + j * b_dim1];
  191. b[i__ + 1 + j * b_dim1] = temp - fact * b[i__ + 1 + j *
  192. b_dim1];
  193. /* L30: */
  194. }
  195. }
  196. /* L40: */
  197. }
  198. if (*n > 1) {
  199. i__ = *n - 1;
  200. if ((d__1 = d__[i__], abs(d__1)) >= (d__2 = dl[i__], abs(d__2))) {
  201. if (d__[i__] != 0.) {
  202. fact = dl[i__] / d__[i__];
  203. d__[i__ + 1] -= fact * du[i__];
  204. i__1 = *nrhs;
  205. for (j = 1; j <= i__1; ++j) {
  206. b[i__ + 1 + j * b_dim1] -= fact * b[i__ + j * b_dim1];
  207. /* L50: */
  208. }
  209. } else {
  210. *info = i__;
  211. return 0;
  212. }
  213. } else {
  214. fact = d__[i__] / dl[i__];
  215. d__[i__] = dl[i__];
  216. temp = d__[i__ + 1];
  217. d__[i__ + 1] = du[i__] - fact * temp;
  218. du[i__] = temp;
  219. i__1 = *nrhs;
  220. for (j = 1; j <= i__1; ++j) {
  221. temp = b[i__ + j * b_dim1];
  222. b[i__ + j * b_dim1] = b[i__ + 1 + j * b_dim1];
  223. b[i__ + 1 + j * b_dim1] = temp - fact * b[i__ + 1 + j *
  224. b_dim1];
  225. /* L60: */
  226. }
  227. }
  228. }
  229. if (d__[*n] == 0.) {
  230. *info = *n;
  231. return 0;
  232. }
  233. }
  234. /* Back solve with the matrix U from the factorization. */
  235. if (*nrhs <= 2) {
  236. j = 1;
  237. L70:
  238. b[*n + j * b_dim1] /= d__[*n];
  239. if (*n > 1) {
  240. b[*n - 1 + j * b_dim1] = (b[*n - 1 + j * b_dim1] - du[*n - 1] * b[
  241. *n + j * b_dim1]) / d__[*n - 1];
  242. }
  243. for (i__ = *n - 2; i__ >= 1; --i__) {
  244. b[i__ + j * b_dim1] = (b[i__ + j * b_dim1] - du[i__] * b[i__ + 1
  245. + j * b_dim1] - dl[i__] * b[i__ + 2 + j * b_dim1]) / d__[
  246. i__];
  247. /* L80: */
  248. }
  249. if (j < *nrhs) {
  250. ++j;
  251. goto L70;
  252. }
  253. } else {
  254. i__1 = *nrhs;
  255. for (j = 1; j <= i__1; ++j) {
  256. b[*n + j * b_dim1] /= d__[*n];
  257. if (*n > 1) {
  258. b[*n - 1 + j * b_dim1] = (b[*n - 1 + j * b_dim1] - du[*n - 1]
  259. * b[*n + j * b_dim1]) / d__[*n - 1];
  260. }
  261. for (i__ = *n - 2; i__ >= 1; --i__) {
  262. b[i__ + j * b_dim1] = (b[i__ + j * b_dim1] - du[i__] * b[i__
  263. + 1 + j * b_dim1] - dl[i__] * b[i__ + 2 + j * b_dim1])
  264. / d__[i__];
  265. /* L90: */
  266. }
  267. /* L100: */
  268. }
  269. }
  270. return 0;
  271. /* End of DGTSV */
  272. } /* dgtsv_ */