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