You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

clarft.f 19 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. *> \brief \b CLARFT forms the triangular factor T of a block reflector H = I - vtvH
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download CLARFT + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clarft.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clarft.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clarft.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * RECURSIVE SUBROUTINE CLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
  22. *
  23. * .. Scalar Arguments ..
  24. * CHARACTER DIRECT, STOREV
  25. * INTEGER K, LDT, LDV, N
  26. * ..
  27. * .. Array Arguments ..
  28. * COMPLEX T( LDT, * ), TAU( * ), V( LDV, * )
  29. * ..
  30. *
  31. *
  32. *> \par Purpose:
  33. * =============
  34. *>
  35. *> \verbatim
  36. *>
  37. *> CLARFT forms the triangular factor T of a complex block reflector H
  38. *> of order n, which is defined as a product of k elementary reflectors.
  39. *>
  40. *> If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
  41. *>
  42. *> If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
  43. *>
  44. *> If STOREV = 'C', the vector which defines the elementary reflector
  45. *> H(i) is stored in the i-th column of the array V, and
  46. *>
  47. *> H = I - V * T * V**H
  48. *>
  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. *>
  52. *> H = I - V**H * T * V
  53. *> \endverbatim
  54. *
  55. * Arguments:
  56. * ==========
  57. *
  58. *> \param[in] DIRECT
  59. *> \verbatim
  60. *> DIRECT is CHARACTER*1
  61. *> Specifies the order in which the elementary reflectors are
  62. *> multiplied to form the block reflector:
  63. *> = 'F': H = H(1) H(2) . . . H(k) (Forward)
  64. *> = 'B': H = H(k) . . . H(2) H(1) (Backward)
  65. *> \endverbatim
  66. *>
  67. *> \param[in] STOREV
  68. *> \verbatim
  69. *> STOREV is CHARACTER*1
  70. *> Specifies how the vectors which define the elementary
  71. *> reflectors are stored (see also Further Details):
  72. *> = 'C': columnwise
  73. *> = 'R': rowwise
  74. *> \endverbatim
  75. *>
  76. *> \param[in] N
  77. *> \verbatim
  78. *> N is INTEGER
  79. *> The order of the block reflector H. N >= 0.
  80. *> \endverbatim
  81. *>
  82. *> \param[in] K
  83. *> \verbatim
  84. *> K is INTEGER
  85. *> The order of the triangular factor T (= the number of
  86. *> elementary reflectors). K >= 1.
  87. *> \endverbatim
  88. *>
  89. *> \param[in] V
  90. *> \verbatim
  91. *> V is COMPLEX array, dimension
  92. *> (LDV,K) if STOREV = 'C'
  93. *> (LDV,N) if STOREV = 'R'
  94. *> The matrix V. See further details.
  95. *> \endverbatim
  96. *>
  97. *> \param[in] LDV
  98. *> \verbatim
  99. *> LDV is INTEGER
  100. *> The leading dimension of the array V.
  101. *> If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
  102. *> \endverbatim
  103. *>
  104. *> \param[in] TAU
  105. *> \verbatim
  106. *> TAU is COMPLEX array, dimension (K)
  107. *> TAU(i) must contain the scalar factor of the elementary
  108. *> reflector H(i).
  109. *> \endverbatim
  110. *>
  111. *> \param[out] T
  112. *> \verbatim
  113. *> T is COMPLEX array, dimension (LDT,K)
  114. *> The k by k triangular factor T of the block reflector.
  115. *> If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
  116. *> lower triangular. The rest of the array is not used.
  117. *> \endverbatim
  118. *>
  119. *> \param[in] LDT
  120. *> \verbatim
  121. *> LDT is INTEGER
  122. *> The leading dimension of the array T. LDT >= K.
  123. *> \endverbatim
  124. *
  125. * Authors:
  126. * ========
  127. *
  128. *> \author Univ. of Tennessee
  129. *> \author Univ. of California Berkeley
  130. *> \author Univ. of Colorado Denver
  131. *> \author NAG Ltd.
  132. *
  133. *> \ingroup larft
  134. *
  135. *> \par Further Details:
  136. * =====================
  137. *>
  138. *> \verbatim
  139. *>
  140. *> The shape of the matrix V and the storage of the vectors which define
  141. *> the H(i) is best illustrated by the following example with n = 5 and
  142. *> k = 3. The elements equal to 1 are not stored.
  143. *>
  144. *> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':
  145. *>
  146. *> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )
  147. *> ( v1 1 ) ( 1 v2 v2 v2 )
  148. *> ( v1 v2 1 ) ( 1 v3 v3 )
  149. *> ( v1 v2 v3 )
  150. *> ( v1 v2 v3 )
  151. *>
  152. *> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':
  153. *>
  154. *> V = ( v1 v2 v3 ) V = ( v1 v1 1 )
  155. *> ( v1 v2 v3 ) ( v2 v2 v2 1 )
  156. *> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )
  157. *> ( 1 v3 )
  158. *> ( 1 )
  159. *> \endverbatim
  160. *>
  161. * =====================================================================
  162. RECURSIVE SUBROUTINE CLARFT( DIRECT, STOREV, N, K, V, LDV,
  163. $ TAU, T, LDT )
  164. *
  165. * -- LAPACK auxiliary routine --
  166. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  167. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  168. *
  169. * .. Scalar Arguments
  170. *
  171. CHARACTER DIRECT, STOREV
  172. INTEGER K, LDT, LDV, N
  173. * ..
  174. * .. Array Arguments ..
  175. *
  176. COMPLEX T( LDT, * ), TAU( * ), V( LDV, * )
  177. * ..
  178. *
  179. * .. Parameters ..
  180. *
  181. COMPLEX ONE, NEG_ONE, ZERO
  182. PARAMETER(ONE=1.0E+0, ZERO = 0.0E+0, NEG_ONE=-1.0E+0)
  183. *
  184. * .. Local Scalars ..
  185. *
  186. INTEGER I,J,L
  187. LOGICAL QR,LQ,QL,DIRF,COLV
  188. *
  189. * .. External Subroutines ..
  190. *
  191. EXTERNAL CTRMM,CGEMM,CLACPY
  192. *
  193. * .. External Functions..
  194. *
  195. LOGICAL LSAME
  196. EXTERNAL LSAME
  197. *
  198. * .. Intrinsic Functions..
  199. *
  200. INTRINSIC CONJG
  201. *
  202. * The general scheme used is inspired by the approach inside DGEQRT3
  203. * which was (at the time of writing this code):
  204. * Based on the algorithm of Elmroth and Gustavson,
  205. * IBM J. Res. Develop. Vol 44 No. 4 July 2000.
  206. * ..
  207. * .. Executable Statements ..
  208. *
  209. * Quick return if possible
  210. *
  211. IF(N.EQ.0.OR.K.EQ.0) THEN
  212. RETURN
  213. END IF
  214. *
  215. * Base case
  216. *
  217. IF(N.EQ.1.OR.K.EQ.1) THEN
  218. T(1,1) = TAU(1)
  219. RETURN
  220. END IF
  221. *
  222. * Beginning of executable statements
  223. *
  224. L = K / 2
  225. *
  226. * Determine what kind of Q we need to compute
  227. * We assume that if the user doesn't provide 'F' for DIRECT,
  228. * then they meant to provide 'B' and if they don't provide
  229. * 'C' for STOREV, then they meant to provide 'R'
  230. *
  231. DIRF = LSAME(DIRECT,'F')
  232. COLV = LSAME(STOREV,'C')
  233. *
  234. * QR happens when we have forward direction in column storage
  235. *
  236. QR = DIRF.AND.COLV
  237. *
  238. * LQ happens when we have forward direction in row storage
  239. *
  240. LQ = DIRF.AND.(.NOT.COLV)
  241. *
  242. * QL happens when we have backward direction in column storage
  243. *
  244. QL = (.NOT.DIRF).AND.COLV
  245. *
  246. * The last case is RQ. Due to how we structured this, if the
  247. * above 3 are false, then RQ must be true, so we never store
  248. * this
  249. * RQ happens when we have backward direction in row storage
  250. * RQ = (.NOT.DIRF).AND.(.NOT.COLV)
  251. *
  252. IF(QR) THEN
  253. *
  254. * Break V apart into 6 components
  255. *
  256. * V = |---------------|
  257. * |V_{1,1} 0 |
  258. * |V_{2,1} V_{2,2}|
  259. * |V_{3,1} V_{3,2}|
  260. * |---------------|
  261. *
  262. * V_{1,1}\in\C^{l,l} unit lower triangular
  263. * V_{2,1}\in\C^{k-l,l} rectangular
  264. * V_{3,1}\in\C^{n-k,l} rectangular
  265. *
  266. * V_{2,2}\in\C^{k-l,k-l} unit lower triangular
  267. * V_{3,2}\in\C^{n-k,k-l} rectangular
  268. *
  269. * We will construct the T matrix
  270. * T = |---------------|
  271. * |T_{1,1} T_{1,2}|
  272. * |0 T_{2,2}|
  273. * |---------------|
  274. *
  275. * T is the triangular factor obtained from block reflectors.
  276. * To motivate the structure, assume we have already computed T_{1,1}
  277. * and T_{2,2}. Then collect the associated reflectors in V_1 and V_2
  278. *
  279. * T_{1,1}\in\C^{l, l} upper triangular
  280. * T_{2,2}\in\C^{k-l, k-l} upper triangular
  281. * T_{1,2}\in\C^{l, k-l} rectangular
  282. *
  283. * Where l = floor(k/2)
  284. *
  285. * Then, consider the product:
  286. *
  287. * (I - V_1*T_{1,1}*V_1')*(I - V_2*T_{2,2}*V_2')
  288. * = I - V_1*T_{1,1}*V_1' - V_2*T_{2,2}*V_2' + V_1*T_{1,1}*V_1'*V_2*T_{2,2}*V_2'
  289. *
  290. * Define T{1,2} = -T_{1,1}*V_1'*V_2*T_{2,2}
  291. *
  292. * Then, we can define the matrix V as
  293. * V = |-------|
  294. * |V_1 V_2|
  295. * |-------|
  296. *
  297. * So, our product is equivalent to the matrix product
  298. * I - V*T*V'
  299. * This means, we can compute T_{1,1} and T_{2,2}, then use this information
  300. * to compute T_{1,2}
  301. *
  302. * Compute T_{1,1} recursively
  303. *
  304. CALL CLARFT(DIRECT, STOREV, N, L, V, LDV, TAU, T, LDT)
  305. *
  306. * Compute T_{2,2} recursively
  307. *
  308. CALL CLARFT(DIRECT, STOREV, N-L, K-L, V(L+1, L+1), LDV,
  309. $ TAU(L+1), T(L+1, L+1), LDT)
  310. *
  311. * Compute T_{1,2}
  312. * T_{1,2} = V_{2,1}'
  313. *
  314. DO J = 1, L
  315. DO I = 1, K-L
  316. T(J, L+I) = CONJG(V(L+I, J))
  317. END DO
  318. END DO
  319. *
  320. * T_{1,2} = T_{1,2}*V_{2,2}
  321. *
  322. CALL CTRMM('Right', 'Lower', 'No transpose', 'Unit', L,
  323. $ K-L, ONE, V(L+1, L+1), LDV, T(1, L+1), LDT)
  324. *
  325. * T_{1,2} = V_{3,1}'*V_{3,2} + T_{1,2}
  326. * Note: We assume K <= N, and GEMM will do nothing if N=K
  327. *
  328. CALL CGEMM('Conjugate', 'No transpose', L, K-L, N-K, ONE,
  329. $ V(K+1, 1), LDV, V(K+1, L+1), LDV, ONE, T(1, L+1),
  330. $ LDT)
  331. *
  332. * At this point, we have that T_{1,2} = V_1'*V_2
  333. * All that is left is to pre and post multiply by -T_{1,1} and T_{2,2}
  334. * respectively.
  335. *
  336. * T_{1,2} = -T_{1,1}*T_{1,2}
  337. *
  338. CALL CTRMM('Left', 'Upper', 'No transpose', 'Non-unit', L,
  339. $ K-L, NEG_ONE, T, LDT, T(1, L+1), LDT)
  340. *
  341. * T_{1,2} = T_{1,2}*T_{2,2}
  342. *
  343. CALL CTRMM('Right', 'Upper', 'No transpose', 'Non-unit', L,
  344. $ K-L, ONE, T(L+1, L+1), LDT, T(1, L+1), LDT)
  345. ELSE IF(LQ) THEN
  346. *
  347. * Break V apart into 6 components
  348. *
  349. * V = |----------------------|
  350. * |V_{1,1} V_{1,2} V{1,3}|
  351. * |0 V_{2,2} V{2,3}|
  352. * |----------------------|
  353. *
  354. * V_{1,1}\in\C^{l,l} unit upper triangular
  355. * V_{1,2}\in\C^{l,k-l} rectangular
  356. * V_{1,3}\in\C^{l,n-k} rectangular
  357. *
  358. * V_{2,2}\in\C^{k-l,k-l} unit upper triangular
  359. * V_{2,3}\in\C^{k-l,n-k} rectangular
  360. *
  361. * Where l = floor(k/2)
  362. *
  363. * We will construct the T matrix
  364. * T = |---------------|
  365. * |T_{1,1} T_{1,2}|
  366. * |0 T_{2,2}|
  367. * |---------------|
  368. *
  369. * T is the triangular factor obtained from block reflectors.
  370. * To motivate the structure, assume we have already computed T_{1,1}
  371. * and T_{2,2}. Then collect the associated reflectors in V_1 and V_2
  372. *
  373. * T_{1,1}\in\C^{l, l} upper triangular
  374. * T_{2,2}\in\C^{k-l, k-l} upper triangular
  375. * T_{1,2}\in\C^{l, k-l} rectangular
  376. *
  377. * Then, consider the product:
  378. *
  379. * (I - V_1'*T_{1,1}*V_1)*(I - V_2'*T_{2,2}*V_2)
  380. * = I - V_1'*T_{1,1}*V_1 - V_2'*T_{2,2}*V_2 + V_1'*T_{1,1}*V_1*V_2'*T_{2,2}*V_2
  381. *
  382. * Define T_{1,2} = -T_{1,1}*V_1*V_2'*T_{2,2}
  383. *
  384. * Then, we can define the matrix V as
  385. * V = |---|
  386. * |V_1|
  387. * |V_2|
  388. * |---|
  389. *
  390. * So, our product is equivalent to the matrix product
  391. * I - V'*T*V
  392. * This means, we can compute T_{1,1} and T_{2,2}, then use this information
  393. * to compute T_{1,2}
  394. *
  395. * Compute T_{1,1} recursively
  396. *
  397. CALL CLARFT(DIRECT, STOREV, N, L, V, LDV, TAU, T, LDT)
  398. *
  399. * Compute T_{2,2} recursively
  400. *
  401. CALL CLARFT(DIRECT, STOREV, N-L, K-L, V(L+1, L+1), LDV,
  402. $ TAU(L+1), T(L+1, L+1), LDT)
  403. *
  404. * Compute T_{1,2}
  405. * T_{1,2} = V_{1,2}
  406. *
  407. CALL CLACPY('All', L, K-L, V(1, L+1), LDV, T(1, L+1), LDT)
  408. *
  409. * T_{1,2} = T_{1,2}*V_{2,2}'
  410. *
  411. CALL CTRMM('Right', 'Upper', 'Conjugate', 'Unit', L, K-L,
  412. $ ONE, V(L+1, L+1), LDV, T(1, L+1), LDT)
  413. *
  414. * T_{1,2} = V_{1,3}*V_{2,3}' + T_{1,2}
  415. * Note: We assume K <= N, and GEMM will do nothing if N=K
  416. *
  417. CALL CGEMM('No transpose', 'Conjugate', L, K-L, N-K, ONE,
  418. $ V(1, K+1), LDV, V(L+1, K+1), LDV, ONE, T(1, L+1), LDT)
  419. *
  420. * At this point, we have that T_{1,2} = V_1*V_2'
  421. * All that is left is to pre and post multiply by -T_{1,1} and T_{2,2}
  422. * respectively.
  423. *
  424. * T_{1,2} = -T_{1,1}*T_{1,2}
  425. *
  426. CALL CTRMM('Left', 'Upper', 'No transpose', 'Non-unit', L,
  427. $ K-L, NEG_ONE, T, LDT, T(1, L+1), LDT)
  428. *
  429. * T_{1,2} = T_{1,2}*T_{2,2}
  430. *
  431. CALL CTRMM('Right', 'Upper', 'No transpose', 'Non-unit', L,
  432. $ K-L, ONE, T(L+1,L+1), LDT, T(1, L+1), LDT)
  433. ELSE IF(QL) THEN
  434. *
  435. * Break V apart into 6 components
  436. *
  437. * V = |---------------|
  438. * |V_{1,1} V_{1,2}|
  439. * |V_{2,1} V_{2,2}|
  440. * |0 V_{3,2}|
  441. * |---------------|
  442. *
  443. * V_{1,1}\in\C^{n-k,k-l} rectangular
  444. * V_{2,1}\in\C^{k-l,k-l} unit upper triangular
  445. *
  446. * V_{1,2}\in\C^{n-k,l} rectangular
  447. * V_{2,2}\in\C^{k-l,l} rectangular
  448. * V_{3,2}\in\C^{l,l} unit upper triangular
  449. *
  450. * We will construct the T matrix
  451. * T = |---------------|
  452. * |T_{1,1} 0 |
  453. * |T_{2,1} T_{2,2}|
  454. * |---------------|
  455. *
  456. * T is the triangular factor obtained from block reflectors.
  457. * To motivate the structure, assume we have already computed T_{1,1}
  458. * and T_{2,2}. Then collect the associated reflectors in V_1 and V_2
  459. *
  460. * T_{1,1}\in\C^{k-l, k-l} non-unit lower triangular
  461. * T_{2,2}\in\C^{l, l} non-unit lower triangular
  462. * T_{2,1}\in\C^{k-l, l} rectangular
  463. *
  464. * Where l = floor(k/2)
  465. *
  466. * Then, consider the product:
  467. *
  468. * (I - V_2*T_{2,2}*V_2')*(I - V_1*T_{1,1}*V_1')
  469. * = I - V_2*T_{2,2}*V_2' - V_1*T_{1,1}*V_1' + V_2*T_{2,2}*V_2'*V_1*T_{1,1}*V_1'
  470. *
  471. * Define T_{2,1} = -T_{2,2}*V_2'*V_1*T_{1,1}
  472. *
  473. * Then, we can define the matrix V as
  474. * V = |-------|
  475. * |V_1 V_2|
  476. * |-------|
  477. *
  478. * So, our product is equivalent to the matrix product
  479. * I - V*T*V'
  480. * This means, we can compute T_{1,1} and T_{2,2}, then use this information
  481. * to compute T_{2,1}
  482. *
  483. * Compute T_{1,1} recursively
  484. *
  485. CALL CLARFT(DIRECT, STOREV, N-L, K-L, V, LDV, TAU, T, LDT)
  486. *
  487. * Compute T_{2,2} recursively
  488. *
  489. CALL CLARFT(DIRECT, STOREV, N, L, V(1, K-L+1), LDV,
  490. $ TAU(K-L+1), T(K-L+1, K-L+1), LDT)
  491. *
  492. * Compute T_{2,1}
  493. * T_{2,1} = V_{2,2}'
  494. *
  495. DO J = 1, K-L
  496. DO I = 1, L
  497. T(K-L+I, J) = CONJG(V(N-K+J, K-L+I))
  498. END DO
  499. END DO
  500. *
  501. * T_{2,1} = T_{2,1}*V_{2,1}
  502. *
  503. CALL CTRMM('Right', 'Upper', 'No transpose', 'Unit', L,
  504. $ K-L, ONE, V(N-K+1, 1), LDV, T(K-L+1, 1), LDT)
  505. *
  506. * T_{2,1} = V_{2,2}'*V_{2,1} + T_{2,1}
  507. * Note: We assume K <= N, and GEMM will do nothing if N=K
  508. *
  509. CALL CGEMM('Conjugate', 'No transpose', L, K-L, N-K, ONE,
  510. $ V(1, K-L+1), LDV, V, LDV, ONE, T(K-L+1, 1),
  511. $ LDT)
  512. *
  513. * At this point, we have that T_{2,1} = V_2'*V_1
  514. * All that is left is to pre and post multiply by -T_{2,2} and T_{1,1}
  515. * respectively.
  516. *
  517. * T_{2,1} = -T_{2,2}*T_{2,1}
  518. *
  519. CALL CTRMM('Left', 'Lower', 'No transpose', 'Non-unit', L,
  520. $ K-L, NEG_ONE, T(K-L+1, K-L+1), LDT,
  521. $ T(K-L+1, 1), LDT)
  522. *
  523. * T_{2,1} = T_{2,1}*T_{1,1}
  524. *
  525. CALL CTRMM('Right', 'Lower', 'No transpose', 'Non-unit', L,
  526. $ K-L, ONE, T, LDT, T(K-L+1, 1), LDT)
  527. ELSE
  528. *
  529. * Else means RQ case
  530. *
  531. * Break V apart into 6 components
  532. *
  533. * V = |-----------------------|
  534. * |V_{1,1} V_{1,2} 0 |
  535. * |V_{2,1} V_{2,2} V_{2,3}|
  536. * |-----------------------|
  537. *
  538. * V_{1,1}\in\C^{k-l,n-k} rectangular
  539. * V_{1,2}\in\C^{k-l,k-l} unit lower triangular
  540. *
  541. * V_{2,1}\in\C^{l,n-k} rectangular
  542. * V_{2,2}\in\C^{l,k-l} rectangular
  543. * V_{2,3}\in\C^{l,l} unit lower triangular
  544. *
  545. * We will construct the T matrix
  546. * T = |---------------|
  547. * |T_{1,1} 0 |
  548. * |T_{2,1} T_{2,2}|
  549. * |---------------|
  550. *
  551. * T is the triangular factor obtained from block reflectors.
  552. * To motivate the structure, assume we have already computed T_{1,1}
  553. * and T_{2,2}. Then collect the associated reflectors in V_1 and V_2
  554. *
  555. * T_{1,1}\in\C^{k-l, k-l} non-unit lower triangular
  556. * T_{2,2}\in\C^{l, l} non-unit lower triangular
  557. * T_{2,1}\in\C^{k-l, l} rectangular
  558. *
  559. * Where l = floor(k/2)
  560. *
  561. * Then, consider the product:
  562. *
  563. * (I - V_2'*T_{2,2}*V_2)*(I - V_1'*T_{1,1}*V_1)
  564. * = I - V_2'*T_{2,2}*V_2 - V_1'*T_{1,1}*V_1 + V_2'*T_{2,2}*V_2*V_1'*T_{1,1}*V_1
  565. *
  566. * Define T_{2,1} = -T_{2,2}*V_2*V_1'*T_{1,1}
  567. *
  568. * Then, we can define the matrix V as
  569. * V = |---|
  570. * |V_1|
  571. * |V_2|
  572. * |---|
  573. *
  574. * So, our product is equivalent to the matrix product
  575. * I - V'*T*V
  576. * This means, we can compute T_{1,1} and T_{2,2}, then use this information
  577. * to compute T_{2,1}
  578. *
  579. * Compute T_{1,1} recursively
  580. *
  581. CALL CLARFT(DIRECT, STOREV, N-L, K-L, V, LDV, TAU, T, LDT)
  582. *
  583. * Compute T_{2,2} recursively
  584. *
  585. CALL CLARFT(DIRECT, STOREV, N, L, V(K-L+1,1), LDV,
  586. $ TAU(K-L+1), T(K-L+1, K-L+1), LDT)
  587. *
  588. * Compute T_{2,1}
  589. * T_{2,1} = V_{2,2}
  590. *
  591. CALL CLACPY('All', L, K-L, V(K-L+1, N-K+1), LDV,
  592. $ T(K-L+1, 1), LDT)
  593. *
  594. * T_{2,1} = T_{2,1}*V_{1,2}'
  595. *
  596. CALL CTRMM('Right', 'Lower', 'Conjugate', 'Unit', L, K-L,
  597. $ ONE, V(1, N-K+1), LDV, T(K-L+1,1), LDT)
  598. *
  599. * T_{2,1} = V_{2,1}*V_{1,1}' + T_{2,1}
  600. * Note: We assume K <= N, and GEMM will do nothing if N=K
  601. *
  602. CALL CGEMM('No transpose', 'Conjugate', L, K-L, N-K, ONE,
  603. $ V(K-L+1, 1), LDV, V, LDV, ONE, T(K-L+1, 1),
  604. $ LDT)
  605. *
  606. * At this point, we have that T_{2,1} = V_2*V_1'
  607. * All that is left is to pre and post multiply by -T_{2,2} and T_{1,1}
  608. * respectively.
  609. *
  610. * T_{2,1} = -T_{2,2}*T_{2,1}
  611. *
  612. CALL CTRMM('Left', 'Lower', 'No tranpose', 'Non-unit', L,
  613. $ K-L, NEG_ONE, T(K-L+1, K-L+1), LDT,
  614. $ T(K-L+1, 1), LDT)
  615. *
  616. * T_{2,1} = T_{2,1}*T_{1,1}
  617. *
  618. CALL CTRMM('Right', 'Lower', 'No tranpose', 'Non-unit', L,
  619. $ K-L, ONE, T, LDT, T(K-L+1, 1), LDT)
  620. END IF
  621. END SUBROUTINE