Statistiques
| Révision :

root / src / lapack / double / dbdsqr.f @ 1

Historique | Voir | Annoter | Télécharger (23,46 ko)

1 1 equemene
      SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
2 1 equemene
     $                   LDU, C, LDC, WORK, INFO )
3 1 equemene
*
4 1 equemene
*  -- LAPACK routine (version 3.2) --
5 1 equemene
*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
6 1 equemene
*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
7 1 equemene
*     January 2007
8 1 equemene
*
9 1 equemene
*     .. Scalar Arguments ..
10 1 equemene
      CHARACTER          UPLO
11 1 equemene
      INTEGER            INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU
12 1 equemene
*     ..
13 1 equemene
*     .. Array Arguments ..
14 1 equemene
      DOUBLE PRECISION   C( LDC, * ), D( * ), E( * ), U( LDU, * ),
15 1 equemene
     $                   VT( LDVT, * ), WORK( * )
16 1 equemene
*     ..
17 1 equemene
*
18 1 equemene
*  Purpose
19 1 equemene
*  =======
20 1 equemene
*
21 1 equemene
*  DBDSQR computes the singular values and, optionally, the right and/or
22 1 equemene
*  left singular vectors from the singular value decomposition (SVD) of
23 1 equemene
*  a real N-by-N (upper or lower) bidiagonal matrix B using the implicit
24 1 equemene
*  zero-shift QR algorithm.  The SVD of B has the form
25 1 equemene
*
26 1 equemene
*     B = Q * S * P**T
27 1 equemene
*
28 1 equemene
*  where S is the diagonal matrix of singular values, Q is an orthogonal
29 1 equemene
*  matrix of left singular vectors, and P is an orthogonal matrix of
30 1 equemene
*  right singular vectors.  If left singular vectors are requested, this
31 1 equemene
*  subroutine actually returns U*Q instead of Q, and, if right singular
32 1 equemene
*  vectors are requested, this subroutine returns P**T*VT instead of
33 1 equemene
*  P**T, for given real input matrices U and VT.  When U and VT are the
34 1 equemene
*  orthogonal matrices that reduce a general matrix A to bidiagonal
35 1 equemene
*  form:  A = U*B*VT, as computed by DGEBRD, then
36 1 equemene
*
37 1 equemene
*     A = (U*Q) * S * (P**T*VT)
38 1 equemene
*
39 1 equemene
*  is the SVD of A.  Optionally, the subroutine may also compute Q**T*C
40 1 equemene
*  for a given real input matrix C.
41 1 equemene
*
42 1 equemene
*  See "Computing  Small Singular Values of Bidiagonal Matrices With
43 1 equemene
*  Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,
44 1 equemene
*  LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11,
45 1 equemene
*  no. 5, pp. 873-912, Sept 1990) and
46 1 equemene
*  "Accurate singular values and differential qd algorithms," by
47 1 equemene
*  B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics
48 1 equemene
*  Department, University of California at Berkeley, July 1992
49 1 equemene
*  for a detailed description of the algorithm.
50 1 equemene
*
51 1 equemene
*  Arguments
52 1 equemene
*  =========
53 1 equemene
*
54 1 equemene
*  UPLO    (input) CHARACTER*1
55 1 equemene
*          = 'U':  B is upper bidiagonal;
56 1 equemene
*          = 'L':  B is lower bidiagonal.
57 1 equemene
*
58 1 equemene
*  N       (input) INTEGER
59 1 equemene
*          The order of the matrix B.  N >= 0.
60 1 equemene
*
61 1 equemene
*  NCVT    (input) INTEGER
62 1 equemene
*          The number of columns of the matrix VT. NCVT >= 0.
63 1 equemene
*
64 1 equemene
*  NRU     (input) INTEGER
65 1 equemene
*          The number of rows of the matrix U. NRU >= 0.
66 1 equemene
*
67 1 equemene
*  NCC     (input) INTEGER
68 1 equemene
*          The number of columns of the matrix C. NCC >= 0.
69 1 equemene
*
70 1 equemene
*  D       (input/output) DOUBLE PRECISION array, dimension (N)
71 1 equemene
*          On entry, the n diagonal elements of the bidiagonal matrix B.
72 1 equemene
*          On exit, if INFO=0, the singular values of B in decreasing
73 1 equemene
*          order.
74 1 equemene
*
75 1 equemene
*  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
76 1 equemene
*          On entry, the N-1 offdiagonal elements of the bidiagonal
77 1 equemene
*          matrix B.
78 1 equemene
*          On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E
79 1 equemene
*          will contain the diagonal and superdiagonal elements of a
80 1 equemene
*          bidiagonal matrix orthogonally equivalent to the one given
81 1 equemene
*          as input.
82 1 equemene
*
83 1 equemene
*  VT      (input/output) DOUBLE PRECISION array, dimension (LDVT, NCVT)
84 1 equemene
*          On entry, an N-by-NCVT matrix VT.
85 1 equemene
*          On exit, VT is overwritten by P**T * VT.
86 1 equemene
*          Not referenced if NCVT = 0.
87 1 equemene
*
88 1 equemene
*  LDVT    (input) INTEGER
89 1 equemene
*          The leading dimension of the array VT.
90 1 equemene
*          LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0.
91 1 equemene
*
92 1 equemene
*  U       (input/output) DOUBLE PRECISION array, dimension (LDU, N)
93 1 equemene
*          On entry, an NRU-by-N matrix U.
94 1 equemene
*          On exit, U is overwritten by U * Q.
95 1 equemene
*          Not referenced if NRU = 0.
96 1 equemene
*
97 1 equemene
*  LDU     (input) INTEGER
98 1 equemene
*          The leading dimension of the array U.  LDU >= max(1,NRU).
99 1 equemene
*
100 1 equemene
*  C       (input/output) DOUBLE PRECISION array, dimension (LDC, NCC)
101 1 equemene
*          On entry, an N-by-NCC matrix C.
102 1 equemene
*          On exit, C is overwritten by Q**T * C.
103 1 equemene
*          Not referenced if NCC = 0.
104 1 equemene
*
105 1 equemene
*  LDC     (input) INTEGER
106 1 equemene
*          The leading dimension of the array C.
107 1 equemene
*          LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0.
108 1 equemene
*
109 1 equemene
*  WORK    (workspace) DOUBLE PRECISION array, dimension (4*N)
110 1 equemene
*
111 1 equemene
*  INFO    (output) INTEGER
112 1 equemene
*          = 0:  successful exit
113 1 equemene
*          < 0:  If INFO = -i, the i-th argument had an illegal value
114 1 equemene
*          > 0:
115 1 equemene
*             if NCVT = NRU = NCC = 0,
116 1 equemene
*                = 1, a split was marked by a positive value in E
117 1 equemene
*                = 2, current block of Z not diagonalized after 30*N
118 1 equemene
*                     iterations (in inner while loop)
119 1 equemene
*                = 3, termination criterion of outer while loop not met
120 1 equemene
*                     (program created more than N unreduced blocks)
121 1 equemene
*             else NCVT = NRU = NCC = 0,
122 1 equemene
*                   the algorithm did not converge; D and E contain the
123 1 equemene
*                   elements of a bidiagonal matrix which is orthogonally
124 1 equemene
*                   similar to the input matrix B;  if INFO = i, i
125 1 equemene
*                   elements of E have not converged to zero.
126 1 equemene
*
127 1 equemene
*  Internal Parameters
128 1 equemene
*  ===================
129 1 equemene
*
130 1 equemene
*  TOLMUL  DOUBLE PRECISION, default = max(10,min(100,EPS**(-1/8)))
131 1 equemene
*          TOLMUL controls the convergence criterion of the QR loop.
132 1 equemene
*          If it is positive, TOLMUL*EPS is the desired relative
133 1 equemene
*             precision in the computed singular values.
134 1 equemene
*          If it is negative, abs(TOLMUL*EPS*sigma_max) is the
135 1 equemene
*             desired absolute accuracy in the computed singular
136 1 equemene
*             values (corresponds to relative accuracy
137 1 equemene
*             abs(TOLMUL*EPS) in the largest singular value.
138 1 equemene
*          abs(TOLMUL) should be between 1 and 1/EPS, and preferably
139 1 equemene
*             between 10 (for fast convergence) and .1/EPS
140 1 equemene
*             (for there to be some accuracy in the results).
141 1 equemene
*          Default is to lose at either one eighth or 2 of the
142 1 equemene
*             available decimal digits in each computed singular value
143 1 equemene
*             (whichever is smaller).
144 1 equemene
*
145 1 equemene
*  MAXITR  INTEGER, default = 6
146 1 equemene
*          MAXITR controls the maximum number of passes of the
147 1 equemene
*          algorithm through its inner loop. The algorithms stops
148 1 equemene
*          (and so fails to converge) if the number of passes
149 1 equemene
*          through the inner loop exceeds MAXITR*N**2.
150 1 equemene
*
151 1 equemene
*  =====================================================================
152 1 equemene
*
153 1 equemene
*     .. Parameters ..
154 1 equemene
      DOUBLE PRECISION   ZERO
155 1 equemene
      PARAMETER          ( ZERO = 0.0D0 )
156 1 equemene
      DOUBLE PRECISION   ONE
157 1 equemene
      PARAMETER          ( ONE = 1.0D0 )
158 1 equemene
      DOUBLE PRECISION   NEGONE
159 1 equemene
      PARAMETER          ( NEGONE = -1.0D0 )
160 1 equemene
      DOUBLE PRECISION   HNDRTH
161 1 equemene
      PARAMETER          ( HNDRTH = 0.01D0 )
162 1 equemene
      DOUBLE PRECISION   TEN
163 1 equemene
      PARAMETER          ( TEN = 10.0D0 )
164 1 equemene
      DOUBLE PRECISION   HNDRD
165 1 equemene
      PARAMETER          ( HNDRD = 100.0D0 )
166 1 equemene
      DOUBLE PRECISION   MEIGTH
167 1 equemene
      PARAMETER          ( MEIGTH = -0.125D0 )
168 1 equemene
      INTEGER            MAXITR
169 1 equemene
      PARAMETER          ( MAXITR = 6 )
170 1 equemene
*     ..
171 1 equemene
*     .. Local Scalars ..
172 1 equemene
      LOGICAL            LOWER, ROTATE
173 1 equemene
      INTEGER            I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
174 1 equemene
     $                   NM12, NM13, OLDLL, OLDM
175 1 equemene
      DOUBLE PRECISION   ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
176 1 equemene
     $                   OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
177 1 equemene
     $                   SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
178 1 equemene
     $                   SN, THRESH, TOL, TOLMUL, UNFL
179 1 equemene
*     ..
180 1 equemene
*     .. External Functions ..
181 1 equemene
      LOGICAL            LSAME
182 1 equemene
      DOUBLE PRECISION   DLAMCH
183 1 equemene
      EXTERNAL           LSAME, DLAMCH
184 1 equemene
*     ..
185 1 equemene
*     .. External Subroutines ..
186 1 equemene
      EXTERNAL           DLARTG, DLAS2, DLASQ1, DLASR, DLASV2, DROT,
187 1 equemene
     $                   DSCAL, DSWAP, XERBLA
188 1 equemene
*     ..
189 1 equemene
*     .. Intrinsic Functions ..
190 1 equemene
      INTRINSIC          ABS, DBLE, MAX, MIN, SIGN, SQRT
191 1 equemene
*     ..
192 1 equemene
*     .. Executable Statements ..
193 1 equemene
*
194 1 equemene
*     Test the input parameters.
195 1 equemene
*
196 1 equemene
      INFO = 0
197 1 equemene
      LOWER = LSAME( UPLO, 'L' )
198 1 equemene
      IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THEN
199 1 equemene
         INFO = -1
200 1 equemene
      ELSE IF( N.LT.0 ) THEN
201 1 equemene
         INFO = -2
202 1 equemene
      ELSE IF( NCVT.LT.0 ) THEN
203 1 equemene
         INFO = -3
204 1 equemene
      ELSE IF( NRU.LT.0 ) THEN
205 1 equemene
         INFO = -4
206 1 equemene
      ELSE IF( NCC.LT.0 ) THEN
207 1 equemene
         INFO = -5
208 1 equemene
      ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
209 1 equemene
     $         ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
210 1 equemene
         INFO = -9
211 1 equemene
      ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
212 1 equemene
         INFO = -11
213 1 equemene
      ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
214 1 equemene
     $         ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
215 1 equemene
         INFO = -13
216 1 equemene
      END IF
217 1 equemene
      IF( INFO.NE.0 ) THEN
218 1 equemene
         CALL XERBLA( 'DBDSQR', -INFO )
219 1 equemene
         RETURN
220 1 equemene
      END IF
221 1 equemene
      IF( N.EQ.0 )
222 1 equemene
     $   RETURN
223 1 equemene
      IF( N.EQ.1 )
224 1 equemene
     $   GO TO 160
225 1 equemene
*
226 1 equemene
*     ROTATE is true if any singular vectors desired, false otherwise
227 1 equemene
*
228 1 equemene
      ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
229 1 equemene
*
230 1 equemene
*     If no singular vectors desired, use qd algorithm
231 1 equemene
*
232 1 equemene
      IF( .NOT.ROTATE ) THEN
233 1 equemene
         CALL DLASQ1( N, D, E, WORK, INFO )
234 1 equemene
         RETURN
235 1 equemene
      END IF
236 1 equemene
*
237 1 equemene
      NM1 = N - 1
238 1 equemene
      NM12 = NM1 + NM1
239 1 equemene
      NM13 = NM12 + NM1
240 1 equemene
      IDIR = 0
241 1 equemene
*
242 1 equemene
*     Get machine constants
243 1 equemene
*
244 1 equemene
      EPS = DLAMCH( 'Epsilon' )
245 1 equemene
      UNFL = DLAMCH( 'Safe minimum' )
246 1 equemene
*
247 1 equemene
*     If matrix lower bidiagonal, rotate to be upper bidiagonal
248 1 equemene
*     by applying Givens rotations on the left
249 1 equemene
*
250 1 equemene
      IF( LOWER ) THEN
251 1 equemene
         DO 10 I = 1, N - 1
252 1 equemene
            CALL DLARTG( D( I ), E( I ), CS, SN, R )
253 1 equemene
            D( I ) = R
254 1 equemene
            E( I ) = SN*D( I+1 )
255 1 equemene
            D( I+1 ) = CS*D( I+1 )
256 1 equemene
            WORK( I ) = CS
257 1 equemene
            WORK( NM1+I ) = SN
258 1 equemene
   10    CONTINUE
259 1 equemene
*
260 1 equemene
*        Update singular vectors if desired
261 1 equemene
*
262 1 equemene
         IF( NRU.GT.0 )
263 1 equemene
     $      CALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ), WORK( N ), U,
