dlarrk.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /* dlarrk.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_dlarrk_(integer *n, integer *iw, doublereal *gl,
  14. doublereal *gu, doublereal *d__, doublereal *e2, doublereal *pivmin,
  15. doublereal *reltol, doublereal *w, doublereal *werr, integer *info)
  16. {
  17. /* System generated locals */
  18. integer i__1;
  19. doublereal d__1, d__2;
  20. /* Builtin functions */
  21. double log(doublereal);
  22. /* Local variables */
  23. integer i__, it;
  24. doublereal mid, eps, tmp1, tmp2, left, atoli, right;
  25. integer itmax;
  26. doublereal rtoli, tnorm;
  27. extern doublereal _starpu_dlamch_(char *);
  28. integer negcnt;
  29. /* -- LAPACK auxiliary routine (version 3.2) -- */
  30. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  31. /* November 2006 */
  32. /* .. Scalar Arguments .. */
  33. /* .. */
  34. /* .. Array Arguments .. */
  35. /* .. */
  36. /* Purpose */
  37. /* ======= */
  38. /* DLARRK computes one eigenvalue of a symmetric tridiagonal */
  39. /* matrix T to suitable accuracy. This is an auxiliary code to be */
  40. /* called from DSTEMR. */
  41. /* To avoid overflow, the matrix must be scaled so that its */
  42. /* largest element is no greater than overflow**(1/2) * */
  43. /* underflow**(1/4) in absolute value, and for greatest */
  44. /* accuracy, it should not be much smaller than that. */
  45. /* See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal */
  46. /* Matrix", Report CS41, Computer Science Dept., Stanford */
  47. /* University, July 21, 1966. */
  48. /* Arguments */
  49. /* ========= */
  50. /* N (input) INTEGER */
  51. /* The order of the tridiagonal matrix T. N >= 0. */
  52. /* IW (input) INTEGER */
  53. /* The index of the eigenvalues to be returned. */
  54. /* GL (input) DOUBLE PRECISION */
  55. /* GU (input) DOUBLE PRECISION */
  56. /* An upper and a lower bound on the eigenvalue. */
  57. /* D (input) DOUBLE PRECISION array, dimension (N) */
  58. /* The n diagonal elements of the tridiagonal matrix T. */
  59. /* E2 (input) DOUBLE PRECISION array, dimension (N-1) */
  60. /* The (n-1) squared off-diagonal elements of the tridiagonal matrix T. */
  61. /* PIVMIN (input) DOUBLE PRECISION */
  62. /* The minimum pivot allowed in the Sturm sequence for T. */
  63. /* RELTOL (input) DOUBLE PRECISION */
  64. /* The minimum relative width of an interval. When an interval */
  65. /* is narrower than RELTOL times the larger (in */
  66. /* magnitude) endpoint, then it is considered to be */
  67. /* sufficiently small, i.e., converged. Note: this should */
  68. /* always be at least radix*machine epsilon. */
  69. /* W (output) DOUBLE PRECISION */
  70. /* WERR (output) DOUBLE PRECISION */
  71. /* The error bound on the corresponding eigenvalue approximation */
  72. /* in W. */
  73. /* INFO (output) INTEGER */
  74. /* = 0: Eigenvalue converged */
  75. /* = -1: Eigenvalue did NOT converge */
  76. /* Internal Parameters */
  77. /* =================== */
  78. /* FUDGE DOUBLE PRECISION, default = 2 */
  79. /* A "fudge factor" to widen the Gershgorin intervals. */
  80. /* ===================================================================== */
  81. /* .. Parameters .. */
  82. /* .. */
  83. /* .. Local Scalars .. */
  84. /* .. */
  85. /* .. External Functions .. */
  86. /* .. */
  87. /* .. Intrinsic Functions .. */
  88. /* .. */
  89. /* .. Executable Statements .. */
  90. /* Get machine constants */
  91. /* Parameter adjustments */
  92. --e2;
  93. --d__;
  94. /* Function Body */
  95. eps = _starpu_dlamch_("P");
  96. /* Computing MAX */
  97. d__1 = abs(*gl), d__2 = abs(*gu);
  98. tnorm = max(d__1,d__2);
  99. rtoli = *reltol;
  100. atoli = *pivmin * 4.;
  101. itmax = (integer) ((log(tnorm + *pivmin) - log(*pivmin)) / log(2.)) + 2;
  102. *info = -1;
  103. left = *gl - tnorm * 2. * eps * *n - *pivmin * 4.;
  104. right = *gu + tnorm * 2. * eps * *n + *pivmin * 4.;
  105. it = 0;
  106. L10:
  107. /* Check if interval converged or maximum number of iterations reached */
  108. tmp1 = (d__1 = right - left, abs(d__1));
  109. /* Computing MAX */
  110. d__1 = abs(right), d__2 = abs(left);
  111. tmp2 = max(d__1,d__2);
  112. /* Computing MAX */
  113. d__1 = max(atoli,*pivmin), d__2 = rtoli * tmp2;
  114. if (tmp1 < max(d__1,d__2)) {
  115. *info = 0;
  116. goto L30;
  117. }
  118. if (it > itmax) {
  119. goto L30;
  120. }
  121. /* Count number of negative pivots for mid-point */
  122. ++it;
  123. mid = (left + right) * .5;
  124. negcnt = 0;
  125. tmp1 = d__[1] - mid;
  126. if (abs(tmp1) < *pivmin) {
  127. tmp1 = -(*pivmin);
  128. }
  129. if (tmp1 <= 0.) {
  130. ++negcnt;
  131. }
  132. i__1 = *n;
  133. for (i__ = 2; i__ <= i__1; ++i__) {
  134. tmp1 = d__[i__] - e2[i__ - 1] / tmp1 - mid;
  135. if (abs(tmp1) < *pivmin) {
  136. tmp1 = -(*pivmin);
  137. }
  138. if (tmp1 <= 0.) {
  139. ++negcnt;
  140. }
  141. /* L20: */
  142. }
  143. if (negcnt >= *iw) {
  144. right = mid;
  145. } else {
  146. left = mid;
  147. }
  148. goto L10;
  149. L30:
  150. /* Converged or maximum number of iterations reached */
  151. *w = (left + right) * .5;
  152. *werr = (d__1 = right - left, abs(d__1)) * .5;
  153. return 0;
  154. /* End of DLARRK */
  155. } /* _starpu_dlarrk_ */