Annotation of rpl/lapack/lapack/dlasdq.f, revision 1.7
1.1 bertrand 1: SUBROUTINE DLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,
2: $ U, LDU, C, LDC, WORK, INFO )
3: *
4: * -- LAPACK auxiliary routine (version 3.2) --
5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
7: * November 2006
8: *
9: * .. Scalar Arguments ..
10: CHARACTER UPLO
11: INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE
12: * ..
13: * .. Array Arguments ..
14: DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),
15: $ VT( LDVT, * ), WORK( * )
16: * ..
17: *
18: * Purpose
19: * =======
20: *
21: * DLASDQ computes the singular value decomposition (SVD) of a real
22: * (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
23: * E, accumulating the transformations if desired. Letting B denote
24: * the input bidiagonal matrix, the algorithm computes orthogonal
25: * matrices Q and P such that B = Q * S * P' (P' denotes the transpose
26: * of P). The singular values S are overwritten on D.
27: *
28: * The input matrix U is changed to U * Q if desired.
29: * The input matrix VT is changed to P' * VT if desired.
30: * The input matrix C is changed to Q' * C if desired.
31: *
32: * See "Computing Small Singular Values of Bidiagonal Matrices With
33: * Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
34: * LAPACK Working Note #3, for a detailed description of the algorithm.
35: *
36: * Arguments
37: * =========
38: *
39: * UPLO (input) CHARACTER*1
40: * On entry, UPLO specifies whether the input bidiagonal matrix
41: * is upper or lower bidiagonal, and wether it is square are
42: * not.
43: * UPLO = 'U' or 'u' B is upper bidiagonal.
44: * UPLO = 'L' or 'l' B is lower bidiagonal.
45: *
46: * SQRE (input) INTEGER
47: * = 0: then the input matrix is N-by-N.
48: * = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and
49: * (N+1)-by-N if UPLU = 'L'.
50: *
51: * The bidiagonal matrix has
52: * N = NL + NR + 1 rows and
53: * M = N + SQRE >= N columns.
54: *
55: * N (input) INTEGER
56: * On entry, N specifies the number of rows and columns
57: * in the matrix. N must be at least 0.
58: *
59: * NCVT (input) INTEGER
60: * On entry, NCVT specifies the number of columns of
61: * the matrix VT. NCVT must be at least 0.
62: *
63: * NRU (input) INTEGER
64: * On entry, NRU specifies the number of rows of
65: * the matrix U. NRU must be at least 0.
66: *
67: * NCC (input) INTEGER
68: * On entry, NCC specifies the number of columns of
69: * the matrix C. NCC must be at least 0.
70: *
71: * D (input/output) DOUBLE PRECISION array, dimension (N)
72: * On entry, D contains the diagonal entries of the
73: * bidiagonal matrix whose SVD is desired. On normal exit,
74: * D contains the singular values in ascending order.
75: *
76: * E (input/output) DOUBLE PRECISION array.
77: * dimension is (N-1) if SQRE = 0 and N if SQRE = 1.
78: * On entry, the entries of E contain the offdiagonal entries
79: * of the bidiagonal matrix whose SVD is desired. On normal
80: * exit, E will contain 0. If the algorithm does not converge,
81: * D and E will contain the diagonal and superdiagonal entries
82: * of a bidiagonal matrix orthogonally equivalent to the one
83: * given as input.
84: *
85: * VT (input/output) DOUBLE PRECISION array, dimension (LDVT, NCVT)
86: * On entry, contains a matrix which on exit has been
87: * premultiplied by P', dimension N-by-NCVT if SQRE = 0
88: * and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).
89: *
90: * LDVT (input) INTEGER
91: * On entry, LDVT specifies the leading dimension of VT as
92: * declared in the calling (sub) program. LDVT must be at
93: * least 1. If NCVT is nonzero LDVT must also be at least N.
94: *
95: * U (input/output) DOUBLE PRECISION array, dimension (LDU, N)
96: * On entry, contains a matrix which on exit has been
97: * postmultiplied by Q, dimension NRU-by-N if SQRE = 0
98: * and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).
99: *
100: * LDU (input) INTEGER
101: * On entry, LDU specifies the leading dimension of U as
102: * declared in the calling (sub) program. LDU must be at
103: * least max( 1, NRU ) .
104: *
105: * C (input/output) DOUBLE PRECISION array, dimension (LDC, NCC)
106: * On entry, contains an N-by-NCC matrix which on exit
107: * has been premultiplied by Q' dimension N-by-NCC if SQRE = 0
108: * and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).
109: *
110: * LDC (input) INTEGER
111: * On entry, LDC specifies the leading dimension of C as
112: * declared in the calling (sub) program. LDC must be at
113: * least 1. If NCC is nonzero, LDC must also be at least N.
114: *
115: * WORK (workspace) DOUBLE PRECISION array, dimension (4*N)
116: * Workspace. Only referenced if one of NCVT, NRU, or NCC is
117: * nonzero, and if N is at least 2.
118: *
119: * INFO (output) INTEGER
120: * On exit, a value of 0 indicates a successful exit.
121: * If INFO < 0, argument number -INFO is illegal.
122: * If INFO > 0, the algorithm did not converge, and INFO
123: * specifies how many superdiagonals did not converge.
124: *
125: * Further Details
126: * ===============
127: *
128: * Based on contributions by
129: * Ming Gu and Huan Ren, Computer Science Division, University of
130: * California at Berkeley, USA
131: *
132: * =====================================================================
133: *
134: * .. Parameters ..
135: DOUBLE PRECISION ZERO
136: PARAMETER ( ZERO = 0.0D+0 )
137: * ..
138: * .. Local Scalars ..
139: LOGICAL ROTATE
140: INTEGER I, ISUB, IUPLO, J, NP1, SQRE1
141: DOUBLE PRECISION CS, R, SMIN, SN
142: * ..
143: * .. External Subroutines ..
144: EXTERNAL DBDSQR, DLARTG, DLASR, DSWAP, XERBLA
145: * ..
146: * .. External Functions ..
147: LOGICAL LSAME
148: EXTERNAL LSAME
149: * ..
150: * .. Intrinsic Functions ..
151: INTRINSIC MAX
152: * ..
153: * .. Executable Statements ..
154: *
155: * Test the input parameters.
156: *
157: INFO = 0
158: IUPLO = 0
159: IF( LSAME( UPLO, 'U' ) )
160: $ IUPLO = 1
161: IF( LSAME( UPLO, 'L' ) )
162: $ IUPLO = 2
163: IF( IUPLO.EQ.0 ) THEN
164: INFO = -1
165: ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
166: INFO = -2
167: ELSE IF( N.LT.0 ) THEN
168: INFO = -3
169: ELSE IF( NCVT.LT.0 ) THEN
170: INFO = -4
171: ELSE IF( NRU.LT.0 ) THEN
172: INFO = -5
173: ELSE IF( NCC.LT.0 ) THEN
174: INFO = -6
175: ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
176: $ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
177: INFO = -10
178: ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
179: INFO = -12
180: ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
181: $ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
182: INFO = -14
183: END IF
184: IF( INFO.NE.0 ) THEN
185: CALL XERBLA( 'DLASDQ', -INFO )
186: RETURN
187: END IF
188: IF( N.EQ.0 )
189: $ RETURN
190: *
191: * ROTATE is true if any singular vectors desired, false otherwise
192: *
193: ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
194: NP1 = N + 1
195: SQRE1 = SQRE
196: *
197: * If matrix non-square upper bidiagonal, rotate to be lower
198: * bidiagonal. The rotations are on the right.
199: *
200: IF( ( IUPLO.EQ.1 ) .AND. ( SQRE1.EQ.1 ) ) THEN
201: DO 10 I = 1, N - 1
202: CALL DLARTG( D( I ), E( I ), CS, SN, R )
203: D( I ) = R
204: E( I ) = SN*D( I+1 )
205: D( I+1 ) = CS*D( I+1 )
206: IF( ROTATE ) THEN
207: WORK( I ) = CS
208: WORK( N+I ) = SN
209: END IF
210: 10 CONTINUE
211: CALL DLARTG( D( N ), E( N ), CS, SN, R )
212: D( N ) = R
213: E( N ) = ZERO
214: IF( ROTATE ) THEN
215: WORK( N ) = CS
216: WORK( N+N ) = SN
217: END IF
218: IUPLO = 2
219: SQRE1 = 0
220: *
221: * Update singular vectors if desired.
222: *
223: IF( NCVT.GT.0 )
224: $ CALL DLASR( 'L', 'V', 'F', NP1, NCVT, WORK( 1 ),
225: $ WORK( NP1 ), VT, LDVT )
226: END IF
227: *
228: * If matrix lower bidiagonal, rotate to be upper bidiagonal
229: * by applying Givens rotations on the left.
230: *
231: IF( IUPLO.EQ.2 ) THEN
232: DO 20 I = 1, N - 1
233: CALL DLARTG( D( I ), E( I ), CS, SN, R )
234: D( I ) = R
235: E( I ) = SN*D( I+1 )
236: D( I+1 ) = CS*D( I+1 )
237: IF( ROTATE ) THEN
238: WORK( I ) = CS
239: WORK( N+I ) = SN
240: END IF
241: 20 CONTINUE
242: *
243: * If matrix (N+1)-by-N lower bidiagonal, one additional
244: * rotation is needed.
245: *
246: IF( SQRE1.EQ.1 ) THEN
247: CALL DLARTG( D( N ), E( N ), CS, SN, R )
248: D( N ) = R
249: IF( ROTATE ) THEN
250: WORK( N ) = CS
251: WORK( N+N ) = SN
252: END IF
253: END IF
254: *
255: * Update singular vectors if desired.
256: *
257: IF( NRU.GT.0 ) THEN
258: IF( SQRE1.EQ.0 ) THEN
259: CALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ),
260: $ WORK( NP1 ), U, LDU )
261: ELSE
262: CALL DLASR( 'R', 'V', 'F', NRU, NP1, WORK( 1 ),
263: $ WORK( NP1 ), U, LDU )
264: END IF
265: END IF
266: IF( NCC.GT.0 ) THEN
267: IF( SQRE1.EQ.0 ) THEN
268: CALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ),
269: $ WORK( NP1 ), C, LDC )
270: ELSE
271: CALL DLASR( 'L', 'V', 'F', NP1, NCC, WORK( 1 ),
272: $ WORK( NP1 ), C, LDC )
273: END IF
274: END IF
275: END IF
276: *
277: * Call DBDSQR to compute the SVD of the reduced real
278: * N-by-N upper bidiagonal matrix.
279: *
280: CALL DBDSQR( 'U', N, NCVT, NRU, NCC, D, E, VT, LDVT, U, LDU, C,
281: $ LDC, WORK, INFO )
282: *
283: * Sort the singular values into ascending order (insertion sort on
284: * singular values, but only one transposition per singular vector)
285: *
286: DO 40 I = 1, N
287: *
288: * Scan for smallest D(I).
289: *
290: ISUB = I
291: SMIN = D( I )
292: DO 30 J = I + 1, N
293: IF( D( J ).LT.SMIN ) THEN
294: ISUB = J
295: SMIN = D( J )
296: END IF
297: 30 CONTINUE
298: IF( ISUB.NE.I ) THEN
299: *
300: * Swap singular values and vectors.
301: *
302: D( ISUB ) = D( I )
303: D( I ) = SMIN
304: IF( NCVT.GT.0 )
305: $ CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( I, 1 ), LDVT )
306: IF( NRU.GT.0 )
307: $ CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, I ), 1 )
308: IF( NCC.GT.0 )
309: $ CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( I, 1 ), LDC )
310: END IF
311: 40 CONTINUE
312: *
313: RETURN
314: *
315: * End of DLASDQ
316: *
317: END
CVSweb interface <joel.bertrand@systella.fr>