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.

scsdts.f 18 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. *> \brief \b SCSDTS
  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 SCSDTS( 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. * REAL 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. *> SCSDTS tests SORCSD, 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 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 REAL array, dimension (LDX,M)
  91. *> The M-by-M matrix X.
  92. *> \endverbatim
  93. *>
  94. *> \param[out] XF
  95. *> \verbatim
  96. *> XF is REAL array, dimension (LDX,M)
  97. *> Details of the CSD of X, as returned by SORCSD;
  98. *> see SORCSD 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 REAL 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 REAL 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 REAL 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 REAL 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 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 SORCSD 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 REAL 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. *> \date November 2011
  224. *
  225. *> \ingroup single_eig
  226. *
  227. * =====================================================================
  228. SUBROUTINE SCSDTS( M, P, Q, X, XF, LDX, U1, LDU1, U2, LDU2, V1T,
  229. $ LDV1T, V2T, LDV2T, THETA, IWORK, WORK, LWORK,
  230. $ RWORK, RESULT )
  231. *
  232. * -- LAPACK test routine (version 3.4.0) --
  233. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  234. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  235. * November 2011
  236. *
  237. * .. Scalar Arguments ..
  238. INTEGER LDX, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q
  239. * ..
  240. * .. Array Arguments ..
  241. INTEGER IWORK( * )
  242. REAL RESULT( 15 ), RWORK( * ), THETA( * )
  243. REAL U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
  244. $ V2T( LDV2T, * ), WORK( LWORK ), X( LDX, * ),
  245. $ XF( LDX, * )
  246. * ..
  247. *
  248. * =====================================================================
  249. *
  250. * .. Parameters ..
  251. REAL PIOVER2, REALONE, REALZERO
  252. PARAMETER ( PIOVER2 = 1.57079632679489662E0,
  253. $ REALONE = 1.0E0, REALZERO = 0.0E0 )
  254. REAL ZERO, ONE
  255. PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
  256. * ..
  257. * .. Local Scalars ..
  258. INTEGER I, INFO, R
  259. REAL EPS2, RESID, ULP, ULPINV
  260. * ..
  261. * .. External Functions ..
  262. REAL SLAMCH, SLANGE, SLANSY
  263. EXTERNAL SLAMCH, SLANGE, SLANSY
  264. * ..
  265. * .. External Subroutines ..
  266. EXTERNAL SGEMM, SLACPY, SLASET, SORCSD, SORCSD2BY1,
  267. $ SSYRK
  268. * ..
  269. * .. Intrinsic Functions ..
  270. INTRINSIC COS, MAX, MIN, REAL, SIN
  271. * ..
  272. * .. Executable Statements ..
  273. *
  274. ULP = SLAMCH( 'Precision' )
  275. ULPINV = REALONE / ULP
  276. *
  277. * The first half of the routine checks the 2-by-2 CSD
  278. *
  279. CALL SLASET( 'Full', M, M, ZERO, ONE, WORK, LDX )
  280. CALL SSYRK( 'Upper', 'Conjugate transpose', M, M, -ONE, X, LDX,
  281. $ ONE, WORK, LDX )
  282. IF (M.GT.0) THEN
  283. EPS2 = MAX( ULP,
  284. $ SLANGE( '1', M, M, WORK, LDX, RWORK ) / REAL( M ) )
  285. ELSE
  286. EPS2 = ULP
  287. END IF
  288. R = MIN( P, M-P, Q, M-Q )
  289. *
  290. * Copy the matrix X to the array XF.
  291. *
  292. CALL SLACPY( 'Full', M, M, X, LDX, XF, LDX )
  293. *
  294. * Compute the CSD
  295. *
  296. CALL SORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'D', M, P, Q, XF(1,1), LDX,
  297. $ XF(1,Q+1), LDX, XF(P+1,1), LDX, XF(P+1,Q+1), LDX,
  298. $ THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T,
  299. $ WORK, LWORK, IWORK, INFO )
  300. *
  301. * Compute XF := diag(U1,U2)'*X*diag(V1,V2) - [D11 D12; D21 D22]
  302. *
  303. CALL SLACPY( 'Full', M, M, X, LDX, XF, LDX )
  304. *
  305. CALL SGEMM( 'No transpose', 'Conjugate transpose', P, Q, Q, ONE,
  306. $ XF, LDX, V1T, LDV1T, ZERO, WORK, LDX )
  307. *
  308. CALL SGEMM( 'Conjugate transpose', 'No transpose', P, Q, P, ONE,
  309. $ U1, LDU1, WORK, LDX, ZERO, XF, LDX )
  310. *
  311. DO I = 1, MIN(P,Q)-R
  312. XF(I,I) = XF(I,I) - ONE
  313. END DO
  314. DO I = 1, R
  315. XF(MIN(P,Q)-R+I,MIN(P,Q)-R+I) =
  316. $ XF(MIN(P,Q)-R+I,MIN(P,Q)-R+I) - COS(THETA(I))
  317. END DO
  318. *
  319. CALL SGEMM( 'No transpose', 'Conjugate transpose', P, M-Q, M-Q,
  320. $ ONE, XF(1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX )
  321. *
  322. CALL SGEMM( 'Conjugate transpose', 'No transpose', P, M-Q, P,
  323. $ ONE, U1, LDU1, WORK, LDX, ZERO, XF(1,Q+1), LDX )
  324. *
  325. DO I = 1, MIN(P,M-Q)-R
  326. XF(P-I+1,M-I+1) = XF(P-I+1,M-I+1) + ONE
  327. END DO
  328. DO I = 1, R
  329. XF(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) =
  330. $ XF(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) +
  331. $ SIN(THETA(R-I+1))
  332. END DO
  333. *
  334. CALL SGEMM( 'No transpose', 'Conjugate transpose', M-P, Q, Q, ONE,
  335. $ XF(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX )
  336. *
  337. CALL SGEMM( 'Conjugate transpose', 'No transpose', M-P, Q, M-P,
  338. $ ONE, U2, LDU2, WORK, LDX, ZERO, XF(P+1,1), LDX )
  339. *
  340. DO I = 1, MIN(M-P,Q)-R
  341. XF(M-I+1,Q-I+1) = XF(M-I+1,Q-I+1) - ONE
  342. END DO
  343. DO I = 1, R
  344. XF(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) =
  345. $ XF(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) -
  346. $ SIN(THETA(R-I+1))
  347. END DO
  348. *
  349. CALL SGEMM( 'No transpose', 'Conjugate transpose', M-P, M-Q, M-Q,
  350. $ ONE, XF(P+1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX )
  351. *
  352. CALL SGEMM( 'Conjugate transpose', 'No transpose', M-P, M-Q, M-P,
  353. $ ONE, U2, LDU2, WORK, LDX, ZERO, XF(P+1,Q+1), LDX )
  354. *
  355. DO I = 1, MIN(M-P,M-Q)-R
  356. XF(P+I,Q+I) = XF(P+I,Q+I) - ONE
  357. END DO
  358. DO I = 1, R
  359. XF(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) =
  360. $ XF(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) -
  361. $ COS(THETA(I))
  362. END DO
  363. *
  364. * Compute norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) .
  365. *
  366. RESID = SLANGE( '1', P, Q, XF, LDX, RWORK )
  367. RESULT( 1 ) = ( RESID / REAL(MAX(1,P,Q)) ) / EPS2
  368. *
  369. * Compute norm( U1'*X12*V2 - D12 ) / ( MAX(1,P,M-Q)*EPS2 ) .
  370. *
  371. RESID = SLANGE( '1', P, M-Q, XF(1,Q+1), LDX, RWORK )
  372. RESULT( 2 ) = ( RESID / REAL(MAX(1,P,M-Q)) ) / EPS2
  373. *
  374. * Compute norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 ) .
  375. *
  376. RESID = SLANGE( '1', M-P, Q, XF(P+1,1), LDX, RWORK )
  377. RESULT( 3 ) = ( RESID / REAL(MAX(1,M-P,Q)) ) / EPS2
  378. *
  379. * Compute norm( U2'*X22*V2 - D22 ) / ( MAX(1,M-P,M-Q)*EPS2 ) .
  380. *
  381. RESID = SLANGE( '1', M-P, M-Q, XF(P+1,Q+1), LDX, RWORK )
  382. RESULT( 4 ) = ( RESID / REAL(MAX(1,M-P,M-Q)) ) / EPS2
  383. *
  384. * Compute I - U1'*U1
  385. *
  386. CALL SLASET( 'Full', P, P, ZERO, ONE, WORK, LDU1 )
  387. CALL SSYRK( 'Upper', 'Conjugate transpose', P, P, -ONE, U1, LDU1,
  388. $ ONE, WORK, LDU1 )
  389. *
  390. * Compute norm( I - U'*U ) / ( MAX(1,P) * ULP ) .
  391. *
  392. RESID = SLANSY( '1', 'Upper', P, WORK, LDU1, RWORK )
  393. RESULT( 5 ) = ( RESID / REAL(MAX(1,P)) ) / ULP
  394. *
  395. * Compute I - U2'*U2
  396. *
  397. CALL SLASET( 'Full', M-P, M-P, ZERO, ONE, WORK, LDU2 )
  398. CALL SSYRK( 'Upper', 'Conjugate transpose', M-P, M-P, -ONE, U2,
  399. $ LDU2, ONE, WORK, LDU2 )
  400. *
  401. * Compute norm( I - U2'*U2 ) / ( MAX(1,M-P) * ULP ) .
  402. *
  403. RESID = SLANSY( '1', 'Upper', M-P, WORK, LDU2, RWORK )
  404. RESULT( 6 ) = ( RESID / REAL(MAX(1,M-P)) ) / ULP
  405. *
  406. * Compute I - V1T*V1T'
  407. *
  408. CALL SLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDV1T )
  409. CALL SSYRK( 'Upper', 'No transpose', Q, Q, -ONE, V1T, LDV1T, ONE,
  410. $ WORK, LDV1T )
  411. *
  412. * Compute norm( I - V1T*V1T' ) / ( MAX(1,Q) * ULP ) .
  413. *
  414. RESID = SLANSY( '1', 'Upper', Q, WORK, LDV1T, RWORK )
  415. RESULT( 7 ) = ( RESID / REAL(MAX(1,Q)) ) / ULP
  416. *
  417. * Compute I - V2T*V2T'
  418. *
  419. CALL SLASET( 'Full', M-Q, M-Q, ZERO, ONE, WORK, LDV2T )
  420. CALL SSYRK( 'Upper', 'No transpose', M-Q, M-Q, -ONE, V2T, LDV2T,
  421. $ ONE, WORK, LDV2T )
  422. *
  423. * Compute norm( I - V2T*V2T' ) / ( MAX(1,M-Q) * ULP ) .
  424. *
  425. RESID = SLANSY( '1', 'Upper', M-Q, WORK, LDV2T, RWORK )
  426. RESULT( 8 ) = ( RESID / REAL(MAX(1,M-Q)) ) / ULP
  427. *
  428. * Check sorting
  429. *
  430. RESULT( 9 ) = REALZERO
  431. DO I = 1, R
  432. IF( THETA(I).LT.REALZERO .OR. THETA(I).GT.PIOVER2 ) THEN
  433. RESULT( 9 ) = ULPINV
  434. END IF
  435. IF( I.GT.1 ) THEN
  436. IF ( THETA(I).LT.THETA(I-1) ) THEN
  437. RESULT( 9 ) = ULPINV
  438. END IF
  439. END IF
  440. END DO
  441. *
  442. * The second half of the routine checks the 2-by-1 CSD
  443. *
  444. CALL SLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDX )
  445. CALL SSYRK( 'Upper', 'Conjugate transpose', Q, M, -ONE, X, LDX,
  446. $ ONE, WORK, LDX )
  447. IF (M.GT.0) THEN
  448. EPS2 = MAX( ULP,
  449. $ SLANGE( '1', Q, Q, WORK, LDX, RWORK ) / REAL( M ) )
  450. ELSE
  451. EPS2 = ULP
  452. END IF
  453. R = MIN( P, M-P, Q, M-Q )
  454. *
  455. * Copy the matrix [X11;X21] to the array XF.
  456. *
  457. CALL SLACPY( 'Full', M, Q, X, LDX, XF, LDX )
  458. *
  459. * Compute the CSD
  460. *
  461. CALL SORCSD2BY1( 'Y', 'Y', 'Y', M, P, Q, XF(1,1), LDX, XF(P+1,1),
  462. $ LDX, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, WORK,
  463. $ LWORK, IWORK, INFO )
  464. *
  465. * Compute [X11;X21] := diag(U1,U2)'*[X11;X21]*V1 - [D11;D21]
  466. *
  467. CALL SGEMM( 'No transpose', 'Conjugate transpose', P, Q, Q, ONE,
  468. $ X, LDX, V1T, LDV1T, ZERO, WORK, LDX )
  469. *
  470. CALL SGEMM( 'Conjugate transpose', 'No transpose', P, Q, P, ONE,
  471. $ U1, LDU1, WORK, LDX, ZERO, X, LDX )
  472. *
  473. DO I = 1, MIN(P,Q)-R
  474. X(I,I) = X(I,I) - ONE
  475. END DO
  476. DO I = 1, R
  477. X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) =
  478. $ X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) - COS(THETA(I))
  479. END DO
  480. *
  481. CALL SGEMM( 'No transpose', 'Conjugate transpose', M-P, Q, Q, ONE,
  482. $ X(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX )
  483. *
  484. CALL SGEMM( '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. $ SIN(THETA(R-I+1))
  494. END DO
  495. *
  496. * Compute norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) .
  497. *
  498. RESID = SLANGE( '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 = SLANGE( '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 SLASET( 'Full', P, P, ZERO, ONE, WORK, LDU1 )
  509. CALL SSYRK( 'Upper', 'Conjugate transpose', P, P, -ONE, U1, LDU1,
  510. $ ONE, WORK, LDU1 )
  511. *
  512. * Compute norm( I - U1'*U1 ) / ( MAX(1,P) * ULP ) .
  513. *
  514. RESID = SLANSY( '1', 'Upper', P, WORK, LDU1, RWORK )
  515. RESULT( 12 ) = ( RESID / REAL(MAX(1,P)) ) / ULP
  516. *
  517. * Compute I - U2'*U2
  518. *
  519. CALL SLASET( 'Full', M-P, M-P, ZERO, ONE, WORK, LDU2 )
  520. CALL SSYRK( 'Upper', 'Conjugate transpose', M-P, M-P, -ONE, U2,
  521. $ LDU2, ONE, WORK, LDU2 )
  522. *
  523. * Compute norm( I - U2'*U2 ) / ( MAX(1,M-P) * ULP ) .
  524. *
  525. RESID = SLANSY( '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 SLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDV1T )
  531. CALL SSYRK( 'Upper', 'No transpose', Q, Q, -ONE, V1T, LDV1T, ONE,
  532. $ WORK, LDV1T )
  533. *
  534. * Compute norm( I - V1T*V1T' ) / ( MAX(1,Q) * ULP ) .
  535. *
  536. RESID = SLANSY( '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 SCSDTS
  556. *
  557. END