264 1 equemene
     $                  LDU )
265 1 equemene
         IF( NCC.GT.0 )
266 1 equemene
     $      CALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ), WORK( N ), C,
267 1 equemene
     $                  LDC )
268 1 equemene
      END IF
269 1 equemene
*
270 1 equemene
*     Compute singular values to relative accuracy TOL
271 1 equemene
*     (By setting TOL to be negative, algorithm will compute
272 1 equemene
*     singular values to absolute accuracy ABS(TOL)*norm(input matrix))
273 1 equemene
*
274 1 equemene
      TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )
275 1 equemene
      TOL = TOLMUL*EPS
276 1 equemene
*
277 1 equemene
*     Compute approximate maximum, minimum singular values
278 1 equemene
*
279 1 equemene
      SMAX = ZERO
280 1 equemene
      DO 20 I = 1, N
281 1 equemene
         SMAX = MAX( SMAX, ABS( D( I ) ) )
282 1 equemene
   20 CONTINUE
283 1 equemene
      DO 30 I = 1, N - 1
284 1 equemene
         SMAX = MAX( SMAX, ABS( E( I ) ) )
285 1 equemene
   30 CONTINUE
286 1 equemene
      SMINL = ZERO
287 1 equemene
      IF( TOL.GE.ZERO ) THEN
