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.

ccsdts.f 18 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. *> \brief \b CCSDTS
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. * Definition:
  9. * ===========
  10. *
  11. * SUBROUTINE CCSDTS( M, P, Q, X, XF, LDX, U1, LDU1, U2, LDU2, V1T,
  12. * LDV1T, V2T, LDV2T, THETA, IWORK, WORK, LWORK,
  13. * RWORK, RESULT )
  14. *
  15. * .. Scalar Arguments ..
  16. * INTEGER LDX, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q
  17. * ..
  18. * .. Array Arguments ..
  19. * INTEGER IWORK( * )
  20. * REAL RESULT( 15 ), RWORK( * ), THETA( * )
  21. * COMPLEX U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
  22. * $ V2T( LDV2T, * ), WORK( LWORK ), X( LDX, * ),
  23. * $ XF( LDX, * )
  24. * ..
  25. *
  26. *
  27. *> \par Purpose:
  28. * =============
  29. *>
  30. *> \verbatim
  31. *>
  32. *> CCSDTS tests CUNCSD, which, given an M-by-M partitioned unitary
  33. *> matrix X,
  34. *> Q M-Q
  35. *> X = [ X11 X12 ] P ,
  36. *> [ X21 X22 ] M-P
  37. *>
  38. *> computes the CSD
  39. *>
  40. *> [ U1 ]**T * [ X11 X12 ] * [ V1 ]
  41. *> [ U2 ] [ X21 X22 ] [ V2 ]
  42. *>
  43. *> [ I 0 0 | 0 0 0 ]
  44. *> [ 0 C 0 | 0 -S 0 ]
  45. *> [ 0 0 0 | 0 0 -I ]
  46. *> = [---------------------] = [ D11 D12 ] .
  47. *> [ 0 0 0 | I 0 0 ] [ D21 D22 ]
  48. *> [ 0 S 0 | 0 C 0 ]
  49. *> [ 0 0 I | 0 0 0 ]
  50. *>
  51. *> and also SORCSD2BY1, which, given
  52. *> Q
  53. *> [ X11 ] P ,
  54. *> [ X21 ] M-P
  55. *>
  56. *> computes the 2-by-1 CSD
  57. *>
  58. *> [ I 0 0 ]
  59. *> [ 0 C 0 ]
  60. *> [ 0 0 0 ]
  61. *> [ U1 ]**T * [ X11 ] * V1 = [----------] = [ D11 ] ,
  62. *> [ U2 ] [ X21 ] [ 0 0 0 ] [ D21 ]
  63. *> [ 0 S 0 ]
  64. *> [ 0 0 I ]
  65. *> \endverbatim
  66. *
  67. * Arguments:
  68. * ==========
  69. *
  70. *> \param[in] M
  71. *> \verbatim
  72. *> M is INTEGER
  73. *> The number of rows of the matrix X. M >= 0.
  74. *> \endverbatim
  75. *>
  76. *> \param[in] P
  77. *> \verbatim
  78. *> P is INTEGER
  79. *> The number of rows of the matrix X11. P >= 0.
  80. *> \endverbatim
  81. *>
  82. *> \param[in] Q
  83. *> \verbatim
  84. *> Q is INTEGER
  85. *> The number of columns of the matrix X11. Q >= 0.
  86. *> \endverbatim
  87. *>
  88. *> \param[in] X
  89. *> \verbatim
  90. *> X is COMPLEX array, dimension (LDX,M)
  91. *> The M-by-M matrix X.
  92. *> \endverbatim
  93. *>
  94. *> \param[out] XF
  95. *> \verbatim
  96. *> XF is COMPLEX array, dimension (LDX,M)
  97. *> Details of the CSD of X, as returned by CUNCSD;
  98. *> see CUNCSD for further details.
  99. *> \endverbatim
  100. *>
  101. *> \param[in] LDX
  102. *> \verbatim
  103. *> LDX is INTEGER
  104. *> The leading dimension of the arrays X and XF.
  105. *> LDX >= max( 1,M ).
  106. *> \endverbatim
  107. *>
  108. *> \param[out] U1
  109. *> \verbatim
  110. *> U1 is COMPLEX array, dimension(LDU1,P)
  111. *> The P-by-P unitary matrix U1.
  112. *> \endverbatim
  113. *>
  114. *> \param[in] LDU1
  115. *> \verbatim
  116. *> LDU1 is INTEGER
  117. *> The leading dimension of the array U1. LDU >= max(1,P).
  118. *> \endverbatim
  119. *>
  120. *> \param[out] U2
  121. *> \verbatim
  122. *> U2 is COMPLEX array, dimension(LDU2,M-P)
  123. *> The (M-P)-by-(M-P) unitary matrix U2.
  124. *> \endverbatim
  125. *>
  126. *> \param[in] LDU2
  127. *> \verbatim
  128. *> LDU2 is INTEGER
  129. *> The leading dimension of the array U2. LDU >= max(1,M-P).
  130. *> \endverbatim
  131. *>
  132. *> \param[out] V1T
  133. *> \verbatim
  134. *> V1T is COMPLEX array, dimension(LDV1T,Q)
  135. *> The Q-by-Q unitary matrix V1T.
  136. *> \endverbatim
  137. *>
  138. *> \param[in] LDV1T
  139. *> \verbatim
  140. *> LDV1T is INTEGER
  141. *> The leading dimension of the array V1T. LDV1T >=
  142. *> max(1,Q).
  143. *> \endverbatim
  144. *>
  145. *> \param[out] V2T
  146. *> \verbatim
  147. *> V2T is COMPLEX array, dimension(LDV2T,M-Q)
  148. *> The (M-Q)-by-(M-Q) unitary matrix V2T.
  149. *> \endverbatim
  150. *>
  151. *> \param[in] LDV2T
  152. *> \verbatim
  153. *> LDV2T is INTEGER
  154. *> The leading dimension of the array V2T. LDV2T >=
  155. *> max(1,M-Q).
  156. *> \endverbatim
  157. *>
  158. *> \param[out] THETA
  159. *> \verbatim
  160. *> THETA is REAL array, dimension MIN(P,M-P,Q,M-Q)
  161. *> The CS values of X; the essentially diagonal matrices C and
  162. *> S are constructed from THETA; see subroutine CUNCSD for
  163. *> details.
  164. *> \endverbatim
  165. *>
  166. *> \param[out] IWORK
  167. *> \verbatim
  168. *> IWORK is INTEGER array, dimension (M)
  169. *> \endverbatim
  170. *>
  171. *> \param[out] WORK
  172. *> \verbatim
  173. *> WORK is COMPLEX array, dimension (LWORK)
  174. *> \endverbatim
  175. *>
  176. *> \param[in] LWORK
  177. *> \verbatim
  178. *> LWORK is INTEGER
  179. *> The dimension of the array WORK
  180. *> \endverbatim
  181. *>
  182. *> \param[out] RWORK
  183. *> \verbatim
  184. *> RWORK is REAL array
  185. *> \endverbatim
  186. *>
  187. *> \param[out] RESULT
  188. *> \verbatim
  189. *> RESULT is REAL array, dimension (15)
  190. *> The test ratios:
  191. *> First, the 2-by-2 CSD:
  192. *> RESULT(1) = norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 )
  193. *> RESULT(2) = norm( U1'*X12*V2 - D12 ) / ( MAX(1,P,M-Q)*EPS2 )
  194. *> RESULT(3) = norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 )
  195. *> RESULT(4) = norm( U2'*X22*V2 - D22 ) / ( MAX(1,M-P,M-Q)*EPS2 )
  196. *> RESULT(5) = norm( I - U1'*U1 ) / ( MAX(1,P)*ULP )
  197. *> RESULT(6) = norm( I - U2'*U2 ) / ( MAX(1,M-P)*ULP )
  198. *> RESULT(7) = norm( I - V1T'*V1T ) / ( MAX(1,Q)*ULP )
  199. *> RESULT(8) = norm( I - V2T'*V2T ) / ( MAX(1,M-Q)*ULP )
  200. *> RESULT(9) = 0 if THETA is in increasing order and
  201. *> all angles are in [0,pi/2];
  202. *> = ULPINV otherwise.
  203. *> Then, the 2-by-1 CSD:
  204. *> RESULT(10) = norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 )
  205. *> RESULT(11) = norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 )
  206. *> RESULT(12) = norm( I - U1'*U1 ) / ( MAX(1,P)*ULP )
  207. *> RESULT(13) = norm( I - U2'*U2 ) / ( MAX(1,M-P)*ULP )
  208. *> RESULT(14) = norm( I - V1T'*V1T ) / ( MAX(1,Q)*ULP )
  209. *> RESULT(15) = 0 if THETA is in increasing order and
  210. *> all angles are in [0,pi/2];
  211. *> = ULPINV otherwise.
  212. *> ( EPS2 = MAX( norm( I - X'*X ) / M, ULP ). )
  213. *> \endverbatim
  214. *
  215. * Authors:
  216. * ========
  217. *
  218. *> \author Univ. of Tennessee
  219. *> \author Univ. of California Berkeley
  220. *> \author Univ. of Colorado Denver
  221. *> \author NAG Ltd.
  222. *
  223. *> \ingroup complex_eig
  224. *
  225. * =====================================================================
  226. SUBROUTINE CCSDTS( M, P, Q, X, XF, LDX, U1, LDU1, U2, LDU2, V1T,
  227. $ LDV1T, V2T, LDV2T, THETA, IWORK, WORK, LWORK,
  228. $ RWORK, RESULT )
  229. *
  230. * -- LAPACK test routine --
  231. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  232. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  233. *
  234. * .. Scalar Arguments ..
  235. INTEGER LDX, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q
  236. * ..
  237. * .. Array Arguments ..
  238. INTEGER IWORK( * )
  239. REAL RESULT( 15 ), RWORK( * ), THETA( * )
  240. COMPLEX U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
  241. $ V2T( LDV2T, * ), WORK( LWORK ), X( LDX, * ),
  242. $ XF( LDX, * )
  243. * ..
  244. *
  245. * =====================================================================
  246. *
  247. * .. Parameters ..
  248. REAL REALONE, REALZERO
  249. PARAMETER ( REALONE = 1.0E0, REALZERO = 0.0E0 )
  250. COMPLEX ZERO, ONE
  251. PARAMETER ( ZERO = (0.0E0,0.0E0), ONE = (1.0E0,0.0E0) )
  252. REAL PIOVER2
  253. PARAMETER ( PIOVER2 = 1.57079632679489661923132169163975144210E0 )
  254. * ..
  255. * .. Local Scalars ..
  256. INTEGER I, INFO, R
  257. REAL EPS2, RESID, ULP, ULPINV
  258. * ..
  259. * .. External Functions ..
  260. REAL SLAMCH, CLANGE, CLANHE
  261. EXTERNAL SLAMCH, CLANGE, CLANHE
  262. * ..
  263. * .. External Subroutines ..
  264. EXTERNAL CGEMM, CHERK, CLACPY, CLASET, CUNCSD,
  265. $ CUNCSD2BY1
  266. * ..
  267. * .. Intrinsic Functions ..
  268. INTRINSIC CMPLX, COS, MAX, MIN, REAL, SIN
  269. * ..
  270. * .. Executable Statements ..
  271. *
  272. ULP = SLAMCH( 'Precision' )
  273. ULPINV = REALONE / ULP
  274. *
  275. * The first half of the routine checks the 2-by-2 CSD
  276. *
  277. CALL CLASET( 'Full', M, M, ZERO, ONE, WORK, LDX )
  278. CALL CHERK( 'Upper', 'Conjugate transpose', M, M, -REALONE,
  279. $ X, LDX, REALONE, WORK, LDX )
  280. IF (M.GT.0) THEN
  281. EPS2 = MAX( ULP,
  282. $ CLANGE( '1', M, M, WORK, LDX, RWORK ) / REAL( M ) )
  283. ELSE
  284. EPS2 = ULP
  285. END IF
  286. R = MIN( P, M-P, Q, M-Q )
  287. *
  288. * Copy the matrix X to the array XF.
  289. *
  290. CALL CLACPY( 'Full', M, M, X, LDX, XF, LDX )
  291. *
  292. * Compute the CSD
  293. *
  294. CALL CUNCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'D', M, P, Q, XF(1,1), LDX,
  295. $ XF(1,Q+1), LDX, XF(P+1,1), LDX, XF(P+1,Q+1), LDX,
  296. $ THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T,
  297. $ WORK, LWORK, RWORK, 17*(R+2), IWORK, INFO )
  298. *
  299. * Compute XF := diag(U1,U2)'*X*diag(V1,V2) - [D11 D12; D21 D22]
  300. *
  301. CALL CLACPY( 'Full', M, M, X, LDX, XF, LDX )
  302. *
  303. CALL CGEMM( 'No transpose', 'Conjugate transpose', P, Q, Q, ONE,
  304. $ XF, LDX, V1T, LDV1T, ZERO, WORK, LDX )
  305. *
  306. CALL CGEMM( 'Conjugate transpose', 'No transpose', P, Q, P, ONE,
  307. $ U1, LDU1, WORK, LDX, ZERO, XF, LDX )
  308. *
  309. DO I = 1, MIN(P,Q)-R
  310. XF(I,I) = XF(I,I) - ONE
  311. END DO
  312. DO I = 1, R
  313. XF(MIN(P,Q)-R+I,MIN(P,Q)-R+I) =
  314. $ XF(MIN(P,Q)-R+I,MIN(P,Q)-R+I) - CMPLX( COS(THETA(I)),
  315. $ 0.0E0 )
  316. END DO
  317. *
  318. CALL CGEMM( 'No transpose', 'Conjugate transpose', P, M-Q, M-Q,
  319. $ ONE, XF(1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX )
  320. *
  321. CALL CGEMM( 'Conjugate transpose', 'No transpose', P, M-Q, P,
  322. $ ONE, U1, LDU1, WORK, LDX, ZERO, XF(1,Q+1), LDX )
  323. *
  324. DO I = 1, MIN(P,M-Q)-R
  325. XF(P-I+1,M-I+1) = XF(P-I+1,M-I+1) + ONE
  326. END DO
  327. DO I = 1, R
  328. XF(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) =
  329. $ XF(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) +
  330. $ CMPLX( SIN(THETA(R-I+1)), 0.0E0 )
  331. END DO
  332. *
  333. CALL CGEMM( 'No transpose', 'Conjugate transpose', M-P, Q, Q, ONE,
  334. $ XF(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX )
  335. *
  336. CALL CGEMM( 'Conjugate transpose', 'No transpose', M-P, Q, M-P,
  337. $ ONE, U2, LDU2, WORK, LDX, ZERO, XF(P+1,1), LDX )
  338. *
  339. DO I = 1, MIN(M-P,Q)-R
  340. XF(M-I+1,Q-I+1) = XF(M-I+1,Q-I+1) - ONE
  341. END DO
  342. DO I = 1, R
  343. XF(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) =
  344. $ XF(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) -
  345. $ CMPLX( SIN(THETA(R-I+1)), 0.0E0 )
  346. END DO
  347. *
  348. CALL CGEMM( 'No transpose', 'Conjugate transpose', M-P, M-Q, M-Q,
  349. $ ONE, XF(P+1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX )
  350. *
  351. CALL CGEMM( 'Conjugate transpose', 'No transpose', M-P, M-Q, M-P,
  352. $ ONE, U2, LDU2, WORK, LDX, ZERO, XF(P+1,Q+1), LDX )
  353. *
  354. DO I = 1, MIN(M-P,M-Q)-R
  355. XF(P+I,Q+I) = XF(P+I,Q+I) - ONE
  356. END DO
  357. DO I = 1, R
  358. XF(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) =
  359. $ XF(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) -
  360. $ CMPLX( COS(THETA(I)), 0.0E0 )
  361. END DO
  362. *
  363. * Compute norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) .
  364. *
  365. RESID = CLANGE( '1', P, Q, XF, LDX, RWORK )
  366. RESULT( 1 ) = ( RESID / REAL(MAX(1,P,Q)) ) / EPS2
  367. *
  368. * Compute norm( U1'*X12*V2 - D12 ) / ( MAX(1,P,M-Q)*EPS2 ) .
  369. *
  370. RESID = CLANGE( '1', P, M-Q, XF(1,Q+1), LDX, RWORK )
  371. RESULT( 2 ) = ( RESID / REAL(MAX(1,P,M-Q)) ) / EPS2
  372. *
  373. * Compute norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 ) .
  374. *
  375. RESID = CLANGE( '1', M-P, Q, XF(P+1,1), LDX, RWORK )
  376. RESULT( 3 ) = ( RESID / REAL(MAX(1,M-P,Q)) ) / EPS2
  377. *
  378. * Compute norm( U2'*X22*V2 - D22 ) / ( MAX(1,M-P,M-Q)*EPS2 ) .
  379. *
  380. RESID = CLANGE( '1', M-P, M-Q, XF(P+1,Q+1), LDX, RWORK )
  381. RESULT( 4 ) = ( RESID / REAL(MAX(1,M-P,M-Q)) ) / EPS2
  382. *
  383. * Compute I - U1'*U1
  384. *
  385. CALL CLASET( 'Full', P, P, ZERO, ONE, WORK, LDU1 )
  386. CALL CHERK( 'Upper', 'Conjugate transpose', P, P, -REALONE,
  387. $ U1, LDU1, REALONE, WORK, LDU1 )
  388. *
  389. * Compute norm( I - U'*U ) / ( MAX(1,P) * ULP ) .
  390. *
  391. RESID = CLANHE( '1', 'Upper', P, WORK, LDU1, RWORK )
  392. RESULT( 5 ) = ( RESID / REAL(MAX(1,P)) ) / ULP
  393. *
  394. * Compute I - U2'*U2
  395. *
  396. CALL CLASET( 'Full', M-P, M-P, ZERO, ONE, WORK, LDU2 )
  397. CALL CHERK( 'Upper', 'Conjugate transpose', M-P, M-P, -REALONE,
  398. $ U2, LDU2, REALONE, WORK, LDU2 )
  399. *
  400. * Compute norm( I - U2'*U2 ) / ( MAX(1,M-P) * ULP ) .
  401. *
  402. RESID = CLANHE( '1', 'Upper', M-P, WORK, LDU2, RWORK )
  403. RESULT( 6 ) = ( RESID / REAL(MAX(1,M-P)) ) / ULP
  404. *
  405. * Compute I - V1T*V1T'
  406. *
  407. CALL CLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDV1T )
  408. CALL CHERK( 'Upper', 'No transpose', Q, Q, -REALONE,
  409. $ V1T, LDV1T, REALONE, WORK, LDV1T )
  410. *
  411. * Compute norm( I - V1T*V1T' ) / ( MAX(1,Q) * ULP ) .
  412. *
  413. RESID = CLANHE( '1', 'Upper', Q, WORK, LDV1T, RWORK )
  414. RESULT( 7 ) = ( RESID / REAL(MAX(1,Q)) ) / ULP
  415. *
  416. * Compute I - V2T*V2T'
  417. *
  418. CALL CLASET( 'Full', M-Q, M-Q, ZERO, ONE, WORK, LDV2T )
  419. CALL CHERK( 'Upper', 'No transpose', M-Q, M-Q, -REALONE,
  420. $ V2T, LDV2T, REALONE, WORK, LDV2T )
  421. *
  422. * Compute norm( I - V2T*V2T' ) / ( MAX(1,M-Q) * ULP ) .
  423. *
  424. RESID = CLANHE( '1', 'Upper', M-Q, WORK, LDV2T, RWORK )
  425. RESULT( 8 ) = ( RESID / REAL(MAX(1,M-Q)) ) / ULP
  426. *
  427. * Check sorting
  428. *
  429. RESULT( 9 ) = REALZERO
  430. DO I = 1, R
  431. IF( THETA(I).LT.REALZERO .OR. THETA(I).GT.PIOVER2 ) THEN
  432. RESULT( 9 ) = ULPINV
  433. END IF
  434. IF( I.GT.1) THEN
  435. IF ( THETA(I).LT.THETA(I-1) ) THEN
  436. RESULT( 9 ) = ULPINV
  437. END IF
  438. END IF
  439. END DO
  440. *
  441. * The second half of the routine checks the 2-by-1 CSD
  442. *
  443. CALL CLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDX )
  444. CALL CHERK( 'Upper', 'Conjugate transpose', Q, M, -REALONE,
  445. $ X, LDX, REALONE, WORK, LDX )
  446. IF (M.GT.0) THEN
  447. EPS2 = MAX( ULP,
  448. $ CLANGE( '1', Q, Q, WORK, LDX, RWORK ) / REAL( M ) )
  449. ELSE
  450. EPS2 = ULP
  451. END IF
  452. R = MIN( P, M-P, Q, M-Q )
  453. *
  454. * Copy the matrix X to the array XF.
  455. *
  456. CALL CLACPY( 'Full', M, Q, X, LDX, XF, LDX )
  457. *
  458. * Compute the CSD
  459. *
  460. CALL CUNCSD2BY1( 'Y', 'Y', 'Y', M, P, Q, XF(1,1), LDX, XF(P+1,1),
  461. $ LDX, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, WORK,
  462. $ LWORK, RWORK, 17*(R+2), IWORK, INFO )
  463. *
  464. * Compute [X11;X21] := diag(U1,U2)'*[X11;X21]*V1 - [D11;D21]
  465. *
  466. CALL CGEMM( 'No transpose', 'Conjugate transpose', P, Q, Q, ONE,
  467. $ X, LDX, V1T, LDV1T, ZERO, WORK, LDX )
  468. *
  469. CALL CGEMM( 'Conjugate transpose', 'No transpose', P, Q, P, ONE,
  470. $ U1, LDU1, WORK, LDX, ZERO, X, LDX )
  471. *
  472. DO I = 1, MIN(P,Q)-R
  473. X(I,I) = X(I,I) - ONE
  474. END DO
  475. DO I = 1, R
  476. X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) =
  477. $ X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) - CMPLX( COS(THETA(I)),
  478. $ 0.0E0 )
  479. END DO
  480. *
  481. CALL CGEMM( 'No transpose', 'Conjugate transpose', M-P, Q, Q, ONE,
  482. $ X(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX )
  483. *
  484. CALL CGEMM( 'Conjugate transpose', 'No transpose', M-P, Q, M-P,
  485. $ ONE, U2, LDU2, WORK, LDX, ZERO, X(P+1,1), LDX )
  486. *
  487. DO I = 1, MIN(M-P,Q)-R
  488. X(M-I+1,Q-I+1) = X(M-I+1,Q-I+1) - ONE
  489. END DO
  490. DO I = 1, R
  491. X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) =
  492. $ X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) -
  493. $ CMPLX( SIN(THETA(R-I+1)), 0.0E0 )
  494. END DO
  495. *
  496. * Compute norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) .
  497. *
  498. RESID = CLANGE( '1', P, Q, X, LDX, RWORK )
  499. RESULT( 10 ) = ( RESID / REAL(MAX(1,P,Q)) ) / EPS2
  500. *
  501. * Compute norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 ) .
  502. *
  503. RESID = CLANGE( '1', M-P, Q, X(P+1,1), LDX, RWORK )
  504. RESULT( 11 ) = ( RESID / REAL(MAX(1,M-P,Q)) ) / EPS2
  505. *
  506. * Compute I - U1'*U1
  507. *
  508. CALL CLASET( 'Full', P, P, ZERO, ONE, WORK, LDU1 )
  509. CALL CHERK( 'Upper', 'Conjugate transpose', P, P, -REALONE,
  510. $ U1, LDU1, REALONE, WORK, LDU1 )
  511. *
  512. * Compute norm( I - U1'*U1 ) / ( MAX(1,P) * ULP ) .
  513. *
  514. RESID = CLANHE( '1', 'Upper', P, WORK, LDU1, RWORK )
  515. RESULT( 12 ) = ( RESID / REAL(MAX(1,P)) ) / ULP
  516. *
  517. * Compute I - U2'*U2
  518. *
  519. CALL CLASET( 'Full', M-P, M-P, ZERO, ONE, WORK, LDU2 )
  520. CALL CHERK( 'Upper', 'Conjugate transpose', M-P, M-P, -REALONE,
  521. $ U2, LDU2, REALONE, WORK, LDU2 )
  522. *
  523. * Compute norm( I - U2'*U2 ) / ( MAX(1,M-P) * ULP ) .
  524. *
  525. RESID = CLANHE( '1', 'Upper', M-P, WORK, LDU2, RWORK )
  526. RESULT( 13 ) = ( RESID / REAL(MAX(1,M-P)) ) / ULP
  527. *
  528. * Compute I - V1T*V1T'
  529. *
  530. CALL CLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDV1T )
  531. CALL CHERK( 'Upper', 'No transpose', Q, Q, -REALONE,
  532. $ V1T, LDV1T, REALONE, WORK, LDV1T )
  533. *
  534. * Compute norm( I - V1T*V1T' ) / ( MAX(1,Q) * ULP ) .
  535. *
  536. RESID = CLANHE( '1', 'Upper', Q, WORK, LDV1T, RWORK )
  537. RESULT( 14 ) = ( RESID / REAL(MAX(1,Q)) ) / ULP
  538. *
  539. * Check sorting
  540. *
  541. RESULT( 15 ) = REALZERO
  542. DO I = 1, R
  543. IF( THETA(I).LT.REALZERO .OR. THETA(I).GT.PIOVER2 ) THEN
  544. RESULT( 15 ) = ULPINV
  545. END IF
  546. IF( I.GT.1) THEN
  547. IF ( THETA(I).LT.THETA(I-1) ) THEN
  548. RESULT( 15 ) = ULPINV
  549. END IF
  550. END IF
  551. END DO
  552. *
  553. RETURN
  554. *
  555. * End of CCSDTS
  556. *
  557. END