1*> \brief \b CSTEDC 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8*> \htmlonly 9*> Download CSTEDC + dependencies 10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cstedc.f"> 11*> [TGZ]</a> 12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cstedc.f"> 13*> [ZIP]</a> 14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cstedc.f"> 15*> [TXT]</a> 16*> \endhtmlonly 17* 18* Definition: 19* =========== 20* 21* SUBROUTINE CSTEDC( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, RWORK, 22* LRWORK, IWORK, LIWORK, INFO ) 23* 24* .. Scalar Arguments .. 25* CHARACTER COMPZ 26* INTEGER INFO, LDZ, LIWORK, LRWORK, LWORK, N 27* .. 28* .. Array Arguments .. 29* INTEGER IWORK( * ) 30* REAL D( * ), E( * ), RWORK( * ) 31* COMPLEX WORK( * ), Z( LDZ, * ) 32* .. 33* 34* 35*> \par Purpose: 36* ============= 37*> 38*> \verbatim 39*> 40*> CSTEDC computes all eigenvalues and, optionally, eigenvectors of a 41*> symmetric tridiagonal matrix using the divide and conquer method. 42*> The eigenvectors of a full or band complex Hermitian matrix can also 43*> be found if CHETRD or CHPTRD or CHBTRD has been used to reduce this 44*> matrix to tridiagonal form. 45*> 46*> This code makes very mild assumptions about floating point 47*> arithmetic. It will work on machines with a guard digit in 48*> add/subtract, or on those binary machines without guard digits 49*> which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2. 50*> It could conceivably fail on hexadecimal or decimal machines 51*> without guard digits, but we know of none. See SLAED3 for details. 52*> \endverbatim 53* 54* Arguments: 55* ========== 56* 57*> \param[in] COMPZ 58*> \verbatim 59*> COMPZ is CHARACTER*1 60*> = 'N': Compute eigenvalues only. 61*> = 'I': Compute eigenvectors of tridiagonal matrix also. 62*> = 'V': Compute eigenvectors of original Hermitian matrix 63*> also. On entry, Z contains the unitary matrix used 64*> to reduce the original matrix to tridiagonal form. 65*> \endverbatim 66*> 67*> \param[in] N 68*> \verbatim 69*> N is INTEGER 70*> The dimension of the symmetric tridiagonal matrix. N >= 0. 71*> \endverbatim 72*> 73*> \param[in,out] D 74*> \verbatim 75*> D is REAL array, dimension (N) 76*> On entry, the diagonal elements of the tridiagonal matrix. 77*> On exit, if INFO = 0, the eigenvalues in ascending order. 78*> \endverbatim 79*> 80*> \param[in,out] E 81*> \verbatim 82*> E is REAL array, dimension (N-1) 83*> On entry, the subdiagonal elements of the tridiagonal matrix. 84*> On exit, E has been destroyed. 85*> \endverbatim 86*> 87*> \param[in,out] Z 88*> \verbatim 89*> Z is COMPLEX array, dimension (LDZ,N) 90*> On entry, if COMPZ = 'V', then Z contains the unitary 91*> matrix used in the reduction to tridiagonal form. 92*> On exit, if INFO = 0, then if COMPZ = 'V', Z contains the 93*> orthonormal eigenvectors of the original Hermitian matrix, 94*> and if COMPZ = 'I', Z contains the orthonormal eigenvectors 95*> of the symmetric tridiagonal matrix. 96*> If COMPZ = 'N', then Z is not referenced. 97*> \endverbatim 98*> 99*> \param[in] LDZ 100*> \verbatim 101*> LDZ is INTEGER 102*> The leading dimension of the array Z. LDZ >= 1. 103*> If eigenvectors are desired, then LDZ >= max(1,N). 104*> \endverbatim 105*> 106*> \param[out] WORK 107*> \verbatim 108*> WORK is COMPLEX array, dimension (MAX(1,LWORK)) 109*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 110*> \endverbatim 111*> 112*> \param[in] LWORK 113*> \verbatim 114*> LWORK is INTEGER 115*> The dimension of the array WORK. 116*> If COMPZ = 'N' or 'I', or N <= 1, LWORK must be at least 1. 117*> If COMPZ = 'V' and N > 1, LWORK must be at least N*N. 118*> Note that for COMPZ = 'V', then if N is less than or 119*> equal to the minimum divide size, usually 25, then LWORK need 120*> only be 1. 121*> 122*> If LWORK = -1, then a workspace query is assumed; the routine 123*> only calculates the optimal sizes of the WORK, RWORK and 124*> IWORK arrays, returns these values as the first entries of 125*> the WORK, RWORK and IWORK arrays, and no error message 126*> related to LWORK or LRWORK or LIWORK is issued by XERBLA. 127*> \endverbatim 128*> 129*> \param[out] RWORK 130*> \verbatim 131*> RWORK is REAL array, dimension (MAX(1,LRWORK)) 132*> On exit, if INFO = 0, RWORK(1) returns the optimal LRWORK. 133*> \endverbatim 134*> 135*> \param[in] LRWORK 136*> \verbatim 137*> LRWORK is INTEGER 138*> The dimension of the array RWORK. 139*> If COMPZ = 'N' or N <= 1, LRWORK must be at least 1. 140*> If COMPZ = 'V' and N > 1, LRWORK must be at least 141*> 1 + 3*N + 2*N*lg N + 4*N**2 , 142*> where lg( N ) = smallest integer k such 143*> that 2**k >= N. 144*> If COMPZ = 'I' and N > 1, LRWORK must be at least 145*> 1 + 4*N + 2*N**2 . 146*> Note that for COMPZ = 'I' or 'V', then if N is less than or 147*> equal to the minimum divide size, usually 25, then LRWORK 148*> need only be max(1,2*(N-1)). 149*> 150*> If LRWORK = -1, then a workspace query is assumed; the 151*> routine only calculates the optimal sizes of the WORK, RWORK 152*> and IWORK arrays, returns these values as the first entries 153*> of the WORK, RWORK and IWORK arrays, and no error message 154*> related to LWORK or LRWORK or LIWORK is issued by XERBLA. 155*> \endverbatim 156*> 157*> \param[out] IWORK 158*> \verbatim 159*> IWORK is INTEGER array, dimension (MAX(1,LIWORK)) 160*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK. 161*> \endverbatim 162*> 163*> \param[in] LIWORK 164*> \verbatim 165*> LIWORK is INTEGER 166*> The dimension of the array IWORK. 167*> If COMPZ = 'N' or N <= 1, LIWORK must be at least 1. 168*> If COMPZ = 'V' or N > 1, LIWORK must be at least 169*> 6 + 6*N + 5*N*lg N. 170*> If COMPZ = 'I' or N > 1, LIWORK must be at least 171*> 3 + 5*N . 172*> Note that for COMPZ = 'I' or 'V', then if N is less than or 173*> equal to the minimum divide size, usually 25, then LIWORK 174*> need only be 1. 175*> 176*> If LIWORK = -1, then a workspace query is assumed; the 177*> routine only calculates the optimal sizes of the WORK, RWORK 178*> and IWORK arrays, returns these values as the first entries 179*> of the WORK, RWORK and IWORK arrays, and no error message 180*> related to LWORK or LRWORK or LIWORK is issued by XERBLA. 181*> \endverbatim 182*> 183*> \param[out] INFO 184*> \verbatim 185*> INFO is INTEGER 186*> = 0: successful exit. 187*> < 0: if INFO = -i, the i-th argument had an illegal value. 188*> > 0: The algorithm failed to compute an eigenvalue while 189*> working on the submatrix lying in rows and columns 190*> INFO/(N+1) through mod(INFO,N+1). 191*> \endverbatim 192* 193* Authors: 194* ======== 195* 196*> \author Univ. of Tennessee 197*> \author Univ. of California Berkeley 198*> \author Univ. of Colorado Denver 199*> \author NAG Ltd. 200* 201*> \ingroup complexOTHERcomputational 202* 203*> \par Contributors: 204* ================== 205*> 206*> Jeff Rutter, Computer Science Division, University of California 207*> at Berkeley, USA 208* 209* ===================================================================== 210 SUBROUTINE CSTEDC( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, RWORK, 211 $ LRWORK, IWORK, LIWORK, INFO ) 212* 213* -- LAPACK computational routine -- 214* -- LAPACK is a software package provided by Univ. of Tennessee, -- 215* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 216* 217* .. Scalar Arguments .. 218 CHARACTER COMPZ 219 INTEGER INFO, LDZ, LIWORK, LRWORK, LWORK, N 220* .. 221* .. Array Arguments .. 222 INTEGER IWORK( * ) 223 REAL D( * ), E( * ), RWORK( * ) 224 COMPLEX WORK( * ), Z( LDZ, * ) 225* .. 226* 227* ===================================================================== 228* 229* .. Parameters .. 230 REAL ZERO, ONE, TWO 231 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0 ) 232* .. 233* .. Local Scalars .. 234 LOGICAL LQUERY 235 INTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN, LL, 236 $ LRWMIN, LWMIN, M, SMLSIZ, START 237 REAL EPS, ORGNRM, P, TINY 238* .. 239* .. External Functions .. 240 LOGICAL LSAME 241 INTEGER ILAENV 242 REAL SLAMCH, SLANST 243 EXTERNAL ILAENV, LSAME, SLAMCH, SLANST 244* .. 245* .. External Subroutines .. 246 EXTERNAL XERBLA, CLACPY, CLACRM, CLAED0, CSTEQR, CSWAP, 247 $ SLASCL, SLASET, SSTEDC, SSTEQR, SSTERF 248* .. 249* .. Intrinsic Functions .. 250 INTRINSIC ABS, INT, LOG, MAX, MOD, REAL, SQRT 251* .. 252* .. Executable Statements .. 253* 254* Test the input parameters. 255* 256 INFO = 0 257 LQUERY = ( LWORK.EQ.-1 .OR. LRWORK.EQ.-1 .OR. LIWORK.EQ.-1 ) 258* 259 IF( LSAME( COMPZ, 'N' ) ) THEN 260 ICOMPZ = 0 261 ELSE IF( LSAME( COMPZ, 'V' ) ) THEN 262 ICOMPZ = 1 263 ELSE IF( LSAME( COMPZ, 'I' ) ) THEN 264 ICOMPZ = 2 265 ELSE 266 ICOMPZ = -1 267 END IF 268 IF( ICOMPZ.LT.0 ) THEN 269 INFO = -1 270 ELSE IF( N.LT.0 ) THEN 271 INFO = -2 272 ELSE IF( ( LDZ.LT.1 ) .OR. 273 $ ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1, N ) ) ) THEN 274 INFO = -6 275 END IF 276* 277 IF( INFO.EQ.0 ) THEN 278* 279* Compute the workspace requirements 280* 281 SMLSIZ = ILAENV( 9, 'CSTEDC', ' ', 0, 0, 0, 0 ) 282 IF( N.LE.1 .OR. ICOMPZ.EQ.0 ) THEN 283 LWMIN = 1 284 LIWMIN = 1 285 LRWMIN = 1 286 ELSE IF( N.LE.SMLSIZ ) THEN 287 LWMIN = 1 288 LIWMIN = 1 289 LRWMIN = 2*( N - 1 ) 290 ELSE IF( ICOMPZ.EQ.1 ) THEN 291 LGN = INT( LOG( REAL( N ) ) / LOG( TWO ) ) 292 IF( 2**LGN.LT.N ) 293 $ LGN = LGN + 1 294 IF( 2**LGN.LT.N ) 295 $ LGN = LGN + 1 296 LWMIN = N*N 297 LRWMIN = 1 + 3*N + 2*N*LGN + 4*N**2 298 LIWMIN = 6 + 6*N + 5*N*LGN 299 ELSE IF( ICOMPZ.EQ.2 ) THEN 300 LWMIN = 1 301 LRWMIN = 1 + 4*N + 2*N**2 302 LIWMIN = 3 + 5*N 303 END IF 304 WORK( 1 ) = LWMIN 305 RWORK( 1 ) = LRWMIN 306 IWORK( 1 ) = LIWMIN 307* 308 IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN 309 INFO = -8 310 ELSE IF( LRWORK.LT.LRWMIN .AND. .NOT.LQUERY ) THEN 311 INFO = -10 312 ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THEN 313 INFO = -12 314 END IF 315 END IF 316* 317 IF( INFO.NE.0 ) THEN 318 CALL XERBLA( 'CSTEDC', -INFO ) 319 RETURN 320 ELSE IF( LQUERY ) THEN 321 RETURN 322 END IF 323* 324* Quick return if possible 325* 326 IF( N.EQ.0 ) 327 $ RETURN 328 IF( N.EQ.1 ) THEN 329 IF( ICOMPZ.NE.0 ) 330 $ Z( 1, 1 ) = ONE 331 RETURN 332 END IF 333* 334* If the following conditional clause is removed, then the routine 335* will use the Divide and Conquer routine to compute only the 336* eigenvalues, which requires (3N + 3N**2) real workspace and 337* (2 + 5N + 2N lg(N)) integer workspace. 338* Since on many architectures SSTERF is much faster than any other 339* algorithm for finding eigenvalues only, it is used here 340* as the default. If the conditional clause is removed, then 341* information on the size of workspace needs to be changed. 342* 343* If COMPZ = 'N', use SSTERF to compute the eigenvalues. 344* 345 IF( ICOMPZ.EQ.0 ) THEN 346 CALL SSTERF( N, D, E, INFO ) 347 GO TO 70 348 END IF 349* 350* If N is smaller than the minimum divide size (SMLSIZ+1), then 351* solve the problem with another solver. 352* 353 IF( N.LE.SMLSIZ ) THEN 354* 355 CALL CSTEQR( COMPZ, N, D, E, Z, LDZ, RWORK, INFO ) 356* 357 ELSE 358* 359* If COMPZ = 'I', we simply call SSTEDC instead. 360* 361 IF( ICOMPZ.EQ.2 ) THEN 362 CALL SLASET( 'Full', N, N, ZERO, ONE, RWORK, N ) 363 LL = N*N + 1 364 CALL SSTEDC( 'I', N, D, E, RWORK, N, 365 $ RWORK( LL ), LRWORK-LL+1, IWORK, LIWORK, INFO ) 366 DO 20 J = 1, N 367 DO 10 I = 1, N 368 Z( I, J ) = RWORK( ( J-1 )*N+I ) 369 10 CONTINUE 370 20 CONTINUE 371 GO TO 70 372 END IF 373* 374* From now on, only option left to be handled is COMPZ = 'V', 375* i.e. ICOMPZ = 1. 376* 377* Scale. 378* 379 ORGNRM = SLANST( 'M', N, D, E ) 380 IF( ORGNRM.EQ.ZERO ) 381 $ GO TO 70 382* 383 EPS = SLAMCH( 'Epsilon' ) 384* 385 START = 1 386* 387* while ( START <= N ) 388* 389 30 CONTINUE 390 IF( START.LE.N ) THEN 391* 392* Let FINISH be the position of the next subdiagonal entry 393* such that E( FINISH ) <= TINY or FINISH = N if no such 394* subdiagonal exists. The matrix identified by the elements 395* between START and FINISH constitutes an independent 396* sub-problem. 397* 398 FINISH = START 399 40 CONTINUE 400 IF( FINISH.LT.N ) THEN 401 TINY = EPS*SQRT( ABS( D( FINISH ) ) )* 402 $ SQRT( ABS( D( FINISH+1 ) ) ) 403 IF( ABS( E( FINISH ) ).GT.TINY ) THEN 404 FINISH = FINISH + 1 405 GO TO 40 406 END IF 407 END IF 408* 409* (Sub) Problem determined. Compute its size and solve it. 410* 411 M = FINISH - START + 1 412 IF( M.GT.SMLSIZ ) THEN 413* 414* Scale. 415* 416 ORGNRM = SLANST( 'M', M, D( START ), E( START ) ) 417 CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, M, 1, D( START ), M, 418 $ INFO ) 419 CALL SLASCL( 'G', 0, 0, ORGNRM, ONE, M-1, 1, E( START ), 420 $ M-1, INFO ) 421* 422 CALL CLAED0( N, M, D( START ), E( START ), Z( 1, START ), 423 $ LDZ, WORK, N, RWORK, IWORK, INFO ) 424 IF( INFO.GT.0 ) THEN 425 INFO = ( INFO / ( M+1 )+START-1 )*( N+1 ) + 426 $ MOD( INFO, ( M+1 ) ) + START - 1 427 GO TO 70 428 END IF 429* 430* Scale back. 431* 432 CALL SLASCL( 'G', 0, 0, ONE, ORGNRM, M, 1, D( START ), M, 433 $ INFO ) 434* 435 ELSE 436 CALL SSTEQR( 'I', M, D( START ), E( START ), RWORK, M, 437 $ RWORK( M*M+1 ), INFO ) 438 CALL CLACRM( N, M, Z( 1, START ), LDZ, RWORK, M, WORK, N, 439 $ RWORK( M*M+1 ) ) 440 CALL CLACPY( 'A', N, M, WORK, N, Z( 1, START ), LDZ ) 441 IF( INFO.GT.0 ) THEN 442 INFO = START*( N+1 ) + FINISH 443 GO TO 70 444 END IF 445 END IF 446* 447 START = FINISH + 1 448 GO TO 30 449 END IF 450* 451* endwhile 452* 453* 454* Use Selection Sort to minimize swaps of eigenvectors 455* 456 DO 60 II = 2, N 457 I = II - 1 458 K = I 459 P = D( I ) 460 DO 50 J = II, N 461 IF( D( J ).LT.P ) THEN 462 K = J 463 P = D( J ) 464 END IF 465 50 CONTINUE 466 IF( K.NE.I ) THEN 467 D( K ) = D( I ) 468 D( I ) = P 469 CALL CSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 ) 470 END IF 471 60 CONTINUE 472 END IF 473* 474 70 CONTINUE 475 WORK( 1 ) = LWMIN 476 RWORK( 1 ) = LRWMIN 477 IWORK( 1 ) = LIWMIN 478* 479 RETURN 480* 481* End of CSTEDC 482* 483 END 484