1 DOUBLE PRECISION FUNCTION ZQRT14( 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*16 A( LDA, * ), WORK( LWORK ), X( LDX, * )
14 * ..
15 *
16 * Purpose
17 * =======
18 *
19 * ZQRT14 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*16 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*16 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*16 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 DOUBLE PRECISION ZERO, ONE
67 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
68 * ..
69 * .. Local Scalars ..
70 LOGICAL TPSD
71 INTEGER I, INFO, J, LDWORK
72 DOUBLE PRECISION ANRM, ERR, XNRM
73 * ..
74 * .. Local Arrays ..
75 DOUBLE PRECISION RWORK( 1 )
76 * ..
77 * .. External Functions ..
78 LOGICAL LSAME
79 DOUBLE PRECISION DLAMCH, ZLANGE
80 EXTERNAL LSAME, DLAMCH, ZLANGE
81 * ..
82 * .. External Subroutines ..
83 EXTERNAL XERBLA, ZGELQ2, ZGEQR2, ZLACPY, ZLASCL
84 * ..
85 * .. Intrinsic Functions ..
86 INTRINSIC ABS, DBLE, DCONJG, MAX, MIN
87 * ..
88 * .. Executable Statements ..
89 *
90 ZQRT14 = 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( 'ZQRT14', 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( 'ZQRT14', 10 )
105 RETURN
106 ELSE IF( M.LE.0 .OR. NRHS.LE.0 ) THEN
107 RETURN
108 END IF
109 ELSE
110 CALL XERBLA( 'ZQRT14', 1 )
111 RETURN
112 END IF
113 *
114 * Copy and scale A
115 *
116 CALL ZLACPY( 'All', M, N, A, LDA, WORK, LDWORK )
117 ANRM = ZLANGE( 'M', M, N, WORK, LDWORK, RWORK )
118 IF( ANRM.NE.ZERO )
119 $ CALL ZLASCL( '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 ZLACPY( 'All', M, NRHS, X, LDX, WORK( N*LDWORK+1 ),
128 $ LDWORK )
129 XNRM = ZLANGE( 'M', M, NRHS, WORK( N*LDWORK+1 ), LDWORK,
130 $ RWORK )
131 IF( XNRM.NE.ZERO )
132 $ CALL ZLASCL( 'G', 0, 0, XNRM, ONE, M, NRHS,
133 $ WORK( N*LDWORK+1 ), LDWORK, INFO )
134 ANRM = ZLANGE( 'One-norm', M, N+NRHS, WORK, LDWORK, RWORK )
135 *
136 * Compute QR factorization of X
137 *
138 CALL ZGEQR2( 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 ) = DCONJG( X( I, J ) )
160 30 CONTINUE
161 40 CONTINUE
162 *
163 XNRM = ZLANGE( 'M', NRHS, N, WORK( M+1 ), LDWORK, RWORK )
164 IF( XNRM.NE.ZERO )
165 $ CALL ZLASCL( 'G', 0, 0, XNRM, ONE, NRHS, N, WORK( M+1 ),
166 $ LDWORK, INFO )
167 *
168 * Compute LQ factorization of work
169 *
170 CALL ZGELQ2( 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 ZQRT14 = ERR / ( DBLE( MAX( M, N, NRHS ) )*DLAMCH( 'Epsilon' ) )
186 *
187 RETURN
188 *
189 * End of ZQRT14
190 *
191 END
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*16 A( LDA, * ), WORK( LWORK ), X( LDX, * )
14 * ..
15 *
16 * Purpose
17 * =======
18 *
19 * ZQRT14 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*16 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*16 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*16 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 DOUBLE PRECISION ZERO, ONE
67 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
68 * ..
69 * .. Local Scalars ..
70 LOGICAL TPSD
71 INTEGER I, INFO, J, LDWORK
72 DOUBLE PRECISION ANRM, ERR, XNRM
73 * ..
74 * .. Local Arrays ..
75 DOUBLE PRECISION RWORK( 1 )
76 * ..
77 * .. External Functions ..
78 LOGICAL LSAME
79 DOUBLE PRECISION DLAMCH, ZLANGE
80 EXTERNAL LSAME, DLAMCH, ZLANGE
81 * ..
82 * .. External Subroutines ..
83 EXTERNAL XERBLA, ZGELQ2, ZGEQR2, ZLACPY, ZLASCL
84 * ..
85 * .. Intrinsic Functions ..
86 INTRINSIC ABS, DBLE, DCONJG, MAX, MIN
87 * ..
88 * .. Executable Statements ..
89 *
90 ZQRT14 = 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( 'ZQRT14', 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( 'ZQRT14', 10 )
105 RETURN
106 ELSE IF( M.LE.0 .OR. NRHS.LE.0 ) THEN
107 RETURN
108 END IF
109 ELSE
110 CALL XERBLA( 'ZQRT14', 1 )
111 RETURN
112 END IF
113 *
114 * Copy and scale A
115 *
116 CALL ZLACPY( 'All', M, N, A, LDA, WORK, LDWORK )
117 ANRM = ZLANGE( 'M', M, N, WORK, LDWORK, RWORK )
118 IF( ANRM.NE.ZERO )
119 $ CALL ZLASCL( '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 ZLACPY( 'All', M, NRHS, X, LDX, WORK( N*LDWORK+1 ),
128 $ LDWORK )
129 XNRM = ZLANGE( 'M', M, NRHS, WORK( N*LDWORK+1 ), LDWORK,
130 $ RWORK )
131 IF( XNRM.NE.ZERO )
132 $ CALL ZLASCL( 'G', 0, 0, XNRM, ONE, M, NRHS,
133 $ WORK( N*LDWORK+1 ), LDWORK, INFO )
134 ANRM = ZLANGE( 'One-norm', M, N+NRHS, WORK, LDWORK, RWORK )
135 *
136 * Compute QR factorization of X
137 *
138 CALL ZGEQR2( 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 ) = DCONJG( X( I, J ) )
160 30 CONTINUE
161 40 CONTINUE
162 *
163 XNRM = ZLANGE( 'M', NRHS, N, WORK( M+1 ), LDWORK, RWORK )
164 IF( XNRM.NE.ZERO )
165 $ CALL ZLASCL( 'G', 0, 0, XNRM, ONE, NRHS, N, WORK( M+1 ),
166 $ LDWORK, INFO )
167 *
168 * Compute LQ factorization of work
169 *
170 CALL ZGELQ2( 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 ZQRT14 = ERR / ( DBLE( MAX( M, N, NRHS ) )*DLAMCH( 'Epsilon' ) )
186 *
187 RETURN
188 *
189 * End of ZQRT14
190 *
191 END