1: SUBROUTINE DLASD0( N, SQRE, D, E, U, LDU, VT, LDVT, SMLSIZ, IWORK,
2: $ 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: INTEGER INFO, LDU, LDVT, N, SMLSIZ, SQRE
11: * ..
12: * .. Array Arguments ..
13: INTEGER IWORK( * )
14: DOUBLE PRECISION D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),
15: $ WORK( * )
16: * ..
17: *
18: * Purpose
19: * =======
20: *
21: * Using a divide and conquer approach, DLASD0 computes the singular
22: * value decomposition (SVD) of a real upper bidiagonal N-by-M
23: * matrix B with diagonal D and offdiagonal E, where M = N + SQRE.
24: * The algorithm computes orthogonal matrices U and VT such that
25: * B = U * S * VT. The singular values S are overwritten on D.
26: *
27: * A related subroutine, DLASDA, computes only the singular values,
28: * and optionally, the singular vectors in compact form.
29: *
30: * Arguments
31: * =========
32: *
33: * N (input) INTEGER
34: * On entry, the row dimension of the upper bidiagonal matrix.
35: * This is also the dimension of the main diagonal array D.
36: *
37: * SQRE (input) INTEGER
38: * Specifies the column dimension of the bidiagonal matrix.
39: * = 0: The bidiagonal matrix has column dimension M = N;
40: * = 1: The bidiagonal matrix has column dimension M = N+1;
41: *
42: * D (input/output) DOUBLE PRECISION array, dimension (N)
43: * On entry D contains the main diagonal of the bidiagonal
44: * matrix.
45: * On exit D, if INFO = 0, contains its singular values.
46: *
47: * E (input) DOUBLE PRECISION array, dimension (M-1)
48: * Contains the subdiagonal entries of the bidiagonal matrix.
49: * On exit, E has been destroyed.
50: *
51: * U (output) DOUBLE PRECISION array, dimension at least (LDQ, N)
52: * On exit, U contains the left singular vectors.
53: *
54: * LDU (input) INTEGER
55: * On entry, leading dimension of U.
56: *
57: * VT (output) DOUBLE PRECISION array, dimension at least (LDVT, M)
58: * On exit, VT' contains the right singular vectors.
59: *
60: * LDVT (input) INTEGER
61: * On entry, leading dimension of VT.
62: *
63: * SMLSIZ (input) INTEGER
64: * On entry, maximum size of the subproblems at the
65: * bottom of the computation tree.
66: *
67: * IWORK (workspace) INTEGER work array.
68: * Dimension must be at least (8 * N)
69: *
70: * WORK (workspace) DOUBLE PRECISION work array.
71: * Dimension must be at least (3 * M**2 + 2 * M)
72: *
73: * INFO (output) INTEGER
74: * = 0: successful exit.
75: * < 0: if INFO = -i, the i-th argument had an illegal value.
76: * > 0: if INFO = 1, an singular value did not converge
77: *
78: * Further Details
79: * ===============
80: *
81: * Based on contributions by
82: * Ming Gu and Huan Ren, Computer Science Division, University of
83: * California at Berkeley, USA
84: *
85: * =====================================================================
86: *
87: * .. Local Scalars ..
88: INTEGER I, I1, IC, IDXQ, IDXQC, IM1, INODE, ITEMP, IWK,
89: $ J, LF, LL, LVL, M, NCC, ND, NDB1, NDIML, NDIMR,
90: $ NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQREI
91: DOUBLE PRECISION ALPHA, BETA
92: * ..
93: * .. External Subroutines ..
94: EXTERNAL DLASD1, DLASDQ, DLASDT, XERBLA
95: * ..
96: * .. Executable Statements ..
97: *
98: * Test the input parameters.
99: *
100: INFO = 0
101: *
102: IF( N.LT.0 ) THEN
103: INFO = -1
104: ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
105: INFO = -2
106: END IF
107: *
108: M = N + SQRE
109: *
110: IF( LDU.LT.N ) THEN
111: INFO = -6
112: ELSE IF( LDVT.LT.M ) THEN
113: INFO = -8
114: ELSE IF( SMLSIZ.LT.3 ) THEN
115: INFO = -9
116: END IF
117: IF( INFO.NE.0 ) THEN
118: CALL XERBLA( 'DLASD0', -INFO )
119: RETURN
120: END IF
121: *
122: * If the input matrix is too small, call DLASDQ to find the SVD.
123: *
124: IF( N.LE.SMLSIZ ) THEN
125: CALL DLASDQ( 'U', SQRE, N, M, N, 0, D, E, VT, LDVT, U, LDU, U,
126: $ LDU, WORK, INFO )
127: RETURN
128: END IF
129: *
130: * Set up the computation tree.
131: *
132: INODE = 1
133: NDIML = INODE + N
134: NDIMR = NDIML + N
135: IDXQ = NDIMR + N
136: IWK = IDXQ + N
137: CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),
138: $ IWORK( NDIMR ), SMLSIZ )
139: *
140: * For the nodes on bottom level of the tree, solve
141: * their subproblems by DLASDQ.
142: *
143: NDB1 = ( ND+1 ) / 2
144: NCC = 0
145: DO 30 I = NDB1, ND
146: *
147: * IC : center row of each node
148: * NL : number of rows of left subproblem
149: * NR : number of rows of right subproblem
150: * NLF: starting row of the left subproblem
151: * NRF: starting row of the right subproblem
152: *
153: I1 = I - 1
154: IC = IWORK( INODE+I1 )
155: NL = IWORK( NDIML+I1 )
156: NLP1 = NL + 1
157: NR = IWORK( NDIMR+I1 )
158: NRP1 = NR + 1
159: NLF = IC - NL
160: NRF = IC + 1
161: SQREI = 1
162: CALL DLASDQ( 'U', SQREI, NL, NLP1, NL, NCC, D( NLF ), E( NLF ),
163: $ VT( NLF, NLF ), LDVT, U( NLF, NLF ), LDU,
164: $ U( NLF, NLF ), LDU, WORK, INFO )
165: IF( INFO.NE.0 ) THEN
166: RETURN
167: END IF
168: ITEMP = IDXQ + NLF - 2
169: DO 10 J = 1, NL
170: IWORK( ITEMP+J ) = J
171: 10 CONTINUE
172: IF( I.EQ.ND ) THEN
173: SQREI = SQRE
174: ELSE
175: SQREI = 1
176: END IF
177: NRP1 = NR + SQREI
178: CALL DLASDQ( 'U', SQREI, NR, NRP1, NR, NCC, D( NRF ), E( NRF ),
179: $ VT( NRF, NRF ), LDVT, U( NRF, NRF ), LDU,
180: $ U( NRF, NRF ), LDU, WORK, INFO )
181: IF( INFO.NE.0 ) THEN
182: RETURN
183: END IF
184: ITEMP = IDXQ + IC
185: DO 20 J = 1, NR
186: IWORK( ITEMP+J-1 ) = J
187: 20 CONTINUE
188: 30 CONTINUE
189: *
190: * Now conquer each subproblem bottom-up.
191: *
192: DO 50 LVL = NLVL, 1, -1
193: *
194: * Find the first node LF and last node LL on the
195: * current level LVL.
196: *
197: IF( LVL.EQ.1 ) THEN
198: LF = 1
199: LL = 1
200: ELSE
201: LF = 2**( LVL-1 )
202: LL = 2*LF - 1
203: END IF
204: DO 40 I = LF, LL
205: IM1 = I - 1
206: IC = IWORK( INODE+IM1 )
207: NL = IWORK( NDIML+IM1 )
208: NR = IWORK( NDIMR+IM1 )
209: NLF = IC - NL
210: IF( ( SQRE.EQ.0 ) .AND. ( I.EQ.LL ) ) THEN
211: SQREI = SQRE
212: ELSE
213: SQREI = 1
214: END IF
215: IDXQC = IDXQ + NLF - 1
216: ALPHA = D( IC )
217: BETA = E( IC )
218: CALL DLASD1( NL, NR, SQREI, D( NLF ), ALPHA, BETA,
219: $ U( NLF, NLF ), LDU, VT( NLF, NLF ), LDVT,
220: $ IWORK( IDXQC ), IWORK( IWK ), WORK, INFO )
221: IF( INFO.NE.0 ) THEN
222: RETURN
223: END IF
224: 40 CONTINUE
225: 50 CONTINUE
226: *
227: RETURN
228: *
229: * End of DLASD0
230: *
231: END
CVSweb interface <joel.bertrand@systella.fr>