dlarft.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /* dlarft.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_b8 = 0.;
  16. /* Subroutine */ int dlarft_(char *direct, char *storev, integer *n, integer *
  17. k, doublereal *v, integer *ldv, doublereal *tau, doublereal *t,
  18. integer *ldt)
  19. {
  20. /* System generated locals */
  21. integer t_dim1, t_offset, v_dim1, v_offset, i__1, i__2, i__3;
  22. doublereal d__1;
  23. /* Local variables */
  24. integer i__, j, prevlastv;
  25. doublereal vii;
  26. extern logical lsame_(char *, char *);
  27. extern /* Subroutine */ int dgemv_(char *, integer *, integer *,
  28. doublereal *, doublereal *, integer *, doublereal *, integer *,
  29. doublereal *, doublereal *, integer *);
  30. integer lastv;
  31. extern /* Subroutine */ int dtrmv_(char *, char *, char *, integer *,
  32. doublereal *, integer *, doublereal *, integer *);
  33. /* -- LAPACK auxiliary routine (version 3.2) -- */
  34. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  35. /* November 2006 */
  36. /* .. Scalar Arguments .. */
  37. /* .. */
  38. /* .. Array Arguments .. */
  39. /* .. */
  40. /* Purpose */
  41. /* ======= */
  42. /* DLARFT forms the triangular factor T of a real block reflector H */
  43. /* of order n, which is defined as a product of k elementary reflectors. */
  44. /* If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular; */
  45. /* If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular. */
  46. /* If STOREV = 'C', the vector which defines the elementary reflector */
  47. /* H(i) is stored in the i-th column of the array V, and */
  48. /* H = I - V * T * V' */
  49. /* If STOREV = 'R', the vector which defines the elementary reflector */
  50. /* H(i) is stored in the i-th row of the array V, and */
  51. /* H = I - V' * T * V */
  52. /* Arguments */
  53. /* ========= */
  54. /* DIRECT (input) CHARACTER*1 */
  55. /* Specifies the order in which the elementary reflectors are */
  56. /* multiplied to form the block reflector: */
  57. /* = 'F': H = H(1) H(2) . . . H(k) (Forward) */
  58. /* = 'B': H = H(k) . . . H(2) H(1) (Backward) */
  59. /* STOREV (input) CHARACTER*1 */
  60. /* Specifies how the vectors which define the elementary */
  61. /* reflectors are stored (see also Further Details): */
  62. /* = 'C': columnwise */
  63. /* = 'R': rowwise */
  64. /* N (input) INTEGER */
  65. /* The order of the block reflector H. N >= 0. */
  66. /* K (input) INTEGER */
  67. /* The order of the triangular factor T (= the number of */
  68. /* elementary reflectors). K >= 1. */
  69. /* V (input/output) DOUBLE PRECISION array, dimension */
  70. /* (LDV,K) if STOREV = 'C' */
  71. /* (LDV,N) if STOREV = 'R' */
  72. /* The matrix V. See further details. */
  73. /* LDV (input) INTEGER */
  74. /* The leading dimension of the array V. */
  75. /* If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K. */
  76. /* TAU (input) DOUBLE PRECISION array, dimension (K) */
  77. /* TAU(i) must contain the scalar factor of the elementary */
  78. /* reflector H(i). */
  79. /* T (output) DOUBLE PRECISION array, dimension (LDT,K) */
  80. /* The k by k triangular factor T of the block reflector. */
  81. /* If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is */
  82. /* lower triangular. The rest of the array is not used. */
  83. /* LDT (input) INTEGER */
  84. /* The leading dimension of the array T. LDT >= K. */
  85. /* Further Details */
  86. /* =============== */
  87. /* The shape of the matrix V and the storage of the vectors which define */
  88. /* the H(i) is best illustrated by the following example with n = 5 and */
  89. /* k = 3. The elements equal to 1 are not stored; the corresponding */
  90. /* array elements are modified but restored on exit. The rest of the */
  91. /* array is not used. */
  92. /* DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R': */
  93. /* V = ( 1 ) V = ( 1 v1 v1 v1 v1 ) */
  94. /* ( v1 1 ) ( 1 v2 v2 v2 ) */
  95. /* ( v1 v2 1 ) ( 1 v3 v3 ) */
  96. /* ( v1 v2 v3 ) */
  97. /* ( v1 v2 v3 ) */
  98. /* DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R': */
  99. /* V = ( v1 v2 v3 ) V = ( v1 v1 1 ) */
  100. /* ( v1 v2 v3 ) ( v2 v2 v2 1 ) */
  101. /* ( 1 v2 v3 ) ( v3 v3 v3 v3 1 ) */
  102. /* ( 1 v3 ) */
  103. /* ( 1 ) */
  104. /* ===================================================================== */
  105. /* .. Parameters .. */
  106. /* .. */
  107. /* .. Local Scalars .. */
  108. /* .. */
  109. /* .. External Subroutines .. */
  110. /* .. */
  111. /* .. External Functions .. */
  112. /* .. */
  113. /* .. Executable Statements .. */
  114. /* Quick return if possible */
  115. /* Parameter adjustments */
  116. v_dim1 = *ldv;
  117. v_offset = 1 + v_dim1;
  118. v -= v_offset;
  119. --tau;
  120. t_dim1 = *ldt;
  121. t_offset = 1 + t_dim1;
  122. t -= t_offset;
  123. /* Function Body */
  124. if (*n == 0) {
  125. return 0;
  126. }
  127. if (lsame_(direct, "F")) {
  128. prevlastv = *n;
  129. i__1 = *k;
  130. for (i__ = 1; i__ <= i__1; ++i__) {
  131. prevlastv = max(i__,prevlastv);
  132. if (tau[i__] == 0.) {
  133. /* H(i) = I */
  134. i__2 = i__;
  135. for (j = 1; j <= i__2; ++j) {
  136. t[j + i__ * t_dim1] = 0.;
  137. /* L10: */
  138. }
  139. } else {
  140. /* general case */
  141. vii = v[i__ + i__ * v_dim1];
  142. v[i__ + i__ * v_dim1] = 1.;
  143. if (lsame_(storev, "C")) {
  144. /* Skip any trailing zeros. */
  145. i__2 = i__ + 1;
  146. for (lastv = *n; lastv >= i__2; --lastv) {
  147. if (v[lastv + i__ * v_dim1] != 0.) {
  148. break;
  149. }
  150. }
  151. j = min(lastv,prevlastv);
  152. /* T(1:i-1,i) := - tau(i) * V(i:j,1:i-1)' * V(i:j,i) */
  153. i__2 = j - i__ + 1;
  154. i__3 = i__ - 1;
  155. d__1 = -tau[i__];
  156. dgemv_("Transpose", &i__2, &i__3, &d__1, &v[i__ + v_dim1],
  157. ldv, &v[i__ + i__ * v_dim1], &c__1, &c_b8, &t[
  158. i__ * t_dim1 + 1], &c__1);
  159. } else {
  160. /* Skip any trailing zeros. */
  161. i__2 = i__ + 1;
  162. for (lastv = *n; lastv >= i__2; --lastv) {
  163. if (v[i__ + lastv * v_dim1] != 0.) {
  164. break;
  165. }
  166. }
  167. j = min(lastv,prevlastv);
  168. /* T(1:i-1,i) := - tau(i) * V(1:i-1,i:j) * V(i,i:j)' */
  169. i__2 = i__ - 1;
  170. i__3 = j - i__ + 1;
  171. d__1 = -tau[i__];
  172. dgemv_("No transpose", &i__2, &i__3, &d__1, &v[i__ *
  173. v_dim1 + 1], ldv, &v[i__ + i__ * v_dim1], ldv, &
  174. c_b8, &t[i__ * t_dim1 + 1], &c__1);
  175. }
  176. v[i__ + i__ * v_dim1] = vii;
  177. /* T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i) */
  178. i__2 = i__ - 1;
  179. dtrmv_("Upper", "No transpose", "Non-unit", &i__2, &t[
  180. t_offset], ldt, &t[i__ * t_dim1 + 1], &c__1);
  181. t[i__ + i__ * t_dim1] = tau[i__];
  182. if (i__ > 1) {
  183. prevlastv = max(prevlastv,lastv);
  184. } else {
  185. prevlastv = lastv;
  186. }
  187. }
  188. /* L20: */
  189. }
  190. } else {
  191. prevlastv = 1;
  192. for (i__ = *k; i__ >= 1; --i__) {
  193. if (tau[i__] == 0.) {
  194. /* H(i) = I */
  195. i__1 = *k;
  196. for (j = i__; j <= i__1; ++j) {
  197. t[j + i__ * t_dim1] = 0.;
  198. /* L30: */
  199. }
  200. } else {
  201. /* general case */
  202. if (i__ < *k) {
  203. if (lsame_(storev, "C")) {
  204. vii = v[*n - *k + i__ + i__ * v_dim1];
  205. v[*n - *k + i__ + i__ * v_dim1] = 1.;
  206. /* Skip any leading zeros. */
  207. i__1 = i__ - 1;
  208. for (lastv = 1; lastv <= i__1; ++lastv) {
  209. if (v[lastv + i__ * v_dim1] != 0.) {
  210. break;
  211. }
  212. }
  213. j = max(lastv,prevlastv);
  214. /* T(i+1:k,i) := */
  215. /* - tau(i) * V(j:n-k+i,i+1:k)' * V(j:n-k+i,i) */
  216. i__1 = *n - *k + i__ - j + 1;
  217. i__2 = *k - i__;
  218. d__1 = -tau[i__];
  219. dgemv_("Transpose", &i__1, &i__2, &d__1, &v[j + (i__
  220. + 1) * v_dim1], ldv, &v[j + i__ * v_dim1], &
  221. c__1, &c_b8, &t[i__ + 1 + i__ * t_dim1], &
  222. c__1);
  223. v[*n - *k + i__ + i__ * v_dim1] = vii;
  224. } else {
  225. vii = v[i__ + (*n - *k + i__) * v_dim1];
  226. v[i__ + (*n - *k + i__) * v_dim1] = 1.;
  227. /* Skip any leading zeros. */
  228. i__1 = i__ - 1;
  229. for (lastv = 1; lastv <= i__1; ++lastv) {
  230. if (v[i__ + lastv * v_dim1] != 0.) {
  231. break;
  232. }
  233. }
  234. j = max(lastv,prevlastv);
  235. /* T(i+1:k,i) := */
  236. /* - tau(i) * V(i+1:k,j:n-k+i) * V(i,j:n-k+i)' */
  237. i__1 = *k - i__;
  238. i__2 = *n - *k + i__ - j + 1;
  239. d__1 = -tau[i__];
  240. dgemv_("No transpose", &i__1, &i__2, &d__1, &v[i__ +
  241. 1 + j * v_dim1], ldv, &v[i__ + j * v_dim1],
  242. ldv, &c_b8, &t[i__ + 1 + i__ * t_dim1], &c__1);
  243. v[i__ + (*n - *k + i__) * v_dim1] = vii;
  244. }
  245. /* T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i) */
  246. i__1 = *k - i__;
  247. dtrmv_("Lower", "No transpose", "Non-unit", &i__1, &t[i__
  248. + 1 + (i__ + 1) * t_dim1], ldt, &t[i__ + 1 + i__ *
  249. t_dim1], &c__1)
  250. ;
  251. if (i__ > 1) {
  252. prevlastv = min(prevlastv,lastv);
  253. } else {
  254. prevlastv = lastv;
  255. }
  256. }
  257. t[i__ + i__ * t_dim1] = tau[i__];
  258. }
  259. /* L40: */
  260. }
  261. }
  262. return 0;
  263. /* End of DLARFT */
  264. } /* dlarft_ */