PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
dqrt15.f
Go to the documentation of this file.
1  SUBROUTINE dqrt15( SCALE, RKSEL, M, N, NRHS, A, LDA, B, LDB, S,
2  $ rank, norma, normb, iseed, work, lwork )
3 *
4 * -- LAPACK test routine (version 3.1) --
5 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
6 * November 2006
7 *
8 * .. Scalar Arguments ..
9  INTEGER lda, ldb, lwork, m, n, nrhs, rank, rksel, scale
10  DOUBLE PRECISION norma, normb
11 * ..
12 * .. Array Arguments ..
13  INTEGER iseed( 4 )
14  DOUBLE PRECISION a( lda, * ), b( ldb, * ), s( * ), work( lwork )
15 * ..
16 *
17 * Purpose
18 * =======
19 *
20 * DQRT15 generates a matrix with full or deficient rank and of various
21 * norms.
22 *
23 * Arguments
24 * =========
25 *
26 * SCALE (input) INTEGER
27 * SCALE = 1: normally scaled matrix
28 * SCALE = 2: matrix scaled up
29 * SCALE = 3: matrix scaled down
30 *
31 * RKSEL (input) INTEGER
32 * RKSEL = 1: full rank matrix
33 * RKSEL = 2: rank-deficient matrix
34 *
35 * M (input) INTEGER
36 * The number of rows of the matrix A.
37 *
38 * N (input) INTEGER
39 * The number of columns of A.
40 *
41 * NRHS (input) INTEGER
42 * The number of columns of B.
43 *
44 * A (output) DOUBLE PRECISION array, dimension (LDA,N)
45 * The M-by-N matrix A.
46 *
47 * LDA (input) INTEGER
48 * The leading dimension of the array A.
49 *
50 * B (output) DOUBLE PRECISION array, dimension (LDB, NRHS)
51 * A matrix that is in the range space of matrix A.
52 *
53 * LDB (input) INTEGER
54 * The leading dimension of the array B.
55 *
56 * S (output) DOUBLE PRECISION array, dimension MIN(M,N)
57 * Singular values of A.
58 *
59 * RANK (output) INTEGER
60 * number of nonzero singular values of A.
61 *
62 * NORMA (output) DOUBLE PRECISION
63 * one-norm of A.
64 *
65 * NORMB (output) DOUBLE PRECISION
66 * one-norm of B.
67 *
68 * ISEED (input/output) integer array, dimension (4)
69 * seed for random number generator.
70 *
71 * WORK (workspace) DOUBLE PRECISION array, dimension (LWORK)
72 *
73 * LWORK (input) INTEGER
74 * length of work space required.
75 * LWORK >= MAX(M+MIN(M,N),NRHS*MIN(M,N),2*N+M)
76 *
77 * =====================================================================
78 *
79 * .. Parameters ..
80  DOUBLE PRECISION zero, one, two, svmin
81  parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0,
82  $ svmin = 0.1d0 )
83 * ..
84 * .. Local Scalars ..
85  INTEGER info, j, mn
86  DOUBLE PRECISION bignum, eps, smlnum, temp
87 * ..
88 * .. Local Arrays ..
89  DOUBLE PRECISION dummy( 1 )
90 * ..
91 * .. External Functions ..
92  DOUBLE PRECISION dasum, dlamch, dlange, dlarnd, dnrm2
93  EXTERNAL dasum, dlamch, dlange, dlarnd, dnrm2
94 * ..
95 * .. External Subroutines ..
96  EXTERNAL dgemm, dlaord, dlarf, dlarnv, dlaror, dlascl,
97  $ dlaset, dscal, xerbla
98 * ..
99 * .. Intrinsic Functions ..
100  INTRINSIC abs, max, min
101 * ..
102 * .. Executable Statements ..
103 *
104  mn = min( m, n )
105  IF( lwork.LT.max( m+mn, mn*nrhs, 2*n+m ) ) THEN
106  CALL xerbla( 'DQRT15', 16 )
107  return
108  END IF
109 *
110  smlnum = dlamch( 'Safe minimum' )
111  bignum = one / smlnum
112  eps = dlamch( 'Epsilon' )
113  smlnum = ( smlnum / eps ) / eps
114  bignum = one / smlnum
115 *
116 * Determine rank and (unscaled) singular values
117 *
118  IF( rksel.EQ.1 ) THEN
119  rank = mn
120  ELSE IF( rksel.EQ.2 ) THEN
121  rank = ( 3*mn ) / 4
122  DO 10 j = rank + 1, mn
123  s( j ) = zero
124  10 continue
125  ELSE
126  CALL xerbla( 'DQRT15', 2 )
127  END IF
128 *
129  IF( rank.GT.0 ) THEN
130 *
131 * Nontrivial case
132 *
133  s( 1 ) = one
134  DO 30 j = 2, rank
135  20 continue
136  temp = dlarnd( 1, iseed )
137  IF( temp.GT.svmin ) THEN
138  s( j ) = abs( temp )
139  ELSE
140  go to 20
141  END IF
142  30 continue
143  CALL dlaord( 'Decreasing', rank, s, 1 )
144 *
145 * Generate 'rank' columns of a random orthogonal matrix in A
146 *
147  CALL dlarnv( 2, iseed, m, work )
148  CALL dscal( m, one / dnrm2( m, work, 1 ), work, 1 )
149  CALL dlaset( 'Full', m, rank, zero, one, a, lda )
150  CALL dlarf( 'Left', m, rank, work, 1, two, a, lda,
151  $ work( m+1 ) )
152 *
153 * workspace used: m+mn
154 *
155 * Generate consistent rhs in the range space of A
156 *
157  CALL dlarnv( 2, iseed, rank*nrhs, work )
158  CALL dgemm( 'No transpose', 'No transpose', m, nrhs, rank, one,
159  $ a, lda, work, rank, zero, b, ldb )
160 *
161 * work space used: <= mn *nrhs
162 *
163 * generate (unscaled) matrix A
164 *
165  DO 40 j = 1, rank
166  CALL dscal( m, s( j ), a( 1, j ), 1 )
167  40 continue
168  IF( rank.LT.n )
169  $ CALL dlaset( 'Full', m, n-rank, zero, zero, a( 1, rank+1 ),
170  $ lda )
171  CALL dlaror( 'Right', 'No initialization', m, n, a, lda, iseed,
172  $ work, info )
173 *
174  ELSE
175 *
176 * work space used 2*n+m
177 *
178 * Generate null matrix and rhs
179 *
180  DO 50 j = 1, mn
181  s( j ) = zero
182  50 continue
183  CALL dlaset( 'Full', m, n, zero, zero, a, lda )
184  CALL dlaset( 'Full', m, nrhs, zero, zero, b, ldb )
185 *
186  END IF
187 *
188 * Scale the matrix
189 *
190  IF( scale.NE.1 ) THEN
191  norma = dlange( 'Max', m, n, a, lda, dummy )
192  IF( norma.NE.zero ) THEN
193  IF( scale.EQ.2 ) THEN
194 *
195 * matrix scaled up
196 *
197  CALL dlascl( 'General', 0, 0, norma, bignum, m, n, a,
198  $ lda, info )
199  CALL dlascl( 'General', 0, 0, norma, bignum, mn, 1, s,
200  $ mn, info )
201  CALL dlascl( 'General', 0, 0, norma, bignum, m, nrhs, b,
202  $ ldb, info )
203  ELSE IF( scale.EQ.3 ) THEN
204 *
205 * matrix scaled down
206 *
207  CALL dlascl( 'General', 0, 0, norma, smlnum, m, n, a,
208  $ lda, info )
209  CALL dlascl( 'General', 0, 0, norma, smlnum, mn, 1, s,
210  $ mn, info )
211  CALL dlascl( 'General', 0, 0, norma, smlnum, m, nrhs, b,
212  $ ldb, info )
213  ELSE
214  CALL xerbla( 'DQRT15', 1 )
215  return
216  END IF
217  END IF
218  END IF
219 *
220  norma = dasum( mn, s, 1 )
221  normb = dlange( 'One-norm', m, nrhs, b, ldb, dummy )
222 *
223  return
224 *
225 * End of DQRT15
226 *
227  END