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.

ddrvbd.f 33 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. *> \brief \b DDRVBD
  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 DDRVBD( NSIZES, MM, NN, NTYPES, DOTYPE, ISEED, THRESH,
  12. * A, LDA, U, LDU, VT, LDVT, ASAV, USAV, VTSAV, S,
  13. * SSAV, E, WORK, LWORK, IWORK, NOUT, INFO )
  14. *
  15. * .. Scalar Arguments ..
  16. * INTEGER INFO, LDA, LDU, LDVT, LWORK, NOUT, NSIZES,
  17. * $ NTYPES
  18. * DOUBLE PRECISION THRESH
  19. * ..
  20. * .. Array Arguments ..
  21. * LOGICAL DOTYPE( * )
  22. * INTEGER ISEED( 4 ), IWORK( * ), MM( * ), NN( * )
  23. * DOUBLE PRECISION A( LDA, * ), ASAV( LDA, * ), E( * ), S( * ),
  24. * $ SSAV( * ), U( LDU, * ), USAV( LDU, * ),
  25. * $ VT( LDVT, * ), VTSAV( LDVT, * ), WORK( * )
  26. * ..
  27. *
  28. *
  29. *> \par Purpose:
  30. * =============
  31. *>
  32. *> \verbatim
  33. *>
  34. *> DDRVBD checks the singular value decomposition (SVD) drivers
  35. *> DGESVD, DGESDD, DGESVJ, and DGEJSV.
  36. *>
  37. *> Both DGESVD and DGESDD factor A = U diag(S) VT, where U and VT are
  38. *> orthogonal and diag(S) is diagonal with the entries of the array S
  39. *> on its diagonal. The entries of S are the singular values,
  40. *> nonnegative and stored in decreasing order. U and VT can be
  41. *> optionally not computed, overwritten on A, or computed partially.
  42. *>
  43. *> A is M by N. Let MNMIN = min( M, N ). S has dimension MNMIN.
  44. *> U can be M by M or M by MNMIN. VT can be N by N or MNMIN by N.
  45. *>
  46. *> When DDRVBD is called, a number of matrix "sizes" (M's and N's)
  47. *> and a number of matrix "types" are specified. For each size (M,N)
  48. *> and each type of matrix, and for the minimal workspace as well as
  49. *> workspace adequate to permit blocking, an M x N matrix "A" will be
  50. *> generated and used to test the SVD routines. For each matrix, A will
  51. *> be factored as A = U diag(S) VT and the following 12 tests computed:
  52. *>
  53. *> Test for DGESVD:
  54. *>
  55. *> (1) | A - U diag(S) VT | / ( |A| max(M,N) ulp )
  56. *>
  57. *> (2) | I - U'U | / ( M ulp )
  58. *>
  59. *> (3) | I - VT VT' | / ( N ulp )
  60. *>
  61. *> (4) S contains MNMIN nonnegative values in decreasing order.
  62. *> (Return 0 if true, 1/ULP if false.)
  63. *>
  64. *> (5) | U - Upartial | / ( M ulp ) where Upartial is a partially
  65. *> computed U.
  66. *>
  67. *> (6) | VT - VTpartial | / ( N ulp ) where VTpartial is a partially
  68. *> computed VT.
  69. *>
  70. *> (7) | S - Spartial | / ( MNMIN ulp |S| ) where Spartial is the
  71. *> vector of singular values from the partial SVD
  72. *>
  73. *> Test for DGESDD:
  74. *>
  75. *> (8) | A - U diag(S) VT | / ( |A| max(M,N) ulp )
  76. *>
  77. *> (9) | I - U'U | / ( M ulp )
  78. *>
  79. *> (10) | I - VT VT' | / ( N ulp )
  80. *>
  81. *> (11) S contains MNMIN nonnegative values in decreasing order.
  82. *> (Return 0 if true, 1/ULP if false.)
  83. *>
  84. *> (12) | U - Upartial | / ( M ulp ) where Upartial is a partially
  85. *> computed U.
  86. *>
  87. *> (13) | VT - VTpartial | / ( N ulp ) where VTpartial is a partially
  88. *> computed VT.
  89. *>
  90. *> (14) | S - Spartial | / ( MNMIN ulp |S| ) where Spartial is the
  91. *> vector of singular values from the partial SVD
  92. *>
  93. *> Test for SGESVJ:
  94. *>
  95. *> (15) | A - U diag(S) VT | / ( |A| max(M,N) ulp )
  96. *>
  97. *> (16) | I - U'U | / ( M ulp )
  98. *>
  99. *> (17) | I - VT VT' | / ( N ulp )
  100. *>
  101. *> (18) S contains MNMIN nonnegative values in decreasing order.
  102. *> (Return 0 if true, 1/ULP if false.)
  103. *>
  104. *> Test for SGEJSV:
  105. *>
  106. *> (19) | A - U diag(S) VT | / ( |A| max(M,N) ulp )
  107. *>
  108. *> (20) | I - U'U | / ( M ulp )
  109. *>
  110. *> (21) | I - VT VT' | / ( N ulp )
  111. *>
  112. *> (22) S contains MNMIN nonnegative values in decreasing order.
  113. *> (Return 0 if true, 1/ULP if false.)
  114. *>
  115. *> The "sizes" are specified by the arrays MM(1:NSIZES) and
  116. *> NN(1:NSIZES); the value of each element pair (MM(j),NN(j))
  117. *> specifies one size. The "types" are specified by a logical array
  118. *> DOTYPE( 1:NTYPES ); if DOTYPE(j) is .TRUE., then matrix type "j"
  119. *> will be generated.
  120. *> Currently, the list of possible types is:
  121. *>
  122. *> (1) The zero matrix.
  123. *> (2) The identity matrix.
  124. *> (3) A matrix of the form U D V, where U and V are orthogonal and
  125. *> D has evenly spaced entries 1, ..., ULP with random signs
  126. *> on the diagonal.
  127. *> (4) Same as (3), but multiplied by the underflow-threshold / ULP.
  128. *> (5) Same as (3), but multiplied by the overflow-threshold * ULP.
  129. *> \endverbatim
  130. *
  131. * Arguments:
  132. * ==========
  133. *
  134. *> \param[in] NSIZES
  135. *> \verbatim
  136. *> NSIZES is INTEGER
  137. *> The number of matrix sizes (M,N) contained in the vectors
  138. *> MM and NN.
  139. *> \endverbatim
  140. *>
  141. *> \param[in] MM
  142. *> \verbatim
  143. *> MM is INTEGER array, dimension (NSIZES)
  144. *> The values of the matrix row dimension M.
  145. *> \endverbatim
  146. *>
  147. *> \param[in] NN
  148. *> \verbatim
  149. *> NN is INTEGER array, dimension (NSIZES)
  150. *> The values of the matrix column dimension N.
  151. *> \endverbatim
  152. *>
  153. *> \param[in] NTYPES
  154. *> \verbatim
  155. *> NTYPES is INTEGER
  156. *> The number of elements in DOTYPE. If it is zero, DDRVBD
  157. *> does nothing. It must be at least zero. If it is MAXTYP+1
  158. *> and NSIZES is 1, then an additional type, MAXTYP+1 is
  159. *> defined, which is to use whatever matrices are in A and B.
  160. *> This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and
  161. *> DOTYPE(MAXTYP+1) is .TRUE. .
  162. *> \endverbatim
  163. *>
  164. *> \param[in] DOTYPE
  165. *> \verbatim
  166. *> DOTYPE is LOGICAL array, dimension (NTYPES)
  167. *> If DOTYPE(j) is .TRUE., then for each size (m,n), a matrix
  168. *> of type j will be generated. If NTYPES is smaller than the
  169. *> maximum number of types defined (PARAMETER MAXTYP), then
  170. *> types NTYPES+1 through MAXTYP will not be generated. If
  171. *> NTYPES is larger than MAXTYP, DOTYPE(MAXTYP+1) through
  172. *> DOTYPE(NTYPES) will be ignored.
  173. *> \endverbatim
  174. *>
  175. *> \param[in,out] ISEED
  176. *> \verbatim
  177. *> ISEED is INTEGER array, dimension (4)
  178. *> On entry, the seed of the random number generator. The array
  179. *> elements should be between 0 and 4095; if not they will be
  180. *> reduced mod 4096. Also, ISEED(4) must be odd.
  181. *> On exit, ISEED is changed and can be used in the next call to
  182. *> DDRVBD to continue the same random number sequence.
  183. *> \endverbatim
  184. *>
  185. *> \param[in] THRESH
  186. *> \verbatim
  187. *> THRESH is DOUBLE PRECISION
  188. *> The threshold value for the test ratios. A result is
  189. *> included in the output file if RESULT >= THRESH. The test
  190. *> ratios are scaled to be O(1), so THRESH should be a small
  191. *> multiple of 1, e.g., 10 or 100. To have every test ratio
  192. *> printed, use THRESH = 0.
  193. *> \endverbatim
  194. *>
  195. *> \param[out] A
  196. *> \verbatim
  197. *> A is DOUBLE PRECISION array, dimension (LDA,NMAX)
  198. *> where NMAX is the maximum value of N in NN.
  199. *> \endverbatim
  200. *>
  201. *> \param[in] LDA
  202. *> \verbatim
  203. *> LDA is INTEGER
  204. *> The leading dimension of the array A. LDA >= max(1,MMAX),
  205. *> where MMAX is the maximum value of M in MM.
  206. *> \endverbatim
  207. *>
  208. *> \param[out] U
  209. *> \verbatim
  210. *> U is DOUBLE PRECISION array, dimension (LDU,MMAX)
  211. *> \endverbatim
  212. *>
  213. *> \param[in] LDU
  214. *> \verbatim
  215. *> LDU is INTEGER
  216. *> The leading dimension of the array U. LDU >= max(1,MMAX).
  217. *> \endverbatim
  218. *>
  219. *> \param[out] VT
  220. *> \verbatim
  221. *> VT is DOUBLE PRECISION array, dimension (LDVT,NMAX)
  222. *> \endverbatim
  223. *>
  224. *> \param[in] LDVT
  225. *> \verbatim
  226. *> LDVT is INTEGER
  227. *> The leading dimension of the array VT. LDVT >= max(1,NMAX).
  228. *> \endverbatim
  229. *>
  230. *> \param[out] ASAV
  231. *> \verbatim
  232. *> ASAV is DOUBLE PRECISION array, dimension (LDA,NMAX)
  233. *> \endverbatim
  234. *>
  235. *> \param[out] USAV
  236. *> \verbatim
  237. *> USAV is DOUBLE PRECISION array, dimension (LDU,MMAX)
  238. *> \endverbatim
  239. *>
  240. *> \param[out] VTSAV
  241. *> \verbatim
  242. *> VTSAV is DOUBLE PRECISION array, dimension (LDVT,NMAX)
  243. *> \endverbatim
  244. *>
  245. *> \param[out] S
  246. *> \verbatim
  247. *> S is DOUBLE PRECISION array, dimension
  248. *> (max(min(MM,NN)))
  249. *> \endverbatim
  250. *>
  251. *> \param[out] SSAV
  252. *> \verbatim
  253. *> SSAV is DOUBLE PRECISION array, dimension
  254. *> (max(min(MM,NN)))
  255. *> \endverbatim
  256. *>
  257. *> \param[out] E
  258. *> \verbatim
  259. *> E is DOUBLE PRECISION array, dimension
  260. *> (max(min(MM,NN)))
  261. *> \endverbatim
  262. *>
  263. *> \param[out] WORK
  264. *> \verbatim
  265. *> WORK is DOUBLE PRECISION array, dimension (LWORK)
  266. *> \endverbatim
  267. *>
  268. *> \param[in] LWORK
  269. *> \verbatim
  270. *> LWORK is INTEGER
  271. *> The number of entries in WORK. This must be at least
  272. *> max(3*MN+MX,5*MN-4)+2*MN**2 for all pairs
  273. *> pairs (MN,MX)=( min(MM(j),NN(j), max(MM(j),NN(j)) )
  274. *> \endverbatim
  275. *>
  276. *> \param[out] IWORK
  277. *> \verbatim
  278. *> IWORK is INTEGER array, dimension at least 8*min(M,N)
  279. *> \endverbatim
  280. *>
  281. *> \param[in] NOUT
  282. *> \verbatim
  283. *> NOUT is INTEGER
  284. *> The FORTRAN unit number for printing out error messages
  285. *> (e.g., if a routine returns IINFO not equal to 0.)
  286. *> \endverbatim
  287. *>
  288. *> \param[out] INFO
  289. *> \verbatim
  290. *> INFO is INTEGER
  291. *> If 0, then everything ran OK.
  292. *> -1: NSIZES < 0
  293. *> -2: Some MM(j) < 0
  294. *> -3: Some NN(j) < 0
  295. *> -4: NTYPES < 0
  296. *> -7: THRESH < 0
  297. *> -10: LDA < 1 or LDA < MMAX, where MMAX is max( MM(j) ).
  298. *> -12: LDU < 1 or LDU < MMAX.
  299. *> -14: LDVT < 1 or LDVT < NMAX, where NMAX is max( NN(j) ).
  300. *> -21: LWORK too small.
  301. *> If DLATMS, or DGESVD returns an error code, the
  302. *> absolute value of it is returned.
  303. *> \endverbatim
  304. *
  305. * Authors:
  306. * ========
  307. *
  308. *> \author Univ. of Tennessee
  309. *> \author Univ. of California Berkeley
  310. *> \author Univ. of Colorado Denver
  311. *> \author NAG Ltd.
  312. *
  313. *> \date November 2011
  314. *
  315. *> \ingroup double_eig
  316. *
  317. * =====================================================================
  318. SUBROUTINE DDRVBD( NSIZES, MM, NN, NTYPES, DOTYPE, ISEED, THRESH,
  319. $ A, LDA, U, LDU, VT, LDVT, ASAV, USAV, VTSAV, S,
  320. $ SSAV, E, WORK, LWORK, IWORK, NOUT, INFO )
  321. *
  322. * -- LAPACK test routine (version 3.4.0) --
  323. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  324. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  325. * November 2011
  326. *
  327. * .. Scalar Arguments ..
  328. INTEGER INFO, LDA, LDU, LDVT, LWORK, NOUT, NSIZES,
  329. $ NTYPES
  330. DOUBLE PRECISION THRESH
  331. * ..
  332. * .. Array Arguments ..
  333. LOGICAL DOTYPE( * )
  334. INTEGER ISEED( 4 ), IWORK( * ), MM( * ), NN( * )
  335. DOUBLE PRECISION A( LDA, * ), ASAV( LDA, * ), E( * ), S( * ),
  336. $ SSAV( * ), U( LDU, * ), USAV( LDU, * ),
  337. $ VT( LDVT, * ), VTSAV( LDVT, * ), WORK( * )
  338. * ..
  339. *
  340. * =====================================================================
  341. *
  342. * .. Parameters ..
  343. DOUBLE PRECISION ZERO, ONE
  344. PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
  345. INTEGER MAXTYP
  346. PARAMETER ( MAXTYP = 5 )
  347. * ..
  348. * .. Local Scalars ..
  349. LOGICAL BADMM, BADNN
  350. CHARACTER JOBQ, JOBU, JOBVT
  351. CHARACTER*3 PATH
  352. INTEGER I, IINFO, IJQ, IJU, IJVT, IWS, IWTMP, J, JSIZE,
  353. $ JTYPE, LSWORK, M, MINWRK, MMAX, MNMAX, MNMIN,
  354. $ MTYPES, N, NFAIL, NMAX, NTEST
  355. DOUBLE PRECISION ANORM, DIF, DIV, OVFL, ULP, ULPINV, UNFL
  356. * ..
  357. * .. Local Arrays ..
  358. CHARACTER CJOB( 4 )
  359. INTEGER IOLDSD( 4 )
  360. DOUBLE PRECISION RESULT( 22 )
  361. * ..
  362. * .. External Functions ..
  363. DOUBLE PRECISION DLAMCH
  364. EXTERNAL DLAMCH
  365. * ..
  366. * .. External Subroutines ..
  367. EXTERNAL ALASVM, DBDT01, DGESDD, DGESVD, DLABAD, DLACPY,
  368. $ DLASET, DLATMS, DORT01, DORT03, XERBLA, DGESVJ,
  369. $ DGEJSV
  370. * ..
  371. * .. Intrinsic Functions ..
  372. INTRINSIC ABS, DBLE, MAX, MIN
  373. * ..
  374. * .. Scalars in Common ..
  375. LOGICAL LERR, OK
  376. CHARACTER*32 SRNAMT
  377. INTEGER INFOT, NUNIT
  378. * ..
  379. * .. Common blocks ..
  380. COMMON / INFOC / INFOT, NUNIT, OK, LERR
  381. COMMON / SRNAMC / SRNAMT
  382. * ..
  383. * .. Data statements ..
  384. DATA CJOB / 'N', 'O', 'S', 'A' /
  385. * ..
  386. * .. Executable Statements ..
  387. *
  388. * Check for errors
  389. *
  390. INFO = 0
  391. BADMM = .FALSE.
  392. BADNN = .FALSE.
  393. MMAX = 1
  394. NMAX = 1
  395. MNMAX = 1
  396. MINWRK = 1
  397. DO 10 J = 1, NSIZES
  398. MMAX = MAX( MMAX, MM( J ) )
  399. IF( MM( J ).LT.0 )
  400. $ BADMM = .TRUE.
  401. NMAX = MAX( NMAX, NN( J ) )
  402. IF( NN( J ).LT.0 )
  403. $ BADNN = .TRUE.
  404. MNMAX = MAX( MNMAX, MIN( MM( J ), NN( J ) ) )
  405. MINWRK = MAX( MINWRK, MAX( 3*MIN( MM( J ),
  406. $ NN( J ) )+MAX( MM( J ), NN( J ) ), 5*MIN( MM( J ),
  407. $ NN( J )-4 ) )+2*MIN( MM( J ), NN( J ) )**2 )
  408. 10 CONTINUE
  409. *
  410. * Check for errors
  411. *
  412. IF( NSIZES.LT.0 ) THEN
  413. INFO = -1
  414. ELSE IF( BADMM ) THEN
  415. INFO = -2
  416. ELSE IF( BADNN ) THEN
  417. INFO = -3
  418. ELSE IF( NTYPES.LT.0 ) THEN
  419. INFO = -4
  420. ELSE IF( LDA.LT.MAX( 1, MMAX ) ) THEN
  421. INFO = -10
  422. ELSE IF( LDU.LT.MAX( 1, MMAX ) ) THEN
  423. INFO = -12
  424. ELSE IF( LDVT.LT.MAX( 1, NMAX ) ) THEN
  425. INFO = -14
  426. ELSE IF( MINWRK.GT.LWORK ) THEN
  427. INFO = -21
  428. END IF
  429. *
  430. IF( INFO.NE.0 ) THEN
  431. CALL XERBLA( 'DDRVBD', -INFO )
  432. RETURN
  433. END IF
  434. *
  435. * Initialize constants
  436. *
  437. PATH( 1: 1 ) = 'Double precision'
  438. PATH( 2: 3 ) = 'BD'
  439. NFAIL = 0
  440. NTEST = 0
  441. UNFL = DLAMCH( 'Safe minimum' )
  442. OVFL = ONE / UNFL
  443. CALL DLABAD( UNFL, OVFL )
  444. ULP = DLAMCH( 'Precision' )
  445. ULPINV = ONE / ULP
  446. INFOT = 0
  447. *
  448. * Loop over sizes, types
  449. *
  450. DO 150 JSIZE = 1, NSIZES
  451. M = MM( JSIZE )
  452. N = NN( JSIZE )
  453. MNMIN = MIN( M, N )
  454. *
  455. IF( NSIZES.NE.1 ) THEN
  456. MTYPES = MIN( MAXTYP, NTYPES )
  457. ELSE
  458. MTYPES = MIN( MAXTYP+1, NTYPES )
  459. END IF
  460. *
  461. DO 140 JTYPE = 1, MTYPES
  462. IF( .NOT.DOTYPE( JTYPE ) )
  463. $ GO TO 140
  464. *
  465. DO 20 J = 1, 4
  466. IOLDSD( J ) = ISEED( J )
  467. 20 CONTINUE
  468. *
  469. * Compute "A"
  470. *
  471. IF( MTYPES.GT.MAXTYP )
  472. $ GO TO 30
  473. *
  474. IF( JTYPE.EQ.1 ) THEN
  475. *
  476. * Zero matrix
  477. *
  478. CALL DLASET( 'Full', M, N, ZERO, ZERO, A, LDA )
  479. *
  480. ELSE IF( JTYPE.EQ.2 ) THEN
  481. *
  482. * Identity matrix
  483. *
  484. CALL DLASET( 'Full', M, N, ZERO, ONE, A, LDA )
  485. *
  486. ELSE
  487. *
  488. * (Scaled) random matrix
  489. *
  490. IF( JTYPE.EQ.3 )
  491. $ ANORM = ONE
  492. IF( JTYPE.EQ.4 )
  493. $ ANORM = UNFL / ULP
  494. IF( JTYPE.EQ.5 )
  495. $ ANORM = OVFL*ULP
  496. CALL DLATMS( M, N, 'U', ISEED, 'N', S, 4, DBLE( MNMIN ),
  497. $ ANORM, M-1, N-1, 'N', A, LDA, WORK, IINFO )
  498. IF( IINFO.NE.0 ) THEN
  499. WRITE( NOUT, FMT = 9996 )'Generator', IINFO, M, N,
  500. $ JTYPE, IOLDSD
  501. INFO = ABS( IINFO )
  502. RETURN
  503. END IF
  504. END IF
  505. *
  506. 30 CONTINUE
  507. CALL DLACPY( 'F', M, N, A, LDA, ASAV, LDA )
  508. *
  509. * Do for minimal and adequate (for blocking) workspace
  510. *
  511. DO 130 IWS = 1, 4
  512. *
  513. DO 40 J = 1, 14
  514. RESULT( J ) = -ONE
  515. 40 CONTINUE
  516. *
  517. * Test DGESVD: Factorize A
  518. *
  519. IWTMP = MAX( 3*MIN( M, N )+MAX( M, N ), 5*MIN( M, N ) )
  520. LSWORK = IWTMP + ( IWS-1 )*( LWORK-IWTMP ) / 3
  521. LSWORK = MIN( LSWORK, LWORK )
  522. LSWORK = MAX( LSWORK, 1 )
  523. IF( IWS.EQ.4 )
  524. $ LSWORK = LWORK
  525. *
  526. IF( IWS.GT.1 )
  527. $ CALL DLACPY( 'F', M, N, ASAV, LDA, A, LDA )
  528. SRNAMT = 'DGESVD'
  529. CALL DGESVD( 'A', 'A', M, N, A, LDA, SSAV, USAV, LDU,
  530. $ VTSAV, LDVT, WORK, LSWORK, IINFO )
  531. IF( IINFO.NE.0 ) THEN
  532. WRITE( NOUT, FMT = 9995 )'GESVD', IINFO, M, N, JTYPE,
  533. $ LSWORK, IOLDSD
  534. INFO = ABS( IINFO )
  535. RETURN
  536. END IF
  537. *
  538. * Do tests 1--4
  539. *
  540. CALL DBDT01( M, N, 0, ASAV, LDA, USAV, LDU, SSAV, E,
  541. $ VTSAV, LDVT, WORK, RESULT( 1 ) )
  542. IF( M.NE.0 .AND. N.NE.0 ) THEN
  543. CALL DORT01( 'Columns', M, M, USAV, LDU, WORK, LWORK,
  544. $ RESULT( 2 ) )
  545. CALL DORT01( 'Rows', N, N, VTSAV, LDVT, WORK, LWORK,
  546. $ RESULT( 3 ) )
  547. END IF
  548. RESULT( 4 ) = ZERO
  549. DO 50 I = 1, MNMIN - 1
  550. IF( SSAV( I ).LT.SSAV( I+1 ) )
  551. $ RESULT( 4 ) = ULPINV
  552. IF( SSAV( I ).LT.ZERO )
  553. $ RESULT( 4 ) = ULPINV
  554. 50 CONTINUE
  555. IF( MNMIN.GE.1 ) THEN
  556. IF( SSAV( MNMIN ).LT.ZERO )
  557. $ RESULT( 4 ) = ULPINV
  558. END IF
  559. *
  560. * Do partial SVDs, comparing to SSAV, USAV, and VTSAV
  561. *
  562. RESULT( 5 ) = ZERO
  563. RESULT( 6 ) = ZERO
  564. RESULT( 7 ) = ZERO
  565. DO 80 IJU = 0, 3
  566. DO 70 IJVT = 0, 3
  567. IF( ( IJU.EQ.3 .AND. IJVT.EQ.3 ) .OR.
  568. $ ( IJU.EQ.1 .AND. IJVT.EQ.1 ) )GO TO 70
  569. JOBU = CJOB( IJU+1 )
  570. JOBVT = CJOB( IJVT+1 )
  571. CALL DLACPY( 'F', M, N, ASAV, LDA, A, LDA )
  572. SRNAMT = 'DGESVD'
  573. CALL DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU,
  574. $ VT, LDVT, WORK, LSWORK, IINFO )
  575. *
  576. * Compare U
  577. *
  578. DIF = ZERO
  579. IF( M.GT.0 .AND. N.GT.0 ) THEN
  580. IF( IJU.EQ.1 ) THEN
  581. CALL DORT03( 'C', M, MNMIN, M, MNMIN, USAV,
  582. $ LDU, A, LDA, WORK, LWORK, DIF,
  583. $ IINFO )
  584. ELSE IF( IJU.EQ.2 ) THEN
  585. CALL DORT03( 'C', M, MNMIN, M, MNMIN, USAV,
  586. $ LDU, U, LDU, WORK, LWORK, DIF,
  587. $ IINFO )
  588. ELSE IF( IJU.EQ.3 ) THEN
  589. CALL DORT03( 'C', M, M, M, MNMIN, USAV, LDU,
  590. $ U, LDU, WORK, LWORK, DIF,
  591. $ IINFO )
  592. END IF
  593. END IF
  594. RESULT( 5 ) = MAX( RESULT( 5 ), DIF )
  595. *
  596. * Compare VT
  597. *
  598. DIF = ZERO
  599. IF( M.GT.0 .AND. N.GT.0 ) THEN
  600. IF( IJVT.EQ.1 ) THEN
  601. CALL DORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
  602. $ LDVT, A, LDA, WORK, LWORK, DIF,
  603. $ IINFO )
  604. ELSE IF( IJVT.EQ.2 ) THEN
  605. CALL DORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
  606. $ LDVT, VT, LDVT, WORK, LWORK,
  607. $ DIF, IINFO )
  608. ELSE IF( IJVT.EQ.3 ) THEN
  609. CALL DORT03( 'R', N, N, N, MNMIN, VTSAV,
  610. $ LDVT, VT, LDVT, WORK, LWORK,
  611. $ DIF, IINFO )
  612. END IF
  613. END IF
  614. RESULT( 6 ) = MAX( RESULT( 6 ), DIF )
  615. *
  616. * Compare S
  617. *
  618. DIF = ZERO
  619. DIV = MAX( DBLE( MNMIN )*ULP*S( 1 ), UNFL )
  620. DO 60 I = 1, MNMIN - 1
  621. IF( SSAV( I ).LT.SSAV( I+1 ) )
  622. $ DIF = ULPINV
  623. IF( SSAV( I ).LT.ZERO )
  624. $ DIF = ULPINV
  625. DIF = MAX( DIF, ABS( SSAV( I )-S( I ) ) / DIV )
  626. 60 CONTINUE
  627. RESULT( 7 ) = MAX( RESULT( 7 ), DIF )
  628. 70 CONTINUE
  629. 80 CONTINUE
  630. *
  631. * Test DGESDD: Factorize A
  632. *
  633. IWTMP = 5*MNMIN*MNMIN + 9*MNMIN + MAX( M, N )
  634. LSWORK = IWTMP + ( IWS-1 )*( LWORK-IWTMP ) / 3
  635. LSWORK = MIN( LSWORK, LWORK )
  636. LSWORK = MAX( LSWORK, 1 )
  637. IF( IWS.EQ.4 )
  638. $ LSWORK = LWORK
  639. *
  640. CALL DLACPY( 'F', M, N, ASAV, LDA, A, LDA )
  641. SRNAMT = 'DGESDD'
  642. CALL DGESDD( 'A', M, N, A, LDA, SSAV, USAV, LDU, VTSAV,
  643. $ LDVT, WORK, LSWORK, IWORK, IINFO )
  644. IF( IINFO.NE.0 ) THEN
  645. WRITE( NOUT, FMT = 9995 )'GESDD', IINFO, M, N, JTYPE,
  646. $ LSWORK, IOLDSD
  647. INFO = ABS( IINFO )
  648. RETURN
  649. END IF
  650. *
  651. * Do tests 8--11
  652. *
  653. CALL DBDT01( M, N, 0, ASAV, LDA, USAV, LDU, SSAV, E,
  654. $ VTSAV, LDVT, WORK, RESULT( 8 ) )
  655. IF( M.NE.0 .AND. N.NE.0 ) THEN
  656. CALL DORT01( 'Columns', M, M, USAV, LDU, WORK, LWORK,
  657. $ RESULT( 9 ) )
  658. CALL DORT01( 'Rows', N, N, VTSAV, LDVT, WORK, LWORK,
  659. $ RESULT( 10 ) )
  660. END IF
  661. RESULT( 11 ) = ZERO
  662. DO 90 I = 1, MNMIN - 1
  663. IF( SSAV( I ).LT.SSAV( I+1 ) )
  664. $ RESULT( 11 ) = ULPINV
  665. IF( SSAV( I ).LT.ZERO )
  666. $ RESULT( 11 ) = ULPINV
  667. 90 CONTINUE
  668. IF( MNMIN.GE.1 ) THEN
  669. IF( SSAV( MNMIN ).LT.ZERO )
  670. $ RESULT( 11 ) = ULPINV
  671. END IF
  672. *
  673. * Do partial SVDs, comparing to SSAV, USAV, and VTSAV
  674. *
  675. RESULT( 12 ) = ZERO
  676. RESULT( 13 ) = ZERO
  677. RESULT( 14 ) = ZERO
  678. DO 110 IJQ = 0, 2
  679. JOBQ = CJOB( IJQ+1 )
  680. CALL DLACPY( 'F', M, N, ASAV, LDA, A, LDA )
  681. SRNAMT = 'DGESDD'
  682. CALL DGESDD( JOBQ, M, N, A, LDA, S, U, LDU, VT, LDVT,
  683. $ WORK, LSWORK, IWORK, IINFO )
  684. *
  685. * Compare U
  686. *
  687. DIF = ZERO
  688. IF( M.GT.0 .AND. N.GT.0 ) THEN
  689. IF( IJQ.EQ.1 ) THEN
  690. IF( M.GE.N ) THEN
  691. CALL DORT03( 'C', M, MNMIN, M, MNMIN, USAV,
  692. $ LDU, A, LDA, WORK, LWORK, DIF,
  693. $ INFO )
  694. ELSE
  695. CALL DORT03( 'C', M, MNMIN, M, MNMIN, USAV,
  696. $ LDU, U, LDU, WORK, LWORK, DIF,
  697. $ INFO )
  698. END IF
  699. ELSE IF( IJQ.EQ.2 ) THEN
  700. CALL DORT03( 'C', M, MNMIN, M, MNMIN, USAV, LDU,
  701. $ U, LDU, WORK, LWORK, DIF, INFO )
  702. END IF
  703. END IF
  704. RESULT( 12 ) = MAX( RESULT( 12 ), DIF )
  705. *
  706. * Compare VT
  707. *
  708. DIF = ZERO
  709. IF( M.GT.0 .AND. N.GT.0 ) THEN
  710. IF( IJQ.EQ.1 ) THEN
  711. IF( M.GE.N ) THEN
  712. CALL DORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
  713. $ LDVT, VT, LDVT, WORK, LWORK,
  714. $ DIF, INFO )
  715. ELSE
  716. CALL DORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
  717. $ LDVT, A, LDA, WORK, LWORK, DIF,
  718. $ INFO )
  719. END IF
  720. ELSE IF( IJQ.EQ.2 ) THEN
  721. CALL DORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
  722. $ LDVT, VT, LDVT, WORK, LWORK, DIF,
  723. $ INFO )
  724. END IF
  725. END IF
  726. RESULT( 13 ) = MAX( RESULT( 13 ), DIF )
  727. *
  728. * Compare S
  729. *
  730. DIF = ZERO
  731. DIV = MAX( DBLE( MNMIN )*ULP*S( 1 ), UNFL )
  732. DO 100 I = 1, MNMIN - 1
  733. IF( SSAV( I ).LT.SSAV( I+1 ) )
  734. $ DIF = ULPINV
  735. IF( SSAV( I ).LT.ZERO )
  736. $ DIF = ULPINV
  737. DIF = MAX( DIF, ABS( SSAV( I )-S( I ) ) / DIV )
  738. 100 CONTINUE
  739. RESULT( 14 ) = MAX( RESULT( 14 ), DIF )
  740. 110 CONTINUE
  741. *
  742. * Test DGESVJ: Factorize A
  743. * Note: DGESVJ does not work for M < N
  744. *
  745. RESULT( 15 ) = ZERO
  746. RESULT( 16 ) = ZERO
  747. RESULT( 17 ) = ZERO
  748. RESULT( 18 ) = ZERO
  749. *
  750. IF( M.GE.N ) THEN
  751. IWTMP = 5*MNMIN*MNMIN + 9*MNMIN + MAX( M, N )
  752. LSWORK = IWTMP + ( IWS-1 )*( LWORK-IWTMP ) / 3
  753. LSWORK = MIN( LSWORK, LWORK )
  754. LSWORK = MAX( LSWORK, 1 )
  755. IF( IWS.EQ.4 )
  756. $ LSWORK = LWORK
  757. *
  758. CALL DLACPY( 'F', M, N, ASAV, LDA, USAV, LDA )
  759. SRNAMT = 'DGESVJ'
  760. CALL DGESVJ( 'G', 'U', 'V', M, N, USAV, LDA, SSAV,
  761. & 0, A, LDVT, WORK, LWORK, INFO )
  762. *
  763. * DGESVJ retuns V not VT, so we transpose to use the same
  764. * test suite.
  765. *
  766. DO J=1,N
  767. DO I=1,N
  768. VTSAV(J,I) = A(I,J)
  769. END DO
  770. END DO
  771. *
  772. IF( IINFO.NE.0 ) THEN
  773. WRITE( NOUT, FMT = 9995 )'GESVJ', IINFO, M, N,
  774. $ JTYPE, LSWORK, IOLDSD
  775. INFO = ABS( IINFO )
  776. RETURN
  777. END IF
  778. *
  779. * Do tests 15--18
  780. *
  781. CALL DBDT01( M, N, 0, ASAV, LDA, USAV, LDU, SSAV, E,
  782. $ VTSAV, LDVT, WORK, RESULT( 15 ) )
  783. IF( M.NE.0 .AND. N.NE.0 ) THEN
  784. CALL DORT01( 'Columns', M, M, USAV, LDU, WORK,
  785. $ LWORK, RESULT( 16 ) )
  786. CALL DORT01( 'Rows', N, N, VTSAV, LDVT, WORK,
  787. $ LWORK, RESULT( 17 ) )
  788. END IF
  789. RESULT( 18 ) = ZERO
  790. DO 200 I = 1, MNMIN - 1
  791. IF( SSAV( I ).LT.SSAV( I+1 ) )
  792. $ RESULT( 18 ) = ULPINV
  793. IF( SSAV( I ).LT.ZERO )
  794. $ RESULT( 18 ) = ULPINV
  795. 200 CONTINUE
  796. IF( MNMIN.GE.1 ) THEN
  797. IF( SSAV( MNMIN ).LT.ZERO )
  798. $ RESULT( 18 ) = ULPINV
  799. END IF
  800. END IF
  801. *
  802. * Test DGEJSV: Factorize A
  803. * Note: DGEJSV does not work for M < N
  804. *
  805. RESULT( 19 ) = ZERO
  806. RESULT( 20 ) = ZERO
  807. RESULT( 21 ) = ZERO
  808. RESULT( 22 ) = ZERO
  809. IF( M.GE.N ) THEN
  810. IWTMP = 5*MNMIN*MNMIN + 9*MNMIN + MAX( M, N )
  811. LSWORK = IWTMP + ( IWS-1 )*( LWORK-IWTMP ) / 3
  812. LSWORK = MIN( LSWORK, LWORK )
  813. LSWORK = MAX( LSWORK, 1 )
  814. IF( IWS.EQ.4 )
  815. $ LSWORK = LWORK
  816. *
  817. CALL DLACPY( 'F', M, N, ASAV, LDA, VTSAV, LDA )
  818. SRNAMT = 'DGEJSV'
  819. CALL DGEJSV( 'G', 'U', 'V', 'R', 'N', 'N',
  820. & M, N, VTSAV, LDA, SSAV, USAV, LDU, A, LDVT,
  821. & WORK, LWORK, IWORK, INFO )
  822. *
  823. * DGEJSV retuns V not VT, so we transpose to use the same
  824. * test suite.
  825. *
  826. DO J=1,N
  827. DO I=1,N
  828. VTSAV(J,I) = A(I,J)
  829. END DO
  830. END DO
  831. *
  832. IF( IINFO.NE.0 ) THEN
  833. WRITE( NOUT, FMT = 9995 )'GESVJ', IINFO, M, N,
  834. $ JTYPE, LSWORK, IOLDSD
  835. INFO = ABS( IINFO )
  836. RETURN
  837. END IF
  838. *
  839. * Do tests 19--22
  840. *
  841. CALL DBDT01( M, N, 0, ASAV, LDA, USAV, LDU, SSAV, E,
  842. $ VTSAV, LDVT, WORK, RESULT( 19 ) )
  843. IF( M.NE.0 .AND. N.NE.0 ) THEN
  844. CALL DORT01( 'Columns', M, M, USAV, LDU, WORK,
  845. $ LWORK, RESULT( 20 ) )
  846. CALL DORT01( 'Rows', N, N, VTSAV, LDVT, WORK,
  847. $ LWORK, RESULT( 21 ) )
  848. END IF
  849. RESULT( 22 ) = ZERO
  850. DO 300 I = 1, MNMIN - 1
  851. IF( SSAV( I ).LT.SSAV( I+1 ) )
  852. $ RESULT( 22 ) = ULPINV
  853. IF( SSAV( I ).LT.ZERO )
  854. $ RESULT( 22 ) = ULPINV
  855. 300 CONTINUE
  856. IF( MNMIN.GE.1 ) THEN
  857. IF( SSAV( MNMIN ).LT.ZERO )
  858. $ RESULT( 22 ) = ULPINV
  859. END IF
  860. END IF
  861. *
  862. * End of Loop -- Check for RESULT(j) > THRESH
  863. *
  864. DO 120 J = 1, 22
  865. IF( RESULT( J ).GE.THRESH ) THEN
  866. IF( NFAIL.EQ.0 ) THEN
  867. WRITE( NOUT, FMT = 9999 )
  868. WRITE( NOUT, FMT = 9998 )
  869. END IF
  870. WRITE( NOUT, FMT = 9997 )M, N, JTYPE, IWS, IOLDSD,
  871. $ J, RESULT( J )
  872. NFAIL = NFAIL + 1
  873. END IF
  874. 120 CONTINUE
  875. NTEST = NTEST + 22
  876. *
  877. 130 CONTINUE
  878. 140 CONTINUE
  879. 150 CONTINUE
  880. *
  881. * Summary
  882. *
  883. CALL ALASVM( PATH, NOUT, NFAIL, NTEST, 0 )
  884. *
  885. 9999 FORMAT( ' SVD -- Real Singular Value Decomposition Driver ',
  886. $ / ' Matrix types (see DDRVBD for details):',
  887. $ / / ' 1 = Zero matrix', / ' 2 = Identity matrix',
  888. $ / ' 3 = Evenly spaced singular values near 1',
  889. $ / ' 4 = Evenly spaced singular values near underflow',
  890. $ / ' 5 = Evenly spaced singular values near overflow', / /
  891. $ ' Tests performed: ( A is dense, U and V are orthogonal,',
  892. $ / 19X, ' S is an array, and Upartial, VTpartial, and',
  893. $ / 19X, ' Spartial are partially computed U, VT and S),', / )
  894. 9998 FORMAT( ' 1 = | A - U diag(S) VT | / ( |A| max(M,N) ulp ) ',
  895. $ / ' 2 = | I - U**T U | / ( M ulp ) ',
  896. $ / ' 3 = | I - VT VT**T | / ( N ulp ) ',
  897. $ / ' 4 = 0 if S contains min(M,N) nonnegative values in',
  898. $ ' decreasing order, else 1/ulp',
  899. $ / ' 5 = | U - Upartial | / ( M ulp )',
  900. $ / ' 6 = | VT - VTpartial | / ( N ulp )',
  901. $ / ' 7 = | S - Spartial | / ( min(M,N) ulp |S| )',
  902. $ / ' 8 = | A - U diag(S) VT | / ( |A| max(M,N) ulp ) ',
  903. $ / ' 9 = | I - U**T U | / ( M ulp ) ',
  904. $ / '10 = | I - VT VT**T | / ( N ulp ) ',
  905. $ / '11 = 0 if S contains min(M,N) nonnegative values in',
  906. $ ' decreasing order, else 1/ulp',
  907. $ / '12 = | U - Upartial | / ( M ulp )',
  908. $ / '13 = | VT - VTpartial | / ( N ulp )',
  909. $ / '14 = | S - Spartial | / ( min(M,N) ulp |S| )',
  910. $ / '15 = | A - U diag(S) VT | / ( |A| max(M,N) ulp ) ',
  911. $ / '16 = | I - U**T U | / ( M ulp ) ',
  912. $ / '17 = | I - VT VT**T | / ( N ulp ) ',
  913. $ / '18 = 0 if S contains min(M,N) nonnegative values in',
  914. $ ' decreasing order, else 1/ulp',
  915. $ / '19 = | U - Upartial | / ( M ulp )',
  916. $ / '20 = | VT - VTpartial | / ( N ulp )',
  917. $ / '21 = | S - Spartial | / ( min(M,N) ulp |S| )', / / )
  918. 9997 FORMAT( ' M=', I5, ', N=', I5, ', type ', I1, ', IWS=', I1,
  919. $ ', seed=', 4( I4, ',' ), ' test(', I2, ')=', G11.4 )
  920. 9996 FORMAT( ' DDRVBD: ', A, ' returned INFO=', I6, '.', / 9X, 'M=',
  921. $ I6, ', N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ),
  922. $ I5, ')' )
  923. 9995 FORMAT( ' DDRVBD: ', A, ' returned INFO=', I6, '.', / 9X, 'M=',
  924. $ I6, ', N=', I6, ', JTYPE=', I6, ', LSWORK=', I6, / 9X,
  925. $ 'ISEED=(', 3( I5, ',' ), I5, ')' )
  926. *
  927. RETURN
  928. *
  929. * End of DDRVBD
  930. *
  931. END