288 1 equemene
*
289 1 equemene
*        Relative accuracy desired
290 1 equemene
*
291 1 equemene
         SMINOA = ABS( D( 1 ) )
292 1 equemene
         IF( SMINOA.EQ.ZERO )
293 1 equemene
     $      GO TO 50
294 1 equemene
         MU = SMINOA
295 1 equemene
         DO 40 I = 2, N
296 1 equemene
            MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )
297 1 equemene
            SMINOA = MIN( SMINOA, MU )
298 1 equemene
            IF( SMINOA.EQ.ZERO )
299 1 equemene
     $         GO TO 50
300 1 equemene
   40    CONTINUE
301 1 equemene
   50    CONTINUE
302 1 equemene
         SMINOA = SMINOA / SQRT( DBLE( N ) )
303 1 equemene
         THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
304 1 equemene
      ELSE
305 1 equemene
*
306 1 equemene
*        Absolute accuracy desired
307 1 equemene
*
308 1 equemene
         THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
309 1 equemene
      END IF
310 1 equemene
*
311 1 equemene
*     Prepare for main iteration loop for the singular values
312 1 equemene
*     (MAXIT is the maximum number of passes through the inner
313 1 equemene
*     loop permitted before nonconvergence signalled.)
314 1 equemene
*
315 1 equemene
      MAXIT = MAXITR*N*N
