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
sqrt03.f
Go to the documentation of this file.
1  SUBROUTINE sqrt03( M, N, K, AF, C, CC, Q, LDA, T, WORK, LWORK,
2  $ rwork, result )
3 *
4  include 'plasmaf.h'
5 *
6 * -- LAPACK test routine (version 3.1) --
7 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
8 * November 2006
9 *
10 * .. Scalar Arguments ..
11  INTEGER k, lda, lwork, m, n
12  INTEGER t( 2 )
13 * ..
14 * .. Array Arguments ..
15  REAL af( lda, * ), c( lda, * ), cc( lda, * ),
16  $ q( lda, * ), result( * ), rwork( * ),
17  $ work( lwork )
18 * ..
19 *
20 * Purpose
21 * =======
22 *
23 * SQRT03 tests SORMQR, which computes Q*C, Q'*C, C*Q or C*Q'.
24 *
25 * SQRT03 compares the results of a call to SORMQR with the results of
26 * forming Q explicitly by a call to SORGQR and then performing matrix
27 * multiplication by a call to SGEMM.
28 *
29 * Arguments
30 * =========
31 *
32 * M (input) INTEGER
33 * The order of the orthogonal matrix Q. M >= 0.
34 *
35 * N (input) INTEGER
36 * The number of rows or columns of the matrix C; C is m-by-n if
37 * Q is applied from the left, or n-by-m if Q is applied from
38 * the right. N >= 0.
39 *
40 * K (input) INTEGER
41 * The number of elementary reflectors whose product defines the
42 * orthogonal matrix Q. M >= K >= 0.
43 *
44 * AF (input) REAL array, dimension (LDA,N)
45 * Details of the QR factorization of an m-by-n matrix, as
46 * returnedby SGEQRF. See SGEQRF for further details.
47 *
48 * C (workspace) REAL array, dimension (LDA,N)
49 *
50 * CC (workspace) REAL array, dimension (LDA,N)
51 *
52 * Q (workspace) REAL array, dimension (LDA,M)
53 *
54 * LDA (input) INTEGER
55 * The leading dimension of the arrays AF, C, CC, and Q.
56 *
57 * TAU (input) REAL array, dimension (min(M,N))
58 * The scalar factors of the elementary reflectors corresponding
59 * to the QR factorization in AF.
60 *
61 * WORK (workspace) REAL array, dimension (LWORK)
62 *
63 * LWORK (input) INTEGER
64 * The length of WORK. LWORK must be at least M, and should be
65 * M*NB, where NB is the blocksize for this environment.
66 *
67 * RWORK (workspace) REAL array, dimension (M)
68 *
69 * RESULT (output) REAL array, dimension (4)
70 * The test ratios compare two techniques for multiplying a
71 * random matrix C by an m-by-m orthogonal matrix Q.
72 * RESULT(1) = norm( Q*C - Q*C ) / ( M * norm(C) * EPS )
73 * RESULT(2) = norm( C*Q - C*Q ) / ( M * norm(C) * EPS )
74 * RESULT(3) = norm( Q'*C - Q'*C )/ ( M * norm(C) * EPS )
75 * RESULT(4) = norm( C*Q' - C*Q' )/ ( M * norm(C) * EPS )
76 *
77 * =====================================================================
78 *
79 * .. Parameters ..
80  REAL one, zero
81  parameter( one = 1.0e0 )
82  parameter( zero = 0.0e+0 )
83  REAL rogue
84  parameter( rogue = -1.0e+10 )
85 * ..
86 * .. Local Scalars ..
87  CHARACTER side, trans
88  INTEGER info, iside, itrans, j, mc, nc
89  INTEGER plasma_side, plasma_trans
90  REAL cnorm, eps, resid
91 * ..
92 * .. External Functions ..
93  LOGICAL lsame
94  REAL slamch, slange
95  EXTERNAL lsame, slamch, slange
96 * ..
97 * .. External Subroutines ..
98  EXTERNAL sgemm, slacpy, slarnv, slaset, sorgqr, sormqr
99 * ..
100 * .. Local Arrays ..
101  INTEGER iseed( 4 )
102 * ..
103 * .. Intrinsic Functions ..
104  INTRINSIC max, real
105 * ..
106 * .. Scalars in Common ..
107  CHARACTER*32 srnamt
108 * ..
109 * .. Common blocks ..
110  common / srnamc / srnamt
111 * ..
112 * .. Data statements ..
113  DATA iseed / 1988, 1989, 1990, 1991 /
114 * ..
115 * .. Executable Statements ..
116 *
117  eps = slamch( 'Epsilon' )
118  work(1) = one
119 *
120 * Copy the first k columns of the factorization to the array Q
121 *
122  IF ( k.EQ.0 ) THEN
123  CALL slaset( 'Full', m, m, rogue, rogue, q, lda )
124  ELSE
125  CALL slaset( 'Full', m, m, zero, one, q, lda )
126  ENDIF
127 *
128 * Generate the m-by-m matrix Q
129 *
130  srnamt = 'SORGQR'
131  CALL plasma_sorgqr( m, m, k, af, lda, t, q, lda, info )
132 *
133  DO 30 iside = 1, 2
134  IF( iside.EQ.1 ) THEN
135  side = 'L'
136  plasma_side = plasmaleft
137  mc = m
138  nc = n
139  ELSE
140  side = 'R'
141  plasma_side = plasmaright
142  mc = n
143  nc = m
144  END IF
145 *
146 * Generate MC by NC matrix C
147 *
148  DO 10 j = 1, nc
149  CALL slarnv( 2, iseed, mc, c( 1, j ) )
150  10 continue
151  cnorm = slange( '1', mc, nc, c, lda, rwork )
152  IF( cnorm.EQ.0.0 )
153  $ cnorm = one
154 *
155  DO 20 itrans = 1, 2
156  IF( itrans.EQ.1 ) THEN
157  trans = 'N'
158  plasma_trans = plasmanotrans
159  ELSE
160  trans = 'T'
161  plasma_trans = plasmatrans
162  END IF
163 *
164 * Copy C
165 *
166  CALL slacpy( 'Full', mc, nc, c, lda, cc, lda )
167 *
168 * Apply Q or Q' to C
169 *
170  srnamt = 'SORMQR'
171  CALL plasma_sormqr( plasma_side, plasma_trans, mc, nc, k,
172  $ af, lda, t, cc, lda, info )
173 *
174 * Form explicit product and subtract
175 *
176  IF ( k.EQ.0 ) THEN
177  CALL slaset( 'Full', m, m, zero, one, q, lda )
178  ENDIF
179  IF( lsame( side, 'L' ) ) THEN
180  CALL sgemm( trans, 'No transpose', mc, nc, mc, -one, q,
181  $ lda, c, lda, one, cc, lda )
182  ELSE
183  CALL sgemm( 'No transpose', trans, mc, nc, nc, -one, c,
184  $ lda, q, lda, one, cc, lda )
185  END IF
186 *
187 * Compute error in the difference
188 *
189  resid = slange( '1', mc, nc, cc, lda, rwork )
190  result( ( iside-1 )*2+itrans ) = resid /
191  $ ( REAL( MAX( 1, M ) )*cnorm*eps )
192 *
193  20 continue
194  30 continue
195 *
196  return
197 *
198 * End of SQRT03
199 *
200  END