00001 SUBROUTINE DBDSDC( UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ,
00002 $ WORK, IWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 CHARACTER COMPQ, UPLO
00011 INTEGER INFO, LDU, LDVT, N
00012
00013
00014 INTEGER IQ( * ), IWORK( * )
00015 DOUBLE PRECISION D( * ), E( * ), Q( * ), U( LDU, * ),
00016 $ VT( LDVT, * ), WORK( * )
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 DOUBLE PRECISION ZERO, ONE, TWO
00139 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )
00140
00141
00142 INTEGER DIFL, DIFR, GIVCOL, GIVNUM, GIVPTR, I, IC,
00143 $ ICOMPQ, IERR, II, IS, IU, IUPLO, IVT, J, K, KK,
00144 $ MLVL, NM1, NSIZE, PERM, POLES, QSTART, SMLSIZ,
00145 $ SMLSZP, SQRE, START, WSTART, Z
00146 DOUBLE PRECISION CS, EPS, ORGNRM, P, R, SN
00147
00148
00149 LOGICAL LSAME
00150 INTEGER ILAENV
00151 DOUBLE PRECISION DLAMCH, DLANST
00152 EXTERNAL LSAME, ILAENV, DLAMCH, DLANST
00153
00154
00155 EXTERNAL DCOPY, DLARTG, DLASCL, DLASD0, DLASDA, DLASDQ,
00156 $ DLASET, DLASR, DSWAP, XERBLA
00157
00158
00159 INTRINSIC ABS, DBLE, INT, LOG, SIGN
00160
00161
00162
00163
00164
00165 INFO = 0
00166
00167 IUPLO = 0
00168 IF( LSAME( UPLO, 'U' ) )
00169 $ IUPLO = 1
00170 IF( LSAME( UPLO, 'L' ) )
00171 $ IUPLO = 2
00172 IF( LSAME( COMPQ, 'N' ) ) THEN
00173 ICOMPQ = 0
00174 ELSE IF( LSAME( COMPQ, 'P' ) ) THEN
00175 ICOMPQ = 1
00176 ELSE IF( LSAME( COMPQ, 'I' ) ) THEN
00177 ICOMPQ = 2
00178 ELSE
00179 ICOMPQ = -1
00180 END IF
00181 IF( IUPLO.EQ.0 ) THEN
00182 INFO = -1
00183 ELSE IF( ICOMPQ.LT.0 ) THEN
00184 INFO = -2
00185 ELSE IF( N.LT.0 ) THEN
00186 INFO = -3
00187 ELSE IF( ( LDU.LT.1 ) .OR. ( ( ICOMPQ.EQ.2 ) .AND. ( LDU.LT.
00188 $ N ) ) ) THEN
00189 INFO = -7
00190 ELSE IF( ( LDVT.LT.1 ) .OR. ( ( ICOMPQ.EQ.2 ) .AND. ( LDVT.LT.
00191 $ N ) ) ) THEN
00192 INFO = -9
00193 END IF
00194 IF( INFO.NE.0 ) THEN
00195 CALL XERBLA( 'DBDSDC', -INFO )
00196 RETURN
00197 END IF
00198
00199
00200
00201 IF( N.EQ.0 )
00202 $ RETURN
00203 SMLSIZ = ILAENV( 9, 'DBDSDC', ' ', 0, 0, 0, 0 )
00204 IF( N.EQ.1 ) THEN
00205 IF( ICOMPQ.EQ.1 ) THEN
00206 Q( 1 ) = SIGN( ONE, D( 1 ) )
00207 Q( 1+SMLSIZ*N ) = ONE
00208 ELSE IF( ICOMPQ.EQ.2 ) THEN
00209 U( 1, 1 ) = SIGN( ONE, D( 1 ) )
00210 VT( 1, 1 ) = ONE
00211 END IF
00212 D( 1 ) = ABS( D( 1 ) )
00213 RETURN
00214 END IF
00215 NM1 = N - 1
00216
00217
00218
00219
00220 WSTART = 1
00221 QSTART = 3
00222 IF( ICOMPQ.EQ.1 ) THEN
00223 CALL DCOPY( N, D, 1, Q( 1 ), 1 )
00224 CALL DCOPY( N-1, E, 1, Q( N+1 ), 1 )
00225 END IF
00226 IF( IUPLO.EQ.2 ) THEN
00227 QSTART = 5
00228 WSTART = 2*N - 1
00229 DO 10 I = 1, N - 1
00230 CALL DLARTG( D( I ), E( I ), CS, SN, R )
00231 D( I ) = R
00232 E( I ) = SN*D( I+1 )
00233 D( I+1 ) = CS*D( I+1 )
00234 IF( ICOMPQ.EQ.1 ) THEN
00235 Q( I+2*N ) = CS
00236 Q( I+3*N ) = SN
00237 ELSE IF( ICOMPQ.EQ.2 ) THEN
00238 WORK( I ) = CS
00239 WORK( NM1+I ) = -SN
00240 END IF
00241 10 CONTINUE
00242 END IF
00243
00244
00245
00246 IF( ICOMPQ.EQ.0 ) THEN
00247 CALL DLASDQ( 'U', 0, N, 0, 0, 0, D, E, VT, LDVT, U, LDU, U,
00248 $ LDU, WORK( WSTART ), INFO )
00249 GO TO 40
00250 END IF
00251
00252
00253
00254
00255 IF( N.LE.SMLSIZ ) THEN
00256 IF( ICOMPQ.EQ.2 ) THEN
00257 CALL DLASET( 'A', N, N, ZERO, ONE, U, LDU )
00258 CALL DLASET( 'A', N, N, ZERO, ONE, VT, LDVT )
00259 CALL DLASDQ( 'U', 0, N, N, N, 0, D, E, VT, LDVT, U, LDU, U,
00260 $ LDU, WORK( WSTART ), INFO )
00261 ELSE IF( ICOMPQ.EQ.1 ) THEN
00262 IU = 1
00263 IVT = IU + N
00264 CALL DLASET( 'A', N, N, ZERO, ONE, Q( IU+( QSTART-1 )*N ),
00265 $ N )
00266 CALL DLASET( 'A', N, N, ZERO, ONE, Q( IVT+( QSTART-1 )*N ),
00267 $ N )
00268 CALL DLASDQ( 'U', 0, N, N, N, 0, D, E,
00269 $ Q( IVT+( QSTART-1 )*N ), N,
00270 $ Q( IU+( QSTART-1 )*N ), N,
00271 $ Q( IU+( QSTART-1 )*N ), N, WORK( WSTART ),
00272 $ INFO )
00273 END IF
00274 GO TO 40
00275 END IF
00276
00277 IF( ICOMPQ.EQ.2 ) THEN
00278 CALL DLASET( 'A', N, N, ZERO, ONE, U, LDU )
00279 CALL DLASET( 'A', N, N, ZERO, ONE, VT, LDVT )
00280 END IF
00281
00282
00283
00284 ORGNRM = DLANST( 'M', N, D, E )
00285 IF( ORGNRM.EQ.ZERO )
00286 $ RETURN
00287 CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, IERR )
00288 CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, IERR )
00289
00290 EPS = DLAMCH( 'Epsilon' )
00291
00292 MLVL = INT( LOG( DBLE( N ) / DBLE( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1
00293 SMLSZP = SMLSIZ + 1
00294
00295 IF( ICOMPQ.EQ.1 ) THEN
00296 IU = 1
00297 IVT = 1 + SMLSIZ
00298 DIFL = IVT + SMLSZP
00299 DIFR = DIFL + MLVL
00300 Z = DIFR + MLVL*2
00301 IC = Z + MLVL
00302 IS = IC + 1
00303 POLES = IS + 1
00304 GIVNUM = POLES + 2*MLVL
00305
00306 K = 1
00307 GIVPTR = 2
00308 PERM = 3
00309 GIVCOL = PERM + MLVL
00310 END IF
00311
00312 DO 20 I = 1, N
00313 IF( ABS( D( I ) ).LT.EPS ) THEN
00314 D( I ) = SIGN( EPS, D( I ) )
00315 END IF
00316 20 CONTINUE
00317
00318 START = 1
00319 SQRE = 0
00320
00321 DO 30 I = 1, NM1
00322 IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN
00323
00324
00325
00326
00327 IF( I.LT.NM1 ) THEN
00328
00329
00330
00331 NSIZE = I - START + 1
00332 ELSE IF( ABS( E( I ) ).GE.EPS ) THEN
00333
00334
00335
00336 NSIZE = N - START + 1
00337 ELSE
00338
00339
00340
00341
00342
00343 NSIZE = I - START + 1
00344 IF( ICOMPQ.EQ.2 ) THEN
00345 U( N, N ) = SIGN( ONE, D( N ) )
00346 VT( N, N ) = ONE
00347 ELSE IF( ICOMPQ.EQ.1 ) THEN
00348 Q( N+( QSTART-1 )*N ) = SIGN( ONE, D( N ) )
00349 Q( N+( SMLSIZ+QSTART-1 )*N ) = ONE
00350 END IF
00351 D( N ) = ABS( D( N ) )
00352 END IF
00353 IF( ICOMPQ.EQ.2 ) THEN
00354 CALL DLASD0( NSIZE, SQRE, D( START ), E( START ),
00355 $ U( START, START ), LDU, VT( START, START ),
00356 $ LDVT, SMLSIZ, IWORK, WORK( WSTART ), INFO )
00357 ELSE
00358 CALL DLASDA( ICOMPQ, SMLSIZ, NSIZE, SQRE, D( START ),
00359 $ E( START ), Q( START+( IU+QSTART-2 )*N ), N,
00360 $ Q( START+( IVT+QSTART-2 )*N ),
00361 $ IQ( START+K*N ), Q( START+( DIFL+QSTART-2 )*
00362 $ N ), Q( START+( DIFR+QSTART-2 )*N ),
00363 $ Q( START+( Z+QSTART-2 )*N ),
00364 $ Q( START+( POLES+QSTART-2 )*N ),
00365 $ IQ( START+GIVPTR*N ), IQ( START+GIVCOL*N ),
00366 $ N, IQ( START+PERM*N ),
00367 $ Q( START+( GIVNUM+QSTART-2 )*N ),
00368 $ Q( START+( IC+QSTART-2 )*N ),
00369 $ Q( START+( IS+QSTART-2 )*N ),
00370 $ WORK( WSTART ), IWORK, INFO )
00371 END IF
00372 IF( INFO.NE.0 ) THEN
00373 RETURN
00374 END IF
00375 START = I + 1
00376 END IF
00377 30 CONTINUE
00378
00379
00380
00381 CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, IERR )
00382 40 CONTINUE
00383
00384
00385
00386 DO 60 II = 2, N
00387 I = II - 1
00388 KK = I
00389 P = D( I )
00390 DO 50 J = II, N
00391 IF( D( J ).GT.P ) THEN
00392 KK = J
00393 P = D( J )
00394 END IF
00395 50 CONTINUE
00396 IF( KK.NE.I ) THEN
00397 D( KK ) = D( I )
00398 D( I ) = P
00399 IF( ICOMPQ.EQ.1 ) THEN
00400 IQ( I ) = KK
00401 ELSE IF( ICOMPQ.EQ.2 ) THEN
00402 CALL DSWAP( N, U( 1, I ), 1, U( 1, KK ), 1 )
00403 CALL DSWAP( N, VT( I, 1 ), LDVT, VT( KK, 1 ), LDVT )
00404 END IF
00405 ELSE IF( ICOMPQ.EQ.1 ) THEN
00406 IQ( I ) = I
00407 END IF
00408 60 CONTINUE
00409
00410
00411
00412 IF( ICOMPQ.EQ.1 ) THEN
00413 IF( IUPLO.EQ.1 ) THEN
00414 IQ( N ) = 1
00415 ELSE
00416 IQ( N ) = 0
00417 END IF
00418 END IF
00419
00420
00421
00422
00423 IF( ( IUPLO.EQ.2 ) .AND. ( ICOMPQ.EQ.2 ) )
00424 $ CALL DLASR( 'L', 'V', 'B', N, N, WORK( 1 ), WORK( N ), U, LDU )
00425
00426 RETURN
00427
00428
00429
00430 END