80 IMPLICIT NONE
81
82
83
84
85
86
87 INTEGER LWORK, M, N, L, NB, LDT
88
89 DOUBLE PRECISION RESULT(6)
90
91
92
93
94
95 DOUBLE PRECISION, ALLOCATABLE :: AF(:,:), Q(:,:),
96 $ R(:,:), RWORK(:), WORK( : ), T(:,:),
97 $ CF(:,:), DF(:,:), A(:,:), C(:,:), D(:,:)
98
99
100 DOUBLE PRECISION ONE, ZERO
101 parameter( zero = 0.0, one = 1.0 )
102
103
104 INTEGER INFO, J, K, M2, NP1
105 DOUBLE PRECISION ANORM, EPS, RESID, CNORM, DNORM
106
107
108 INTEGER ISEED( 4 )
109
110
111 DOUBLE PRECISION DLAMCH, DLANGE, DLANSY
112 LOGICAL LSAME
114
115
116 DATA iseed / 1988, 1989, 1990, 1991 /
117
119 k = n
120 m2 = m+n
121 IF( m.GT.0 ) THEN
122 np1 = n+1
123 ELSE
124 np1 = 1
125 END IF
126 lwork = m2*m2*nb
127
128
129
130 ALLOCATE(a(m2,n),af(m2,n),q(m2,m2),r(m2,m2),rwork(m2),
131 $ work(lwork),t(nb,n),c(m2,n),cf(m2,n),
132 $ d(n,m2),df(n,m2) )
133
134
135
136 ldt=nb
137 CALL dlaset(
'Full', m2, n, zero, zero, a, m2 )
138 CALL dlaset(
'Full', nb, n, zero, zero, t, nb )
139 DO j=1,n
140 CALL dlarnv( 2, iseed, j, a( 1, j ) )
141 END DO
142 IF( m.GT.0 ) THEN
143 DO j=1,n
144 CALL dlarnv( 2, iseed, m-l, a( min(n+m,n+1), j ) )
145 END DO
146 END IF
147 IF( l.GT.0 ) THEN
148 DO j=1,n
149 CALL dlarnv( 2, iseed, min(j,l), a( min(n+m,n+m-l+1), j ) )
150 END DO
151 END IF
152
153
154
155 CALL dlacpy(
'Full', m2, n, a, m2, af, m2 )
156
157
158
159 CALL dtpqrt( m,n,l,nb,af,m2,af(np1,1),m2,t,ldt,work,info)
160
161
162
163 CALL dlaset(
'Full', m2, m2, zero, one, q, m2 )
164 CALL dgemqrt(
'R',
'N', m2, m2, k, nb, af, m2, t, ldt, q, m2,
165 $ work, info )
166
167
168
169 CALL dlaset(
'Full', m2, n, zero, zero, r, m2 )
170 CALL dlacpy(
'Upper', m2, n, af, m2, r, m2 )
171
172
173
174 CALL dgemm(
'T',
'N', m2, n, m2, -one, q, m2, a, m2, one, r, m2 )
175 anorm =
dlange(
'1', m2, n, a, m2, rwork )
176 resid =
dlange(
'1', m2, n, r, m2, rwork )
177 IF( anorm.GT.zero ) THEN
178 result( 1 ) = resid / (eps*anorm*max(1,m2))
179 ELSE
180 result( 1 ) = zero
181 END IF
182
183
184
185 CALL dlaset(
'Full', m2, m2, zero, one, r, m2 )
186 CALL dsyrk(
'U',
'C', m2, m2, -one, q, m2, one, r, m2 )
187 resid =
dlansy(
'1',
'Upper', m2, r, m2, rwork )
188 result( 2 ) = resid / (eps*max(1,m2))
189
190
191
192 DO j=1,n
193 CALL dlarnv( 2, iseed, m2, c( 1, j ) )
194 END DO
195 cnorm =
dlange(
'1', m2, n, c, m2, rwork)
196 CALL dlacpy(
'Full', m2, n, c, m2, cf, m2 )
197
198
199
200 CALL dtpmqrt(
'L',
'N', m,n,k,l,nb,af(np1,1),m2,t,ldt,cf,m2,
201 $ cf(np1,1),m2,work,info)
202
203
204
205 CALL dgemm(
'N',
'N', m2, n, m2, -one, q, m2, c, m2, one, cf, m2 )
206 resid =
dlange(
'1', m2, n, cf, m2, rwork )
207 IF( cnorm.GT.zero ) THEN
208 result( 3 ) = resid / (eps*max(1,m2)*cnorm)
209 ELSE
210 result( 3 ) = zero
211 END IF
212
213
214
215 CALL dlacpy(
'Full', m2, n, c, m2, cf, m2 )
216
217
218
219 CALL dtpmqrt(
'L',
'T',m,n,k,l,nb,af(np1,1),m2,t,ldt,cf,m2,
220 $ cf(np1,1),m2,work,info)
221
222
223
224 CALL dgemm(
'T',
'N',m2,n,m2,-one,q,m2,c,m2,one,cf,m2)
225 resid =
dlange(
'1', m2, n, cf, m2, rwork )
226 IF( cnorm.GT.zero ) THEN
227 result( 4 ) = resid / (eps*max(1,m2)*cnorm)
228 ELSE
229 result( 4 ) = zero
230 END IF
231
232
233
234 DO j=1,m2
235 CALL dlarnv( 2, iseed, n, d( 1, j ) )
236 END DO
237 dnorm =
dlange(
'1', n, m2, d, n, rwork)
238 CALL dlacpy(
'Full', n, m2, d, n, df, n )
239
240
241
242 CALL dtpmqrt(
'R',
'N',n,m,n,l,nb,af(np1,1),m2,t,ldt,df,n,
243 $ df(1,np1),n,work,info)
244
245
246
247 CALL dgemm(
'N',
'N',n,m2,m2,-one,d,n,q,m2,one,df,n)
248 resid =
dlange(
'1',n, m2,df,n,rwork )
249 IF( cnorm.GT.zero ) THEN
250 result( 5 ) = resid / (eps*max(1,m2)*dnorm)
251 ELSE
252 result( 5 ) = zero
253 END IF
254
255
256
257 CALL dlacpy(
'Full',n,m2,d,n,df,n )
258
259
260
261 CALL dtpmqrt(
'R',
'T',n,m,n,l,nb,af(np1,1),m2,t,ldt,df,n,
262 $ df(1,np1),n,work,info)
263
264
265
266
267 CALL dgemm(
'N',
'T', n, m2, m2, -one, d, n, q, m2, one, df, n )
268 resid =
dlange(
'1', n, m2, df, n, rwork )
269 IF( cnorm.GT.zero ) THEN
270 result( 6 ) = resid / (eps*max(1,m2)*dnorm)
271 ELSE
272 result( 6 ) = zero
273 END IF
274
275
276
277 DEALLOCATE ( a, af, q, r, rwork, work, t, c, d, cf, df)
278 RETURN
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dgemqrt(side, trans, m, n, k, nb, v, ldv, t, ldt, c, ldc, work, info)
DGEMQRT
subroutine dsyrk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
DSYRK
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
double precision function dlamch(cmach)
DLAMCH
double precision function dlange(norm, m, n, a, lda, work)
DLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
double precision function dlansy(norm, uplo, n, a, lda, work)
DLANSY returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
subroutine dlarnv(idist, iseed, n, x)
DLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
logical function lsame(ca, cb)
LSAME
subroutine dtpmqrt(side, trans, m, n, k, l, nb, v, ldv, t, ldt, a, lda, b, ldb, work, info)
DTPMQRT
subroutine dtpqrt(m, n, l, nb, a, lda, b, ldb, t, ldt, work, info)
DTPQRT