316 1 equemene
      ITER = 0
317 1 equemene
      OLDLL = -1
318 1 equemene
      OLDM = -1
319 1 equemene
*
320 1 equemene
*     M points to last element of unconverged part of matrix
321 1 equemene
*
322 1 equemene
      M = N
323 1 equemene
*
324 1 equemene
*     Begin main iteration loop
325 1 equemene
*
326 1 equemene
   60 CONTINUE
327 1 equemene
*
328 1 equemene
*     Check for convergence or exceeding iteration count
329 1 equemene
*
330 1 equemene
      IF( M.LE.1 )
331 1 equemene
     $   GO TO 160
332 1 equemene
      IF( ITER.GT.MAXIT )
333 1 equemene
     $   GO TO 200
334 1 equemene
*
335 1 equemene
*     Find diagonal block of matrix to work on
336 1 equemene
*
337 1 equemene
      IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )
338 1 equemene
     $   D( M ) = ZERO
339 1 equemene
      SMAX = ABS( D( M ) )
340 1 equemene
      SMIN = SMAX
341 1 equemene
      DO 70 LLL = 1, M - 1
342 1 equemene
         LL = M - LLL
343 1 equemene
         ABSS = ABS( D( LL ) )
344 1 equemene
         ABSE = ABS( E( LL ) )
345 1 equemene
         IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )
346 1 equemene
     $      D( LL ) = ZERO
347 1 equemene
         IF( ABSE.LE.THRESH )
348 1 equemene
     $      GO TO 80
349 1 equemene
         SMIN = MIN( SMIN, ABSS )
350 1 equemene
         SMAX = MAX( SMAX, ABSS, ABSE )
351 1 equemene
   70 CONTINUE
352 1 equemene
      LL = 0
353 1 equemene
      GO TO 90
354 1 equemene
   80 CONTINUE
