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.

dcsdts.f 18 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. *> \brief \b DCSDTS
  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 DCSDTS( 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. * DOUBLE PRECISION RESULT( 15 ), RWORK( * ), THETA( * )
  21. * DOUBLE PRECISION 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. *> DCSDTS tests DORCSD, which, given an M-by-M partitioned orthogonal
  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 DORCSD2BY1, 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 DOUBLE PRECISION array, dimension (LDX,M)
  91. *> The M-by-M matrix X.
  92. *> \endverbatim
  93. *>
  94. *> \param[out] XF
  95. *> \verbatim
  96. *> XF is DOUBLE PRECISION array, dimension (LDX,M)
  97. *> Details of the CSD of X, as returned by DORCSD;
  98. *> see DORCSD 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 DOUBLE PRECISION array, dimension(LDU1,P)
  111. *> The P-by-P orthogonal 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 DOUBLE PRECISION array, dimension(LDU2,M-P)
  123. *> The (M-P)-by-(M-P) orthogonal 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 DOUBLE PRECISION array, dimension(LDV1T,Q)
  135. *> The Q-by-Q orthogonal 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 DOUBLE PRECISION array, dimension(LDV2T,M-Q)
  148. *> The (M-Q)-by-(M-Q) orthogonal 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 DOUBLE PRECISION 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 DORCSD 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 DOUBLE PRECISION 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 DOUBLE PRECISION array
  185. *> \endverbatim
  186. *>
  187. *> \param[out] RESULT
  188. *> \verbatim
  189. *> RESULT is DOUBLE PRECISION 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 double_eig
  224. *
  225. * =====================================================================
  226. SUBROUTINE DCSDTS( 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. DOUBLE PRECISION RESULT( 15 ), RWORK( * ), THETA( * )
  240. DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
  241. $ V2T( LDV2T, * ), WORK( LWORK ), X( LDX, * ),
  242. $ XF( LDX, * )
  243. * ..
  244. *
  245. * =====================================================================
  246. *
  247. * .. Parameters ..
  248. DOUBLE PRECISION REALONE, REALZERO
  249. PARAMETER ( REALONE = 1.0D0, REALZERO = 0.0D0 )
  250. DOUBLE PRECISION ZERO, ONE
  251. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  252. DOUBLE PRECISION PIOVER2
  253. PARAMETER ( PIOVER2 = 1.57079632679489661923132169163975144210D0 )
  254. * ..
  255. * .. Local Scalars ..
  256. INTEGER I, INFO, R
  257. DOUBLE PRECISION EPS2, RESID, ULP, ULPINV
  258. * ..
  259. * .. External Functions ..
  260. DOUBLE PRECISION DLAMCH, DLANGE, DLANSY
  261. EXTERNAL DLAMCH, DLANGE, DLANSY
  262. * ..
  263. * .. External Subroutines ..
  264. EXTERNAL DGEMM, DLACPY, DLASET, DORCSD, DORCSD2BY1,
  265. $ DSYRK
  266. * ..
  267. * .. Intrinsic Functions ..
  268. INTRINSIC COS, DBLE, MAX, MIN, SIN
  269. * ..
  270. * .. Executable Statements ..
  271. *
  272. ULP = DLAMCH( 'Precision' )
  273. ULPINV = REALONE / ULP
  274. *
  275. * The first half of the routine checks the 2-by-2 CSD
  276. *
  277. CALL DLASET( 'Full', M, M, ZERO, ONE, WORK, LDX )
  278. CALL DSYRK( 'Upper', 'Conjugate transpose', M, M, -ONE, X, LDX,
  279. $ ONE, WORK, LDX )
  280. IF (M.GT.0) THEN
  281. EPS2 = MAX( ULP,
  282. $ DLANGE( '1', M, M, WORK, LDX, RWORK ) / DBLE( 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 DLACPY( 'Full', M, M, X, LDX, XF, LDX )
  291. *
  292. * Compute the CSD
  293. *
  294. CALL DORCSD( '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, IWORK, INFO )
  298. *
  299. * Compute XF := diag(U1,U2)'*X*diag(V1,V2) - [D11 D12; D21 D22]
  300. *
  301. CALL DLACPY( 'Full', M, M, X, LDX, XF, LDX )
  302. *
  303. CALL DGEMM( 'No transpose', 'Conjugate transpose', P, Q, Q, ONE,
  304. $ XF, LDX, V1T, LDV1T, ZERO, WORK, LDX )
  305. *
  306. CALL DGEMM( '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) - COS(THETA(I))
  315. END DO
  316. *
  317. CALL DGEMM( 'No transpose', 'Conjugate transpose', P, M-Q, M-Q,
  318. $ ONE, XF(1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX )
  319. *
  320. CALL DGEMM( 'Conjugate transpose', 'No transpose', P, M-Q, P,
  321. $ ONE, U1, LDU1, WORK, LDX, ZERO, XF(1,Q+1), LDX )
  322. *
  323. DO I = 1, MIN(P,M-Q)-R
  324. XF(P-I+1,M-I+1) = XF(P-I+1,M-I+1) + ONE
  325. END DO
  326. DO I = 1, R
  327. XF(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) =
  328. $ XF(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) +
  329. $ SIN(THETA(R-I+1))
  330. END DO
  331. *
  332. CALL DGEMM( 'No transpose', 'Conjugate transpose', M-P, Q, Q, ONE,
  333. $ XF(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX )
  334. *
  335. CALL DGEMM( 'Conjugate transpose', 'No transpose', M-P, Q, M-P,
  336. $ ONE, U2, LDU2, WORK, LDX, ZERO, XF(P+1,1), LDX )
  337. *
  338. DO I = 1, MIN(M-P,Q)-R
  339. XF(M-I+1,Q-I+1) = XF(M-I+1,Q-I+1) - ONE
  340. END DO
  341. DO I = 1, R
  342. XF(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) =
  343. $ XF(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) -
  344. $ SIN(THETA(R-I+1))
  345. END DO
  346. *
  347. CALL DGEMM( 'No transpose', 'Conjugate transpose', M-P, M-Q, M-Q,
  348. $ ONE, XF(P+1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX )
  349. *
  350. CALL DGEMM( 'Conjugate transpose', 'No transpose', M-P, M-Q, M-P,
  351. $ ONE, U2, LDU2, WORK, LDX, ZERO, XF(P+1,Q+1), LDX )
  352. *
  353. DO I = 1, MIN(M-P,M-Q)-R
  354. XF(P+I,Q+I) = XF(P+I,Q+I) - ONE
  355. END DO
  356. DO I = 1, R
  357. XF(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) =
  358. $ XF(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) -
  359. $ COS(THETA(I))
  360. END DO
  361. *
  362. * Compute norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) .
  363. *
  364. RESID = DLANGE( '1', P, Q, XF, LDX, RWORK )
  365. RESULT( 1 ) = ( RESID / DBLE(MAX(1,P,Q)) ) / EPS2
  366. *
  367. * Compute norm( U1'*X12*V2 - D12 ) / ( MAX(1,P,M-Q)*EPS2 ) .
  368. *
  369. RESID = DLANGE( '1', P, M-Q, XF(1,Q+1), LDX, RWORK )
  370. RESULT( 2 ) = ( RESID / DBLE(MAX(1,P,M-Q)) ) / EPS2
  371. *
  372. * Compute norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 ) .
  373. *
  374. RESID = DLANGE( '1', M-P, Q, XF(P+1,1), LDX, RWORK )
  375. RESULT( 3 ) = ( RESID / DBLE(MAX(1,M-P,Q)) ) / EPS2
  376. *
  377. * Compute norm( U2'*X22*V2 - D22 ) / ( MAX(1,M-P,M-Q)*EPS2 ) .
  378. *
  379. RESID = DLANGE( '1', M-P, M-Q, XF(P+1,Q+1), LDX, RWORK )
  380. RESULT( 4 ) = ( RESID / DBLE(MAX(1,M-P,M-Q)) ) / EPS2
  381. *
  382. * Compute I - U1'*U1
  383. *
  384. CALL DLASET( 'Full', P, P, ZERO, ONE, WORK, LDU1 )
  385. CALL DSYRK( 'Upper', 'Conjugate transpose', P, P, -ONE, U1, LDU1,
  386. $ ONE, WORK, LDU1 )
  387. *
  388. * Compute norm( I - U'*U ) / ( MAX(1,P) * ULP ) .
  389. *
  390. RESID = DLANSY( '1', 'Upper', P, WORK, LDU1, RWORK )
  391. RESULT( 5 ) = ( RESID / DBLE(MAX(1,P)) ) / ULP
  392. *
  393. * Compute I - U2'*U2
  394. *
  395. CALL DLASET( 'Full', M-P, M-P, ZERO, ONE, WORK, LDU2 )
  396. CALL DSYRK( 'Upper', 'Conjugate transpose', M-P, M-P, -ONE, U2,
  397. $ LDU2, ONE, WORK, LDU2 )
  398. *
  399. * Compute norm( I - U2'*U2 ) / ( MAX(1,M-P) * ULP ) .
  400. *
  401. RESID = DLANSY( '1', 'Upper', M-P, WORK, LDU2, RWORK )
  402. RESULT( 6 ) = ( RESID / DBLE(MAX(1,M-P)) ) / ULP
  403. *
  404. * Compute I - V1T*V1T'
  405. *
  406. CALL DLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDV1T )
  407. CALL DSYRK( 'Upper', 'No transpose', Q, Q, -ONE, V1T, LDV1T, ONE,
  408. $ WORK, LDV1T )
  409. *
  410. * Compute norm( I - V1T*V1T' ) / ( MAX(1,Q) * ULP ) .
  411. *
  412. RESID = DLANSY( '1', 'Upper', Q, WORK, LDV1T, RWORK )
  413. RESULT( 7 ) = ( RESID / DBLE(MAX(1,Q)) ) / ULP
  414. *
  415. * Compute I - V2T*V2T'
  416. *
  417. CALL DLASET( 'Full', M-Q, M-Q, ZERO, ONE, WORK, LDV2T )
  418. CALL DSYRK( 'Upper', 'No transpose', M-Q, M-Q, -ONE, V2T, LDV2T,
  419. $ ONE, WORK, LDV2T )
  420. *
  421. * Compute norm( I - V2T*V2T' ) / ( MAX(1,M-Q) * ULP ) .
  422. *
  423. RESID = DLANSY( '1', 'Upper', M-Q, WORK, LDV2T, RWORK )
  424. RESULT( 8 ) = ( RESID / DBLE(MAX(1,M-Q)) ) / ULP
  425. *
  426. * Check sorting
  427. *
  428. RESULT( 9 ) = REALZERO
  429. DO I = 1, R
  430. IF( THETA(I).LT.REALZERO .OR. THETA(I).GT.PIOVER2 ) THEN
  431. RESULT( 9 ) = ULPINV
  432. END IF
  433. IF( I.GT.1 ) THEN
  434. IF ( THETA(I).LT.THETA(I-1) ) THEN
  435. RESULT( 9 ) = ULPINV
  436. END IF
  437. END IF
  438. END DO
  439. *
  440. * The second half of the routine checks the 2-by-1 CSD
  441. *
  442. CALL DLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDX )
  443. CALL DSYRK( 'Upper', 'Conjugate transpose', Q, M, -ONE, X, LDX,
  444. $ ONE, WORK, LDX )
  445. IF( M.GT.0 ) THEN
  446. EPS2 = MAX( ULP,
  447. $ DLANGE( '1', Q, Q, WORK, LDX, RWORK ) / DBLE( M ) )
  448. ELSE
  449. EPS2 = ULP
  450. END IF
  451. R = MIN( P, M-P, Q, M-Q )
  452. *
  453. * Copy the matrix [ X11; X21 ] to the array XF.
  454. *
  455. CALL DLACPY( 'Full', M, Q, X, LDX, XF, LDX )
  456. *
  457. * Compute the CSD
  458. *
  459. CALL DORCSD2BY1( 'Y', 'Y', 'Y', M, P, Q, XF(1,1), LDX, XF(P+1,1),
  460. $ LDX, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, WORK,
  461. $ LWORK, IWORK, INFO )
  462. *
  463. * Compute [X11;X21] := diag(U1,U2)'*[X11;X21]*V1 - [D11;D21]
  464. *
  465. CALL DGEMM( 'No transpose', 'Conjugate transpose', P, Q, Q, ONE,
  466. $ X, LDX, V1T, LDV1T, ZERO, WORK, LDX )
  467. *
  468. CALL DGEMM( 'Conjugate transpose', 'No transpose', P, Q, P, ONE,
  469. $ U1, LDU1, WORK, LDX, ZERO, X, LDX )
  470. *
  471. DO I = 1, MIN(P,Q)-R
  472. X(I,I) = X(I,I) - ONE
  473. END DO
  474. DO I = 1, R
  475. X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) =
  476. $ X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) - COS(THETA(I))
  477. END DO
  478. *
  479. CALL DGEMM( 'No transpose', 'Conjugate transpose', M-P, Q, Q, ONE,
  480. $ X(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX )
  481. *
  482. CALL DGEMM( 'Conjugate transpose', 'No transpose', M-P, Q, M-P,
  483. $ ONE, U2, LDU2, WORK, LDX, ZERO, X(P+1,1), LDX )
  484. *
  485. DO I = 1, MIN(M-P,Q)-R
  486. X(M-I+1,Q-I+1) = X(M-I+1,Q-I+1) - ONE
  487. END DO
  488. DO I = 1, R
  489. X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) =
  490. $ X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) -
  491. $ SIN(THETA(R-I+1))
  492. END DO
  493. *
  494. * Compute norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) .
  495. *
  496. RESID = DLANGE( '1', P, Q, X, LDX, RWORK )
  497. RESULT( 10 ) = ( RESID / DBLE(MAX(1,P,Q)) ) / EPS2
  498. *
  499. * Compute norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 ) .
  500. *
  501. RESID = DLANGE( '1', M-P, Q, X(P+1,1), LDX, RWORK )
  502. RESULT( 11 ) = ( RESID / DBLE(MAX(1,M-P,Q)) ) / EPS2
  503. *
  504. * Compute I - U1'*U1
  505. *
  506. CALL DLASET( 'Full', P, P, ZERO, ONE, WORK, LDU1 )
  507. CALL DSYRK( 'Upper', 'Conjugate transpose', P, P, -ONE, U1, LDU1,
  508. $ ONE, WORK, LDU1 )
  509. *
  510. * Compute norm( I - U1'*U1 ) / ( MAX(1,P) * ULP ) .
  511. *
  512. RESID = DLANSY( '1', 'Upper', P, WORK, LDU1, RWORK )
  513. RESULT( 12 ) = ( RESID / DBLE(MAX(1,P)) ) / ULP
  514. *
  515. * Compute I - U2'*U2
  516. *
  517. CALL DLASET( 'Full', M-P, M-P, ZERO, ONE, WORK, LDU2 )
  518. CALL DSYRK( 'Upper', 'Conjugate transpose', M-P, M-P, -ONE, U2,
  519. $ LDU2, ONE, WORK, LDU2 )
  520. *
  521. * Compute norm( I - U2'*U2 ) / ( MAX(1,M-P) * ULP ) .
  522. *
  523. RESID = DLANSY( '1', 'Upper', M-P, WORK, LDU2, RWORK )
  524. RESULT( 13 ) = ( RESID / DBLE(MAX(1,M-P)) ) / ULP
  525. *
  526. * Compute I - V1T*V1T'
  527. *
  528. CALL DLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDV1T )
  529. CALL DSYRK( 'Upper', 'No transpose', Q, Q, -ONE, V1T, LDV1T, ONE,
  530. $ WORK, LDV1T )
  531. *
  532. * Compute norm( I - V1T*V1T' ) / ( MAX(1,Q) * ULP ) .
  533. *
  534. RESID = DLANSY( '1', 'Upper', Q, WORK, LDV1T, RWORK )
  535. RESULT( 14 ) = ( RESID / DBLE(MAX(1,Q)) ) / ULP
  536. *
  537. * Check sorting
  538. *
  539. RESULT( 15 ) = REALZERO
  540. DO I = 1, R
  541. IF( THETA(I).LT.REALZERO .OR. THETA(I).GT.PIOVER2 ) THEN
  542. RESULT( 15 ) = ULPINV
  543. END IF
  544. IF( I.GT.1 ) THEN
  545. IF ( THETA(I).LT.THETA(I-1) ) THEN
  546. RESULT( 15 ) = ULPINV
  547. END IF
  548. END IF
  549. END DO
  550. *
  551. RETURN
  552. *
  553. * End of DCSDTS
  554. *
  555. END