LAPACK  3.7.0
LAPACK: Linear Algebra PACKage
stsqr01.f
Go to the documentation of this file.
1 *> \brief \b STSQR01
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 * Definition:
9 * ===========
10 *
11 * SUBROUTINE STSQR01(TSSW, M,N, MB, NB, RESULT)
12 *
13 * .. Scalar Arguments ..
14 * INTEGER M, N, MB
15 * .. Return values ..
16 * REAL RESULT(6)
17 *
18 *
19 *> \par Purpose:
20 * =============
21 *>
22 *> \verbatim
23 *>
24 *> DTSQR01 tests DGEQR , DGELQ, DGEMLQ and DGEMQR.
25 *> \endverbatim
26 *
27 * Arguments:
28 * ==========
29 *
30 *> \param[in] TSSW
31 *> \verbatim
32 *> TSSW is CHARACTER
33 *> 'TS' for testing tall skinny QR
34 *> and anything else for testing short wide LQ
35 *> \endverbatim
36 *> \param[in] M
37 *> \verbatim
38 *> M is INTEGER
39 *> Number of rows in test matrix.
40 *> \endverbatim
41 *>
42 *> \param[in] N
43 *> \verbatim
44 *> N is INTEGER
45 *> Number of columns in test matrix.
46 *> \endverbatim
47 *> \param[in] MB
48 *> \verbatim
49 *> MB is INTEGER
50 *> Number of row in row block in test matrix.
51 *> \endverbatim
52 *>
53 *> \param[in] NB
54 *> \verbatim
55 *> NB is INTEGER
56 *> Number of columns in column block test matrix.
57 *> \endverbatim
58 *>
59 *> \param[out] RESULT
60 *> \verbatim
61 *> RESULT is REAL array, dimension (6)
62 *> Results of each of the six tests below.
63 *>
64 *> RESULT(1) = | A - Q R | or | A - L Q |
65 *> RESULT(2) = | I - Q^H Q | or | I - Q Q^H |
66 *> RESULT(3) = | Q C - Q C |
67 *> RESULT(4) = | Q^H C - Q^H C |
68 *> RESULT(5) = | C Q - C Q |
69 *> RESULT(6) = | C Q^H - C Q^H |
70 *> \endverbatim
71 *
72 * Authors:
73 * ========
74 *
75 *> \author Univ. of Tennessee
76 *> \author Univ. of California Berkeley
77 *> \author Univ. of Colorado Denver
78 *> \author NAG Ltd.
79 *
80 *> \date April 2012
81 *
82 *> \ingroup double_lin
83 *
84 * =====================================================================
85  SUBROUTINE stsqr01(TSSW, M, N, MB, NB, RESULT)
86  IMPLICIT NONE
87 *
88 * -- LAPACK test routine (version 3.7.0) --
89 * -- LAPACK is a software package provided by Univ. of Tennessee, --
90 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
91 * April 2012
92 *
93 * .. Scalar Arguments ..
94  CHARACTER TSSW
95  INTEGER M, N, MB, NB
96 * .. Return values ..
97  REAL RESULT(6)
98 *
99 * =====================================================================
100 *
101 * ..
102 * .. Local allocatable arrays
103  REAL, ALLOCATABLE :: AF(:,:), Q(:,:),
104  $ r(:,:), rwork(:), work( : ), t(:),
105  $ cf(:,:), df(:,:), a(:,:), c(:,:), d(:,:), lq(:,:)
106 *
107 * .. Parameters ..
108  REAL ONE, ZERO
109  parameter( zero = 0.0, one = 1.0 )
110 * ..
111 * .. Local Scalars ..
112  LOGICAL TESTZEROS, TS
113  INTEGER INFO, J, K, L, LWORK, TSIZE, MNB
114  REAL ANORM, EPS, RESID, CNORM, DNORM
115 * ..
116 * .. Local Arrays ..
117  INTEGER ISEED( 4 )
118  REAL TQUERY( 5 ), WORKQUERY
119 * ..
120 * .. External Functions ..
121  REAL SLAMCH, SLANGE, SLANSY
122  LOGICAL LSAME
123  INTEGER ILAENV
124  EXTERNAL slamch, slarnv, slange, slansy, lsame, ilaenv
125 * ..
126 * .. Intrinsic Functions ..
127  INTRINSIC max, min
128 * .. Scalars in Common ..
129  CHARACTER*32 srnamt
130 * ..
131 * .. Common blocks ..
132  COMMON / srnamc / srnamt
133 * ..
134 * .. Data statements ..
135  DATA iseed / 1988, 1989, 1990, 1991 /
136 *
137 * TEST TALL SKINNY OR SHORT WIDE
138 *
139  ts = lsame(tssw, 'TS')
140 *
141 * TEST MATRICES WITH HALF OF MATRIX BEING ZEROS
142 *
143  testzeros = .false.
144 *
145  eps = slamch( 'Epsilon' )
146  k = min(m,n)
147  l = max(m,n,1)
148  mnb = max( mb, nb)
149  lwork = max(3,l)*mnb
150 *
151 * Dynamically allocate local arrays
152 *
153  ALLOCATE ( a(m,n), af(m,n), q(l,l), r(m,l), rwork(l),
154  $ c(m,n), cf(m,n),
155  $ d(n,m), df(n,m), lq(l,n) )
156 *
157 * Put random numbers into A and copy to AF
158 *
159  DO j=1,n
160  CALL slarnv( 2, iseed, m, a( 1, j ) )
161  END DO
162  IF (testzeros) THEN
163  IF (m.GE.4) THEN
164  DO j=1,n
165  CALL slarnv( 2, iseed, m/2, a( m/4, j ) )
166  END DO
167  END IF
168  END IF
169  CALL slacpy( 'Full', m, n, a, m, af, m )
170 *
171  IF (ts) THEN
172 *
173 * Factor the matrix A in the array AF.
174 *
175  CALL sgeqr( m, n, af, m, tquery, -1, workquery, -1, info )
176  tsize = int( tquery( 1 ) )
177  lwork = int( workquery )
178  CALL sgemqr( 'L', 'N', m, m, k, af, m, tquery, tsize, cf, m,
179  $ workquery, -1, info)
180  lwork = max( lwork, int( workquery ) )
181  CALL sgemqr( 'L', 'N', m, n, k, af, m, tquery, tsize, cf, m,
182  $ workquery, -1, info)
183  lwork = max( lwork, int( workquery ) )
184  CALL sgemqr( 'L', 'T', m, n, k, af, m, tquery, tsize, cf, m,
185  $ workquery, -1, info)
186  lwork = max( lwork, int( workquery ) )
187  CALL sgemqr( 'R', 'N', n, m, k, af, m, tquery, tsize, df, n,
188  $ workquery, -1, info)
189  lwork = max( lwork, int( workquery ) )
190  CALL sgemqr( 'R', 'T', n, m, k, af, m, tquery, tsize, df, n,
191  $ workquery, -1, info)
192  lwork = max( lwork, int( workquery ) )
193  ALLOCATE ( t( tsize ) )
194  ALLOCATE ( work( lwork ) )
195  srnamt = 'SGEQR'
196  CALL sgeqr( m, n, af, m, t, tsize, work, lwork, info )
197 *
198 * Generate the m-by-m matrix Q
199 *
200  CALL slaset( 'Full', m, m, zero, one, q, m )
201  srnamt = 'SGEMQR'
202  CALL sgemqr( 'L', 'N', m, m, k, af, m, t, tsize, q, m,
203  $ work, lwork, info )
204 *
205 * Copy R
206 *
207  CALL slaset( 'Full', m, n, zero, zero, r, m )
208  CALL slacpy( 'Upper', m, n, af, m, r, m )
209 *
210 * Compute |R - Q'*A| / |A| and store in RESULT(1)
211 *
212  CALL sgemm( 'T', 'N', m, n, m, -one, q, m, a, m, one, r, m )
213  anorm = slange( '1', m, n, a, m, rwork )
214  resid = slange( '1', m, n, r, m, rwork )
215  IF( anorm.GT.zero ) THEN
216  result( 1 ) = resid / (eps*max(1,m)*anorm)
217  ELSE
218  result( 1 ) = zero
219  END IF
220 *
221 * Compute |I - Q'*Q| and store in RESULT(2)
222 *
223  CALL slaset( 'Full', m, m, zero, one, r, m )
224  CALL ssyrk( 'U', 'C', m, m, -one, q, m, one, r, m )
225  resid = slansy( '1', 'Upper', m, r, m, rwork )
226  result( 2 ) = resid / (eps*max(1,m))
227 *
228 * Generate random m-by-n matrix C and a copy CF
229 *
230  DO j=1,n
231  CALL slarnv( 2, iseed, m, c( 1, j ) )
232  END DO
233  cnorm = slange( '1', m, n, c, m, rwork)
234  CALL slacpy( 'Full', m, n, c, m, cf, m )
235 *
236 * Apply Q to C as Q*C
237 *
238  srnamt = 'DGEQR'
239  CALL sgemqr( 'L', 'N', m, n, k, af, m, t, tsize, cf, m,
240  $ work, lwork, info)
241 *
242 * Compute |Q*C - Q*C| / |C|
243 *
244  CALL sgemm( 'N', 'N', m, n, m, -one, q, m, c, m, one, cf, m )
245  resid = slange( '1', m, n, cf, m, rwork )
246  IF( cnorm.GT.zero ) THEN
247  result( 3 ) = resid / (eps*max(1,m)*cnorm)
248  ELSE
249  result( 3 ) = zero
250  END IF
251 *
252 * Copy C into CF again
253 *
254  CALL slacpy( 'Full', m, n, c, m, cf, m )
255 *
256 * Apply Q to C as QT*C
257 *
258  srnamt = 'DGEQR'
259  CALL sgemqr( 'L', 'T', m, n, k, af, m, t, tsize, cf, m,
260  $ work, lwork, info)
261 *
262 * Compute |QT*C - QT*C| / |C|
263 *
264  CALL sgemm( 'T', 'N', m, n, m, -one, q, m, c, m, one, cf, m )
265  resid = slange( '1', m, n, cf, m, rwork )
266  IF( cnorm.GT.zero ) THEN
267  result( 4 ) = resid / (eps*max(1,m)*cnorm)
268  ELSE
269  result( 4 ) = zero
270  END IF
271 *
272 * Generate random n-by-m matrix D and a copy DF
273 *
274  DO j=1,m
275  CALL slarnv( 2, iseed, n, d( 1, j ) )
276  END DO
277  dnorm = slange( '1', n, m, d, n, rwork)
278  CALL slacpy( 'Full', n, m, d, n, df, n )
279 *
280 * Apply Q to D as D*Q
281 *
282  srnamt = 'DGEQR'
283  CALL sgemqr( 'R', 'N', n, m, k, af, m, t, tsize, df, n,
284  $ work, lwork, info)
285 *
286 * Compute |D*Q - D*Q| / |D|
287 *
288  CALL sgemm( 'N', 'N', n, m, m, -one, d, n, q, m, one, df, n )
289  resid = slange( '1', n, m, df, n, rwork )
290  IF( dnorm.GT.zero ) THEN
291  result( 5 ) = resid / (eps*max(1,m)*dnorm)
292  ELSE
293  result( 5 ) = zero
294  END IF
295 *
296 * Copy D into DF again
297 *
298  CALL slacpy( 'Full', n, m, d, n, df, n )
299 *
300 * Apply Q to D as D*QT
301 *
302  CALL sgemqr( 'R', 'T', n, m, k, af, m, t, tsize, df, n,
303  $ work, lwork, info)
304 *
305 * Compute |D*QT - D*QT| / |D|
306 *
307  CALL sgemm( 'N', 'T', n, m, m, -one, d, n, q, m, one, df, n )
308  resid = slange( '1', n, m, df, n, rwork )
309  IF( cnorm.GT.zero ) THEN
310  result( 6 ) = resid / (eps*max(1,m)*dnorm)
311  ELSE
312  result( 6 ) = zero
313  END IF
314 *
315 * Short and wide
316 *
317  ELSE
318  CALL sgelq( m, n, af, m, tquery, -1, workquery, -1, info )
319  tsize = int( tquery( 1 ) )
320  lwork = int( workquery )
321  CALL sgemlq( 'R', 'N', n, n, k, af, m, tquery, tsize, q, n,
322  $ workquery, -1, info )
323  lwork = max( lwork, int( workquery ) )
324  CALL sgemlq( 'L', 'N', n, m, k, af, m, tquery, tsize, df, n,
325  $ workquery, -1, info)
326  lwork = max( lwork, int( workquery ) )
327  CALL sgemlq( 'L', 'T', n, m, k, af, m, tquery, tsize, df, n,
328  $ workquery, -1, info)
329  lwork = max( lwork, int( workquery ) )
330  CALL sgemlq( 'R', 'N', m, n, k, af, m, tquery, tsize, cf, m,
331  $ workquery, -1, info)
332  lwork = max( lwork, int( workquery ) )
333  CALL sgemlq( 'R', 'T', m, n, k, af, m, tquery, tsize, cf, m,
334  $ workquery, -1, info)
335  lwork = max( lwork, int( workquery ) )
336  ALLOCATE ( t( tsize ) )
337  ALLOCATE ( work( lwork ) )
338  srnamt = 'SGELQ'
339  CALL sgelq( m, n, af, m, t, tsize, work, lwork, info )
340 *
341 *
342 * Generate the n-by-n matrix Q
343 *
344  CALL slaset( 'Full', n, n, zero, one, q, n )
345  srnamt = 'SGEMLQ'
346  CALL sgemlq( 'R', 'N', n, n, k, af, m, t, tsize, q, n,
347  $ work, lwork, info )
348 *
349 * Copy R
350 *
351  CALL slaset( 'Full', m, n, zero, zero, lq, l )
352  CALL slacpy( 'Lower', m, n, af, m, lq, l )
353 *
354 * Compute |L - A*Q'| / |A| and store in RESULT(1)
355 *
356  CALL sgemm( 'N', 'T', m, n, n, -one, a, m, q, n, one, lq, l )
357  anorm = slange( '1', m, n, a, m, rwork )
358  resid = slange( '1', m, n, lq, l, rwork )
359  IF( anorm.GT.zero ) THEN
360  result( 1 ) = resid / (eps*max(1,n)*anorm)
361  ELSE
362  result( 1 ) = zero
363  END IF
364 *
365 * Compute |I - Q'*Q| and store in RESULT(2)
366 *
367  CALL slaset( 'Full', n, n, zero, one, lq, l )
368  CALL ssyrk( 'U', 'C', n, n, -one, q, n, one, lq, l )
369  resid = slansy( '1', 'Upper', n, lq, l, rwork )
370  result( 2 ) = resid / (eps*max(1,n))
371 *
372 * Generate random m-by-n matrix C and a copy CF
373 *
374  DO j=1,m
375  CALL slarnv( 2, iseed, n, d( 1, j ) )
376  END DO
377  dnorm = slange( '1', n, m, d, n, rwork)
378  CALL slacpy( 'Full', n, m, d, n, df, n )
379 *
380 * Apply Q to C as Q*C
381 *
382  CALL sgemlq( 'L', 'N', n, m, k, af, m, t, tsize, df, n,
383  $ work, lwork, info)
384 *
385 * Compute |Q*D - Q*D| / |D|
386 *
387  CALL sgemm( 'N', 'N', n, m, n, -one, q, n, d, n, one, df, n )
388  resid = slange( '1', n, m, df, n, rwork )
389  IF( dnorm.GT.zero ) THEN
390  result( 3 ) = resid / (eps*max(1,n)*dnorm)
391  ELSE
392  result( 3 ) = zero
393  END IF
394 *
395 * Copy D into DF again
396 *
397  CALL slacpy( 'Full', n, m, d, n, df, n )
398 *
399 * Apply Q to D as QT*D
400 *
401  CALL sgemlq( 'L', 'T', n, m, k, af, m, t, tsize, df, n,
402  $ work, lwork, info)
403 *
404 * Compute |QT*D - QT*D| / |D|
405 *
406  CALL sgemm( 'T', 'N', n, m, n, -one, q, n, d, n, one, df, n )
407  resid = slange( '1', n, m, df, n, rwork )
408  IF( dnorm.GT.zero ) THEN
409  result( 4 ) = resid / (eps*max(1,n)*dnorm)
410  ELSE
411  result( 4 ) = zero
412  END IF
413 *
414 * Generate random n-by-m matrix D and a copy DF
415 *
416  DO j=1,n
417  CALL slarnv( 2, iseed, m, c( 1, j ) )
418  END DO
419  cnorm = slange( '1', m, n, c, m, rwork)
420  CALL slacpy( 'Full', m, n, c, m, cf, m )
421 *
422 * Apply Q to C as C*Q
423 *
424  CALL sgemlq( 'R', 'N', m, n, k, af, m, t, tsize, cf, m,
425  $ work, lwork, info)
426 *
427 * Compute |C*Q - C*Q| / |C|
428 *
429  CALL sgemm( 'N', 'N', m, n, n, -one, c, m, q, n, one, cf, m )
430  resid = slange( '1', n, m, df, n, rwork )
431  IF( cnorm.GT.zero ) THEN
432  result( 5 ) = resid / (eps*max(1,n)*cnorm)
433  ELSE
434  result( 5 ) = zero
435  END IF
436 *
437 * Copy C into CF again
438 *
439  CALL slacpy( 'Full', m, n, c, m, cf, m )
440 *
441 * Apply Q to D as D*QT
442 *
443  CALL sgemlq( 'R', 'T', m, n, k, af, m, t, tsize, cf, m,
444  $ work, lwork, info)
445 *
446 * Compute |C*QT - C*QT| / |C|
447 *
448  CALL sgemm( 'N', 'T', m, n, n, -one, c, m, q, n, one, cf, m )
449  resid = slange( '1', m, n, cf, m, rwork )
450  IF( cnorm.GT.zero ) THEN
451  result( 6 ) = resid / (eps*max(1,n)*cnorm)
452  ELSE
453  result( 6 ) = zero
454  END IF
455 *
456  END IF
457 *
458 * Deallocate all arrays
459 *
460  DEALLOCATE ( a, af, q, r, rwork, work, t, c, d, cf, df)
461 *
462  RETURN
463  END
subroutine ssyrk(UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, C, LDC)
SSYRK
Definition: ssyrk.f:171
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
Definition: sgemm.f:189
subroutine sgeqr(M, N, A, LDA, T, TSIZE, WORK, LWORK, INFO)
Definition: sgeqr.f:162
subroutine slaset(UPLO, M, N, ALPHA, BETA, A, LDA)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
Definition: slaset.f:112
subroutine slarnv(IDIST, ISEED, N, X)
SLARNV returns a vector of random numbers from a uniform or normal distribution.
Definition: slarnv.f:99
subroutine sgemqr(SIDE, TRANS, M, N, K, A, LDA, T, TSIZE, C, LDC, WORK, LWORK, INFO)
Definition: sgemqr.f:171
subroutine sgemlq(SIDE, TRANS, M, N, K, A, LDA, T, TSIZE, C, LDC, WORK, LWORK, INFO)
Definition: sgemlq.f:169
subroutine sgelq(M, N, A, LDA, T, TSIZE, WORK, LWORK, INFO)
Definition: sgelq.f:161
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
Definition: slacpy.f:105
subroutine stsqr01(TSSW, M, N, MB, NB, RESULT)
STSQR01
Definition: stsqr01.f:86