ddisna.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* ddisna.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 _starpu_ddisna_(char *job, integer *m, integer *n, doublereal *
  14. d__, doublereal *sep, integer *info)
  15. {
  16. /* System generated locals */
  17. integer i__1;
  18. doublereal d__1, d__2, d__3;
  19. /* Local variables */
  20. integer i__, k;
  21. doublereal eps;
  22. logical decr, left, incr, sing, eigen;
  23. extern logical _starpu_lsame_(char *, char *);
  24. doublereal anorm;
  25. logical right;
  26. extern doublereal _starpu_dlamch_(char *);
  27. doublereal oldgap, safmin;
  28. extern /* Subroutine */ int _starpu_xerbla_(char *, integer *);
  29. doublereal newgap, thresh;
  30. /* -- LAPACK routine (version 3.2) -- */
  31. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  32. /* November 2006 */
  33. /* .. Scalar Arguments .. */
  34. /* .. */
  35. /* .. Array Arguments .. */
  36. /* .. */
  37. /* Purpose */
  38. /* ======= */
  39. /* DDISNA computes the reciprocal condition numbers for the eigenvectors */
  40. /* of a real symmetric or complex Hermitian matrix or for the left or */
  41. /* right singular vectors of a general m-by-n matrix. The reciprocal */
  42. /* condition number is the 'gap' between the corresponding eigenvalue or */
  43. /* singular value and the nearest other one. */
  44. /* The bound on the error, measured by angle in radians, in the I-th */
  45. /* computed vector is given by */
  46. /* DLAMCH( 'E' ) * ( ANORM / SEP( I ) ) */
  47. /* where ANORM = 2-norm(A) = max( abs( D(j) ) ). SEP(I) is not allowed */
  48. /* to be smaller than DLAMCH( 'E' )*ANORM in order to limit the size of */
  49. /* the error bound. */
  50. /* DDISNA may also be used to compute error bounds for eigenvectors of */
  51. /* the generalized symmetric definite eigenproblem. */
  52. /* Arguments */
  53. /* ========= */
  54. /* JOB (input) CHARACTER*1 */
  55. /* Specifies for which problem the reciprocal condition numbers */
  56. /* should be computed: */
  57. /* = 'E': the eigenvectors of a symmetric/Hermitian matrix; */
  58. /* = 'L': the left singular vectors of a general matrix; */
  59. /* = 'R': the right singular vectors of a general matrix. */
  60. /* M (input) INTEGER */
  61. /* The number of rows of the matrix. M >= 0. */
  62. /* N (input) INTEGER */
  63. /* If JOB = 'L' or 'R', the number of columns of the matrix, */
  64. /* in which case N >= 0. Ignored if JOB = 'E'. */
  65. /* D (input) DOUBLE PRECISION array, dimension (M) if JOB = 'E' */
  66. /* dimension (min(M,N)) if JOB = 'L' or 'R' */
  67. /* The eigenvalues (if JOB = 'E') or singular values (if JOB = */
  68. /* 'L' or 'R') of the matrix, in either increasing or decreasing */
  69. /* order. If singular values, they must be non-negative. */
  70. /* SEP (output) DOUBLE PRECISION array, dimension (M) if JOB = 'E' */
  71. /* dimension (min(M,N)) if JOB = 'L' or 'R' */
  72. /* The reciprocal condition numbers of the vectors. */
  73. /* INFO (output) INTEGER */
  74. /* = 0: successful exit. */
  75. /* < 0: if INFO = -i, the i-th argument had an illegal value. */
  76. /* ===================================================================== */
  77. /* .. Parameters .. */
  78. /* .. */
  79. /* .. Local Scalars .. */
  80. /* .. */
  81. /* .. External Functions .. */
  82. /* .. */
  83. /* .. Intrinsic Functions .. */
  84. /* .. */
  85. /* .. External Subroutines .. */
  86. /* .. */
  87. /* .. Executable Statements .. */
  88. /* Test the input arguments */
  89. /* Parameter adjustments */
  90. --sep;
  91. --d__;
  92. /* Function Body */
  93. *info = 0;
  94. eigen = _starpu_lsame_(job, "E");
  95. left = _starpu_lsame_(job, "L");
  96. right = _starpu_lsame_(job, "R");
  97. sing = left || right;
  98. if (eigen) {
  99. k = *m;
  100. } else if (sing) {
  101. k = min(*m,*n);
  102. }
  103. if (! eigen && ! sing) {
  104. *info = -1;
  105. } else if (*m < 0) {
  106. *info = -2;
  107. } else if (k < 0) {
  108. *info = -3;
  109. } else {
  110. incr = TRUE_;
  111. decr = TRUE_;
  112. i__1 = k - 1;
  113. for (i__ = 1; i__ <= i__1; ++i__) {
  114. if (incr) {
  115. incr = incr && d__[i__] <= d__[i__ + 1];
  116. }
  117. if (decr) {
  118. decr = decr && d__[i__] >= d__[i__ + 1];
  119. }
  120. /* L10: */
  121. }
  122. if (sing && k > 0) {
  123. if (incr) {
  124. incr = incr && 0. <= d__[1];
  125. }
  126. if (decr) {
  127. decr = decr && d__[k] >= 0.;
  128. }
  129. }
  130. if (! (incr || decr)) {
  131. *info = -4;
  132. }
  133. }
  134. if (*info != 0) {
  135. i__1 = -(*info);
  136. _starpu_xerbla_("DDISNA", &i__1);
  137. return 0;
  138. }
  139. /* Quick return if possible */
  140. if (k == 0) {
  141. return 0;
  142. }
  143. /* Compute reciprocal condition numbers */
  144. if (k == 1) {
  145. sep[1] = _starpu_dlamch_("O");
  146. } else {
  147. oldgap = (d__1 = d__[2] - d__[1], abs(d__1));
  148. sep[1] = oldgap;
  149. i__1 = k - 1;
  150. for (i__ = 2; i__ <= i__1; ++i__) {
  151. newgap = (d__1 = d__[i__ + 1] - d__[i__], abs(d__1));
  152. sep[i__] = min(oldgap,newgap);
  153. oldgap = newgap;
  154. /* L20: */
  155. }
  156. sep[k] = oldgap;
  157. }
  158. if (sing) {
  159. if (left && *m > *n || right && *m < *n) {
  160. if (incr) {
  161. sep[1] = min(sep[1],d__[1]);
  162. }
  163. if (decr) {
  164. /* Computing MIN */
  165. d__1 = sep[k], d__2 = d__[k];
  166. sep[k] = min(d__1,d__2);
  167. }
  168. }
  169. }
  170. /* Ensure that reciprocal condition numbers are not less than */
  171. /* threshold, in order to limit the size of the error bound */
  172. eps = _starpu_dlamch_("E");
  173. safmin = _starpu_dlamch_("S");
  174. /* Computing MAX */
  175. d__2 = abs(d__[1]), d__3 = (d__1 = d__[k], abs(d__1));
  176. anorm = max(d__2,d__3);
  177. if (anorm == 0.) {
  178. thresh = eps;
  179. } else {
  180. /* Computing MAX */
  181. d__1 = eps * anorm;
  182. thresh = max(d__1,safmin);
  183. }
  184. i__1 = k;
  185. for (i__ = 1; i__ <= i__1; ++i__) {
  186. /* Computing MAX */
  187. d__1 = sep[i__];
  188. sep[i__] = max(d__1,thresh);
  189. /* L30: */
  190. }
  191. return 0;
  192. /* End of DDISNA */
  193. } /* _starpu_ddisna_ */