LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
slals0.f
Go to the documentation of this file.
1*> \brief \b SLALS0 applies back multiplying factors in solving the least squares problem using divide and conquer SVD approach. Used by sgelsd.
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download SLALS0 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slals0.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slals0.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slals0.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE SLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,
20* PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
21* POLES, DIFL, DIFR, Z, K, C, S, WORK, INFO )
22*
23* .. Scalar Arguments ..
24* INTEGER GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
25* $ LDGNUM, NL, NR, NRHS, SQRE
26* REAL C, S
27* ..
28* .. Array Arguments ..
29* INTEGER GIVCOL( LDGCOL, * ), PERM( * )
30* REAL B( LDB, * ), BX( LDBX, * ), DIFL( * ),
31* $ DIFR( LDGNUM, * ), GIVNUM( LDGNUM, * ),
32* $ POLES( LDGNUM, * ), WORK( * ), Z( * )
33* ..
34*
35*
36*> \par Purpose:
37* =============
38*>
39*> \verbatim
40*>
41*> SLALS0 applies back the multiplying factors of either the left or the
42*> right singular vector matrix of a diagonal matrix appended by a row
43*> to the right hand side matrix B in solving the least squares problem
44*> using the divide-and-conquer SVD approach.
45*>
46*> For the left singular vector matrix, three types of orthogonal
47*> matrices are involved:
48*>
49*> (1L) Givens rotations: the number of such rotations is GIVPTR; the
50*> pairs of columns/rows they were applied to are stored in GIVCOL;
51*> and the C- and S-values of these rotations are stored in GIVNUM.
52*>
53*> (2L) Permutation. The (NL+1)-st row of B is to be moved to the first
54*> row, and for J=2:N, PERM(J)-th row of B is to be moved to the
55*> J-th row.
56*>
57*> (3L) The left singular vector matrix of the remaining matrix.
58*>
59*> For the right singular vector matrix, four types of orthogonal
60*> matrices are involved:
61*>
62*> (1R) The right singular vector matrix of the remaining matrix.
63*>
64*> (2R) If SQRE = 1, one extra Givens rotation to generate the right
65*> null space.
66*>
67*> (3R) The inverse transformation of (2L).
68*>
69*> (4R) The inverse transformation of (1L).
70*> \endverbatim
71*
72* Arguments:
73* ==========
74*
75*> \param[in] ICOMPQ
76*> \verbatim
77*> ICOMPQ is INTEGER
78*> Specifies whether singular vectors are to be computed in
79*> factored form:
80*> = 0: Left singular vector matrix.
81*> = 1: Right singular vector matrix.
82*> \endverbatim
83*>
84*> \param[in] NL
85*> \verbatim
86*> NL is INTEGER
87*> The row dimension of the upper block. NL >= 1.
88*> \endverbatim
89*>
90*> \param[in] NR
91*> \verbatim
92*> NR is INTEGER
93*> The row dimension of the lower block. NR >= 1.
94*> \endverbatim
95*>
96*> \param[in] SQRE
97*> \verbatim
98*> SQRE is INTEGER
99*> = 0: the lower block is an NR-by-NR square matrix.
100*> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
101*>
102*> The bidiagonal matrix has row dimension N = NL + NR + 1,
103*> and column dimension M = N + SQRE.
104*> \endverbatim
105*>
106*> \param[in] NRHS
107*> \verbatim
108*> NRHS is INTEGER
109*> The number of columns of B and BX. NRHS must be at least 1.
110*> \endverbatim
111*>
112*> \param[in,out] B
113*> \verbatim
114*> B is REAL array, dimension ( LDB, NRHS )
115*> On input, B contains the right hand sides of the least
116*> squares problem in rows 1 through M. On output, B contains
117*> the solution X in rows 1 through N.
118*> \endverbatim
119*>
120*> \param[in] LDB
121*> \verbatim
122*> LDB is INTEGER
123*> The leading dimension of B. LDB must be at least
124*> max(1,MAX( M, N ) ).
125*> \endverbatim
126*>
127*> \param[out] BX
128*> \verbatim
129*> BX is REAL array, dimension ( LDBX, NRHS )
130*> \endverbatim
131*>
132*> \param[in] LDBX
133*> \verbatim
134*> LDBX is INTEGER
135*> The leading dimension of BX.
136*> \endverbatim
137*>
138*> \param[in] PERM
139*> \verbatim
140*> PERM is INTEGER array, dimension ( N )
141*> The permutations (from deflation and sorting) applied
142*> to the two blocks.
143*> \endverbatim
144*>
145*> \param[in] GIVPTR
146*> \verbatim
147*> GIVPTR is INTEGER
148*> The number of Givens rotations which took place in this
149*> subproblem.
150*> \endverbatim
151*>
152*> \param[in] GIVCOL
153*> \verbatim
154*> GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )
155*> Each pair of numbers indicates a pair of rows/columns
156*> involved in a Givens rotation.
157*> \endverbatim
158*>
159*> \param[in] LDGCOL
160*> \verbatim
161*> LDGCOL is INTEGER
162*> The leading dimension of GIVCOL, must be at least N.
163*> \endverbatim
164*>
165*> \param[in] GIVNUM
166*> \verbatim
167*> GIVNUM is REAL array, dimension ( LDGNUM, 2 )
168*> Each number indicates the C or S value used in the
169*> corresponding Givens rotation.
170*> \endverbatim
171*>
172*> \param[in] LDGNUM
173*> \verbatim
174*> LDGNUM is INTEGER
175*> The leading dimension of arrays DIFR, POLES and
176*> GIVNUM, must be at least K.
177*> \endverbatim
178*>
179*> \param[in] POLES
180*> \verbatim
181*> POLES is REAL array, dimension ( LDGNUM, 2 )
182*> On entry, POLES(1:K, 1) contains the new singular
183*> values obtained from solving the secular equation, and
184*> POLES(1:K, 2) is an array containing the poles in the secular
185*> equation.
186*> \endverbatim
187*>
188*> \param[in] DIFL
189*> \verbatim
190*> DIFL is REAL array, dimension ( K ).
191*> On entry, DIFL(I) is the distance between I-th updated
192*> (undeflated) singular value and the I-th (undeflated) old
193*> singular value.
194*> \endverbatim
195*>
196*> \param[in] DIFR
197*> \verbatim
198*> DIFR is REAL array, dimension ( LDGNUM, 2 ).
199*> On entry, DIFR(I, 1) contains the distances between I-th
200*> updated (undeflated) singular value and the I+1-th
201*> (undeflated) old singular value. And DIFR(I, 2) is the
202*> normalizing factor for the I-th right singular vector.
203*> \endverbatim
204*>
205*> \param[in] Z
206*> \verbatim
207*> Z is REAL array, dimension ( K )
208*> Contain the components of the deflation-adjusted updating row
209*> vector.
210*> \endverbatim
211*>
212*> \param[in] K
213*> \verbatim
214*> K is INTEGER
215*> Contains the dimension of the non-deflated matrix,
216*> This is the order of the related secular equation. 1 <= K <=N.
217*> \endverbatim
218*>
219*> \param[in] C
220*> \verbatim
221*> C is REAL
222*> C contains garbage if SQRE =0 and the C-value of a Givens
223*> rotation related to the right null space if SQRE = 1.
224*> \endverbatim
225*>
226*> \param[in] S
227*> \verbatim
228*> S is REAL
229*> S contains garbage if SQRE =0 and the S-value of a Givens
230*> rotation related to the right null space if SQRE = 1.
231*> \endverbatim
232*>
233*> \param[out] WORK
234*> \verbatim
235*> WORK is REAL array, dimension ( K )
236*> \endverbatim
237*>
238*> \param[out] INFO
239*> \verbatim
240*> INFO is INTEGER
241*> = 0: successful exit.
242*> < 0: if INFO = -i, the i-th argument had an illegal value.
243*> \endverbatim
244*
245* Authors:
246* ========
247*
248*> \author Univ. of Tennessee
249*> \author Univ. of California Berkeley
250*> \author Univ. of Colorado Denver
251*> \author NAG Ltd.
252*
253*> \ingroup lals0
254*
255*> \par Contributors:
256* ==================
257*>
258*> Ming Gu and Ren-Cang Li, Computer Science Division, University of
259*> California at Berkeley, USA \n
260*> Osni Marques, LBNL/NERSC, USA \n
261*
262* =====================================================================
263 SUBROUTINE slals0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX,
264 $ LDBX,
265 $ PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,
266 $ POLES, DIFL, DIFR, Z, K, C, S, WORK, INFO )
267*
268* -- LAPACK computational routine --
269* -- LAPACK is a software package provided by Univ. of Tennessee, --
270* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
271*
272* .. Scalar Arguments ..
273 INTEGER GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,
274 $ LDGNUM, NL, NR, NRHS, SQRE
275 REAL C, S
276* ..
277* .. Array Arguments ..
278 INTEGER GIVCOL( LDGCOL, * ), PERM( * )
279 REAL B( LDB, * ), BX( LDBX, * ), DIFL( * ),
280 $ DIFR( LDGNUM, * ), GIVNUM( LDGNUM, * ),
281 $ poles( ldgnum, * ), work( * ), z( * )
282* ..
283*
284* =====================================================================
285*
286* .. Parameters ..
287 REAL ONE, ZERO, NEGONE
288 PARAMETER ( ONE = 1.0e0, zero = 0.0e0, negone = -1.0e0 )
289* ..
290* .. Local Scalars ..
291 INTEGER I, J, M, N, NLP1
292 REAL DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP
293* ..
294* .. External Subroutines ..
295 EXTERNAL scopy, sgemv, slacpy, slascl, srot,
296 $ sscal,
297 $ xerbla
298* ..
299* .. External Functions ..
300 REAL SLAMC3, SNRM2
301 EXTERNAL SLAMC3, SNRM2
302* ..
303* .. Intrinsic Functions ..
304 INTRINSIC max
305* ..
306* .. Executable Statements ..
307*
308* Test the input parameters.
309*
310 info = 0
311 n = nl + nr + 1
312*
313 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
314 info = -1
315 ELSE IF( nl.LT.1 ) THEN
316 info = -2
317 ELSE IF( nr.LT.1 ) THEN
318 info = -3
319 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
320 info = -4
321 ELSE IF( nrhs.LT.1 ) THEN
322 info = -5
323 ELSE IF( ldb.LT.n ) THEN
324 info = -7
325 ELSE IF( ldbx.LT.n ) THEN
326 info = -9
327 ELSE IF( givptr.LT.0 ) THEN
328 info = -11
329 ELSE IF( ldgcol.LT.n ) THEN
330 info = -13
331 ELSE IF( ldgnum.LT.n ) THEN
332 info = -15
333 ELSE IF( k.LT.1 ) THEN
334 info = -20
335 END IF
336 IF( info.NE.0 ) THEN
337 CALL xerbla( 'SLALS0', -info )
338 RETURN
339 END IF
340*
341 m = n + sqre
342 nlp1 = nl + 1
343*
344 IF( icompq.EQ.0 ) THEN
345*
346* Apply back orthogonal transformations from the left.
347*
348* Step (1L): apply back the Givens rotations performed.
349*
350 DO 10 i = 1, givptr
351 CALL srot( nrhs, b( givcol( i, 2 ), 1 ), ldb,
352 $ b( givcol( i, 1 ), 1 ), ldb, givnum( i, 2 ),
353 $ givnum( i, 1 ) )
354 10 CONTINUE
355*
356* Step (2L): permute rows of B.
357*
358 CALL scopy( nrhs, b( nlp1, 1 ), ldb, bx( 1, 1 ), ldbx )
359 DO 20 i = 2, n
360 CALL scopy( nrhs, b( perm( i ), 1 ), ldb, bx( i, 1 ),
361 $ ldbx )
362 20 CONTINUE
363*
364* Step (3L): apply the inverse of the left singular vector
365* matrix to BX.
366*
367 IF( k.EQ.1 ) THEN
368 CALL scopy( nrhs, bx, ldbx, b, ldb )
369 IF( z( 1 ).LT.zero ) THEN
370 CALL sscal( nrhs, negone, b, ldb )
371 END IF
372 ELSE
373 DO 50 j = 1, k
374 diflj = difl( j )
375 dj = poles( j, 1 )
376 dsigj = -poles( j, 2 )
377 IF( j.LT.k ) THEN
378 difrj = -difr( j, 1 )
379 dsigjp = -poles( j+1, 2 )
380 END IF
381 IF( ( z( j ).EQ.zero ) .OR. ( poles( j, 2 ).EQ.zero ) )
382 $ THEN
383 work( j ) = zero
384 ELSE
385 work( j ) = -poles( j, 2 )*z( j ) / diflj /
386 $ ( poles( j, 2 )+dj )
387 END IF
388 DO 30 i = 1, j - 1
389 IF( ( z( i ).EQ.zero ) .OR.
390 $ ( poles( i, 2 ).EQ.zero ) ) THEN
391 work( i ) = zero
392 ELSE
393*
394* Use calls to the subroutine SLAMC3 to enforce the
395* parentheses (x+y)+z. The goal is to prevent
396* optimizing compilers from doing x+(y+z).
397*
398 work( i ) = poles( i, 2 )*z( i ) /
399 $ ( slamc3( poles( i, 2 ), dsigj )-
400 $ diflj ) / ( poles( i, 2 )+dj )
401 END IF
402 30 CONTINUE
403 DO 40 i = j + 1, k
404 IF( ( z( i ).EQ.zero ) .OR.
405 $ ( poles( i, 2 ).EQ.zero ) ) THEN
406 work( i ) = zero
407 ELSE
408 work( i ) = poles( i, 2 )*z( i ) /
409 $ ( slamc3( poles( i, 2 ), dsigjp )+
410 $ difrj ) / ( poles( i, 2 )+dj )
411 END IF
412 40 CONTINUE
413 work( 1 ) = negone
414 temp = snrm2( k, work, 1 )
415 CALL sgemv( 'T', k, nrhs, one, bx, ldbx, work, 1,
416 $ zero,
417 $ b( j, 1 ), ldb )
418 CALL slascl( 'G', 0, 0, temp, one, 1, nrhs, b( j, 1 ),
419 $ ldb, info )
420 50 CONTINUE
421 END IF
422*
423* Move the deflated rows of BX to B also.
424*
425 IF( k.LT.max( m, n ) )
426 $ CALL slacpy( 'A', n-k, nrhs, bx( k+1, 1 ), ldbx,
427 $ b( k+1, 1 ), ldb )
428 ELSE
429*
430* Apply back the right orthogonal transformations.
431*
432* Step (1R): apply back the new right singular vector matrix
433* to B.
434*
435 IF( k.EQ.1 ) THEN
436 CALL scopy( nrhs, b, ldb, bx, ldbx )
437 ELSE
438 DO 80 j = 1, k
439 dsigj = poles( j, 2 )
440 IF( z( j ).EQ.zero ) THEN
441 work( j ) = zero
442 ELSE
443 work( j ) = -z( j ) / difl( j ) /
444 $ ( dsigj+poles( j, 1 ) ) / difr( j, 2 )
445 END IF
446 DO 60 i = 1, j - 1
447 IF( z( j ).EQ.zero ) THEN
448 work( i ) = zero
449 ELSE
450*
451* Use calls to the subroutine SLAMC3 to enforce the
452* parentheses (x+y)+z. The goal is to prevent
453* optimizing compilers from doing x+(y+z).
454*
455 work( i ) = z( j ) / ( slamc3( dsigj,
456 $ -poles( i+1,
457 $ 2 ) )-difr( i, 1 ) ) /
458 $ ( dsigj+poles( i, 1 ) ) / difr( i, 2 )
459 END IF
460 60 CONTINUE
461 DO 70 i = j + 1, k
462 IF( z( j ).EQ.zero ) THEN
463 work( i ) = zero
464 ELSE
465 work( i ) = z( j ) / ( slamc3( dsigj, -poles( i,
466 $ 2 ) )-difl( i ) ) /
467 $ ( dsigj+poles( i, 1 ) ) / difr( i, 2 )
468 END IF
469 70 CONTINUE
470 CALL sgemv( 'T', k, nrhs, one, b, ldb, work, 1, zero,
471 $ bx( j, 1 ), ldbx )
472 80 CONTINUE
473 END IF
474*
475* Step (2R): if SQRE = 1, apply back the rotation that is
476* related to the right null space of the subproblem.
477*
478 IF( sqre.EQ.1 ) THEN
479 CALL scopy( nrhs, b( m, 1 ), ldb, bx( m, 1 ), ldbx )
480 CALL srot( nrhs, bx( 1, 1 ), ldbx, bx( m, 1 ), ldbx, c,
481 $ s )
482 END IF
483 IF( k.LT.max( m, n ) )
484 $ CALL slacpy( 'A', n-k, nrhs, b( k+1, 1 ), ldb, bx( k+1,
485 $ 1 ),
486 $ ldbx )
487*
488* Step (3R): permute rows of B.
489*
490 CALL scopy( nrhs, bx( 1, 1 ), ldbx, b( nlp1, 1 ), ldb )
491 IF( sqre.EQ.1 ) THEN
492 CALL scopy( nrhs, bx( m, 1 ), ldbx, b( m, 1 ), ldb )
493 END IF
494 DO 90 i = 2, n
495 CALL scopy( nrhs, bx( i, 1 ), ldbx, b( perm( i ), 1 ),
496 $ ldb )
497 90 CONTINUE
498*
499* Step (4R): apply back the Givens rotations performed.
500*
501 DO 100 i = givptr, 1, -1
502 CALL srot( nrhs, b( givcol( i, 2 ), 1 ), ldb,
503 $ b( givcol( i, 1 ), 1 ), ldb, givnum( i, 2 ),
504 $ -givnum( i, 1 ) )
505 100 CONTINUE
506 END IF
507*
508 RETURN
509*
510* End of SLALS0
511*
512 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
Definition scopy.f:82
subroutine sgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
SGEMV
Definition sgemv.f:158
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
Definition slacpy.f:101
subroutine slals0(icompq, nl, nr, sqre, nrhs, b, ldb, bx, ldbx, perm, givptr, givcol, ldgcol, givnum, ldgnum, poles, difl, difr, z, k, c, s, work, info)
SLALS0 applies back multiplying factors in solving the least squares problem using divide and conquer...
Definition slals0.f:267
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition slascl.f:142
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT
Definition srot.f:92
subroutine sscal(n, sa, sx, incx)
SSCAL
Definition sscal.f:79