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