OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
slasd3.f
Go to the documentation of this file.
1*> \brief \b SLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and Z, and then updates the singular vectors by matrix multiplication. 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 SLASD3 + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slasd3.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slasd3.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slasd3.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE SLASD3( NL, NR, SQRE, K, D, Q, LDQ, DSIGMA, U, LDU, U2,
22* LDU2, VT, LDVT, VT2, LDVT2, IDXC, CTOT, Z,
23* INFO )
24*
25* .. Scalar Arguments ..
26* INTEGER INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,
27* $ SQRE
28* ..
29* .. Array Arguments ..
30* INTEGER CTOT( * ), IDXC( * )
31* REAL D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),
32* $ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
33* $ Z( * )
34* ..
35*
36*
37*> \par Purpose:
38* =============
39*>
40*> \verbatim
41*>
42*> SLASD3 finds all the square roots of the roots of the secular
43*> equation, as defined by the values in D and Z. It makes the
44*> appropriate calls to SLASD4 and then updates the singular
45*> vectors by matrix multiplication.
46*>
47*> This code makes very mild assumptions about floating point
48*> arithmetic. It will work on machines with a guard digit in
49*> add/subtract, or on those binary machines without guard digits
50*> which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
51*> It could conceivably fail on hexadecimal or decimal machines
52*> without guard digits, but we know of none.
53*>
54*> SLASD3 is called from SLASD1.
55*> \endverbatim
56*
57* Arguments:
58* ==========
59*
60*> \param[in] NL
61*> \verbatim
62*> NL is INTEGER
63*> The row dimension of the upper block. NL >= 1.
64*> \endverbatim
65*>
66*> \param[in] NR
67*> \verbatim
68*> NR is INTEGER
69*> The row dimension of the lower block. NR >= 1.
70*> \endverbatim
71*>
72*> \param[in] SQRE
73*> \verbatim
74*> SQRE is INTEGER
75*> = 0: the lower block is an NR-by-NR square matrix.
76*> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
77*>
78*> The bidiagonal matrix has N = NL + NR + 1 rows and
79*> M = N + SQRE >= N columns.
80*> \endverbatim
81*>
82*> \param[in] K
83*> \verbatim
84*> K is INTEGER
85*> The size of the secular equation, 1 =< K = < N.
86*> \endverbatim
87*>
88*> \param[out] D
89*> \verbatim
90*> D is REAL array, dimension(K)
91*> On exit the square roots of the roots of the secular equation,
92*> in ascending order.
93*> \endverbatim
94*>
95*> \param[out] Q
96*> \verbatim
97*> Q is REAL array, dimension (LDQ,K)
98*> \endverbatim
99*>
100*> \param[in] LDQ
101*> \verbatim
102*> LDQ is INTEGER
103*> The leading dimension of the array Q. LDQ >= K.
104*> \endverbatim
105*>
106*> \param[in,out] DSIGMA
107*> \verbatim
108*> DSIGMA is REAL array, dimension(K)
109*> The first K elements of this array contain the old roots
110*> of the deflated updating problem. These are the poles
111*> of the secular equation.
112*> \endverbatim
113*>
114*> \param[out] U
115*> \verbatim
116*> U is REAL array, dimension (LDU, N)
117*> The last N - K columns of this matrix contain the deflated
118*> left singular vectors.
119*> \endverbatim
120*>
121*> \param[in] LDU
122*> \verbatim
123*> LDU is INTEGER
124*> The leading dimension of the array U. LDU >= N.
125*> \endverbatim
126*>
127*> \param[in] U2
128*> \verbatim
129*> U2 is REAL array, dimension (LDU2, N)
130*> The first K columns of this matrix contain the non-deflated
131*> left singular vectors for the split problem.
132*> \endverbatim
133*>
134*> \param[in] LDU2
135*> \verbatim
136*> LDU2 is INTEGER
137*> The leading dimension of the array U2. LDU2 >= N.
138*> \endverbatim
139*>
140*> \param[out] VT
141*> \verbatim
142*> VT is REAL array, dimension (LDVT, M)
143*> The last M - K columns of VT**T contain the deflated
144*> right singular vectors.
145*> \endverbatim
146*>
147*> \param[in] LDVT
148*> \verbatim
149*> LDVT is INTEGER
150*> The leading dimension of the array VT. LDVT >= N.
151*> \endverbatim
152*>
153*> \param[in,out] VT2
154*> \verbatim
155*> VT2 is REAL array, dimension (LDVT2, N)
156*> The first K columns of VT2**T contain the non-deflated
157*> right singular vectors for the split problem.
158*> \endverbatim
159*>
160*> \param[in] LDVT2
161*> \verbatim
162*> LDVT2 is INTEGER
163*> The leading dimension of the array VT2. LDVT2 >= N.
164*> \endverbatim
165*>
166*> \param[in] IDXC
167*> \verbatim
168*> IDXC is INTEGER array, dimension (N)
169*> The permutation used to arrange the columns of U (and rows of
170*> VT) into three groups: the first group contains non-zero
171*> entries only at and above (or before) NL +1; the second
172*> contains non-zero entries only at and below (or after) NL+2;
173*> and the third is dense. The first column of U and the row of
174*> VT are treated separately, however.
175*>
176*> The rows of the singular vectors found by SLASD4
177*> must be likewise permuted before the matrix multiplies can
178*> take place.
179*> \endverbatim
180*>
181*> \param[in] CTOT
182*> \verbatim
183*> CTOT is INTEGER array, dimension (4)
184*> A count of the total number of the various types of columns
185*> in U (or rows in VT), as described in IDXC. The fourth column
186*> type is any column which has been deflated.
187*> \endverbatim
188*>
189*> \param[in,out] Z
190*> \verbatim
191*> Z is REAL array, dimension (K)
192*> The first K elements of this array contain the components
193*> of the deflation-adjusted updating row vector.
194*> \endverbatim
195*>
196*> \param[out] INFO
197*> \verbatim
198*> INFO is INTEGER
199*> = 0: successful exit.
200*> < 0: if INFO = -i, the i-th argument had an illegal value.
201*> > 0: if INFO = 1, a singular value did not converge
202*> \endverbatim
203*
204* Authors:
205* ========
206*
207*> \author Univ. of Tennessee
208*> \author Univ. of California Berkeley
209*> \author Univ. of Colorado Denver
210*> \author NAG Ltd.
211*
212*> \ingroup OTHERauxiliary
213*
214*> \par Contributors:
215* ==================
216*>
217*> Ming Gu and Huan Ren, Computer Science Division, University of
218*> California at Berkeley, USA
219*>
220* =====================================================================
221 SUBROUTINE slasd3( NL, NR, SQRE, K, D, Q, LDQ, DSIGMA, U, LDU, U2,
222 $ LDU2, VT, LDVT, VT2, LDVT2, IDXC, CTOT, Z,
223 $ INFO )
224*
225* -- LAPACK auxiliary routine --
226* -- LAPACK is a software package provided by Univ. of Tennessee, --
227* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
228*
229* .. Scalar Arguments ..
230 INTEGER INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,
231 $ SQRE
232* ..
233* .. Array Arguments ..
234 INTEGER CTOT( * ), IDXC( * )
235 REAL D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),
236 $ u2( ldu2, * ), vt( ldvt, * ), vt2( ldvt2, * ),
237 $ z( * )
238* ..
239*
240* =====================================================================
241*
242* .. Parameters ..
243 REAL ONE, ZERO, NEGONE
244 PARAMETER ( ONE = 1.0e+0, zero = 0.0e+0,
245 $ negone = -1.0e+0 )
246* ..
247* .. Local Scalars ..
248 INTEGER CTEMP, I, J, JC, KTEMP, M, N, NLP1, NLP2, NRP1
249 REAL RHO, TEMP
250* ..
251* .. External Functions ..
252 REAL SLAMC3, SNRM2
253 EXTERNAL SLAMC3, SNRM2
254* ..
255* .. External Subroutines ..
256 EXTERNAL scopy, sgemm, slacpy, slascl, slasd4, xerbla
257* ..
258* .. Intrinsic Functions ..
259 INTRINSIC abs, sign, sqrt
260* ..
261* .. Executable Statements ..
262*
263* Test the input parameters.
264*
265 info = 0
266*
267 IF( nl.LT.1 ) THEN
268 info = -1
269 ELSE IF( nr.LT.1 ) THEN
270 info = -2
271 ELSE IF( ( sqre.NE.1 ) .AND. ( sqre.NE.0 ) ) THEN
272 info = -3
273 END IF
274*
275 n = nl + nr + 1
276 m = n + sqre
277 nlp1 = nl + 1
278 nlp2 = nl + 2
279*
280 IF( ( k.LT.1 ) .OR. ( k.GT.n ) ) THEN
281 info = -4
282 ELSE IF( ldq.LT.k ) THEN
283 info = -7
284 ELSE IF( ldu.LT.n ) THEN
285 info = -10
286 ELSE IF( ldu2.LT.n ) THEN
287 info = -12
288 ELSE IF( ldvt.LT.m ) THEN
289 info = -14
290 ELSE IF( ldvt2.LT.m ) THEN
291 info = -16
292 END IF
293 IF( info.NE.0 ) THEN
294 CALL xerbla( 'SLASD3', -info )
295 RETURN
296 END IF
297*
298* Quick return if possible
299*
300 IF( k.EQ.1 ) THEN
301 d( 1 ) = abs( z( 1 ) )
302 CALL scopy( m, vt2( 1, 1 ), ldvt2, vt( 1, 1 ), ldvt )
303 IF( z( 1 ).GT.zero ) THEN
304 CALL scopy( n, u2( 1, 1 ), 1, u( 1, 1 ), 1 )
305 ELSE
306 DO 10 i = 1, n
307 u( i, 1 ) = -u2( i, 1 )
308 10 CONTINUE
309 END IF
310 RETURN
311 END IF
312*
313* Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
314* be computed with high relative accuracy (barring over/underflow).
315* This is a problem on machines without a guard digit in
316* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
317* The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
318* which on any of these machines zeros out the bottommost
319* bit of DSIGMA(I) if it is 1; this makes the subsequent
320* subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
321* occurs. On binary machines with a guard digit (almost all
322* machines) it does not change DSIGMA(I) at all. On hexadecimal
323* and decimal machines with a guard digit, it slightly
324* changes the bottommost bits of DSIGMA(I). It does not account
325* for hexadecimal or decimal machines without guard digits
326* (we know of none). We use a subroutine call to compute
327* 2*DSIGMA(I) to prevent optimizing compilers from eliminating
328* this code.
329*
330 DO 20 i = 1, k
331 dsigma( i ) = slamc3( dsigma( i ), dsigma( i ) ) - dsigma( i )
332 20 CONTINUE
333*
334* Keep a copy of Z.
335*
336 CALL scopy( k, z, 1, q, 1 )
337*
338* Normalize Z.
339*
340 rho = snrm2( k, z, 1 )
341 CALL slascl( 'g', 0, 0, RHO, ONE, K, 1, Z, K, INFO )
342 RHO = RHO*RHO
343*
344* Find the new singular values.
345*
346 DO 30 J = 1, K
347 CALL SLASD4( K, J, DSIGMA, Z, U( 1, J ), RHO, D( J ),
348 $ VT( 1, J ), INFO )
349*
350* If the zero finder fails, report the convergence failure.
351*
352.NE. IF( INFO0 ) THEN
353 RETURN
354 END IF
355 30 CONTINUE
356*
357* Compute updated Z.
358*
359 DO 60 I = 1, K
360 Z( I ) = U( I, K )*VT( I, K )
361 DO 40 J = 1, I - 1
362 Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /
363 $ ( DSIGMA( I )-DSIGMA( J ) ) /
364 $ ( DSIGMA( I )+DSIGMA( J ) ) )
365 40 CONTINUE
366 DO 50 J = I, K - 1
367 Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /
368 $ ( DSIGMA( I )-DSIGMA( J+1 ) ) /
369 $ ( DSIGMA( I )+DSIGMA( J+1 ) ) )
370 50 CONTINUE
371 Z( I ) = SIGN( SQRT( ABS( Z( I ) ) ), Q( I, 1 ) )
372 60 CONTINUE
373*
374* Compute left singular vectors of the modified diagonal matrix,
375* and store related information for the right singular vectors.
376*
377 DO 90 I = 1, K
378 VT( 1, I ) = Z( 1 ) / U( 1, I ) / VT( 1, I )
379 U( 1, I ) = NEGONE
380 DO 70 J = 2, K
381 VT( J, I ) = Z( J ) / U( J, I ) / VT( J, I )
382 U( J, I ) = DSIGMA( J )*VT( J, I )
383 70 CONTINUE
384 TEMP = SNRM2( K, U( 1, I ), 1 )
385 Q( 1, I ) = U( 1, I ) / TEMP
386 DO 80 J = 2, K
387 JC = IDXC( J )
388 Q( J, I ) = U( JC, I ) / TEMP
389 80 CONTINUE
390 90 CONTINUE
391*
392* Update the left singular vector matrix.
393*
394.EQ. IF( K2 ) THEN
395 CALL SGEMM( 'n', 'n', N, K, K, ONE, U2, LDU2, Q, LDQ, ZERO, U,
396 $ LDU )
397 GO TO 100
398 END IF
399.GT. IF( CTOT( 1 )0 ) THEN
400 CALL SGEMM( 'n', 'n', NL, K, CTOT( 1 ), ONE, U2( 1, 2 ), LDU2,
401 $ Q( 2, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )
402.GT. IF( CTOT( 3 )0 ) THEN
403 KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
404 CALL SGEMM( 'n', 'n', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),
405 $ LDU2, Q( KTEMP, 1 ), LDQ, ONE, U( 1, 1 ), LDU )
406 END IF
407.GT. ELSE IF( CTOT( 3 )0 ) THEN
408 KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
409 CALL SGEMM( 'n', 'n', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),
410 $ LDU2, Q( KTEMP, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )
411 ELSE
412 CALL SLACPY( 'f', NL, K, U2, LDU2, U, LDU )
413 END IF
414 CALL SCOPY( K, Q( 1, 1 ), LDQ, U( NLP1, 1 ), LDU )
415 KTEMP = 2 + CTOT( 1 )
416 CTEMP = CTOT( 2 ) + CTOT( 3 )
417 CALL SGEMM( 'n', 'n', NR, K, CTEMP, ONE, U2( NLP2, KTEMP ), LDU2,
418 $ Q( KTEMP, 1 ), LDQ, ZERO, U( NLP2, 1 ), LDU )
419*
420* Generate the right singular vectors.
421*
422 100 CONTINUE
423 DO 120 I = 1, K
424 TEMP = SNRM2( K, VT( 1, I ), 1 )
425 Q( I, 1 ) = VT( 1, I ) / TEMP
426 DO 110 J = 2, K
427 JC = IDXC( J )
428 Q( I, J ) = VT( JC, I ) / TEMP
429 110 CONTINUE
430 120 CONTINUE
431*
432* Update the right singular vector matrix.
433*
434.EQ. IF( K2 ) THEN
435 CALL SGEMM( 'n', 'n', K, M, K, ONE, Q, LDQ, VT2, LDVT2, ZERO,
436 $ VT, LDVT )
437 RETURN
438 END IF
439 KTEMP = 1 + CTOT( 1 )
440 CALL SGEMM( 'n', 'n', K, NLP1, KTEMP, ONE, Q( 1, 1 ), LDQ,
441 $ VT2( 1, 1 ), LDVT2, ZERO, VT( 1, 1 ), LDVT )
442 KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )
443.LE. IF( KTEMPLDVT2 )
444 $ CALL SGEMM( 'n', 'n', K, NLP1, CTOT( 3 ), ONE, Q( 1, KTEMP ),
445 $ LDQ, VT2( KTEMP, 1 ), LDVT2, ONE, VT( 1, 1 ),
446 $ LDVT )
447*
448 KTEMP = CTOT( 1 ) + 1
449 NRP1 = NR + SQRE
450.GT. IF( KTEMP1 ) THEN
451 DO 130 I = 1, K
452 Q( I, KTEMP ) = Q( I, 1 )
453 130 CONTINUE
454 DO 140 I = NLP2, M
455 VT2( KTEMP, I ) = VT2( 1, I )
456 140 CONTINUE
457 END IF
458 CTEMP = 1 + CTOT( 2 ) + CTOT( 3 )
459 CALL SGEMM( 'n', 'n', K, NRP1, CTEMP, ONE, Q( 1, KTEMP ), LDQ,
460 $ VT2( KTEMP, NLP2 ), LDVT2, ZERO, VT( 1, NLP2 ), LDVT )
461*
462 RETURN
463*
464* End of SLASD3
465*
466 END
subroutine slasd4(n, i, d, z, delta, rho, sigma, work, info)
SLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modif...
Definition slasd4.f:153
subroutine slasd3(nl, nr, sqre, k, d, q, ldq, dsigma, u, ldu, u2, ldu2, vt, ldvt, vt2, ldvt2, idxc, ctot, z, info)
SLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and...
Definition slasd3.f:224
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
Definition slacpy.f:103
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:143
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
Definition scopy.f:82
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
Definition sgemm.f:187