355 1 equemene
      E( LL ) = ZERO
356 1 equemene
*
357 1 equemene
*     Matrix splits since E(LL) = 0
358 1 equemene
*
359 1 equemene
      IF( LL.EQ.M-1 ) THEN
360 1 equemene
*
361 1 equemene
*        Convergence of bottom singular value, return to top of loop
362 1 equemene
*
363 1 equemene
         M = M - 1
364 1 equemene
         GO TO 60
365 1 equemene
      END IF
366 1 equemene
   90 CONTINUE
367 1 equemene
      LL = LL + 1
368 1 equemene
*
369 1 equemene
*     E(LL) through E(M-1) are nonzero, E(LL-1) is zero
370 1 equemene
*
371 1 equemene
      IF( LL.EQ.M-1 ) THEN
372 1 equemene
*
373 1 equemene
*        2 by 2 block, handle separately
374 1 equemene
*
375 1 equemene
         CALL DLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,
376 1 equemene
     $                COSR, SINL, COSL )
377 1 equemene
         D( M-1 ) = SIGMX
378 1 equemene
         E( M-1 ) = ZERO
379 1 equemene
         D( M ) = SIGMN
380 1 equemene
*
381 1 equemene
*        Compute singular vectors, if desired
382 1 equemene
*
383 1 equemene
         IF( NCVT.GT.0 )
384 1 equemene
     $      CALL DROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT, COSR,
385 1 equemene
     $                 SINR )
386 1 equemene
         IF( NRU.GT.0 )
387 1 equemene
     $      CALL DROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )
388 1 equemene
         IF( NCC.GT.0 )
389 1 equemene
     $      CALL DROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,
390 1 equemene
     $                 SINL )
391 1 equemene
         M = M - 2
392 1 equemene
         GO TO 60
393 1 equemene
      END IF
394 1 equemene
*
395 1 equemene
*     If working on new submatrix, choose shift direction
396 1 equemene
*     (from larger end diagonal element towards smaller)
397 1 equemene
*
398 1 equemene
      IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN
399 1 equemene
         IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN
400 1 equemene
*
401 1 equemene
*           Chase bulge from top (big end) to bottom (small end)
402 1 equemene
*
403 1 equemene
            IDIR = 1
404 1 equemene
         ELSE
405 1 equemene
*
406 1 equemene
*           Chase bulge from bottom (big end) to top (small end)
407 1 equemene
*
408 1 equemene
            IDIR = 2
409 1 equemene
         END IF
410 1 equemene
      END IF
411 1 equemene
*
412 1 equemene
*     Apply convergence tests
413 1 equemene
*
414 1 equemene
      IF( IDIR.EQ.1 ) THEN
415 1 equemene
*
416 1 equemene
*        Run convergence test in forward direction
417 1 equemene
*        First apply standard test to bottom of matrix
418 1 equemene
*
419 1 equemene
         IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.
420 1 equemene
     $       ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN
421 1 equemene
            E( M-1 ) = ZERO
422 1 equemene
            GO TO 60
423 1 equemene
         END IF
424 1 equemene
*
425 1 equemene
         IF( TOL.GE.ZERO ) THEN
426 1 equemene
*
427 1 equemene
*           If relative accuracy desired,
428 1 equemene
*           apply convergence criterion forward
429 1 equemene
*
430 1 equemene
            MU = ABS( D( LL ) )
431 1 equemene
            SMINL = MU
432 1 equemene
            DO 100 LLL = LL, M - 1
433 1 equemene
               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
434 1 equemene
                  E( LLL ) = ZERO
435 1 equemene
                  GO TO 60
436 1 equemene
               END IF
437 1 equemene
               MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
438 1 equemene
               SMINL = MIN( SMINL, MU )
439 1 equemene
  100       CONTINUE
440 1 equemene
         END IF
441 1 equemene
*
442 1 equemene
      ELSE
443 1 equemene
*
444 1 equemene
*        Run convergence test in backward direction
445 1 equemene
*        First apply standard test to top of matrix
446 1 equemene
*
447 1 equemene
         IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.
448 1 equemene
     $       ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN
449 1 equemene
            E( LL ) = ZERO
450 1 equemene
            GO TO 60
451 1 equemene
         END IF
452 1 equemene
*
453 1 equemene
         IF( TOL.GE.ZERO ) THEN
454 1 equemene
*
455 1 equemene
*           If relative accuracy desired,
456 1 equemene
*           apply convergence criterion backward
457 1 equemene
*
458 1 equemene
            MU = ABS( D( M ) )
459 1 equemene
            SMINL = MU
460 1 equemene
            DO 110 LLL = M - 1, LL, -1
461 1 equemene
               IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
462 1 equemene
                  E( LLL ) = ZERO
463 1 equemene
                  GO TO 60
464 1 equemene
               END IF
465 1 equemene
               MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
466 1 equemene
               SMINL = MIN( SMINL, MU )
