1       DOUBLE COMPLEX   FUNCTION ZLATM3( M, N, I, J, ISUB, JSUB, KL, KU,
  2      $                 IDIST, ISEED, D, IGRADE, DL, DR, IPVTNG, IWORK,
  3      $                 SPARSE )
  4 *
  5 *  -- LAPACK auxiliary test routine (version 3.1) --
  6 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  7 *     June 2010
  8 *
  9 *     .. Scalar Arguments ..
 10 *
 11       INTEGER            I, IDIST, IGRADE, IPVTNG, ISUB, J, JSUB, KL,
 12      $                   KU, M, N
 13       DOUBLE PRECISION   SPARSE
 14 *     ..
 15 *
 16 *     .. Array Arguments ..
 17 *
 18       INTEGER            ISEED( 4 ), IWORK( * )
 19       COMPLEX*16         D( * ), DL( * ), DR( * )
 20 *     ..
 21 *
 22 *  Purpose
 23 *  =======
 24 *
 25 *     ZLATM3 returns the (ISUB,JSUB) entry of a random matrix of
 26 *     dimension (M, N) described by the other paramters. (ISUB,JSUB)
 27 *     is the final position of the (I,J) entry after pivoting
 28 *     according to IPVTNG and IWORK. ZLATM3 is called by the
 29 *     ZLATMR routine in order to build random test matrices. No error
 30 *     checking on parameters is done, because this routine is called in
 31 *     a tight loop by ZLATMR which has already checked the parameters.
 32 *
 33 *     Use of ZLATM3 differs from CLATM2 in the order in which the random
 34 *     number generator is called to fill in random matrix entries.
 35 *     With ZLATM2, the generator is called to fill in the pivoted matrix
 36 *     columnwise. With ZLATM3, the generator is called to fill in the
 37 *     matrix columnwise, after which it is pivoted. Thus, ZLATM3 can
 38 *     be used to construct random matrices which differ only in their
 39 *     order of rows and/or columns. ZLATM2 is used to construct band
 40 *     matrices while avoiding calling the random number generator for
 41 *     entries outside the band (and therefore generating random numbers
 42 *     in different orders for different pivot orders).
 43 *
 44 *     The matrix whose (ISUB,JSUB) entry is returned is constructed as
 45 *     follows (this routine only computes one entry):
 46 *
 47 *       If ISUB is outside (1..M) or JSUB is outside (1..N), return zero
 48 *          (this is convenient for generating matrices in band format).
 49 *
 50 *       Generate a matrix A with random entries of distribution IDIST.
 51 *
 52 *       Set the diagonal to D.
 53 *
 54 *       Grade the matrix, if desired, from the left (by DL) and/or
 55 *          from the right (by DR or DL) as specified by IGRADE.
 56 *
 57 *       Permute, if desired, the rows and/or columns as specified by
 58 *          IPVTNG and IWORK.
 59 *
 60 *       Band the matrix to have lower bandwidth KL and upper
 61 *          bandwidth KU.
 62 *
 63 *       Set random entries to zero as specified by SPARSE.
 64 *
 65 *  Arguments
 66 *  =========
 67 *
 68 *  M        (input) INTEGER
 69 *           Number of rows of matrix. Not modified.
 70 *
 71 *  N        (input) INTEGER
 72 *           Number of columns of matrix. Not modified.
 73 *
 74 *  I        (input) INTEGER
 75 *           Row of unpivoted entry to be returned. Not modified.
 76 *
 77 *  J        (input) INTEGER
 78 *           Column of unpivoted entry to be returned. Not modified.
 79 *
 80 *  ISUB     (input/output) INTEGER
 81 *           Row of pivoted entry to be returned. Changed on exit.
 82 *
 83 *  JSUB     (input/output) INTEGER
 84 *           Column of pivoted entry to be returned. Changed on exit.
 85 *
 86 *  KL       (input) INTEGER
 87 *           Lower bandwidth. Not modified.
 88 *
 89 *  KU       (input) INTEGER
 90 *           Upper bandwidth. Not modified.
 91 *
 92 *  IDIST    (input) INTEGER
 93 *           On entry, IDIST specifies the type of distribution to be
 94 *           used to generate a random matrix .
 95 *           1 => real and imaginary parts each UNIFORM( 0, 1 )
 96 *           2 => real and imaginary parts each UNIFORM( -1, 1 )
 97 *           3 => real and imaginary parts each NORMAL( 0, 1 )
 98 *           4 => complex number uniform in DISK( 0 , 1 )
 99 *           Not modified.
