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
cqrt14.f
Go to the documentation of this file.
1  REAL FUNCTION cqrt14( TRANS, M, N, NRHS, A, LDA, X,
2  $ ldx, 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  CHARACTER trans
10  INTEGER lda, ldx, lwork, m, n, nrhs
11 * ..
12 * .. Array Arguments ..
13  COMPLEX a( lda, * ), work( lwork ), x( ldx, * )
14 * ..
15 *
16 * Purpose
17 * =======
18 *
19 * CQRT14 checks whether X is in the row space of A or A'. It does so
20 * by scaling both X and A such that their norms are in the range
21 * [sqrt(eps), 1/sqrt(eps)], then computing a QR factorization of [A,X]
22 * (if TRANS = 'C') or an LQ factorization of [A',X]' (if TRANS = 'N'),
23 * and returning the norm of the trailing triangle, scaled by
24 * MAX(M,N,NRHS)*eps.
25 *
26 * Arguments
27 * =========
28 *
29 * TRANS (input) CHARACTER*1
30 * = 'N': No transpose, check for X in the row space of A
31 * = 'C': Conjugate transpose, check for X in row space of A'.
32 *
33 * M (input) INTEGER
34 * The number of rows of the matrix A.
35 *
36 * N (input) INTEGER
37 * The number of columns of the matrix A.
38 *
39 * NRHS (input) INTEGER
40 * The number of right hand sides, i.e., the number of columns
41 * of X.
42 *
43 * A (input) COMPLEX array, dimension (LDA,N)
44 * The M-by-N matrix A.
45 *
46 * LDA (input) INTEGER
47 * The leading dimension of the array A.
48 *
49 * X (input) COMPLEX array, dimension (LDX,NRHS)
50 * If TRANS = 'N', the N-by-NRHS matrix X.
51 * IF TRANS = 'C', the M-by-NRHS matrix X.
52 *
53 * LDX (input) INTEGER
54 * The leading dimension of the array X.
55 *
56 * WORK (workspace) COMPLEX array dimension (LWORK)
57 *
58 * LWORK (input) INTEGER
59 * length of workspace array required
60 * If TRANS = 'N', LWORK >= (M+NRHS)*(N+2);
61 * if TRANS = 'C', LWORK >= (N+NRHS)*(M+2).
62 *
63 * =====================================================================
64 *
65 * .. Parameters ..
66  REAL zero, one
67  parameter( zero = 0.0e0, one = 1.0e0 )
68 * ..
69 * .. Local Scalars ..
70  LOGICAL tpsd
71  INTEGER i, info, j, ldwork
72  REAL anrm, err, xnrm
73 * ..
74 * .. Local Arrays ..
75  REAL rwork( 1 )
76 * ..
77 * .. External Functions ..
78  LOGICAL lsame
79  REAL clange, slamch
80  EXTERNAL lsame, clange, slamch
81 * ..
82 * .. External Subroutines ..
83  EXTERNAL cgelq2, cgeqr2, clacpy, clascl, xerbla
84 * ..
85 * .. Intrinsic Functions ..
86  INTRINSIC abs, conjg, max, min, real
87 * ..
88 * .. Executable Statements ..
89 *
90  cqrt14 = zero
91  IF( lsame( trans, 'N' ) ) THEN
92  ldwork = m + nrhs
93  tpsd = .false.
94  IF( lwork.LT.( m+nrhs )*( n+2 ) ) THEN
95  CALL xerbla( 'CQRT14', 10 )
96  return
97  ELSE IF( n.LE.0 .OR. nrhs.LE.0 ) THEN
98  return
99  END IF
100  ELSE IF( lsame( trans, 'C' ) ) THEN
101  ldwork = m
102  tpsd = .true.
103  IF( lwork.LT.( n+nrhs )*( m+2 ) ) THEN
104  CALL xerbla( 'CQRT14', 10 )
105  return
106  ELSE IF( m.LE.0 .OR. nrhs.LE.0 ) THEN
107  return
108  END IF
109  ELSE
110  CALL xerbla( 'CQRT14', 1 )
111  return
112  END IF
113 *
114 * Copy and scale A
115 *
116  CALL clacpy( 'All', m, n, a, lda, work, ldwork )
117  anrm = clange( 'M', m, n, work, ldwork, rwork )
118  IF( anrm.NE.zero )
119  $ CALL clascl( 'G', 0, 0, anrm, one, m, n, work, ldwork, info )
120 *
121 * Copy X or X' into the right place and scale it
122 *
123  IF( tpsd ) THEN
124 *
125 * Copy X into columns n+1:n+nrhs of work
126 *
127  CALL clacpy( 'All', m, nrhs, x, ldx, work( n*ldwork+1 ),
128  $ ldwork )
129  xnrm = clange( 'M', m, nrhs, work( n*ldwork+1 ), ldwork,
130  $ rwork )
131  IF( xnrm.NE.zero )
132  $ CALL clascl( 'G', 0, 0, xnrm, one, m, nrhs,
133  $ work( n*ldwork+1 ), ldwork, info )
134  anrm = clange( 'One-norm', m, n+nrhs, work, ldwork, rwork )
135 *
136 * Compute QR factorization of X
137 *
138  CALL cgeqr2( m, n+nrhs, work, ldwork,
139  $ work( ldwork*( n+nrhs )+1 ),
140  $ work( ldwork*( n+nrhs )+min( m, n+nrhs )+1 ),
141  $ info )
142 *
143 * Compute largest entry in upper triangle of
144 * work(n+1:m,n+1:n+nrhs)
145 *
146  err = zero
147  DO 20 j = n + 1, n + nrhs
148  DO 10 i = n + 1, min( m, j )
149  err = max( err, abs( work( i+( j-1 )*m ) ) )
150  10 continue
151  20 continue
152 *
153  ELSE
154 *
155 * Copy X' into rows m+1:m+nrhs of work
156 *
157  DO 40 i = 1, n
158  DO 30 j = 1, nrhs
159  work( m+j+( i-1 )*ldwork ) = conjg( x( i, j ) )
160  30 continue
161  40 continue
162 *
163  xnrm = clange( 'M', nrhs, n, work( m+1 ), ldwork, rwork )
164  IF( xnrm.NE.zero )
165  $ CALL clascl( 'G', 0, 0, xnrm, one, nrhs, n, work( m+1 ),
166  $ ldwork, info )
167 *
168 * Compute LQ factorization of work
169 *
170  CALL cgelq2( ldwork, n, work, ldwork, work( ldwork*n+1 ),
171  $ work( ldwork*( n+1 )+1 ), info )
172 *
173 * Compute largest entry in lower triangle in
174 * work(m+1:m+nrhs,m+1:n)
175 *
176  err = zero
177  DO 60 j = m + 1, n
178  DO 50 i = j, ldwork
179  err = max( err, abs( work( i+( j-1 )*ldwork ) ) )
180  50 continue
181  60 continue
182 *
183  END IF
184 *
185  cqrt14 = err / ( REAL( MAX( M, N, NRHS ) )*slamch( 'Epsilon' ) )
186 *
187  return
188 *
189 * End of CQRT14
190 *
191  END