467 1 equemene
  110       CONTINUE
468 1 equemene
         END IF
469 1 equemene
      END IF
470 1 equemene
      OLDLL = LL
471 1 equemene
      OLDM = M
472 1 equemene
*
473 1 equemene
*     Compute shift.  First, test if shifting would ruin relative
474 1 equemene
*     accuracy, and if so set the shift to zero.
475 1 equemene
*
476 1 equemene
      IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.
477 1 equemene
     $    MAX( EPS, HNDRTH*TOL ) ) THEN
478 1 equemene
*
479 1 equemene
*        Use a zero shift to avoid loss of relative accuracy
480 1 equemene
*
481 1 equemene
         SHIFT = ZERO
482 1 equemene
      ELSE
483 1 equemene
*
484 1 equemene
*        Compute the shift from 2-by-2 block at end of matrix
485 1 equemene
*
486 1 equemene
         IF( IDIR.EQ.1 ) THEN
487 1 equemene
            SLL = ABS( D( LL ) )
488 1 equemene
            CALL DLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )
489 1 equemene
         ELSE
490 1 equemene
            SLL = ABS( D( M ) )
491 1 equemene
            CALL DLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )
492 1 equemene
         END IF
493 1 equemene
*
494 1 equemene
*        Test if shift negligible, and if so set to zero
495 1 equemene
*
496 1 equemene
         IF( SLL.GT.ZERO ) THEN
497 1 equemene
            IF( ( SHIFT / SLL )**2.LT.EPS )
498 1 equemene
     $         SHIFT = ZERO
499 1 equemene
         END IF
500 1 equemene
      END IF
501 1 equemene
*
502 1 equemene
*     Increment iteration count
503 1 equemene
*
504 1 equemene
      ITER = ITER + M - LL
505 1 equemene
*
506 1 equemene
*     If SHIFT = 0, do simplified QR iteration
507 1 equemene
*
508 1 equemene
      IF( SHIFT.EQ.ZERO ) THEN
509 1 equemene
         IF( IDIR.EQ.1 ) THEN
510 1 equemene
*
511 1 equemene
*           Chase bulge from top to bottom
512 1 equemene
*           Save cosines and sines for later singular vector updates
513 1 equemene
*
514 1 equemene
            CS = ONE
515 1 equemene
            OLDCS = ONE
516 1 equemene
            DO 120 I = LL, M - 1
517 1 equemene
               CALL DLARTG( D( I )*CS, E( I ), CS, SN, R )
518 1 equemene
               IF( I.GT.LL )
519 1 equemene
     $            E( I-1 ) = OLDSN*R
520 1 equemene
               CALL DLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )
521 1 equemene
               WORK( I-LL+1 ) = CS
522 1 equemene
               WORK( I-LL+1+NM1 ) = SN
523 1 equemene
               WORK( I-LL+1+NM12 ) = OLDCS
524 1 equemene
               WORK( I-LL+1+NM13 ) = OLDSN
525 1 equemene
  120       CONTINUE
526 1 equemene
            H = D( M )*CS
527 1 equemene
            D( M ) = H*OLDCS
528 1 equemene
            E( M-1 ) = H*OLDSN
529 1 equemene
*
530 1 equemene
*           Update singular vectors
531 1 equemene
*
532 1 equemene
            IF( NCVT.GT.0 )
533 1 equemene
     $         CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),
534 1 equemene
     $                     WORK( N ), VT( LL, 1 ), LDVT )
535 1 equemene
            IF( NRU.GT.0 )
536 1 equemene
     $         CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),
537 1 equemene
     $                     WORK( NM13+1 ), U( 1, LL ), LDU )
538 1 equemene
            IF( NCC.GT.0 )
539 1 equemene
     $         CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),
540 1 equemene
     $                     WORK( NM13+1 ), C( LL, 1 ), LDC )
541 1 equemene
*
542 1 equemene
*           Test convergence
543 1 equemene
*
544 1 equemene
            IF( ABS( E( M-1 ) ).LE.THRESH )
545 1 equemene
     $         E( M-1 ) = ZERO
546 1 equemene
*
547 1 equemene
         ELSE
548 1 equemene
*
549 1 equemene
*           Chase bulge from bottom to top
550 1 equemene
*           Save cosines and sines for later singular vector updates
551 1 equemene
*
552 1 equemene
            CS = ONE
553 1 equemene
            OLDCS = ONE
554 1 equemene
            DO 130 I = M, LL + 1, -1
555 1 equemene
               CALL DLARTG( D( I )*CS, E( I-1 ), CS, SN, R )
556 1 equemene
               IF( I.LT.M )
557 1 equemene
     $            E( I ) = OLDSN*R
558 1 equemene
               CALL DLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )
559 1 equemene
               WORK( I-LL ) = CS
560 1 equemene
               WORK( I-LL+NM1 ) = -SN
