1 SUBROUTINE DPST01( UPLO, N, A, LDA, AFAC, LDAFAC, PERM, LDPERM,
2 $ PIV, RWORK, RESID, RANK )
3 *
4 * -- LAPACK test routine (version 3.1) --
5 * Craig Lucas, University of Manchester / NAG Ltd.
6 * October, 2008
7 *
8 * .. Scalar Arguments ..
9 DOUBLE PRECISION RESID
10 INTEGER LDA, LDAFAC, LDPERM, N, RANK
11 CHARACTER UPLO
12 * ..
13 * .. Array Arguments ..
14 DOUBLE PRECISION A( LDA, * ), AFAC( LDAFAC, * ),
15 $ PERM( LDPERM, * ), RWORK( * )
16 INTEGER PIV( * )
17 * ..
18 *
19 * Purpose
20 * =======
21 *
22 * DPST01 reconstructs a symmetric positive semidefinite matrix A
23 * from its L or U factors and the permutation matrix P and computes
24 * the residual
25 * norm( P*L*L'*P' - A ) / ( N * norm(A) * EPS ) or
26 * norm( P*U'*U*P' - A ) / ( N * norm(A) * EPS ),
27 * where EPS is the machine epsilon.
28 *
29 * Arguments
30 * ==========
31 *
32 * UPLO (input) CHARACTER*1
33 * Specifies whether the upper or lower triangular part of the
34 * symmetric matrix A is stored:
35 * = 'U': Upper triangular
36 * = 'L': Lower triangular
37 *
38 * N (input) INTEGER
39 * The number of rows and columns of the matrix A. N >= 0.
40 *
41 * A (input) DOUBLE PRECISION array, dimension (LDA,N)
42 * The original symmetric matrix A.
43 *
44 * LDA (input) INTEGER
45 * The leading dimension of the array A. LDA >= max(1,N)
46 *
47 * AFAC (input) DOUBLE PRECISION array, dimension (LDAFAC,N)
48 * The factor L or U from the L*L' or U'*U
49 * factorization of A.
50 *
51 * LDAFAC (input) INTEGER
52 * The leading dimension of the array AFAC. LDAFAC >= max(1,N).
53 *
54 * PERM (output) DOUBLE PRECISION array, dimension (LDPERM,N)
55 * Overwritten with the reconstructed matrix, and then with the
56 * difference P*L*L'*P' - A (or P*U'*U*P' - A)
57 *
58 * LDPERM (input) INTEGER
59 * The leading dimension of the array PERM.
60 * LDAPERM >= max(1,N).
61 *
62 * PIV (input) INTEGER array, dimension (N)
63 * PIV is such that the nonzero entries are
64 * P( PIV( K ), K ) = 1.
65 *
66 * RWORK (workspace) DOUBLE PRECISION array, dimension (N)
67 *
68 * RESID (output) DOUBLE PRECISION
69 * If UPLO = 'L', norm(L*L' - A) / ( N * norm(A) * EPS )
70 * If UPLO = 'U', norm(U'*U - A) / ( N * norm(A) * EPS )
71 *
72 * =====================================================================
73 *
74 * .. Parameters ..
75 DOUBLE PRECISION ZERO, ONE
76 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
77 * ..
78 * .. Local Scalars ..
79 DOUBLE PRECISION ANORM, EPS, T
80 INTEGER I, J, K
81 * ..
82 * .. External Functions ..
83 DOUBLE PRECISION DDOT, DLAMCH, DLANSY
84 LOGICAL LSAME
85 EXTERNAL DDOT, DLAMCH, DLANSY, LSAME
86 * ..
87 * .. External Subroutines ..
88 EXTERNAL DSCAL, DSYR, DTRMV
89 * ..
90 * .. Intrinsic Functions ..
91 INTRINSIC DBLE
92 * ..
93 * .. Executable Statements ..
94 *
95 * Quick exit if N = 0.
96 *
97 IF( N.LE.0 ) THEN
98 RESID = ZERO
99 RETURN
100 END IF
101 *
102 * Exit with RESID = 1/EPS if ANORM = 0.
103 *
104 EPS = DLAMCH( 'Epsilon' )
105 ANORM = DLANSY( '1', UPLO, N, A, LDA, RWORK )
106 IF( ANORM.LE.ZERO ) THEN
107 RESID = ONE / EPS
108 RETURN
109 END IF
110 *
111 * Compute the product U'*U, overwriting U.
112 *
113 IF( LSAME( UPLO, 'U' ) ) THEN
114 *
115 IF( RANK.LT.N ) THEN
116 DO 110 J = RANK + 1, N
117 DO 100 I = RANK + 1, J
118 AFAC( I, J ) = ZERO
119 100 CONTINUE
120 110 CONTINUE
121 END IF
122 *
123 DO 120 K = N, 1, -1
124 *
125 * Compute the (K,K) element of the result.
126 *
127 T = DDOT( K, AFAC( 1, K ), 1, AFAC( 1, K ), 1 )
128 AFAC( K, K ) = T
129 *
130 * Compute the rest of column K.
131 *
132 CALL DTRMV( 'Upper', 'Transpose', 'Non-unit', K-1, AFAC,
133 $ LDAFAC, AFAC( 1, K ), 1 )
134 *
135 120 CONTINUE
136 *
137 * Compute the product L*L', overwriting L.
138 *
139 ELSE
140 *
141 IF( RANK.LT.N ) THEN
142 DO 140 J = RANK + 1, N
143 DO 130 I = J, N
144 AFAC( I, J ) = ZERO
145 130 CONTINUE
146 140 CONTINUE
147 END IF
148 *
149 DO 150 K = N, 1, -1
150 * Add a multiple of column K of the factor L to each of
151 * columns K+1 through N.
152 *
153 IF( K+1.LE.N )
154 $ CALL DSYR( 'Lower', N-K, ONE, AFAC( K+1, K ), 1,
155 $ AFAC( K+1, K+1 ), LDAFAC )
156 *
157 * Scale column K by the diagonal element.
158 *
159 T = AFAC( K, K )
160 CALL DSCAL( N-K+1, T, AFAC( K, K ), 1 )
161 150 CONTINUE
162 *
163 END IF
164 *
165 * Form P*L*L'*P' or P*U'*U*P'
166 *
167 IF( LSAME( UPLO, 'U' ) ) THEN
168 *
169 DO 170 J = 1, N
170 DO 160 I = 1, N
171 IF( PIV( I ).LE.PIV( J ) ) THEN
172 IF( I.LE.J ) THEN
173 PERM( PIV( I ), PIV( J ) ) = AFAC( I, J )
174 ELSE
175 PERM( PIV( I ), PIV( J ) ) = AFAC( J, I )
176 END IF
177 END IF
178 160 CONTINUE
179 170 CONTINUE
180 *
181 *
182 ELSE
183 *
184 DO 190 J = 1, N
185 DO 180 I = 1, N
186 IF( PIV( I ).GE.PIV( J ) ) THEN
187 IF( I.GE.J ) THEN
188 PERM( PIV( I ), PIV( J ) ) = AFAC( I, J )
189 ELSE
190 PERM( PIV( I ), PIV( J ) ) = AFAC( J, I )
191 END IF
192 END IF
193 180 CONTINUE
194 190 CONTINUE
195 *
196 END IF
197 *
198 * Compute the difference P*L*L'*P' - A (or P*U'*U*P' - A).
199 *
200 IF( LSAME( UPLO, 'U' ) ) THEN
201 DO 210 J = 1, N
202 DO 200 I = 1, J
203 PERM( I, J ) = PERM( I, J ) - A( I, J )
204 200 CONTINUE
205 210 CONTINUE
206 ELSE
207 DO 230 J = 1, N
208 DO 220 I = J, N
209 PERM( I, J ) = PERM( I, J ) - A( I, J )
210 220 CONTINUE
211 230 CONTINUE
212 END IF
213 *
214 * Compute norm( P*L*L'P - A ) / ( N * norm(A) * EPS ), or
215 * ( P*U'*U*P' - A )/ ( N * norm(A) * EPS ).
216 *
217 RESID = DLANSY( '1', UPLO, N, PERM, LDAFAC, RWORK )
218 *
219 RESID = ( ( RESID / DBLE( N ) ) / ANORM ) / EPS
220 *
221 RETURN
222 *
223 * End of DPST01
224 *
225 END
2 $ PIV, RWORK, RESID, RANK )
3 *
4 * -- LAPACK test routine (version 3.1) --
5 * Craig Lucas, University of Manchester / NAG Ltd.
6 * October, 2008
7 *
8 * .. Scalar Arguments ..
9 DOUBLE PRECISION RESID
10 INTEGER LDA, LDAFAC, LDPERM, N, RANK
11 CHARACTER UPLO
12 * ..
13 * .. Array Arguments ..
14 DOUBLE PRECISION A( LDA, * ), AFAC( LDAFAC, * ),
15 $ PERM( LDPERM, * ), RWORK( * )
16 INTEGER PIV( * )
17 * ..
18 *
19 * Purpose
20 * =======
21 *
22 * DPST01 reconstructs a symmetric positive semidefinite matrix A
23 * from its L or U factors and the permutation matrix P and computes
24 * the residual
25 * norm( P*L*L'*P' - A ) / ( N * norm(A) * EPS ) or
26 * norm( P*U'*U*P' - A ) / ( N * norm(A) * EPS ),
27 * where EPS is the machine epsilon.
28 *
29 * Arguments
30 * ==========
31 *
32 * UPLO (input) CHARACTER*1
33 * Specifies whether the upper or lower triangular part of the
34 * symmetric matrix A is stored:
35 * = 'U': Upper triangular
36 * = 'L': Lower triangular
37 *
38 * N (input) INTEGER
39 * The number of rows and columns of the matrix A. N >= 0.
40 *
41 * A (input) DOUBLE PRECISION array, dimension (LDA,N)
42 * The original symmetric matrix A.
43 *
44 * LDA (input) INTEGER
45 * The leading dimension of the array A. LDA >= max(1,N)
46 *
47 * AFAC (input) DOUBLE PRECISION array, dimension (LDAFAC,N)
48 * The factor L or U from the L*L' or U'*U
49 * factorization of A.
50 *
51 * LDAFAC (input) INTEGER
52 * The leading dimension of the array AFAC. LDAFAC >= max(1,N).
53 *
54 * PERM (output) DOUBLE PRECISION array, dimension (LDPERM,N)
55 * Overwritten with the reconstructed matrix, and then with the
56 * difference P*L*L'*P' - A (or P*U'*U*P' - A)
57 *
58 * LDPERM (input) INTEGER
59 * The leading dimension of the array PERM.
60 * LDAPERM >= max(1,N).
61 *
62 * PIV (input) INTEGER array, dimension (N)
63 * PIV is such that the nonzero entries are
64 * P( PIV( K ), K ) = 1.
65 *
66 * RWORK (workspace) DOUBLE PRECISION array, dimension (N)
67 *
68 * RESID (output) DOUBLE PRECISION
69 * If UPLO = 'L', norm(L*L' - A) / ( N * norm(A) * EPS )
70 * If UPLO = 'U', norm(U'*U - A) / ( N * norm(A) * EPS )
71 *
72 * =====================================================================
73 *
74 * .. Parameters ..
75 DOUBLE PRECISION ZERO, ONE
76 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
77 * ..
78 * .. Local Scalars ..
79 DOUBLE PRECISION ANORM, EPS, T
80 INTEGER I, J, K
81 * ..
82 * .. External Functions ..
83 DOUBLE PRECISION DDOT, DLAMCH, DLANSY
84 LOGICAL LSAME
85 EXTERNAL DDOT, DLAMCH, DLANSY, LSAME
86 * ..
87 * .. External Subroutines ..
88 EXTERNAL DSCAL, DSYR, DTRMV
89 * ..
90 * .. Intrinsic Functions ..
91 INTRINSIC DBLE
92 * ..
93 * .. Executable Statements ..
94 *
95 * Quick exit if N = 0.
96 *
97 IF( N.LE.0 ) THEN
98 RESID = ZERO
99 RETURN
100 END IF
101 *
102 * Exit with RESID = 1/EPS if ANORM = 0.
103 *
104 EPS = DLAMCH( 'Epsilon' )
105 ANORM = DLANSY( '1', UPLO, N, A, LDA, RWORK )
106 IF( ANORM.LE.ZERO ) THEN
107 RESID = ONE / EPS
108 RETURN
109 END IF
110 *
111 * Compute the product U'*U, overwriting U.
112 *
113 IF( LSAME( UPLO, 'U' ) ) THEN
114 *
115 IF( RANK.LT.N ) THEN
116 DO 110 J = RANK + 1, N
117 DO 100 I = RANK + 1, J
118 AFAC( I, J ) = ZERO
119 100 CONTINUE
120 110 CONTINUE
121 END IF
122 *
123 DO 120 K = N, 1, -1
124 *
125 * Compute the (K,K) element of the result.
126 *
127 T = DDOT( K, AFAC( 1, K ), 1, AFAC( 1, K ), 1 )
128 AFAC( K, K ) = T
129 *
130 * Compute the rest of column K.
131 *
132 CALL DTRMV( 'Upper', 'Transpose', 'Non-unit', K-1, AFAC,
133 $ LDAFAC, AFAC( 1, K ), 1 )
134 *
135 120 CONTINUE
136 *
137 * Compute the product L*L', overwriting L.
138 *
139 ELSE
140 *
141 IF( RANK.LT.N ) THEN
142 DO 140 J = RANK + 1, N
143 DO 130 I = J, N
144 AFAC( I, J ) = ZERO
145 130 CONTINUE
146 140 CONTINUE
147 END IF
148 *
149 DO 150 K = N, 1, -1
150 * Add a multiple of column K of the factor L to each of
151 * columns K+1 through N.
152 *
153 IF( K+1.LE.N )
154 $ CALL DSYR( 'Lower', N-K, ONE, AFAC( K+1, K ), 1,
155 $ AFAC( K+1, K+1 ), LDAFAC )
156 *
157 * Scale column K by the diagonal element.
158 *
159 T = AFAC( K, K )
160 CALL DSCAL( N-K+1, T, AFAC( K, K ), 1 )
161 150 CONTINUE
162 *
163 END IF
164 *
165 * Form P*L*L'*P' or P*U'*U*P'
166 *
167 IF( LSAME( UPLO, 'U' ) ) THEN
168 *
169 DO 170 J = 1, N
170 DO 160 I = 1, N
171 IF( PIV( I ).LE.PIV( J ) ) THEN
172 IF( I.LE.J ) THEN
173 PERM( PIV( I ), PIV( J ) ) = AFAC( I, J )
174 ELSE
175 PERM( PIV( I ), PIV( J ) ) = AFAC( J, I )
176 END IF
177 END IF
178 160 CONTINUE
179 170 CONTINUE
180 *
181 *
182 ELSE
183 *
184 DO 190 J = 1, N
185 DO 180 I = 1, N
186 IF( PIV( I ).GE.PIV( J ) ) THEN
187 IF( I.GE.J ) THEN
188 PERM( PIV( I ), PIV( J ) ) = AFAC( I, J )
189 ELSE
190 PERM( PIV( I ), PIV( J ) ) = AFAC( J, I )
191 END IF
192 END IF
193 180 CONTINUE
194 190 CONTINUE
195 *
196 END IF
197 *
198 * Compute the difference P*L*L'*P' - A (or P*U'*U*P' - A).
199 *
200 IF( LSAME( UPLO, 'U' ) ) THEN
201 DO 210 J = 1, N
202 DO 200 I = 1, J
203 PERM( I, J ) = PERM( I, J ) - A( I, J )
204 200 CONTINUE
205 210 CONTINUE
206 ELSE
207 DO 230 J = 1, N
208 DO 220 I = J, N
209 PERM( I, J ) = PERM( I, J ) - A( I, J )
210 220 CONTINUE
211 230 CONTINUE
212 END IF
213 *
214 * Compute norm( P*L*L'P - A ) / ( N * norm(A) * EPS ), or
215 * ( P*U'*U*P' - A )/ ( N * norm(A) * EPS ).
216 *
217 RESID = DLANSY( '1', UPLO, N, PERM, LDAFAC, RWORK )
218 *
219 RESID = ( ( RESID / DBLE( N ) ) / ANORM ) / EPS
220 *
221 RETURN
222 *
223 * End of DPST01
224 *
225 END