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 13 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  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( 9 ), 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. *> \endverbatim
  51. *
  52. * Arguments:
  53. * ==========
  54. *
  55. *> \param[in] M
  56. *> \verbatim
  57. *> M is INTEGER
  58. *> The number of rows of the matrix X. M >= 0.
  59. *> \endverbatim
  60. *>
  61. *> \param[in] P
  62. *> \verbatim
  63. *> P is INTEGER
  64. *> The number of rows of the matrix X11. P >= 0.
  65. *> \endverbatim
  66. *>
  67. *> \param[in] Q
  68. *> \verbatim
  69. *> Q is INTEGER
  70. *> The number of columns of the matrix X11. Q >= 0.
  71. *> \endverbatim
  72. *>
  73. *> \param[in] X
  74. *> \verbatim
  75. *> X is DOUBLE PRECISION array, dimension (LDX,M)
  76. *> The M-by-M matrix X.
  77. *> \endverbatim
  78. *>
  79. *> \param[out] XF
  80. *> \verbatim
  81. *> XF is DOUBLE PRECISION array, dimension (LDX,M)
  82. *> Details of the CSD of X, as returned by DORCSD;
  83. *> see DORCSD for further details.
  84. *> \endverbatim
  85. *>
  86. *> \param[in] LDX
  87. *> \verbatim
  88. *> LDX is INTEGER
  89. *> The leading dimension of the arrays X and XF.
  90. *> LDX >= max( 1,M ).
  91. *> \endverbatim
  92. *>
  93. *> \param[out] U1
  94. *> \verbatim
  95. *> U1 is DOUBLE PRECISION array, dimension(LDU1,P)
  96. *> The P-by-P orthogonal matrix U1.
  97. *> \endverbatim
  98. *>
  99. *> \param[in] LDU1
  100. *> \verbatim
  101. *> LDU1 is INTEGER
  102. *> The leading dimension of the array U1. LDU >= max(1,P).
  103. *> \endverbatim
  104. *>
  105. *> \param[out] U2
  106. *> \verbatim
  107. *> U2 is DOUBLE PRECISION array, dimension(LDU2,M-P)
  108. *> The (M-P)-by-(M-P) orthogonal matrix U2.
  109. *> \endverbatim
  110. *>
  111. *> \param[in] LDU2
  112. *> \verbatim
  113. *> LDU2 is INTEGER
  114. *> The leading dimension of the array U2. LDU >= max(1,M-P).
  115. *> \endverbatim
  116. *>
  117. *> \param[out] V1T
  118. *> \verbatim
  119. *> V1T is DOUBLE PRECISION array, dimension(LDV1T,Q)
  120. *> The Q-by-Q orthogonal matrix V1T.
  121. *> \endverbatim
  122. *>
  123. *> \param[in] LDV1T
  124. *> \verbatim
  125. *> LDV1T is INTEGER
  126. *> The leading dimension of the array V1T. LDV1T >=
  127. *> max(1,Q).
  128. *> \endverbatim
  129. *>
  130. *> \param[out] V2T
  131. *> \verbatim
  132. *> V2T is DOUBLE PRECISION array, dimension(LDV2T,M-Q)
  133. *> The (M-Q)-by-(M-Q) orthogonal matrix V2T.
  134. *> \endverbatim
  135. *>
  136. *> \param[in] LDV2T
  137. *> \verbatim
  138. *> LDV2T is INTEGER
  139. *> The leading dimension of the array V2T. LDV2T >=
  140. *> max(1,M-Q).
  141. *> \endverbatim
  142. *>
  143. *> \param[out] THETA
  144. *> \verbatim
  145. *> THETA is DOUBLE PRECISION array, dimension MIN(P,M-P,Q,M-Q)
  146. *> The CS values of X; the essentially diagonal matrices C and
  147. *> S are constructed from THETA; see subroutine DORCSD for
  148. *> details.
  149. *> \endverbatim
  150. *>
  151. *> \param[out] IWORK
  152. *> \verbatim
  153. *> IWORK is INTEGER array, dimension (M)
  154. *> \endverbatim
  155. *>
  156. *> \param[out] WORK
  157. *> \verbatim
  158. *> WORK is DOUBLE PRECISION array, dimension (LWORK)
  159. *> \endverbatim
  160. *>
  161. *> \param[in] LWORK
  162. *> \verbatim
  163. *> LWORK is INTEGER
  164. *> The dimension of the array WORK
  165. *> \endverbatim
  166. *>
  167. *> \param[out] RWORK
  168. *> \verbatim
  169. *> RWORK is DOUBLE PRECISION array
  170. *> \endverbatim
  171. *>
  172. *> \param[out] RESULT
  173. *> \verbatim
  174. *> RESULT is DOUBLE PRECISION array, dimension (9)
  175. *> The test ratios:
  176. *> RESULT(1) = norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 )
  177. *> RESULT(2) = norm( U1'*X12*V2 - D12 ) / ( MAX(1,P,M-Q)*EPS2 )
  178. *> RESULT(3) = norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 )
  179. *> RESULT(4) = norm( U2'*X22*V2 - D22 ) / ( MAX(1,M-P,M-Q)*EPS2 )
  180. *> RESULT(5) = norm( I - U1'*U1 ) / ( MAX(1,P)*ULP )
  181. *> RESULT(6) = norm( I - U2'*U2 ) / ( MAX(1,M-P)*ULP )
  182. *> RESULT(7) = norm( I - V1T'*V1T ) / ( MAX(1,Q)*ULP )
  183. *> RESULT(8) = norm( I - V2T'*V2T ) / ( MAX(1,M-Q)*ULP )
  184. *> RESULT(9) = 0 if THETA is in increasing order and
  185. *> all angles are in [0,pi/2];
  186. *> = ULPINV otherwise.
  187. *> ( EPS2 = MAX( norm( I - X'*X ) / M, ULP ). )
  188. *> \endverbatim
  189. *
  190. * Authors:
  191. * ========
  192. *
  193. *> \author Univ. of Tennessee
  194. *> \author Univ. of California Berkeley
  195. *> \author Univ. of Colorado Denver
  196. *> \author NAG Ltd.
  197. *
  198. *> \date November 2011
  199. *
  200. *> \ingroup double_eig
  201. *
  202. * =====================================================================
  203. SUBROUTINE DCSDTS( M, P, Q, X, XF, LDX, U1, LDU1, U2, LDU2, V1T,
  204. $ LDV1T, V2T, LDV2T, THETA, IWORK, WORK, LWORK,
  205. $ RWORK, RESULT )
  206. *
  207. * -- LAPACK test routine (version 3.4.0) --
  208. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  209. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  210. * November 2011
  211. *
  212. * .. Scalar Arguments ..
  213. INTEGER LDX, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q
  214. * ..
  215. * .. Array Arguments ..
  216. INTEGER IWORK( * )
  217. DOUBLE PRECISION RESULT( 9 ), RWORK( * ), THETA( * )
  218. DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
  219. $ V2T( LDV2T, * ), WORK( LWORK ), X( LDX, * ),
  220. $ XF( LDX, * )
  221. * ..
  222. *
  223. * =====================================================================
  224. *
  225. * .. Parameters ..
  226. DOUBLE PRECISION PIOVER2, REALONE, REALZERO
  227. PARAMETER ( PIOVER2 = 1.57079632679489662D0,
  228. $ REALONE = 1.0D0, REALZERO = 0.0D0 )
  229. DOUBLE PRECISION ZERO, ONE
  230. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  231. * ..
  232. * .. Local Scalars ..
  233. INTEGER I, INFO, R
  234. DOUBLE PRECISION EPS2, RESID, ULP, ULPINV
  235. * ..
  236. * .. External Functions ..
  237. DOUBLE PRECISION DLAMCH, DLANGE, DLANSY
  238. EXTERNAL DLAMCH, DLANGE, DLANSY
  239. * ..
  240. * .. External Subroutines ..
  241. EXTERNAL DGEMM, DLACPY, DLASET, DORCSD, DSYRK
  242. * ..
  243. * .. Intrinsic Functions ..
  244. INTRINSIC DBLE, MAX, MIN
  245. * ..
  246. * .. Executable Statements ..
  247. *
  248. ULP = DLAMCH( 'Precision' )
  249. ULPINV = REALONE / ULP
  250. CALL DLASET( 'Full', M, M, ZERO, ONE, WORK, LDX )
  251. CALL DSYRK( 'Upper', 'Conjugate transpose', M, M, -ONE, X, LDX,
  252. $ ONE, WORK, LDX )
  253. IF (M.GT.0) THEN
  254. EPS2 = MAX( ULP,
  255. $ DLANGE( '1', M, M, WORK, LDX, RWORK ) / DBLE( M ) )
  256. ELSE
  257. EPS2 = ULP
  258. END IF
  259. R = MIN( P, M-P, Q, M-Q )
  260. *
  261. * Copy the matrix X to the array XF.
  262. *
  263. CALL DLACPY( 'Full', M, M, X, LDX, XF, LDX )
  264. *
  265. * Compute the CSD
  266. *
  267. CALL DORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'D', M, P, Q, XF(1,1), LDX,
  268. $ XF(1,Q+1), LDX, XF(P+1,1), LDX, XF(P+1,Q+1), LDX,
  269. $ THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T,
  270. $ WORK, LWORK, IWORK, INFO )
  271. *
  272. * Compute X := diag(U1,U2)'*X*diag(V1,V2) - [D11 D12; D21 D22]
  273. *
  274. CALL DGEMM( 'No transpose', 'Conjugate transpose', P, Q, Q, ONE,
  275. $ X, LDX, V1T, LDV1T, ZERO, WORK, LDX )
  276. *
  277. CALL DGEMM( 'Conjugate transpose', 'No transpose', P, Q, P, ONE,
  278. $ U1, LDU1, WORK, LDX, ZERO, X, LDX )
  279. *
  280. DO I = 1, MIN(P,Q)-R
  281. X(I,I) = X(I,I) - ONE
  282. END DO
  283. DO I = 1, R
  284. X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) =
  285. $ X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) - COS(THETA(I))
  286. END DO
  287. *
  288. CALL DGEMM( 'No transpose', 'Conjugate transpose', P, M-Q, M-Q,
  289. $ ONE, X(1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX )
  290. *
  291. CALL DGEMM( 'Conjugate transpose', 'No transpose', P, M-Q, P,
  292. $ ONE, U1, LDU1, WORK, LDX, ZERO, X(1,Q+1), LDX )
  293. *
  294. DO I = 1, MIN(P,M-Q)-R
  295. X(P-I+1,M-I+1) = X(P-I+1,M-I+1) + ONE
  296. END DO
  297. DO I = 1, R
  298. X(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) =
  299. $ X(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) +
  300. $ SIN(THETA(R-I+1))
  301. END DO
  302. *
  303. CALL DGEMM( 'No transpose', 'Conjugate transpose', M-P, Q, Q, ONE,
  304. $ X(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX )
  305. *
  306. CALL DGEMM( 'Conjugate transpose', 'No transpose', M-P, Q, M-P,
  307. $ ONE, U2, LDU2, WORK, LDX, ZERO, X(P+1,1), LDX )
  308. *
  309. DO I = 1, MIN(M-P,Q)-R
  310. X(M-I+1,Q-I+1) = X(M-I+1,Q-I+1) - ONE
  311. END DO
  312. DO I = 1, R
  313. X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) =
  314. $ X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) -
  315. $ SIN(THETA(R-I+1))
  316. END DO
  317. *
  318. CALL DGEMM( 'No transpose', 'Conjugate transpose', M-P, M-Q, M-Q,
  319. $ ONE, X(P+1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX )
  320. *
  321. CALL DGEMM( 'Conjugate transpose', 'No transpose', M-P, M-Q, M-P,
  322. $ ONE, U2, LDU2, WORK, LDX, ZERO, X(P+1,Q+1), LDX )
  323. *
  324. DO I = 1, MIN(M-P,M-Q)-R
  325. X(P+I,Q+I) = X(P+I,Q+I) - ONE
  326. END DO
  327. DO I = 1, R
  328. X(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) =
  329. $ X(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) -
  330. $ COS(THETA(I))
  331. END DO
  332. *
  333. * Compute norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) .
  334. *
  335. RESID = DLANGE( '1', P, Q, X, LDX, RWORK )
  336. RESULT( 1 ) = ( RESID / DBLE(MAX(1,P,Q)) ) / EPS2
  337. *
  338. * Compute norm( U1'*X12*V2 - D12 ) / ( MAX(1,P,M-Q)*EPS2 ) .
  339. *
  340. RESID = DLANGE( '1', P, M-Q, X(1,Q+1), LDX, RWORK )
  341. RESULT( 2 ) = ( RESID / DBLE(MAX(1,P,M-Q)) ) / EPS2
  342. *
  343. * Compute norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 ) .
  344. *
  345. RESID = DLANGE( '1', M-P, Q, X(P+1,1), LDX, RWORK )
  346. RESULT( 3 ) = ( RESID / DBLE(MAX(1,M-P,Q)) ) / EPS2
  347. *
  348. * Compute norm( U2'*X22*V2 - D22 ) / ( MAX(1,M-P,M-Q)*EPS2 ) .
  349. *
  350. RESID = DLANGE( '1', M-P, M-Q, X(P+1,Q+1), LDX, RWORK )
  351. RESULT( 4 ) = ( RESID / DBLE(MAX(1,M-P,M-Q)) ) / EPS2
  352. *
  353. * Compute I - U1'*U1
  354. *
  355. CALL DLASET( 'Full', P, P, ZERO, ONE, WORK, LDU1 )
  356. CALL DSYRK( 'Upper', 'Conjugate transpose', P, P, -ONE, U1, LDU1,
  357. $ ONE, WORK, LDU1 )
  358. *
  359. * Compute norm( I - U'*U ) / ( MAX(1,P) * ULP ) .
  360. *
  361. RESID = DLANSY( '1', 'Upper', P, WORK, LDU1, RWORK )
  362. RESULT( 5 ) = ( RESID / DBLE(MAX(1,P)) ) / ULP
  363. *
  364. * Compute I - U2'*U2
  365. *
  366. CALL DLASET( 'Full', M-P, M-P, ZERO, ONE, WORK, LDU2 )
  367. CALL DSYRK( 'Upper', 'Conjugate transpose', M-P, M-P, -ONE, U2,
  368. $ LDU2, ONE, WORK, LDU2 )
  369. *
  370. * Compute norm( I - U2'*U2 ) / ( MAX(1,M-P) * ULP ) .
  371. *
  372. RESID = DLANSY( '1', 'Upper', M-P, WORK, LDU2, RWORK )
  373. RESULT( 6 ) = ( RESID / DBLE(MAX(1,M-P)) ) / ULP
  374. *
  375. * Compute I - V1T*V1T'
  376. *
  377. CALL DLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDV1T )
  378. CALL DSYRK( 'Upper', 'No transpose', Q, Q, -ONE, V1T, LDV1T, ONE,
  379. $ WORK, LDV1T )
  380. *
  381. * Compute norm( I - V1T*V1T' ) / ( MAX(1,Q) * ULP ) .
  382. *
  383. RESID = DLANSY( '1', 'Upper', Q, WORK, LDV1T, RWORK )
  384. RESULT( 7 ) = ( RESID / DBLE(MAX(1,Q)) ) / ULP
  385. *
  386. * Compute I - V2T*V2T'
  387. *
  388. CALL DLASET( 'Full', M-Q, M-Q, ZERO, ONE, WORK, LDV2T )
  389. CALL DSYRK( 'Upper', 'No transpose', M-Q, M-Q, -ONE, V2T, LDV2T,
  390. $ ONE, WORK, LDV2T )
  391. *
  392. * Compute norm( I - V2T*V2T' ) / ( MAX(1,M-Q) * ULP ) .
  393. *
  394. RESID = DLANSY( '1', 'Upper', M-Q, WORK, LDV2T, RWORK )
  395. RESULT( 8 ) = ( RESID / DBLE(MAX(1,M-Q)) ) / ULP
  396. *
  397. * Check sorting
  398. *
  399. RESULT(9) = REALZERO
  400. DO I = 1, R
  401. IF( THETA(I).LT.REALZERO .OR. THETA(I).GT.PIOVER2 ) THEN
  402. RESULT(9) = ULPINV
  403. END IF
  404. IF( I.GT.1) THEN
  405. IF ( THETA(I).LT.THETA(I-1) ) THEN
  406. RESULT(9) = ULPINV
  407. END IF
  408. END IF
  409. END DO
  410. *
  411. RETURN
  412. *
  413. * End of DCSDTS
  414. *
  415. END