dposvxx.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /* dposvxx.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 dposvxx_(char *fact, char *uplo, integer *n, integer *
  14. nrhs, doublereal *a, integer *lda, doublereal *af, integer *ldaf,
  15. char *equed, doublereal *s, doublereal *b, integer *ldb, doublereal *
  16. x, integer *ldx, doublereal *rcond, doublereal *rpvgrw, doublereal *
  17. berr, integer *n_err_bnds__, doublereal *err_bnds_norm__, doublereal *
  18. err_bnds_comp__, integer *nparams, doublereal *params, doublereal *
  19. work, integer *iwork, integer *info)
  20. {
  21. /* System generated locals */
  22. integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, x_dim1,
  23. x_offset, err_bnds_norm_dim1, err_bnds_norm_offset,
  24. err_bnds_comp_dim1, err_bnds_comp_offset, i__1;
  25. doublereal d__1, d__2;
  26. /* Local variables */
  27. integer j;
  28. doublereal amax, smin, smax;
  29. extern doublereal dla_porpvgrw__(char *, integer *, doublereal *, integer
  30. *, doublereal *, integer *, doublereal *, ftnlen);
  31. extern logical lsame_(char *, char *);
  32. doublereal scond;
  33. logical equil, rcequ;
  34. extern doublereal dlamch_(char *);
  35. logical nofact;
  36. extern /* Subroutine */ int dlacpy_(char *, integer *, integer *,
  37. doublereal *, integer *, doublereal *, integer *),
  38. xerbla_(char *, integer *);
  39. doublereal bignum;
  40. integer infequ;
  41. extern /* Subroutine */ int dlaqsy_(char *, integer *, doublereal *,
  42. integer *, doublereal *, doublereal *, doublereal *, char *), dpotrf_(char *, integer *, doublereal *, integer
  43. *, integer *);
  44. doublereal smlnum;
  45. extern /* Subroutine */ int dpotrs_(char *, integer *, integer *,
  46. doublereal *, integer *, doublereal *, integer *, integer *), dlascl2_(integer *, integer *, doublereal *, doublereal *
  47. , integer *), dpoequb_(integer *, doublereal *, integer *,
  48. doublereal *, doublereal *, doublereal *, integer *), dporfsx_(
  49. char *, char *, integer *, integer *, doublereal *, integer *,
  50. doublereal *, integer *, doublereal *, doublereal *, integer *,
  51. doublereal *, integer *, doublereal *, doublereal *, integer *,
  52. doublereal *, doublereal *, integer *, doublereal *, doublereal *,
  53. integer *, integer *);
  54. /* -- LAPACK driver routine (version 3.2) -- */
  55. /* -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- */
  56. /* -- Jason Riedy of Univ. of California Berkeley. -- */
  57. /* -- November 2008 -- */
  58. /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
  59. /* -- Univ. of California Berkeley and NAG Ltd. -- */
  60. /* .. */
  61. /* .. Scalar Arguments .. */
  62. /* .. */
  63. /* .. Array Arguments .. */
  64. /* .. */
  65. /* Purpose */
  66. /* ======= */
  67. /* DPOSVXX uses the Cholesky factorization A = U**T*U or A = L*L**T */
  68. /* to compute the solution to a double precision system of linear equations */
  69. /* A * X = B, where A is an N-by-N symmetric positive definite matrix */
  70. /* and X and B are N-by-NRHS matrices. */
  71. /* If requested, both normwise and maximum componentwise error bounds */
  72. /* are returned. DPOSVXX will return a solution with a tiny */
  73. /* guaranteed error (O(eps) where eps is the working machine */
  74. /* precision) unless the matrix is very ill-conditioned, in which */
  75. /* case a warning is returned. Relevant condition numbers also are */
  76. /* calculated and returned. */
  77. /* DPOSVXX accepts user-provided factorizations and equilibration */
  78. /* factors; see the definitions of the FACT and EQUED options. */
  79. /* Solving with refinement and using a factorization from a previous */
  80. /* DPOSVXX call will also produce a solution with either O(eps) */
  81. /* errors or warnings, but we cannot make that claim for general */
  82. /* user-provided factorizations and equilibration factors if they */
  83. /* differ from what DPOSVXX would itself produce. */
  84. /* Description */
  85. /* =========== */
  86. /* The following steps are performed: */
  87. /* 1. If FACT = 'E', double precision scaling factors are computed to equilibrate */
  88. /* the system: */
  89. /* diag(S)*A*diag(S) *inv(diag(S))*X = diag(S)*B */
  90. /* Whether or not the system will be equilibrated depends on the */
  91. /* scaling of the matrix A, but if equilibration is used, A is */
  92. /* overwritten by diag(S)*A*diag(S) and B by diag(S)*B. */
  93. /* 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to */
  94. /* factor the matrix A (after equilibration if FACT = 'E') as */
  95. /* A = U**T* U, if UPLO = 'U', or */
  96. /* A = L * L**T, if UPLO = 'L', */
  97. /* where U is an upper triangular matrix and L is a lower triangular */
  98. /* matrix. */
  99. /* 3. If the leading i-by-i principal minor is not positive definite, */
  100. /* then the routine returns with INFO = i. Otherwise, the factored */
  101. /* form of A is used to estimate the condition number of the matrix */
  102. /* A (see argument RCOND). If the reciprocal of the condition number */
  103. /* is less than machine precision, the routine still goes on to solve */
  104. /* for X and compute error bounds as described below. */
  105. /* 4. The system of equations is solved for X using the factored form */
  106. /* of A. */
  107. /* 5. By default (unless PARAMS(LA_LINRX_ITREF_I) is set to zero), */
  108. /* the routine will use iterative refinement to try to get a small */
  109. /* error and error bounds. Refinement calculates the residual to at */
  110. /* least twice the working precision. */
  111. /* 6. If equilibration was used, the matrix X is premultiplied by */
  112. /* diag(S) so that it solves the original system before */
  113. /* equilibration. */
  114. /* Arguments */
  115. /* ========= */
  116. /* Some optional parameters are bundled in the PARAMS array. These */
  117. /* settings determine how refinement is performed, but often the */
  118. /* defaults are acceptable. If the defaults are acceptable, users */
  119. /* can pass NPARAMS = 0 which prevents the source code from accessing */
  120. /* the PARAMS argument. */
  121. /* FACT (input) CHARACTER*1 */
  122. /* Specifies whether or not the factored form of the matrix A is */
  123. /* supplied on entry, and if not, whether the matrix A should be */
  124. /* equilibrated before it is factored. */
  125. /* = 'F': On entry, AF contains the factored form of A. */
  126. /* If EQUED is not 'N', the matrix A has been */
  127. /* equilibrated with scaling factors given by S. */
  128. /* A and AF are not modified. */
  129. /* = 'N': The matrix A will be copied to AF and factored. */
  130. /* = 'E': The matrix A will be equilibrated if necessary, then */
  131. /* copied to AF and factored. */
  132. /* UPLO (input) CHARACTER*1 */
  133. /* = 'U': Upper triangle of A is stored; */
  134. /* = 'L': Lower triangle of A is stored. */
  135. /* N (input) INTEGER */
  136. /* The number of linear equations, i.e., the order of the */
  137. /* matrix A. N >= 0. */
  138. /* NRHS (input) INTEGER */
  139. /* The number of right hand sides, i.e., the number of columns */
  140. /* of the matrices B and X. NRHS >= 0. */
  141. /* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
  142. /* On entry, the symmetric matrix A, except if FACT = 'F' and EQUED = */
  143. /* 'Y', then A must contain the equilibrated matrix */
  144. /* diag(S)*A*diag(S). If UPLO = 'U', the leading N-by-N upper */
  145. /* triangular part of A contains the upper triangular part of the */
  146. /* matrix A, and the strictly lower triangular part of A is not */
  147. /* referenced. If UPLO = 'L', the leading N-by-N lower triangular */
  148. /* part of A contains the lower triangular part of the matrix A, and */
  149. /* the strictly upper triangular part of A is not referenced. A is */
  150. /* not modified if FACT = 'F' or 'N', or if FACT = 'E' and EQUED = */
  151. /* 'N' on exit. */
  152. /* On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by */
  153. /* diag(S)*A*diag(S). */
  154. /* LDA (input) INTEGER */
  155. /* The leading dimension of the array A. LDA >= max(1,N). */
  156. /* AF (input or output) DOUBLE PRECISION array, dimension (LDAF,N) */
  157. /* If FACT = 'F', then AF is an input argument and on entry */
  158. /* contains the triangular factor U or L from the Cholesky */
  159. /* factorization A = U**T*U or A = L*L**T, in the same storage */
  160. /* format as A. If EQUED .ne. 'N', then AF is the factored */
  161. /* form of the equilibrated matrix diag(S)*A*diag(S). */
  162. /* If FACT = 'N', then AF is an output argument and on exit */
  163. /* returns the triangular factor U or L from the Cholesky */
  164. /* factorization A = U**T*U or A = L*L**T of the original */
  165. /* matrix A. */
  166. /* If FACT = 'E', then AF is an output argument and on exit */
  167. /* returns the triangular factor U or L from the Cholesky */
  168. /* factorization A = U**T*U or A = L*L**T of the equilibrated */
  169. /* matrix A (see the description of A for the form of the */
  170. /* equilibrated matrix). */
  171. /* LDAF (input) INTEGER */
  172. /* The leading dimension of the array AF. LDAF >= max(1,N). */
  173. /* EQUED (input or output) CHARACTER*1 */
  174. /* Specifies the form of equilibration that was done. */
  175. /* = 'N': No equilibration (always true if FACT = 'N'). */
  176. /* = 'Y': Both row and column equilibration, i.e., A has been */
  177. /* replaced by diag(S) * A * diag(S). */
  178. /* EQUED is an input argument if FACT = 'F'; otherwise, it is an */
  179. /* output argument. */
  180. /* S (input or output) DOUBLE PRECISION array, dimension (N) */
  181. /* The row scale factors for A. If EQUED = 'Y', A is multiplied on */
  182. /* the left and right by diag(S). S is an input argument if FACT = */
  183. /* 'F'; otherwise, S is an output argument. If FACT = 'F' and EQUED */
  184. /* = 'Y', each element of S must be positive. If S is output, each */
  185. /* element of S is a power of the radix. If S is input, each element */
  186. /* of S should be a power of the radix to ensure a reliable solution */
  187. /* and error estimates. Scaling by powers of the radix does not cause */
  188. /* rounding errors unless the result underflows or overflows. */
  189. /* Rounding errors during scaling lead to refining with a matrix that */
  190. /* is not equivalent to the input matrix, producing error estimates */
  191. /* that may not be reliable. */
  192. /* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) */
  193. /* On entry, the N-by-NRHS right hand side matrix B. */
  194. /* On exit, */
  195. /* if EQUED = 'N', B is not modified; */
  196. /* if EQUED = 'Y', B is overwritten by diag(S)*B; */
  197. /* LDB (input) INTEGER */
  198. /* The leading dimension of the array B. LDB >= max(1,N). */
  199. /* X (output) DOUBLE PRECISION array, dimension (LDX,NRHS) */
  200. /* If INFO = 0, the N-by-NRHS solution matrix X to the original */
  201. /* system of equations. Note that A and B are modified on exit if */
  202. /* EQUED .ne. 'N', and the solution to the equilibrated system is */
  203. /* inv(diag(S))*X. */
  204. /* LDX (input) INTEGER */
  205. /* The leading dimension of the array X. LDX >= max(1,N). */
  206. /* RCOND (output) DOUBLE PRECISION */
  207. /* Reciprocal scaled condition number. This is an estimate of the */
  208. /* reciprocal Skeel condition number of the matrix A after */
  209. /* equilibration (if done). If this is less than the machine */
  210. /* precision (in particular, if it is zero), the matrix is singular */
  211. /* to working precision. Note that the error may still be small even */
  212. /* if this number is very small and the matrix appears ill- */
  213. /* conditioned. */
  214. /* RPVGRW (output) DOUBLE PRECISION */
  215. /* Reciprocal pivot growth. On exit, this contains the reciprocal */
  216. /* pivot growth factor norm(A)/norm(U). The "max absolute element" */
  217. /* norm is used. If this is much less than 1, then the stability of */
  218. /* the LU factorization of the (equilibrated) matrix A could be poor. */
  219. /* This also means that the solution X, estimated condition numbers, */
  220. /* and error bounds could be unreliable. If factorization fails with */
  221. /* 0<INFO<=N, then this contains the reciprocal pivot growth factor */
  222. /* for the leading INFO columns of A. */
  223. /* BERR (output) DOUBLE PRECISION array, dimension (NRHS) */
  224. /* Componentwise relative backward error. This is the */
  225. /* componentwise relative backward error of each solution vector X(j) */
  226. /* (i.e., the smallest relative change in any element of A or B that */
  227. /* makes X(j) an exact solution). */
  228. /* N_ERR_BNDS (input) INTEGER */
  229. /* Number of error bounds to return for each right hand side */
  230. /* and each type (normwise or componentwise). See ERR_BNDS_NORM and */
  231. /* ERR_BNDS_COMP below. */
  232. /* ERR_BNDS_NORM (output) DOUBLE PRECISION array, dimension (NRHS, N_ERR_BNDS) */
  233. /* For each right-hand side, this array contains information about */
  234. /* various error bounds and condition numbers corresponding to the */
  235. /* normwise relative error, which is defined as follows: */
  236. /* Normwise relative error in the ith solution vector: */
  237. /* max_j (abs(XTRUE(j,i) - X(j,i))) */
  238. /* ------------------------------ */
  239. /* max_j abs(X(j,i)) */
  240. /* The array is indexed by the type of error information as described */
  241. /* below. There currently are up to three pieces of information */
  242. /* returned. */
  243. /* The first index in ERR_BNDS_NORM(i,:) corresponds to the ith */
  244. /* right-hand side. */
  245. /* The second index in ERR_BNDS_NORM(:,err) contains the following */
  246. /* three fields: */
  247. /* err = 1 "Trust/don't trust" boolean. Trust the answer if the */
  248. /* reciprocal condition number is less than the threshold */
  249. /* sqrt(n) * dlamch('Epsilon'). */
  250. /* err = 2 "Guaranteed" error bound: The estimated forward error, */
  251. /* almost certainly within a factor of 10 of the true error */
  252. /* so long as the next entry is greater than the threshold */
  253. /* sqrt(n) * dlamch('Epsilon'). This error bound should only */
  254. /* be trusted if the previous boolean is true. */
  255. /* err = 3 Reciprocal condition number: Estimated normwise */
  256. /* reciprocal condition number. Compared with the threshold */
  257. /* sqrt(n) * dlamch('Epsilon') to determine if the error */
  258. /* estimate is "guaranteed". These reciprocal condition */
  259. /* numbers are 1 / (norm(Z^{-1},inf) * norm(Z,inf)) for some */
  260. /* appropriately scaled matrix Z. */
  261. /* Let Z = S*A, where S scales each row by a power of the */
  262. /* radix so all absolute row sums of Z are approximately 1. */
  263. /* See Lapack Working Note 165 for further details and extra */
  264. /* cautions. */
  265. /* ERR_BNDS_COMP (output) DOUBLE PRECISION array, dimension (NRHS, N_ERR_BNDS) */
  266. /* For each right-hand side, this array contains information about */
  267. /* various error bounds and condition numbers corresponding to the */
  268. /* componentwise relative error, which is defined as follows: */
  269. /* Componentwise relative error in the ith solution vector: */
  270. /* abs(XTRUE(j,i) - X(j,i)) */
  271. /* max_j ---------------------- */
  272. /* abs(X(j,i)) */
  273. /* The array is indexed by the right-hand side i (on which the */
  274. /* componentwise relative error depends), and the type of error */
  275. /* information as described below. There currently are up to three */
  276. /* pieces of information returned for each right-hand side. If */
  277. /* componentwise accuracy is not requested (PARAMS(3) = 0.0), then */
  278. /* ERR_BNDS_COMP is not accessed. If N_ERR_BNDS .LT. 3, then at most */
  279. /* the first (:,N_ERR_BNDS) entries are returned. */
  280. /* The first index in ERR_BNDS_COMP(i,:) corresponds to the ith */
  281. /* right-hand side. */
  282. /* The second index in ERR_BNDS_COMP(:,err) contains the following */
  283. /* three fields: */
  284. /* err = 1 "Trust/don't trust" boolean. Trust the answer if the */
  285. /* reciprocal condition number is less than the threshold */
  286. /* sqrt(n) * dlamch('Epsilon'). */
  287. /* err = 2 "Guaranteed" error bound: The estimated forward error, */
  288. /* almost certainly within a factor of 10 of the true error */
  289. /* so long as the next entry is greater than the threshold */
  290. /* sqrt(n) * dlamch('Epsilon'). This error bound should only */
  291. /* be trusted if the previous boolean is true. */
  292. /* err = 3 Reciprocal condition number: Estimated componentwise */
  293. /* reciprocal condition number. Compared with the threshold */
  294. /* sqrt(n) * dlamch('Epsilon') to determine if the error */
  295. /* estimate is "guaranteed". These reciprocal condition */
  296. /* numbers are 1 / (norm(Z^{-1},inf) * norm(Z,inf)) for some */
  297. /* appropriately scaled matrix Z. */
  298. /* Let Z = S*(A*diag(x)), where x is the solution for the */
  299. /* current right-hand side and S scales each row of */
  300. /* A*diag(x) by a power of the radix so all absolute row */
  301. /* sums of Z are approximately 1. */
  302. /* See Lapack Working Note 165 for further details and extra */
  303. /* cautions. */
  304. /* NPARAMS (input) INTEGER */
  305. /* Specifies the number of parameters set in PARAMS. If .LE. 0, the */
  306. /* PARAMS array is never referenced and default values are used. */
  307. /* PARAMS (input / output) DOUBLE PRECISION array, dimension NPARAMS */
  308. /* Specifies algorithm parameters. If an entry is .LT. 0.0, then */
  309. /* that entry will be filled with default value used for that */
  310. /* parameter. Only positions up to NPARAMS are accessed; defaults */
  311. /* are used for higher-numbered parameters. */
  312. /* PARAMS(LA_LINRX_ITREF_I = 1) : Whether to perform iterative */
  313. /* refinement or not. */
  314. /* Default: 1.0D+0 */
  315. /* = 0.0 : No refinement is performed, and no error bounds are */
  316. /* computed. */
  317. /* = 1.0 : Use the extra-precise refinement algorithm. */
  318. /* (other values are reserved for future use) */
  319. /* PARAMS(LA_LINRX_ITHRESH_I = 2) : Maximum number of residual */
  320. /* computations allowed for refinement. */
  321. /* Default: 10 */
  322. /* Aggressive: Set to 100 to permit convergence using approximate */
  323. /* factorizations or factorizations other than LU. If */
  324. /* the factorization uses a technique other than */
  325. /* Gaussian elimination, the guarantees in */
  326. /* err_bnds_norm and err_bnds_comp may no longer be */
  327. /* trustworthy. */
  328. /* PARAMS(LA_LINRX_CWISE_I = 3) : Flag determining if the code */
  329. /* will attempt to find a solution with small componentwise */
  330. /* relative error in the double-precision algorithm. Positive */
  331. /* is true, 0.0 is false. */
  332. /* Default: 1.0 (attempt componentwise convergence) */
  333. /* WORK (workspace) DOUBLE PRECISION array, dimension (4*N) */
  334. /* IWORK (workspace) INTEGER array, dimension (N) */
  335. /* INFO (output) INTEGER */
  336. /* = 0: Successful exit. The solution to every right-hand side is */
  337. /* guaranteed. */
  338. /* < 0: If INFO = -i, the i-th argument had an illegal value */
  339. /* > 0 and <= N: U(INFO,INFO) is exactly zero. The factorization */
  340. /* has been completed, but the factor U is exactly singular, so */
  341. /* the solution and error bounds could not be computed. RCOND = 0 */
  342. /* is returned. */
  343. /* = N+J: The solution corresponding to the Jth right-hand side is */
  344. /* not guaranteed. The solutions corresponding to other right- */
  345. /* hand sides K with K > J may not be guaranteed as well, but */
  346. /* only the first such right-hand side is reported. If a small */
  347. /* componentwise error is not requested (PARAMS(3) = 0.0) then */
  348. /* the Jth right-hand side is the first with a normwise error */
  349. /* bound that is not guaranteed (the smallest J such */
  350. /* that ERR_BNDS_NORM(J,1) = 0.0). By default (PARAMS(3) = 1.0) */
  351. /* the Jth right-hand side is the first with either a normwise or */
  352. /* componentwise error bound that is not guaranteed (the smallest */
  353. /* J such that either ERR_BNDS_NORM(J,1) = 0.0 or */
  354. /* ERR_BNDS_COMP(J,1) = 0.0). See the definition of */
  355. /* ERR_BNDS_NORM(:,1) and ERR_BNDS_COMP(:,1). To get information */
  356. /* about all of the right-hand sides check ERR_BNDS_NORM or */
  357. /* ERR_BNDS_COMP. */
  358. /* ================================================================== */
  359. /* .. Parameters .. */
  360. /* .. */
  361. /* .. Local Scalars .. */
  362. /* .. */
  363. /* .. External Functions .. */
  364. /* .. */
  365. /* .. External Subroutines .. */
  366. /* .. */
  367. /* .. Intrinsic Functions .. */
  368. /* .. */
  369. /* .. Executable Statements .. */
  370. /* Parameter adjustments */
  371. err_bnds_comp_dim1 = *nrhs;
  372. err_bnds_comp_offset = 1 + err_bnds_comp_dim1;
  373. err_bnds_comp__ -= err_bnds_comp_offset;
  374. err_bnds_norm_dim1 = *nrhs;
  375. err_bnds_norm_offset = 1 + err_bnds_norm_dim1;
  376. err_bnds_norm__ -= err_bnds_norm_offset;
  377. a_dim1 = *lda;
  378. a_offset = 1 + a_dim1;
  379. a -= a_offset;
  380. af_dim1 = *ldaf;
  381. af_offset = 1 + af_dim1;
  382. af -= af_offset;
  383. --s;
  384. b_dim1 = *ldb;
  385. b_offset = 1 + b_dim1;
  386. b -= b_offset;
  387. x_dim1 = *ldx;
  388. x_offset = 1 + x_dim1;
  389. x -= x_offset;
  390. --berr;
  391. --params;
  392. --work;
  393. --iwork;
  394. /* Function Body */
  395. *info = 0;
  396. nofact = lsame_(fact, "N");
  397. equil = lsame_(fact, "E");
  398. smlnum = dlamch_("Safe minimum");
  399. bignum = 1. / smlnum;
  400. if (nofact || equil) {
  401. *(unsigned char *)equed = 'N';
  402. rcequ = FALSE_;
  403. } else {
  404. rcequ = lsame_(equed, "Y");
  405. }
  406. /* Default is failure. If an input parameter is wrong or */
  407. /* factorization fails, make everything look horrible. Only the */
  408. /* pivot growth is set here, the rest is initialized in DPORFSX. */
  409. *rpvgrw = 0.;
  410. /* Test the input parameters. PARAMS is not tested until DPORFSX. */
  411. if (! nofact && ! equil && ! lsame_(fact, "F")) {
  412. *info = -1;
  413. } else if (! lsame_(uplo, "U") && ! lsame_(uplo,
  414. "L")) {
  415. *info = -2;
  416. } else if (*n < 0) {
  417. *info = -3;
  418. } else if (*nrhs < 0) {
  419. *info = -4;
  420. } else if (*lda < max(1,*n)) {
  421. *info = -6;
  422. } else if (*ldaf < max(1,*n)) {
  423. *info = -8;
  424. } else if (lsame_(fact, "F") && ! (rcequ || lsame_(
  425. equed, "N"))) {
  426. *info = -9;
  427. } else {
  428. if (rcequ) {
  429. smin = bignum;
  430. smax = 0.;
  431. i__1 = *n;
  432. for (j = 1; j <= i__1; ++j) {
  433. /* Computing MIN */
  434. d__1 = smin, d__2 = s[j];
  435. smin = min(d__1,d__2);
  436. /* Computing MAX */
  437. d__1 = smax, d__2 = s[j];
  438. smax = max(d__1,d__2);
  439. /* L10: */
  440. }
  441. if (smin <= 0.) {
  442. *info = -10;
  443. } else if (*n > 0) {
  444. scond = max(smin,smlnum) / min(smax,bignum);
  445. } else {
  446. scond = 1.;
  447. }
  448. }
  449. if (*info == 0) {
  450. if (*ldb < max(1,*n)) {
  451. *info = -12;
  452. } else if (*ldx < max(1,*n)) {
  453. *info = -14;
  454. }
  455. }
  456. }
  457. if (*info != 0) {
  458. i__1 = -(*info);
  459. xerbla_("DPOSVXX", &i__1);
  460. return 0;
  461. }
  462. if (equil) {
  463. /* Compute row and column scalings to equilibrate the matrix A. */
  464. dpoequb_(n, &a[a_offset], lda, &s[1], &scond, &amax, &infequ);
  465. if (infequ == 0) {
  466. /* Equilibrate the matrix. */
  467. dlaqsy_(uplo, n, &a[a_offset], lda, &s[1], &scond, &amax, equed);
  468. rcequ = lsame_(equed, "Y");
  469. }
  470. }
  471. /* Scale the right-hand side. */
  472. if (rcequ) {
  473. dlascl2_(n, nrhs, &s[1], &b[b_offset], ldb);
  474. }
  475. if (nofact || equil) {
  476. /* Compute the LU factorization of A. */
  477. dlacpy_(uplo, n, n, &a[a_offset], lda, &af[af_offset], ldaf);
  478. dpotrf_(uplo, n, &af[af_offset], ldaf, info);
  479. /* Return if INFO is non-zero. */
  480. if (*info != 0) {
  481. /* Pivot in column INFO is exactly 0 */
  482. /* Compute the reciprocal pivot growth factor of the */
  483. /* leading rank-deficient INFO columns of A. */
  484. *rpvgrw = dla_porpvgrw__(uplo, info, &a[a_offset], lda, &af[
  485. af_offset], ldaf, &work[1], (ftnlen)1);
  486. return 0;
  487. }
  488. }
  489. /* Compute the reciprocal growth factor RPVGRW. */
  490. *rpvgrw = dla_porpvgrw__(uplo, n, &a[a_offset], lda, &af[af_offset], ldaf,
  491. &work[1], (ftnlen)1);
  492. /* Compute the solution matrix X. */
  493. dlacpy_("Full", n, nrhs, &b[b_offset], ldb, &x[x_offset], ldx);
  494. dpotrs_(uplo, n, nrhs, &af[af_offset], ldaf, &x[x_offset], ldx, info);
  495. /* Use iterative refinement to improve the computed solution and */
  496. /* compute error bounds and backward error estimates for it. */
  497. dporfsx_(uplo, equed, n, nrhs, &a[a_offset], lda, &af[af_offset], ldaf, &
  498. s[1], &b[b_offset], ldb, &x[x_offset], ldx, rcond, &berr[1],
  499. n_err_bnds__, &err_bnds_norm__[err_bnds_norm_offset], &
  500. err_bnds_comp__[err_bnds_comp_offset], nparams, &params[1], &work[
  501. 1], &iwork[1], info);
  502. /* Scale solutions. */
  503. if (rcequ) {
  504. dlascl2_(n, nrhs, &s[1], &x[x_offset], ldx);
  505. }
  506. return 0;
  507. /* End of DPOSVXX */
  508. } /* dposvxx_ */