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.

stsqr01.f 13 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. *> \brief \b STSQR01
  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 STSQR01(TSSW, M,N, MB, NB, RESULT)
  12. *
  13. * .. Scalar Arguments ..
  14. * INTEGER M, N, MB
  15. * .. Return values ..
  16. * REAL RESULT(6)
  17. *
  18. *
  19. *> \par Purpose:
  20. * =============
  21. *>
  22. *> \verbatim
  23. *>
  24. *> DTSQR01 tests DGEQR , DGELQ, DGEMLQ and DGEMQR.
  25. *> \endverbatim
  26. *
  27. * Arguments:
  28. * ==========
  29. *
  30. *> \param[in] TSSW
  31. *> \verbatim
  32. *> TSSW is CHARACTER
  33. *> 'TS' for testing tall skinny QR
  34. *> and anything else for testing short wide LQ
  35. *> \endverbatim
  36. *> \param[in] M
  37. *> \verbatim
  38. *> M is INTEGER
  39. *> Number of rows in test matrix.
  40. *> \endverbatim
  41. *>
  42. *> \param[in] N
  43. *> \verbatim
  44. *> N is INTEGER
  45. *> Number of columns in test matrix.
  46. *> \endverbatim
  47. *> \param[in] MB
  48. *> \verbatim
  49. *> MB is INTEGER
  50. *> Number of row in row block in test matrix.
  51. *> \endverbatim
  52. *>
  53. *> \param[in] NB
  54. *> \verbatim
  55. *> NB is INTEGER
  56. *> Number of columns in column block test matrix.
  57. *> \endverbatim
  58. *>
  59. *> \param[out] RESULT
  60. *> \verbatim
  61. *> RESULT is REAL array, dimension (6)
  62. *> Results of each of the six tests below.
  63. *>
  64. *> RESULT(1) = | A - Q R | or | A - L Q |
  65. *> RESULT(2) = | I - Q^H Q | or | I - Q Q^H |
  66. *> RESULT(3) = | Q C - Q C |
  67. *> RESULT(4) = | Q^H C - Q^H C |
  68. *> RESULT(5) = | C Q - C Q |
  69. *> RESULT(6) = | C Q^H - C Q^H |
  70. *> \endverbatim
  71. *
  72. * Authors:
  73. * ========
  74. *
  75. *> \author Univ. of Tennessee
  76. *> \author Univ. of California Berkeley
  77. *> \author Univ. of Colorado Denver
  78. *> \author NAG Ltd.
  79. *
  80. *> \ingroup double_lin
  81. *
  82. * =====================================================================
  83. SUBROUTINE STSQR01(TSSW, M, N, MB, NB, RESULT)
  84. IMPLICIT NONE
  85. *
  86. * -- LAPACK test routine --
  87. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  88. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  89. *
  90. * .. Scalar Arguments ..
  91. CHARACTER TSSW
  92. INTEGER M, N, MB, NB
  93. * .. Return values ..
  94. REAL RESULT(6)
  95. *
  96. * =====================================================================
  97. *
  98. * ..
  99. * .. Local allocatable arrays
  100. REAL, ALLOCATABLE :: AF(:,:), Q(:,:),
  101. $ R(:,:), RWORK(:), WORK( : ), T(:),
  102. $ CF(:,:), DF(:,:), A(:,:), C(:,:), D(:,:), LQ(:,:)
  103. *
  104. * .. Parameters ..
  105. REAL ONE, ZERO
  106. PARAMETER( ZERO = 0.0, ONE = 1.0 )
  107. * ..
  108. * .. Local Scalars ..
  109. LOGICAL TESTZEROS, TS
  110. INTEGER INFO, J, K, L, LWORK, TSIZE, MNB
  111. REAL ANORM, EPS, RESID, CNORM, DNORM
  112. * ..
  113. * .. Local Arrays ..
  114. INTEGER ISEED( 4 )
  115. REAL TQUERY( 5 ), WORKQUERY( 1 )
  116. * ..
  117. * .. External Functions ..
  118. REAL SLAMCH, SLANGE, SLANSY
  119. LOGICAL LSAME
  120. INTEGER ILAENV
  121. EXTERNAL SLAMCH, SLARNV, SLANGE, SLANSY, LSAME, ILAENV
  122. * ..
  123. * .. Intrinsic Functions ..
  124. INTRINSIC MAX, MIN
  125. * .. Scalars in Common ..
  126. CHARACTER*32 srnamt
  127. * ..
  128. * .. Common blocks ..
  129. COMMON / srnamc / srnamt
  130. * ..
  131. * .. Data statements ..
  132. DATA ISEED / 1988, 1989, 1990, 1991 /
  133. *
  134. * TEST TALL SKINNY OR SHORT WIDE
  135. *
  136. TS = LSAME(TSSW, 'TS')
  137. *
  138. * TEST MATRICES WITH HALF OF MATRIX BEING ZEROS
  139. *
  140. TESTZEROS = .FALSE.
  141. *
  142. EPS = SLAMCH( 'Epsilon' )
  143. K = MIN(M,N)
  144. L = MAX(M,N,1)
  145. MNB = MAX ( MB, NB)
  146. LWORK = MAX(3,L)*MNB
  147. *
  148. * Dynamically allocate local arrays
  149. *
  150. ALLOCATE ( A(M,N), AF(M,N), Q(L,L), R(M,L), RWORK(L),
  151. $ C(M,N), CF(M,N),
  152. $ D(N,M), DF(N,M), LQ(L,N) )
  153. *
  154. * Put random numbers into A and copy to AF
  155. *
  156. DO J=1,N
  157. CALL SLARNV( 2, ISEED, M, A( 1, J ) )
  158. END DO
  159. IF (TESTZEROS) THEN
  160. IF (M.GE.4) THEN
  161. DO J=1,N
  162. CALL SLARNV( 2, ISEED, M/2, A( M/4, J ) )
  163. END DO
  164. END IF
  165. END IF
  166. CALL SLACPY( 'Full', M, N, A, M, AF, M )
  167. *
  168. IF (TS) THEN
  169. *
  170. * Factor the matrix A in the array AF.
  171. *
  172. CALL SGEQR( M, N, AF, M, TQUERY, -1, WORKQUERY, -1, INFO )
  173. TSIZE = INT( TQUERY( 1 ) )
  174. LWORK = INT( WORKQUERY( 1 ) )
  175. CALL SGEMQR( 'L', 'N', M, M, K, AF, M, TQUERY, TSIZE, CF, M,
  176. $ WORKQUERY, -1, INFO)
  177. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  178. CALL SGEMQR( 'L', 'N', M, N, K, AF, M, TQUERY, TSIZE, CF, M,
  179. $ WORKQUERY, -1, INFO)
  180. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  181. CALL SGEMQR( 'L', 'T', M, N, K, AF, M, TQUERY, TSIZE, CF, M,
  182. $ WORKQUERY, -1, INFO)
  183. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  184. CALL SGEMQR( 'R', 'N', N, M, K, AF, M, TQUERY, TSIZE, DF, N,
  185. $ WORKQUERY, -1, INFO)
  186. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  187. CALL SGEMQR( 'R', 'T', N, M, K, AF, M, TQUERY, TSIZE, DF, N,
  188. $ WORKQUERY, -1, INFO)
  189. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  190. ALLOCATE ( T( TSIZE ) )
  191. ALLOCATE ( WORK( LWORK ) )
  192. srnamt = 'SGEQR'
  193. CALL SGEQR( M, N, AF, M, T, TSIZE, WORK, LWORK, INFO )
  194. *
  195. * Generate the m-by-m matrix Q
  196. *
  197. CALL SLASET( 'Full', M, M, ZERO, ONE, Q, M )
  198. srnamt = 'SGEMQR'
  199. CALL SGEMQR( 'L', 'N', M, M, K, AF, M, T, TSIZE, Q, M,
  200. $ WORK, LWORK, INFO )
  201. *
  202. * Copy R
  203. *
  204. CALL SLASET( 'Full', M, N, ZERO, ZERO, R, M )
  205. CALL SLACPY( 'Upper', M, N, AF, M, R, M )
  206. *
  207. * Compute |R - Q'*A| / |A| and store in RESULT(1)
  208. *
  209. CALL SGEMM( 'T', 'N', M, N, M, -ONE, Q, M, A, M, ONE, R, M )
  210. ANORM = SLANGE( '1', M, N, A, M, RWORK )
  211. RESID = SLANGE( '1', M, N, R, M, RWORK )
  212. IF( ANORM.GT.ZERO ) THEN
  213. RESULT( 1 ) = RESID / (EPS*MAX(1,M)*ANORM)
  214. ELSE
  215. RESULT( 1 ) = ZERO
  216. END IF
  217. *
  218. * Compute |I - Q'*Q| and store in RESULT(2)
  219. *
  220. CALL SLASET( 'Full', M, M, ZERO, ONE, R, M )
  221. CALL SSYRK( 'U', 'C', M, M, -ONE, Q, M, ONE, R, M )
  222. RESID = SLANSY( '1', 'Upper', M, R, M, RWORK )
  223. RESULT( 2 ) = RESID / (EPS*MAX(1,M))
  224. *
  225. * Generate random m-by-n matrix C and a copy CF
  226. *
  227. DO J=1,N
  228. CALL SLARNV( 2, ISEED, M, C( 1, J ) )
  229. END DO
  230. CNORM = SLANGE( '1', M, N, C, M, RWORK)
  231. CALL SLACPY( 'Full', M, N, C, M, CF, M )
  232. *
  233. * Apply Q to C as Q*C
  234. *
  235. srnamt = 'DGEQR'
  236. CALL SGEMQR( 'L', 'N', M, N, K, AF, M, T, TSIZE, CF, M,
  237. $ WORK, LWORK, INFO)
  238. *
  239. * Compute |Q*C - Q*C| / |C|
  240. *
  241. CALL SGEMM( 'N', 'N', M, N, M, -ONE, Q, M, C, M, ONE, CF, M )
  242. RESID = SLANGE( '1', M, N, CF, M, RWORK )
  243. IF( CNORM.GT.ZERO ) THEN
  244. RESULT( 3 ) = RESID / (EPS*MAX(1,M)*CNORM)
  245. ELSE
  246. RESULT( 3 ) = ZERO
  247. END IF
  248. *
  249. * Copy C into CF again
  250. *
  251. CALL SLACPY( 'Full', M, N, C, M, CF, M )
  252. *
  253. * Apply Q to C as QT*C
  254. *
  255. srnamt = 'DGEQR'
  256. CALL SGEMQR( 'L', 'T', M, N, K, AF, M, T, TSIZE, CF, M,
  257. $ WORK, LWORK, INFO)
  258. *
  259. * Compute |QT*C - QT*C| / |C|
  260. *
  261. CALL SGEMM( 'T', 'N', M, N, M, -ONE, Q, M, C, M, ONE, CF, M )
  262. RESID = SLANGE( '1', M, N, CF, M, RWORK )
  263. IF( CNORM.GT.ZERO ) THEN
  264. RESULT( 4 ) = RESID / (EPS*MAX(1,M)*CNORM)
  265. ELSE
  266. RESULT( 4 ) = ZERO
  267. END IF
  268. *
  269. * Generate random n-by-m matrix D and a copy DF
  270. *
  271. DO J=1,M
  272. CALL SLARNV( 2, ISEED, N, D( 1, J ) )
  273. END DO
  274. DNORM = SLANGE( '1', N, M, D, N, RWORK)
  275. CALL SLACPY( 'Full', N, M, D, N, DF, N )
  276. *
  277. * Apply Q to D as D*Q
  278. *
  279. srnamt = 'DGEQR'
  280. CALL SGEMQR( 'R', 'N', N, M, K, AF, M, T, TSIZE, DF, N,
  281. $ WORK, LWORK, INFO)
  282. *
  283. * Compute |D*Q - D*Q| / |D|
  284. *
  285. CALL SGEMM( 'N', 'N', N, M, M, -ONE, D, N, Q, M, ONE, DF, N )
  286. RESID = SLANGE( '1', N, M, DF, N, RWORK )
  287. IF( DNORM.GT.ZERO ) THEN
  288. RESULT( 5 ) = RESID / (EPS*MAX(1,M)*DNORM)
  289. ELSE
  290. RESULT( 5 ) = ZERO
  291. END IF
  292. *
  293. * Copy D into DF again
  294. *
  295. CALL SLACPY( 'Full', N, M, D, N, DF, N )
  296. *
  297. * Apply Q to D as D*QT
  298. *
  299. CALL SGEMQR( 'R', 'T', N, M, K, AF, M, T, TSIZE, DF, N,
  300. $ WORK, LWORK, INFO)
  301. *
  302. * Compute |D*QT - D*QT| / |D|
  303. *
  304. CALL SGEMM( 'N', 'T', N, M, M, -ONE, D, N, Q, M, ONE, DF, N )
  305. RESID = SLANGE( '1', N, M, DF, N, RWORK )
  306. IF( CNORM.GT.ZERO ) THEN
  307. RESULT( 6 ) = RESID / (EPS*MAX(1,M)*DNORM)
  308. ELSE
  309. RESULT( 6 ) = ZERO
  310. END IF
  311. *
  312. * Short and wide
  313. *
  314. ELSE
  315. CALL SGELQ( M, N, AF, M, TQUERY, -1, WORKQUERY, -1, INFO )
  316. TSIZE = INT( TQUERY( 1 ) )
  317. LWORK = INT( WORKQUERY( 1 ))
  318. CALL SGEMLQ( 'R', 'N', N, N, K, AF, M, TQUERY, TSIZE, Q, N,
  319. $ WORKQUERY, -1, INFO )
  320. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  321. CALL SGEMLQ( 'L', 'N', N, M, K, AF, M, TQUERY, TSIZE, DF, N,
  322. $ WORKQUERY, -1, INFO)
  323. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  324. CALL SGEMLQ( 'L', 'T', N, M, K, AF, M, TQUERY, TSIZE, DF, N,
  325. $ WORKQUERY, -1, INFO)
  326. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  327. CALL SGEMLQ( 'R', 'N', M, N, K, AF, M, TQUERY, TSIZE, CF, M,
  328. $ WORKQUERY, -1, INFO)
  329. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  330. CALL SGEMLQ( 'R', 'T', M, N, K, AF, M, TQUERY, TSIZE, CF, M,
  331. $ WORKQUERY, -1, INFO)
  332. LWORK = MAX( LWORK, INT( WORKQUERY( 1 ) ) )
  333. ALLOCATE ( T( TSIZE ) )
  334. ALLOCATE ( WORK( LWORK ) )
  335. srnamt = 'SGELQ'
  336. CALL SGELQ( M, N, AF, M, T, TSIZE, WORK, LWORK, INFO )
  337. *
  338. *
  339. * Generate the n-by-n matrix Q
  340. *
  341. CALL SLASET( 'Full', N, N, ZERO, ONE, Q, N )
  342. srnamt = 'SGEMLQ'
  343. CALL SGEMLQ( 'R', 'N', N, N, K, AF, M, T, TSIZE, Q, N,
  344. $ WORK, LWORK, INFO )
  345. *
  346. * Copy R
  347. *
  348. CALL SLASET( 'Full', M, N, ZERO, ZERO, LQ, L )
  349. CALL SLACPY( 'Lower', M, N, AF, M, LQ, L )
  350. *
  351. * Compute |L - A*Q'| / |A| and store in RESULT(1)
  352. *
  353. CALL SGEMM( 'N', 'T', M, N, N, -ONE, A, M, Q, N, ONE, LQ, L )
  354. ANORM = SLANGE( '1', M, N, A, M, RWORK )
  355. RESID = SLANGE( '1', M, N, LQ, L, RWORK )
  356. IF( ANORM.GT.ZERO ) THEN
  357. RESULT( 1 ) = RESID / (EPS*MAX(1,N)*ANORM)
  358. ELSE
  359. RESULT( 1 ) = ZERO
  360. END IF
  361. *
  362. * Compute |I - Q'*Q| and store in RESULT(2)
  363. *
  364. CALL SLASET( 'Full', N, N, ZERO, ONE, LQ, L )
  365. CALL SSYRK( 'U', 'C', N, N, -ONE, Q, N, ONE, LQ, L )
  366. RESID = SLANSY( '1', 'Upper', N, LQ, L, RWORK )
  367. RESULT( 2 ) = RESID / (EPS*MAX(1,N))
  368. *
  369. * Generate random m-by-n matrix C and a copy CF
  370. *
  371. DO J=1,M
  372. CALL SLARNV( 2, ISEED, N, D( 1, J ) )
  373. END DO
  374. DNORM = SLANGE( '1', N, M, D, N, RWORK)
  375. CALL SLACPY( 'Full', N, M, D, N, DF, N )
  376. *
  377. * Apply Q to C as Q*C
  378. *
  379. CALL SGEMLQ( 'L', 'N', N, M, K, AF, M, T, TSIZE, DF, N,
  380. $ WORK, LWORK, INFO)
  381. *
  382. * Compute |Q*D - Q*D| / |D|
  383. *
  384. CALL SGEMM( 'N', 'N', N, M, N, -ONE, Q, N, D, N, ONE, DF, N )
  385. RESID = SLANGE( '1', N, M, DF, N, RWORK )
  386. IF( DNORM.GT.ZERO ) THEN
  387. RESULT( 3 ) = RESID / (EPS*MAX(1,N)*DNORM)
  388. ELSE
  389. RESULT( 3 ) = ZERO
  390. END IF
  391. *
  392. * Copy D into DF again
  393. *
  394. CALL SLACPY( 'Full', N, M, D, N, DF, N )
  395. *
  396. * Apply Q to D as QT*D
  397. *
  398. CALL SGEMLQ( 'L', 'T', N, M, K, AF, M, T, TSIZE, DF, N,
  399. $ WORK, LWORK, INFO)
  400. *
  401. * Compute |QT*D - QT*D| / |D|
  402. *
  403. CALL SGEMM( 'T', 'N', N, M, N, -ONE, Q, N, D, N, ONE, DF, N )
  404. RESID = SLANGE( '1', N, M, DF, N, RWORK )
  405. IF( DNORM.GT.ZERO ) THEN
  406. RESULT( 4 ) = RESID / (EPS*MAX(1,N)*DNORM)
  407. ELSE
  408. RESULT( 4 ) = ZERO
  409. END IF
  410. *
  411. * Generate random n-by-m matrix D and a copy DF
  412. *
  413. DO J=1,N
  414. CALL SLARNV( 2, ISEED, M, C( 1, J ) )
  415. END DO
  416. CNORM = SLANGE( '1', M, N, C, M, RWORK)
  417. CALL SLACPY( 'Full', M, N, C, M, CF, M )
  418. *
  419. * Apply Q to C as C*Q
  420. *
  421. CALL SGEMLQ( 'R', 'N', M, N, K, AF, M, T, TSIZE, CF, M,
  422. $ WORK, LWORK, INFO)
  423. *
  424. * Compute |C*Q - C*Q| / |C|
  425. *
  426. CALL SGEMM( 'N', 'N', M, N, N, -ONE, C, M, Q, N, ONE, CF, M )
  427. RESID = SLANGE( '1', N, M, DF, N, RWORK )
  428. IF( CNORM.GT.ZERO ) THEN
  429. RESULT( 5 ) = RESID / (EPS*MAX(1,N)*CNORM)
  430. ELSE
  431. RESULT( 5 ) = ZERO
  432. END IF
  433. *
  434. * Copy C into CF again
  435. *
  436. CALL SLACPY( 'Full', M, N, C, M, CF, M )
  437. *
  438. * Apply Q to D as D*QT
  439. *
  440. CALL SGEMLQ( 'R', 'T', M, N, K, AF, M, T, TSIZE, CF, M,
  441. $ WORK, LWORK, INFO)
  442. *
  443. * Compute |C*QT - C*QT| / |C|
  444. *
  445. CALL SGEMM( 'N', 'T', M, N, N, -ONE, C, M, Q, N, ONE, CF, M )
  446. RESID = SLANGE( '1', M, N, CF, M, RWORK )
  447. IF( CNORM.GT.ZERO ) THEN
  448. RESULT( 6 ) = RESID / (EPS*MAX(1,N)*CNORM)
  449. ELSE
  450. RESULT( 6 ) = ZERO
  451. END IF
  452. *
  453. END IF
  454. *
  455. * Deallocate all arrays
  456. *
  457. DEALLOCATE ( A, AF, Q, R, RWORK, WORK, T, C, D, CF, DF)
  458. *
  459. RETURN
  460. END