LAPACK 3.12.0
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dlasd0.f
Go to the documentation of this file.
1*> \brief \b DLASD0 computes the singular values of a real upper bidiagonal n-by-m matrix B with diagonal d and off-diagonal e. Used by sbdsdc.
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download DLASD0 + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd0.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd0.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd0.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE DLASD0( N, SQRE, D, E, U, LDU, VT, LDVT, SMLSIZ, IWORK,
22* WORK, INFO )
23*
24* .. Scalar Arguments ..
25* INTEGER INFO, LDU, LDVT, N, SMLSIZ, SQRE
26* ..
27* .. Array Arguments ..
28* INTEGER IWORK( * )
29* DOUBLE PRECISION D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),
30* $ WORK( * )
31* ..
32*
33*
34*> \par Purpose:
35* =============
36*>
37*> \verbatim
38*>
39*> Using a divide and conquer approach, DLASD0 computes the singular
40*> value decomposition (SVD) of a real upper bidiagonal N-by-M
41*> matrix B with diagonal D and offdiagonal E, where M = N + SQRE.
42*> The algorithm computes orthogonal matrices U and VT such that
43*> B = U * S * VT. The singular values S are overwritten on D.
44*>
45*> A related subroutine, DLASDA, computes only the singular values,
46*> and optionally, the singular vectors in compact form.
47*> \endverbatim
48*
49* Arguments:
50* ==========
51*
52*> \param[in] N
53*> \verbatim
54*> N is INTEGER
55*> On entry, the row dimension of the upper bidiagonal matrix.
56*> This is also the dimension of the main diagonal array D.
57*> \endverbatim
58*>
59*> \param[in] SQRE
60*> \verbatim
61*> SQRE is INTEGER
62*> Specifies the column dimension of the bidiagonal matrix.
63*> = 0: The bidiagonal matrix has column dimension M = N;
64*> = 1: The bidiagonal matrix has column dimension M = N+1;
65*> \endverbatim
66*>
67*> \param[in,out] D
68*> \verbatim
69*> D is DOUBLE PRECISION array, dimension (N)
70*> On entry D contains the main diagonal of the bidiagonal
71*> matrix.
72*> On exit D, if INFO = 0, contains its singular values.
73*> \endverbatim
74*>
75*> \param[in,out] E
76*> \verbatim
77*> E is DOUBLE PRECISION array, dimension (M-1)
78*> Contains the subdiagonal entries of the bidiagonal matrix.
79*> On exit, E has been destroyed.
80*> \endverbatim
81*>
82*> \param[in,out] U
83*> \verbatim
84*> U is DOUBLE PRECISION array, dimension (LDU, N)
85*> On exit, U contains the left singular vectors,
86*> if U passed in as (N, N) Identity.
87*> \endverbatim
88*>
89*> \param[in] LDU
90*> \verbatim
91*> LDU is INTEGER
92*> On entry, leading dimension of U.
93*> \endverbatim
94*>
95*> \param[in,out] VT
96*> \verbatim
97*> VT is DOUBLE PRECISION array, dimension (LDVT, M)
98*> On exit, VT**T contains the right singular vectors,
99*> if VT passed in as (M, M) Identity.
100*> \endverbatim
101*>
102*> \param[in] LDVT
103*> \verbatim
104*> LDVT is INTEGER
105*> On entry, leading dimension of VT.
106*> \endverbatim
107*>
108*> \param[in] SMLSIZ
109*> \verbatim
110*> SMLSIZ is INTEGER
111*> On entry, maximum size of the subproblems at the
112*> bottom of the computation tree.
113*> \endverbatim
114*>
115*> \param[out] IWORK
116*> \verbatim
117*> IWORK is INTEGER array, dimension (8*N)
118*> \endverbatim
119*>
120*> \param[out] WORK
121*> \verbatim
122*> WORK is DOUBLE PRECISION array, dimension (3*M**2+2*M)
123*> \endverbatim
124*>
125*> \param[out] INFO
126*> \verbatim
127*> INFO is INTEGER
128*> = 0: successful exit.
129*> < 0: if INFO = -i, the i-th argument had an illegal value.
130*> > 0: if INFO = 1, a singular value did not converge
131*> \endverbatim
132*
133* Authors:
134* ========
135*
136*> \author Univ. of Tennessee
137*> \author Univ. of California Berkeley
138*> \author Univ. of Colorado Denver
139*> \author NAG Ltd.
140*
141*> \ingroup lasd0
142*
143*> \par Contributors:
144* ==================
145*>
146*> Ming Gu and Huan Ren, Computer Science Division, University of
147*> California at Berkeley, USA
148*>
149* =====================================================================
150 SUBROUTINE dlasd0( N, SQRE, D, E, U, LDU, VT, LDVT, SMLSIZ, IWORK,
151 $ WORK, INFO )
152*
153* -- LAPACK auxiliary routine --
154* -- LAPACK is a software package provided by Univ. of Tennessee, --
155* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
156*
157* .. Scalar Arguments ..
158 INTEGER INFO, LDU, LDVT, N, SMLSIZ, SQRE
159* ..
160* .. Array Arguments ..
161 INTEGER IWORK( * )
162 DOUBLE PRECISION D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),
163 $ work( * )
164* ..
165*
166* =====================================================================
167*
168* .. Local Scalars ..
169 INTEGER I, I1, IC, IDXQ, IDXQC, IM1, INODE, ITEMP, IWK,
170 $ j, lf, ll, lvl, m, ncc, nd, ndb1, ndiml, ndimr,
171 $ nl, nlf, nlp1, nlvl, nr, nrf, nrp1, sqrei
172 DOUBLE PRECISION ALPHA, BETA
173* ..
174* .. External Subroutines ..
175 EXTERNAL dlasd1, dlasdq, dlasdt, xerbla
176* ..
177* .. Executable Statements ..
178*
179* Test the input parameters.
180*
181 info = 0
182*
183 IF( n.LT.0 ) THEN
184 info = -1
185 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
186 info = -2
187 END IF
188*
189 m = n + sqre
190*
191 IF( ldu.LT.n ) THEN
192 info = -6
193 ELSE IF( ldvt.LT.m ) THEN
194 info = -8
195 ELSE IF( smlsiz.LT.3 ) THEN
196 info = -9
197 END IF
198 IF( info.NE.0 ) THEN
199 CALL xerbla( 'DLASD0', -info )
200 RETURN
201 END IF
202*
203* If the input matrix is too small, call DLASDQ to find the SVD.
204*
205 IF( n.LE.smlsiz ) THEN
206 CALL dlasdq( 'U', sqre, n, m, n, 0, d, e, vt, ldvt, u, ldu, u,
207 $ ldu, work, info )
208 RETURN
209 END IF
210*
211* Set up the computation tree.
212*
213 inode = 1
214 ndiml = inode + n
215 ndimr = ndiml + n
216 idxq = ndimr + n
217 iwk = idxq + n
218 CALL dlasdt( n, nlvl, nd, iwork( inode ), iwork( ndiml ),
219 $ iwork( ndimr ), smlsiz )
220*
221* For the nodes on bottom level of the tree, solve
222* their subproblems by DLASDQ.
223*
224 ndb1 = ( nd+1 ) / 2
225 ncc = 0
226 DO 30 i = ndb1, nd
227*
228* IC : center row of each node
229* NL : number of rows of left subproblem
230* NR : number of rows of right subproblem
231* NLF: starting row of the left subproblem
232* NRF: starting row of the right subproblem
233*
234 i1 = i - 1
235 ic = iwork( inode+i1 )
236 nl = iwork( ndiml+i1 )
237 nlp1 = nl + 1
238 nr = iwork( ndimr+i1 )
239 nrp1 = nr + 1
240 nlf = ic - nl
241 nrf = ic + 1
242 sqrei = 1
243 CALL dlasdq( 'U', sqrei, nl, nlp1, nl, ncc, d( nlf ), e( nlf ),
244 $ vt( nlf, nlf ), ldvt, u( nlf, nlf ), ldu,
245 $ u( nlf, nlf ), ldu, work, info )
246 IF( info.NE.0 ) THEN
247 RETURN
248 END IF
249 itemp = idxq + nlf - 2
250 DO 10 j = 1, nl
251 iwork( itemp+j ) = j
252 10 CONTINUE
253 IF( i.EQ.nd ) THEN
254 sqrei = sqre
255 ELSE
256 sqrei = 1
257 END IF
258 nrp1 = nr + sqrei
259 CALL dlasdq( 'U', sqrei, nr, nrp1, nr, ncc, d( nrf ), e( nrf ),
260 $ vt( nrf, nrf ), ldvt, u( nrf, nrf ), ldu,
261 $ u( nrf, nrf ), ldu, work, info )
262 IF( info.NE.0 ) THEN
263 RETURN
264 END IF
265 itemp = idxq + ic
266 DO 20 j = 1, nr
267 iwork( itemp+j-1 ) = j
268 20 CONTINUE
269 30 CONTINUE
270*
271* Now conquer each subproblem bottom-up.
272*
273 DO 50 lvl = nlvl, 1, -1
274*
275* Find the first node LF and last node LL on the
276* current level LVL.
277*
278 IF( lvl.EQ.1 ) THEN
279 lf = 1
280 ll = 1
281 ELSE
282 lf = 2**( lvl-1 )
283 ll = 2*lf - 1
284 END IF
285 DO 40 i = lf, ll
286 im1 = i - 1
287 ic = iwork( inode+im1 )
288 nl = iwork( ndiml+im1 )
289 nr = iwork( ndimr+im1 )
290 nlf = ic - nl
291 IF( ( sqre.EQ.0 ) .AND. ( i.EQ.ll ) ) THEN
292 sqrei = sqre
293 ELSE
294 sqrei = 1
295 END IF
296 idxqc = idxq + nlf - 1
297 alpha = d( ic )
298 beta = e( ic )
299 CALL dlasd1( nl, nr, sqrei, d( nlf ), alpha, beta,
300 $ u( nlf, nlf ), ldu, vt( nlf, nlf ), ldvt,
301 $ iwork( idxqc ), iwork( iwk ), work, info )
302*
303* Report the possible convergence failure.
304*
305 IF( info.NE.0 ) THEN
306 RETURN
307 END IF
308 40 CONTINUE
309 50 CONTINUE
310*
311 RETURN
312*
313* End of DLASD0
314*
315 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dlasd0(n, sqre, d, e, u, ldu, vt, ldvt, smlsiz, iwork, work, info)
DLASD0 computes the singular values of a real upper bidiagonal n-by-m matrix B with diagonal d and of...
Definition dlasd0.f:152
subroutine dlasd1(nl, nr, sqre, d, alpha, beta, u, ldu, vt, ldvt, idxq, iwork, work, info)
DLASD1 computes the SVD of an upper bidiagonal matrix B of the specified size. Used by sbdsdc.
Definition dlasd1.f:204
subroutine dlasdq(uplo, sqre, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
DLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e....
Definition dlasdq.f:211
subroutine dlasdt(n, lvl, nd, inode, ndiml, ndimr, msub)
DLASDT creates a tree of subproblems for bidiagonal divide and conquer. Used by sbdsdc.
Definition dlasdt.f:105