3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
11 * SUBROUTINE SLATMR( M, N, DIST, ISEED, SYM, D, MODE, COND, DMAX,
12 * RSIGN, GRADE, DL, MODEL, CONDL, DR, MODER,
13 * CONDR, PIVTNG, IPIVOT, KL, KU, SPARSE, ANORM,
14 * PACK, A, LDA, IWORK, INFO )
16 * .. Scalar Arguments ..
17 * CHARACTER DIST, GRADE, PACK, PIVTNG, RSIGN, SYM
18 * INTEGER INFO, KL, KU, LDA, M, MODE, MODEL, MODER, N
19 * REAL ANORM, COND, CONDL, CONDR, DMAX, SPARSE
21 * .. Array Arguments ..
22 * INTEGER IPIVOT( * ), ISEED( 4 ), IWORK( * )
23 * REAL A( LDA, * ), D( * ), DL( * ), DR( * )
32 *> SLATMR generates random matrices of various types for testing
35 *> SLATMR operates by applying the following sequence of
38 *> Generate a matrix A with random entries of distribution DIST
39 *> which is symmetric if SYM='S', and nonsymmetric
42 *> Set the diagonal to D, where D may be input or
43 *> computed according to MODE, COND, DMAX and RSIGN
44 *> as described below.
46 *> Grade the matrix, if desired, from the left and/or right
47 *> as specified by GRADE. The inputs DL, MODEL, CONDL, DR,
48 *> MODER and CONDR also determine the grading as described
51 *> Permute, if desired, the rows and/or columns as specified by
54 *> Set random entries to zero, if desired, to get a random sparse
55 *> matrix as specified by SPARSE.
57 *> Make A a band matrix, if desired, by zeroing out the matrix
58 *> outside a band of lower bandwidth KL and upper bandwidth KU.
60 *> Scale A, if desired, to have maximum entry ANORM.
62 *> Pack the matrix if desired. Options specified by PACK are:
64 *> zero out upper half (if symmetric)
65 *> zero out lower half (if symmetric)
66 *> store the upper half columnwise (if symmetric or
67 *> square upper triangular)
68 *> store the lower half columnwise (if symmetric or
69 *> square lower triangular)
70 *> same as upper half rowwise if symmetric
71 *> store the lower triangle in banded format (if symmetric)
72 *> store the upper triangle in banded format (if symmetric)
73 *> store the entire matrix in banded format
75 *> Note: If two calls to SLATMR differ only in the PACK parameter,
76 *> they will generate mathematically equivalent matrices.
78 *> If two calls to SLATMR both have full bandwidth (KL = M-1
79 *> and KU = N-1), and differ only in the PIVTNG and PACK
80 *> parameters, then the matrices generated will differ only
81 *> in the order of the rows and/or columns, and otherwise
82 *> contain the same data. This consistency cannot be and
83 *> is not maintained with less than full bandwidth.
92 *> Number of rows of A. Not modified.
98 *> Number of columns of A. Not modified.
103 *> DIST is CHARACTER*1
104 *> On entry, DIST specifies the type of distribution to be used
105 *> to generate a random matrix .
106 *> 'U' => UNIFORM( 0, 1 ) ( 'U' for uniform )
107 *> 'S' => UNIFORM( -1, 1 ) ( 'S' for symmetric )
108 *> 'N' => NORMAL( 0, 1 ) ( 'N' for normal )
112 *> \param[in,out] ISEED
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 SLATMR
122 *> to continue the same random number sequence.
128 *> SYM is CHARACTER*1
129 *> If SYM='S' or 'H', generated matrix is symmetric.
130 *> If SYM='N', generated matrix is nonsymmetric.
136 *> D is REAL array, dimension (min(M,N))
137 *> On entry this array specifies the diagonal entries
138 *> of the diagonal of A. D may either be specified
139 *> on entry, or set according to MODE and COND as described
140 *> below. May be changed on exit if MODE is nonzero.
146 *> On entry describes how D is to be used:
147 *> MODE = 0 means use D as input
148 *> MODE = 1 sets D(1)=1 and D(2:N)=1.0/COND
149 *> MODE = 2 sets D(1:N-1)=1 and D(N)=1.0/COND
150 *> MODE = 3 sets D(I)=COND**(-(I-1)/(N-1))
151 *> MODE = 4 sets D(i)=1 - (i-1)/(N-1)*(1 - 1/COND)
152 *> MODE = 5 sets D to random numbers in the range
153 *> ( 1/COND , 1 ) such that their logarithms
154 *> are uniformly distributed.
155 *> MODE = 6 set D to random numbers from same distribution
156 *> as the rest of the matrix.
157 *> MODE < 0 has the same meaning as ABS(MODE), except that
158 *> the order of the elements of D is reversed.
159 *> Thus if MODE is positive, D has entries ranging from
160 *> 1 to 1/COND, if negative, from 1/COND to 1,
167 *> On entry, used as described under MODE above.
168 *> If used, it must be >= 1. Not modified.
174 *> If MODE neither -6, 0 nor 6, the diagonal is scaled by
175 *> DMAX / max(abs(D(i))), so that maximum absolute entry
176 *> of diagonal is abs(DMAX). If DMAX is negative (or zero),
177 *> diagonal will be scaled by a negative number (or zero).
182 *> RSIGN is CHARACTER*1
183 *> If MODE neither -6, 0 nor 6, specifies sign of diagonal
185 *> 'T' => diagonal entries are multiplied by 1 or -1
186 *> with probability .5
187 *> 'F' => diagonal unchanged
193 *> GRADE is CHARACTER*1
194 *> Specifies grading of matrix as follows:
196 *> 'L' => matrix premultiplied by diag( DL )
197 *> (only if matrix nonsymmetric)
198 *> 'R' => matrix postmultiplied by diag( DR )
199 *> (only if matrix nonsymmetric)
200 *> 'B' => matrix premultiplied by diag( DL ) and
201 *> postmultiplied by diag( DR )
202 *> (only if matrix nonsymmetric)
203 *> 'S' or 'H' => matrix premultiplied by diag( DL ) and
204 *> postmultiplied by diag( DL )
205 *> ('S' for symmetric, or 'H' for Hermitian)
206 *> 'E' => matrix premultiplied by diag( DL ) and
207 *> postmultiplied by inv( diag( DL ) )
208 *> ( 'E' for eigenvalue invariance)
209 *> (only if matrix nonsymmetric)
210 *> Note: if GRADE='E', then M must equal N.
216 *> DL is REAL array, dimension (M)
217 *> If MODEL=0, then on entry this array specifies the diagonal
218 *> entries of a diagonal matrix used as described under GRADE
219 *> above. If MODEL is not zero, then DL will be set according
220 *> to MODEL and CONDL, analogous to the way D is set according
221 *> to MODE and COND (except there is no DMAX parameter for DL).
222 *> If GRADE='E', then DL cannot have zero entries.
223 *> Not referenced if GRADE = 'N' or 'R'. Changed on exit.
229 *> This specifies how the diagonal array DL is to be computed,
230 *> just as MODE specifies how D is to be computed.
237 *> When MODEL is not zero, this specifies the condition number
238 *> of the computed DL. Not modified.
243 *> DR is REAL array, dimension (N)
244 *> If MODER=0, then on entry this array specifies the diagonal
245 *> entries of a diagonal matrix used as described under GRADE
246 *> above. If MODER is not zero, then DR will be set according
247 *> to MODER and CONDR, analogous to the way D is set according
248 *> to MODE and COND (except there is no DMAX parameter for DR).
249 *> Not referenced if GRADE = 'N', 'L', 'H', 'S' or 'E'.
256 *> This specifies how the diagonal array DR is to be computed,
257 *> just as MODE specifies how D is to be computed.
264 *> When MODER is not zero, this specifies the condition number
265 *> of the computed DR. Not modified.
270 *> PIVTNG is CHARACTER*1
271 *> On entry specifies pivoting permutations as follows:
272 *> 'N' or ' ' => none.
273 *> 'L' => left or row pivoting (matrix must be nonsymmetric).
274 *> 'R' => right or column pivoting (matrix must be
276 *> 'B' or 'F' => both or full pivoting, i.e., on both sides.
277 *> In this case, M must equal N
279 *> If two calls to SLATMR both have full bandwidth (KL = M-1
280 *> and KU = N-1), and differ only in the PIVTNG and PACK
281 *> parameters, then the matrices generated will differ only
282 *> in the order of the rows and/or columns, and otherwise
283 *> contain the same data. This consistency cannot be
284 *> maintained with less than full bandwidth.
289 *> IPIVOT is INTEGER array, dimension (N or M)
290 *> This array specifies the permutation used. After the
291 *> basic matrix is generated, the rows, columns, or both
292 *> are permuted. If, say, row pivoting is selected, SLATMR
293 *> starts with the *last* row and interchanges the M-th and
294 *> IPIVOT(M)-th rows, then moves to the next-to-last row,
295 *> interchanging the (M-1)-th and the IPIVOT(M-1)-th rows,
296 *> and so on. In terms of "2-cycles", the permutation is
297 *> (1 IPIVOT(1)) (2 IPIVOT(2)) ... (M IPIVOT(M))
298 *> where the rightmost cycle is applied first. This is the
299 *> *inverse* of the effect of pivoting in LINPACK. The idea
300 *> is that factoring (with pivoting) an identity matrix
301 *> which has been inverse-pivoted in this way should
302 *> result in a pivot vector identical to IPIVOT.
303 *> Not referenced if PIVTNG = 'N'. Not modified.
309 *> On entry specifies the sparsity of the matrix if a sparse
310 *> matrix is to be generated. SPARSE should lie between
311 *> 0 and 1. To generate a sparse matrix, for each matrix entry
312 *> a uniform ( 0, 1 ) random number x is generated and
313 *> compared to SPARSE; if x is larger the matrix entry
314 *> is unchanged and if x is smaller the entry is set
315 *> to zero. Thus on the average a fraction SPARSE of the
316 *> entries will be set to zero.
323 *> On entry specifies the lower bandwidth of the matrix. For
324 *> example, KL=0 implies upper triangular, KL=1 implies upper
325 *> Hessenberg, and KL at least M-1 implies the matrix is not
326 *> banded. Must equal KU if matrix is symmetric.
333 *> On entry specifies the upper bandwidth of the matrix. For
334 *> example, KU=0 implies lower triangular, KU=1 implies lower
335 *> Hessenberg, and KU at least N-1 implies the matrix is not
336 *> banded. Must equal KL if matrix is symmetric.
343 *> On entry specifies maximum entry of output matrix
344 *> (output matrix will by multiplied by a constant so that
345 *> its largest absolute entry equal ANORM)
346 *> if ANORM is nonnegative. If ANORM is negative no scaling
347 *> is done. Not modified.
352 *> PACK is CHARACTER*1
353 *> On entry specifies packing of matrix as follows:
355 *> 'U' => zero out all subdiagonal entries (if symmetric)
356 *> 'L' => zero out all superdiagonal entries (if symmetric)
357 *> 'C' => store the upper triangle columnwise
358 *> (only if matrix symmetric or square upper triangular)
359 *> 'R' => store the lower triangle columnwise
360 *> (only if matrix symmetric or square lower triangular)
361 *> (same as upper half rowwise if symmetric)
362 *> 'B' => store the lower triangle in band storage scheme
363 *> (only if matrix symmetric)
364 *> 'Q' => store the upper triangle in band storage scheme
365 *> (only if matrix symmetric)
366 *> 'Z' => store the entire matrix in band storage scheme
367 *> (pivoting can be provided for by using this
368 *> option to store A in the trailing rows of
369 *> the allocated storage)
371 *> Using these options, the various LAPACK packed and banded
372 *> storage schemes can be obtained:
374 *> PB, SB or TB - use 'B' or 'Q'
375 *> PP, SP or TP - use 'C' or 'R'
377 *> If two calls to SLATMR differ only in the PACK parameter,
378 *> they will generate mathematically equivalent matrices.
384 *> A is REAL array, dimension (LDA,N)
385 *> On exit A is the desired test matrix. Only those
386 *> entries of A which are significant on output
387 *> will be referenced (even if A is in packed or band
388 *> storage format). The 'unoccupied corners' of A in
389 *> band format will be zeroed out.
395 *> on entry LDA specifies the first dimension of A as
396 *> declared in the calling program.
397 *> If PACK='N', 'U' or 'L', LDA must be at least max ( 1, M ).
398 *> If PACK='C' or 'R', LDA must be at least 1.
399 *> If PACK='B', or 'Q', LDA must be MIN ( KU+1, N )
400 *> If PACK='Z', LDA must be at least KUU+KLL+1, where
401 *> KUU = MIN ( KU, N-1 ) and KLL = MIN ( KL, N-1 )
407 *> IWORK is INTEGER array, dimension ( N or M)
408 *> Workspace. Not referenced if PIVTNG = 'N'. Changed on exit.
414 *> Error parameter on exit:
415 *> 0 => normal return
416 *> -1 => M negative or unequal to N and SYM='S' or 'H'
418 *> -3 => DIST illegal string
419 *> -5 => SYM illegal string
420 *> -7 => MODE not in range -6 to 6
421 *> -8 => COND less than 1.0, and MODE neither -6, 0 nor 6
422 *> -10 => MODE neither -6, 0 nor 6 and RSIGN illegal string
423 *> -11 => GRADE illegal string, or GRADE='E' and
424 *> M not equal to N, or GRADE='L', 'R', 'B' or 'E' and
426 *> -12 => GRADE = 'E' and DL contains zero
427 *> -13 => MODEL not in range -6 to 6 and GRADE= 'L', 'B', 'H',
429 *> -14 => CONDL less than 1.0, GRADE='L', 'B', 'H', 'S' or 'E',
430 *> and MODEL neither -6, 0 nor 6
431 *> -16 => MODER not in range -6 to 6 and GRADE= 'R' or 'B'
432 *> -17 => CONDR less than 1.0, GRADE='R' or 'B', and
433 *> MODER neither -6, 0 nor 6
434 *> -18 => PIVTNG illegal string, or PIVTNG='B' or 'F' and
435 *> M not equal to N, or PIVTNG='L' or 'R' and SYM='S'
437 *> -19 => IPIVOT contains out of range number and
438 *> PIVTNG not equal to 'N'
439 *> -20 => KL negative
440 *> -21 => KU negative, or SYM='S' or 'H' and KU not equal to KL
441 *> -22 => SPARSE not in range 0. to 1.
442 *> -24 => PACK illegal string, or PACK='U', 'L', 'B' or 'Q'
443 *> and SYM='N', or PACK='C' and SYM='N' and either KL
444 *> not equal to 0 or N not equal to M, or PACK='R' and
445 *> SYM='N', and either KU not equal to 0 or N not equal
447 *> -26 => LDA too small
448 *> 1 => Error return from SLATM1 (computing D)
449 *> 2 => Cannot scale diagonal to DMAX (max. entry is 0)
450 *> 3 => Error return from SLATM1 (computing DL)
451 *> 4 => Error return from SLATM1 (computing DR)
452 *> 5 => ANORM is positive, but matrix constructed prior to
453 *> attempting to scale it to have norm ANORM, is zero
459 *> \author Univ. of Tennessee
460 *> \author Univ. of California Berkeley
461 *> \author Univ. of Colorado Denver
464 *> \date November 2011
466 *> \ingroup real_matgen
468 * =====================================================================
469 SUBROUTINE SLATMR( M, N, DIST, ISEED, SYM, D, MODE, COND, DMAX,
470 $ RSIGN, GRADE, DL, MODEL, CONDL, DR, MODER,
471 $ CONDR, PIVTNG, IPIVOT, KL, KU, SPARSE, ANORM,
472 $ PACK, A, LDA, IWORK, INFO )
474 * -- LAPACK computational routine (version 3.4.0) --
475 * -- LAPACK is a software package provided by Univ. of Tennessee, --
476 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
479 * .. Scalar Arguments ..
480 CHARACTER DIST, GRADE, PACK, PIVTNG, RSIGN, SYM
481 INTEGER INFO, KL, KU, LDA, M, MODE, MODEL, MODER, N
482 REAL ANORM, COND, CONDL, CONDR, DMAX, SPARSE
484 * .. Array Arguments ..
485 INTEGER IPIVOT( * ), ISEED( 4 ), IWORK( * )
486 REAL A( LDA, * ), D( * ), DL( * ), DR( * )
489 * =====================================================================
493 PARAMETER ( ZERO = 0.0E0 )
495 PARAMETER ( ONE = 1.0E0 )
497 * .. Local Scalars ..
498 LOGICAL BADPVT, DZERO, FULBND
499 INTEGER I, IDIST, IGRADE, IISUB, IPACK, IPVTNG, IRSIGN,
500 $ ISUB, ISYM, J, JJSUB, JSUB, K, KLL, KUU, MNMIN,
501 $ MNSUB, MXSUB, NPVTS
502 REAL ALPHA, ONORM, TEMP
507 * .. External Functions ..
509 REAL SLANGB, SLANGE, SLANSB, SLANSP, SLANSY, SLATM2,
511 EXTERNAL LSAME, SLANGB, SLANGE, SLANSB, SLANSP, SLANSY,
514 * .. External Subroutines ..
515 EXTERNAL SLATM1, SSCAL, XERBLA
517 * .. Intrinsic Functions ..
518 INTRINSIC ABS, MAX, MIN, MOD
520 * .. Executable Statements ..
522 * 1) Decode and Test the input parameters.
523 * Initialize flags & seed.
527 * Quick return if possible
529 IF( M.EQ.0 .OR. N.EQ.0 )
534 IF( LSAME( DIST, 'U' ) ) THEN
536 ELSE IF( LSAME( DIST, 'S' ) ) THEN
538 ELSE IF( LSAME( DIST, 'N' ) ) THEN
546 IF( LSAME( SYM, 'S' ) ) THEN
548 ELSE IF( LSAME( SYM, 'N' ) ) THEN
550 ELSE IF( LSAME( SYM, 'H' ) ) THEN
558 IF( LSAME( RSIGN, 'F' ) ) THEN
560 ELSE IF( LSAME( RSIGN, 'T' ) ) THEN
568 IF( LSAME( PIVTNG, 'N' ) ) THEN
570 ELSE IF( LSAME( PIVTNG, ' ' ) ) THEN
572 ELSE IF( LSAME( PIVTNG, 'L' ) ) THEN
575 ELSE IF( LSAME( PIVTNG, 'R' ) ) THEN
578 ELSE IF( LSAME( PIVTNG, 'B' ) ) THEN
581 ELSE IF( LSAME( PIVTNG, 'F' ) ) THEN
590 IF( LSAME( GRADE, 'N' ) ) THEN
592 ELSE IF( LSAME( GRADE, 'L' ) ) THEN
594 ELSE IF( LSAME( GRADE, 'R' ) ) THEN
596 ELSE IF( LSAME( GRADE, 'B' ) ) THEN
598 ELSE IF( LSAME( GRADE, 'E' ) ) THEN
600 ELSE IF( LSAME( GRADE, 'H' ) .OR. LSAME( GRADE, 'S' ) ) THEN
608 IF( LSAME( PACK, 'N' ) ) THEN
610 ELSE IF( LSAME( PACK, 'U' ) ) THEN
612 ELSE IF( LSAME( PACK, 'L' ) ) THEN
614 ELSE IF( LSAME( PACK, 'C' ) ) THEN
616 ELSE IF( LSAME( PACK, 'R' ) ) THEN
618 ELSE IF( LSAME( PACK, 'B' ) ) THEN
620 ELSE IF( LSAME( PACK, 'Q' ) ) THEN
622 ELSE IF( LSAME( PACK, 'Z' ) ) THEN
628 * Set certain internal parameters
634 * If inv(DL) is used, check to see if DL has a zero entry.
637 IF( IGRADE.EQ.4 .AND. MODEL.EQ.0 ) THEN
639 IF( DL( I ).EQ.ZERO )
644 * Check values in IPIVOT
647 IF( IPVTNG.GT.0 ) THEN
649 IF( IPIVOT( J ).LE.0 .OR. IPIVOT( J ).GT.NPVTS )
654 * Set INFO if an error
658 ELSE IF( M.NE.N .AND. ISYM.EQ.0 ) THEN
660 ELSE IF( N.LT.0 ) THEN
662 ELSE IF( IDIST.EQ.-1 ) THEN
664 ELSE IF( ISYM.EQ.-1 ) THEN
666 ELSE IF( MODE.LT.-6 .OR. MODE.GT.6 ) THEN
668 ELSE IF( ( MODE.NE.-6 .AND. MODE.NE.0 .AND. MODE.NE.6 ) .AND.
671 ELSE IF( ( MODE.NE.-6 .AND. MODE.NE.0 .AND. MODE.NE.6 ) .AND.
672 $ IRSIGN.EQ.-1 ) THEN
674 ELSE IF( IGRADE.EQ.-1 .OR. ( IGRADE.EQ.4 .AND. M.NE.N ) .OR.
675 $ ( ( IGRADE.GE.1 .AND. IGRADE.LE.4 ) .AND. ISYM.EQ.0 ) )
678 ELSE IF( IGRADE.EQ.4 .AND. DZERO ) THEN
680 ELSE IF( ( IGRADE.EQ.1 .OR. IGRADE.EQ.3 .OR. IGRADE.EQ.4 .OR.
681 $ IGRADE.EQ.5 ) .AND. ( MODEL.LT.-6 .OR. MODEL.GT.6 ) )
684 ELSE IF( ( IGRADE.EQ.1 .OR. IGRADE.EQ.3 .OR. IGRADE.EQ.4 .OR.
685 $ IGRADE.EQ.5 ) .AND. ( MODEL.NE.-6 .AND. MODEL.NE.0 .AND.
686 $ MODEL.NE.6 ) .AND. CONDL.LT.ONE ) THEN
688 ELSE IF( ( IGRADE.EQ.2 .OR. IGRADE.EQ.3 ) .AND.
689 $ ( MODER.LT.-6 .OR. MODER.GT.6 ) ) THEN
691 ELSE IF( ( IGRADE.EQ.2 .OR. IGRADE.EQ.3 ) .AND.
692 $ ( MODER.NE.-6 .AND. MODER.NE.0 .AND. MODER.NE.6 ) .AND.
693 $ CONDR.LT.ONE ) THEN
695 ELSE IF( IPVTNG.EQ.-1 .OR. ( IPVTNG.EQ.3 .AND. M.NE.N ) .OR.
696 $ ( ( IPVTNG.EQ.1 .OR. IPVTNG.EQ.2 ) .AND. ISYM.EQ.0 ) )
699 ELSE IF( IPVTNG.NE.0 .AND. BADPVT ) THEN
701 ELSE IF( KL.LT.0 ) THEN
703 ELSE IF( KU.LT.0 .OR. ( ISYM.EQ.0 .AND. KL.NE.KU ) ) THEN
705 ELSE IF( SPARSE.LT.ZERO .OR. SPARSE.GT.ONE ) THEN
707 ELSE IF( IPACK.EQ.-1 .OR. ( ( IPACK.EQ.1 .OR. IPACK.EQ.2 .OR.
708 $ IPACK.EQ.5 .OR. IPACK.EQ.6 ) .AND. ISYM.EQ.1 ) .OR.
709 $ ( IPACK.EQ.3 .AND. ISYM.EQ.1 .AND. ( KL.NE.0 .OR. M.NE.
710 $ N ) ) .OR. ( IPACK.EQ.4 .AND. ISYM.EQ.1 .AND. ( KU.NE.
711 $ 0 .OR. M.NE.N ) ) ) THEN
713 ELSE IF( ( ( IPACK.EQ.0 .OR. IPACK.EQ.1 .OR. IPACK.EQ.2 ) .AND.
714 $ LDA.LT.MAX( 1, M ) ) .OR. ( ( IPACK.EQ.3 .OR. IPACK.EQ.
715 $ 4 ) .AND. LDA.LT.1 ) .OR. ( ( IPACK.EQ.5 .OR. IPACK.EQ.
716 $ 6 ) .AND. LDA.LT.KUU+1 ) .OR.
717 $ ( IPACK.EQ.7 .AND. LDA.LT.KLL+KUU+1 ) ) THEN
722 CALL XERBLA( 'SLATMR', -INFO )
726 * Decide if we can pivot consistently
729 IF( KUU.EQ.N-1 .AND. KLL.EQ.M-1 )
732 * Initialize random number generator
735 ISEED( I ) = MOD( ABS( ISEED( I ) ), 4096 )
738 ISEED( 4 ) = 2*( ISEED( 4 ) / 2 ) + 1
740 * 2) Set up D, DL, and DR, if indicated.
742 * Compute D according to COND and MODE
744 CALL SLATM1( MODE, COND, IRSIGN, IDIST, ISEED, D, MNMIN, INFO )
749 IF( MODE.NE.0 .AND. MODE.NE.-6 .AND. MODE.NE.6 ) THEN
755 TEMP = MAX( TEMP, ABS( D( I ) ) )
757 IF( TEMP.EQ.ZERO .AND. DMAX.NE.ZERO ) THEN
761 IF( TEMP.NE.ZERO ) THEN
767 D( I ) = ALPHA*D( I )
772 * Compute DL if grading set
774 IF( IGRADE.EQ.1 .OR. IGRADE.EQ.3 .OR. IGRADE.EQ.4 .OR. IGRADE.EQ.
776 CALL SLATM1( MODEL, CONDL, 0, IDIST, ISEED, DL, M, INFO )
783 * Compute DR if grading set
785 IF( IGRADE.EQ.2 .OR. IGRADE.EQ.3 ) THEN
786 CALL SLATM1( MODER, CONDR, 0, IDIST, ISEED, DR, N, INFO )
793 * 3) Generate IWORK if pivoting
795 IF( IPVTNG.GT.0 ) THEN
803 IWORK( I ) = IWORK( K )
807 DO 80 I = NPVTS, 1, -1
810 IWORK( I ) = IWORK( K )
816 * 4) Generate matrices for each kind of PACKing
817 * Always sweep matrix columnwise (if symmetric, upper
818 * half only) so that matrix generated does not depend
823 * Use SLATM3 so matrices generated with differing PIVOTing only
824 * differ only in the order of their rows and/or columns.
826 IF( IPACK.EQ.0 ) THEN
830 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU,
831 $ IDIST, ISEED, D, IGRADE, DL, DR, IPVTNG,
833 A( ISUB, JSUB ) = TEMP
834 A( JSUB, ISUB ) = TEMP
837 ELSE IF( ISYM.EQ.1 ) THEN
840 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU,
841 $ IDIST, ISEED, D, IGRADE, DL, DR, IPVTNG,
843 A( ISUB, JSUB ) = TEMP
848 ELSE IF( IPACK.EQ.1 ) THEN
852 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU, IDIST,
853 $ ISEED, D, IGRADE, DL, DR, IPVTNG, IWORK,
855 MNSUB = MIN( ISUB, JSUB )
856 MXSUB = MAX( ISUB, JSUB )
857 A( MNSUB, MXSUB ) = TEMP
859 $ A( MXSUB, MNSUB ) = ZERO
863 ELSE IF( IPACK.EQ.2 ) THEN
867 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU, IDIST,
868 $ ISEED, D, IGRADE, DL, DR, IPVTNG, IWORK,
870 MNSUB = MIN( ISUB, JSUB )
871 MXSUB = MAX( ISUB, JSUB )
872 A( MXSUB, MNSUB ) = TEMP
874 $ A( MNSUB, MXSUB ) = ZERO
878 ELSE IF( IPACK.EQ.3 ) THEN
882 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU, IDIST,
883 $ ISEED, D, IGRADE, DL, DR, IPVTNG, IWORK,
886 * Compute K = location of (ISUB,JSUB) entry in packed
889 MNSUB = MIN( ISUB, JSUB )
890 MXSUB = MAX( ISUB, JSUB )
891 K = MXSUB*( MXSUB-1 ) / 2 + MNSUB
893 * Convert K to (IISUB,JJSUB) location
895 JJSUB = ( K-1 ) / LDA + 1
896 IISUB = K - LDA*( JJSUB-1 )
898 A( IISUB, JJSUB ) = TEMP
902 ELSE IF( IPACK.EQ.4 ) THEN
906 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU, IDIST,
907 $ ISEED, D, IGRADE, DL, DR, IPVTNG, IWORK,
910 * Compute K = location of (I,J) entry in packed array
912 MNSUB = MIN( ISUB, JSUB )
913 MXSUB = MAX( ISUB, JSUB )
914 IF( MNSUB.EQ.1 ) THEN
917 K = N*( N+1 ) / 2 - ( N-MNSUB+1 )*( N-MNSUB+2 ) /
918 $ 2 + MXSUB - MNSUB + 1
921 * Convert K to (IISUB,JJSUB) location
923 JJSUB = ( K-1 ) / LDA + 1
924 IISUB = K - LDA*( JJSUB-1 )
926 A( IISUB, JJSUB ) = TEMP
930 ELSE IF( IPACK.EQ.5 ) THEN
933 DO 210 I = J - KUU, J
935 A( J-I+1, I+N ) = ZERO
937 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU,
938 $ IDIST, ISEED, D, IGRADE, DL, DR, IPVTNG,
940 MNSUB = MIN( ISUB, JSUB )
941 MXSUB = MAX( ISUB, JSUB )
942 A( MXSUB-MNSUB+1, MNSUB ) = TEMP
947 ELSE IF( IPACK.EQ.6 ) THEN
950 DO 230 I = J - KUU, J
951 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU, IDIST,
952 $ ISEED, D, IGRADE, DL, DR, IPVTNG, IWORK,
954 MNSUB = MIN( ISUB, JSUB )
955 MXSUB = MAX( ISUB, JSUB )
956 A( MNSUB-MXSUB+KUU+1, MXSUB ) = TEMP
960 ELSE IF( IPACK.EQ.7 ) THEN
964 DO 250 I = J - KUU, J
965 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU,
966 $ IDIST, ISEED, D, IGRADE, DL, DR, IPVTNG,
968 MNSUB = MIN( ISUB, JSUB )
969 MXSUB = MAX( ISUB, JSUB )
970 A( MNSUB-MXSUB+KUU+1, MXSUB ) = TEMP
972 $ A( J-I+1+KUU, I+N ) = ZERO
973 IF( I.GE.1 .AND. MNSUB.NE.MXSUB )
974 $ A( MXSUB-MNSUB+1+KUU, MNSUB ) = TEMP
977 ELSE IF( ISYM.EQ.1 ) THEN
979 DO 270 I = J - KUU, J + KLL
980 TEMP = SLATM3( M, N, I, J, ISUB, JSUB, KL, KU,
981 $ IDIST, ISEED, D, IGRADE, DL, DR, IPVTNG,
983 A( ISUB-JSUB+KUU+1, JSUB ) = TEMP
994 IF( IPACK.EQ.0 ) THEN
998 A( I, J ) = SLATM2( M, N, I, J, KL, KU, IDIST,
999 $ ISEED, D, IGRADE, DL, DR, IPVTNG,
1001 A( J, I ) = A( I, J )
1004 ELSE IF( ISYM.EQ.1 ) THEN
1007 A( I, J ) = SLATM2( M, N, I, J, KL, KU, IDIST,
1008 $ ISEED, D, IGRADE, DL, DR, IPVTNG,
1014 ELSE IF( IPACK.EQ.1 ) THEN
1018 A( I, J ) = SLATM2( M, N, I, J, KL, KU, IDIST, ISEED,
1019 $ D, IGRADE, DL, DR, IPVTNG, IWORK, SPARSE )
1025 ELSE IF( IPACK.EQ.2 ) THEN
1029 A( J, I ) = SLATM2( M, N, I, J, KL, KU, IDIST, ISEED,
1030 $ D, IGRADE, DL, DR, IPVTNG, IWORK, SPARSE )
1036 ELSE IF( IPACK.EQ.3 ) THEN
1043 IF( ISUB.GT.LDA ) THEN
1047 A( ISUB, JSUB ) = SLATM2( M, N, I, J, KL, KU, IDIST,
1048 $ ISEED, D, IGRADE, DL, DR, IPVTNG,
1053 ELSE IF( IPACK.EQ.4 ) THEN
1055 IF( ISYM.EQ.0 ) THEN
1059 * Compute K = location of (I,J) entry in packed array
1064 K = N*( N+1 ) / 2 - ( N-I+1 )*( N-I+2 ) / 2 +
1068 * Convert K to (ISUB,JSUB) location
1070 JSUB = ( K-1 ) / LDA + 1
1071 ISUB = K - LDA*( JSUB-1 )
1073 A( ISUB, JSUB ) = SLATM2( M, N, I, J, KL, KU,
1074 $ IDIST, ISEED, D, IGRADE, DL, DR,
1075 $ IPVTNG, IWORK, SPARSE )
1084 IF( ISUB.GT.LDA ) THEN
1088 A( ISUB, JSUB ) = SLATM2( M, N, I, J, KL, KU,
1089 $ IDIST, ISEED, D, IGRADE, DL, DR,
1090 $ IPVTNG, IWORK, SPARSE )
1095 ELSE IF( IPACK.EQ.5 ) THEN
1098 DO 430 I = J - KUU, J
1100 A( J-I+1, I+N ) = ZERO
1102 A( J-I+1, I ) = SLATM2( M, N, I, J, KL, KU, IDIST,
1103 $ ISEED, D, IGRADE, DL, DR, IPVTNG,
1109 ELSE IF( IPACK.EQ.6 ) THEN
1112 DO 450 I = J - KUU, J
1113 A( I-J+KUU+1, J ) = SLATM2( M, N, I, J, KL, KU, IDIST,
1114 $ ISEED, D, IGRADE, DL, DR, IPVTNG,
1119 ELSE IF( IPACK.EQ.7 ) THEN
1121 IF( ISYM.EQ.0 ) THEN
1123 DO 470 I = J - KUU, J
1124 A( I-J+KUU+1, J ) = SLATM2( M, N, I, J, KL, KU,
1125 $ IDIST, ISEED, D, IGRADE, DL,
1126 $ DR, IPVTNG, IWORK, SPARSE )
1128 $ A( J-I+1+KUU, I+N ) = ZERO
1129 IF( I.GE.1 .AND. I.NE.J )
1130 $ A( J-I+1+KUU, I ) = A( I-J+KUU+1, J )
1133 ELSE IF( ISYM.EQ.1 ) THEN
1135 DO 490 I = J - KUU, J + KLL
1136 A( I-J+KUU+1, J ) = SLATM2( M, N, I, J, KL, KU,
1137 $ IDIST, ISEED, D, IGRADE, DL,
1138 $ DR, IPVTNG, IWORK, SPARSE )
1147 * 5) Scaling the norm
1149 IF( IPACK.EQ.0 ) THEN
1150 ONORM = SLANGE( 'M', M, N, A, LDA, TEMPA )
1151 ELSE IF( IPACK.EQ.1 ) THEN
1152 ONORM = SLANSY( 'M', 'U', N, A, LDA, TEMPA )
1153 ELSE IF( IPACK.EQ.2 ) THEN
1154 ONORM = SLANSY( 'M', 'L', N, A, LDA, TEMPA )
1155 ELSE IF( IPACK.EQ.3 ) THEN
1156 ONORM = SLANSP( 'M', 'U', N, A, TEMPA )
1157 ELSE IF( IPACK.EQ.4 ) THEN
1158 ONORM = SLANSP( 'M', 'L', N, A, TEMPA )
1159 ELSE IF( IPACK.EQ.5 ) THEN
1160 ONORM = SLANSB( 'M', 'L', N, KLL, A, LDA, TEMPA )
1161 ELSE IF( IPACK.EQ.6 ) THEN
1162 ONORM = SLANSB( 'M', 'U', N, KUU, A, LDA, TEMPA )
1163 ELSE IF( IPACK.EQ.7 ) THEN
1164 ONORM = SLANGB( 'M', N, KLL, KUU, A, LDA, TEMPA )
1167 IF( ANORM.GE.ZERO ) THEN
1169 IF( ANORM.GT.ZERO .AND. ONORM.EQ.ZERO ) THEN
1171 * Desired scaling impossible
1176 ELSE IF( ( ANORM.GT.ONE .AND. ONORM.LT.ONE ) .OR.
1177 $ ( ANORM.LT.ONE .AND. ONORM.GT.ONE ) ) THEN
1179 * Scale carefully to avoid over / underflow
1181 IF( IPACK.LE.2 ) THEN
1183 CALL SSCAL( M, ONE / ONORM, A( 1, J ), 1 )
1184 CALL SSCAL( M, ANORM, A( 1, J ), 1 )
1187 ELSE IF( IPACK.EQ.3 .OR. IPACK.EQ.4 ) THEN
1189 CALL SSCAL( N*( N+1 ) / 2, ONE / ONORM, A, 1 )
1190 CALL SSCAL( N*( N+1 ) / 2, ANORM, A, 1 )
1192 ELSE IF( IPACK.GE.5 ) THEN
1195 CALL SSCAL( KLL+KUU+1, ONE / ONORM, A( 1, J ), 1 )
1196 CALL SSCAL( KLL+KUU+1, ANORM, A( 1, J ), 1 )
1203 * Scale straightforwardly
1205 IF( IPACK.LE.2 ) THEN
1207 CALL SSCAL( M, ANORM / ONORM, A( 1, J ), 1 )
1210 ELSE IF( IPACK.EQ.3 .OR. IPACK.EQ.4 ) THEN
1212 CALL SSCAL( N*( N+1 ) / 2, ANORM / ONORM, A, 1 )
1214 ELSE IF( IPACK.GE.5 ) THEN
1217 CALL SSCAL( KLL+KUU+1, ANORM / ONORM, A( 1, J ), 1 )