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
zlqt03.f
Go to the documentation of this file.
1  SUBROUTINE zlqt03( 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  DOUBLE PRECISION result( * ), rwork( * )
16  COMPLEX*16 af( lda, * ), c( lda, * ), cc( lda, * ),
17  $ q( lda, * ), work( lwork )
18 * ..
19 *
20 * Purpose
21 * =======
22 *
23 * ZLQT03 tests ZUNMLQ, which computes Q*C, Q'*C, C*Q or C*Q'.
24 *
25 * ZLQT03 compares the results of a call to ZUNMLQ with the results of
26 * forming Q explicitly by a call to ZUNGLQ and then performing matrix
27 * multiplication by a call to ZGEMM.
28 *
29 * Arguments
30 * =========
31 *
32 * M (input) INTEGER
33 * The number of rows or columns of the matrix C; C is n-by-m if
34 * Q is applied from the left, or m-by-n if Q is applied from
35 * the right. M >= 0.
36 *
37 * N (input) INTEGER
38 * The order of the orthogonal matrix Q. N >= 0.
39 *
40 * K (input) INTEGER
41 * The number of elementary reflectors whose product defines the
42 * orthogonal matrix Q. N >= K >= 0.
43 *
44 * AF (input) COMPLEX*16 array, dimension (LDA,N)
45 * Details of the LQ factorization of an m-by-n matrix, as
46 * returned by ZGELQF. See CGELQF for further details.
47 *
48 * C (workspace) COMPLEX*16 array, dimension (LDA,N)
49 *
50 * CC (workspace) COMPLEX*16 array, dimension (LDA,N)
51 *
52 * Q (workspace) COMPLEX*16 array, dimension (LDA,N)
53 *
54 * LDA (input) INTEGER
55 * The leading dimension of the arrays AF, C, CC, and Q.
56 *
57 * TAU (input) COMPLEX*16 array, dimension (min(M,N))
58 * The scalar factors of the elementary reflectors corresponding
59 * to the LQ factorization in AF.
60 *
61 * WORK (workspace) COMPLEX*16 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) DOUBLE PRECISION array, dimension (M)
68 *
69 * RESULT (output) DOUBLE PRECISION array, dimension (4)
70 * The test ratios compare two techniques for multiplying a
71 * random matrix C by an n-by-n orthogonal matrix Q.
72 * RESULT(1) = norm( Q*C - Q*C ) / ( N * norm(C) * EPS )
73 * RESULT(2) = norm( C*Q - C*Q ) / ( N * norm(C) * EPS )
74 * RESULT(3) = norm( Q'*C - Q'*C )/ ( N * norm(C) * EPS )
75 * RESULT(4) = norm( C*Q' - C*Q' )/ ( N * norm(C) * EPS )
76 *
77 * =====================================================================
78 *
79 * .. Parameters ..
80  DOUBLE PRECISION zero, one
81  parameter( zero = 0.0d+0, one = 1.0d+0 )
82  COMPLEX*16 rogue
83  parameter( rogue = ( -1.0d+10, -1.0d+10 ) )
84 * ..
85 * .. Local Scalars ..
86  CHARACTER side, trans
87  INTEGER info, iside, itrans, j, mc, nc
88  INTEGER plasma_side, plasma_trans
89  DOUBLE PRECISION cnorm, eps, resid
90 * ..
91 * .. External Functions ..
92  LOGICAL lsame
93  DOUBLE PRECISION dlamch, zlange
94  EXTERNAL lsame, dlamch, zlange
95 * ..
96 * .. External Subroutines ..
97  EXTERNAL zgemm, zlacpy, zlarnv, zlaset, zunglq, zunmlq
98 * ..
99 * .. Local Arrays ..
100  INTEGER iseed( 4 )
101 * ..
102 * .. Intrinsic Functions ..
103  INTRINSIC dble, dcmplx, max
104 * ..
105 * .. Scalars in Common ..
106  CHARACTER*32 srnamt
107 * ..
108 * .. Common blocks ..
109  common / srnamc / srnamt
110 * ..
111 * .. Data statements ..
112  DATA iseed / 1988, 1989, 1990, 1991 /
113 * ..
114 * .. Executable Statements ..
115 *
116  eps = dlamch( 'Epsilon' )
117 *
118 * Copy the first k rows of the factorization to the array Q
119 *
120  IF ( k.EQ.0 ) THEN
121  CALL zlaset( 'Full', n, n, rogue, rogue, q, lda )
122  ELSE
123  CALL zlaset( 'Full', n, n, dcmplx( zero ), dcmplx( one ),
124  $ q, lda )
125  ENDIF
126 *
127 * Generate the n-by-n matrix Q
128 *
129  srnamt = 'ZUNGLQ'
130  CALL plasma_zunglq( n, n, k, af, lda, t, q, lda, info )
131 *
132  DO 30 iside = 1, 2
133  IF( iside.EQ.1 ) THEN
134  side = 'L'
135  plasma_side = plasmaleft
136  mc = n
137  nc = m
138  ELSE
139  side = 'R'
140  plasma_side = plasmaright
141  mc = m
142  nc = n
143  END IF
144 *
145 * Generate MC by NC matrix C
146 *
147  DO 10 j = 1, nc
148  CALL zlarnv( 2, iseed, mc, c( 1, j ) )
149  10 continue
150  cnorm = zlange( '1', mc, nc, c, lda, rwork )
151  IF( cnorm.EQ.zero )
152  $ cnorm = one
153 *
154  DO 20 itrans = 1, 2
155  IF( itrans.EQ.1 ) THEN
156  plasma_trans = plasmanotrans
157  trans = 'N'
158  ELSE
159  trans = 'C'
160  plasma_trans = plasmaconjtrans
161  END IF
162 *
163 * Copy C
164 *
165  CALL zlacpy( 'Full', mc, nc, c, lda, cc, lda )
166 *
167 * Apply Q or Q' to C
168 *
169  srnamt = 'ZUNMLQ'
170  CALL plasma_zunmlq( plasma_side, plasma_trans, mc, nc, k,
171  $ af, lda, t, cc, lda, info )
172 *
173 * Form explicit product and subtract
174 *
175  IF ( k.EQ.0 ) THEN
176  CALL zlaset( 'Full', n, n, dcmplx( zero ),
177  $ dcmplx( one ), q, lda )
178  ENDIF
179  IF( lsame( side, 'L' ) ) THEN
180  CALL zgemm( trans, 'No transpose', mc, nc, mc,
181  $ dcmplx( -one ), q, lda, c, lda,
182  $ dcmplx( one ), cc, lda )
183  ELSE
184  CALL zgemm( 'No transpose', trans, mc, nc, nc,
185  $ dcmplx( -one ), c, lda, q, lda,
186  $ dcmplx( one ), cc, lda )
187  END IF
188 *
189 * Compute error in the difference
190 *
191  resid = zlange( '1', mc, nc, cc, lda, rwork )
192  result( ( iside-1 )*2+itrans ) = resid /
193  $ ( dble( max( 1, n ) )*cnorm*eps )
194 *
195  20 continue
196  30 continue
197 *
198  return
199 *
200 * End of ZLQT03
201 *
202  END