dgecon.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /* dgecon.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. /* Subroutine */ int _starpu_dgecon_(char *norm, integer *n, doublereal *a, integer *
  16. lda, doublereal *anorm, doublereal *rcond, doublereal *work, integer *
  17. iwork, integer *info)
  18. {
  19. /* System generated locals */
  20. integer a_dim1, a_offset, i__1;
  21. doublereal d__1;
  22. /* Local variables */
  23. doublereal sl;
  24. integer ix;
  25. doublereal su;
  26. integer kase, kase1;
  27. doublereal scale;
  28. extern logical _starpu_lsame_(char *, char *);
  29. integer isave[3];
  30. extern /* Subroutine */ int _starpu_drscl_(integer *, doublereal *, doublereal *,
  31. integer *), _starpu_dlacn2_(integer *, doublereal *, doublereal *,
  32. integer *, doublereal *, integer *, integer *);
  33. extern doublereal _starpu_dlamch_(char *);
  34. extern integer _starpu_idamax_(integer *, doublereal *, integer *);
  35. extern /* Subroutine */ int _starpu_xerbla_(char *, integer *);
  36. doublereal ainvnm;
  37. extern /* Subroutine */ int _starpu_dlatrs_(char *, char *, char *, char *,
  38. integer *, doublereal *, integer *, doublereal *, doublereal *,
  39. doublereal *, integer *);
  40. logical onenrm;
  41. char normin[1];
  42. doublereal smlnum;
  43. /* -- LAPACK routine (version 3.2) -- */
  44. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  45. /* November 2006 */
  46. /* Modified to call DLACN2 in place of DLACON, 5 Feb 03, SJH. */
  47. /* .. Scalar Arguments .. */
  48. /* .. */
  49. /* .. Array Arguments .. */
  50. /* .. */
  51. /* Purpose */
  52. /* ======= */
  53. /* DGECON estimates the reciprocal of the condition number of a general */
  54. /* real matrix A, in either the 1-norm or the infinity-norm, using */
  55. /* the LU factorization computed by DGETRF. */
  56. /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */
  57. /* condition number is computed as */
  58. /* RCOND = 1 / ( norm(A) * norm(inv(A)) ). */
  59. /* Arguments */
  60. /* ========= */
  61. /* NORM (input) CHARACTER*1 */
  62. /* Specifies whether the 1-norm condition number or the */
  63. /* infinity-norm condition number is required: */
  64. /* = '1' or 'O': 1-norm; */
  65. /* = 'I': Infinity-norm. */
  66. /* N (input) INTEGER */
  67. /* The order of the matrix A. N >= 0. */
  68. /* A (input) DOUBLE PRECISION array, dimension (LDA,N) */
  69. /* The factors L and U from the factorization A = P*L*U */
  70. /* as computed by DGETRF. */
  71. /* LDA (input) INTEGER */
  72. /* The leading dimension of the array A. LDA >= max(1,N). */
  73. /* ANORM (input) DOUBLE PRECISION */
  74. /* If NORM = '1' or 'O', the 1-norm of the original matrix A. */
  75. /* If NORM = 'I', the infinity-norm of the original matrix A. */
  76. /* RCOND (output) DOUBLE PRECISION */
  77. /* The reciprocal of the condition number of the matrix A, */
  78. /* computed as RCOND = 1/(norm(A) * norm(inv(A))). */
  79. /* WORK (workspace) DOUBLE PRECISION array, dimension (4*N) */
  80. /* IWORK (workspace) INTEGER 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. /* ===================================================================== */
  85. /* .. Parameters .. */
  86. /* .. */
  87. /* .. Local Scalars .. */
  88. /* .. */
  89. /* .. Local Arrays .. */
  90. /* .. */
  91. /* .. External Functions .. */
  92. /* .. */
  93. /* .. External Subroutines .. */
  94. /* .. */
  95. /* .. Intrinsic Functions .. */
  96. /* .. */
  97. /* .. Executable Statements .. */
  98. /* Test the input parameters. */
  99. /* Parameter adjustments */
  100. a_dim1 = *lda;
  101. a_offset = 1 + a_dim1;
  102. a -= a_offset;
  103. --work;
  104. --iwork;
  105. /* Function Body */
  106. *info = 0;
  107. onenrm = *(unsigned char *)norm == '1' || _starpu_lsame_(norm, "O");
  108. if (! onenrm && ! _starpu_lsame_(norm, "I")) {
  109. *info = -1;
  110. } else if (*n < 0) {
  111. *info = -2;
  112. } else if (*lda < max(1,*n)) {
  113. *info = -4;
  114. } else if (*anorm < 0.) {
  115. *info = -5;
  116. }
  117. if (*info != 0) {
  118. i__1 = -(*info);
  119. _starpu_xerbla_("DGECON", &i__1);
  120. return 0;
  121. }
  122. /* Quick return if possible */
  123. *rcond = 0.;
  124. if (*n == 0) {
  125. *rcond = 1.;
  126. return 0;
  127. } else if (*anorm == 0.) {
  128. return 0;
  129. }
  130. smlnum = _starpu_dlamch_("Safe minimum");
  131. /* Estimate the norm of inv(A). */
  132. ainvnm = 0.;
  133. *(unsigned char *)normin = 'N';
  134. if (onenrm) {
  135. kase1 = 1;
  136. } else {
  137. kase1 = 2;
  138. }
  139. kase = 0;
  140. L10:
  141. _starpu_dlacn2_(n, &work[*n + 1], &work[1], &iwork[1], &ainvnm, &kase, isave);
  142. if (kase != 0) {
  143. if (kase == kase1) {
  144. /* Multiply by inv(L). */
  145. _starpu_dlatrs_("Lower", "No transpose", "Unit", normin, n, &a[a_offset],
  146. lda, &work[1], &sl, &work[(*n << 1) + 1], info);
  147. /* Multiply by inv(U). */
  148. _starpu_dlatrs_("Upper", "No transpose", "Non-unit", normin, n, &a[
  149. a_offset], lda, &work[1], &su, &work[*n * 3 + 1], info);
  150. } else {
  151. /* Multiply by inv(U'). */
  152. _starpu_dlatrs_("Upper", "Transpose", "Non-unit", normin, n, &a[a_offset],
  153. lda, &work[1], &su, &work[*n * 3 + 1], info);
  154. /* Multiply by inv(L'). */
  155. _starpu_dlatrs_("Lower", "Transpose", "Unit", normin, n, &a[a_offset],
  156. lda, &work[1], &sl, &work[(*n << 1) + 1], info);
  157. }
  158. /* Divide X by 1/(SL*SU) if doing so will not cause overflow. */
  159. scale = sl * su;
  160. *(unsigned char *)normin = 'Y';
  161. if (scale != 1.) {
  162. ix = _starpu_idamax_(n, &work[1], &c__1);
  163. if (scale < (d__1 = work[ix], abs(d__1)) * smlnum || scale == 0.)
  164. {
  165. goto L20;
  166. }
  167. _starpu_drscl_(n, &scale, &work[1], &c__1);
  168. }
  169. goto L10;
  170. }
  171. /* Compute the estimate of the reciprocal condition number. */
  172. if (ainvnm != 0.) {
  173. *rcond = 1. / ainvnm / *anorm;
  174. }
  175. L20:
  176. return 0;
  177. /* End of DGECON */
  178. } /* _starpu_dgecon_ */