Annotation of rpl/lapack/lapack/dlasdq.f, revision 1.20
1.12 bertrand 1: *> \brief \b DLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.
1.9 bertrand 2: *
3: * =========== DOCUMENTATION ===========
4: *
1.17 bertrand 5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
1.9 bertrand 7: *
8: *> \htmlonly
1.17 bertrand 9: *> Download DLASDQ + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasdq.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasdq.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasdq.f">
1.9 bertrand 15: *> [TXT]</a>
1.17 bertrand 16: *> \endhtmlonly
1.9 bertrand 17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE DLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,
22: * U, LDU, C, LDC, WORK, INFO )
1.17 bertrand 23: *
1.9 bertrand 24: * .. Scalar Arguments ..
25: * CHARACTER UPLO
26: * INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE
27: * ..
28: * .. Array Arguments ..
29: * DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),
30: * $ VT( LDVT, * ), WORK( * )
31: * ..
1.17 bertrand 32: *
1.9 bertrand 33: *
34: *> \par Purpose:
35: * =============
36: *>
37: *> \verbatim
38: *>
39: *> DLASDQ computes the singular value decomposition (SVD) of a real
40: *> (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
41: *> E, accumulating the transformations if desired. Letting B denote
42: *> the input bidiagonal matrix, the algorithm computes orthogonal
43: *> matrices Q and P such that B = Q * S * P**T (P**T denotes the transpose
44: *> of P). The singular values S are overwritten on D.
45: *>
46: *> The input matrix U is changed to U * Q if desired.
47: *> The input matrix VT is changed to P**T * VT if desired.
48: *> The input matrix C is changed to Q**T * C if desired.
49: *>
50: *> See "Computing Small Singular Values of Bidiagonal Matrices With
51: *> Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
52: *> LAPACK Working Note #3, for a detailed description of the algorithm.
53: *> \endverbatim
54: *
55: * Arguments:
56: * ==========
57: *
58: *> \param[in] UPLO
59: *> \verbatim
60: *> UPLO is CHARACTER*1
61: *> On entry, UPLO specifies whether the input bidiagonal matrix
1.15 bertrand 62: *> is upper or lower bidiagonal, and whether it is square are
1.9 bertrand 63: *> not.
64: *> UPLO = 'U' or 'u' B is upper bidiagonal.
65: *> UPLO = 'L' or 'l' B is lower bidiagonal.
66: *> \endverbatim
67: *>
68: *> \param[in] SQRE
69: *> \verbatim
70: *> SQRE is INTEGER
71: *> = 0: then the input matrix is N-by-N.
72: *> = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and
73: *> (N+1)-by-N if UPLU = 'L'.
74: *>
75: *> The bidiagonal matrix has
76: *> N = NL + NR + 1 rows and
77: *> M = N + SQRE >= N columns.
78: *> \endverbatim
79: *>
80: *> \param[in] N
81: *> \verbatim
82: *> N is INTEGER
83: *> On entry, N specifies the number of rows and columns
84: *> in the matrix. N must be at least 0.
85: *> \endverbatim
86: *>
87: *> \param[in] NCVT
88: *> \verbatim
89: *> NCVT is INTEGER
90: *> On entry, NCVT specifies the number of columns of
91: *> the matrix VT. NCVT must be at least 0.
92: *> \endverbatim
93: *>
94: *> \param[in] NRU
95: *> \verbatim
96: *> NRU is INTEGER
97: *> On entry, NRU specifies the number of rows of
98: *> the matrix U. NRU must be at least 0.
99: *> \endverbatim
100: *>
101: *> \param[in] NCC
102: *> \verbatim
103: *> NCC is INTEGER
104: *> On entry, NCC specifies the number of columns of
105: *> the matrix C. NCC must be at least 0.
106: *> \endverbatim
107: *>
108: *> \param[in,out] D
109: *> \verbatim
110: *> D is DOUBLE PRECISION array, dimension (N)
111: *> On entry, D contains the diagonal entries of the
112: *> bidiagonal matrix whose SVD is desired. On normal exit,
113: *> D contains the singular values in ascending order.
114: *> \endverbatim
115: *>
116: *> \param[in,out] E
117: *> \verbatim
118: *> E is DOUBLE PRECISION array.
119: *> dimension is (N-1) if SQRE = 0 and N if SQRE = 1.
120: *> On entry, the entries of E contain the offdiagonal entries
121: *> of the bidiagonal matrix whose SVD is desired. On normal
122: *> exit, E will contain 0. If the algorithm does not converge,
123: *> D and E will contain the diagonal and superdiagonal entries
124: *> of a bidiagonal matrix orthogonally equivalent to the one
125: *> given as input.
126: *> \endverbatim
127: *>
128: *> \param[in,out] VT
129: *> \verbatim
130: *> VT is DOUBLE PRECISION array, dimension (LDVT, NCVT)
131: *> On entry, contains a matrix which on exit has been
132: *> premultiplied by P**T, dimension N-by-NCVT if SQRE = 0
133: *> and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).
134: *> \endverbatim
135: *>
136: *> \param[in] LDVT
137: *> \verbatim
138: *> LDVT is INTEGER
139: *> On entry, LDVT specifies the leading dimension of VT as
140: *> declared in the calling (sub) program. LDVT must be at
141: *> least 1. If NCVT is nonzero LDVT must also be at least N.
142: *> \endverbatim
143: *>
144: *> \param[in,out] U
145: *> \verbatim
146: *> U is DOUBLE PRECISION array, dimension (LDU, N)
147: *> On entry, contains a matrix which on exit has been
148: *> postmultiplied by Q, dimension NRU-by-N if SQRE = 0
149: *> and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).
150: *> \endverbatim
151: *>
152: *> \param[in] LDU
153: *> \verbatim
154: *> LDU is INTEGER
155: *> On entry, LDU specifies the leading dimension of U as
156: *> declared in the calling (sub) program. LDU must be at
157: *> least max( 1, NRU ) .
158: *> \endverbatim
159: *>
160: *> \param[in,out] C
161: *> \verbatim
162: *> C is DOUBLE PRECISION array, dimension (LDC, NCC)
163: *> On entry, contains an N-by-NCC matrix which on exit
164: *> has been premultiplied by Q**T dimension N-by-NCC if SQRE = 0
165: *> and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).
166: *> \endverbatim
167: *>
168: *> \param[in] LDC
169: *> \verbatim
170: *> LDC is INTEGER
171: *> On entry, LDC specifies the leading dimension of C as
172: *> declared in the calling (sub) program. LDC must be at
173: *> least 1. If NCC is nonzero, LDC must also be at least N.
174: *> \endverbatim
175: *>
176: *> \param[out] WORK
177: *> \verbatim
178: *> WORK is DOUBLE PRECISION array, dimension (4*N)
179: *> Workspace. Only referenced if one of NCVT, NRU, or NCC is
180: *> nonzero, and if N is at least 2.
181: *> \endverbatim
182: *>
183: *> \param[out] INFO
184: *> \verbatim
185: *> INFO is INTEGER
186: *> On exit, a value of 0 indicates a successful exit.
187: *> If INFO < 0, argument number -INFO is illegal.
188: *> If INFO > 0, the algorithm did not converge, and INFO
189: *> specifies how many superdiagonals did not converge.
190: *> \endverbatim
191: *
192: * Authors:
193: * ========
194: *
1.17 bertrand 195: *> \author Univ. of Tennessee
196: *> \author Univ. of California Berkeley
197: *> \author Univ. of Colorado Denver
198: *> \author NAG Ltd.
1.9 bertrand 199: *
1.17 bertrand 200: *> \ingroup OTHERauxiliary
1.9 bertrand 201: *
202: *> \par Contributors:
203: * ==================
204: *>
205: *> Ming Gu and Huan Ren, Computer Science Division, University of
206: *> California at Berkeley, USA
207: *>
208: * =====================================================================
1.1 bertrand 209: SUBROUTINE DLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,
210: $ U, LDU, C, LDC, WORK, INFO )
211: *
1.20 ! bertrand 212: * -- LAPACK auxiliary routine --
1.1 bertrand 213: * -- LAPACK is a software package provided by Univ. of Tennessee, --
214: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
215: *
216: * .. Scalar Arguments ..
217: CHARACTER UPLO
218: INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE
219: * ..
220: * .. Array Arguments ..
221: DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),
222: $ VT( LDVT, * ), WORK( * )
223: * ..
224: *
225: * =====================================================================
226: *
227: * .. Parameters ..
228: DOUBLE PRECISION ZERO
229: PARAMETER ( ZERO = 0.0D+0 )
230: * ..
231: * .. Local Scalars ..
232: LOGICAL ROTATE
233: INTEGER I, ISUB, IUPLO, J, NP1, SQRE1
234: DOUBLE PRECISION CS, R, SMIN, SN
235: * ..
236: * .. External Subroutines ..
237: EXTERNAL DBDSQR, DLARTG, DLASR, DSWAP, XERBLA
238: * ..
239: * .. External Functions ..
240: LOGICAL LSAME
241: EXTERNAL LSAME
242: * ..
243: * .. Intrinsic Functions ..
244: INTRINSIC MAX
245: * ..
246: * .. Executable Statements ..
247: *
248: * Test the input parameters.
249: *
250: INFO = 0
251: IUPLO = 0
252: IF( LSAME( UPLO, 'U' ) )
253: $ IUPLO = 1
254: IF( LSAME( UPLO, 'L' ) )
255: $ IUPLO = 2
256: IF( IUPLO.EQ.0 ) THEN
257: INFO = -1
258: ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
259: INFO = -2
260: ELSE IF( N.LT.0 ) THEN
261: INFO = -3
262: ELSE IF( NCVT.LT.0 ) THEN
263: INFO = -4
264: ELSE IF( NRU.LT.0 ) THEN
265: INFO = -5
266: ELSE IF( NCC.LT.0 ) THEN
267: INFO = -6
268: ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
269: $ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
270: INFO = -10
271: ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
272: INFO = -12
273: ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
274: $ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
275: INFO = -14
276: END IF
277: IF( INFO.NE.0 ) THEN
278: CALL XERBLA( 'DLASDQ', -INFO )
279: RETURN
280: END IF
281: IF( N.EQ.0 )
282: $ RETURN
283: *
284: * ROTATE is true if any singular vectors desired, false otherwise
285: *
286: ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
287: NP1 = N + 1
288: SQRE1 = SQRE
289: *
290: * If matrix non-square upper bidiagonal, rotate to be lower
291: * bidiagonal. The rotations are on the right.
292: *
293: IF( ( IUPLO.EQ.1 ) .AND. ( SQRE1.EQ.1 ) ) THEN
294: DO 10 I = 1, N - 1
295: CALL DLARTG( D( I ), E( I ), CS, SN, R )
296: D( I ) = R
297: E( I ) = SN*D( I+1 )
298: D( I+1 ) = CS*D( I+1 )
299: IF( ROTATE ) THEN
300: WORK( I ) = CS
301: WORK( N+I ) = SN
302: END IF
303: 10 CONTINUE
304: CALL DLARTG( D( N ), E( N ), CS, SN, R )
305: D( N ) = R
306: E( N ) = ZERO
307: IF( ROTATE ) THEN
308: WORK( N ) = CS
309: WORK( N+N ) = SN
310: END IF
311: IUPLO = 2
312: SQRE1 = 0
313: *
314: * Update singular vectors if desired.
315: *
316: IF( NCVT.GT.0 )
317: $ CALL DLASR( 'L', 'V', 'F', NP1, NCVT, WORK( 1 ),
318: $ WORK( NP1 ), VT, LDVT )
319: END IF
320: *
321: * If matrix lower bidiagonal, rotate to be upper bidiagonal
322: * by applying Givens rotations on the left.
323: *
324: IF( IUPLO.EQ.2 ) THEN
325: DO 20 I = 1, N - 1
326: CALL DLARTG( D( I ), E( I ), CS, SN, R )
327: D( I ) = R
328: E( I ) = SN*D( I+1 )
329: D( I+1 ) = CS*D( I+1 )
330: IF( ROTATE ) THEN
331: WORK( I ) = CS
332: WORK( N+I ) = SN
333: END IF
334: 20 CONTINUE
335: *
336: * If matrix (N+1)-by-N lower bidiagonal, one additional
337: * rotation is needed.
338: *
339: IF( SQRE1.EQ.1 ) THEN
340: CALL DLARTG( D( N ), E( N ), CS, SN, R )
341: D( N ) = R
342: IF( ROTATE ) THEN
343: WORK( N ) = CS
344: WORK( N+N ) = SN
345: END IF
346: END IF
347: *
348: * Update singular vectors if desired.
349: *
350: IF( NRU.GT.0 ) THEN
351: IF( SQRE1.EQ.0 ) THEN
352: CALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ),
353: $ WORK( NP1 ), U, LDU )
354: ELSE
355: CALL DLASR( 'R', 'V', 'F', NRU, NP1, WORK( 1 ),
356: $ WORK( NP1 ), U, LDU )
357: END IF
358: END IF
359: IF( NCC.GT.0 ) THEN
360: IF( SQRE1.EQ.0 ) THEN
361: CALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ),
362: $ WORK( NP1 ), C, LDC )
363: ELSE
364: CALL DLASR( 'L', 'V', 'F', NP1, NCC, WORK( 1 ),
365: $ WORK( NP1 ), C, LDC )
366: END IF
367: END IF
368: END IF
369: *
370: * Call DBDSQR to compute the SVD of the reduced real
371: * N-by-N upper bidiagonal matrix.
372: *
373: CALL DBDSQR( 'U', N, NCVT, NRU, NCC, D, E, VT, LDVT, U, LDU, C,
374: $ LDC, WORK, INFO )
375: *
376: * Sort the singular values into ascending order (insertion sort on
377: * singular values, but only one transposition per singular vector)
378: *
379: DO 40 I = 1, N
380: *
381: * Scan for smallest D(I).
382: *
383: ISUB = I
384: SMIN = D( I )
385: DO 30 J = I + 1, N
386: IF( D( J ).LT.SMIN ) THEN
387: ISUB = J
388: SMIN = D( J )
389: END IF
390: 30 CONTINUE
391: IF( ISUB.NE.I ) THEN
392: *
393: * Swap singular values and vectors.
394: *
395: D( ISUB ) = D( I )
396: D( I ) = SMIN
397: IF( NCVT.GT.0 )
398: $ CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( I, 1 ), LDVT )
399: IF( NRU.GT.0 )
400: $ CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, I ), 1 )
401: IF( NCC.GT.0 )
402: $ CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( I, 1 ), LDC )
403: END IF
404: 40 CONTINUE
405: *
406: RETURN
407: *
408: * End of DLASDQ
409: *
410: END
CVSweb interface <joel.bertrand@systella.fr>