1 *> \brief \b ZLALS0 applies back multiplying factors in solving the least squares problem using divide and conquer SVD approach. Used by sgelsd.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download ZLALS0 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlals0.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlals0.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlals0.f">
21 * SUBROUTINE ZLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
22 * PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
23 * POLES, DIFL, DIFR, Z, K, C, S, RWORK, INFO )
25 * .. Scalar Arguments ..
26 * INTEGER GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
27 * $ LDGNUM, NL, NR, NRHS, SQRE
28 * DOUBLE PRECISION C, S
30 * .. Array Arguments ..
31 * INTEGER GIVCOL( LDGCOL, * ), PERM( * )
32 * DOUBLE PRECISION DIFL( * ), DIFR( LDGNUM, * ),
33 * $ GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
34 * $ RWORK( * ), Z( * )
35 * COMPLEX*16 B( LDB, * ), BX( LDBX, * )
44 *> ZLALS0 applies back the multiplying factors of either the left or the
45 *> right singular vector matrix of a diagonal matrix appended by a row
46 *> to the right hand side matrix B in solving the least squares problem
47 *> using the divide-and-conquer SVD approach.
49 *> For the left singular vector matrix, three types of orthogonal
50 *> matrices are involved:
52 *> (1L) Givens rotations: the number of such rotations is GIVPTR; the
53 *> pairs of columns/rows they were applied to are stored in GIVCOL;
54 *> and the C- and S-values of these rotations are stored in GIVNUM.
56 *> (2L) Permutation. The (NL+1)-st row of B is to be moved to the first
57 *> row, and for J=2:N, PERM(J)-th row of B is to be moved to the
60 *> (3L) The left singular vector matrix of the remaining matrix.
62 *> For the right singular vector matrix, four types of orthogonal
63 *> matrices are involved:
65 *> (1R) The right singular vector matrix of the remaining matrix.
67 *> (2R) If SQRE = 1, one extra Givens rotation to generate the right
70 *> (3R) The inverse transformation of (2L).
72 *> (4R) The inverse transformation of (1L).
81 *> Specifies whether singular vectors are to be computed in
83 *> = 0: Left singular vector matrix.
84 *> = 1: Right singular vector matrix.
90 *> The row dimension of the upper block. NL >= 1.
96 *> The row dimension of the lower block. NR >= 1.
102 *> = 0: the lower block is an NR-by-NR square matrix.
103 *> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
105 *> The bidiagonal matrix has row dimension N = NL + NR + 1,
106 *> and column dimension M = N + SQRE.
112 *> The number of columns of B and BX. NRHS must be at least 1.
117 *> B is COMPLEX*16 array, dimension ( LDB, NRHS )
118 *> On input, B contains the right hand sides of the least
119 *> squares problem in rows 1 through M. On output, B contains
120 *> the solution X in rows 1 through N.
126 *> The leading dimension of B. LDB must be at least
127 *> max(1,MAX( M, N ) ).
132 *> BX is COMPLEX*16 array, dimension ( LDBX, NRHS )
138 *> The leading dimension of BX.
143 *> PERM is INTEGER array, dimension ( N )
144 *> The permutations (from deflation and sorting) applied
145 *> to the two blocks.
151 *> The number of Givens rotations which took place in this
157 *> GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )
158 *> Each pair of numbers indicates a pair of rows/columns
159 *> involved in a Givens rotation.
165 *> The leading dimension of GIVCOL, must be at least N.
170 *> GIVNUM is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
171 *> Each number indicates the C or S value used in the
172 *> corresponding Givens rotation.
178 *> The leading dimension of arrays DIFR, POLES and
179 *> GIVNUM, must be at least K.
184 *> POLES is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
185 *> On entry, POLES(1:K, 1) contains the new singular
186 *> values obtained from solving the secular equation, and
187 *> POLES(1:K, 2) is an array containing the poles in the secular
193 *> DIFL is DOUBLE PRECISION array, dimension ( K ).
194 *> On entry, DIFL(I) is the distance between I-th updated
195 *> (undeflated) singular value and the I-th (undeflated) old
201 *> DIFR is DOUBLE PRECISION array, dimension ( LDGNUM, 2 ).
202 *> On entry, DIFR(I, 1) contains the distances between I-th
203 *> updated (undeflated) singular value and the I+1-th
204 *> (undeflated) old singular value. And DIFR(I, 2) is the
205 *> normalizing factor for the I-th right singular vector.
210 *> Z is DOUBLE PRECISION array, dimension ( K )
211 *> Contain the components of the deflation-adjusted updating row
218 *> Contains the dimension of the non-deflated matrix,
219 *> This is the order of the related secular equation. 1 <= K <=N.
224 *> C is DOUBLE PRECISION
225 *> C contains garbage if SQRE =0 and the C-value of a Givens
226 *> rotation related to the right null space if SQRE = 1.
231 *> S is DOUBLE PRECISION
232 *> S contains garbage if SQRE =0 and the S-value of a Givens
233 *> rotation related to the right null space if SQRE = 1.
238 *> RWORK is DOUBLE PRECISION array, dimension
239 *> ( K*(1+NRHS) + 2*NRHS )
245 *> = 0: successful exit.
246 *> < 0: if INFO = -i, the i-th argument had an illegal value.
252 *> \author Univ. of Tennessee
253 *> \author Univ. of California Berkeley
254 *> \author Univ. of Colorado Denver
257 *> \date November 2015
259 *> \ingroup complex16OTHERcomputational
261 *> \par Contributors:
264 *> Ming Gu and Ren-Cang Li, Computer Science Division, University of
265 *> California at Berkeley, USA \n
266 *> Osni Marques, LBNL/NERSC, USA \n
268 * =====================================================================
269 SUBROUTINE ZLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
270 $ PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
271 $ POLES, DIFL, DIFR, Z, K, C, S, RWORK, INFO )
273 * -- LAPACK computational routine (version 3.6.0) --
274 * -- LAPACK is a software package provided by Univ. of Tennessee, --
275 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
278 * .. Scalar Arguments ..
279 INTEGER GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
280 $ LDGNUM, NL, NR, NRHS, SQRE
281 DOUBLE PRECISION C, S
283 * .. Array Arguments ..
284 INTEGER GIVCOL( LDGCOL, * ), PERM( * )
285 DOUBLE PRECISION DIFL( * ), DIFR( LDGNUM, * ),
286 $ GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
288 COMPLEX*16 B( LDB, * ), BX( LDBX, * )
291 * =====================================================================
294 DOUBLE PRECISION ONE, ZERO, NEGONE
295 PARAMETER ( ONE = 1.0D0, ZERO = 0.0D0, NEGONE = -1.0D0 )
297 * .. Local Scalars ..
298 INTEGER I, J, JCOL, JROW, M, N, NLP1
299 DOUBLE PRECISION DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP
301 * .. External Subroutines ..
302 EXTERNAL DGEMV, XERBLA, ZCOPY, ZDROT, ZDSCAL, ZLACPY,
305 * .. External Functions ..
306 DOUBLE PRECISION DLAMC3, DNRM2
307 EXTERNAL DLAMC3, DNRM2
309 * .. Intrinsic Functions ..
310 INTRINSIC DBLE, DCMPLX, DIMAG, MAX
312 * .. Executable Statements ..
314 * Test the input parameters.
319 IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN
321 ELSE IF( NL.LT.1 ) THEN
323 ELSE IF( NR.LT.1 ) THEN
325 ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN
327 ELSE IF( NRHS.LT.1 ) THEN
329 ELSE IF( LDB.LT.N ) THEN
331 ELSE IF( LDBX.LT.N ) THEN
333 ELSE IF( GIVPTR.LT.0 ) THEN
335 ELSE IF( LDGCOL.LT.N ) THEN
337 ELSE IF( LDGNUM.LT.N ) THEN
339 ELSE IF( K.LT.1 ) THEN
343 CALL XERBLA( 'ZLALS0', -INFO )
350 IF( ICOMPQ.EQ.0 ) THEN
352 * Apply back orthogonal transformations from the left.
354 * Step (1L): apply back the Givens rotations performed.
357 CALL ZDROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
358 $ B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),
362 * Step (2L): permute rows of B.
364 CALL ZCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )
366 CALL ZCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )
369 * Step (3L): apply the inverse of the left singular vector
373 CALL ZCOPY( NRHS, BX, LDBX, B, LDB )
374 IF( Z( 1 ).LT.ZERO ) THEN
375 CALL ZDSCAL( NRHS, NEGONE, B, LDB )
381 DSIGJ = -POLES( J, 2 )
383 DIFRJ = -DIFR( J, 1 )
384 DSIGJP = -POLES( J+1, 2 )
386 IF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )
390 RWORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /
391 $ ( POLES( J, 2 )+DJ )
394 IF( ( Z( I ).EQ.ZERO ) .OR.
395 $ ( POLES( I, 2 ).EQ.ZERO ) ) THEN
398 RWORK( I ) = POLES( I, 2 )*Z( I ) /
399 $ ( DLAMC3( POLES( I, 2 ), DSIGJ )-
400 $ DIFLJ ) / ( POLES( I, 2 )+DJ )
404 IF( ( Z( I ).EQ.ZERO ) .OR.
405 $ ( POLES( I, 2 ).EQ.ZERO ) ) THEN
408 RWORK( I ) = POLES( I, 2 )*Z( I ) /
409 $ ( DLAMC3( POLES( I, 2 ), DSIGJP )+
410 $ DIFRJ ) / ( POLES( I, 2 )+DJ )
414 TEMP = DNRM2( K, RWORK, 1 )
416 * Since B and BX are complex, the following call to DGEMV
417 * is performed in two steps (real and imaginary parts).
419 * CALL DGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,
426 RWORK( I ) = DBLE( BX( JROW, JCOL ) )
429 CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
430 $ RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
435 RWORK( I ) = DIMAG( BX( JROW, JCOL ) )
438 CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
439 $ RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
441 B( J, JCOL ) = DCMPLX( RWORK( JCOL+K ),
442 $ RWORK( JCOL+K+NRHS ) )
444 CALL ZLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),
449 * Move the deflated rows of BX to B also.
451 IF( K.LT.MAX( M, N ) )
452 $ CALL ZLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,
456 * Apply back the right orthogonal transformations.
458 * Step (1R): apply back the new right singular vector matrix
462 CALL ZCOPY( NRHS, B, LDB, BX, LDBX )
465 DSIGJ = POLES( J, 2 )
466 IF( Z( J ).EQ.ZERO ) THEN
469 RWORK( J ) = -Z( J ) / DIFL( J ) /
470 $ ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )
473 IF( Z( J ).EQ.ZERO ) THEN
476 RWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I+1,
477 $ 2 ) )-DIFR( I, 1 ) ) /
478 $ ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
482 IF( Z( J ).EQ.ZERO ) THEN
485 RWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I,
486 $ 2 ) )-DIFL( I ) ) /
487 $ ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )
491 * Since B and BX are complex, the following call to DGEMV
492 * is performed in two steps (real and imaginary parts).
494 * CALL DGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,
495 * $ BX( J, 1 ), LDBX )
498 DO 140 JCOL = 1, NRHS
501 RWORK( I ) = DBLE( B( JROW, JCOL ) )
504 CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
505 $ RWORK( 1 ), 1, ZERO, RWORK( 1+K ), 1 )
507 DO 160 JCOL = 1, NRHS
510 RWORK( I ) = DIMAG( B( JROW, JCOL ) )
513 CALL DGEMV( 'T', K, NRHS, ONE, RWORK( 1+K+NRHS*2 ), K,
514 $ RWORK( 1 ), 1, ZERO, RWORK( 1+K+NRHS ), 1 )
515 DO 170 JCOL = 1, NRHS
516 BX( J, JCOL ) = DCMPLX( RWORK( JCOL+K ),
517 $ RWORK( JCOL+K+NRHS ) )
522 * Step (2R): if SQRE = 1, apply back the rotation that is
523 * related to the right null space of the subproblem.
526 CALL ZCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )
527 CALL ZDROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )
529 IF( K.LT.MAX( M, N ) )
530 $ CALL ZLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB, BX( K+1, 1 ),
533 * Step (3R): permute rows of B.
535 CALL ZCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )
537 CALL ZCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )
540 CALL ZCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )
543 * Step (4R): apply back the Givens rotations performed.
545 DO 200 I = GIVPTR, 1, -1
546 CALL ZDROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,
547 $ B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),