LAPACK 3.11.0
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zgsvts3.f
Go to the documentation of this file.
1*> \brief \b ZGSVTS3
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 ZGSVTS3( M, P, N, A, AF, LDA, B, BF, LDB, U, LDU, V,
12* LDV, Q, LDQ, ALPHA, BETA, R, LDR, IWORK, WORK,
13* LWORK, RWORK, RESULT )
14*
15* .. Scalar Arguments ..
16* INTEGER LDA, LDB, LDQ, LDR, LDU, LDV, LWORK, M, N, P
17* ..
18* .. Array Arguments ..
19* INTEGER IWORK( * )
20* DOUBLE PRECISION ALPHA( * ), BETA( * ), RESULT( 6 ), RWORK( * )
21* COMPLEX*16 A( LDA, * ), AF( LDA, * ), B( LDB, * ),
22* $ BF( LDB, * ), Q( LDQ, * ), R( LDR, * ),
23* $ U( LDU, * ), V( LDV, * ), WORK( LWORK )
24* ..
25*
26*
27*> \par Purpose:
28* =============
29*>
30*> \verbatim
31*>
32*> ZGSVTS3 tests ZGGSVD3, which computes the GSVD of an M-by-N matrix A
33*> and a P-by-N matrix B:
34*> U'*A*Q = D1*R and V'*B*Q = D2*R.
35*> \endverbatim
36*
37* Arguments:
38* ==========
39*
40*> \param[in] M
41*> \verbatim
42*> M is INTEGER
43*> The number of rows of the matrix A. M >= 0.
44*> \endverbatim
45*>
46*> \param[in] P
47*> \verbatim
48*> P is INTEGER
49*> The number of rows of the matrix B. P >= 0.
50*> \endverbatim
51*>
52*> \param[in] N
53*> \verbatim
54*> N is INTEGER
55*> The number of columns of the matrices A and B. N >= 0.
56*> \endverbatim
57*>
58*> \param[in] A
59*> \verbatim
60*> A is COMPLEX*16 array, dimension (LDA,M)
61*> The M-by-N matrix A.
62*> \endverbatim
63*>
64*> \param[out] AF
65*> \verbatim
66*> AF is COMPLEX*16 array, dimension (LDA,N)
67*> Details of the GSVD of A and B, as returned by ZGGSVD3,
68*> see ZGGSVD3 for further details.
69*> \endverbatim
70*>
71*> \param[in] LDA
72*> \verbatim
73*> LDA is INTEGER
74*> The leading dimension of the arrays A and AF.
75*> LDA >= max( 1,M ).
76*> \endverbatim
77*>
78*> \param[in] B
79*> \verbatim
80*> B is COMPLEX*16 array, dimension (LDB,P)
81*> On entry, the P-by-N matrix B.
82*> \endverbatim
83*>
84*> \param[out] BF
85*> \verbatim
86*> BF is COMPLEX*16 array, dimension (LDB,N)
87*> Details of the GSVD of A and B, as returned by ZGGSVD3,
88*> see ZGGSVD3 for further details.
89*> \endverbatim
90*>
91*> \param[in] LDB
92*> \verbatim
93*> LDB is INTEGER
94*> The leading dimension of the arrays B and BF.
95*> LDB >= max(1,P).
96*> \endverbatim
97*>
98*> \param[out] U
99*> \verbatim
100*> U is COMPLEX*16 array, dimension(LDU,M)
101*> The M by M unitary matrix U.
102*> \endverbatim
103*>
104*> \param[in] LDU
105*> \verbatim
106*> LDU is INTEGER
107*> The leading dimension of the array U. LDU >= max(1,M).
108*> \endverbatim
109*>
110*> \param[out] V
111*> \verbatim
112*> V is COMPLEX*16 array, dimension(LDV,M)
113*> The P by P unitary matrix V.
114*> \endverbatim
115*>
116*> \param[in] LDV
117*> \verbatim
118*> LDV is INTEGER
119*> The leading dimension of the array V. LDV >= max(1,P).
120*> \endverbatim
121*>
122*> \param[out] Q
123*> \verbatim
124*> Q is COMPLEX*16 array, dimension(LDQ,N)
125*> The N by N unitary matrix Q.
126*> \endverbatim
127*>
128*> \param[in] LDQ
129*> \verbatim
130*> LDQ is INTEGER
131*> The leading dimension of the array Q. LDQ >= max(1,N).
132*> \endverbatim
133*>
134*> \param[out] ALPHA
135*> \verbatim
136*> ALPHA is DOUBLE PRECISION array, dimension (N)
137*> \endverbatim
138*>
139*> \param[out] BETA
140*> \verbatim
141*> BETA is DOUBLE PRECISION array, dimension (N)
142*>
143*> The generalized singular value pairs of A and B, the
144*> ``diagonal'' matrices D1 and D2 are constructed from
145*> ALPHA and BETA, see subroutine ZGGSVD3 for details.
146*> \endverbatim
147*>
148*> \param[out] R
149*> \verbatim
150*> R is COMPLEX*16 array, dimension(LDQ,N)
151*> The upper triangular matrix R.
152*> \endverbatim
153*>
154*> \param[in] LDR
155*> \verbatim
156*> LDR is INTEGER
157*> The leading dimension of the array R. LDR >= max(1,N).
158*> \endverbatim
159*>
160*> \param[out] IWORK
161*> \verbatim
162*> IWORK is INTEGER array, dimension (N)
163*> \endverbatim
164*>
165*> \param[out] WORK
166*> \verbatim
167*> WORK is COMPLEX*16 array, dimension (LWORK)
168*> \endverbatim
169*>
170*> \param[in] LWORK
171*> \verbatim
172*> LWORK is INTEGER
173*> The dimension of the array WORK,
174*> LWORK >= max(M,P,N)*max(M,P,N).
175*> \endverbatim
176*>
177*> \param[out] RWORK
178*> \verbatim
179*> RWORK is DOUBLE PRECISION array, dimension (max(M,P,N))
180*> \endverbatim
181*>
182*> \param[out] RESULT
183*> \verbatim
184*> RESULT is DOUBLE PRECISION array, dimension (6)
185*> The test ratios:
186*> RESULT(1) = norm( U'*A*Q - D1*R ) / ( MAX(M,N)*norm(A)*ULP)
187*> RESULT(2) = norm( V'*B*Q - D2*R ) / ( MAX(P,N)*norm(B)*ULP)
188*> RESULT(3) = norm( I - U'*U ) / ( M*ULP )
189*> RESULT(4) = norm( I - V'*V ) / ( P*ULP )
190*> RESULT(5) = norm( I - Q'*Q ) / ( N*ULP )
191*> RESULT(6) = 0 if ALPHA is in decreasing order;
192*> = ULPINV otherwise.
193*> \endverbatim
194*
195* Authors:
196* ========
197*
198*> \author Univ. of Tennessee
199*> \author Univ. of California Berkeley
200*> \author Univ. of Colorado Denver
201*> \author NAG Ltd.
202*
203*> \ingroup complex16_eig
204*
205* =====================================================================
206 SUBROUTINE zgsvts3( M, P, N, A, AF, LDA, B, BF, LDB, U, LDU, V,
207 $ LDV, Q, LDQ, ALPHA, BETA, R, LDR, IWORK, WORK,
208 $ LWORK, RWORK, RESULT )
209*
210* -- LAPACK test routine --
211* -- LAPACK is a software package provided by Univ. of Tennessee, --
212* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
213*
214* .. Scalar Arguments ..
215 INTEGER LDA, LDB, LDQ, LDR, LDU, LDV, LWORK, M, N, P
216* ..
217* .. Array Arguments ..
218 INTEGER IWORK( * )
219 DOUBLE PRECISION ALPHA( * ), BETA( * ), RESULT( 6 ), RWORK( * )
220 COMPLEX*16 A( LDA, * ), AF( LDA, * ), B( LDB, * ),
221 $ bf( ldb, * ), q( ldq, * ), r( ldr, * ),
222 $ u( ldu, * ), v( ldv, * ), work( lwork )
223* ..
224*
225* =====================================================================
226*
227* .. Parameters ..
228 DOUBLE PRECISION ZERO, ONE
229 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
230 COMPLEX*16 CZERO, CONE
231 parameter( czero = ( 0.0d+0, 0.0d+0 ),
232 $ cone = ( 1.0d+0, 0.0d+0 ) )
233* ..
234* .. Local Scalars ..
235 INTEGER I, INFO, J, K, L
236 DOUBLE PRECISION ANORM, BNORM, RESID, TEMP, ULP, ULPINV, UNFL
237* ..
238* .. External Functions ..
239 DOUBLE PRECISION DLAMCH, ZLANGE, ZLANHE
240 EXTERNAL DLAMCH, ZLANGE, ZLANHE
241* ..
242* .. External Subroutines ..
243 EXTERNAL dcopy, zgemm, zggsvd3, zherk, zlacpy, zlaset
244* ..
245* .. Intrinsic Functions ..
246 INTRINSIC dble, max, min
247* ..
248* .. Executable Statements ..
249*
250 ulp = dlamch( 'Precision' )
251 ulpinv = one / ulp
252 unfl = dlamch( 'Safe minimum' )
253*
254* Copy the matrix A to the array AF.
255*
256 CALL zlacpy( 'Full', m, n, a, lda, af, lda )
257 CALL zlacpy( 'Full', p, n, b, ldb, bf, ldb )
258*
259 anorm = max( zlange( '1', m, n, a, lda, rwork ), unfl )
260 bnorm = max( zlange( '1', p, n, b, ldb, rwork ), unfl )
261*
262* Factorize the matrices A and B in the arrays AF and BF.
263*
264 CALL zggsvd3( 'U', 'V', 'Q', m, n, p, k, l, af, lda, bf, ldb,
265 $ alpha, beta, u, ldu, v, ldv, q, ldq, work, lwork,
266 $ rwork, iwork, info )
267*
268* Copy R
269*
270 DO 20 i = 1, min( k+l, m )
271 DO 10 j = i, k + l
272 r( i, j ) = af( i, n-k-l+j )
273 10 CONTINUE
274 20 CONTINUE
275*
276 IF( m-k-l.LT.0 ) THEN
277 DO 40 i = m + 1, k + l
278 DO 30 j = i, k + l
279 r( i, j ) = bf( i-k, n-k-l+j )
280 30 CONTINUE
281 40 CONTINUE
282 END IF
283*
284* Compute A:= U'*A*Q - D1*R
285*
286 CALL zgemm( 'No transpose', 'No transpose', m, n, n, cone, a, lda,
287 $ q, ldq, czero, work, lda )
288*
289 CALL zgemm( 'Conjugate transpose', 'No transpose', m, n, m, cone,
290 $ u, ldu, work, lda, czero, a, lda )
291*
292 DO 60 i = 1, k
293 DO 50 j = i, k + l
294 a( i, n-k-l+j ) = a( i, n-k-l+j ) - r( i, j )
295 50 CONTINUE
296 60 CONTINUE
297*
298 DO 80 i = k + 1, min( k+l, m )
299 DO 70 j = i, k + l
300 a( i, n-k-l+j ) = a( i, n-k-l+j ) - alpha( i )*r( i, j )
301 70 CONTINUE
302 80 CONTINUE
303*
304* Compute norm( U'*A*Q - D1*R ) / ( MAX(1,M,N)*norm(A)*ULP ) .
305*
306 resid = zlange( '1', m, n, a, lda, rwork )
307 IF( anorm.GT.zero ) THEN
308 result( 1 ) = ( ( resid / dble( max( 1, m, n ) ) ) / anorm ) /
309 $ ulp
310 ELSE
311 result( 1 ) = zero
312 END IF
313*
314* Compute B := V'*B*Q - D2*R
315*
316 CALL zgemm( 'No transpose', 'No transpose', p, n, n, cone, b, ldb,
317 $ q, ldq, czero, work, ldb )
318*
319 CALL zgemm( 'Conjugate transpose', 'No transpose', p, n, p, cone,
320 $ v, ldv, work, ldb, czero, b, ldb )
321*
322 DO 100 i = 1, l
323 DO 90 j = i, l
324 b( i, n-l+j ) = b( i, n-l+j ) - beta( k+i )*r( k+i, k+j )
325 90 CONTINUE
326 100 CONTINUE
327*
328* Compute norm( V'*B*Q - D2*R ) / ( MAX(P,N)*norm(B)*ULP ) .
329*
330 resid = zlange( '1', p, n, b, ldb, rwork )
331 IF( bnorm.GT.zero ) THEN
332 result( 2 ) = ( ( resid / dble( max( 1, p, n ) ) ) / bnorm ) /
333 $ ulp
334 ELSE
335 result( 2 ) = zero
336 END IF
337*
338* Compute I - U'*U
339*
340 CALL zlaset( 'Full', m, m, czero, cone, work, ldq )
341 CALL zherk( 'Upper', 'Conjugate transpose', m, m, -one, u, ldu,
342 $ one, work, ldu )
343*
344* Compute norm( I - U'*U ) / ( M * ULP ) .
345*
346 resid = zlanhe( '1', 'Upper', m, work, ldu, rwork )
347 result( 3 ) = ( resid / dble( max( 1, m ) ) ) / ulp
348*
349* Compute I - V'*V
350*
351 CALL zlaset( 'Full', p, p, czero, cone, work, ldv )
352 CALL zherk( 'Upper', 'Conjugate transpose', p, p, -one, v, ldv,
353 $ one, work, ldv )
354*
355* Compute norm( I - V'*V ) / ( P * ULP ) .
356*
357 resid = zlanhe( '1', 'Upper', p, work, ldv, rwork )
358 result( 4 ) = ( resid / dble( max( 1, p ) ) ) / ulp
359*
360* Compute I - Q'*Q
361*
362 CALL zlaset( 'Full', n, n, czero, cone, work, ldq )
363 CALL zherk( 'Upper', 'Conjugate transpose', n, n, -one, q, ldq,
364 $ one, work, ldq )
365*
366* Compute norm( I - Q'*Q ) / ( N * ULP ) .
367*
368 resid = zlanhe( '1', 'Upper', n, work, ldq, rwork )
369 result( 5 ) = ( resid / dble( max( 1, n ) ) ) / ulp
370*
371* Check sorting
372*
373 CALL dcopy( n, alpha, 1, rwork, 1 )
374 DO 110 i = k + 1, min( k+l, m )
375 j = iwork( i )
376 IF( i.NE.j ) THEN
377 temp = rwork( i )
378 rwork( i ) = rwork( j )
379 rwork( j ) = temp
380 END IF
381 110 CONTINUE
382*
383 result( 6 ) = zero
384 DO 120 i = k + 1, min( k+l, m ) - 1
385 IF( rwork( i ).LT.rwork( i+1 ) )
386 $ result( 6 ) = ulpinv
387 120 CONTINUE
388*
389 RETURN
390*
391* End of ZGSVTS3
392*
393 END
subroutine zgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
ZGEMM
Definition: zgemm.f:187
subroutine zherk(UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, C, LDC)
ZHERK
Definition: zherk.f:173
subroutine zgsvts3(M, P, N, A, AF, LDA, B, BF, LDB, U, LDU, V, LDV, Q, LDQ, ALPHA, BETA, R, LDR, IWORK, WORK, LWORK, RWORK, RESULT)
ZGSVTS3
Definition: zgsvts3.f:209
subroutine zggsvd3(JOBU, JOBV, JOBQ, M, N, P, K, L, A, LDA, B, LDB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ, WORK, LWORK, RWORK, IWORK, INFO)
ZGGSVD3 computes the singular value decomposition (SVD) for OTHER matrices
Definition: zggsvd3.f:353
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
Definition: zlacpy.f:103
subroutine zlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition: zlaset.f:106
subroutine dcopy(N, DX, INCX, DY, INCY)
DCOPY
Definition: dcopy.f:82