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.

dlatms.f 40 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
  1. *> \brief \b DLATMS
  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 DLATMS( M, N, DIST, ISEED, SYM, D, MODE, COND, DMAX,
  12. * KL, KU, PACK, A, LDA, WORK, INFO )
  13. *
  14. * .. Scalar Arguments ..
  15. * CHARACTER DIST, PACK, SYM
  16. * INTEGER INFO, KL, KU, LDA, M, MODE, N
  17. * DOUBLE PRECISION COND, DMAX
  18. * ..
  19. * .. Array Arguments ..
  20. * INTEGER ISEED( 4 )
  21. * DOUBLE PRECISION A( LDA, * ), D( * ), WORK( * )
  22. * ..
  23. *
  24. *
  25. *> \par Purpose:
  26. * =============
  27. *>
  28. *> \verbatim
  29. *>
  30. *> DLATMS generates random matrices with specified singular values
  31. *> (or symmetric/hermitian with specified eigenvalues)
  32. *> for testing LAPACK programs.
  33. *>
  34. *> DLATMS operates by applying the following sequence of
  35. *> operations:
  36. *>
  37. *> Set the diagonal to D, where D may be input or
  38. *> computed according to MODE, COND, DMAX, and SYM
  39. *> as described below.
  40. *>
  41. *> Generate a matrix with the appropriate band structure, by one
  42. *> of two methods:
  43. *>
  44. *> Method A:
  45. *> Generate a dense M x N matrix by multiplying D on the left
  46. *> and the right by random unitary matrices, then:
  47. *>
  48. *> Reduce the bandwidth according to KL and KU, using
  49. *> Householder transformations.
  50. *>
  51. *> Method B:
  52. *> Convert the bandwidth-0 (i.e., diagonal) matrix to a
  53. *> bandwidth-1 matrix using Givens rotations, "chasing"
  54. *> out-of-band elements back, much as in QR; then
  55. *> convert the bandwidth-1 to a bandwidth-2 matrix, etc.
  56. *> Note that for reasonably small bandwidths (relative to
  57. *> M and N) this requires less storage, as a dense matrix
  58. *> is not generated. Also, for symmetric matrices, only
  59. *> one triangle is generated.
  60. *>
  61. *> Method A is chosen if the bandwidth is a large fraction of the
  62. *> order of the matrix, and LDA is at least M (so a dense
  63. *> matrix can be stored.) Method B is chosen if the bandwidth
  64. *> is small (< 1/2 N for symmetric, < .3 N+M for
  65. *> non-symmetric), or LDA is less than M and not less than the
  66. *> bandwidth.
  67. *>
  68. *> Pack the matrix if desired. Options specified by PACK are:
  69. *> no packing
  70. *> zero out upper half (if symmetric)
  71. *> zero out lower half (if symmetric)
  72. *> store the upper half columnwise (if symmetric or upper
  73. *> triangular)
  74. *> store the lower half columnwise (if symmetric or lower
  75. *> triangular)
  76. *> store the lower triangle in banded format (if symmetric
  77. *> or lower triangular)
  78. *> store the upper triangle in banded format (if symmetric
  79. *> or upper triangular)
  80. *> store the entire matrix in banded format
  81. *> If Method B is chosen, and band format is specified, then the
  82. *> matrix will be generated in the band format, so no repacking
  83. *> will be necessary.
  84. *> \endverbatim
  85. *
  86. * Arguments:
  87. * ==========
  88. *
  89. *> \param[in] M
  90. *> \verbatim
  91. *> M is INTEGER
  92. *> The number of rows of A. Not modified.
  93. *> \endverbatim
  94. *>
  95. *> \param[in] N
  96. *> \verbatim
  97. *> N is INTEGER
  98. *> The number of columns of A. Not modified.
  99. *> \endverbatim
  100. *>
  101. *> \param[in] DIST
  102. *> \verbatim
  103. *> DIST is CHARACTER*1
  104. *> On entry, DIST specifies the type of distribution to be used
  105. *> to generate the random eigen-/singular values.
  106. *> 'U' => UNIFORM( 0, 1 ) ( 'U' for uniform )
  107. *> 'S' => UNIFORM( -1, 1 ) ( 'S' for symmetric )
  108. *> 'N' => NORMAL( 0, 1 ) ( 'N' for normal )
  109. *> Not modified.
  110. *> \endverbatim
  111. *>
  112. *> \param[in,out] ISEED
  113. *> \verbatim
  114. *> ISEED is INTEGER array, dimension ( 4 )
  115. *> On entry ISEED specifies the seed of the random number
  116. *> generator. They should lie between 0 and 4095 inclusive,
  117. *> and ISEED(4) should be odd. The random number generator
  118. *> uses a linear congruential sequence limited to small
  119. *> integers, and so should produce machine independent
  120. *> random numbers. The values of ISEED are changed on
  121. *> exit, and can be used in the next call to DLATMS
  122. *> to continue the same random number sequence.
  123. *> Changed on exit.
  124. *> \endverbatim
  125. *>
  126. *> \param[in] SYM
  127. *> \verbatim
  128. *> SYM is CHARACTER*1
  129. *> If SYM='S' or 'H', the generated matrix is symmetric, with
  130. *> eigenvalues specified by D, COND, MODE, and DMAX; they
  131. *> may be positive, negative, or zero.
  132. *> If SYM='P', the generated matrix is symmetric, with
  133. *> eigenvalues (= singular values) specified by D, COND,
  134. *> MODE, and DMAX; they will not be negative.
  135. *> If SYM='N', the generated matrix is nonsymmetric, with
  136. *> singular values specified by D, COND, MODE, and DMAX;
  137. *> they will not be negative.
  138. *> Not modified.
  139. *> \endverbatim
  140. *>
  141. *> \param[in,out] D
  142. *> \verbatim
  143. *> D is DOUBLE PRECISION array, dimension ( MIN( M , N ) )
  144. *> This array is used to specify the singular values or
  145. *> eigenvalues of A (see SYM, above.) If MODE=0, then D is
  146. *> assumed to contain the singular/eigenvalues, otherwise
  147. *> they will be computed according to MODE, COND, and DMAX,
  148. *> and placed in D.
  149. *> Modified if MODE is nonzero.
  150. *> \endverbatim
  151. *>
  152. *> \param[in] MODE
  153. *> \verbatim
  154. *> MODE is INTEGER
  155. *> On entry this describes how the singular/eigenvalues are to
  156. *> be specified:
  157. *> MODE = 0 means use D as input
  158. *> MODE = 1 sets D(1)=1 and D(2:N)=1.0/COND
  159. *> MODE = 2 sets D(1:N-1)=1 and D(N)=1.0/COND
  160. *> MODE = 3 sets D(I)=COND**(-(I-1)/(N-1))
  161. *> MODE = 4 sets D(i)=1 - (i-1)/(N-1)*(1 - 1/COND)
  162. *> MODE = 5 sets D to random numbers in the range
  163. *> ( 1/COND , 1 ) such that their logarithms
  164. *> are uniformly distributed.
  165. *> MODE = 6 set D to random numbers from same distribution
  166. *> as the rest of the matrix.
  167. *> MODE < 0 has the same meaning as ABS(MODE), except that
  168. *> the order of the elements of D is reversed.
  169. *> Thus if MODE is positive, D has entries ranging from
  170. *> 1 to 1/COND, if negative, from 1/COND to 1,
  171. *> If SYM='S' or 'H', and MODE is neither 0, 6, nor -6, then
  172. *> the elements of D will also be multiplied by a random
  173. *> sign (i.e., +1 or -1.)
  174. *> Not modified.
  175. *> \endverbatim
  176. *>
  177. *> \param[in] COND
  178. *> \verbatim
  179. *> COND is DOUBLE PRECISION
  180. *> On entry, this is used as described under MODE above.
  181. *> If used, it must be >= 1. Not modified.
  182. *> \endverbatim
  183. *>
  184. *> \param[in] DMAX
  185. *> \verbatim
  186. *> DMAX is DOUBLE PRECISION
  187. *> If MODE is neither -6, 0 nor 6, the contents of D, as
  188. *> computed according to MODE and COND, will be scaled by
  189. *> DMAX / max(abs(D(i))); thus, the maximum absolute eigen- or
  190. *> singular value (which is to say the norm) will be abs(DMAX).
  191. *> Note that DMAX need not be positive: if DMAX is negative
  192. *> (or zero), D will be scaled by a negative number (or zero).
  193. *> Not modified.
  194. *> \endverbatim
  195. *>
  196. *> \param[in] KL
  197. *> \verbatim
  198. *> KL is INTEGER
  199. *> This specifies the lower bandwidth of the matrix. For
  200. *> example, KL=0 implies upper triangular, KL=1 implies upper
  201. *> Hessenberg, and KL being at least M-1 means that the matrix
  202. *> has full lower bandwidth. KL must equal KU if the matrix
  203. *> is symmetric.
  204. *> Not modified.
  205. *> \endverbatim
  206. *>
  207. *> \param[in] KU
  208. *> \verbatim
  209. *> KU is INTEGER
  210. *> This specifies the upper bandwidth of the matrix. For
  211. *> example, KU=0 implies lower triangular, KU=1 implies lower
  212. *> Hessenberg, and KU being at least N-1 means that the matrix
  213. *> has full upper bandwidth. KL must equal KU if the matrix
  214. *> is symmetric.
  215. *> Not modified.
  216. *> \endverbatim
  217. *>
  218. *> \param[in] PACK
  219. *> \verbatim
  220. *> PACK is CHARACTER*1
  221. *> This specifies packing of matrix as follows:
  222. *> 'N' => no packing
  223. *> 'U' => zero out all subdiagonal entries (if symmetric)
  224. *> 'L' => zero out all superdiagonal entries (if symmetric)
  225. *> 'C' => store the upper triangle columnwise
  226. *> (only if the matrix is symmetric or upper triangular)
  227. *> 'R' => store the lower triangle columnwise
  228. *> (only if the matrix is symmetric or lower triangular)
  229. *> 'B' => store the lower triangle in band storage scheme
  230. *> (only if matrix symmetric or lower triangular)
  231. *> 'Q' => store the upper triangle in band storage scheme
  232. *> (only if matrix symmetric or upper triangular)
  233. *> 'Z' => store the entire matrix in band storage scheme
  234. *> (pivoting can be provided for by using this
  235. *> option to store A in the trailing rows of
  236. *> the allocated storage)
  237. *>
  238. *> Using these options, the various LAPACK packed and banded
  239. *> storage schemes can be obtained:
  240. *> GB - use 'Z'
  241. *> PB, SB or TB - use 'B' or 'Q'
  242. *> PP, SP or TP - use 'C' or 'R'
  243. *>
  244. *> If two calls to DLATMS differ only in the PACK parameter,
  245. *> they will generate mathematically equivalent matrices.
  246. *> Not modified.
  247. *> \endverbatim
  248. *>
  249. *> \param[in,out] A
  250. *> \verbatim
  251. *> A is DOUBLE PRECISION array, dimension ( LDA, N )
  252. *> On exit A is the desired test matrix. A is first generated
  253. *> in full (unpacked) form, and then packed, if so specified
  254. *> by PACK. Thus, the first M elements of the first N
  255. *> columns will always be modified. If PACK specifies a
  256. *> packed or banded storage scheme, all LDA elements of the
  257. *> first N columns will be modified; the elements of the
  258. *> array which do not correspond to elements of the generated
  259. *> matrix are set to zero.
  260. *> Modified.
  261. *> \endverbatim
  262. *>
  263. *> \param[in] LDA
  264. *> \verbatim
  265. *> LDA is INTEGER
  266. *> LDA specifies the first dimension of A as declared in the
  267. *> calling program. If PACK='N', 'U', 'L', 'C', or 'R', then
  268. *> LDA must be at least M. If PACK='B' or 'Q', then LDA must
  269. *> be at least MIN( KL, M-1) (which is equal to MIN(KU,N-1)).
  270. *> If PACK='Z', LDA must be large enough to hold the packed
  271. *> array: MIN( KU, N-1) + MIN( KL, M-1) + 1.
  272. *> Not modified.
  273. *> \endverbatim
  274. *>
  275. *> \param[out] WORK
  276. *> \verbatim
  277. *> WORK is DOUBLE PRECISION array, dimension ( 3*MAX( N , M ) )
  278. *> Workspace.
  279. *> Modified.
  280. *> \endverbatim
  281. *>
  282. *> \param[out] INFO
  283. *> \verbatim
  284. *> INFO is INTEGER
  285. *> Error code. On exit, INFO will be set to one of the
  286. *> following values:
  287. *> 0 => normal return
  288. *> -1 => M negative or unequal to N and SYM='S', 'H', or 'P'
  289. *> -2 => N negative
  290. *> -3 => DIST illegal string
  291. *> -5 => SYM illegal string
  292. *> -7 => MODE not in range -6 to 6
  293. *> -8 => COND less than 1.0, and MODE neither -6, 0 nor 6
  294. *> -10 => KL negative
  295. *> -11 => KU negative, or SYM='S' or 'H' and KU not equal to KL
  296. *> -12 => PACK illegal string, or PACK='U' or 'L', and SYM='N';
  297. *> or PACK='C' or 'Q' and SYM='N' and KL is not zero;
  298. *> or PACK='R' or 'B' and SYM='N' and KU is not zero;
  299. *> or PACK='U', 'L', 'C', 'R', 'B', or 'Q', and M is not
  300. *> N.
  301. *> -14 => LDA is less than M, or PACK='Z' and LDA is less than
  302. *> MIN(KU,N-1) + MIN(KL,M-1) + 1.
  303. *> 1 => Error return from DLATM1
  304. *> 2 => Cannot scale to DMAX (max. sing. value is 0)
  305. *> 3 => Error return from DLAGGE or SLAGSY
  306. *> \endverbatim
  307. *
  308. * Authors:
  309. * ========
  310. *
  311. *> \author Univ. of Tennessee
  312. *> \author Univ. of California Berkeley
  313. *> \author Univ. of Colorado Denver
  314. *> \author NAG Ltd.
  315. *
  316. *> \date November 2011
  317. *
  318. *> \ingroup double_matgen
  319. *
  320. * =====================================================================
  321. SUBROUTINE DLATMS( M, N, DIST, ISEED, SYM, D, MODE, COND, DMAX,
  322. $ KL, KU, PACK, A, LDA, WORK, INFO )
  323. *
  324. * -- LAPACK computational routine (version 3.4.0) --
  325. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  326. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  327. * November 2011
  328. *
  329. * .. Scalar Arguments ..
  330. CHARACTER DIST, PACK, SYM
  331. INTEGER INFO, KL, KU, LDA, M, MODE, N
  332. DOUBLE PRECISION COND, DMAX
  333. * ..
  334. * .. Array Arguments ..
  335. INTEGER ISEED( 4 )
  336. DOUBLE PRECISION A( LDA, * ), D( * ), WORK( * )
  337. * ..
  338. *
  339. * =====================================================================
  340. *
  341. * .. Parameters ..
  342. DOUBLE PRECISION ZERO
  343. PARAMETER ( ZERO = 0.0D0 )
  344. DOUBLE PRECISION ONE
  345. PARAMETER ( ONE = 1.0D0 )
  346. DOUBLE PRECISION TWOPI
  347. PARAMETER ( TWOPI = 6.2831853071795864769252867663D+0 )
  348. * ..
  349. * .. Local Scalars ..
  350. LOGICAL GIVENS, ILEXTR, ILTEMP, TOPDWN
  351. INTEGER I, IC, ICOL, IDIST, IENDCH, IINFO, IL, ILDA,
  352. $ IOFFG, IOFFST, IPACK, IPACKG, IR, IR1, IR2,
  353. $ IROW, IRSIGN, ISKEW, ISYM, ISYMPK, J, JC, JCH,
  354. $ JKL, JKU, JR, K, LLB, MINLDA, MNMIN, MR, NC,
  355. $ UUB
  356. DOUBLE PRECISION ALPHA, ANGLE, C, DUMMY, EXTRA, S, TEMP
  357. * ..
  358. * .. External Functions ..
  359. LOGICAL LSAME
  360. DOUBLE PRECISION DLARND
  361. EXTERNAL LSAME, DLARND
  362. * ..
  363. * .. External Subroutines ..
  364. EXTERNAL DCOPY, DLAGGE, DLAGSY, DLAROT, DLARTG, DLASET,
  365. $ DLATM1, DSCAL, XERBLA
  366. * ..
  367. * .. Intrinsic Functions ..
  368. INTRINSIC ABS, COS, DBLE, MAX, MIN, MOD, SIN
  369. * ..
  370. * .. Executable Statements ..
  371. *
  372. * 1) Decode and Test the input parameters.
  373. * Initialize flags & seed.
  374. *
  375. INFO = 0
  376. *
  377. * Quick return if possible
  378. *
  379. IF( M.EQ.0 .OR. N.EQ.0 )
  380. $ RETURN
  381. *
  382. * Decode DIST
  383. *
  384. IF( LSAME( DIST, 'U' ) ) THEN
  385. IDIST = 1
  386. ELSE IF( LSAME( DIST, 'S' ) ) THEN
  387. IDIST = 2
  388. ELSE IF( LSAME( DIST, 'N' ) ) THEN
  389. IDIST = 3
  390. ELSE
  391. IDIST = -1
  392. END IF
  393. *
  394. * Decode SYM
  395. *
  396. IF( LSAME( SYM, 'N' ) ) THEN
  397. ISYM = 1
  398. IRSIGN = 0
  399. ELSE IF( LSAME( SYM, 'P' ) ) THEN
  400. ISYM = 2
  401. IRSIGN = 0
  402. ELSE IF( LSAME( SYM, 'S' ) ) THEN
  403. ISYM = 2
  404. IRSIGN = 1
  405. ELSE IF( LSAME( SYM, 'H' ) ) THEN
  406. ISYM = 2
  407. IRSIGN = 1
  408. ELSE
  409. ISYM = -1
  410. END IF
  411. *
  412. * Decode PACK
  413. *
  414. ISYMPK = 0
  415. IF( LSAME( PACK, 'N' ) ) THEN
  416. IPACK = 0
  417. ELSE IF( LSAME( PACK, 'U' ) ) THEN
  418. IPACK = 1
  419. ISYMPK = 1
  420. ELSE IF( LSAME( PACK, 'L' ) ) THEN
  421. IPACK = 2
  422. ISYMPK = 1
  423. ELSE IF( LSAME( PACK, 'C' ) ) THEN
  424. IPACK = 3
  425. ISYMPK = 2
  426. ELSE IF( LSAME( PACK, 'R' ) ) THEN
  427. IPACK = 4
  428. ISYMPK = 3
  429. ELSE IF( LSAME( PACK, 'B' ) ) THEN
  430. IPACK = 5
  431. ISYMPK = 3
  432. ELSE IF( LSAME( PACK, 'Q' ) ) THEN
  433. IPACK = 6
  434. ISYMPK = 2
  435. ELSE IF( LSAME( PACK, 'Z' ) ) THEN
  436. IPACK = 7
  437. ELSE
  438. IPACK = -1
  439. END IF
  440. *
  441. * Set certain internal parameters
  442. *
  443. MNMIN = MIN( M, N )
  444. LLB = MIN( KL, M-1 )
  445. UUB = MIN( KU, N-1 )
  446. MR = MIN( M, N+LLB )
  447. NC = MIN( N, M+UUB )
  448. *
  449. IF( IPACK.EQ.5 .OR. IPACK.EQ.6 ) THEN
  450. MINLDA = UUB + 1
  451. ELSE IF( IPACK.EQ.7 ) THEN
  452. MINLDA = LLB + UUB + 1
  453. ELSE
  454. MINLDA = M
  455. END IF
  456. *
  457. * Use Givens rotation method if bandwidth small enough,
  458. * or if LDA is too small to store the matrix unpacked.
  459. *
  460. GIVENS = .FALSE.
  461. IF( ISYM.EQ.1 ) THEN
  462. IF( DBLE( LLB+UUB ).LT.0.3D0*DBLE( MAX( 1, MR+NC ) ) )
  463. $ GIVENS = .TRUE.
  464. ELSE
  465. IF( 2*LLB.LT.M )
  466. $ GIVENS = .TRUE.
  467. END IF
  468. IF( LDA.LT.M .AND. LDA.GE.MINLDA )
  469. $ GIVENS = .TRUE.
  470. *
  471. * Set INFO if an error
  472. *
  473. IF( M.LT.0 ) THEN
  474. INFO = -1
  475. ELSE IF( M.NE.N .AND. ISYM.NE.1 ) THEN
  476. INFO = -1
  477. ELSE IF( N.LT.0 ) THEN
  478. INFO = -2
  479. ELSE IF( IDIST.EQ.-1 ) THEN
  480. INFO = -3
  481. ELSE IF( ISYM.EQ.-1 ) THEN
  482. INFO = -5
  483. ELSE IF( ABS( MODE ).GT.6 ) THEN
  484. INFO = -7
  485. ELSE IF( ( MODE.NE.0 .AND. ABS( MODE ).NE.6 ) .AND. COND.LT.ONE )
  486. $ THEN
  487. INFO = -8
  488. ELSE IF( KL.LT.0 ) THEN
  489. INFO = -10
  490. ELSE IF( KU.LT.0 .OR. ( ISYM.NE.1 .AND. KL.NE.KU ) ) THEN
  491. INFO = -11
  492. ELSE IF( IPACK.EQ.-1 .OR. ( ISYMPK.EQ.1 .AND. ISYM.EQ.1 ) .OR.
  493. $ ( ISYMPK.EQ.2 .AND. ISYM.EQ.1 .AND. KL.GT.0 ) .OR.
  494. $ ( ISYMPK.EQ.3 .AND. ISYM.EQ.1 .AND. KU.GT.0 ) .OR.
  495. $ ( ISYMPK.NE.0 .AND. M.NE.N ) ) THEN
  496. INFO = -12
  497. ELSE IF( LDA.LT.MAX( 1, MINLDA ) ) THEN
  498. INFO = -14
  499. END IF
  500. *
  501. IF( INFO.NE.0 ) THEN
  502. CALL XERBLA( 'DLATMS', -INFO )
  503. RETURN
  504. END IF
  505. *
  506. * Initialize random number generator
  507. *
  508. DO 10 I = 1, 4
  509. ISEED( I ) = MOD( ABS( ISEED( I ) ), 4096 )
  510. 10 CONTINUE
  511. *
  512. IF( MOD( ISEED( 4 ), 2 ).NE.1 )
  513. $ ISEED( 4 ) = ISEED( 4 ) + 1
  514. *
  515. * 2) Set up D if indicated.
  516. *
  517. * Compute D according to COND and MODE
  518. *
  519. CALL DLATM1( MODE, COND, IRSIGN, IDIST, ISEED, D, MNMIN, IINFO )
  520. IF( IINFO.NE.0 ) THEN
  521. INFO = 1
  522. RETURN
  523. END IF
  524. *
  525. * Choose Top-Down if D is (apparently) increasing,
  526. * Bottom-Up if D is (apparently) decreasing.
  527. *
  528. IF( ABS( D( 1 ) ).LE.ABS( D( MNMIN ) ) ) THEN
  529. TOPDWN = .TRUE.
  530. ELSE
  531. TOPDWN = .FALSE.
  532. END IF
  533. *
  534. IF( MODE.NE.0 .AND. ABS( MODE ).NE.6 ) THEN
  535. *
  536. * Scale by DMAX
  537. *
  538. TEMP = ABS( D( 1 ) )
  539. DO 20 I = 2, MNMIN
  540. TEMP = MAX( TEMP, ABS( D( I ) ) )
  541. 20 CONTINUE
  542. *
  543. IF( TEMP.GT.ZERO ) THEN
  544. ALPHA = DMAX / TEMP
  545. ELSE
  546. INFO = 2
  547. RETURN
  548. END IF
  549. *
  550. CALL DSCAL( MNMIN, ALPHA, D, 1 )
  551. *
  552. END IF
  553. *
  554. * 3) Generate Banded Matrix using Givens rotations.
  555. * Also the special case of UUB=LLB=0
  556. *
  557. * Compute Addressing constants to cover all
  558. * storage formats. Whether GE, SY, GB, or SB,
  559. * upper or lower triangle or both,
  560. * the (i,j)-th element is in
  561. * A( i - ISKEW*j + IOFFST, j )
  562. *
  563. IF( IPACK.GT.4 ) THEN
  564. ILDA = LDA - 1
  565. ISKEW = 1
  566. IF( IPACK.GT.5 ) THEN
  567. IOFFST = UUB + 1
  568. ELSE
  569. IOFFST = 1
  570. END IF
  571. ELSE
  572. ILDA = LDA
  573. ISKEW = 0
  574. IOFFST = 0
  575. END IF
  576. *
  577. * IPACKG is the format that the matrix is generated in. If this is
  578. * different from IPACK, then the matrix must be repacked at the
  579. * end. It also signals how to compute the norm, for scaling.
  580. *
  581. IPACKG = 0
  582. CALL DLASET( 'Full', LDA, N, ZERO, ZERO, A, LDA )
  583. *
  584. * Diagonal Matrix -- We are done, unless it
  585. * is to be stored SP/PP/TP (PACK='R' or 'C')
  586. *
  587. IF( LLB.EQ.0 .AND. UUB.EQ.0 ) THEN
  588. CALL DCOPY( MNMIN, D, 1, A( 1-ISKEW+IOFFST, 1 ), ILDA+1 )
  589. IF( IPACK.LE.2 .OR. IPACK.GE.5 )
  590. $ IPACKG = IPACK
  591. *
  592. ELSE IF( GIVENS ) THEN
  593. *
  594. * Check whether to use Givens rotations,
  595. * Householder transformations, or nothing.
  596. *
  597. IF( ISYM.EQ.1 ) THEN
  598. *
  599. * Non-symmetric -- A = U D V
  600. *
  601. IF( IPACK.GT.4 ) THEN
  602. IPACKG = IPACK
  603. ELSE
  604. IPACKG = 0
  605. END IF
  606. *
  607. CALL DCOPY( MNMIN, D, 1, A( 1-ISKEW+IOFFST, 1 ), ILDA+1 )
  608. *
  609. IF( TOPDWN ) THEN
  610. JKL = 0
  611. DO 50 JKU = 1, UUB
  612. *
  613. * Transform from bandwidth JKL, JKU-1 to JKL, JKU
  614. *
  615. * Last row actually rotated is M
  616. * Last column actually rotated is MIN( M+JKU, N )
  617. *
  618. DO 40 JR = 1, MIN( M+JKU, N ) + JKL - 1
  619. EXTRA = ZERO
  620. ANGLE = TWOPI*DLARND( 1, ISEED )
  621. C = COS( ANGLE )
  622. S = SIN( ANGLE )
  623. ICOL = MAX( 1, JR-JKL )
  624. IF( JR.LT.M ) THEN
  625. IL = MIN( N, JR+JKU ) + 1 - ICOL
  626. CALL DLAROT( .TRUE., JR.GT.JKL, .FALSE., IL, C,
  627. $ S, A( JR-ISKEW*ICOL+IOFFST, ICOL ),
  628. $ ILDA, EXTRA, DUMMY )
  629. END IF
  630. *
  631. * Chase "EXTRA" back up
  632. *
  633. IR = JR
  634. IC = ICOL
  635. DO 30 JCH = JR - JKL, 1, -JKL - JKU
  636. IF( IR.LT.M ) THEN
  637. CALL DLARTG( A( IR+1-ISKEW*( IC+1 )+IOFFST,
  638. $ IC+1 ), EXTRA, C, S, DUMMY )
  639. END IF
  640. IROW = MAX( 1, JCH-JKU )
  641. IL = IR + 2 - IROW
  642. TEMP = ZERO
  643. ILTEMP = JCH.GT.JKU
  644. CALL DLAROT( .FALSE., ILTEMP, .TRUE., IL, C, -S,
  645. $ A( IROW-ISKEW*IC+IOFFST, IC ),
  646. $ ILDA, TEMP, EXTRA )
  647. IF( ILTEMP ) THEN
  648. CALL DLARTG( A( IROW+1-ISKEW*( IC+1 )+IOFFST,
  649. $ IC+1 ), TEMP, C, S, DUMMY )
  650. ICOL = MAX( 1, JCH-JKU-JKL )
  651. IL = IC + 2 - ICOL
  652. EXTRA = ZERO
  653. CALL DLAROT( .TRUE., JCH.GT.JKU+JKL, .TRUE.,
  654. $ IL, C, -S, A( IROW-ISKEW*ICOL+
  655. $ IOFFST, ICOL ), ILDA, EXTRA,
  656. $ TEMP )
  657. IC = ICOL
  658. IR = IROW
  659. END IF
  660. 30 CONTINUE
  661. 40 CONTINUE
  662. 50 CONTINUE
  663. *
  664. JKU = UUB
  665. DO 80 JKL = 1, LLB
  666. *
  667. * Transform from bandwidth JKL-1, JKU to JKL, JKU
  668. *
  669. DO 70 JC = 1, MIN( N+JKL, M ) + JKU - 1
  670. EXTRA = ZERO
  671. ANGLE = TWOPI*DLARND( 1, ISEED )
  672. C = COS( ANGLE )
  673. S = SIN( ANGLE )
  674. IROW = MAX( 1, JC-JKU )
  675. IF( JC.LT.N ) THEN
  676. IL = MIN( M, JC+JKL ) + 1 - IROW
  677. CALL DLAROT( .FALSE., JC.GT.JKU, .FALSE., IL, C,
  678. $ S, A( IROW-ISKEW*JC+IOFFST, JC ),
  679. $ ILDA, EXTRA, DUMMY )
  680. END IF
  681. *
  682. * Chase "EXTRA" back up
  683. *
  684. IC = JC
  685. IR = IROW
  686. DO 60 JCH = JC - JKU, 1, -JKL - JKU
  687. IF( IC.LT.N ) THEN
  688. CALL DLARTG( A( IR+1-ISKEW*( IC+1 )+IOFFST,
  689. $ IC+1 ), EXTRA, C, S, DUMMY )
  690. END IF
  691. ICOL = MAX( 1, JCH-JKL )
  692. IL = IC + 2 - ICOL
  693. TEMP = ZERO
  694. ILTEMP = JCH.GT.JKL
  695. CALL DLAROT( .TRUE., ILTEMP, .TRUE., IL, C, -S,
  696. $ A( IR-ISKEW*ICOL+IOFFST, ICOL ),
  697. $ ILDA, TEMP, EXTRA )
  698. IF( ILTEMP ) THEN
  699. CALL DLARTG( A( IR+1-ISKEW*( ICOL+1 )+IOFFST,
  700. $ ICOL+1 ), TEMP, C, S, DUMMY )
  701. IROW = MAX( 1, JCH-JKL-JKU )
  702. IL = IR + 2 - IROW
  703. EXTRA = ZERO
  704. CALL DLAROT( .FALSE., JCH.GT.JKL+JKU, .TRUE.,
  705. $ IL, C, -S, A( IROW-ISKEW*ICOL+
  706. $ IOFFST, ICOL ), ILDA, EXTRA,
  707. $ TEMP )
  708. IC = ICOL
  709. IR = IROW
  710. END IF
  711. 60 CONTINUE
  712. 70 CONTINUE
  713. 80 CONTINUE
  714. *
  715. ELSE
  716. *
  717. * Bottom-Up -- Start at the bottom right.
  718. *
  719. JKL = 0
  720. DO 110 JKU = 1, UUB
  721. *
  722. * Transform from bandwidth JKL, JKU-1 to JKL, JKU
  723. *
  724. * First row actually rotated is M
  725. * First column actually rotated is MIN( M+JKU, N )
  726. *
  727. IENDCH = MIN( M, N+JKL ) - 1
  728. DO 100 JC = MIN( M+JKU, N ) - 1, 1 - JKL, -1
  729. EXTRA = ZERO
  730. ANGLE = TWOPI*DLARND( 1, ISEED )
  731. C = COS( ANGLE )
  732. S = SIN( ANGLE )
  733. IROW = MAX( 1, JC-JKU+1 )
  734. IF( JC.GT.0 ) THEN
  735. IL = MIN( M, JC+JKL+1 ) + 1 - IROW
  736. CALL DLAROT( .FALSE., .FALSE., JC+JKL.LT.M, IL,
  737. $ C, S, A( IROW-ISKEW*JC+IOFFST,
  738. $ JC ), ILDA, DUMMY, EXTRA )
  739. END IF
  740. *
  741. * Chase "EXTRA" back down
  742. *
  743. IC = JC
  744. DO 90 JCH = JC + JKL, IENDCH, JKL + JKU
  745. ILEXTR = IC.GT.0
  746. IF( ILEXTR ) THEN
  747. CALL DLARTG( A( JCH-ISKEW*IC+IOFFST, IC ),
  748. $ EXTRA, C, S, DUMMY )
  749. END IF
  750. IC = MAX( 1, IC )
  751. ICOL = MIN( N-1, JCH+JKU )
  752. ILTEMP = JCH + JKU.LT.N
  753. TEMP = ZERO
  754. CALL DLAROT( .TRUE., ILEXTR, ILTEMP, ICOL+2-IC,
  755. $ C, S, A( JCH-ISKEW*IC+IOFFST, IC ),
  756. $ ILDA, EXTRA, TEMP )
  757. IF( ILTEMP ) THEN
  758. CALL DLARTG( A( JCH-ISKEW*ICOL+IOFFST,
  759. $ ICOL ), TEMP, C, S, DUMMY )
  760. IL = MIN( IENDCH, JCH+JKL+JKU ) + 2 - JCH
  761. EXTRA = ZERO
  762. CALL DLAROT( .FALSE., .TRUE.,
  763. $ JCH+JKL+JKU.LE.IENDCH, IL, C, S,
  764. $ A( JCH-ISKEW*ICOL+IOFFST,
  765. $ ICOL ), ILDA, TEMP, EXTRA )
  766. IC = ICOL
  767. END IF
  768. 90 CONTINUE
  769. 100 CONTINUE
  770. 110 CONTINUE
  771. *
  772. JKU = UUB
  773. DO 140 JKL = 1, LLB
  774. *
  775. * Transform from bandwidth JKL-1, JKU to JKL, JKU
  776. *
  777. * First row actually rotated is MIN( N+JKL, M )
  778. * First column actually rotated is N
  779. *
  780. IENDCH = MIN( N, M+JKU ) - 1
  781. DO 130 JR = MIN( N+JKL, M ) - 1, 1 - JKU, -1
  782. EXTRA = ZERO
  783. ANGLE = TWOPI*DLARND( 1, ISEED )
  784. C = COS( ANGLE )
  785. S = SIN( ANGLE )
  786. ICOL = MAX( 1, JR-JKL+1 )
  787. IF( JR.GT.0 ) THEN
  788. IL = MIN( N, JR+JKU+1 ) + 1 - ICOL
  789. CALL DLAROT( .TRUE., .FALSE., JR+JKU.LT.N, IL,
  790. $ C, S, A( JR-ISKEW*ICOL+IOFFST,
  791. $ ICOL ), ILDA, DUMMY, EXTRA )
  792. END IF
  793. *
  794. * Chase "EXTRA" back down
  795. *
  796. IR = JR
  797. DO 120 JCH = JR + JKU, IENDCH, JKL + JKU
  798. ILEXTR = IR.GT.0
  799. IF( ILEXTR ) THEN
  800. CALL DLARTG( A( IR-ISKEW*JCH+IOFFST, JCH ),
  801. $ EXTRA, C, S, DUMMY )
  802. END IF
  803. IR = MAX( 1, IR )
  804. IROW = MIN( M-1, JCH+JKL )
  805. ILTEMP = JCH + JKL.LT.M
  806. TEMP = ZERO
  807. CALL DLAROT( .FALSE., ILEXTR, ILTEMP, IROW+2-IR,
  808. $ C, S, A( IR-ISKEW*JCH+IOFFST,
  809. $ JCH ), ILDA, EXTRA, TEMP )
  810. IF( ILTEMP ) THEN
  811. CALL DLARTG( A( IROW-ISKEW*JCH+IOFFST, JCH ),
  812. $ TEMP, C, S, DUMMY )
  813. IL = MIN( IENDCH, JCH+JKL+JKU ) + 2 - JCH
  814. EXTRA = ZERO
  815. CALL DLAROT( .TRUE., .TRUE.,
  816. $ JCH+JKL+JKU.LE.IENDCH, IL, C, S,
  817. $ A( IROW-ISKEW*JCH+IOFFST, JCH ),
  818. $ ILDA, TEMP, EXTRA )
  819. IR = IROW
  820. END IF
  821. 120 CONTINUE
  822. 130 CONTINUE
  823. 140 CONTINUE
  824. END IF
  825. *
  826. ELSE
  827. *
  828. * Symmetric -- A = U D U'
  829. *
  830. IPACKG = IPACK
  831. IOFFG = IOFFST
  832. *
  833. IF( TOPDWN ) THEN
  834. *
  835. * Top-Down -- Generate Upper triangle only
  836. *
  837. IF( IPACK.GE.5 ) THEN
  838. IPACKG = 6
  839. IOFFG = UUB + 1
  840. ELSE
  841. IPACKG = 1
  842. END IF
  843. CALL DCOPY( MNMIN, D, 1, A( 1-ISKEW+IOFFG, 1 ), ILDA+1 )
  844. *
  845. DO 170 K = 1, UUB
  846. DO 160 JC = 1, N - 1
  847. IROW = MAX( 1, JC-K )
  848. IL = MIN( JC+1, K+2 )
  849. EXTRA = ZERO
  850. TEMP = A( JC-ISKEW*( JC+1 )+IOFFG, JC+1 )
  851. ANGLE = TWOPI*DLARND( 1, ISEED )
  852. C = COS( ANGLE )
  853. S = SIN( ANGLE )
  854. CALL DLAROT( .FALSE., JC.GT.K, .TRUE., IL, C, S,
  855. $ A( IROW-ISKEW*JC+IOFFG, JC ), ILDA,
  856. $ EXTRA, TEMP )
  857. CALL DLAROT( .TRUE., .TRUE., .FALSE.,
  858. $ MIN( K, N-JC )+1, C, S,
  859. $ A( ( 1-ISKEW )*JC+IOFFG, JC ), ILDA,
  860. $ TEMP, DUMMY )
  861. *
  862. * Chase EXTRA back up the matrix
  863. *
  864. ICOL = JC
  865. DO 150 JCH = JC - K, 1, -K
  866. CALL DLARTG( A( JCH+1-ISKEW*( ICOL+1 )+IOFFG,
  867. $ ICOL+1 ), EXTRA, C, S, DUMMY )
  868. TEMP = A( JCH-ISKEW*( JCH+1 )+IOFFG, JCH+1 )
  869. CALL DLAROT( .TRUE., .TRUE., .TRUE., K+2, C, -S,
  870. $ A( ( 1-ISKEW )*JCH+IOFFG, JCH ),
  871. $ ILDA, TEMP, EXTRA )
  872. IROW = MAX( 1, JCH-K )
  873. IL = MIN( JCH+1, K+2 )
  874. EXTRA = ZERO
  875. CALL DLAROT( .FALSE., JCH.GT.K, .TRUE., IL, C,
  876. $ -S, A( IROW-ISKEW*JCH+IOFFG, JCH ),
  877. $ ILDA, EXTRA, TEMP )
  878. ICOL = JCH
  879. 150 CONTINUE
  880. 160 CONTINUE
  881. 170 CONTINUE
  882. *
  883. * If we need lower triangle, copy from upper. Note that
  884. * the order of copying is chosen to work for 'q' -> 'b'
  885. *
  886. IF( IPACK.NE.IPACKG .AND. IPACK.NE.3 ) THEN
  887. DO 190 JC = 1, N
  888. IROW = IOFFST - ISKEW*JC
  889. DO 180 JR = JC, MIN( N, JC+UUB )
  890. A( JR+IROW, JC ) = A( JC-ISKEW*JR+IOFFG, JR )
  891. 180 CONTINUE
  892. 190 CONTINUE
  893. IF( IPACK.EQ.5 ) THEN
  894. DO 210 JC = N - UUB + 1, N
  895. DO 200 JR = N + 2 - JC, UUB + 1
  896. A( JR, JC ) = ZERO
  897. 200 CONTINUE
  898. 210 CONTINUE
  899. END IF
  900. IF( IPACKG.EQ.6 ) THEN
  901. IPACKG = IPACK
  902. ELSE
  903. IPACKG = 0
  904. END IF
  905. END IF
  906. ELSE
  907. *
  908. * Bottom-Up -- Generate Lower triangle only
  909. *
  910. IF( IPACK.GE.5 ) THEN
  911. IPACKG = 5
  912. IF( IPACK.EQ.6 )
  913. $ IOFFG = 1
  914. ELSE
  915. IPACKG = 2
  916. END IF
  917. CALL DCOPY( MNMIN, D, 1, A( 1-ISKEW+IOFFG, 1 ), ILDA+1 )
  918. *
  919. DO 240 K = 1, UUB
  920. DO 230 JC = N - 1, 1, -1
  921. IL = MIN( N+1-JC, K+2 )
  922. EXTRA = ZERO
  923. TEMP = A( 1+( 1-ISKEW )*JC+IOFFG, JC )
  924. ANGLE = TWOPI*DLARND( 1, ISEED )
  925. C = COS( ANGLE )
  926. S = -SIN( ANGLE )
  927. CALL DLAROT( .FALSE., .TRUE., N-JC.GT.K, IL, C, S,
  928. $ A( ( 1-ISKEW )*JC+IOFFG, JC ), ILDA,
  929. $ TEMP, EXTRA )
  930. ICOL = MAX( 1, JC-K+1 )
  931. CALL DLAROT( .TRUE., .FALSE., .TRUE., JC+2-ICOL, C,
  932. $ S, A( JC-ISKEW*ICOL+IOFFG, ICOL ),
  933. $ ILDA, DUMMY, TEMP )
  934. *
  935. * Chase EXTRA back down the matrix
  936. *
  937. ICOL = JC
  938. DO 220 JCH = JC + K, N - 1, K
  939. CALL DLARTG( A( JCH-ISKEW*ICOL+IOFFG, ICOL ),
  940. $ EXTRA, C, S, DUMMY )
  941. TEMP = A( 1+( 1-ISKEW )*JCH+IOFFG, JCH )
  942. CALL DLAROT( .TRUE., .TRUE., .TRUE., K+2, C, S,
  943. $ A( JCH-ISKEW*ICOL+IOFFG, ICOL ),
  944. $ ILDA, EXTRA, TEMP )
  945. IL = MIN( N+1-JCH, K+2 )
  946. EXTRA = ZERO
  947. CALL DLAROT( .FALSE., .TRUE., N-JCH.GT.K, IL, C,
  948. $ S, A( ( 1-ISKEW )*JCH+IOFFG, JCH ),
  949. $ ILDA, TEMP, EXTRA )
  950. ICOL = JCH
  951. 220 CONTINUE
  952. 230 CONTINUE
  953. 240 CONTINUE
  954. *
  955. * If we need upper triangle, copy from lower. Note that
  956. * the order of copying is chosen to work for 'b' -> 'q'
  957. *
  958. IF( IPACK.NE.IPACKG .AND. IPACK.NE.4 ) THEN
  959. DO 260 JC = N, 1, -1
  960. IROW = IOFFST - ISKEW*JC
  961. DO 250 JR = JC, MAX( 1, JC-UUB ), -1
  962. A( JR+IROW, JC ) = A( JC-ISKEW*JR+IOFFG, JR )
  963. 250 CONTINUE
  964. 260 CONTINUE
  965. IF( IPACK.EQ.6 ) THEN
  966. DO 280 JC = 1, UUB
  967. DO 270 JR = 1, UUB + 1 - JC
  968. A( JR, JC ) = ZERO
  969. 270 CONTINUE
  970. 280 CONTINUE
  971. END IF
  972. IF( IPACKG.EQ.5 ) THEN
  973. IPACKG = IPACK
  974. ELSE
  975. IPACKG = 0
  976. END IF
  977. END IF
  978. END IF
  979. END IF
  980. *
  981. ELSE
  982. *
  983. * 4) Generate Banded Matrix by first
  984. * Rotating by random Unitary matrices,
  985. * then reducing the bandwidth using Householder
  986. * transformations.
  987. *
  988. * Note: we should get here only if LDA .ge. N
  989. *
  990. IF( ISYM.EQ.1 ) THEN
  991. *
  992. * Non-symmetric -- A = U D V
  993. *
  994. CALL DLAGGE( MR, NC, LLB, UUB, D, A, LDA, ISEED, WORK,
  995. $ IINFO )
  996. ELSE
  997. *
  998. * Symmetric -- A = U D U'
  999. *
  1000. CALL DLAGSY( M, LLB, D, A, LDA, ISEED, WORK, IINFO )
  1001. *
  1002. END IF
  1003. IF( IINFO.NE.0 ) THEN
  1004. INFO = 3
  1005. RETURN
  1006. END IF
  1007. END IF
  1008. *
  1009. * 5) Pack the matrix
  1010. *
  1011. IF( IPACK.NE.IPACKG ) THEN
  1012. IF( IPACK.EQ.1 ) THEN
  1013. *
  1014. * 'U' -- Upper triangular, not packed
  1015. *
  1016. DO 300 J = 1, M
  1017. DO 290 I = J + 1, M
  1018. A( I, J ) = ZERO
  1019. 290 CONTINUE
  1020. 300 CONTINUE
  1021. *
  1022. ELSE IF( IPACK.EQ.2 ) THEN
  1023. *
  1024. * 'L' -- Lower triangular, not packed
  1025. *
  1026. DO 320 J = 2, M
  1027. DO 310 I = 1, J - 1
  1028. A( I, J ) = ZERO
  1029. 310 CONTINUE
  1030. 320 CONTINUE
  1031. *
  1032. ELSE IF( IPACK.EQ.3 ) THEN
  1033. *
  1034. * 'C' -- Upper triangle packed Columnwise.
  1035. *
  1036. ICOL = 1
  1037. IROW = 0
  1038. DO 340 J = 1, M
  1039. DO 330 I = 1, J
  1040. IROW = IROW + 1
  1041. IF( IROW.GT.LDA ) THEN
  1042. IROW = 1
  1043. ICOL = ICOL + 1
  1044. END IF
  1045. A( IROW, ICOL ) = A( I, J )
  1046. 330 CONTINUE
  1047. 340 CONTINUE
  1048. *
  1049. ELSE IF( IPACK.EQ.4 ) THEN
  1050. *
  1051. * 'R' -- Lower triangle packed Columnwise.
  1052. *
  1053. ICOL = 1
  1054. IROW = 0
  1055. DO 360 J = 1, M
  1056. DO 350 I = J, M
  1057. IROW = IROW + 1
  1058. IF( IROW.GT.LDA ) THEN
  1059. IROW = 1
  1060. ICOL = ICOL + 1
  1061. END IF
  1062. A( IROW, ICOL ) = A( I, J )
  1063. 350 CONTINUE
  1064. 360 CONTINUE
  1065. *
  1066. ELSE IF( IPACK.GE.5 ) THEN
  1067. *
  1068. * 'B' -- The lower triangle is packed as a band matrix.
  1069. * 'Q' -- The upper triangle is packed as a band matrix.
  1070. * 'Z' -- The whole matrix is packed as a band matrix.
  1071. *
  1072. IF( IPACK.EQ.5 )
  1073. $ UUB = 0
  1074. IF( IPACK.EQ.6 )
  1075. $ LLB = 0
  1076. *
  1077. DO 380 J = 1, UUB
  1078. DO 370 I = MIN( J+LLB, M ), 1, -1
  1079. A( I-J+UUB+1, J ) = A( I, J )
  1080. 370 CONTINUE
  1081. 380 CONTINUE
  1082. *
  1083. DO 400 J = UUB + 2, N
  1084. DO 390 I = J - UUB, MIN( J+LLB, M )
  1085. A( I-J+UUB+1, J ) = A( I, J )
  1086. 390 CONTINUE
  1087. 400 CONTINUE
  1088. END IF
  1089. *
  1090. * If packed, zero out extraneous elements.
  1091. *
  1092. * Symmetric/Triangular Packed --
  1093. * zero out everything after A(IROW,ICOL)
  1094. *
  1095. IF( IPACK.EQ.3 .OR. IPACK.EQ.4 ) THEN
  1096. DO 420 JC = ICOL, M
  1097. DO 410 JR = IROW + 1, LDA
  1098. A( JR, JC ) = ZERO
  1099. 410 CONTINUE
  1100. IROW = 0
  1101. 420 CONTINUE
  1102. *
  1103. ELSE IF( IPACK.GE.5 ) THEN
  1104. *
  1105. * Packed Band --
  1106. * 1st row is now in A( UUB+2-j, j), zero above it
  1107. * m-th row is now in A( M+UUB-j,j), zero below it
  1108. * last non-zero diagonal is now in A( UUB+LLB+1,j ),
  1109. * zero below it, too.
  1110. *
  1111. IR1 = UUB + LLB + 2
  1112. IR2 = UUB + M + 2
  1113. DO 450 JC = 1, N
  1114. DO 430 JR = 1, UUB + 1 - JC
  1115. A( JR, JC ) = ZERO
  1116. 430 CONTINUE
  1117. DO 440 JR = MAX( 1, MIN( IR1, IR2-JC ) ), LDA
  1118. A( JR, JC ) = ZERO
  1119. 440 CONTINUE
  1120. 450 CONTINUE
  1121. END IF
  1122. END IF
  1123. *
  1124. RETURN
  1125. *
  1126. * End of DLATMS
  1127. *
  1128. END