561 1 equemene
               WORK( I-LL+NM12 ) = OLDCS
562 1 equemene
               WORK( I-LL+NM13 ) = -OLDSN
563 1 equemene
  130       CONTINUE
564 1 equemene
            H = D( LL )*CS
565 1 equemene
            D( LL ) = H*OLDCS
566 1 equemene
            E( LL ) = H*OLDSN
567 1 equemene
*
568 1 equemene
*           Update singular vectors
569 1 equemene
*
570 1 equemene
            IF( NCVT.GT.0 )
571 1 equemene
     $         CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),
572 1 equemene
     $                     WORK( NM13+1 ), VT( LL, 1 ), LDVT )
573 1 equemene
            IF( NRU.GT.0 )
574 1 equemene
     $         CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),
575 1 equemene
     $                     WORK( N ), U( 1, LL ), LDU )
576 1 equemene
            IF( NCC.GT.0 )
577 1 equemene
     $         CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),
578 1 equemene
     $                     WORK( N ), C( LL, 1 ), LDC )
579 1 equemene
*
580 1 equemene
*           Test convergence
581 1 equemene
*
582 1 equemene
            IF( ABS( E( LL ) ).LE.THRESH )
583 1 equemene
     $         E( LL ) = ZERO
584 1 equemene
         END IF
585 1 equemene
      ELSE
586 1 equemene
*
587 1 equemene
*        Use nonzero shift
588 1 equemene
*
589 1 equemene
         IF( IDIR.EQ.1 ) THEN
590 1 equemene
*
591 1 equemene
*           Chase bulge from top to bottom
592 1 equemene
*           Save cosines and sines for later singular vector updates
593 1 equemene
*
594 1 equemene
            F = ( ABS( D( LL ) )-SHIFT )*
595 1 equemene
     $          ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )
596 1 equemene
            G = E( LL )
597 1 equemene
            DO 140 I = LL, M - 1
598 1 equemene
               CALL DLARTG( F, G, COSR, SINR, R )
599 1 equemene
               IF( I.GT.LL )
600 1 equemene
     $            E( I-1 ) = R
601 1 equemene
               F = COSR*D( I ) + SINR*E( I )
602 1 equemene
               E( I ) = COSR*E( I ) - SINR*D( I )
603 1 equemene
               G = SINR*D( I+1 )
604 1 equemene
               D( I+1 ) = COSR*D( I+1 )
605 1 equemene
               CALL DLARTG( F, G, COSL, SINL, R )
606 1 equemene
               D( I ) = R
607 1 equemene
               F = COSL*E( I ) + SINL*D( I+1 )
608 1 equemene
               D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )
609 1 equemene
               IF( I.LT.M-1 ) THEN
610 1 equemene
                  G = SINL*E( I+1 )
611 1 equemene
                  E( I+1 ) = COSL*E( I+1 )
612 1 equemene
               END IF
613 1 equemene
               WORK( I-LL+1 ) = COSR
614 1 equemene
               WORK( I-LL+1+NM1 ) = SINR
615 1 equemene
               WORK( I-LL+1+NM12 ) = COSL
616 1 equemene
               WORK( I-LL+1+NM13 ) = SINL
617 1 equemene
  140       CONTINUE
618 1 equemene
            E( M-1 ) = F
619 1 equemene
*
620 1 equemene
*           Update singular vectors
621 1 equemene
*
622 1 equemene
            IF( NCVT.GT.0 )
623 1 equemene
     $         CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),
624 1 equemene
     $                     WORK( N ), VT( LL, 1 ), LDVT )
625 1 equemene
            IF( NRU.GT.0 )
626 1 equemene
     $         CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),
627 1 equemene
     $                     WORK( NM13+1 ), U( 1, LL ), LDU )
628 1 equemene
            IF( NCC.GT.0 )
629 1 equemene
     $         CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),
630 1 equemene
     $                     WORK( NM13+1 ), C( LL, 1 ), LDC )
631 1 equemene
*
632 1 equemene
*           Test convergence
633 1 equemene
*
634 1 equemene
            IF( ABS( E( M-1 ) ).LE.THRESH )
635 1 equemene
     $         E( M-1 ) = ZERO
636 1 equemene
*
637 1 equemene
         ELSE
638 1 equemene
*
639 1 equemene
*           Chase bulge from bottom to top
640 1 equemene
*           Save cosines and sines for later singular vector updates
641 1 equemene
*
642 1 equemene
            F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /
643 1 equemene
     $          D( M ) )
644 1 equemene
            G = E( M-1 )
645 1 equemene
            DO 150 I = M, LL + 1, -1
646 1 equemene
               CALL DLARTG( F, G, COSR, SINR, R )
647 1 equemene
               IF( I.LT.M )
648 1 equemene
     $            E( I ) = R
649 1 equemene
               F = COSR*D( I ) + SINR*E( I-1 )
650 1 equemene
               E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )
