LAPACK 3.11.0
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
sgsvts3.f
Go to the documentation of this file.
1*> \brief \b SGSVTS3
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 SGSVTS3( 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* REAL 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*> SGSVTS3 tests SGGSVD3, 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 REAL array, dimension (LDA,M)
62*> The M-by-N matrix A.
63*> \endverbatim
64*>
65*> \param[out] AF
66*> \verbatim
67*> AF is REAL array, dimension (LDA,N)
68*> Details of the GSVD of A and B, as returned by SGGSVD3,
69*> see SGGSVD3 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 REAL 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 REAL array, dimension (LDB,N)
88*> Details of the GSVD of A and B, as returned by SGGSVD3,
89*> see SGGSVD3 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 REAL 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 REAL 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 REAL 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 REAL array, dimension (N)
138*> \endverbatim
139*>
140*> \param[out] BETA
141*> \verbatim
142*> BETA is REAL 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 SGGSVD3 for details.
147*> \endverbatim
148*>
149*> \param[out] R
150*> \verbatim
151*> R is REAL 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 REAL 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 REAL array, dimension (max(M,P,N))
181*> \endverbatim
182*>
183*> \param[out] RESULT
184*> \verbatim
185*> RESULT is REAL 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 single_eig
205*
206* =====================================================================
207 SUBROUTINE sgsvts3( 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 REAL 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 REAL ZERO, ONE
231 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
232* ..
233* .. Local Scalars ..
234 INTEGER I, INFO, J, K, L
235 REAL ANORM, BNORM, RESID, TEMP, ULP, ULPINV, UNFL
236* ..
237* .. External Functions ..
238 REAL SLAMCH, SLANGE, SLANSY
239 EXTERNAL SLAMCH, SLANGE, SLANSY
240* ..
241* .. External Subroutines ..
242 EXTERNAL scopy, sgemm, sggsvd3, slacpy, slaset, ssyrk
243* ..
244* .. Intrinsic Functions ..
245 INTRINSIC max, min, real
246* ..
247* .. Executable Statements ..
248*
249 ulp = slamch( 'Precision' )
250 ulpinv = one / ulp
251 unfl = slamch( 'Safe minimum' )
252*
253* Copy the matrix A to the array AF.
254*
255 CALL slacpy( 'Full', m, n, a, lda, af, lda )
256 CALL slacpy( 'Full', p, n, b, ldb, bf, ldb )
257*
258 anorm = max( slange( '1', m, n, a, lda, rwork ), unfl )
259 bnorm = max( slange( '1', p, n, b, ldb, rwork ), unfl )
260*
261* Factorize the matrices A and B in the arrays AF and BF.
262*
263 CALL sggsvd3( '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 sgemm( 'No transpose', 'No transpose', m, n, n, one, a, lda,
286 $ q, ldq, zero, work, lda )
287*
288 CALL sgemm( '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 = slange( '1', m, n, a, lda, rwork )
306*
307 IF( anorm.GT.zero ) THEN
308 result( 1 ) = ( ( resid / real( 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 sgemm( 'No transpose', 'No transpose', p, n, n, one, b, ldb,
317 $ q, ldq, zero, work, ldb )
318*
319 CALL sgemm( '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 = slange( '1', p, n, b, ldb, rwork )
331 IF( bnorm.GT.zero ) THEN
332 result( 2 ) = ( ( resid / real( 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 slaset( 'Full', m, m, zero, one, work, ldq )
341 CALL ssyrk( 'Upper', 'Transpose', m, m, -one, u, ldu, one, work,
342 $ ldu )
343*
344* Compute norm( I - U'*U ) / ( M * ULP ) .
345*
346 resid = slansy( '1', 'Upper', m, work, ldu, rwork )
347 result( 3 ) = ( resid / real( max( 1, m ) ) ) / ulp
348*
349* Compute I - V'*V
350*
351 CALL slaset( 'Full', p, p, zero, one, work, ldv )
352 CALL ssyrk( 'Upper', 'Transpose', p, p, -one, v, ldv, one, work,
353 $ ldv )
354*
355* Compute norm( I - V'*V ) / ( P * ULP ) .
356*
357 resid = slansy( '1', 'Upper', p, work, ldv, rwork )
358 result( 4 ) = ( resid / real( max( 1, p ) ) ) / ulp
359*
360* Compute I - Q'*Q
361*
362 CALL slaset( 'Full', n, n, zero, one, work, ldq )
363 CALL ssyrk( 'Upper', 'Transpose', n, n, -one, q, ldq, one, work,
364 $ ldq )
365*
366* Compute norm( I - Q'*Q ) / ( N * ULP ) .
367*
368 resid = slansy( '1', 'Upper', n, work, ldq, rwork )
369 result( 5 ) = ( resid / real( max( 1, n ) ) ) / ulp
370*
371* Check sorting
372*
373 CALL scopy( 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 SGSVTS3
392*
393 END
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:110
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
Definition: slacpy.f:103
subroutine sggsvd3(JOBU, JOBV, JOBQ, M, N, P, K, L, A, LDA, B, LDB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ, WORK, LWORK, IWORK, INFO)
SGGSVD3 computes the singular value decomposition (SVD) for OTHER matrices
Definition: sggsvd3.f:349
subroutine scopy(N, SX, INCX, SY, INCY)
SCOPY
Definition: scopy.f:82
subroutine ssyrk(UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, C, LDC)
SSYRK
Definition: ssyrk.f:169
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
Definition: sgemm.f:187
subroutine sgsvts3(M, P, N, A, AF, LDA, B, BF, LDB, U, LDU, V, LDV, Q, LDQ, ALPHA, BETA, R, LDR, IWORK, WORK, LWORK, RWORK, RESULT)
SGSVTS3
Definition: sgsvts3.f:210