LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dbbcsd.f
Go to the documentation of this file.
1*> \brief \b DBBCSD
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DBBCSD + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dbbcsd.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dbbcsd.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dbbcsd.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q,
20* THETA, PHI, U1, LDU1, U2, LDU2, V1T, LDV1T,
21* V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,
22* B22D, B22E, WORK, LWORK, INFO )
23*
24* .. Scalar Arguments ..
25* CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS
26* INTEGER INFO, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q
27* ..
28* .. Array Arguments ..
29* DOUBLE PRECISION B11D( * ), B11E( * ), B12D( * ), B12E( * ),
30* $ B21D( * ), B21E( * ), B22D( * ), B22E( * ),
31* $ PHI( * ), THETA( * ), WORK( * )
32* DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
33* $ V2T( LDV2T, * )
34* ..
35*
36*
37*> \par Purpose:
38* =============
39*>
40*> \verbatim
41*>
42*> DBBCSD computes the CS decomposition of an orthogonal matrix in
43*> bidiagonal-block form,
44*>
45*>
46*> [ B11 | B12 0 0 ]
47*> [ 0 | 0 -I 0 ]
48*> X = [----------------]
49*> [ B21 | B22 0 0 ]
50*> [ 0 | 0 0 I ]
51*>
52*> [ C | -S 0 0 ]
53*> [ U1 | ] [ 0 | 0 -I 0 ] [ V1 | ]**T
54*> = [---------] [---------------] [---------] .
55*> [ | U2 ] [ S | C 0 0 ] [ | V2 ]
56*> [ 0 | 0 0 I ]
57*>
58*> X is M-by-M, its top-left block is P-by-Q, and Q must be no larger
59*> than P, M-P, or M-Q. (If Q is not the smallest index, then X must be
60*> transposed and/or permuted. This can be done in constant time using
61*> the TRANS and SIGNS options. See DORCSD for details.)
62*>
63*> The bidiagonal matrices B11, B12, B21, and B22 are represented
64*> implicitly by angles THETA(1:Q) and PHI(1:Q-1).
65*>
66*> The orthogonal matrices U1, U2, V1T, and V2T are input/output.
67*> The input matrices are pre- or post-multiplied by the appropriate
68*> singular vector matrices.
69*> \endverbatim
70*
71* Arguments:
72* ==========
73*
74*> \param[in] JOBU1
75*> \verbatim
76*> JOBU1 is CHARACTER
77*> = 'Y': U1 is updated;
78*> otherwise: U1 is not updated.
79*> \endverbatim
80*>
81*> \param[in] JOBU2
82*> \verbatim
83*> JOBU2 is CHARACTER
84*> = 'Y': U2 is updated;
85*> otherwise: U2 is not updated.
86*> \endverbatim
87*>
88*> \param[in] JOBV1T
89*> \verbatim
90*> JOBV1T is CHARACTER
91*> = 'Y': V1T is updated;
92*> otherwise: V1T is not updated.
93*> \endverbatim
94*>
95*> \param[in] JOBV2T
96*> \verbatim
97*> JOBV2T is CHARACTER
98*> = 'Y': V2T is updated;
99*> otherwise: V2T is not updated.
100*> \endverbatim
101*>
102*> \param[in] TRANS
103*> \verbatim
104*> TRANS is CHARACTER
105*> = 'T': X, U1, U2, V1T, and V2T are stored in row-major
106*> order;
107*> otherwise: X, U1, U2, V1T, and V2T are stored in column-
108*> major order.
109*> \endverbatim
110*>
111*> \param[in] M
112*> \verbatim
113*> M is INTEGER
114*> The number of rows and columns in X, the orthogonal matrix in
115*> bidiagonal-block form.
116*> \endverbatim
117*>
118*> \param[in] P
119*> \verbatim
120*> P is INTEGER
121*> The number of rows in the top-left block of X. 0 <= P <= M.
122*> \endverbatim
123*>
124*> \param[in] Q
125*> \verbatim
126*> Q is INTEGER
127*> The number of columns in the top-left block of X.
128*> 0 <= Q <= MIN(P,M-P,M-Q).
129*> \endverbatim
130*>
131*> \param[in,out] THETA
132*> \verbatim
133*> THETA is DOUBLE PRECISION array, dimension (Q)
134*> On entry, the angles THETA(1),...,THETA(Q) that, along with
135*> PHI(1), ...,PHI(Q-1), define the matrix in bidiagonal-block
136*> form. On exit, the angles whose cosines and sines define the
137*> diagonal blocks in the CS decomposition.
138*> \endverbatim
139*>
140*> \param[in,out] PHI
141*> \verbatim
142*> PHI is DOUBLE PRECISION array, dimension (Q-1)
143*> The angles PHI(1),...,PHI(Q-1) that, along with THETA(1),...,
144*> THETA(Q), define the matrix in bidiagonal-block form.
145*> \endverbatim
146*>
147*> \param[in,out] U1
148*> \verbatim
149*> U1 is DOUBLE PRECISION array, dimension (LDU1,P)
150*> On entry, a P-by-P matrix. On exit, U1 is postmultiplied
151*> by the left singular vector matrix common to [ B11 ; 0 ] and
152*> [ B12 0 0 ; 0 -I 0 0 ].
153*> \endverbatim
154*>
155*> \param[in] LDU1
156*> \verbatim
157*> LDU1 is INTEGER
158*> The leading dimension of the array U1, LDU1 >= MAX(1,P).
159*> \endverbatim
160*>
161*> \param[in,out] U2
162*> \verbatim
163*> U2 is DOUBLE PRECISION array, dimension (LDU2,M-P)
164*> On entry, an (M-P)-by-(M-P) matrix. On exit, U2 is
165*> postmultiplied by the left singular vector matrix common to
166*> [ B21 ; 0 ] and [ B22 0 0 ; 0 0 I ].
167*> \endverbatim
168*>
169*> \param[in] LDU2
170*> \verbatim
171*> LDU2 is INTEGER
172*> The leading dimension of the array U2, LDU2 >= MAX(1,M-P).
173*> \endverbatim
174*>
175*> \param[in,out] V1T
176*> \verbatim
177*> V1T is DOUBLE PRECISION array, dimension (LDV1T,Q)
178*> On entry, a Q-by-Q matrix. On exit, V1T is premultiplied
179*> by the transpose of the right singular vector
180*> matrix common to [ B11 ; 0 ] and [ B21 ; 0 ].
181*> \endverbatim
182*>
183*> \param[in] LDV1T
184*> \verbatim
185*> LDV1T is INTEGER
186*> The leading dimension of the array V1T, LDV1T >= MAX(1,Q).
187*> \endverbatim
188*>
189*> \param[in,out] V2T
190*> \verbatim
191*> V2T is DOUBLE PRECISION array, dimension (LDV2T,M-Q)
192*> On entry, an (M-Q)-by-(M-Q) matrix. On exit, V2T is
193*> premultiplied by the transpose of the right
194*> singular vector matrix common to [ B12 0 0 ; 0 -I 0 ] and
195*> [ B22 0 0 ; 0 0 I ].
196*> \endverbatim
197*>
198*> \param[in] LDV2T
199*> \verbatim
200*> LDV2T is INTEGER
201*> The leading dimension of the array V2T, LDV2T >= MAX(1,M-Q).
202*> \endverbatim
203*>
204*> \param[out] B11D
205*> \verbatim
206*> B11D is DOUBLE PRECISION array, dimension (Q)
207*> When DBBCSD converges, B11D contains the cosines of THETA(1),
208*> ..., THETA(Q). If DBBCSD fails to converge, then B11D
209*> contains the diagonal of the partially reduced top-left
210*> block.
211*> \endverbatim
212*>
213*> \param[out] B11E
214*> \verbatim
215*> B11E is DOUBLE PRECISION array, dimension (Q-1)
216*> When DBBCSD converges, B11E contains zeros. If DBBCSD fails
217*> to converge, then B11E contains the superdiagonal of the
218*> partially reduced top-left block.
219*> \endverbatim
220*>
221*> \param[out] B12D
222*> \verbatim
223*> B12D is DOUBLE PRECISION array, dimension (Q)
224*> When DBBCSD converges, B12D contains the negative sines of
225*> THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then
226*> B12D contains the diagonal of the partially reduced top-right
227*> block.
228*> \endverbatim
229*>
230*> \param[out] B12E
231*> \verbatim
232*> B12E is DOUBLE PRECISION array, dimension (Q-1)
233*> When DBBCSD converges, B12E contains zeros. If DBBCSD fails
234*> to converge, then B12E contains the subdiagonal of the
235*> partially reduced top-right block.
236*> \endverbatim
237*>
238*> \param[out] B21D
239*> \verbatim
240*> B21D is DOUBLE PRECISION array, dimension (Q)
241*> When DBBCSD converges, B21D contains the negative sines of
242*> THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then
243*> B21D contains the diagonal of the partially reduced bottom-left
244*> block.
245*> \endverbatim
246*>
247*> \param[out] B21E
248*> \verbatim
249*> B21E is DOUBLE PRECISION array, dimension (Q-1)
250*> When DBBCSD converges, B21E contains zeros. If DBBCSD fails
251*> to converge, then B21E contains the subdiagonal of the
252*> partially reduced bottom-left block.
253*> \endverbatim
254*>
255*> \param[out] B22D
256*> \verbatim
257*> B22D is DOUBLE PRECISION array, dimension (Q)
258*> When DBBCSD converges, B22D contains the negative sines of
259*> THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then
260*> B22D contains the diagonal of the partially reduced bottom-right
261*> block.
262*> \endverbatim
263*>
264*> \param[out] B22E
265*> \verbatim
266*> B22E is DOUBLE PRECISION array, dimension (Q-1)
267*> When DBBCSD converges, B22E contains zeros. If DBBCSD fails
268*> to converge, then B22E contains the subdiagonal of the
269*> partially reduced bottom-right block.
270*> \endverbatim
271*>
272*> \param[out] WORK
273*> \verbatim
274*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
275*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
276*> \endverbatim
277*>
278*> \param[in] LWORK
279*> \verbatim
280*> LWORK is INTEGER
281*> The dimension of the array WORK. LWORK >= MAX(1,8*Q).
282*>
283*> If LWORK = -1, then a workspace query is assumed; the
284*> routine only calculates the optimal size of the WORK array,
285*> returns this value as the first entry of the work array, and
286*> no error message related to LWORK is issued by XERBLA.
287*> \endverbatim
288*>
289*> \param[out] INFO
290*> \verbatim
291*> INFO is INTEGER
292*> = 0: successful exit.
293*> < 0: if INFO = -i, the i-th argument had an illegal value.
294*> > 0: if DBBCSD did not converge, INFO specifies the number
295*> of nonzero entries in PHI, and B11D, B11E, etc.,
296*> contain the partially reduced matrix.
297*> \endverbatim
298*
299*> \par Internal Parameters:
300* =========================
301*>
302*> \verbatim
303*> TOLMUL DOUBLE PRECISION, default = MAX(10,MIN(100,EPS**(-1/8)))
304*> TOLMUL controls the convergence criterion of the QR loop.
305*> Angles THETA(i), PHI(i) are rounded to 0 or PI/2 when they
306*> are within TOLMUL*EPS of either bound.
307*> \endverbatim
308*
309*> \par References:
310* ================
311*>
312*> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.
313*> Algorithms, 50(1):33-65, 2009.
314*
315* Authors:
316* ========
317*
318*> \author Univ. of Tennessee
319*> \author Univ. of California Berkeley
320*> \author Univ. of Colorado Denver
321*> \author NAG Ltd.
322*
323*> \ingroup bbcsd
324*
325* =====================================================================
326 SUBROUTINE dbbcsd( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P,
327 $ Q,
328 $ THETA, PHI, U1, LDU1, U2, LDU2, V1T, LDV1T,
329 $ V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,
330 $ B22D, B22E, WORK, LWORK, INFO )
331*
332* -- LAPACK computational routine --
333* -- LAPACK is a software package provided by Univ. of Tennessee, --
334* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
335*
336* .. Scalar Arguments ..
337 CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS
338 INTEGER INFO, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q
339* ..
340* .. Array Arguments ..
341 DOUBLE PRECISION B11D( * ), B11E( * ), B12D( * ), B12E( * ),
342 $ b21d( * ), b21e( * ), b22d( * ), b22e( * ),
343 $ phi( * ), theta( * ), work( * )
344 DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
345 $ v2t( ldv2t, * )
346* ..
347*
348* ===================================================================
349*
350* .. Parameters ..
351 INTEGER MAXITR
352 PARAMETER ( MAXITR = 6 )
353 double precision hundred, meighth, one, ten, zero
354 parameter( hundred = 100.0d0, meighth = -0.125d0,
355 $ one = 1.0d0, ten = 10.0d0, zero = 0.0d0 )
356 DOUBLE PRECISION NEGONE
357 parameter( negone = -1.0d0 )
358 DOUBLE PRECISION PIOVER2
359 PARAMETER ( PIOVER2 = 1.57079632679489661923132169163975144210d0 )
360* ..
361* .. Local Scalars ..
362 LOGICAL COLMAJOR, LQUERY, RESTART11, RESTART12,
363 $ restart21, restart22, wantu1, wantu2, wantv1t,
364 $ wantv2t
365 INTEGER I, IMIN, IMAX, ITER, IU1CS, IU1SN, IU2CS,
366 $ iu2sn, iv1tcs, iv1tsn, iv2tcs, iv2tsn, j,
367 $ lworkmin, lworkopt, maxit, mini
368 DOUBLE PRECISION B11BULGE, B12BULGE, B21BULGE, B22BULGE, DUMMY,
369 $ eps, mu, nu, r, sigma11, sigma21,
370 $ temp, thetamax, thetamin, thresh, tol, tolmul,
371 $ unfl, x1, x2, y1, y2
372*
373* .. External Subroutines ..
374 EXTERNAL dlasr, dscal, dswap, dlartgp, dlartgs,
375 $ dlas2,
376 $ xerbla
377* ..
378* .. External Functions ..
379 DOUBLE PRECISION DLAMCH
380 LOGICAL LSAME
381 EXTERNAL LSAME, DLAMCH
382* ..
383* .. Intrinsic Functions ..
384 INTRINSIC abs, atan2, cos, max, min, sin, sqrt
385* ..
386* .. Executable Statements ..
387*
388* Test input arguments
389*
390 info = 0
391 lquery = lwork .EQ. -1
392 wantu1 = lsame( jobu1, 'Y' )
393 wantu2 = lsame( jobu2, 'Y' )
394 wantv1t = lsame( jobv1t, 'Y' )
395 wantv2t = lsame( jobv2t, 'Y' )
396 colmajor = .NOT. lsame( trans, 'T' )
397*
398 IF( m .LT. 0 ) THEN
399 info = -6
400 ELSE IF( p .LT. 0 .OR. p .GT. m ) THEN
401 info = -7
402 ELSE IF( q .LT. 0 .OR. q .GT. m ) THEN
403 info = -8
404 ELSE IF( q .GT. p .OR. q .GT. m-p .OR. q .GT. m-q ) THEN
405 info = -8
406 ELSE IF( wantu1 .AND. ldu1 .LT. p ) THEN
407 info = -12
408 ELSE IF( wantu2 .AND. ldu2 .LT. m-p ) THEN
409 info = -14
410 ELSE IF( wantv1t .AND. ldv1t .LT. q ) THEN
411 info = -16
412 ELSE IF( wantv2t .AND. ldv2t .LT. m-q ) THEN
413 info = -18
414 END IF
415*
416* Quick return if Q = 0
417*
418 IF( info .EQ. 0 .AND. q .EQ. 0 ) THEN
419 lworkmin = 1
420 work(1) = lworkmin
421 RETURN
422 END IF
423*
424* Compute workspace
425*
426 IF( info .EQ. 0 ) THEN
427 iu1cs = 1
428 iu1sn = iu1cs + q
429 iu2cs = iu1sn + q
430 iu2sn = iu2cs + q
431 iv1tcs = iu2sn + q
432 iv1tsn = iv1tcs + q
433 iv2tcs = iv1tsn + q
434 iv2tsn = iv2tcs + q
435 lworkopt = iv2tsn + q - 1
436 lworkmin = lworkopt
437 work(1) = lworkopt
438 IF( lwork .LT. lworkmin .AND. .NOT. lquery ) THEN
439 info = -28
440 END IF
441 END IF
442*
443 IF( info .NE. 0 ) THEN
444 CALL xerbla( 'DBBCSD', -info )
445 RETURN
446 ELSE IF( lquery ) THEN
447 RETURN
448 END IF
449*
450* Get machine constants
451*
452 eps = dlamch( 'Epsilon' )
453 unfl = dlamch( 'Safe minimum' )
454 tolmul = max( ten, min( hundred, eps**meighth ) )
455 tol = tolmul*eps
456 thresh = max( tol, maxitr*q*q*unfl )
457*
458* Test for negligible sines or cosines
459*
460 DO i = 1, q
461 IF( theta(i) .LT. thresh ) THEN
462 theta(i) = zero
463 ELSE IF( theta(i) .GT. piover2-thresh ) THEN
464 theta(i) = piover2
465 END IF
466 END DO
467 DO i = 1, q-1
468 IF( phi(i) .LT. thresh ) THEN
469 phi(i) = zero
470 ELSE IF( phi(i) .GT. piover2-thresh ) THEN
471 phi(i) = piover2
472 END IF
473 END DO
474*
475* Initial deflation
476*
477 imax = q
478 DO WHILE( imax .GT. 1 )
479 IF( phi(imax-1) .NE. zero ) THEN
480 EXIT
481 END IF
482 imax = imax - 1
483 END DO
484 imin = imax - 1
485 IF ( imin .GT. 1 ) THEN
486 DO WHILE( phi(imin-1) .NE. zero )
487 imin = imin - 1
488 IF ( imin .LE. 1 ) EXIT
489 END DO
490 END IF
491*
492* Initialize iteration counter
493*
494 maxit = maxitr*q*q
495 iter = 0
496*
497* Begin main iteration loop
498*
499 DO WHILE( imax .GT. 1 )
500*
501* Compute the matrix entries
502*
503 b11d(imin) = cos( theta(imin) )
504 b21d(imin) = -sin( theta(imin) )
505 DO i = imin, imax - 1
506 b11e(i) = -sin( theta(i) ) * sin( phi(i) )
507 b11d(i+1) = cos( theta(i+1) ) * cos( phi(i) )
508 b12d(i) = sin( theta(i) ) * cos( phi(i) )
509 b12e(i) = cos( theta(i+1) ) * sin( phi(i) )
510 b21e(i) = -cos( theta(i) ) * sin( phi(i) )
511 b21d(i+1) = -sin( theta(i+1) ) * cos( phi(i) )
512 b22d(i) = cos( theta(i) ) * cos( phi(i) )
513 b22e(i) = -sin( theta(i+1) ) * sin( phi(i) )
514 END DO
515 b12d(imax) = sin( theta(imax) )
516 b22d(imax) = cos( theta(imax) )
517*
518* Abort if not converging; otherwise, increment ITER
519*
520 IF( iter .GT. maxit ) THEN
521 info = 0
522 DO i = 1, q
523 IF( phi(i) .NE. zero )
524 $ info = info + 1
525 END DO
526 RETURN
527 END IF
528*
529 iter = iter + imax - imin
530*
531* Compute shifts
532*
533 thetamax = theta(imin)
534 thetamin = theta(imin)
535 DO i = imin+1, imax
536 IF( theta(i) > thetamax )
537 $ thetamax = theta(i)
538 IF( theta(i) < thetamin )
539 $ thetamin = theta(i)
540 END DO
541*
542 IF( thetamax .GT. piover2 - thresh ) THEN
543*
544* Zero on diagonals of B11 and B22; induce deflation with a
545* zero shift
546*
547 mu = zero
548 nu = one
549*
550 ELSE IF( thetamin .LT. thresh ) THEN
551*
552* Zero on diagonals of B12 and B22; induce deflation with a
553* zero shift
554*
555 mu = one
556 nu = zero
557*
558 ELSE
559*
560* Compute shifts for B11 and B21 and use the lesser
561*
562 CALL dlas2( b11d(imax-1), b11e(imax-1), b11d(imax),
563 $ sigma11,
564 $ dummy )
565 CALL dlas2( b21d(imax-1), b21e(imax-1), b21d(imax),
566 $ sigma21,
567 $ dummy )
568*
569 IF( sigma11 .LE. sigma21 ) THEN
570 mu = sigma11
571 nu = sqrt( one - mu**2 )
572 IF( mu .LT. thresh ) THEN
573 mu = zero
574 nu = one
575 END IF
576 ELSE
577 nu = sigma21
578 mu = sqrt( 1.0 - nu**2 )
579 IF( nu .LT. thresh ) THEN
580 mu = one
581 nu = zero
582 END IF
583 END IF
584 END IF
585*
586* Rotate to produce bulges in B11 and B21
587*
588 IF( mu .LE. nu ) THEN
589 CALL dlartgs( b11d(imin), b11e(imin), mu,
590 $ work(iv1tcs+imin-1), work(iv1tsn+imin-1) )
591 ELSE
592 CALL dlartgs( b21d(imin), b21e(imin), nu,
593 $ work(iv1tcs+imin-1), work(iv1tsn+imin-1) )
594 END IF
595*
596 temp = work(iv1tcs+imin-1)*b11d(imin) +
597 $ work(iv1tsn+imin-1)*b11e(imin)
598 b11e(imin) = work(iv1tcs+imin-1)*b11e(imin) -
599 $ work(iv1tsn+imin-1)*b11d(imin)
600 b11d(imin) = temp
601 b11bulge = work(iv1tsn+imin-1)*b11d(imin+1)
602 b11d(imin+1) = work(iv1tcs+imin-1)*b11d(imin+1)
603 temp = work(iv1tcs+imin-1)*b21d(imin) +
604 $ work(iv1tsn+imin-1)*b21e(imin)
605 b21e(imin) = work(iv1tcs+imin-1)*b21e(imin) -
606 $ work(iv1tsn+imin-1)*b21d(imin)
607 b21d(imin) = temp
608 b21bulge = work(iv1tsn+imin-1)*b21d(imin+1)
609 b21d(imin+1) = work(iv1tcs+imin-1)*b21d(imin+1)
610*
611* Compute THETA(IMIN)
612*
613 theta( imin ) = atan2( sqrt( b21d(imin)**2+b21bulge**2 ),
614 $ sqrt( b11d(imin)**2+b11bulge**2 ) )
615*
616* Chase the bulges in B11(IMIN+1,IMIN) and B21(IMIN+1,IMIN)
617*
618 IF( b11d(imin)**2+b11bulge**2 .GT. thresh**2 ) THEN
619 CALL dlartgp( b11bulge, b11d(imin), work(iu1sn+imin-1),
620 $ work(iu1cs+imin-1), r )
621 ELSE IF( mu .LE. nu ) THEN
622 CALL dlartgs( b11e( imin ), b11d( imin + 1 ), mu,
623 $ work(iu1cs+imin-1), work(iu1sn+imin-1) )
624 ELSE
625 CALL dlartgs( b12d( imin ), b12e( imin ), nu,
626 $ work(iu1cs+imin-1), work(iu1sn+imin-1) )
627 END IF
628 IF( b21d(imin)**2+b21bulge**2 .GT. thresh**2 ) THEN
629 CALL dlartgp( b21bulge, b21d(imin), work(iu2sn+imin-1),
630 $ work(iu2cs+imin-1), r )
631 ELSE IF( nu .LT. mu ) THEN
632 CALL dlartgs( b21e( imin ), b21d( imin + 1 ), nu,
633 $ work(iu2cs+imin-1), work(iu2sn+imin-1) )
634 ELSE
635 CALL dlartgs( b22d(imin), b22e(imin), mu,
636 $ work(iu2cs+imin-1), work(iu2sn+imin-1) )
637 END IF
638 work(iu2cs+imin-1) = -work(iu2cs+imin-1)
639 work(iu2sn+imin-1) = -work(iu2sn+imin-1)
640*
641 temp = work(iu1cs+imin-1)*b11e(imin) +
642 $ work(iu1sn+imin-1)*b11d(imin+1)
643 b11d(imin+1) = work(iu1cs+imin-1)*b11d(imin+1) -
644 $ work(iu1sn+imin-1)*b11e(imin)
645 b11e(imin) = temp
646 IF( imax .GT. imin+1 ) THEN
647 b11bulge = work(iu1sn+imin-1)*b11e(imin+1)
648 b11e(imin+1) = work(iu1cs+imin-1)*b11e(imin+1)
649 END IF
650 temp = work(iu1cs+imin-1)*b12d(imin) +
651 $ work(iu1sn+imin-1)*b12e(imin)
652 b12e(imin) = work(iu1cs+imin-1)*b12e(imin) -
653 $ work(iu1sn+imin-1)*b12d(imin)
654 b12d(imin) = temp
655 b12bulge = work(iu1sn+imin-1)*b12d(imin+1)
656 b12d(imin+1) = work(iu1cs+imin-1)*b12d(imin+1)
657 temp = work(iu2cs+imin-1)*b21e(imin) +
658 $ work(iu2sn+imin-1)*b21d(imin+1)
659 b21d(imin+1) = work(iu2cs+imin-1)*b21d(imin+1) -
660 $ work(iu2sn+imin-1)*b21e(imin)
661 b21e(imin) = temp
662 IF( imax .GT. imin+1 ) THEN
663 b21bulge = work(iu2sn+imin-1)*b21e(imin+1)
664 b21e(imin+1) = work(iu2cs+imin-1)*b21e(imin+1)
665 END IF
666 temp = work(iu2cs+imin-1)*b22d(imin) +
667 $ work(iu2sn+imin-1)*b22e(imin)
668 b22e(imin) = work(iu2cs+imin-1)*b22e(imin) -
669 $ work(iu2sn+imin-1)*b22d(imin)
670 b22d(imin) = temp
671 b22bulge = work(iu2sn+imin-1)*b22d(imin+1)
672 b22d(imin+1) = work(iu2cs+imin-1)*b22d(imin+1)
673*
674* Inner loop: chase bulges from B11(IMIN,IMIN+2),
675* B12(IMIN,IMIN+1), B21(IMIN,IMIN+2), and B22(IMIN,IMIN+1) to
676* bottom-right
677*
678 DO i = imin+1, imax-1
679*
680* Compute PHI(I-1)
681*
682 x1 = sin(theta(i-1))*b11e(i-1) + cos(theta(i-1))*b21e(i-1)
683 x2 = sin(theta(i-1))*b11bulge + cos(theta(i-1))*b21bulge
684 y1 = sin(theta(i-1))*b12d(i-1) + cos(theta(i-1))*b22d(i-1)
685 y2 = sin(theta(i-1))*b12bulge + cos(theta(i-1))*b22bulge
686*
687 phi(i-1) = atan2( sqrt(x1**2+x2**2), sqrt(y1**2+y2**2) )
688*
689* Determine if there are bulges to chase or if a new direct
690* summand has been reached
691*
692 restart11 = b11e(i-1)**2 + b11bulge**2 .LE. thresh**2
693 restart21 = b21e(i-1)**2 + b21bulge**2 .LE. thresh**2
694 restart12 = b12d(i-1)**2 + b12bulge**2 .LE. thresh**2
695 restart22 = b22d(i-1)**2 + b22bulge**2 .LE. thresh**2
696*
697* If possible, chase bulges from B11(I-1,I+1), B12(I-1,I),
698* B21(I-1,I+1), and B22(I-1,I). If necessary, restart bulge-
699* chasing by applying the original shift again.
700*
701 IF( .NOT. restart11 .AND. .NOT. restart21 ) THEN
702 CALL dlartgp( x2, x1, work(iv1tsn+i-1),
703 $ work(iv1tcs+i-1),
704 $ r )
705 ELSE IF( .NOT. restart11 .AND. restart21 ) THEN
706 CALL dlartgp( b11bulge, b11e(i-1), work(iv1tsn+i-1),
707 $ work(iv1tcs+i-1), r )
708 ELSE IF( restart11 .AND. .NOT. restart21 ) THEN
709 CALL dlartgp( b21bulge, b21e(i-1), work(iv1tsn+i-1),
710 $ work(iv1tcs+i-1), r )
711 ELSE IF( mu .LE. nu ) THEN
712 CALL dlartgs( b11d(i), b11e(i), mu, work(iv1tcs+i-1),
713 $ work(iv1tsn+i-1) )
714 ELSE
715 CALL dlartgs( b21d(i), b21e(i), nu, work(iv1tcs+i-1),
716 $ work(iv1tsn+i-1) )
717 END IF
718 work(iv1tcs+i-1) = -work(iv1tcs+i-1)
719 work(iv1tsn+i-1) = -work(iv1tsn+i-1)
720 IF( .NOT. restart12 .AND. .NOT. restart22 ) THEN
721 CALL dlartgp( y2, y1, work(iv2tsn+i-1-1),
722 $ work(iv2tcs+i-1-1), r )
723 ELSE IF( .NOT. restart12 .AND. restart22 ) THEN
724 CALL dlartgp( b12bulge, b12d(i-1), work(iv2tsn+i-1-1),
725 $ work(iv2tcs+i-1-1), r )
726 ELSE IF( restart12 .AND. .NOT. restart22 ) THEN
727 CALL dlartgp( b22bulge, b22d(i-1), work(iv2tsn+i-1-1),
728 $ work(iv2tcs+i-1-1), r )
729 ELSE IF( nu .LT. mu ) THEN
730 CALL dlartgs( b12e(i-1), b12d(i), nu,
731 $ work(iv2tcs+i-1-1),
732 $ work(iv2tsn+i-1-1) )
733 ELSE
734 CALL dlartgs( b22e(i-1), b22d(i), mu,
735 $ work(iv2tcs+i-1-1),
736 $ work(iv2tsn+i-1-1) )
737 END IF
738*
739 temp = work(iv1tcs+i-1)*b11d(i) + work(iv1tsn+i-1)*b11e(i)
740 b11e(i) = work(iv1tcs+i-1)*b11e(i) -
741 $ work(iv1tsn+i-1)*b11d(i)
742 b11d(i) = temp
743 b11bulge = work(iv1tsn+i-1)*b11d(i+1)
744 b11d(i+1) = work(iv1tcs+i-1)*b11d(i+1)
745 temp = work(iv1tcs+i-1)*b21d(i) + work(iv1tsn+i-1)*b21e(i)
746 b21e(i) = work(iv1tcs+i-1)*b21e(i) -
747 $ work(iv1tsn+i-1)*b21d(i)
748 b21d(i) = temp
749 b21bulge = work(iv1tsn+i-1)*b21d(i+1)
750 b21d(i+1) = work(iv1tcs+i-1)*b21d(i+1)
751 temp = work(iv2tcs+i-1-1)*b12e(i-1) +
752 $ work(iv2tsn+i-1-1)*b12d(i)
753 b12d(i) = work(iv2tcs+i-1-1)*b12d(i) -
754 $ work(iv2tsn+i-1-1)*b12e(i-1)
755 b12e(i-1) = temp
756 b12bulge = work(iv2tsn+i-1-1)*b12e(i)
757 b12e(i) = work(iv2tcs+i-1-1)*b12e(i)
758 temp = work(iv2tcs+i-1-1)*b22e(i-1) +
759 $ work(iv2tsn+i-1-1)*b22d(i)
760 b22d(i) = work(iv2tcs+i-1-1)*b22d(i) -
761 $ work(iv2tsn+i-1-1)*b22e(i-1)
762 b22e(i-1) = temp
763 b22bulge = work(iv2tsn+i-1-1)*b22e(i)
764 b22e(i) = work(iv2tcs+i-1-1)*b22e(i)
765*
766* Compute THETA(I)
767*
768 x1 = cos(phi(i-1))*b11d(i) + sin(phi(i-1))*b12e(i-1)
769 x2 = cos(phi(i-1))*b11bulge + sin(phi(i-1))*b12bulge
770 y1 = cos(phi(i-1))*b21d(i) + sin(phi(i-1))*b22e(i-1)
771 y2 = cos(phi(i-1))*b21bulge + sin(phi(i-1))*b22bulge
772*
773 theta(i) = atan2( sqrt(y1**2+y2**2), sqrt(x1**2+x2**2) )
774*
775* Determine if there are bulges to chase or if a new direct
776* summand has been reached
777*
778 restart11 = b11d(i)**2 + b11bulge**2 .LE. thresh**2
779 restart12 = b12e(i-1)**2 + b12bulge**2 .LE. thresh**2
780 restart21 = b21d(i)**2 + b21bulge**2 .LE. thresh**2
781 restart22 = b22e(i-1)**2 + b22bulge**2 .LE. thresh**2
782*
783* If possible, chase bulges from B11(I+1,I), B12(I+1,I-1),
784* B21(I+1,I), and B22(I+1,I-1). If necessary, restart bulge-
785* chasing by applying the original shift again.
786*
787 IF( .NOT. restart11 .AND. .NOT. restart12 ) THEN
788 CALL dlartgp( x2, x1, work(iu1sn+i-1),
789 $ work(iu1cs+i-1),
790 $ r )
791 ELSE IF( .NOT. restart11 .AND. restart12 ) THEN
792 CALL dlartgp( b11bulge, b11d(i), work(iu1sn+i-1),
793 $ work(iu1cs+i-1), r )
794 ELSE IF( restart11 .AND. .NOT. restart12 ) THEN
795 CALL dlartgp( b12bulge, b12e(i-1), work(iu1sn+i-1),
796 $ work(iu1cs+i-1), r )
797 ELSE IF( mu .LE. nu ) THEN
798 CALL dlartgs( b11e(i), b11d(i+1), mu, work(iu1cs+i-1),
799 $ work(iu1sn+i-1) )
800 ELSE
801 CALL dlartgs( b12d(i), b12e(i), nu, work(iu1cs+i-1),
802 $ work(iu1sn+i-1) )
803 END IF
804 IF( .NOT. restart21 .AND. .NOT. restart22 ) THEN
805 CALL dlartgp( y2, y1, work(iu2sn+i-1),
806 $ work(iu2cs+i-1),
807 $ r )
808 ELSE IF( .NOT. restart21 .AND. restart22 ) THEN
809 CALL dlartgp( b21bulge, b21d(i), work(iu2sn+i-1),
810 $ work(iu2cs+i-1), r )
811 ELSE IF( restart21 .AND. .NOT. restart22 ) THEN
812 CALL dlartgp( b22bulge, b22e(i-1), work(iu2sn+i-1),
813 $ work(iu2cs+i-1), r )
814 ELSE IF( nu .LT. mu ) THEN
815 CALL dlartgs( b21e(i), b21e(i+1), nu, work(iu2cs+i-1),
816 $ work(iu2sn+i-1) )
817 ELSE
818 CALL dlartgs( b22d(i), b22e(i), mu, work(iu2cs+i-1),
819 $ work(iu2sn+i-1) )
820 END IF
821 work(iu2cs+i-1) = -work(iu2cs+i-1)
822 work(iu2sn+i-1) = -work(iu2sn+i-1)
823*
824 temp = work(iu1cs+i-1)*b11e(i) + work(iu1sn+i-1)*b11d(i+1)
825 b11d(i+1) = work(iu1cs+i-1)*b11d(i+1) -
826 $ work(iu1sn+i-1)*b11e(i)
827 b11e(i) = temp
828 IF( i .LT. imax - 1 ) THEN
829 b11bulge = work(iu1sn+i-1)*b11e(i+1)
830 b11e(i+1) = work(iu1cs+i-1)*b11e(i+1)
831 END IF
832 temp = work(iu2cs+i-1)*b21e(i) + work(iu2sn+i-1)*b21d(i+1)
833 b21d(i+1) = work(iu2cs+i-1)*b21d(i+1) -
834 $ work(iu2sn+i-1)*b21e(i)
835 b21e(i) = temp
836 IF( i .LT. imax - 1 ) THEN
837 b21bulge = work(iu2sn+i-1)*b21e(i+1)
838 b21e(i+1) = work(iu2cs+i-1)*b21e(i+1)
839 END IF
840 temp = work(iu1cs+i-1)*b12d(i) + work(iu1sn+i-1)*b12e(i)
841 b12e(i) = work(iu1cs+i-1)*b12e(i) - work(iu1sn+i-1)*b12d(i)
842 b12d(i) = temp
843 b12bulge = work(iu1sn+i-1)*b12d(i+1)
844 b12d(i+1) = work(iu1cs+i-1)*b12d(i+1)
845 temp = work(iu2cs+i-1)*b22d(i) + work(iu2sn+i-1)*b22e(i)
846 b22e(i) = work(iu2cs+i-1)*b22e(i) - work(iu2sn+i-1)*b22d(i)
847 b22d(i) = temp
848 b22bulge = work(iu2sn+i-1)*b22d(i+1)
849 b22d(i+1) = work(iu2cs+i-1)*b22d(i+1)
850*
851 END DO
852*
853* Compute PHI(IMAX-1)
854*
855 x1 = sin(theta(imax-1))*b11e(imax-1) +
856 $ cos(theta(imax-1))*b21e(imax-1)
857 y1 = sin(theta(imax-1))*b12d(imax-1) +
858 $ cos(theta(imax-1))*b22d(imax-1)
859 y2 = sin(theta(imax-1))*b12bulge + cos(theta(imax-1))*b22bulge
860*
861 phi(imax-1) = atan2( abs(x1), sqrt(y1**2+y2**2) )
862*
863* Chase bulges from B12(IMAX-1,IMAX) and B22(IMAX-1,IMAX)
864*
865 restart12 = b12d(imax-1)**2 + b12bulge**2 .LE. thresh**2
866 restart22 = b22d(imax-1)**2 + b22bulge**2 .LE. thresh**2
867*
868 IF( .NOT. restart12 .AND. .NOT. restart22 ) THEN
869 CALL dlartgp( y2, y1, work(iv2tsn+imax-1-1),
870 $ work(iv2tcs+imax-1-1), r )
871 ELSE IF( .NOT. restart12 .AND. restart22 ) THEN
872 CALL dlartgp( b12bulge, b12d(imax-1),
873 $ work(iv2tsn+imax-1-1),
874 $ work(iv2tcs+imax-1-1), r )
875 ELSE IF( restart12 .AND. .NOT. restart22 ) THEN
876 CALL dlartgp( b22bulge, b22d(imax-1),
877 $ work(iv2tsn+imax-1-1),
878 $ work(iv2tcs+imax-1-1), r )
879 ELSE IF( nu .LT. mu ) THEN
880 CALL dlartgs( b12e(imax-1), b12d(imax), nu,
881 $ work(iv2tcs+imax-1-1), work(iv2tsn+imax-1-1) )
882 ELSE
883 CALL dlartgs( b22e(imax-1), b22d(imax), mu,
884 $ work(iv2tcs+imax-1-1), work(iv2tsn+imax-1-1) )
885 END IF
886*
887 temp = work(iv2tcs+imax-1-1)*b12e(imax-1) +
888 $ work(iv2tsn+imax-1-1)*b12d(imax)
889 b12d(imax) = work(iv2tcs+imax-1-1)*b12d(imax) -
890 $ work(iv2tsn+imax-1-1)*b12e(imax-1)
891 b12e(imax-1) = temp
892 temp = work(iv2tcs+imax-1-1)*b22e(imax-1) +
893 $ work(iv2tsn+imax-1-1)*b22d(imax)
894 b22d(imax) = work(iv2tcs+imax-1-1)*b22d(imax) -
895 $ work(iv2tsn+imax-1-1)*b22e(imax-1)
896 b22e(imax-1) = temp
897*
898* Update singular vectors
899*
900 IF( wantu1 ) THEN
901 IF( colmajor ) THEN
902 CALL dlasr( 'R', 'V', 'F', p, imax-imin+1,
903 $ work(iu1cs+imin-1), work(iu1sn+imin-1),
904 $ u1(1,imin), ldu1 )
905 ELSE
906 CALL dlasr( 'L', 'V', 'F', imax-imin+1, p,
907 $ work(iu1cs+imin-1), work(iu1sn+imin-1),
908 $ u1(imin,1), ldu1 )
909 END IF
910 END IF
911 IF( wantu2 ) THEN
912 IF( colmajor ) THEN
913 CALL dlasr( 'R', 'V', 'F', m-p, imax-imin+1,
914 $ work(iu2cs+imin-1), work(iu2sn+imin-1),
915 $ u2(1,imin), ldu2 )
916 ELSE
917 CALL dlasr( 'L', 'V', 'F', imax-imin+1, m-p,
918 $ work(iu2cs+imin-1), work(iu2sn+imin-1),
919 $ u2(imin,1), ldu2 )
920 END IF
921 END IF
922 IF( wantv1t ) THEN
923 IF( colmajor ) THEN
924 CALL dlasr( 'L', 'V', 'F', imax-imin+1, q,
925 $ work(iv1tcs+imin-1), work(iv1tsn+imin-1),
926 $ v1t(imin,1), ldv1t )
927 ELSE
928 CALL dlasr( 'R', 'V', 'F', q, imax-imin+1,
929 $ work(iv1tcs+imin-1), work(iv1tsn+imin-1),
930 $ v1t(1,imin), ldv1t )
931 END IF
932 END IF
933 IF( wantv2t ) THEN
934 IF( colmajor ) THEN
935 CALL dlasr( 'L', 'V', 'F', imax-imin+1, m-q,
936 $ work(iv2tcs+imin-1), work(iv2tsn+imin-1),
937 $ v2t(imin,1), ldv2t )
938 ELSE
939 CALL dlasr( 'R', 'V', 'F', m-q, imax-imin+1,
940 $ work(iv2tcs+imin-1), work(iv2tsn+imin-1),
941 $ v2t(1,imin), ldv2t )
942 END IF
943 END IF
944*
945* Fix signs on B11(IMAX-1,IMAX) and B21(IMAX-1,IMAX)
946*
947 IF( b11e(imax-1)+b21e(imax-1) .GT. 0 ) THEN
948 b11d(imax) = -b11d(imax)
949 b21d(imax) = -b21d(imax)
950 IF( wantv1t ) THEN
951 IF( colmajor ) THEN
952 CALL dscal( q, negone, v1t(imax,1), ldv1t )
953 ELSE
954 CALL dscal( q, negone, v1t(1,imax), 1 )
955 END IF
956 END IF
957 END IF
958*
959* Compute THETA(IMAX)
960*
961 x1 = cos(phi(imax-1))*b11d(imax) +
962 $ sin(phi(imax-1))*b12e(imax-1)
963 y1 = cos(phi(imax-1))*b21d(imax) +
964 $ sin(phi(imax-1))*b22e(imax-1)
965*
966 theta(imax) = atan2( abs(y1), abs(x1) )
967*
968* Fix signs on B11(IMAX,IMAX), B12(IMAX,IMAX-1), B21(IMAX,IMAX),
969* and B22(IMAX,IMAX-1)
970*
971 IF( b11d(imax)+b12e(imax-1) .LT. 0 ) THEN
972 b12d(imax) = -b12d(imax)
973 IF( wantu1 ) THEN
974 IF( colmajor ) THEN
975 CALL dscal( p, negone, u1(1,imax), 1 )
976 ELSE
977 CALL dscal( p, negone, u1(imax,1), ldu1 )
978 END IF
979 END IF
980 END IF
981 IF( b21d(imax)+b22e(imax-1) .GT. 0 ) THEN
982 b22d(imax) = -b22d(imax)
983 IF( wantu2 ) THEN
984 IF( colmajor ) THEN
985 CALL dscal( m-p, negone, u2(1,imax), 1 )
986 ELSE
987 CALL dscal( m-p, negone, u2(imax,1), ldu2 )
988 END IF
989 END IF
990 END IF
991*
992* Fix signs on B12(IMAX,IMAX) and B22(IMAX,IMAX)
993*
994 IF( b12d(imax)+b22d(imax) .LT. 0 ) THEN
995 IF( wantv2t ) THEN
996 IF( colmajor ) THEN
997 CALL dscal( m-q, negone, v2t(imax,1), ldv2t )
998 ELSE
999 CALL dscal( m-q, negone, v2t(1,imax), 1 )
1000 END IF
1001 END IF
1002 END IF
1003*
1004* Test for negligible sines or cosines
1005*
1006 DO i = imin, imax
1007 IF( theta(i) .LT. thresh ) THEN
1008 theta(i) = zero
1009 ELSE IF( theta(i) .GT. piover2-thresh ) THEN
1010 theta(i) = piover2
1011 END IF
1012 END DO
1013 DO i = imin, imax-1
1014 IF( phi(i) .LT. thresh ) THEN
1015 phi(i) = zero
1016 ELSE IF( phi(i) .GT. piover2-thresh ) THEN
1017 phi(i) = piover2
1018 END IF
1019 END DO
1020*
1021* Deflate
1022*
1023 IF (imax .GT. 1) THEN
1024 DO WHILE( phi(imax-1) .EQ. zero )
1025 imax = imax - 1
1026 IF (imax .LE. 1) EXIT
1027 END DO
1028 END IF
1029 IF( imin .GT. imax - 1 )
1030 $ imin = imax - 1
1031 IF (imin .GT. 1) THEN
1032 DO WHILE (phi(imin-1) .NE. zero)
1033 imin = imin - 1
1034 IF (imin .LE. 1) EXIT
1035 END DO
1036 END IF
1037*
1038* Repeat main iteration loop
1039*
1040 END DO
1041*
1042* Postprocessing: order THETA from least to greatest
1043*
1044 DO i = 1, q
1045*
1046 mini = i
1047 thetamin = theta(i)
1048 DO j = i+1, q
1049 IF( theta(j) .LT. thetamin ) THEN
1050 mini = j
1051 thetamin = theta(j)
1052 END IF
1053 END DO
1054*
1055 IF( mini .NE. i ) THEN
1056 theta(mini) = theta(i)
1057 theta(i) = thetamin
1058 IF( colmajor ) THEN
1059 IF( wantu1 )
1060 $ CALL dswap( p, u1(1,i), 1, u1(1,mini), 1 )
1061 IF( wantu2 )
1062 $ CALL dswap( m-p, u2(1,i), 1, u2(1,mini), 1 )
1063 IF( wantv1t )
1064 $ CALL dswap( q, v1t(i,1), ldv1t, v1t(mini,1),
1065 $ ldv1t )
1066 IF( wantv2t )
1067 $ CALL dswap( m-q, v2t(i,1), ldv2t, v2t(mini,1),
1068 $ ldv2t )
1069 ELSE
1070 IF( wantu1 )
1071 $ CALL dswap( p, u1(i,1), ldu1, u1(mini,1), ldu1 )
1072 IF( wantu2 )
1073 $ CALL dswap( m-p, u2(i,1), ldu2, u2(mini,1), ldu2 )
1074 IF( wantv1t )
1075 $ CALL dswap( q, v1t(1,i), 1, v1t(1,mini), 1 )
1076 IF( wantv2t )
1077 $ CALL dswap( m-q, v2t(1,i), 1, v2t(1,mini), 1 )
1078 END IF
1079 END IF
1080*
1081 END DO
1082*
1083 RETURN
1084*
1085* End of DBBCSD
1086*
1087 END
1088
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dbbcsd(jobu1, jobu2, jobv1t, jobv2t, trans, m, p, q, theta, phi, u1, ldu1, u2, ldu2, v1t, ldv1t, v2t, ldv2t, b11d, b11e, b12d, b12e, b21d, b21e, b22d, b22e, work, lwork, info)
DBBCSD
Definition dbbcsd.f:331
subroutine dlartgp(f, g, cs, sn, r)
DLARTGP generates a plane rotation so that the diagonal is nonnegative.
Definition dlartgp.f:93
subroutine dlartgs(x, y, sigma, cs, sn)
DLARTGS generates a plane rotation designed to introduce a bulge in implicit QR iteration for the bid...
Definition dlartgs.f:88
subroutine dlas2(f, g, h, ssmin, ssmax)
DLAS2 computes singular values of a 2-by-2 triangular matrix.
Definition dlas2.f:103
subroutine dlasr(side, pivot, direct, m, n, c, s, a, lda)
DLASR applies a sequence of plane rotations to a general rectangular matrix.
Definition dlasr.f:197
subroutine dscal(n, da, dx, incx)
DSCAL
Definition dscal.f:79
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
Definition dswap.f:82