dlaev2.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* dlaev2.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_dlaev2_(doublereal *a, doublereal *b, doublereal *c__,
  14. doublereal *rt1, doublereal *rt2, doublereal *cs1, doublereal *sn1)
  15. {
  16. /* System generated locals */
  17. doublereal d__1;
  18. /* Builtin functions */
  19. double sqrt(doublereal);
  20. /* Local variables */
  21. doublereal ab, df, cs, ct, tb, sm, tn, rt, adf, acs;
  22. integer sgn1, sgn2;
  23. doublereal acmn, acmx;
  24. /* -- LAPACK auxiliary routine (version 3.2) -- */
  25. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  26. /* November 2006 */
  27. /* .. Scalar Arguments .. */
  28. /* .. */
  29. /* Purpose */
  30. /* ======= */
  31. /* DLAEV2 computes the eigendecomposition of a 2-by-2 symmetric matrix */
  32. /* [ A B ] */
  33. /* [ B C ]. */
  34. /* On return, RT1 is the eigenvalue of larger absolute value, RT2 is the */
  35. /* eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right */
  36. /* eigenvector for RT1, giving the decomposition */
  37. /* [ CS1 SN1 ] [ A B ] [ CS1 -SN1 ] = [ RT1 0 ] */
  38. /* [-SN1 CS1 ] [ B C ] [ SN1 CS1 ] [ 0 RT2 ]. */
  39. /* Arguments */
  40. /* ========= */
  41. /* A (input) DOUBLE PRECISION */
  42. /* The (1,1) element of the 2-by-2 matrix. */
  43. /* B (input) DOUBLE PRECISION */
  44. /* The (1,2) element and the conjugate of the (2,1) element of */
  45. /* the 2-by-2 matrix. */
  46. /* C (input) DOUBLE PRECISION */
  47. /* The (2,2) element of the 2-by-2 matrix. */
  48. /* RT1 (output) DOUBLE PRECISION */
  49. /* The eigenvalue of larger absolute value. */
  50. /* RT2 (output) DOUBLE PRECISION */
  51. /* The eigenvalue of smaller absolute value. */
  52. /* CS1 (output) DOUBLE PRECISION */
  53. /* SN1 (output) DOUBLE PRECISION */
  54. /* The vector (CS1, SN1) is a unit right eigenvector for RT1. */
  55. /* Further Details */
  56. /* =============== */
  57. /* RT1 is accurate to a few ulps barring over/underflow. */
  58. /* RT2 may be inaccurate if there is massive cancellation in the */
  59. /* determinant A*C-B*B; higher precision or correctly rounded or */
  60. /* correctly truncated arithmetic would be needed to compute RT2 */
  61. /* accurately in all cases. */
  62. /* CS1 and SN1 are accurate to a few ulps barring over/underflow. */
  63. /* Overflow is possible only if RT1 is within a factor of 5 of overflow. */
  64. /* Underflow is harmless if the input data is 0 or exceeds */
  65. /* underflow_threshold / macheps. */
  66. /* ===================================================================== */
  67. /* .. Parameters .. */
  68. /* .. */
  69. /* .. Local Scalars .. */
  70. /* .. */
  71. /* .. Intrinsic Functions .. */
  72. /* .. */
  73. /* .. Executable Statements .. */
  74. /* Compute the eigenvalues */
  75. sm = *a + *c__;
  76. df = *a - *c__;
  77. adf = abs(df);
  78. tb = *b + *b;
  79. ab = abs(tb);
  80. if (abs(*a) > abs(*c__)) {
  81. acmx = *a;
  82. acmn = *c__;
  83. } else {
  84. acmx = *c__;
  85. acmn = *a;
  86. }
  87. if (adf > ab) {
  88. /* Computing 2nd power */
  89. d__1 = ab / adf;
  90. rt = adf * sqrt(d__1 * d__1 + 1.);
  91. } else if (adf < ab) {
  92. /* Computing 2nd power */
  93. d__1 = adf / ab;
  94. rt = ab * sqrt(d__1 * d__1 + 1.);
  95. } else {
  96. /* Includes case AB=ADF=0 */
  97. rt = ab * sqrt(2.);
  98. }
  99. if (sm < 0.) {
  100. *rt1 = (sm - rt) * .5;
  101. sgn1 = -1;
  102. /* Order of execution important. */
  103. /* To get fully accurate smaller eigenvalue, */
  104. /* next line needs to be executed in higher precision. */
  105. *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
  106. } else if (sm > 0.) {
  107. *rt1 = (sm + rt) * .5;
  108. sgn1 = 1;
  109. /* Order of execution important. */
  110. /* To get fully accurate smaller eigenvalue, */
  111. /* next line needs to be executed in higher precision. */
  112. *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
  113. } else {
  114. /* Includes case RT1 = RT2 = 0 */
  115. *rt1 = rt * .5;
  116. *rt2 = rt * -.5;
  117. sgn1 = 1;
  118. }
  119. /* Compute the eigenvector */
  120. if (df >= 0.) {
  121. cs = df + rt;
  122. sgn2 = 1;
  123. } else {
  124. cs = df - rt;
  125. sgn2 = -1;
  126. }
  127. acs = abs(cs);
  128. if (acs > ab) {
  129. ct = -tb / cs;
  130. *sn1 = 1. / sqrt(ct * ct + 1.);
  131. *cs1 = ct * *sn1;
  132. } else {
  133. if (ab == 0.) {
  134. *cs1 = 1.;
  135. *sn1 = 0.;
  136. } else {
  137. tn = -cs / tb;
  138. *cs1 = 1. / sqrt(tn * tn + 1.);
  139. *sn1 = tn * *cs1;
  140. }
  141. }
  142. if (sgn1 == sgn2) {
  143. tn = *cs1;
  144. *cs1 = -(*sn1);
  145. *sn1 = tn;
  146. }
  147. return 0;
  148. /* End of DLAEV2 */
  149. } /* _starpu_dlaev2_ */