dlasq3.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /* dlasq3.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 dlasq3_(integer *i0, integer *n0, doublereal *z__,
  14. integer *pp, doublereal *dmin__, doublereal *sigma, doublereal *desig,
  15. doublereal *qmax, integer *nfail, integer *iter, integer *ndiv,
  16. logical *ieee, integer *ttype, doublereal *dmin1, doublereal *dmin2,
  17. doublereal *dn, doublereal *dn1, doublereal *dn2, doublereal *g,
  18. doublereal *tau)
  19. {
  20. /* System generated locals */
  21. integer i__1;
  22. doublereal d__1, d__2;
  23. /* Builtin functions */
  24. double sqrt(doublereal);
  25. /* Local variables */
  26. doublereal s, t;
  27. integer j4, nn;
  28. doublereal eps, tol;
  29. integer n0in, ipn4;
  30. doublereal tol2, temp;
  31. extern /* Subroutine */ int dlasq4_(integer *, integer *, doublereal *,
  32. integer *, integer *, doublereal *, doublereal *, doublereal *,
  33. doublereal *, doublereal *, doublereal *, doublereal *, integer *,
  34. doublereal *), dlasq5_(integer *, integer *, doublereal *,
  35. integer *, doublereal *, doublereal *, doublereal *, doublereal *,
  36. doublereal *, doublereal *, doublereal *, logical *), dlasq6_(
  37. integer *, integer *, doublereal *, integer *, doublereal *,
  38. doublereal *, doublereal *, doublereal *, doublereal *,
  39. doublereal *);
  40. extern doublereal dlamch_(char *);
  41. extern logical disnan_(doublereal *);
  42. /* -- LAPACK routine (version 3.2) -- */
  43. /* -- Contributed by Osni Marques of the Lawrence Berkeley National -- */
  44. /* -- Laboratory and Beresford Parlett of the Univ. of California at -- */
  45. /* -- Berkeley -- */
  46. /* -- November 2008 -- */
  47. /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
  48. /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
  49. /* .. Scalar Arguments .. */
  50. /* .. */
  51. /* .. Array Arguments .. */
  52. /* .. */
  53. /* Purpose */
  54. /* ======= */
  55. /* DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds. */
  56. /* In case of failure it changes shifts, and tries again until output */
  57. /* is positive. */
  58. /* Arguments */
  59. /* ========= */
  60. /* I0 (input) INTEGER */
  61. /* First index. */
  62. /* N0 (input) INTEGER */
  63. /* Last index. */
  64. /* Z (input) DOUBLE PRECISION array, dimension ( 4*N ) */
  65. /* Z holds the qd array. */
  66. /* PP (input/output) INTEGER */
  67. /* PP=0 for ping, PP=1 for pong. */
  68. /* PP=2 indicates that flipping was applied to the Z array */
  69. /* and that the initial tests for deflation should not be */
  70. /* performed. */
  71. /* DMIN (output) DOUBLE PRECISION */
  72. /* Minimum value of d. */
  73. /* SIGMA (output) DOUBLE PRECISION */
  74. /* Sum of shifts used in current segment. */
  75. /* DESIG (input/output) DOUBLE PRECISION */
  76. /* Lower order part of SIGMA */
  77. /* QMAX (input) DOUBLE PRECISION */
  78. /* Maximum value of q. */
  79. /* NFAIL (output) INTEGER */
  80. /* Number of times shift was too big. */
  81. /* ITER (output) INTEGER */
  82. /* Number of iterations. */
  83. /* NDIV (output) INTEGER */
  84. /* Number of divisions. */
  85. /* IEEE (input) LOGICAL */
  86. /* Flag for IEEE or non IEEE arithmetic (passed to DLASQ5). */
  87. /* TTYPE (input/output) INTEGER */
  88. /* Shift type. */
  89. /* DMIN1, DMIN2, DN, DN1, DN2, G, TAU (input/output) DOUBLE PRECISION */
  90. /* These are passed as arguments in order to save their values */
  91. /* between calls to DLASQ3. */
  92. /* ===================================================================== */
  93. /* .. Parameters .. */
  94. /* .. */
  95. /* .. Local Scalars .. */
  96. /* .. */
  97. /* .. External Subroutines .. */
  98. /* .. */
  99. /* .. External Function .. */
  100. /* .. */
  101. /* .. Intrinsic Functions .. */
  102. /* .. */
  103. /* .. Executable Statements .. */
  104. /* Parameter adjustments */
  105. --z__;
  106. /* Function Body */
  107. n0in = *n0;
  108. eps = dlamch_("Precision");
  109. tol = eps * 100.;
  110. /* Computing 2nd power */
  111. d__1 = tol;
  112. tol2 = d__1 * d__1;
  113. /* Check for deflation. */
  114. L10:
  115. if (*n0 < *i0) {
  116. return 0;
  117. }
  118. if (*n0 == *i0) {
  119. goto L20;
  120. }
  121. nn = (*n0 << 2) + *pp;
  122. if (*n0 == *i0 + 1) {
  123. goto L40;
  124. }
  125. /* Check whether E(N0-1) is negligible, 1 eigenvalue. */
  126. if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) -
  127. 4] > tol2 * z__[nn - 7]) {
  128. goto L30;
  129. }
  130. L20:
  131. z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
  132. --(*n0);
  133. goto L10;
  134. /* Check whether E(N0-2) is negligible, 2 eigenvalues. */
  135. L30:
  136. if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
  137. nn - 11]) {
  138. goto L50;
  139. }
  140. L40:
  141. if (z__[nn - 3] > z__[nn - 7]) {
  142. s = z__[nn - 3];
  143. z__[nn - 3] = z__[nn - 7];
  144. z__[nn - 7] = s;
  145. }
  146. if (z__[nn - 5] > z__[nn - 3] * tol2) {
  147. t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
  148. s = z__[nn - 3] * (z__[nn - 5] / t);
  149. if (s <= t) {
  150. s = z__[nn - 3] * (z__[nn - 5] / (t * (sqrt(s / t + 1.) + 1.)));
  151. } else {
  152. s = z__[nn - 3] * (z__[nn - 5] / (t + sqrt(t) * sqrt(t + s)));
  153. }
  154. t = z__[nn - 7] + (s + z__[nn - 5]);
  155. z__[nn - 3] *= z__[nn - 7] / t;
  156. z__[nn - 7] = t;
  157. }
  158. z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
  159. z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
  160. *n0 += -2;
  161. goto L10;
  162. L50:
  163. if (*pp == 2) {
  164. *pp = 0;
  165. }
  166. /* Reverse the qd-array, if warranted. */
  167. if (*dmin__ <= 0. || *n0 < n0in) {
  168. if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
  169. ipn4 = *i0 + *n0 << 2;
  170. i__1 = *i0 + *n0 - 1 << 1;
  171. for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
  172. temp = z__[j4 - 3];
  173. z__[j4 - 3] = z__[ipn4 - j4 - 3];
  174. z__[ipn4 - j4 - 3] = temp;
  175. temp = z__[j4 - 2];
  176. z__[j4 - 2] = z__[ipn4 - j4 - 2];
  177. z__[ipn4 - j4 - 2] = temp;
  178. temp = z__[j4 - 1];
  179. z__[j4 - 1] = z__[ipn4 - j4 - 5];
  180. z__[ipn4 - j4 - 5] = temp;
  181. temp = z__[j4];
  182. z__[j4] = z__[ipn4 - j4 - 4];
  183. z__[ipn4 - j4 - 4] = temp;
  184. /* L60: */
  185. }
  186. if (*n0 - *i0 <= 4) {
  187. z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
  188. z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
  189. }
  190. /* Computing MIN */
  191. d__1 = *dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
  192. *dmin2 = min(d__1,d__2);
  193. /* Computing MIN */
  194. d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
  195. , d__1 = min(d__1,d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
  196. z__[(*n0 << 2) + *pp - 1] = min(d__1,d__2);
  197. /* Computing MIN */
  198. d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
  199. min(d__1,d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
  200. z__[(*n0 << 2) - *pp] = min(d__1,d__2);
  201. /* Computing MAX */
  202. d__1 = *qmax, d__2 = z__[(*i0 << 2) + *pp - 3], d__1 = max(d__1,
  203. d__2), d__2 = z__[(*i0 << 2) + *pp + 1];
  204. *qmax = max(d__1,d__2);
  205. *dmin__ = -0.;
  206. }
  207. }
  208. /* Choose a shift. */
  209. dlasq4_(i0, n0, &z__[1], pp, &n0in, dmin__, dmin1, dmin2, dn, dn1, dn2,
  210. tau, ttype, g);
  211. /* Call dqds until DMIN > 0. */
  212. L70:
  213. dlasq5_(i0, n0, &z__[1], pp, tau, dmin__, dmin1, dmin2, dn, dn1, dn2,
  214. ieee);
  215. *ndiv += *n0 - *i0 + 2;
  216. ++(*iter);
  217. /* Check status. */
  218. if (*dmin__ >= 0. && *dmin1 > 0.) {
  219. /* Success. */
  220. goto L90;
  221. } else if (*dmin__ < 0. && *dmin1 > 0. && z__[(*n0 - 1 << 2) - *pp] < tol
  222. * (*sigma + *dn1) && abs(*dn) < tol * *sigma) {
  223. /* Convergence hidden by negative DN. */
  224. z__[(*n0 - 1 << 2) - *pp + 2] = 0.;
  225. *dmin__ = 0.;
  226. goto L90;
  227. } else if (*dmin__ < 0.) {
  228. /* TAU too big. Select new TAU and try again. */
  229. ++(*nfail);
  230. if (*ttype < -22) {
  231. /* Failed twice. Play it safe. */
  232. *tau = 0.;
  233. } else if (*dmin1 > 0.) {
  234. /* Late failure. Gives excellent shift. */
  235. *tau = (*tau + *dmin__) * (1. - eps * 2.);
  236. *ttype += -11;
  237. } else {
  238. /* Early failure. Divide by 4. */
  239. *tau *= .25;
  240. *ttype += -12;
  241. }
  242. goto L70;
  243. } else if (disnan_(dmin__)) {
  244. /* NaN. */
  245. if (*tau == 0.) {
  246. goto L80;
  247. } else {
  248. *tau = 0.;
  249. goto L70;
  250. }
  251. } else {
  252. /* Possible underflow. Play it safe. */
  253. goto L80;
  254. }
  255. /* Risk of underflow. */
  256. L80:
  257. dlasq6_(i0, n0, &z__[1], pp, dmin__, dmin1, dmin2, dn, dn1, dn2);
  258. *ndiv += *n0 - *i0 + 2;
  259. ++(*iter);
  260. *tau = 0.;
  261. L90:
  262. if (*tau < *sigma) {
  263. *desig += *tau;
  264. t = *sigma + *desig;
  265. *desig -= t - *sigma;
  266. } else {
  267. t = *sigma + *tau;
  268. *desig = *sigma - (t - *tau) + *desig;
  269. }
  270. *sigma = t;
  271. return 0;
  272. /* End of DLASQ3 */
  273. } /* dlasq3_ */