100 *
101 *  ISEED    (input/output) INTEGER array of dimension ( 4 )
102 *           Seed for random number generator.
103 *           Changed on exit.
104 *
105 *  D        (input) COMPLEX*16 array of dimension ( MIN( I , J ) )
106 *           Diagonal entries of matrix. Not modified.
107 *
108 *  IGRADE   (input) INTEGER
109 *           Specifies grading of matrix as follows:
110 *           0  => no grading
111 *           1  => matrix premultiplied by diag( DL )
112 *           2  => matrix postmultiplied by diag( DR )
113 *           3  => matrix premultiplied by diag( DL ) and
114 *                         postmultiplied by diag( DR )
115 *           4  => matrix premultiplied by diag( DL ) and
116 *                         postmultiplied by inv( diag( DL ) )
117 *           5  => matrix premultiplied by diag( DL ) and
118 *                         postmultiplied by diag( CONJG(DL) )
119 *           6  => matrix premultiplied by diag( DL ) and
120 *                         postmultiplied by diag( DL )
121 *           Not modified.
122 *
123 *  DL       (input) COMPLEX*16 array ( I or J, as appropriate )
124 *           Left scale factors for grading matrix.  Not modified.
125 *
126 *  DR       (input) COMPLEX*16 array ( I or J, as appropriate )
127 *           Right scale factors for grading matrix.  Not modified.
128 *
129 *  IPVTNG   (input) INTEGER
130 *           On entry specifies pivoting permutations as follows:
131 *           0 => none.
132 *           1 => row pivoting.
133 *           2 => column pivoting.
134 *           3 => full pivoting, i.e., on both sides.
135 *           Not modified.
136 *
137 *  IWORK    (input) INTEGER array ( I or J, as appropriate )
138 *           This array specifies the permutation used. The
139 *           row (or column) originally in position K is in
140 *           position IWORK( K ) after pivoting.
141 *           This differs from IWORK for ZLATM2. Not modified.
142 *
143 *  SPARSE   (input) DOUBLE PRECISION between 0. and 1.
144 *           On entry specifies the sparsity of the matrix
145 *           if sparse matix is to be generated.
146 *           SPARSE should lie between 0 and 1.
147 *           A uniform ( 0, 1 ) random number x is generated and
148 *           compared to SPARSE; if x is larger the matrix entry
149 *           is unchanged and if x is smaller the entry is set
150 *           to zero. Thus on the average a fraction SPARSE of the
151 *           entries will be set to zero.
152 *           Not modified.
153 *
154 *  =====================================================================
155 *
156 *     .. Parameters ..
157 *
158       DOUBLE PRECISION   ZERO
159       PARAMETER          ( ZERO = 0.0D0 )
160       COMPLEX*16         CZERO
161       PARAMETER          ( CZERO = ( 0.0D00.0D0 ) )
162 *     ..
163 *
164 *     .. Local Scalars ..
165 *
166       COMPLEX*16         CTEMP
167 *     ..
168 *
169 *     .. External Functions ..
170 *
171       DOUBLE PRECISION   DLARAN
172       COMPLEX*16         ZLARND
173       EXTERNAL           DLARAN, ZLARND
174 *     ..
175 *
176 *     .. Intrinsic Functions ..
177 *
178       INTRINSIC          DCONJG
179 *     ..
180 *
181 *-----------------------------------------------------------------------
182 *
183 *     .. Executable Statements ..
184 *
185 *
186 *     Check for I and J in range
187 *
188       IF( I.LT.1 .OR. I.GT..OR. J.LT.1 .OR. J.GT.N ) THEN
189          ISUB = I
190          JSUB = J
191          ZLATM3 = CZERO
192          RETURN
193       END IF
194 *
195 *     Compute subscripts depending on IPVTNG
196 *
197       IF( IPVTNG.EQ.0 ) THEN
198          ISUB = I
199          JSUB = J
200       ELSE IF( IPVTNG.EQ.1 ) THEN
201          ISUB = IWORK( I )
202          JSUB = J
203       ELSE IF( IPVTNG.EQ.2 ) THEN
204          ISUB = I
205          JSUB = IWORK( J )
206       ELSE IF( IPVTNG.EQ.3 ) THEN
207          ISUB = IWORK( I )
208          JSUB = IWORK( J )
209       END IF
210 *
211 *     Check for banding
212 *
213       IF( JSUB.GT.ISUB+KU .OR. JSUB.LT.ISUB-KL ) THEN
214          ZLATM3 = CZERO
215          RETURN
216       END IF
217 *
218 *     Check for sparsity
219 *
220       IF( SPARSE.GT.ZERO ) THEN
221          IF( DLARAN( ISEED ).LT.SPARSE ) THEN
222             ZLATM3 = CZERO
223             RETURN
224          END IF
225       END IF
226 *
227 *     Compute entry and grade it according to IGRADE
228 *
229       IF( I.EQ.J ) THEN
230          CTEMP = D( I )
231       ELSE
232          CTEMP = ZLARND( IDIST, ISEED )
233       END IF
234       IF( IGRADE.EQ.1 ) THEN
235          CTEMP = CTEMP*DL( I )
236       ELSE IF( IGRADE.EQ.2 ) THEN
237          CTEMP = CTEMP*DR( J )
238       ELSE IF( IGRADE.EQ.3 ) THEN
239          CTEMP = CTEMP*DL( I )*DR( J )
240       ELSE IF( IGRADE.EQ.4 .AND. I.NE.J ) THEN
241          CTEMP = CTEMP*DL( I ) / DL( J )
242       ELSE IF( IGRADE.EQ.5 ) THEN
243          CTEMP = CTEMP*DL( I )*DCONJG( DL( J ) )
244       ELSE IF( IGRADE.EQ.6 ) THEN
245          CTEMP = CTEMP*DL( I )*DL( J )
246       END IF
247       ZLATM3 = CTEMP
248       RETURN
249 *
250 *     End of ZLATM3
251 *
252       END