651 1 equemene
               G = SINR*D( I-1 )
652 1 equemene
               D( I-1 ) = COSR*D( I-1 )
653 1 equemene
               CALL DLARTG( F, G, COSL, SINL, R )
654 1 equemene
               D( I ) = R
655 1 equemene
               F = COSL*E( I-1 ) + SINL*D( I-1 )
656 1 equemene
               D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )
657 1 equemene
               IF( I.GT.LL+1 ) THEN
658 1 equemene
                  G = SINL*E( I-2 )
659 1 equemene
                  E( I-2 ) = COSL*E( I-2 )
660 1 equemene
               END IF
661 1 equemene
               WORK( I-LL ) = COSR
662 1 equemene
               WORK( I-LL+NM1 ) = -SINR
663 1 equemene
               WORK( I-LL+NM12 ) = COSL
664 1 equemene
               WORK( I-LL+NM13 ) = -SINL
665 1 equemene
  150       CONTINUE
666 1 equemene
            E( LL ) = F
667 1 equemene
*
668 1 equemene
*           Test convergence
669 1 equemene
*
670 1 equemene
            IF( ABS( E( LL ) ).LE.THRESH )
671 1 equemene
     $         E( LL ) = ZERO
672 1 equemene
*
673 1 equemene
*           Update singular vectors if desired
674 1 equemene
*
675 1 equemene
            IF( NCVT.GT.0 )
676 1 equemene
     $         CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),
677 1 equemene
     $                     WORK( NM13+1 ), VT( LL, 1 ), LDVT )
678 1 equemene
            IF( NRU.GT.0 )
679 1 equemene
     $         CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),
680 1 equemene
     $                     WORK( N ), U( 1, LL ), LDU )
681 1 equemene
            IF( NCC.GT.0 )
682 1 equemene
     $         CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),
683 1 equemene
     $                     WORK( N ), C( LL, 1 ), LDC )
684 1 equemene
         END IF
685 1 equemene
      END IF
686 1 equemene
*
687 1 equemene
*     QR iteration finished, go back and check convergence
688 1 equemene
*
689 1 equemene
      GO TO 60
690 1 equemene
*
691 1 equemene
*     All singular values converged, so make them positive
692 1 equemene
*
693 1 equemene
  160 CONTINUE
694 1 equemene
      DO 170 I = 1, N
695 1 equemene
         IF( D( I ).LT.ZERO ) THEN
696 1 equemene
            D( I ) = -D( I )
697 1 equemene
*
698 1 equemene
*           Change sign of singular vectors, if desired
699 1 equemene
*
700 1 equemene
            IF( NCVT.GT.0 )
701 1 equemene
     $         CALL DSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )
702 1 equemene
         END IF
703 1 equemene
  170 CONTINUE
704 1 equemene
*
705 1 equemene
*     Sort the singular values into decreasing order (insertion sort on
706 1 equemene
*     singular values, but only one transposition per singular vector)
707 1 equemene
*
708 1 equemene
      DO 190 I = 1, N - 1
709 1 equemene
*
710 1 equemene
*        Scan for smallest D(I)
711 1 equemene
*
712 1 equemene
         ISUB = 1
713 1 equemene
         SMIN = D( 1 )
714 1 equemene
         DO 180 J = 2, N + 1 - I
715 1 equemene
            IF( D( J ).LE.SMIN ) THEN
716 1 equemene
               ISUB = J
717 1 equemene
               SMIN = D( J )
718 1 equemene
            END IF
719 1 equemene
  180    CONTINUE
720 1 equemene
         IF( ISUB.NE.N+1-I ) THEN
721 1 equemene
*
722 1 equemene
*           Swap singular values and vectors
723 1 equemene
*
724 1 equemene
            D( ISUB ) = D( N+1-I )
725 1 equemene
            D( N+1-I ) = SMIN
726 1 equemene
            IF( NCVT.GT.0 )
727 1 equemene
     $         CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),
728 1 equemene
     $                     LDVT )
729 1 equemene
            IF( NRU.GT.0 )
730 1 equemene
     $         CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )
731 1 equemene
            IF( NCC.GT.0 )
732 1 equemene
     $         CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )
733 1 equemene
         END IF
734 1 equemene
  190 CONTINUE
735 1 equemene
      GO TO 220
736 1 equemene
*
737 1 equemene
*     Maximum number of iterations exceeded, failure to converge
738 1 equemene
*
739 1 equemene
  200 CONTINUE
740 1 equemene
      INFO = 0
741 1 equemene
      DO 210 I = 1, N - 1
742 1 equemene
         IF( E( I ).NE.ZERO )
743 1 equemene
     $      INFO = INFO + 1
744 1 equemene
  210 CONTINUE
745 1 equemene
  220 CONTINUE
746 1 equemene
      RETURN
747 1 equemene
*
748 1 equemene
*     End of DBDSQR
749 1 equemene
*
750 1 equemene
      END