1       SUBROUTINE DSBT21( UPLO, N, KA, KS, A, LDA, D, E, U, LDU, WORK,
  2      $                   RESULT )
  3 *
  4 *  -- LAPACK test routine (version 3.1) --
  5 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
  6 *     November 2006
  7 *
  8 *     .. Scalar Arguments ..
  9       CHARACTER          UPLO
 10       INTEGER            KA, KS, LDA, LDU, N
 11 *     ..
 12 *     .. Array Arguments ..
 13       DOUBLE PRECISION   A( LDA, * ), D( * ), E( * ), RESULT2 ),
 14      $                   U( LDU, * ), WORK( * )
 15 *     ..
 16 *
 17 *  Purpose
 18 *  =======
 19 *
 20 *  DSBT21  generally checks a decomposition of the form
 21 *
 22 *          A = U S U'
 23 *
 24 *  where ' means transpose, A is symmetric banded, U is
 25 *  orthogonal, and S is diagonal (if KS=0) or symmetric
 26 *  tridiagonal (if KS=1).
 27 *
 28 *  Specifically:
 29 *
 30 *          RESULT(1) = | A - U S U' | / ( |A| n ulp ) *and*
 31 *          RESULT(2) = | I - UU' | / ( n ulp )
 32 *
 33 *  Arguments
 34 *  =========
 35 *
 36 *  UPLO    (input) CHARACTER
 37 *          If UPLO='U', the upper triangle of A and V will be used and
 38 *          the (strictly) lower triangle will not be referenced.
 39 *          If UPLO='L', the lower triangle of A and V will be used and
 40 *          the (strictly) upper triangle will not be referenced.
 41 *
 42 *  N       (input) INTEGER
 43 *          The size of the matrix.  If it is zero, DSBT21 does nothing.
 44 *          It must be at least zero.
 45 *
 46 *  KA      (input) INTEGER
 47 *          The bandwidth of the matrix A.  It must be at least zero.  If
 48 *          it is larger than N-1, then max( 0, N-1 ) will be used.
 49 *
 50 *  KS      (input) INTEGER
 51 *          The bandwidth of the matrix S.  It may only be zero or one.
 52 *          If zero, then S is diagonal, and E is not referenced.  If
 53 *          one, then S is symmetric tri-diagonal.
 54 *
 55 *  A       (input) DOUBLE PRECISION array, dimension (LDA, N)
 56 *          The original (unfactored) matrix.  It is assumed to be
 57 *          symmetric, and only the upper (UPLO='U') or only the lower
 58 *          (UPLO='L') will be referenced.
 59 *
 60 *  LDA     (input) INTEGER
 61 *          The leading dimension of A.  It must be at least 1
 62 *          and at least min( KA, N-1 ).
 63 *
 64 *  D       (input) DOUBLE PRECISION array, dimension (N)
 65 *          The diagonal of the (symmetric tri-) diagonal matrix S.
 66 *
 67 *  E       (input) DOUBLE PRECISION array, dimension (N-1)
 68 *          The off-diagonal of the (symmetric tri-) diagonal matrix S.
 69 *          E(1) is the (1,2) and (2,1) element, E(2) is the (2,3) and
 70 *          (3,2) element, etc.
 71 *          Not referenced if KS=0.
 72 *
 73 *  U       (input) DOUBLE PRECISION array, dimension (LDU, N)
 74 *          The orthogonal matrix in the decomposition, expressed as a
 75 *          dense matrix (i.e., not as a product of Householder
 76 *          transformations, Givens transformations, etc.)
 77 *
 78 *  LDU     (input) INTEGER
 79 *          The leading dimension of U.  LDU must be at least N and
 80 *          at least 1.
 81 *
 82 *  WORK    (workspace) DOUBLE PRECISION array, dimension (N**2+N)
 83 *
 84 *  RESULT  (output) DOUBLE PRECISION array, dimension (2)
 85 *          The values computed by the two tests described above.  The
 86 *          values are currently limited to 1/ulp, to avoid overflow.
 87 *
 88 *  =====================================================================
 89 *
 90 *     .. Parameters ..
 91       DOUBLE PRECISION   ZERO, ONE
 92       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
 93 *     ..
 94 *     .. Local Scalars ..
 95       LOGICAL            LOWER
 96       CHARACTER          CUPLO
 97       INTEGER            IKA, J, JC, JR, LW
 98       DOUBLE PRECISION   ANORM, ULP, UNFL, WNORM
 99 *     ..
