1       SUBROUTINE SLATM7( MODE, COND, IRSIGN, IDIST, ISEED, D, N,
  2      $                   RANK, INFO )
  3 *
  4 *  -- LAPACK test routine (version 3.1) --
  5 *     Craig Lucas, University of Manchester / NAG Ltd.
  6 *     October, 2008
  7 *
  8 *     .. Scalar Arguments ..
  9       REAL               COND
 10       INTEGER            IDIST, INFO, IRSIGN, MODE, N, RANK
 11 *     ..
 12 *     .. Array Arguments ..
 13       REAL               D( * )
 14       INTEGER            ISEED( 4 )
 15 *     ..
 16 *
 17 *  Purpose
 18 *  =======
 19 *
 20 *     SLATM7 computes the entries of D as specified by MODE
 21 *     COND and IRSIGN. IDIST and ISEED determine the generation
 22 *     of random numbers. SLATM7 is called by SLATMT to generate
 23 *     random test matrices.
 24 *
 25 *  Arguments
 26 *  =========
 27 *
 28 *  MODE   - INTEGER
 29 *           On entry describes how D is to be computed:
 30 *           MODE = 0 means do not change D.
 31 *
 32 *           MODE = 1 sets D(1)=1 and D(2:RANK)=1.0/COND
 33 *           MODE = 2 sets D(1:RANK-1)=1 and D(RANK)=1.0/COND
 34 *           MODE = 3 sets D(I)=COND**(-(I-1)/(RANK-1)) I=1:RANK
 35 *
 36 *           MODE = 4 sets D(i)=1 - (i-1)/(N-1)*(1 - 1/COND)
 37 *           MODE = 5 sets D to random numbers in the range
 38 *                    ( 1/COND , 1 ) such that their logarithms
 39 *                    are uniformly distributed.
 40 *           MODE = 6 set D to random numbers from same distribution
 41 *                    as the rest of the matrix.
 42 *           MODE < 0 has the same meaning as ABS(MODE), except that
 43 *              the order of the elements of D is reversed.
 44 *           Thus if MODE is positive, D has entries ranging from
 45 *              1 to 1/COND, if negative, from 1/COND to 1,
 46 *           Not modified.
 47 *
 48 *  COND   - REAL
 49 *           On entry, used as described under MODE above.
 50 *           If used, it must be >= 1. Not modified.
 51 *
 52 *  IRSIGN - INTEGER
 53 *           On entry, if MODE neither -6, 0 nor 6, determines sign of
 54 *           entries of D
 55 *           0 => leave entries of D unchanged
 56 *           1 => multiply each entry of D by 1 or -1 with probability .5
 57 *
 58 *  IDIST  - CHARACTER*1
 59 *           On entry, IDIST specifies the type of distribution to be
 60 *           used to generate a random matrix .
 61 *           1 => UNIFORM( 0, 1 )
 62 *           2 => UNIFORM( -1, 1 )
 63 *           3 => NORMAL( 0, 1 )
 64 *           Not modified.
 65 *
 66 *  ISEED  - INTEGER array, dimension ( 4 )
 67 *           On entry ISEED specifies the seed of the random number
 68 *           generator. The random number generator uses a
 69 *           linear congruential sequence limited to small
 70 *           integers, and so should produce machine independent
 71 *           random numbers. The values of ISEED are changed on
 72 *           exit, and can be used in the next call to SLATM7
 73 *           to continue the same random number sequence.
 74 *           Changed on exit.
 75 *
 76 *  D      - REAL array, dimension ( MIN( M , N ) )
 77 *           Array to be computed according to MODE, COND and IRSIGN.
 78 *           May be changed on exit if MODE is nonzero.
 79 *
 80 *  N      - INTEGER
 81 *           Number of entries of D. Not modified.
 82 *
 83 *  RANK   - INTEGER
 84 *           The rank of matrix to be generated for modes 1,2,3 only.
 85 *           D( RANK+1:N ) = 0.
 86 *           Not modified.
 87 *
 88 *  INFO   - INTEGER
 89 *            0  => normal termination
 90 *           -1  => if MODE not in range -6 to 6
 91 *           -2  => if MODE neither -6, 0 nor 6, and
 92 *                  IRSIGN neither 0 nor 1
 93 *           -3  => if MODE neither -6, 0 nor 6 and COND less than 1
 94 *           -4  => if MODE equals 6 or -6 and IDIST not in range 1 to 3
 95 *           -7  => if N negative
 96 *
 97 *  =====================================================================
 98 *
 99 *     .. Parameters ..
