dlaic1.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /* dlaic1.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. static doublereal c_b5 = 1.;
  16. /* Subroutine */ int _starpu_dlaic1_(integer *job, integer *j, doublereal *x,
  17. doublereal *sest, doublereal *w, doublereal *gamma, doublereal *
  18. sestpr, doublereal *s, doublereal *c__)
  19. {
  20. /* System generated locals */
  21. doublereal d__1, d__2, d__3, d__4;
  22. /* Builtin functions */
  23. double sqrt(doublereal), d_sign(doublereal *, doublereal *);
  24. /* Local variables */
  25. doublereal b, t, s1, s2, eps, tmp;
  26. extern doublereal _starpu_ddot_(integer *, doublereal *, integer *, doublereal *,
  27. integer *);
  28. doublereal sine, test, zeta1, zeta2, alpha, norma;
  29. extern doublereal _starpu_dlamch_(char *);
  30. doublereal absgam, absalp, cosine, absest;
  31. /* -- LAPACK auxiliary routine (version 3.2) -- */
  32. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  33. /* November 2006 */
  34. /* .. Scalar Arguments .. */
  35. /* .. */
  36. /* .. Array Arguments .. */
  37. /* .. */
  38. /* Purpose */
  39. /* ======= */
  40. /* DLAIC1 applies one step of incremental condition estimation in */
  41. /* its simplest version: */
  42. /* Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j */
  43. /* lower triangular matrix L, such that */
  44. /* twonorm(L*x) = sest */
  45. /* Then DLAIC1 computes sestpr, s, c such that */
  46. /* the vector */
  47. /* [ s*x ] */
  48. /* xhat = [ c ] */
  49. /* is an approximate singular vector of */
  50. /* [ L 0 ] */
  51. /* Lhat = [ w' gamma ] */
  52. /* in the sense that */
  53. /* twonorm(Lhat*xhat) = sestpr. */
  54. /* Depending on JOB, an estimate for the largest or smallest singular */
  55. /* value is computed. */
  56. /* Note that [s c]' and sestpr**2 is an eigenpair of the system */
  57. /* diag(sest*sest, 0) + [alpha gamma] * [ alpha ] */
  58. /* [ gamma ] */
  59. /* where alpha = x'*w. */
  60. /* Arguments */
  61. /* ========= */
  62. /* JOB (input) INTEGER */
  63. /* = 1: an estimate for the largest singular value is computed. */
  64. /* = 2: an estimate for the smallest singular value is computed. */
  65. /* J (input) INTEGER */
  66. /* Length of X and W */
  67. /* X (input) DOUBLE PRECISION array, dimension (J) */
  68. /* The j-vector x. */
  69. /* SEST (input) DOUBLE PRECISION */
  70. /* Estimated singular value of j by j matrix L */
  71. /* W (input) DOUBLE PRECISION array, dimension (J) */
  72. /* The j-vector w. */
  73. /* GAMMA (input) DOUBLE PRECISION */
  74. /* The diagonal element gamma. */
  75. /* SESTPR (output) DOUBLE PRECISION */
  76. /* Estimated singular value of (j+1) by (j+1) matrix Lhat. */
  77. /* S (output) DOUBLE PRECISION */
  78. /* Sine needed in forming xhat. */
  79. /* C (output) DOUBLE PRECISION */
  80. /* Cosine needed in forming xhat. */
  81. /* ===================================================================== */
  82. /* .. Parameters .. */
  83. /* .. */
  84. /* .. Local Scalars .. */
  85. /* .. */
  86. /* .. Intrinsic Functions .. */
  87. /* .. */
  88. /* .. External Functions .. */
  89. /* .. */
  90. /* .. Executable Statements .. */
  91. /* Parameter adjustments */
  92. --w;
  93. --x;
  94. /* Function Body */
  95. eps = _starpu_dlamch_("Epsilon");
  96. alpha = _starpu_ddot_(j, &x[1], &c__1, &w[1], &c__1);
  97. absalp = abs(alpha);
  98. absgam = abs(*gamma);
  99. absest = abs(*sest);
  100. if (*job == 1) {
  101. /* Estimating largest singular value */
  102. /* special cases */
  103. if (*sest == 0.) {
  104. s1 = max(absgam,absalp);
  105. if (s1 == 0.) {
  106. *s = 0.;
  107. *c__ = 1.;
  108. *sestpr = 0.;
  109. } else {
  110. *s = alpha / s1;
  111. *c__ = *gamma / s1;
  112. tmp = sqrt(*s * *s + *c__ * *c__);
  113. *s /= tmp;
  114. *c__ /= tmp;
  115. *sestpr = s1 * tmp;
  116. }
  117. return 0;
  118. } else if (absgam <= eps * absest) {
  119. *s = 1.;
  120. *c__ = 0.;
  121. tmp = max(absest,absalp);
  122. s1 = absest / tmp;
  123. s2 = absalp / tmp;
  124. *sestpr = tmp * sqrt(s1 * s1 + s2 * s2);
  125. return 0;
  126. } else if (absalp <= eps * absest) {
  127. s1 = absgam;
  128. s2 = absest;
  129. if (s1 <= s2) {
  130. *s = 1.;
  131. *c__ = 0.;
  132. *sestpr = s2;
  133. } else {
  134. *s = 0.;
  135. *c__ = 1.;
  136. *sestpr = s1;
  137. }
  138. return 0;
  139. } else if (absest <= eps * absalp || absest <= eps * absgam) {
  140. s1 = absgam;
  141. s2 = absalp;
  142. if (s1 <= s2) {
  143. tmp = s1 / s2;
  144. *s = sqrt(tmp * tmp + 1.);
  145. *sestpr = s2 * *s;
  146. *c__ = *gamma / s2 / *s;
  147. *s = d_sign(&c_b5, &alpha) / *s;
  148. } else {
  149. tmp = s2 / s1;
  150. *c__ = sqrt(tmp * tmp + 1.);
  151. *sestpr = s1 * *c__;
  152. *s = alpha / s1 / *c__;
  153. *c__ = d_sign(&c_b5, gamma) / *c__;
  154. }
  155. return 0;
  156. } else {
  157. /* normal case */
  158. zeta1 = alpha / absest;
  159. zeta2 = *gamma / absest;
  160. b = (1. - zeta1 * zeta1 - zeta2 * zeta2) * .5;
  161. *c__ = zeta1 * zeta1;
  162. if (b > 0.) {
  163. t = *c__ / (b + sqrt(b * b + *c__));
  164. } else {
  165. t = sqrt(b * b + *c__) - b;
  166. }
  167. sine = -zeta1 / t;
  168. cosine = -zeta2 / (t + 1.);
  169. tmp = sqrt(sine * sine + cosine * cosine);
  170. *s = sine / tmp;
  171. *c__ = cosine / tmp;
  172. *sestpr = sqrt(t + 1.) * absest;
  173. return 0;
  174. }
  175. } else if (*job == 2) {
  176. /* Estimating smallest singular value */
  177. /* special cases */
  178. if (*sest == 0.) {
  179. *sestpr = 0.;
  180. if (max(absgam,absalp) == 0.) {
  181. sine = 1.;
  182. cosine = 0.;
  183. } else {
  184. sine = -(*gamma);
  185. cosine = alpha;
  186. }
  187. /* Computing MAX */
  188. d__1 = abs(sine), d__2 = abs(cosine);
  189. s1 = max(d__1,d__2);
  190. *s = sine / s1;
  191. *c__ = cosine / s1;
  192. tmp = sqrt(*s * *s + *c__ * *c__);
  193. *s /= tmp;
  194. *c__ /= tmp;
  195. return 0;
  196. } else if (absgam <= eps * absest) {
  197. *s = 0.;
  198. *c__ = 1.;
  199. *sestpr = absgam;
  200. return 0;
  201. } else if (absalp <= eps * absest) {
  202. s1 = absgam;
  203. s2 = absest;
  204. if (s1 <= s2) {
  205. *s = 0.;
  206. *c__ = 1.;
  207. *sestpr = s1;
  208. } else {
  209. *s = 1.;
  210. *c__ = 0.;
  211. *sestpr = s2;
  212. }
  213. return 0;
  214. } else if (absest <= eps * absalp || absest <= eps * absgam) {
  215. s1 = absgam;
  216. s2 = absalp;
  217. if (s1 <= s2) {
  218. tmp = s1 / s2;
  219. *c__ = sqrt(tmp * tmp + 1.);
  220. *sestpr = absest * (tmp / *c__);
  221. *s = -(*gamma / s2) / *c__;
  222. *c__ = d_sign(&c_b5, &alpha) / *c__;
  223. } else {
  224. tmp = s2 / s1;
  225. *s = sqrt(tmp * tmp + 1.);
  226. *sestpr = absest / *s;
  227. *c__ = alpha / s1 / *s;
  228. *s = -d_sign(&c_b5, gamma) / *s;
  229. }
  230. return 0;
  231. } else {
  232. /* normal case */
  233. zeta1 = alpha / absest;
  234. zeta2 = *gamma / absest;
  235. /* Computing MAX */
  236. d__3 = zeta1 * zeta1 + 1. + (d__1 = zeta1 * zeta2, abs(d__1)),
  237. d__4 = (d__2 = zeta1 * zeta2, abs(d__2)) + zeta2 * zeta2;
  238. norma = max(d__3,d__4);
  239. /* See if root is closer to zero or to ONE */
  240. test = (zeta1 - zeta2) * 2. * (zeta1 + zeta2) + 1.;
  241. if (test >= 0.) {
  242. /* root is close to zero, compute directly */
  243. b = (zeta1 * zeta1 + zeta2 * zeta2 + 1.) * .5;
  244. *c__ = zeta2 * zeta2;
  245. t = *c__ / (b + sqrt((d__1 = b * b - *c__, abs(d__1))));
  246. sine = zeta1 / (1. - t);
  247. cosine = -zeta2 / t;
  248. *sestpr = sqrt(t + eps * 4. * eps * norma) * absest;
  249. } else {
  250. /* root is closer to ONE, shift by that amount */
  251. b = (zeta2 * zeta2 + zeta1 * zeta1 - 1.) * .5;
  252. *c__ = zeta1 * zeta1;
  253. if (b >= 0.) {
  254. t = -(*c__) / (b + sqrt(b * b + *c__));
  255. } else {
  256. t = b - sqrt(b * b + *c__);
  257. }
  258. sine = -zeta1 / t;
  259. cosine = -zeta2 / (t + 1.);
  260. *sestpr = sqrt(t + 1. + eps * 4. * eps * norma) * absest;
  261. }
  262. tmp = sqrt(sine * sine + cosine * cosine);
  263. *s = sine / tmp;
  264. *c__ = cosine / tmp;
  265. return 0;
  266. }
  267. }
  268. return 0;
  269. /* End of DLAIC1 */
  270. } /* _starpu_dlaic1_ */