LAPACK 3.3.0

cstt22.f

Go to the documentation of this file.
```00001       SUBROUTINE CSTT22( N, M, KBAND, AD, AE, SD, SE, U, LDU, WORK,
00002      \$                   LDWORK, RWORK, RESULT )
00003 *
00004 *  -- LAPACK test routine (version 3.1) --
00005 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00006 *     November 2006
00007 *
00008 *     .. Scalar Arguments ..
00009       INTEGER            KBAND, LDU, LDWORK, M, N
00010 *     ..
00011 *     .. Array Arguments ..
00012       REAL               AD( * ), AE( * ), RESULT( 2 ), RWORK( * ),
00013      \$                   SD( * ), SE( * )
00014       COMPLEX            U( LDU, * ), WORK( LDWORK, * )
00015 *     ..
00016 *
00017 *  Purpose
00018 *  =======
00019 *
00020 *  CSTT22  checks a set of M eigenvalues and eigenvectors,
00021 *
00022 *      A U = U S
00023 *
00024 *  where A is Hermitian tridiagonal, the columns of U are unitary,
00025 *  and S is diagonal (if KBAND=0) or Hermitian tridiagonal (if KBAND=1).
00026 *  Two tests are performed:
00027 *
00028 *     RESULT(1) = | U* A U - S | / ( |A| m ulp )
00029 *
00030 *     RESULT(2) = | I - U*U | / ( m ulp )
00031 *
00032 *  Arguments
00033 *  =========
00034 *
00035 *  N       (input) INTEGER
00036 *          The size of the matrix.  If it is zero, CSTT22 does nothing.
00037 *          It must be at least zero.
00038 *
00039 *  M       (input) INTEGER
00040 *          The number of eigenpairs to check.  If it is zero, CSTT22
00041 *          does nothing.  It must be at least zero.
00042 *
00043 *  KBAND   (input) INTEGER
00044 *          The bandwidth of the matrix S.  It may only be zero or one.
00045 *          If zero, then S is diagonal, and SE is not referenced.  If
00046 *          one, then S is Hermitian tri-diagonal.
00047 *
00048 *  AD      (input) REAL array, dimension (N)
00049 *          The diagonal of the original (unfactored) matrix A.  A is
00050 *          assumed to be Hermitian tridiagonal.
00051 *
00052 *  AE      (input) REAL array, dimension (N)
00053 *          The off-diagonal of the original (unfactored) matrix A.  A
00054 *          is assumed to be Hermitian tridiagonal.  AE(1) is ignored,
00055 *          AE(2) is the (1,2) and (2,1) element, etc.
00056 *
00057 *  SD      (input) REAL array, dimension (N)
00058 *          The diagonal of the (Hermitian tri-) diagonal matrix S.
00059 *
00060 *  SE      (input) REAL array, dimension (N)
00061 *          The off-diagonal of the (Hermitian tri-) diagonal matrix S.
00062 *          Not referenced if KBSND=0.  If KBAND=1, then AE(1) is
00063 *          ignored, SE(2) is the (1,2) and (2,1) element, etc.
00064 *
00065 *  U       (input) REAL array, dimension (LDU, N)
00066 *          The unitary matrix in the decomposition.
00067 *
00068 *  LDU     (input) INTEGER
00069 *          The leading dimension of U.  LDU must be at least N.
00070 *
00071 *  WORK    (workspace) COMPLEX array, dimension (LDWORK, M+1)
00072 *
00073 *  LDWORK  (input) INTEGER
00074 *          The leading dimension of WORK.  LDWORK must be at least
00075 *          max(1,M).
00076 *
00077 *  RWORK   (workspace) REAL array, dimension (N)
00078 *
00079 *  RESULT  (output) REAL array, dimension (2)
00080 *          The values computed by the two tests described above.  The
00081 *          values are currently limited to 1/ulp, to avoid overflow.
00082 *
00083 *  =====================================================================
00084 *
00085 *     .. Parameters ..
00086       REAL               ZERO, ONE
00087       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
00088       COMPLEX            CZERO, CONE
00089       PARAMETER          ( CZERO = ( 0.0E+0, 0.0E+0 ),
00090      \$                   CONE = ( 1.0E+0, 0.0E+0 ) )
00091 *     ..
00092 *     .. Local Scalars ..
00093       INTEGER            I, J, K
00094       REAL               ANORM, ULP, UNFL, WNORM
00095       COMPLEX            AUKJ
00096 *     ..
00097 *     .. External Functions ..
00098       REAL               CLANGE, CLANSY, SLAMCH
00099       EXTERNAL           CLANGE, CLANSY, SLAMCH
00100 *     ..
00101 *     .. External Subroutines ..
00102       EXTERNAL           CGEMM
00103 *     ..
00104 *     .. Intrinsic Functions ..
00105       INTRINSIC          ABS, MAX, MIN, REAL
00106 *     ..
00107 *     .. Executable Statements ..
00108 *
00109       RESULT( 1 ) = ZERO
00110       RESULT( 2 ) = ZERO
00111       IF( N.LE.0 .OR. M.LE.0 )
00112      \$   RETURN
00113 *
00114       UNFL = SLAMCH( 'Safe minimum' )
00115       ULP = SLAMCH( 'Epsilon' )
00116 *
00117 *     Do Test 1
00118 *
00119 *     Compute the 1-norm of A.
00120 *
00121       IF( N.GT.1 ) THEN
00122          ANORM = ABS( AD( 1 ) ) + ABS( AE( 1 ) )
00123          DO 10 J = 2, N - 1
00124             ANORM = MAX( ANORM, ABS( AD( J ) )+ABS( AE( J ) )+
00125      \$              ABS( AE( J-1 ) ) )
00126    10    CONTINUE
00127          ANORM = MAX( ANORM, ABS( AD( N ) )+ABS( AE( N-1 ) ) )
00128       ELSE
00129          ANORM = ABS( AD( 1 ) )
00130       END IF
00131       ANORM = MAX( ANORM, UNFL )
00132 *
00133 *     Norm of U*AU - S
00134 *
00135       DO 40 I = 1, M
00136          DO 30 J = 1, M
00137             WORK( I, J ) = CZERO
00138             DO 20 K = 1, N
00139                AUKJ = AD( K )*U( K, J )
00140                IF( K.NE.N )
00141      \$            AUKJ = AUKJ + AE( K )*U( K+1, J )
00142                IF( K.NE.1 )
00143      \$            AUKJ = AUKJ + AE( K-1 )*U( K-1, J )
00144                WORK( I, J ) = WORK( I, J ) + U( K, I )*AUKJ
00145    20       CONTINUE
00146    30    CONTINUE
00147          WORK( I, I ) = WORK( I, I ) - SD( I )
00148          IF( KBAND.EQ.1 ) THEN
00149             IF( I.NE.1 )
00150      \$         WORK( I, I-1 ) = WORK( I, I-1 ) - SE( I-1 )
00151             IF( I.NE.N )
00152      \$         WORK( I, I+1 ) = WORK( I, I+1 ) - SE( I )
00153          END IF
00154    40 CONTINUE
00155 *
00156       WNORM = CLANSY( '1', 'L', M, WORK, M, RWORK )
00157 *
00158       IF( ANORM.GT.WNORM ) THEN
00159          RESULT( 1 ) = ( WNORM / ANORM ) / ( M*ULP )
00160       ELSE
00161          IF( ANORM.LT.ONE ) THEN
00162             RESULT( 1 ) = ( MIN( WNORM, M*ANORM ) / ANORM ) / ( M*ULP )
00163          ELSE
00164             RESULT( 1 ) = MIN( WNORM / ANORM, REAL( M ) ) / ( M*ULP )
00165          END IF
00166       END IF
00167 *
00168 *     Do Test 2
00169 *
00170 *     Compute  U*U - I
00171 *
00172       CALL CGEMM( 'T', 'N', M, M, N, CONE, U, LDU, U, LDU, CZERO, WORK,
00173      \$            M )
00174 *
00175       DO 50 J = 1, M
00176          WORK( J, J ) = WORK( J, J ) - ONE
00177    50 CONTINUE
00178 *
00179       RESULT( 2 ) = MIN( REAL( M ), CLANGE( '1', M, M, WORK, M,
00180      \$              RWORK ) ) / ( M*ULP )
00181 *
00182       RETURN
00183 *
00184 *     End of CSTT22
00185 *
00186       END
```