100 *     .. External Functions ..
101       LOGICAL            LSAME
102       DOUBLE PRECISION   DLAMCH, DLANGE, DLANSB, DLANSP
103       EXTERNAL           LSAME, DLAMCH, DLANGE, DLANSB, DLANSP
104 *     ..
105 *     .. External Subroutines ..
106       EXTERNAL           DGEMM, DSPR, DSPR2
107 *     ..
108 *     .. Intrinsic Functions ..
109       INTRINSIC          DBLEMAXMIN
110 *     ..
111 *     .. Executable Statements ..
112 *
113 *     Constants
114 *
115       RESULT1 ) = ZERO
116       RESULT2 ) = ZERO
117       IF( N.LE.0 )
118      $   RETURN
119 *
120       IKA = MAX0MIN( N-1, KA ) )
121       LW = ( N*( N+1 ) ) / 2
122 *
123       IF( LSAME( UPLO, 'U' ) ) THEN
124          LOWER = .FALSE.
125          CUPLO = 'U'
126       ELSE
127          LOWER = .TRUE.
128          CUPLO = 'L'
129       END IF
130 *
131       UNFL = DLAMCH( 'Safe minimum' )
132       ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
133 *
134 *     Some Error Checks
135 *
136 *     Do Test 1
137 *
138 *     Norm of A:
139 *
140       ANORM = MAX( DLANSB( '1', CUPLO, N, IKA, A, LDA, WORK ), UNFL )
141 *
142 *     Compute error matrix:    Error = A - U S U'
143 *
144 *     Copy A from SB to SP storage format.
145 *
146       J = 0
147       DO 50 JC = 1, N
148          IF( LOWER ) THEN
149             DO 10 JR = 1MIN( IKA+1, N+1-JC )
150                J = J + 1
151                WORK( J ) = A( JR, JC )
152    10       CONTINUE
153             DO 20 JR = IKA + 2, N + 1 - JC
154                J = J + 1
155                WORK( J ) = ZERO
156    20       CONTINUE
157          ELSE
158             DO 30 JR = IKA + 2, JC
159                J = J + 1
160                WORK( J ) = ZERO
161    30       CONTINUE
162             DO 40 JR = MIN( IKA, JC-1 ), 0-1
163                J = J + 1
164                WORK( J ) = A( IKA+1-JR, JC )
165    40       CONTINUE
166          END IF
167    50 CONTINUE
168 *
169       DO 60 J = 1, N
170          CALL DSPR( CUPLO, N, -D( J ), U( 1, J ), 1, WORK )
171    60 CONTINUE
172 *
173       IF( N.GT.1 .AND. KS.EQ.1 ) THEN
174          DO 70 J = 1, N - 1
175             CALL DSPR2( CUPLO, N, -E( J ), U( 1, J ), 1, U( 1, J+1 ), 1,
176      $                  WORK )
177    70    CONTINUE
178       END IF
179       WNORM = DLANSP( '1', CUPLO, N, WORK, WORK( LW+1 ) )
180 *
181       IF( ANORM.GT.WNORM ) THEN
182          RESULT1 ) = ( WNORM / ANORM ) / ( N*ULP )
183       ELSE
184          IF( ANORM.LT.ONE ) THEN
185             RESULT1 ) = ( MIN( WNORM, N*ANORM ) / ANORM ) / ( N*ULP )
186          ELSE
187             RESULT1 ) = MIN( WNORM / ANORM, DBLE( N ) ) / ( N*ULP )
188          END IF
189       END IF
190 *
191 *     Do Test 2
192 *
193 *     Compute  UU' - I
194 *
195       CALL DGEMM( 'N''C', N, N, N, ONE, U, LDU, U, LDU, ZERO, WORK,
196      $            N )
197 *
198       DO 80 J = 1, N
199          WORK( ( N+1 )*( J-1 )+1 ) = WORK( ( N+1 )*( J-1 )+1 ) - ONE
200    80 CONTINUE
201 *
202       RESULT2 ) = MIN( DLANGE( '1', N, N, WORK, N, WORK( N**2+1 ) ),
203      $              DBLE( N ) ) / ( N*ULP )
204 *
205       RETURN
206 *
207 *     End of DSBT21
208 *
209       END