100       REAL               ONE
101       PARAMETER          ( ONE = 1.0E0 )
102       REAL               ZERO
103       PARAMETER          ( ZERO = 0.0E0 )
104       REAL               HALF
105       PARAMETER          ( HALF = 0.5E0 )
106 *     ..
107 *     .. Local Scalars ..
108       REAL               ALPHA, TEMP
109       INTEGER            I
110 *     ..
111 *     .. External Functions ..
112       REAL               SLARAN
113       EXTERNAL           SLARAN
114 *     ..
115 *     .. External Subroutines ..
116       EXTERNAL           SLARNV, XERBLA
117 *     ..
118 *     .. Intrinsic Functions ..
119       INTRINSIC          ABSEXPLOG, REAL
120 *     ..
121 *     .. Executable Statements ..
122 *
123 *     Decode and Test the input parameters. Initialize flags & seed.
124 *
125       INFO = 0
126 *
127 *     Quick return if possible
128 *
129       IF( N.EQ.0 )
130      $   RETURN
131 *
132 *     Set INFO if an error
133 *
134       IF( MODE.LT.-6 .OR. MODE.GT.6 ) THEN
135          INFO = -1
136       ELSE IF( ( MODE.NE.-6 .AND. MODE.NE.0 .AND. MODE.NE.6 ) .AND.
137      $         ( IRSIGN.NE.0 .AND. IRSIGN.NE.1 ) ) THEN
138          INFO = -2
139       ELSE IF( ( MODE.NE.-6 .AND. MODE.NE.0 .AND. MODE.NE.6 ) .AND.
140      $         COND.LT.ONE ) THEN
141          INFO = -3
142       ELSE IF( ( MODE.EQ.6 .OR. MODE.EQ.-6 ) .AND.
143      $         ( IDIST.LT.1 .OR. IDIST.GT.3 ) ) THEN
144          INFO = -4
145       ELSE IF( N.LT.0 ) THEN
146          INFO = -7
147       END IF
148 *
149       IF( INFO.NE.0 ) THEN
150          CALL XERBLA( 'SLATM7'-INFO )
151          RETURN
152       END IF
153 *
154 *     Compute D according to COND and MODE
155 *
156       IF( MODE.NE.0 ) THEN
157          GO TO ( 100130160190210230 )ABS( MODE )
158 *
159 *        One large D value:
160 *
161   100    CONTINUE
162          DO 110 I = 2, RANK
163             D( I ) = ONE / COND
164   110    CONTINUE
165          DO 120 I = RANK + 1, N
166             D( I ) = ZERO
167   120    CONTINUE
168          D( 1 ) = ONE
169          GO TO 240
170 *
171 *        One small D value:
172 *
173   130    CONTINUE
174          DO 140 I = 1, RANK - 1
175             D( I ) = ONE
176   140    CONTINUE
177          DO 150 I = RANK + 1, N
178             D( I ) = ZERO
179   150    CONTINUE
180          D( RANK ) = ONE / COND
181          GO TO 240
182 *
183 *        Exponentially distributed D values:
184 *
185   160    CONTINUE
186          D( 1 ) = ONE
187          IF( N.GT.1 ) THEN
188             ALPHA = COND**-ONE / REAL( RANK-1 ) )
189             DO 170 I = 2, RANK
190                D( I ) = ALPHA**( I-1 )
191   170       CONTINUE
192             DO 180 I = RANK + 1, N
193                D( I ) = ZERO
194   180       CONTINUE
195          END IF
196          GO TO 240
197 *
198 *        Arithmetically distributed D values:
199 *
200   190    CONTINUE
201          D( 1 ) = ONE
202          IF( N.GT.1 ) THEN
203             TEMP = ONE / COND
204             ALPHA = ( ONE-TEMP ) / REAL( N-1 )
205             DO 200 I = 2, N
206                D( I ) = REAL( N-I )*ALPHA + TEMP
207   200       CONTINUE
208          END IF
209          GO TO 240
210 *
211 *        Randomly distributed D values on ( 1/COND , 1):
212 *
213   210    CONTINUE
214          ALPHA = LOG( ONE / COND )
215          DO 220 I = 1, N
216             D( I ) = EXP( ALPHA*SLARAN( ISEED ) )
217   220    CONTINUE
218          GO TO 240
219 *
220 *        Randomly distributed D values from IDIST
221 *
222   230    CONTINUE
223          CALL SLARNV( IDIST, ISEED, N, D )
224 *
225   240    CONTINUE
226 *
227 *        If MODE neither -6 nor 0 nor 6, and IRSIGN = 1, assign
228 *        random signs to D
229 *
230          IF( ( MODE.NE.-6 .AND. MODE.NE.0 .AND. MODE.NE.6 ) .AND.
231      $       IRSIGN.EQ.1 ) THEN
232             DO 250 I = 1, N
233                TEMP = SLARAN( ISEED )
234                IF( TEMP.GT.HALF )
235      $            D( I ) = -D( I )
236   250       CONTINUE
237          END IF
238 *
239 *        Reverse if MODE < 0
240 *
241          IF( MODE.LT.0 ) THEN
242             DO 260 I = 1, N / 2
243                TEMP = D( I )
244                D( I ) = D( N+1-I )
245                D( N+1-I ) = TEMP
246   260       CONTINUE
247          END IF
248 *
249       END IF
250 *
251       RETURN
252 *
253 *     End of SLATM7
254 *
255       END