LAPACK 3.3.0

zlatmt.f

Go to the documentation of this file.
00001       SUBROUTINE ZLATMT( M, N, DIST, ISEED, SYM, D, MODE, COND, DMAX,
00002      $                   RANK, KL, KU, PACK, A, LDA, WORK, INFO )
00003 *
00004 *  -- LAPACK test routine (version 3.1) --
00005 *     Craig Lucas, University of Manchester / NAG Ltd.
00006 *     October, 2008
00007 *
00008 *     .. Scalar Arguments ..
00009       DOUBLE PRECISION   COND, DMAX
00010       INTEGER            INFO, KL, KU, LDA, M, MODE, N, RANK
00011       CHARACTER          DIST, PACK, SYM
00012 *     ..
00013 *     .. Array Arguments ..
00014       COMPLEX*16         A( LDA, * ), WORK( * )
00015       DOUBLE PRECISION   D( * )
00016       INTEGER            ISEED( 4 )
00017 *     ..
00018 *
00019 *  Purpose
00020 *  =======
00021 *
00022 *     ZLATMT generates random matrices with specified singular values
00023 *     (or hermitian with specified eigenvalues)
00024 *     for testing LAPACK programs.
00025 *
00026 *     ZLATMT operates by applying the following sequence of
00027 *     operations:
00028 *
00029 *       Set the diagonal to D, where D may be input or
00030 *          computed according to MODE, COND, DMAX, and SYM
00031 *          as described below.
00032 *
00033 *       Generate a matrix with the appropriate band structure, by one
00034 *          of two methods:
00035 *
00036 *       Method A:
00037 *           Generate a dense M x N matrix by multiplying D on the left
00038 *               and the right by random unitary matrices, then:
00039 *
00040 *           Reduce the bandwidth according to KL and KU, using
00041 *               Householder transformations.
00042 *
00043 *       Method B:
00044 *           Convert the bandwidth-0 (i.e., diagonal) matrix to a
00045 *               bandwidth-1 matrix using Givens rotations, "chasing"
00046 *               out-of-band elements back, much as in QR; then convert
00047 *               the bandwidth-1 to a bandwidth-2 matrix, etc.  Note
00048 *               that for reasonably small bandwidths (relative to M and
00049 *               N) this requires less storage, as a dense matrix is not
00050 *               generated.  Also, for hermitian or symmetric matrices,
00051 *               only one triangle is generated.
00052 *
00053 *       Method A is chosen if the bandwidth is a large fraction of the
00054 *           order of the matrix, and LDA is at least M (so a dense
00055 *           matrix can be stored.)  Method B is chosen if the bandwidth
00056 *           is small (< 1/2 N for hermitian or symmetric, < .3 N+M for
00057 *           non-symmetric), or LDA is less than M and not less than the
00058 *           bandwidth.
00059 *
00060 *       Pack the matrix if desired. Options specified by PACK are:
00061 *          no packing
00062 *          zero out upper half (if hermitian)
00063 *          zero out lower half (if hermitian)
00064 *          store the upper half columnwise (if hermitian or upper
00065 *                triangular)
00066 *          store the lower half columnwise (if hermitian or lower
00067 *                triangular)
00068 *          store the lower triangle in banded format (if hermitian or
00069 *                lower triangular)
00070 *          store the upper triangle in banded format (if hermitian or
00071 *                upper triangular)
00072 *          store the entire matrix in banded format
00073 *       If Method B is chosen, and band format is specified, then the
00074 *          matrix will be generated in the band format, so no repacking
00075 *          will be necessary.
00076 *
00077 *  Arguments
00078 *  =========
00079 *
00080 *  M        (input) INTEGER
00081 *           The number of rows of A. Not modified.
00082 *
00083 *  N        (input) INTEGER
00084 *           The number of columns of A. N must equal M if the matrix
00085 *           is symmetric or hermitian (i.e., if SYM is not 'N')
00086 *           Not modified.
00087 *
00088 *  DIST     (input) CHARACTER*1
00089 *           On entry, DIST specifies the type of distribution to be used
00090 *           to generate the random eigen-/singular values.
00091 *           'U' => UNIFORM( 0, 1 )  ( 'U' for uniform )
00092 *           'S' => UNIFORM( -1, 1 ) ( 'S' for symmetric )
00093 *           'N' => NORMAL( 0, 1 )   ( 'N' for normal )
00094 *           Not modified.
00095 *
00096 *  ISEED    (input/output) INTEGER array, dimension ( 4 )
00097 *           On entry ISEED specifies the seed of the random number
00098 *           generator. They should lie between 0 and 4095 inclusive,
00099 *           and ISEED(4) should be odd. The random number generator
00100 *           uses a linear congruential sequence limited to small
00101 *           integers, and so should produce machine independent
00102 *           random numbers. The values of ISEED are changed on
00103 *           exit, and can be used in the next call to ZLATMT
00104 *           to continue the same random number sequence.
00105 *           Changed on exit.
00106 *
00107 *  SYM      (input) CHARACTER*1
00108 *           If SYM='H', the generated matrix is hermitian, with
00109 *             eigenvalues specified by D, COND, MODE, and DMAX; they
00110 *             may be positive, negative, or zero.
00111 *           If SYM='P', the generated matrix is hermitian, with
00112 *             eigenvalues (= singular values) specified by D, COND,
00113 *             MODE, and DMAX; they will not be negative.
00114 *           If SYM='N', the generated matrix is nonsymmetric, with
00115 *             singular values specified by D, COND, MODE, and DMAX;
00116 *             they will not be negative.
00117 *           If SYM='S', the generated matrix is (complex) symmetric,
00118 *             with singular values specified by D, COND, MODE, and
00119 *             DMAX; they will not be negative.
00120 *           Not modified.
00121 *
00122 *  D        (input/output) DOUBLE PRECISION array, dimension ( MIN( M, N ) )
00123 *           This array is used to specify the singular values or
00124 *           eigenvalues of A (see SYM, above.)  If MODE=0, then D is
00125 *           assumed to contain the singular/eigenvalues, otherwise
00126 *           they will be computed according to MODE, COND, and DMAX,
00127 *           and placed in D.
00128 *           Modified if MODE is nonzero.
00129 *
00130 *  MODE     (input) INTEGER
00131 *           On entry this describes how the singular/eigenvalues are to
00132 *           be specified:
00133 *           MODE = 0 means use D as input
00134 *           MODE = 1 sets D(1)=1 and D(2:RANK)=1.0/COND
00135 *           MODE = 2 sets D(1:RANK-1)=1 and D(RANK)=1.0/COND
00136 *           MODE = 3 sets D(I)=COND**(-(I-1)/(RANK-1))
00137 *           MODE = 4 sets D(i)=1 - (i-1)/(N-1)*(1 - 1/COND)
00138 *           MODE = 5 sets D to random numbers in the range
00139 *                    ( 1/COND , 1 ) such that their logarithms
00140 *                    are uniformly distributed.
00141 *           MODE = 6 set D to random numbers from same distribution
00142 *                    as the rest of the matrix.
00143 *           MODE < 0 has the same meaning as ABS(MODE), except that
00144 *              the order of the elements of D is reversed.
00145 *           Thus if MODE is positive, D has entries ranging from
00146 *              1 to 1/COND, if negative, from 1/COND to 1,
00147 *           If SYM='H', and MODE is neither 0, 6, nor -6, then
00148 *              the elements of D will also be multiplied by a random
00149 *              sign (i.e., +1 or -1.)
00150 *           Not modified.
00151 *
00152 *  COND     (input) DOUBLE PRECISION
00153 *           On entry, this is used as described under MODE above.
00154 *           If used, it must be >= 1. Not modified.
00155 *
00156 *  DMAX     (input) DOUBLE PRECISION
00157 *           If MODE is neither -6, 0 nor 6, the contents of D, as
00158 *           computed according to MODE and COND, will be scaled by
00159 *           DMAX / max(abs(D(i))); thus, the maximum absolute eigen- or
00160 *           singular value (which is to say the norm) will be abs(DMAX).
00161 *           Note that DMAX need not be positive: if DMAX is negative
00162 *           (or zero), D will be scaled by a negative number (or zero).
00163 *           Not modified.
00164 *
00165 *  RANK     (input) INTEGER
00166 *           The rank of matrix to be generated for modes 1,2,3 only.
00167 *           D( RANK+1:N ) = 0.
00168 *           Not modified.
00169 *
00170 *  KL       (input) INTEGER
00171 *           This specifies the lower bandwidth of the  matrix. For
00172 *           example, KL=0 implies upper triangular, KL=1 implies upper
00173 *           Hessenberg, and KL being at least M-1 means that the matrix
00174 *           has full lower bandwidth.  KL must equal KU if the matrix
00175 *           is symmetric or hermitian.
00176 *           Not modified.
00177 *
00178 *  KU       (input) INTEGER
00179 *           This specifies the upper bandwidth of the  matrix. For
00180 *           example, KU=0 implies lower triangular, KU=1 implies lower
00181 *           Hessenberg, and KU being at least N-1 means that the matrix
00182 *           has full upper bandwidth.  KL must equal KU if the matrix
00183 *           is symmetric or hermitian.
00184 *           Not modified.
00185 *
00186 *  PACK     (input) CHARACTER*1
00187 *           This specifies packing of matrix as follows:
00188 *           'N' => no packing
00189 *           'U' => zero out all subdiagonal entries (if symmetric
00190 *                  or hermitian)
00191 *           'L' => zero out all superdiagonal entries (if symmetric
00192 *                  or hermitian)
00193 *           'C' => store the upper triangle columnwise (only if the
00194 *                  matrix is symmetric, hermitian, or upper triangular)
00195 *           'R' => store the lower triangle columnwise (only if the
00196 *                  matrix is symmetric, hermitian, or lower triangular)
00197 *           'B' => store the lower triangle in band storage scheme
00198 *                  (only if the matrix is symmetric, hermitian, or
00199 *                  lower triangular)
00200 *           'Q' => store the upper triangle in band storage scheme
00201 *                  (only if the matrix is symmetric, hermitian, or
00202 *                  upper triangular)
00203 *           'Z' => store the entire matrix in band storage scheme
00204 *                      (pivoting can be provided for by using this
00205 *                      option to store A in the trailing rows of
00206 *                      the allocated storage)
00207 *
00208 *           Using these options, the various LAPACK packed and banded
00209 *           storage schemes can be obtained:
00210 *           GB                    - use 'Z'
00211 *           PB, SB, HB, or TB     - use 'B' or 'Q'
00212 *           PP, SP, HB, or TP     - use 'C' or 'R'
00213 *
00214 *           If two calls to ZLATMT differ only in the PACK parameter,
00215 *           they will generate mathematically equivalent matrices.
00216 *           Not modified.
00217 *
00218 *  A        (input/output) COMPLEX*16 array, dimension ( LDA, N )
00219 *           On exit A is the desired test matrix.  A is first generated
00220 *           in full (unpacked) form, and then packed, if so specified
00221 *           by PACK.  Thus, the first M elements of the first N
00222 *           columns will always be modified.  If PACK specifies a
00223 *           packed or banded storage scheme, all LDA elements of the
00224 *           first N columns will be modified; the elements of the
00225 *           array which do not correspond to elements of the generated
00226 *           matrix are set to zero.
00227 *           Modified.
00228 *
00229 *  LDA      (input) INTEGER
00230 *           LDA specifies the first dimension of A as declared in the
00231 *           calling program.  If PACK='N', 'U', 'L', 'C', or 'R', then
00232 *           LDA must be at least M.  If PACK='B' or 'Q', then LDA must
00233 *           be at least MIN( KL, M-1) (which is equal to MIN(KU,N-1)).
00234 *           If PACK='Z', LDA must be large enough to hold the packed
00235 *           array: MIN( KU, N-1) + MIN( KL, M-1) + 1.
00236 *           Not modified.
00237 *
00238 *  WORK     (workspace) COMPLEX*16 array, dimension ( 3*MAX( N, M ) )
00239 *           Workspace.
00240 *           Modified.
00241 *
00242 *  INFO     (output) INTEGER
00243 *           Error code.  On exit, INFO will be set to one of the
00244 *           following values:
00245 *             0 => normal return
00246 *            -1 => M negative or unequal to N and SYM='S', 'H', or 'P'
00247 *            -2 => N negative
00248 *            -3 => DIST illegal string
00249 *            -5 => SYM illegal string
00250 *            -7 => MODE not in range -6 to 6
00251 *            -8 => COND less than 1.0, and MODE neither -6, 0 nor 6
00252 *           -10 => KL negative
00253 *           -11 => KU negative, or SYM is not 'N' and KU is not equal to
00254 *                  KL
00255 *           -12 => PACK illegal string, or PACK='U' or 'L', and SYM='N';
00256 *                  or PACK='C' or 'Q' and SYM='N' and KL is not zero;
00257 *                  or PACK='R' or 'B' and SYM='N' and KU is not zero;
00258 *                  or PACK='U', 'L', 'C', 'R', 'B', or 'Q', and M is not
00259 *                  N.
00260 *           -14 => LDA is less than M, or PACK='Z' and LDA is less than
00261 *                  MIN(KU,N-1) + MIN(KL,M-1) + 1.
00262 *            1  => Error return from DLATM7
00263 *            2  => Cannot scale to DMAX (max. sing. value is 0)
00264 *            3  => Error return from ZLAGGE, ZLAGHE or ZLAGSY
00265 *
00266 *  =====================================================================
00267 *
00268 *     .. Parameters ..
00269       DOUBLE PRECISION   ZERO
00270       PARAMETER          ( ZERO = 0.0D+0 )
00271       DOUBLE PRECISION   ONE
00272       PARAMETER          ( ONE = 1.0D+0 )
00273       COMPLEX*16         CZERO
00274       PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ) )
00275       DOUBLE PRECISION   TWOPI
00276       PARAMETER          ( TWOPI = 6.2831853071795864769252867663D+0 )
00277 *     ..
00278 *     .. Local Scalars ..
00279       COMPLEX*16         C, CT, DUMMY, EXTRA, S, ST, ZTEMP
00280       DOUBLE PRECISION   ALPHA, ANGLE, REALC, TEMP
00281       INTEGER            I, IC, ICOL, IDIST, IENDCH, IINFO, IL, ILDA,
00282      $                   IOFFG, IOFFST, IPACK, IPACKG, IR, IR1, IR2,
00283      $                   IROW, IRSIGN, ISKEW, ISYM, ISYMPK, J, JC, JCH,
00284      $                   JKL, JKU, JR, K, LLB, MINLDA, MNMIN, MR, NC,
00285      $                   UUB
00286       LOGICAL            CSYM, GIVENS, ILEXTR, ILTEMP, TOPDWN
00287 *     ..
00288 *     .. External Functions ..
00289       COMPLEX*16         ZLARND
00290       DOUBLE PRECISION   DLARND
00291       LOGICAL            LSAME
00292       EXTERNAL           ZLARND, DLARND, LSAME
00293 *     ..
00294 *     .. External Subroutines ..
00295       EXTERNAL           DLATM7, DSCAL, XERBLA, ZLAGGE, ZLAGHE,
00296      $                   ZLAGSY, ZLAROT, ZLARTG, ZLASET
00297 *     ..
00298 *     .. Intrinsic Functions ..
00299       INTRINSIC          ABS, COS, DBLE, DCMPLX, DCONJG, MAX, MIN, MOD,
00300      $                   SIN
00301 *     ..
00302 *     .. Executable Statements ..
00303 *
00304 *     1)      Decode and Test the input parameters.
00305 *             Initialize flags & seed.
00306 *
00307       INFO = 0
00308 *
00309 *     Quick return if possible
00310 *
00311       IF( M.EQ.0 .OR. N.EQ.0 )
00312      $   RETURN
00313 *
00314 *     Decode DIST
00315 *
00316       IF( LSAME( DIST, 'U' ) ) THEN
00317          IDIST = 1
00318       ELSE IF( LSAME( DIST, 'S' ) ) THEN
00319          IDIST = 2
00320       ELSE IF( LSAME( DIST, 'N' ) ) THEN
00321          IDIST = 3
00322       ELSE
00323          IDIST = -1
00324       END IF
00325 *
00326 *     Decode SYM
00327 *
00328       IF( LSAME( SYM, 'N' ) ) THEN
00329          ISYM = 1
00330          IRSIGN = 0
00331          CSYM = .FALSE.
00332       ELSE IF( LSAME( SYM, 'P' ) ) THEN
00333          ISYM = 2
00334          IRSIGN = 0
00335          CSYM = .FALSE.
00336       ELSE IF( LSAME( SYM, 'S' ) ) THEN
00337          ISYM = 2
00338          IRSIGN = 0
00339          CSYM = .TRUE.
00340       ELSE IF( LSAME( SYM, 'H' ) ) THEN
00341          ISYM = 2
00342          IRSIGN = 1
00343          CSYM = .FALSE.
00344       ELSE
00345          ISYM = -1
00346       END IF
00347 *
00348 *     Decode PACK
00349 *
00350       ISYMPK = 0
00351       IF( LSAME( PACK, 'N' ) ) THEN
00352          IPACK = 0
00353       ELSE IF( LSAME( PACK, 'U' ) ) THEN
00354          IPACK = 1
00355          ISYMPK = 1
00356       ELSE IF( LSAME( PACK, 'L' ) ) THEN
00357          IPACK = 2
00358          ISYMPK = 1
00359       ELSE IF( LSAME( PACK, 'C' ) ) THEN
00360          IPACK = 3
00361          ISYMPK = 2
00362       ELSE IF( LSAME( PACK, 'R' ) ) THEN
00363          IPACK = 4
00364          ISYMPK = 3
00365       ELSE IF( LSAME( PACK, 'B' ) ) THEN
00366          IPACK = 5
00367          ISYMPK = 3
00368       ELSE IF( LSAME( PACK, 'Q' ) ) THEN
00369          IPACK = 6
00370          ISYMPK = 2
00371       ELSE IF( LSAME( PACK, 'Z' ) ) THEN
00372          IPACK = 7
00373       ELSE
00374          IPACK = -1
00375       END IF
00376 *
00377 *     Set certain internal parameters
00378 *
00379       MNMIN = MIN( M, N )
00380       LLB = MIN( KL, M-1 )
00381       UUB = MIN( KU, N-1 )
00382       MR = MIN( M, N+LLB )
00383       NC = MIN( N, M+UUB )
00384 *
00385       IF( IPACK.EQ.5 .OR. IPACK.EQ.6 ) THEN
00386          MINLDA = UUB + 1
00387       ELSE IF( IPACK.EQ.7 ) THEN
00388          MINLDA = LLB + UUB + 1
00389       ELSE
00390          MINLDA = M
00391       END IF
00392 *
00393 *     Use Givens rotation method if bandwidth small enough,
00394 *     or if LDA is too small to store the matrix unpacked.
00395 *
00396       GIVENS = .FALSE.
00397       IF( ISYM.EQ.1 ) THEN
00398          IF( DBLE( LLB+UUB ).LT.0.3D0*DBLE( MAX( 1, MR+NC ) ) )
00399      $      GIVENS = .TRUE.
00400       ELSE
00401          IF( 2*LLB.LT.M )
00402      $      GIVENS = .TRUE.
00403       END IF
00404       IF( LDA.LT.M .AND. LDA.GE.MINLDA )
00405      $   GIVENS = .TRUE.
00406 *
00407 *     Set INFO if an error
00408 *
00409       IF( M.LT.0 ) THEN
00410          INFO = -1
00411       ELSE IF( M.NE.N .AND. ISYM.NE.1 ) THEN
00412          INFO = -1
00413       ELSE IF( N.LT.0 ) THEN
00414          INFO = -2
00415       ELSE IF( IDIST.EQ.-1 ) THEN
00416          INFO = -3
00417       ELSE IF( ISYM.EQ.-1 ) THEN
00418          INFO = -5
00419       ELSE IF( ABS( MODE ).GT.6 ) THEN
00420          INFO = -7
00421       ELSE IF( ( MODE.NE.0 .AND. ABS( MODE ).NE.6 ) .AND. COND.LT.ONE )
00422      $         THEN
00423          INFO = -8
00424       ELSE IF( KL.LT.0 ) THEN
00425          INFO = -10
00426       ELSE IF( KU.LT.0 .OR. ( ISYM.NE.1 .AND. KL.NE.KU ) ) THEN
00427          INFO = -11
00428       ELSE IF( IPACK.EQ.-1 .OR. ( ISYMPK.EQ.1 .AND. ISYM.EQ.1 ) .OR.
00429      $         ( ISYMPK.EQ.2 .AND. ISYM.EQ.1 .AND. KL.GT.0 ) .OR.
00430      $         ( ISYMPK.EQ.3 .AND. ISYM.EQ.1 .AND. KU.GT.0 ) .OR.
00431      $         ( ISYMPK.NE.0 .AND. M.NE.N ) ) THEN
00432          INFO = -12
00433       ELSE IF( LDA.LT.MAX( 1, MINLDA ) ) THEN
00434          INFO = -14
00435       END IF
00436 *
00437       IF( INFO.NE.0 ) THEN
00438          CALL XERBLA( 'ZLATMT', -INFO )
00439          RETURN
00440       END IF
00441 *
00442 *     Initialize random number generator
00443 *
00444       DO 100 I = 1, 4
00445          ISEED( I ) = MOD( ABS( ISEED( I ) ), 4096 )
00446   100 CONTINUE
00447 *
00448       IF( MOD( ISEED( 4 ), 2 ).NE.1 )
00449      $   ISEED( 4 ) = ISEED( 4 ) + 1
00450 *
00451 *     2)      Set up D  if indicated.
00452 *
00453 *             Compute D according to COND and MODE
00454 *
00455       CALL DLATM7( MODE, COND, IRSIGN, IDIST, ISEED, D, MNMIN, RANK,
00456      $             IINFO )
00457       IF( IINFO.NE.0 ) THEN
00458          INFO = 1
00459          RETURN
00460       END IF
00461 *
00462 *     Choose Top-Down if D is (apparently) increasing,
00463 *     Bottom-Up if D is (apparently) decreasing.
00464 *
00465       IF( ABS( D( 1 ) ).LE.ABS( D( RANK ) ) ) THEN
00466          TOPDWN = .TRUE.
00467       ELSE
00468          TOPDWN = .FALSE.
00469       END IF
00470 *
00471       IF( MODE.NE.0 .AND. ABS( MODE ).NE.6 ) THEN
00472 *
00473 *        Scale by DMAX
00474 *
00475          TEMP = ABS( D( 1 ) )
00476          DO 110 I = 2, RANK
00477             TEMP = MAX( TEMP, ABS( D( I ) ) )
00478   110    CONTINUE
00479 *
00480          IF( TEMP.GT.ZERO ) THEN
00481             ALPHA = DMAX / TEMP
00482          ELSE
00483             INFO = 2
00484             RETURN
00485          END IF
00486 *
00487          CALL DSCAL( RANK, ALPHA, D, 1 )
00488 *
00489       END IF
00490 *
00491       CALL ZLASET( 'Full', LDA, N, CZERO, CZERO, A, LDA )
00492 *
00493 *     3)      Generate Banded Matrix using Givens rotations.
00494 *             Also the special case of UUB=LLB=0
00495 *
00496 *               Compute Addressing constants to cover all
00497 *               storage formats.  Whether GE, HE, SY, GB, HB, or SB,
00498 *               upper or lower triangle or both,
00499 *               the (i,j)-th element is in
00500 *               A( i - ISKEW*j + IOFFST, j )
00501 *
00502       IF( IPACK.GT.4 ) THEN
00503          ILDA = LDA - 1
00504          ISKEW = 1
00505          IF( IPACK.GT.5 ) THEN
00506             IOFFST = UUB + 1
00507          ELSE
00508             IOFFST = 1
00509          END IF
00510       ELSE
00511          ILDA = LDA
00512          ISKEW = 0
00513          IOFFST = 0
00514       END IF
00515 *
00516 *     IPACKG is the format that the matrix is generated in. If this is
00517 *     different from IPACK, then the matrix must be repacked at the
00518 *     end.  It also signals how to compute the norm, for scaling.
00519 *
00520       IPACKG = 0
00521 *
00522 *     Diagonal Matrix -- We are done, unless it
00523 *     is to be stored HP/SP/PP/TP (PACK='R' or 'C')
00524 *
00525       IF( LLB.EQ.0 .AND. UUB.EQ.0 ) THEN
00526          DO 120 J = 1, MNMIN
00527             A( ( 1-ISKEW )*J+IOFFST, J ) = DCMPLX( D( J ) )
00528   120    CONTINUE
00529 *
00530          IF( IPACK.LE.2 .OR. IPACK.GE.5 )
00531      $      IPACKG = IPACK
00532 *
00533       ELSE IF( GIVENS ) THEN
00534 *
00535 *        Check whether to use Givens rotations,
00536 *        Householder transformations, or nothing.
00537 *
00538          IF( ISYM.EQ.1 ) THEN
00539 *
00540 *           Non-symmetric -- A = U D V
00541 *
00542             IF( IPACK.GT.4 ) THEN
00543                IPACKG = IPACK
00544             ELSE
00545                IPACKG = 0
00546             END IF
00547 *
00548             DO 130 J = 1, MNMIN
00549                A( ( 1-ISKEW )*J+IOFFST, J ) = DCMPLX( D( J ) )
00550   130       CONTINUE
00551 *
00552             IF( TOPDWN ) THEN
00553                JKL = 0
00554                DO 160 JKU = 1, UUB
00555 *
00556 *                 Transform from bandwidth JKL, JKU-1 to JKL, JKU
00557 *
00558 *                 Last row actually rotated is M
00559 *                 Last column actually rotated is MIN( M+JKU, N )
00560 *
00561                   DO 150 JR = 1, MIN( M+JKU, N ) + JKL - 1
00562                      EXTRA = CZERO
00563                      ANGLE = TWOPI*DLARND( 1, ISEED )
00564                      C = COS( ANGLE )*ZLARND( 5, ISEED )
00565                      S = SIN( ANGLE )*ZLARND( 5, ISEED )
00566                      ICOL = MAX( 1, JR-JKL )
00567                      IF( JR.LT.M ) THEN
00568                         IL = MIN( N, JR+JKU ) + 1 - ICOL
00569                         CALL ZLAROT( .TRUE., JR.GT.JKL, .FALSE., IL, C,
00570      $                               S, A( JR-ISKEW*ICOL+IOFFST, ICOL ),
00571      $                               ILDA, EXTRA, DUMMY )
00572                      END IF
00573 *
00574 *                    Chase "EXTRA" back up
00575 *
00576                      IR = JR
00577                      IC = ICOL
00578                      DO 140 JCH = JR - JKL, 1, -JKL - JKU
00579                         IF( IR.LT.M ) THEN
00580                            CALL ZLARTG( A( IR+1-ISKEW*( IC+1 )+IOFFST,
00581      $                                  IC+1 ), EXTRA, REALC, S, DUMMY )
00582                            DUMMY = DLARND( 5, ISEED )
00583                            C = DCONJG( REALC*DUMMY )
00584                            S = DCONJG( -S*DUMMY )
00585                         END IF
00586                         IROW = MAX( 1, JCH-JKU )
00587                         IL = IR + 2 - IROW
00588                         ZTEMP = CZERO
00589                         ILTEMP = JCH.GT.JKU
00590                         CALL ZLAROT( .FALSE., ILTEMP, .TRUE., IL, C, S,
00591      $                               A( IROW-ISKEW*IC+IOFFST, IC ),
00592      $                               ILDA, ZTEMP, EXTRA )
00593                         IF( ILTEMP ) THEN
00594                            CALL ZLARTG( A( IROW+1-ISKEW*( IC+1 )+IOFFST,
00595      $                                  IC+1 ), ZTEMP, REALC, S, DUMMY )
00596                            DUMMY = ZLARND( 5, ISEED )
00597                            C = DCONJG( REALC*DUMMY )
00598                            S = DCONJG( -S*DUMMY )
00599 *
00600                            ICOL = MAX( 1, JCH-JKU-JKL )
00601                            IL = IC + 2 - ICOL
00602                            EXTRA = CZERO
00603                            CALL ZLAROT( .TRUE., JCH.GT.JKU+JKL, .TRUE.,
00604      $                                  IL, C, S, A( IROW-ISKEW*ICOL+
00605      $                                  IOFFST, ICOL ), ILDA, EXTRA,
00606      $                                  ZTEMP )
00607                            IC = ICOL
00608                            IR = IROW
00609                         END IF
00610   140                CONTINUE
00611   150             CONTINUE
00612   160          CONTINUE
00613 *
00614                JKU = UUB
00615                DO 190 JKL = 1, LLB
00616 *
00617 *                 Transform from bandwidth JKL-1, JKU to JKL, JKU
00618 *
00619                   DO 180 JC = 1, MIN( N+JKL, M ) + JKU - 1
00620                      EXTRA = CZERO
00621                      ANGLE = TWOPI*DLARND( 1, ISEED )
00622                      C = COS( ANGLE )*ZLARND( 5, ISEED )
00623                      S = SIN( ANGLE )*ZLARND( 5, ISEED )
00624                      IROW = MAX( 1, JC-JKU )
00625                      IF( JC.LT.N ) THEN
00626                         IL = MIN( M, JC+JKL ) + 1 - IROW
00627                         CALL ZLAROT( .FALSE., JC.GT.JKU, .FALSE., IL, C,
00628      $                               S, A( IROW-ISKEW*JC+IOFFST, JC ),
00629      $                               ILDA, EXTRA, DUMMY )
00630                      END IF
00631 *
00632 *                    Chase "EXTRA" back up
00633 *
00634                      IC = JC
00635                      IR = IROW
00636                      DO 170 JCH = JC - JKU, 1, -JKL - JKU
00637                         IF( IC.LT.N ) THEN
00638                            CALL ZLARTG( A( IR+1-ISKEW*( IC+1 )+IOFFST,
00639      $                                  IC+1 ), EXTRA, REALC, S, DUMMY )
00640                            DUMMY = ZLARND( 5, ISEED )
00641                            C = DCONJG( REALC*DUMMY )
00642                            S = DCONJG( -S*DUMMY )
00643                         END IF
00644                         ICOL = MAX( 1, JCH-JKL )
00645                         IL = IC + 2 - ICOL
00646                         ZTEMP = CZERO
00647                         ILTEMP = JCH.GT.JKL
00648                         CALL ZLAROT( .TRUE., ILTEMP, .TRUE., IL, C, S,
00649      $                               A( IR-ISKEW*ICOL+IOFFST, ICOL ),
00650      $                               ILDA, ZTEMP, EXTRA )
00651                         IF( ILTEMP ) THEN
00652                            CALL ZLARTG( A( IR+1-ISKEW*( ICOL+1 )+IOFFST,
00653      $                                  ICOL+1 ), ZTEMP, REALC, S,
00654      $                                  DUMMY )
00655                            DUMMY = ZLARND( 5, ISEED )
00656                            C = DCONJG( REALC*DUMMY )
00657                            S = DCONJG( -S*DUMMY )
00658                            IROW = MAX( 1, JCH-JKL-JKU )
00659                            IL = IR + 2 - IROW
00660                            EXTRA = CZERO
00661                            CALL ZLAROT( .FALSE., JCH.GT.JKL+JKU, .TRUE.,
00662      $                                  IL, C, S, A( IROW-ISKEW*ICOL+
00663      $                                  IOFFST, ICOL ), ILDA, EXTRA,
00664      $                                  ZTEMP )
00665                            IC = ICOL
00666                            IR = IROW
00667                         END IF
00668   170                CONTINUE
00669   180             CONTINUE
00670   190          CONTINUE
00671 *
00672             ELSE
00673 *
00674 *              Bottom-Up -- Start at the bottom right.
00675 *
00676                JKL = 0
00677                DO 220 JKU = 1, UUB
00678 *
00679 *                 Transform from bandwidth JKL, JKU-1 to JKL, JKU
00680 *
00681 *                 First row actually rotated is M
00682 *                 First column actually rotated is MIN( M+JKU, N )
00683 *
00684                   IENDCH = MIN( M, N+JKL ) - 1
00685                   DO 210 JC = MIN( M+JKU, N ) - 1, 1 - JKL, -1
00686                      EXTRA = CZERO
00687                      ANGLE = TWOPI*DLARND( 1, ISEED )
00688                      C = COS( ANGLE )*ZLARND( 5, ISEED )
00689                      S = SIN( ANGLE )*ZLARND( 5, ISEED )
00690                      IROW = MAX( 1, JC-JKU+1 )
00691                      IF( JC.GT.0 ) THEN
00692                         IL = MIN( M, JC+JKL+1 ) + 1 - IROW
00693                         CALL ZLAROT( .FALSE., .FALSE., JC+JKL.LT.M, IL,
00694      $                               C, S, A( IROW-ISKEW*JC+IOFFST,
00695      $                               JC ), ILDA, DUMMY, EXTRA )
00696                      END IF
00697 *
00698 *                    Chase "EXTRA" back down
00699 *
00700                      IC = JC
00701                      DO 200 JCH = JC + JKL, IENDCH, JKL + JKU
00702                         ILEXTR = IC.GT.0
00703                         IF( ILEXTR ) THEN
00704                            CALL ZLARTG( A( JCH-ISKEW*IC+IOFFST, IC ),
00705      $                                  EXTRA, REALC, S, DUMMY )
00706                            DUMMY = ZLARND( 5, ISEED )
00707                            C = REALC*DUMMY
00708                            S = S*DUMMY
00709                         END IF
00710                         IC = MAX( 1, IC )
00711                         ICOL = MIN( N-1, JCH+JKU )
00712                         ILTEMP = JCH + JKU.LT.N
00713                         ZTEMP = CZERO
00714                         CALL ZLAROT( .TRUE., ILEXTR, ILTEMP, ICOL+2-IC,
00715      $                               C, S, A( JCH-ISKEW*IC+IOFFST, IC ),
00716      $                               ILDA, EXTRA, ZTEMP )
00717                         IF( ILTEMP ) THEN
00718                            CALL ZLARTG( A( JCH-ISKEW*ICOL+IOFFST,
00719      $                                  ICOL ), ZTEMP, REALC, S, DUMMY )
00720                            DUMMY = ZLARND( 5, ISEED )
00721                            C = REALC*DUMMY
00722                            S = S*DUMMY
00723                            IL = MIN( IENDCH, JCH+JKL+JKU ) + 2 - JCH
00724                            EXTRA = CZERO
00725                            CALL ZLAROT( .FALSE., .TRUE.,
00726      $                                  JCH+JKL+JKU.LE.IENDCH, IL, C, S,
00727      $                                  A( JCH-ISKEW*ICOL+IOFFST,
00728      $                                  ICOL ), ILDA, ZTEMP, EXTRA )
00729                            IC = ICOL
00730                         END IF
00731   200                CONTINUE
00732   210             CONTINUE
00733   220          CONTINUE
00734 *
00735                JKU = UUB
00736                DO 250 JKL = 1, LLB
00737 *
00738 *                 Transform from bandwidth JKL-1, JKU to JKL, JKU
00739 *
00740 *                 First row actually rotated is MIN( N+JKL, M )
00741 *                 First column actually rotated is N
00742 *
00743                   IENDCH = MIN( N, M+JKU ) - 1
00744                   DO 240 JR = MIN( N+JKL, M ) - 1, 1 - JKU, -1
00745                      EXTRA = CZERO
00746                      ANGLE = TWOPI*DLARND( 1, ISEED )
00747                      C = COS( ANGLE )*ZLARND( 5, ISEED )
00748                      S = SIN( ANGLE )*ZLARND( 5, ISEED )
00749                      ICOL = MAX( 1, JR-JKL+1 )
00750                      IF( JR.GT.0 ) THEN
00751                         IL = MIN( N, JR+JKU+1 ) + 1 - ICOL
00752                         CALL ZLAROT( .TRUE., .FALSE., JR+JKU.LT.N, IL,
00753      $                               C, S, A( JR-ISKEW*ICOL+IOFFST,
00754      $                               ICOL ), ILDA, DUMMY, EXTRA )
00755                      END IF
00756 *
00757 *                    Chase "EXTRA" back down
00758 *
00759                      IR = JR
00760                      DO 230 JCH = JR + JKU, IENDCH, JKL + JKU
00761                         ILEXTR = IR.GT.0
00762                         IF( ILEXTR ) THEN
00763                            CALL ZLARTG( A( IR-ISKEW*JCH+IOFFST, JCH ),
00764      $                                  EXTRA, REALC, S, DUMMY )
00765                            DUMMY = ZLARND( 5, ISEED )
00766                            C = REALC*DUMMY
00767                            S = S*DUMMY
00768                         END IF
00769                         IR = MAX( 1, IR )
00770                         IROW = MIN( M-1, JCH+JKL )
00771                         ILTEMP = JCH + JKL.LT.M
00772                         ZTEMP = CZERO
00773                         CALL ZLAROT( .FALSE., ILEXTR, ILTEMP, IROW+2-IR,
00774      $                               C, S, A( IR-ISKEW*JCH+IOFFST,
00775      $                               JCH ), ILDA, EXTRA, ZTEMP )
00776                         IF( ILTEMP ) THEN
00777                            CALL ZLARTG( A( IROW-ISKEW*JCH+IOFFST, JCH ),
00778      $                                  ZTEMP, REALC, S, DUMMY )
00779                            DUMMY = ZLARND( 5, ISEED )
00780                            C = REALC*DUMMY
00781                            S = S*DUMMY
00782                            IL = MIN( IENDCH, JCH+JKL+JKU ) + 2 - JCH
00783                            EXTRA = CZERO
00784                            CALL ZLAROT( .TRUE., .TRUE.,
00785      $                                  JCH+JKL+JKU.LE.IENDCH, IL, C, S,
00786      $                                  A( IROW-ISKEW*JCH+IOFFST, JCH ),
00787      $                                  ILDA, ZTEMP, EXTRA )
00788                            IR = IROW
00789                         END IF
00790   230                CONTINUE
00791   240             CONTINUE
00792   250          CONTINUE
00793 *
00794             END IF
00795 *
00796          ELSE
00797 *
00798 *           Symmetric -- A = U D U'
00799 *           Hermitian -- A = U D U*
00800 *
00801             IPACKG = IPACK
00802             IOFFG = IOFFST
00803 *
00804             IF( TOPDWN ) THEN
00805 *
00806 *              Top-Down -- Generate Upper triangle only
00807 *
00808                IF( IPACK.GE.5 ) THEN
00809                   IPACKG = 6
00810                   IOFFG = UUB + 1
00811                ELSE
00812                   IPACKG = 1
00813                END IF
00814 *
00815                DO 260 J = 1, MNMIN
00816                   A( ( 1-ISKEW )*J+IOFFG, J ) = DCMPLX( D( J ) )
00817   260          CONTINUE
00818 *
00819                DO 290 K = 1, UUB
00820                   DO 280 JC = 1, N - 1
00821                      IROW = MAX( 1, JC-K )
00822                      IL = MIN( JC+1, K+2 )
00823                      EXTRA = CZERO
00824                      ZTEMP = A( JC-ISKEW*( JC+1 )+IOFFG, JC+1 )
00825                      ANGLE = TWOPI*DLARND( 1, ISEED )
00826                      C = COS( ANGLE )*ZLARND( 5, ISEED )
00827                      S = SIN( ANGLE )*ZLARND( 5, ISEED )
00828                      IF( CSYM ) THEN
00829                         CT = C
00830                         ST = S
00831                      ELSE
00832                         ZTEMP = DCONJG( ZTEMP )
00833                         CT = DCONJG( C )
00834                         ST = DCONJG( S )
00835                      END IF
00836                      CALL ZLAROT( .FALSE., JC.GT.K, .TRUE., IL, C, S,
00837      $                            A( IROW-ISKEW*JC+IOFFG, JC ), ILDA,
00838      $                            EXTRA, ZTEMP )
00839                      CALL ZLAROT( .TRUE., .TRUE., .FALSE.,
00840      $                            MIN( K, N-JC )+1, CT, ST,
00841      $                            A( ( 1-ISKEW )*JC+IOFFG, JC ), ILDA,
00842      $                            ZTEMP, DUMMY )
00843 *
00844 *                    Chase EXTRA back up the matrix
00845 *
00846                      ICOL = JC
00847                      DO 270 JCH = JC - K, 1, -K
00848                         CALL ZLARTG( A( JCH+1-ISKEW*( ICOL+1 )+IOFFG,
00849      $                               ICOL+1 ), EXTRA, REALC, S, DUMMY )
00850                         DUMMY = ZLARND( 5, ISEED )
00851                         C = DCONJG( REALC*DUMMY )
00852                         S = DCONJG( -S*DUMMY )
00853                         ZTEMP = A( JCH-ISKEW*( JCH+1 )+IOFFG, JCH+1 )
00854                         IF( CSYM ) THEN
00855                            CT = C
00856                            ST = S
00857                         ELSE
00858                            ZTEMP = DCONJG( ZTEMP )
00859                            CT = DCONJG( C )
00860                            ST = DCONJG( S )
00861                         END IF
00862                         CALL ZLAROT( .TRUE., .TRUE., .TRUE., K+2, C, S,
00863      $                               A( ( 1-ISKEW )*JCH+IOFFG, JCH ),
00864      $                               ILDA, ZTEMP, EXTRA )
00865                         IROW = MAX( 1, JCH-K )
00866                         IL = MIN( JCH+1, K+2 )
00867                         EXTRA = CZERO
00868                         CALL ZLAROT( .FALSE., JCH.GT.K, .TRUE., IL, CT,
00869      $                               ST, A( IROW-ISKEW*JCH+IOFFG, JCH ),
00870      $                               ILDA, EXTRA, ZTEMP )
00871                         ICOL = JCH
00872   270                CONTINUE
00873   280             CONTINUE
00874   290          CONTINUE
00875 *
00876 *              If we need lower triangle, copy from upper. Note that
00877 *              the order of copying is chosen to work for 'q' -> 'b'
00878 *
00879                IF( IPACK.NE.IPACKG .AND. IPACK.NE.3 ) THEN
00880                   DO 320 JC = 1, N
00881                      IROW = IOFFST - ISKEW*JC
00882                      IF( CSYM ) THEN
00883                         DO 300 JR = JC, MIN( N, JC+UUB )
00884                            A( JR+IROW, JC ) = A( JC-ISKEW*JR+IOFFG, JR )
00885   300                   CONTINUE
00886                      ELSE
00887                         DO 310 JR = JC, MIN( N, JC+UUB )
00888                            A( JR+IROW, JC ) = DCONJG( A( JC-ISKEW*JR+
00889      $                                        IOFFG, JR ) )
00890   310                   CONTINUE
00891                      END IF
00892   320             CONTINUE
00893                   IF( IPACK.EQ.5 ) THEN
00894                      DO 340 JC = N - UUB + 1, N
00895                         DO 330 JR = N + 2 - JC, UUB + 1
00896                            A( JR, JC ) = CZERO
00897   330                   CONTINUE
00898   340                CONTINUE
00899                   END IF
00900                   IF( IPACKG.EQ.6 ) THEN
00901                      IPACKG = IPACK
00902                   ELSE
00903                      IPACKG = 0
00904                   END IF
00905                END IF
00906             ELSE
00907 *
00908 *              Bottom-Up -- Generate Lower triangle only
00909 *
00910                IF( IPACK.GE.5 ) THEN
00911                   IPACKG = 5
00912                   IF( IPACK.EQ.6 )
00913      $               IOFFG = 1
00914                ELSE
00915                   IPACKG = 2
00916                END IF
00917 *
00918                DO 350 J = 1, MNMIN
00919                   A( ( 1-ISKEW )*J+IOFFG, J ) = DCMPLX( D( J ) )
00920   350          CONTINUE
00921 *
00922                DO 380 K = 1, UUB
00923                   DO 370 JC = N - 1, 1, -1
00924                      IL = MIN( N+1-JC, K+2 )
00925                      EXTRA = CZERO
00926                      ZTEMP = A( 1+( 1-ISKEW )*JC+IOFFG, JC )
00927                      ANGLE = TWOPI*DLARND( 1, ISEED )
00928                      C = COS( ANGLE )*ZLARND( 5, ISEED )
00929                      S = SIN( ANGLE )*ZLARND( 5, ISEED )
00930                      IF( CSYM ) THEN
00931                         CT = C
00932                         ST = S
00933                      ELSE
00934                         ZTEMP = DCONJG( ZTEMP )
00935                         CT = DCONJG( C )
00936                         ST = DCONJG( S )
00937                      END IF
00938                      CALL ZLAROT( .FALSE., .TRUE., N-JC.GT.K, IL, C, S,
00939      $                            A( ( 1-ISKEW )*JC+IOFFG, JC ), ILDA,
00940      $                            ZTEMP, EXTRA )
00941                      ICOL = MAX( 1, JC-K+1 )
00942                      CALL ZLAROT( .TRUE., .FALSE., .TRUE., JC+2-ICOL,
00943      $                            CT, ST, A( JC-ISKEW*ICOL+IOFFG,
00944      $                            ICOL ), ILDA, DUMMY, ZTEMP )
00945 *
00946 *                    Chase EXTRA back down the matrix
00947 *
00948                      ICOL = JC
00949                      DO 360 JCH = JC + K, N - 1, K
00950                         CALL ZLARTG( A( JCH-ISKEW*ICOL+IOFFG, ICOL ),
00951      $                               EXTRA, REALC, S, DUMMY )
00952                         DUMMY = ZLARND( 5, ISEED )
00953                         C = REALC*DUMMY
00954                         S = S*DUMMY
00955                         ZTEMP = A( 1+( 1-ISKEW )*JCH+IOFFG, JCH )
00956                         IF( CSYM ) THEN
00957                            CT = C
00958                            ST = S
00959                         ELSE
00960                            ZTEMP = DCONJG( ZTEMP )
00961                            CT = DCONJG( C )
00962                            ST = DCONJG( S )
00963                         END IF
00964                         CALL ZLAROT( .TRUE., .TRUE., .TRUE., K+2, C, S,
00965      $                               A( JCH-ISKEW*ICOL+IOFFG, ICOL ),
00966      $                               ILDA, EXTRA, ZTEMP )
00967                         IL = MIN( N+1-JCH, K+2 )
00968                         EXTRA = CZERO
00969                         CALL ZLAROT( .FALSE., .TRUE., N-JCH.GT.K, IL,
00970      $                               CT, ST, A( ( 1-ISKEW )*JCH+IOFFG,
00971      $                               JCH ), ILDA, ZTEMP, EXTRA )
00972                         ICOL = JCH
00973   360                CONTINUE
00974   370             CONTINUE
00975   380          CONTINUE
00976 *
00977 *              If we need upper triangle, copy from lower. Note that
00978 *              the order of copying is chosen to work for 'b' -> 'q'
00979 *
00980                IF( IPACK.NE.IPACKG .AND. IPACK.NE.4 ) THEN
00981                   DO 410 JC = N, 1, -1
00982                      IROW = IOFFST - ISKEW*JC
00983                      IF( CSYM ) THEN
00984                         DO 390 JR = JC, MAX( 1, JC-UUB ), -1
00985                            A( JR+IROW, JC ) = A( JC-ISKEW*JR+IOFFG, JR )
00986   390                   CONTINUE
00987                      ELSE
00988                         DO 400 JR = JC, MAX( 1, JC-UUB ), -1
00989                            A( JR+IROW, JC ) = DCONJG( A( JC-ISKEW*JR+
00990      $                                        IOFFG, JR ) )
00991   400                   CONTINUE
00992                      END IF
00993   410             CONTINUE
00994                   IF( IPACK.EQ.6 ) THEN
00995                      DO 430 JC = 1, UUB
00996                         DO 420 JR = 1, UUB + 1 - JC
00997                            A( JR, JC ) = CZERO
00998   420                   CONTINUE
00999   430                CONTINUE
01000                   END IF
01001                   IF( IPACKG.EQ.5 ) THEN
01002                      IPACKG = IPACK
01003                   ELSE
01004                      IPACKG = 0
01005                   END IF
01006                END IF
01007             END IF
01008 *
01009 *           Ensure that the diagonal is real if Hermitian
01010 *
01011             IF( .NOT.CSYM ) THEN
01012                DO 440 JC = 1, N
01013                   IROW = IOFFST + ( 1-ISKEW )*JC
01014                   A( IROW, JC ) = DCMPLX( DBLE( A( IROW, JC ) ) )
01015   440          CONTINUE
01016             END IF
01017 *
01018          END IF
01019 *
01020       ELSE
01021 *
01022 *        4)      Generate Banded Matrix by first
01023 *                Rotating by random Unitary matrices,
01024 *                then reducing the bandwidth using Householder
01025 *                transformations.
01026 *
01027 *                Note: we should get here only if LDA .ge. N
01028 *
01029          IF( ISYM.EQ.1 ) THEN
01030 *
01031 *           Non-symmetric -- A = U D V
01032 *
01033             CALL ZLAGGE( MR, NC, LLB, UUB, D, A, LDA, ISEED, WORK,
01034      $                   IINFO )
01035          ELSE
01036 *
01037 *           Symmetric -- A = U D U' or
01038 *           Hermitian -- A = U D U*
01039 *
01040             IF( CSYM ) THEN
01041                CALL ZLAGSY( M, LLB, D, A, LDA, ISEED, WORK, IINFO )
01042             ELSE
01043                CALL ZLAGHE( M, LLB, D, A, LDA, ISEED, WORK, IINFO )
01044             END IF
01045          END IF
01046 *
01047          IF( IINFO.NE.0 ) THEN
01048             INFO = 3
01049             RETURN
01050          END IF
01051       END IF
01052 *
01053 *     5)      Pack the matrix
01054 *
01055       IF( IPACK.NE.IPACKG ) THEN
01056          IF( IPACK.EQ.1 ) THEN
01057 *
01058 *           'U' -- Upper triangular, not packed
01059 *
01060             DO 460 J = 1, M
01061                DO 450 I = J + 1, M
01062                   A( I, J ) = CZERO
01063   450          CONTINUE
01064   460       CONTINUE
01065 *
01066          ELSE IF( IPACK.EQ.2 ) THEN
01067 *
01068 *           'L' -- Lower triangular, not packed
01069 *
01070             DO 480 J = 2, M
01071                DO 470 I = 1, J - 1
01072                   A( I, J ) = CZERO
01073   470          CONTINUE
01074   480       CONTINUE
01075 *
01076          ELSE IF( IPACK.EQ.3 ) THEN
01077 *
01078 *           'C' -- Upper triangle packed Columnwise.
01079 *
01080             ICOL = 1
01081             IROW = 0
01082             DO 500 J = 1, M
01083                DO 490 I = 1, J
01084                   IROW = IROW + 1
01085                   IF( IROW.GT.LDA ) THEN
01086                      IROW = 1
01087                      ICOL = ICOL + 1
01088                   END IF
01089                   A( IROW, ICOL ) = A( I, J )
01090   490          CONTINUE
01091   500       CONTINUE
01092 *
01093          ELSE IF( IPACK.EQ.4 ) THEN
01094 *
01095 *           'R' -- Lower triangle packed Columnwise.
01096 *
01097             ICOL = 1
01098             IROW = 0
01099             DO 520 J = 1, M
01100                DO 510 I = J, M
01101                   IROW = IROW + 1
01102                   IF( IROW.GT.LDA ) THEN
01103                      IROW = 1
01104                      ICOL = ICOL + 1
01105                   END IF
01106                   A( IROW, ICOL ) = A( I, J )
01107   510          CONTINUE
01108   520       CONTINUE
01109 *
01110          ELSE IF( IPACK.GE.5 ) THEN
01111 *
01112 *           'B' -- The lower triangle is packed as a band matrix.
01113 *           'Q' -- The upper triangle is packed as a band matrix.
01114 *           'Z' -- The whole matrix is packed as a band matrix.
01115 *
01116             IF( IPACK.EQ.5 )
01117      $         UUB = 0
01118             IF( IPACK.EQ.6 )
01119      $         LLB = 0
01120 *
01121             DO 540 J = 1, UUB
01122                DO 530 I = MIN( J+LLB, M ), 1, -1
01123                   A( I-J+UUB+1, J ) = A( I, J )
01124   530          CONTINUE
01125   540       CONTINUE
01126 *
01127             DO 560 J = UUB + 2, N
01128                DO 550 I = J - UUB, MIN( J+LLB, M )
01129                   A( I-J+UUB+1, J ) = A( I, J )
01130   550          CONTINUE
01131   560       CONTINUE
01132          END IF
01133 *
01134 *        If packed, zero out extraneous elements.
01135 *
01136 *        Symmetric/Triangular Packed --
01137 *        zero out everything after A(IROW,ICOL)
01138 *
01139          IF( IPACK.EQ.3 .OR. IPACK.EQ.4 ) THEN
01140             DO 580 JC = ICOL, M
01141                DO 570 JR = IROW + 1, LDA
01142                   A( JR, JC ) = CZERO
01143   570          CONTINUE
01144                IROW = 0
01145   580       CONTINUE
01146 *
01147          ELSE IF( IPACK.GE.5 ) THEN
01148 *
01149 *           Packed Band --
01150 *              1st row is now in A( UUB+2-j, j), zero above it
01151 *              m-th row is now in A( M+UUB-j,j), zero below it
01152 *              last non-zero diagonal is now in A( UUB+LLB+1,j ),
01153 *                 zero below it, too.
01154 *
01155             IR1 = UUB + LLB + 2
01156             IR2 = UUB + M + 2
01157             DO 610 JC = 1, N
01158                DO 590 JR = 1, UUB + 1 - JC
01159                   A( JR, JC ) = CZERO
01160   590          CONTINUE
01161                DO 600 JR = MAX( 1, MIN( IR1, IR2-JC ) ), LDA
01162                   A( JR, JC ) = CZERO
01163   600          CONTINUE
01164   610       CONTINUE
01165          END IF
01166       END IF
01167 *
01168       RETURN
01169 *
01170 *     End of ZLATMT
01171 *
01172       END
 All Files Functions