1*> \brief \b CHETD2 reduces a Hermitian matrix to real symmetric tridiagonal form by an unitary similarity transformation (unblocked algorithm). 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8*> \htmlonly 9*> Download CHETD2 + dependencies 10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/chetd2.f"> 11*> [TGZ]</a> 12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/chetd2.f"> 13*> [ZIP]</a> 14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/chetd2.f"> 15*> [TXT]</a> 16*> \endhtmlonly 17* 18* Definition: 19* =========== 20* 21* SUBROUTINE CHETD2( UPLO, N, A, LDA, D, E, TAU, INFO ) 22* 23* .. Scalar Arguments .. 24* CHARACTER UPLO 25* INTEGER INFO, LDA, N 26* .. 27* .. Array Arguments .. 28* REAL D( * ), E( * ) 29* COMPLEX A( LDA, * ), TAU( * ) 30* .. 31* 32* 33*> \par Purpose: 34* ============= 35*> 36*> \verbatim 37*> 38*> CHETD2 reduces a complex Hermitian matrix A to real symmetric 39*> tridiagonal form T by a unitary similarity transformation: 40*> Q**H * A * Q = T. 41*> \endverbatim 42* 43* Arguments: 44* ========== 45* 46*> \param[in] UPLO 47*> \verbatim 48*> UPLO is CHARACTER*1 49*> Specifies whether the upper or lower triangular part of the 50*> Hermitian matrix A is stored: 51*> = 'U': Upper triangular 52*> = 'L': Lower triangular 53*> \endverbatim 54*> 55*> \param[in] N 56*> \verbatim 57*> N is INTEGER 58*> The order of the matrix A. N >= 0. 59*> \endverbatim 60*> 61*> \param[in,out] A 62*> \verbatim 63*> A is COMPLEX array, dimension (LDA,N) 64*> On entry, the Hermitian matrix A. If UPLO = 'U', the leading 65*> n-by-n upper triangular part of A contains the upper 66*> triangular part of the matrix A, and the strictly lower 67*> triangular part of A is not referenced. If UPLO = 'L', the 68*> leading n-by-n lower triangular part of A contains the lower 69*> triangular part of the matrix A, and the strictly upper 70*> triangular part of A is not referenced. 71*> On exit, if UPLO = 'U', the diagonal and first superdiagonal 72*> of A are overwritten by the corresponding elements of the 73*> tridiagonal matrix T, and the elements above the first 74*> superdiagonal, with the array TAU, represent the unitary 75*> matrix Q as a product of elementary reflectors; if UPLO 76*> = 'L', the diagonal and first subdiagonal of A are over- 77*> written by the corresponding elements of the tridiagonal 78*> matrix T, and the elements below the first subdiagonal, with 79*> the array TAU, represent the unitary matrix Q as a product 80*> of elementary reflectors. See Further Details. 81*> \endverbatim 82*> 83*> \param[in] LDA 84*> \verbatim 85*> LDA is INTEGER 86*> The leading dimension of the array A. LDA >= max(1,N). 87*> \endverbatim 88*> 89*> \param[out] D 90*> \verbatim 91*> D is REAL array, dimension (N) 92*> The diagonal elements of the tridiagonal matrix T: 93*> D(i) = A(i,i). 94*> \endverbatim 95*> 96*> \param[out] E 97*> \verbatim 98*> E is REAL array, dimension (N-1) 99*> The off-diagonal elements of the tridiagonal matrix T: 100*> E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'. 101*> \endverbatim 102*> 103*> \param[out] TAU 104*> \verbatim 105*> TAU is COMPLEX array, dimension (N-1) 106*> The scalar factors of the elementary reflectors (see Further 107*> Details). 108*> \endverbatim 109*> 110*> \param[out] INFO 111*> \verbatim 112*> INFO is INTEGER 113*> = 0: successful exit 114*> < 0: if INFO = -i, the i-th argument had an illegal value. 115*> \endverbatim 116* 117* Authors: 118* ======== 119* 120*> \author Univ. of Tennessee 121*> \author Univ. of California Berkeley 122*> \author Univ. of Colorado Denver 123*> \author NAG Ltd. 124* 125*> \date September 2012 126* 127*> \ingroup complexHEcomputational 128* 129*> \par Further Details: 130* ===================== 131*> 132*> \verbatim 133*> 134*> If UPLO = 'U', the matrix Q is represented as a product of elementary 135*> reflectors 136*> 137*> Q = H(n-1) . . . H(2) H(1). 138*> 139*> Each H(i) has the form 140*> 141*> H(i) = I - tau * v * v**H 142*> 143*> where tau is a complex scalar, and v is a complex vector with 144*> v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in 145*> A(1:i-1,i+1), and tau in TAU(i). 146*> 147*> If UPLO = 'L', the matrix Q is represented as a product of elementary 148*> reflectors 149*> 150*> Q = H(1) H(2) . . . H(n-1). 151*> 152*> Each H(i) has the form 153*> 154*> H(i) = I - tau * v * v**H 155*> 156*> where tau is a complex scalar, and v is a complex vector with 157*> v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i), 158*> and tau in TAU(i). 159*> 160*> The contents of A on exit are illustrated by the following examples 161*> with n = 5: 162*> 163*> if UPLO = 'U': if UPLO = 'L': 164*> 165*> ( d e v2 v3 v4 ) ( d ) 166*> ( d e v3 v4 ) ( e d ) 167*> ( d e v4 ) ( v1 e d ) 168*> ( d e ) ( v1 v2 e d ) 169*> ( d ) ( v1 v2 v3 e d ) 170*> 171*> where d and e denote diagonal and off-diagonal elements of T, and vi 172*> denotes an element of the vector defining H(i). 173*> \endverbatim 174*> 175* ===================================================================== 176 SUBROUTINE CHETD2( UPLO, N, A, LDA, D, E, TAU, INFO ) 177* 178* -- LAPACK computational routine (version 3.4.2) -- 179* -- LAPACK is a software package provided by Univ. of Tennessee, -- 180* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 181* September 2012 182* 183* .. Scalar Arguments .. 184 CHARACTER UPLO 185 INTEGER INFO, LDA, N 186* .. 187* .. Array Arguments .. 188 REAL D( * ), E( * ) 189 COMPLEX A( LDA, * ), TAU( * ) 190* .. 191* 192* ===================================================================== 193* 194* .. Parameters .. 195 COMPLEX ONE, ZERO, HALF 196 PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ), 197 $ ZERO = ( 0.0E+0, 0.0E+0 ), 198 $ HALF = ( 0.5E+0, 0.0E+0 ) ) 199* .. 200* .. Local Scalars .. 201 LOGICAL UPPER 202 INTEGER I 203 COMPLEX ALPHA, TAUI 204* .. 205* .. External Subroutines .. 206 EXTERNAL CAXPY, CHEMV, CHER2, CLARFG, XERBLA 207* .. 208* .. External Functions .. 209 LOGICAL LSAME 210 COMPLEX CDOTC 211 EXTERNAL LSAME, CDOTC 212* .. 213* .. Intrinsic Functions .. 214 INTRINSIC MAX, MIN, REAL 215* .. 216* .. Executable Statements .. 217* 218* Test the input parameters 219* 220 INFO = 0 221 UPPER = LSAME( UPLO, 'U' ) 222 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN 223 INFO = -1 224 ELSE IF( N.LT.0 ) THEN 225 INFO = -2 226 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN 227 INFO = -4 228 END IF 229 IF( INFO.NE.0 ) THEN 230 CALL XERBLA( 'CHETD2', -INFO ) 231 RETURN 232 END IF 233* 234* Quick return if possible 235* 236 IF( N.LE.0 ) 237 $ RETURN 238* 239 IF( UPPER ) THEN 240* 241* Reduce the upper triangle of A 242* 243 A( N, N ) = REAL( A( N, N ) ) 244 DO 10 I = N - 1, 1, -1 245* 246* Generate elementary reflector H(i) = I - tau * v * v**H 247* to annihilate A(1:i-1,i+1) 248* 249 ALPHA = A( I, I+1 ) 250 CALL CLARFG( I, ALPHA, A( 1, I+1 ), 1, TAUI ) 251 E( I ) = ALPHA 252* 253 IF( TAUI.NE.ZERO ) THEN 254* 255* Apply H(i) from both sides to A(1:i,1:i) 256* 257 A( I, I+1 ) = ONE 258* 259* Compute x := tau * A * v storing x in TAU(1:i) 260* 261 CALL CHEMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, ZERO, 262 $ TAU, 1 ) 263* 264* Compute w := x - 1/2 * tau * (x**H * v) * v 265* 266 ALPHA = -HALF*TAUI*CDOTC( I, TAU, 1, A( 1, I+1 ), 1 ) 267 CALL CAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 ) 268* 269* Apply the transformation as a rank-2 update: 270* A := A - v * w**H - w * v**H 271* 272 CALL CHER2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A, 273 $ LDA ) 274* 275 ELSE 276 A( I, I ) = REAL( A( I, I ) ) 277 END IF 278 A( I, I+1 ) = E( I ) 279 D( I+1 ) = A( I+1, I+1 ) 280 TAU( I ) = TAUI 281 10 CONTINUE 282 D( 1 ) = A( 1, 1 ) 283 ELSE 284* 285* Reduce the lower triangle of A 286* 287 A( 1, 1 ) = REAL( A( 1, 1 ) ) 288 DO 20 I = 1, N - 1 289* 290* Generate elementary reflector H(i) = I - tau * v * v**H 291* to annihilate A(i+2:n,i) 292* 293 ALPHA = A( I+1, I ) 294 CALL CLARFG( N-I, ALPHA, A( MIN( I+2, N ), I ), 1, TAUI ) 295 E( I ) = ALPHA 296* 297 IF( TAUI.NE.ZERO ) THEN 298* 299* Apply H(i) from both sides to A(i+1:n,i+1:n) 300* 301 A( I+1, I ) = ONE 302* 303* Compute x := tau * A * v storing y in TAU(i:n-1) 304* 305 CALL CHEMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA, 306 $ A( I+1, I ), 1, ZERO, TAU( I ), 1 ) 307* 308* Compute w := x - 1/2 * tau * (x**H * v) * v 309* 310 ALPHA = -HALF*TAUI*CDOTC( N-I, TAU( I ), 1, A( I+1, I ), 311 $ 1 ) 312 CALL CAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 ) 313* 314* Apply the transformation as a rank-2 update: 315* A := A - v * w**H - w * v**H 316* 317 CALL CHER2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), 1, 318 $ A( I+1, I+1 ), LDA ) 319* 320 ELSE 321 A( I+1, I+1 ) = REAL( A( I+1, I+1 ) ) 322 END IF 323 A( I+1, I ) = E( I ) 324 D( I ) = A( I, I ) 325 TAU( I ) = TAUI 326 20 CONTINUE 327 D( N ) = A( N, N ) 328 END IF 329* 330 RETURN 331* 332* End of CHETD2 333* 334 END 335