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