LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dlasda.f
Go to the documentation of this file.
1*> \brief \b DLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix 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*> Download DLASDA + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasda.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasda.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasda.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DLASDA( ICOMPQ, SMLSIZ, N, SQRE, D, E, U, LDU, VT, K,
20* DIFL, DIFR, Z, POLES, GIVPTR, GIVCOL, LDGCOL,
21* PERM, GIVNUM, C, S, WORK, IWORK, INFO )
22*
23* .. Scalar Arguments ..
24* INTEGER ICOMPQ, INFO, LDGCOL, LDU, N, SMLSIZ, SQRE
25* ..
26* .. Array Arguments ..
27* INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
28* $ K( * ), PERM( LDGCOL, * )
29* DOUBLE PRECISION C( * ), D( * ), DIFL( LDU, * ), DIFR( LDU, * ),
30* $ E( * ), GIVNUM( LDU, * ), POLES( LDU, * ),
31* $ S( * ), U( LDU, * ), VT( LDU, * ), WORK( * ),
32* $ Z( LDU, * )
33* ..
34*
35*
36*> \par Purpose:
37* =============
38*>
39*> \verbatim
40*>
41*> Using a divide and conquer approach, DLASDA computes the singular
42*> value decomposition (SVD) of a real upper bidiagonal N-by-M matrix
43*> B with diagonal D and offdiagonal E, where M = N + SQRE. The
44*> algorithm computes the singular values in the SVD B = U * S * VT.
45*> The orthogonal matrices U and VT are optionally computed in
46*> compact form.
47*>
48*> A related subroutine, DLASD0, computes the singular values and
49*> the singular vectors in explicit form.
50*> \endverbatim
51*
52* Arguments:
53* ==========
54*
55*> \param[in] ICOMPQ
56*> \verbatim
57*> ICOMPQ is INTEGER
58*> Specifies whether singular vectors are to be computed
59*> in compact form, as follows
60*> = 0: Compute singular values only.
61*> = 1: Compute singular vectors of upper bidiagonal
62*> matrix in compact form.
63*> \endverbatim
64*>
65*> \param[in] SMLSIZ
66*> \verbatim
67*> SMLSIZ is INTEGER
68*> The maximum size of the subproblems at the bottom of the
69*> computation tree.
70*> \endverbatim
71*>
72*> \param[in] N
73*> \verbatim
74*> N is INTEGER
75*> The row dimension of the upper bidiagonal matrix. This is
76*> also the dimension of the main diagonal array D.
77*> \endverbatim
78*>
79*> \param[in] SQRE
80*> \verbatim
81*> SQRE is INTEGER
82*> Specifies the column dimension of the bidiagonal matrix.
83*> = 0: The bidiagonal matrix has column dimension M = N;
84*> = 1: The bidiagonal matrix has column dimension M = N + 1.
85*> \endverbatim
86*>
87*> \param[in,out] D
88*> \verbatim
89*> D is DOUBLE PRECISION array, dimension ( N )
90*> On entry D contains the main diagonal of the bidiagonal
91*> matrix. On exit D, if INFO = 0, contains its singular values.
92*> \endverbatim
93*>
94*> \param[in] E
95*> \verbatim
96*> E is DOUBLE PRECISION array, dimension ( M-1 )
97*> Contains the subdiagonal entries of the bidiagonal matrix.
98*> On exit, E has been destroyed.
99*> \endverbatim
100*>
101*> \param[out] U
102*> \verbatim
103*> U is DOUBLE PRECISION array,
104*> dimension ( LDU, SMLSIZ ) if ICOMPQ = 1, and not referenced
105*> if ICOMPQ = 0. If ICOMPQ = 1, on exit, U contains the left
106*> singular vector matrices of all subproblems at the bottom
107*> level.
108*> \endverbatim
109*>
110*> \param[in] LDU
111*> \verbatim
112*> LDU is INTEGER, LDU = > N.
113*> The leading dimension of arrays U, VT, DIFL, DIFR, POLES,
114*> GIVNUM, and Z.
115*> \endverbatim
116*>
117*> \param[out] VT
118*> \verbatim
119*> VT is DOUBLE PRECISION array,
120*> dimension ( LDU, SMLSIZ+1 ) if ICOMPQ = 1, and not referenced
121*> if ICOMPQ = 0. If ICOMPQ = 1, on exit, VT**T contains the right
122*> singular vector matrices of all subproblems at the bottom
123*> level.
124*> \endverbatim
125*>
126*> \param[out] K
127*> \verbatim
128*> K is INTEGER array,
129*> dimension ( N ) if ICOMPQ = 1 and dimension 1 if ICOMPQ = 0.
130*> If ICOMPQ = 1, on exit, K(I) is the dimension of the I-th
131*> secular equation on the computation tree.
132*> \endverbatim
133*>
134*> \param[out] DIFL
135*> \verbatim
136*> DIFL is DOUBLE PRECISION array, dimension ( LDU, NLVL ),
137*> where NLVL = floor(log_2 (N/SMLSIZ))).
138*> \endverbatim
139*>
140*> \param[out] DIFR
141*> \verbatim
142*> DIFR is DOUBLE PRECISION array,
143*> dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1 and
144*> dimension ( N ) if ICOMPQ = 0.
145*> If ICOMPQ = 1, on exit, DIFL(1:N, I) and DIFR(1:N, 2 * I - 1)
146*> record distances between singular values on the I-th
147*> level and singular values on the (I -1)-th level, and
148*> DIFR(1:N, 2 * I ) contains the normalizing factors for
149*> the right singular vector matrix. See DLASD8 for details.
150*> \endverbatim
151*>
152*> \param[out] Z
153*> \verbatim
154*> Z is DOUBLE PRECISION array,
155*> dimension ( LDU, NLVL ) if ICOMPQ = 1 and
156*> dimension ( N ) if ICOMPQ = 0.
157*> The first K elements of Z(1, I) contain the components of
158*> the deflation-adjusted updating row vector for subproblems
159*> on the I-th level.
160*> \endverbatim
161*>
162*> \param[out] POLES
163*> \verbatim
164*> POLES is DOUBLE PRECISION array,
165*> dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not referenced
166*> if ICOMPQ = 0. If ICOMPQ = 1, on exit, POLES(1, 2*I - 1) and
167*> POLES(1, 2*I) contain the new and old singular values
168*> involved in the secular equations on the I-th level.
169*> \endverbatim
170*>
171*> \param[out] GIVPTR
172*> \verbatim
173*> GIVPTR is INTEGER array,
174*> dimension ( N ) if ICOMPQ = 1, and not referenced if
175*> ICOMPQ = 0. If ICOMPQ = 1, on exit, GIVPTR( I ) records
176*> the number of Givens rotations performed on the I-th
177*> problem on the computation tree.
178*> \endverbatim
179*>
180*> \param[out] GIVCOL
181*> \verbatim
182*> GIVCOL is INTEGER array,
183*> dimension ( LDGCOL, 2 * NLVL ) if ICOMPQ = 1, and not
184*> referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
185*> GIVCOL(1, 2 *I - 1) and GIVCOL(1, 2 *I) record the locations
186*> of Givens rotations performed on the I-th level on the
187*> computation tree.
188*> \endverbatim
189*>
190*> \param[in] LDGCOL
191*> \verbatim
192*> LDGCOL is INTEGER, LDGCOL = > N.
193*> The leading dimension of arrays GIVCOL and PERM.
194*> \endverbatim
195*>
196*> \param[out] PERM
197*> \verbatim
198*> PERM is INTEGER array,
199*> dimension ( LDGCOL, NLVL ) if ICOMPQ = 1, and not referenced
200*> if ICOMPQ = 0. If ICOMPQ = 1, on exit, PERM(1, I) records
201*> permutations done on the I-th level of the computation tree.
202*> \endverbatim
203*>
204*> \param[out] GIVNUM
205*> \verbatim
206*> GIVNUM is DOUBLE PRECISION array,
207*> dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not
208*> referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
209*> GIVNUM(1, 2 *I - 1) and GIVNUM(1, 2 *I) record the C- and S-
210*> values of Givens rotations performed on the I-th level on
211*> the computation tree.
212*> \endverbatim
213*>
214*> \param[out] C
215*> \verbatim
216*> C is DOUBLE PRECISION array,
217*> dimension ( N ) if ICOMPQ = 1, and dimension 1 if ICOMPQ = 0.
218*> If ICOMPQ = 1 and the I-th subproblem is not square, on exit,
219*> C( I ) contains the C-value of a Givens rotation related to
220*> the right null space of the I-th subproblem.
221*> \endverbatim
222*>
223*> \param[out] S
224*> \verbatim
225*> S is DOUBLE PRECISION array, dimension ( N ) if
226*> ICOMPQ = 1, and dimension 1 if ICOMPQ = 0. If ICOMPQ = 1
227*> and the I-th subproblem is not square, on exit, S( I )
228*> contains the S-value of a Givens rotation related to
229*> the right null space of the I-th subproblem.
230*> \endverbatim
231*>
232*> \param[out] WORK
233*> \verbatim
234*> WORK is DOUBLE PRECISION array, dimension
235*> (6 * N + (SMLSIZ + 1)*(SMLSIZ + 1)).
236*> \endverbatim
237*>
238*> \param[out] IWORK
239*> \verbatim
240*> IWORK is INTEGER array, dimension (7*N)
241*> \endverbatim
242*>
243*> \param[out] INFO
244*> \verbatim
245*> INFO is INTEGER
246*> = 0: successful exit.
247*> < 0: if INFO = -i, the i-th argument had an illegal value.
248*> > 0: if INFO = 1, a singular value did not converge
249*> \endverbatim
250*
251* Authors:
252* ========
253*
254*> \author Univ. of Tennessee
255*> \author Univ. of California Berkeley
256*> \author Univ. of Colorado Denver
257*> \author NAG Ltd.
258*
259*> \ingroup lasda
260*
261*> \par Contributors:
262* ==================
263*>
264*> Ming Gu and Huan Ren, Computer Science Division, University of
265*> California at Berkeley, USA
266*>
267* =====================================================================
268 SUBROUTINE dlasda( ICOMPQ, SMLSIZ, N, SQRE, D, E, U, LDU, VT,
269 $ K,
270 $ DIFL, DIFR, Z, POLES, GIVPTR, GIVCOL, LDGCOL,
271 $ PERM, GIVNUM, C, S, WORK, IWORK, INFO )
272*
273* -- LAPACK auxiliary routine --
274* -- LAPACK is a software package provided by Univ. of Tennessee, --
275* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
276*
277* .. Scalar Arguments ..
278 INTEGER ICOMPQ, INFO, LDGCOL, LDU, N, SMLSIZ, SQRE
279* ..
280* .. Array Arguments ..
281 INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
282 $ K( * ), PERM( LDGCOL, * )
283 DOUBLE PRECISION C( * ), D( * ), DIFL( LDU, * ), DIFR( LDU, * ),
284 $ e( * ), givnum( ldu, * ), poles( ldu, * ),
285 $ s( * ), u( ldu, * ), vt( ldu, * ), work( * ),
286 $ z( ldu, * )
287* ..
288*
289* =====================================================================
290*
291* .. Parameters ..
292 DOUBLE PRECISION ZERO, ONE
293 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
294* ..
295* .. Local Scalars ..
296 INTEGER I, I1, IC, IDXQ, IDXQI, IM1, INODE, ITEMP, IWK,
297 $ J, LF, LL, LVL, LVL2, M, NCC, ND, NDB1, NDIML,
298 $ NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, NRU,
299 $ nwork1, nwork2, smlszp, sqrei, vf, vfi, vl, vli
300 DOUBLE PRECISION ALPHA, BETA
301* ..
302* .. External Subroutines ..
303 EXTERNAL dcopy, dlasd6, dlasdq, dlasdt, dlaset,
304 $ xerbla
305* ..
306* .. Executable Statements ..
307*
308* Test the input parameters.
309*
310 info = 0
311*
312 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
313 info = -1
314 ELSE IF( smlsiz.LT.3 ) THEN
315 info = -2
316 ELSE IF( n.LT.0 ) THEN
317 info = -3
318 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
319 info = -4
320 ELSE IF( ldu.LT.( n+sqre ) ) THEN
321 info = -8
322 ELSE IF( ldgcol.LT.n ) THEN
323 info = -17
324 END IF
325 IF( info.NE.0 ) THEN
326 CALL xerbla( 'DLASDA', -info )
327 RETURN
328 END IF
329*
330 m = n + sqre
331*
332* If the input matrix is too small, call DLASDQ to find the SVD.
333*
334 IF( n.LE.smlsiz ) THEN
335 IF( icompq.EQ.0 ) THEN
336 CALL dlasdq( 'U', sqre, n, 0, 0, 0, d, e, vt, ldu, u,
337 $ ldu,
338 $ u, ldu, work, info )
339 ELSE
340 CALL dlasdq( 'U', sqre, n, m, n, 0, d, e, vt, ldu, u,
341 $ ldu,
342 $ u, ldu, work, info )
343 END IF
344 RETURN
345 END IF
346*
347* Book-keeping and set up the computation tree.
348*
349 inode = 1
350 ndiml = inode + n
351 ndimr = ndiml + n
352 idxq = ndimr + n
353 iwk = idxq + n
354*
355 ncc = 0
356 nru = 0
357*
358 smlszp = smlsiz + 1
359 vf = 1
360 vl = vf + m
361 nwork1 = vl + m
362 nwork2 = nwork1 + smlszp*smlszp
363*
364 CALL dlasdt( n, nlvl, nd, iwork( inode ), iwork( ndiml ),
365 $ iwork( ndimr ), smlsiz )
366*
367* for the nodes on bottom level of the tree, solve
368* their subproblems by DLASDQ.
369*
370 ndb1 = ( nd+1 ) / 2
371 DO 30 i = ndb1, nd
372*
373* IC : center row of each node
374* NL : number of rows of left subproblem
375* NR : number of rows of right subproblem
376* NLF: starting row of the left subproblem
377* NRF: starting row of the right subproblem
378*
379 i1 = i - 1
380 ic = iwork( inode+i1 )
381 nl = iwork( ndiml+i1 )
382 nlp1 = nl + 1
383 nr = iwork( ndimr+i1 )
384 nlf = ic - nl
385 nrf = ic + 1
386 idxqi = idxq + nlf - 2
387 vfi = vf + nlf - 1
388 vli = vl + nlf - 1
389 sqrei = 1
390 IF( icompq.EQ.0 ) THEN
391 CALL dlaset( 'A', nlp1, nlp1, zero, one, work( nwork1 ),
392 $ smlszp )
393 CALL dlasdq( 'U', sqrei, nl, nlp1, nru, ncc, d( nlf ),
394 $ e( nlf ), work( nwork1 ), smlszp,
395 $ work( nwork2 ), nl, work( nwork2 ), nl,
396 $ work( nwork2 ), info )
397 itemp = nwork1 + nl*smlszp
398 CALL dcopy( nlp1, work( nwork1 ), 1, work( vfi ), 1 )
399 CALL dcopy( nlp1, work( itemp ), 1, work( vli ), 1 )
400 ELSE
401 CALL dlaset( 'A', nl, nl, zero, one, u( nlf, 1 ), ldu )
402 CALL dlaset( 'A', nlp1, nlp1, zero, one, vt( nlf, 1 ),
403 $ ldu )
404 CALL dlasdq( 'U', sqrei, nl, nlp1, nl, ncc, d( nlf ),
405 $ e( nlf ), vt( nlf, 1 ), ldu, u( nlf, 1 ), ldu,
406 $ u( nlf, 1 ), ldu, work( nwork1 ), info )
407 CALL dcopy( nlp1, vt( nlf, 1 ), 1, work( vfi ), 1 )
408 CALL dcopy( nlp1, vt( nlf, nlp1 ), 1, work( vli ), 1 )
409 END IF
410 IF( info.NE.0 ) THEN
411 RETURN
412 END IF
413 DO 10 j = 1, nl
414 iwork( idxqi+j ) = j
415 10 CONTINUE
416 IF( ( i.EQ.nd ) .AND. ( sqre.EQ.0 ) ) THEN
417 sqrei = 0
418 ELSE
419 sqrei = 1
420 END IF
421 idxqi = idxqi + nlp1
422 vfi = vfi + nlp1
423 vli = vli + nlp1
424 nrp1 = nr + sqrei
425 IF( icompq.EQ.0 ) THEN
426 CALL dlaset( 'A', nrp1, nrp1, zero, one, work( nwork1 ),
427 $ smlszp )
428 CALL dlasdq( 'U', sqrei, nr, nrp1, nru, ncc, d( nrf ),
429 $ e( nrf ), work( nwork1 ), smlszp,
430 $ work( nwork2 ), nr, work( nwork2 ), nr,
431 $ work( nwork2 ), info )
432 itemp = nwork1 + ( nrp1-1 )*smlszp
433 CALL dcopy( nrp1, work( nwork1 ), 1, work( vfi ), 1 )
434 CALL dcopy( nrp1, work( itemp ), 1, work( vli ), 1 )
435 ELSE
436 CALL dlaset( 'A', nr, nr, zero, one, u( nrf, 1 ), ldu )
437 CALL dlaset( 'A', nrp1, nrp1, zero, one, vt( nrf, 1 ),
438 $ ldu )
439 CALL dlasdq( 'U', sqrei, nr, nrp1, nr, ncc, d( nrf ),
440 $ e( nrf ), vt( nrf, 1 ), ldu, u( nrf, 1 ), ldu,
441 $ u( nrf, 1 ), ldu, work( nwork1 ), info )
442 CALL dcopy( nrp1, vt( nrf, 1 ), 1, work( vfi ), 1 )
443 CALL dcopy( nrp1, vt( nrf, nrp1 ), 1, work( vli ), 1 )
444 END IF
445 IF( info.NE.0 ) THEN
446 RETURN
447 END IF
448 DO 20 j = 1, nr
449 iwork( idxqi+j ) = j
450 20 CONTINUE
451 30 CONTINUE
452*
453* Now conquer each subproblem bottom-up.
454*
455 j = 2**nlvl
456 DO 50 lvl = nlvl, 1, -1
457 lvl2 = lvl*2 - 1
458*
459* Find the first node LF and last node LL on
460* the current level LVL.
461*
462 IF( lvl.EQ.1 ) THEN
463 lf = 1
464 ll = 1
465 ELSE
466 lf = 2**( lvl-1 )
467 ll = 2*lf - 1
468 END IF
469 DO 40 i = lf, ll
470 im1 = i - 1
471 ic = iwork( inode+im1 )
472 nl = iwork( ndiml+im1 )
473 nr = iwork( ndimr+im1 )
474 nlf = ic - nl
475 nrf = ic + 1
476 IF( i.EQ.ll ) THEN
477 sqrei = sqre
478 ELSE
479 sqrei = 1
480 END IF
481 vfi = vf + nlf - 1
482 vli = vl + nlf - 1
483 idxqi = idxq + nlf - 1
484 alpha = d( ic )
485 beta = e( ic )
486 IF( icompq.EQ.0 ) THEN
487 CALL dlasd6( icompq, nl, nr, sqrei, d( nlf ),
488 $ work( vfi ), work( vli ), alpha, beta,
489 $ iwork( idxqi ), perm, givptr( 1 ), givcol,
490 $ ldgcol, givnum, ldu, poles, difl, difr, z,
491 $ k( 1 ), c( 1 ), s( 1 ), work( nwork1 ),
492 $ iwork( iwk ), info )
493 ELSE
494 j = j - 1
495 CALL dlasd6( icompq, nl, nr, sqrei, d( nlf ),
496 $ work( vfi ), work( vli ), alpha, beta,
497 $ iwork( idxqi ), perm( nlf, lvl ),
498 $ givptr( j ), givcol( nlf, lvl2 ), ldgcol,
499 $ givnum( nlf, lvl2 ), ldu,
500 $ poles( nlf, lvl2 ), difl( nlf, lvl ),
501 $ difr( nlf, lvl2 ), z( nlf, lvl ), k( j ),
502 $ c( j ), s( j ), work( nwork1 ),
503 $ iwork( iwk ), info )
504 END IF
505 IF( info.NE.0 ) THEN
506 RETURN
507 END IF
508 40 CONTINUE
509 50 CONTINUE
510*
511 RETURN
512*
513* End of DLASDA
514*
515 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine dlasd6(icompq, nl, nr, sqre, d, vf, vl, alpha, beta, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, poles, difl, difr, z, k, c, s, work, iwork, info)
DLASD6 computes the SVD of an updated upper bidiagonal matrix obtained by merging two smaller ones by...
Definition dlasd6.f:312
subroutine dlasda(icompq, smlsiz, n, sqre, d, e, u, ldu, vt, k, difl, difr, z, poles, givptr, givcol, ldgcol, perm, givnum, c, s, work, iwork, info)
DLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagona...
Definition dlasda.f:272
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:210
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:103
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition dlaset.f:108