dlags2.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /* dlags2.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_dlags2_(logical *upper, doublereal *a1, doublereal *a2,
  14. doublereal *a3, doublereal *b1, doublereal *b2, doublereal *b3,
  15. doublereal *csu, doublereal *snu, doublereal *csv, doublereal *snv,
  16. doublereal *csq, doublereal *snq)
  17. {
  18. /* System generated locals */
  19. doublereal d__1;
  20. /* Local variables */
  21. doublereal a, b, c__, d__, r__, s1, s2, ua11, ua12, ua21, ua22, vb11,
  22. vb12, vb21, vb22, csl, csr, snl, snr, aua11, aua12, aua21, aua22,
  23. avb11, avb12, avb21, avb22, ua11r, ua22r, vb11r, vb22r;
  24. extern /* Subroutine */ int _starpu_dlasv2_(doublereal *, doublereal *,
  25. doublereal *, doublereal *, doublereal *, doublereal *,
  26. doublereal *, doublereal *, doublereal *), _starpu_dlartg_(doublereal *,
  27. doublereal *, doublereal *, doublereal *, doublereal *);
  28. /* -- LAPACK auxiliary routine (version 3.2) -- */
  29. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  30. /* November 2006 */
  31. /* .. Scalar Arguments .. */
  32. /* .. */
  33. /* Purpose */
  34. /* ======= */
  35. /* DLAGS2 computes 2-by-2 orthogonal matrices U, V and Q, such */
  36. /* that if ( UPPER ) then */
  37. /* U'*A*Q = U'*( A1 A2 )*Q = ( x 0 ) */
  38. /* ( 0 A3 ) ( x x ) */
  39. /* and */
  40. /* V'*B*Q = V'*( B1 B2 )*Q = ( x 0 ) */
  41. /* ( 0 B3 ) ( x x ) */
  42. /* or if ( .NOT.UPPER ) then */
  43. /* U'*A*Q = U'*( A1 0 )*Q = ( x x ) */
  44. /* ( A2 A3 ) ( 0 x ) */
  45. /* and */
  46. /* V'*B*Q = V'*( B1 0 )*Q = ( x x ) */
  47. /* ( B2 B3 ) ( 0 x ) */
  48. /* The rows of the transformed A and B are parallel, where */
  49. /* U = ( CSU SNU ), V = ( CSV SNV ), Q = ( CSQ SNQ ) */
  50. /* ( -SNU CSU ) ( -SNV CSV ) ( -SNQ CSQ ) */
  51. /* Z' denotes the transpose of Z. */
  52. /* Arguments */
  53. /* ========= */
  54. /* UPPER (input) LOGICAL */
  55. /* = .TRUE.: the input matrices A and B are upper triangular. */
  56. /* = .FALSE.: the input matrices A and B are lower triangular. */
  57. /* A1 (input) DOUBLE PRECISION */
  58. /* A2 (input) DOUBLE PRECISION */
  59. /* A3 (input) DOUBLE PRECISION */
  60. /* On entry, A1, A2 and A3 are elements of the input 2-by-2 */
  61. /* upper (lower) triangular matrix A. */
  62. /* B1 (input) DOUBLE PRECISION */
  63. /* B2 (input) DOUBLE PRECISION */
  64. /* B3 (input) DOUBLE PRECISION */
  65. /* On entry, B1, B2 and B3 are elements of the input 2-by-2 */
  66. /* upper (lower) triangular matrix B. */
  67. /* CSU (output) DOUBLE PRECISION */
  68. /* SNU (output) DOUBLE PRECISION */
  69. /* The desired orthogonal matrix U. */
  70. /* CSV (output) DOUBLE PRECISION */
  71. /* SNV (output) DOUBLE PRECISION */
  72. /* The desired orthogonal matrix V. */
  73. /* CSQ (output) DOUBLE PRECISION */
  74. /* SNQ (output) DOUBLE PRECISION */
  75. /* The desired orthogonal matrix Q. */
  76. /* ===================================================================== */
  77. /* .. Parameters .. */
  78. /* .. */
  79. /* .. Local Scalars .. */
  80. /* .. */
  81. /* .. External Subroutines .. */
  82. /* .. */
  83. /* .. Intrinsic Functions .. */
  84. /* .. */
  85. /* .. Executable Statements .. */
  86. if (*upper) {
  87. /* Input matrices A and B are upper triangular matrices */
  88. /* Form matrix C = A*adj(B) = ( a b ) */
  89. /* ( 0 d ) */
  90. a = *a1 * *b3;
  91. d__ = *a3 * *b1;
  92. b = *a2 * *b1 - *a1 * *b2;
  93. /* The SVD of real 2-by-2 triangular C */
  94. /* ( CSL -SNL )*( A B )*( CSR SNR ) = ( R 0 ) */
  95. /* ( SNL CSL ) ( 0 D ) ( -SNR CSR ) ( 0 T ) */
  96. _starpu_dlasv2_(&a, &b, &d__, &s1, &s2, &snr, &csr, &snl, &csl);
  97. if (abs(csl) >= abs(snl) || abs(csr) >= abs(snr)) {
  98. /* Compute the (1,1) and (1,2) elements of U'*A and V'*B, */
  99. /* and (1,2) element of |U|'*|A| and |V|'*|B|. */
  100. ua11r = csl * *a1;
  101. ua12 = csl * *a2 + snl * *a3;
  102. vb11r = csr * *b1;
  103. vb12 = csr * *b2 + snr * *b3;
  104. aua12 = abs(csl) * abs(*a2) + abs(snl) * abs(*a3);
  105. avb12 = abs(csr) * abs(*b2) + abs(snr) * abs(*b3);
  106. /* zero (1,2) elements of U'*A and V'*B */
  107. if (abs(ua11r) + abs(ua12) != 0.) {
  108. if (aua12 / (abs(ua11r) + abs(ua12)) <= avb12 / (abs(vb11r) +
  109. abs(vb12))) {
  110. d__1 = -ua11r;
  111. _starpu_dlartg_(&d__1, &ua12, csq, snq, &r__);
  112. } else {
  113. d__1 = -vb11r;
  114. _starpu_dlartg_(&d__1, &vb12, csq, snq, &r__);
  115. }
  116. } else {
  117. d__1 = -vb11r;
  118. _starpu_dlartg_(&d__1, &vb12, csq, snq, &r__);
  119. }
  120. *csu = csl;
  121. *snu = -snl;
  122. *csv = csr;
  123. *snv = -snr;
  124. } else {
  125. /* Compute the (2,1) and (2,2) elements of U'*A and V'*B, */
  126. /* and (2,2) element of |U|'*|A| and |V|'*|B|. */
  127. ua21 = -snl * *a1;
  128. ua22 = -snl * *a2 + csl * *a3;
  129. vb21 = -snr * *b1;
  130. vb22 = -snr * *b2 + csr * *b3;
  131. aua22 = abs(snl) * abs(*a2) + abs(csl) * abs(*a3);
  132. avb22 = abs(snr) * abs(*b2) + abs(csr) * abs(*b3);
  133. /* zero (2,2) elements of U'*A and V'*B, and then swap. */
  134. if (abs(ua21) + abs(ua22) != 0.) {
  135. if (aua22 / (abs(ua21) + abs(ua22)) <= avb22 / (abs(vb21) +
  136. abs(vb22))) {
  137. d__1 = -ua21;
  138. _starpu_dlartg_(&d__1, &ua22, csq, snq, &r__);
  139. } else {
  140. d__1 = -vb21;
  141. _starpu_dlartg_(&d__1, &vb22, csq, snq, &r__);
  142. }
  143. } else {
  144. d__1 = -vb21;
  145. _starpu_dlartg_(&d__1, &vb22, csq, snq, &r__);
  146. }
  147. *csu = snl;
  148. *snu = csl;
  149. *csv = snr;
  150. *snv = csr;
  151. }
  152. } else {
  153. /* Input matrices A and B are lower triangular matrices */
  154. /* Form matrix C = A*adj(B) = ( a 0 ) */
  155. /* ( c d ) */
  156. a = *a1 * *b3;
  157. d__ = *a3 * *b1;
  158. c__ = *a2 * *b3 - *a3 * *b2;
  159. /* The SVD of real 2-by-2 triangular C */
  160. /* ( CSL -SNL )*( A 0 )*( CSR SNR ) = ( R 0 ) */
  161. /* ( SNL CSL ) ( C D ) ( -SNR CSR ) ( 0 T ) */
  162. _starpu_dlasv2_(&a, &c__, &d__, &s1, &s2, &snr, &csr, &snl, &csl);
  163. if (abs(csr) >= abs(snr) || abs(csl) >= abs(snl)) {
  164. /* Compute the (2,1) and (2,2) elements of U'*A and V'*B, */
  165. /* and (2,1) element of |U|'*|A| and |V|'*|B|. */
  166. ua21 = -snr * *a1 + csr * *a2;
  167. ua22r = csr * *a3;
  168. vb21 = -snl * *b1 + csl * *b2;
  169. vb22r = csl * *b3;
  170. aua21 = abs(snr) * abs(*a1) + abs(csr) * abs(*a2);
  171. avb21 = abs(snl) * abs(*b1) + abs(csl) * abs(*b2);
  172. /* zero (2,1) elements of U'*A and V'*B. */
  173. if (abs(ua21) + abs(ua22r) != 0.) {
  174. if (aua21 / (abs(ua21) + abs(ua22r)) <= avb21 / (abs(vb21) +
  175. abs(vb22r))) {
  176. _starpu_dlartg_(&ua22r, &ua21, csq, snq, &r__);
  177. } else {
  178. _starpu_dlartg_(&vb22r, &vb21, csq, snq, &r__);
  179. }
  180. } else {
  181. _starpu_dlartg_(&vb22r, &vb21, csq, snq, &r__);
  182. }
  183. *csu = csr;
  184. *snu = -snr;
  185. *csv = csl;
  186. *snv = -snl;
  187. } else {
  188. /* Compute the (1,1) and (1,2) elements of U'*A and V'*B, */
  189. /* and (1,1) element of |U|'*|A| and |V|'*|B|. */
  190. ua11 = csr * *a1 + snr * *a2;
  191. ua12 = snr * *a3;
  192. vb11 = csl * *b1 + snl * *b2;
  193. vb12 = snl * *b3;
  194. aua11 = abs(csr) * abs(*a1) + abs(snr) * abs(*a2);
  195. avb11 = abs(csl) * abs(*b1) + abs(snl) * abs(*b2);
  196. /* zero (1,1) elements of U'*A and V'*B, and then swap. */
  197. if (abs(ua11) + abs(ua12) != 0.) {
  198. if (aua11 / (abs(ua11) + abs(ua12)) <= avb11 / (abs(vb11) +
  199. abs(vb12))) {
  200. _starpu_dlartg_(&ua12, &ua11, csq, snq, &r__);
  201. } else {
  202. _starpu_dlartg_(&vb12, &vb11, csq, snq, &r__);
  203. }
  204. } else {
  205. _starpu_dlartg_(&vb12, &vb11, csq, snq, &r__);
  206. }
  207. *csu = snr;
  208. *snu = csr;
  209. *csv = snl;
  210. *snv = csl;
  211. }
  212. }
  213. return 0;
  214. /* End of DLAGS2 */
  215. } /* _starpu_dlags2_ */