LAPACK 3.3.0

cbdt01.f

Go to the documentation of this file.
00001       SUBROUTINE CBDT01( M, N, KD, A, LDA, Q, LDQ, D, E, PT, LDPT, WORK,
00002      $                   RWORK, RESID )
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            KD, LDA, LDPT, LDQ, M, N
00010       REAL               RESID
00011 *     ..
00012 *     .. Array Arguments ..
00013       REAL               D( * ), E( * ), RWORK( * )
00014       COMPLEX            A( LDA, * ), PT( LDPT, * ), Q( LDQ, * ),
00015      $                   WORK( * )
00016 *     ..
00017 *
00018 *  Purpose
00019 *  =======
00020 *
00021 *  CBDT01 reconstructs a general matrix A from its bidiagonal form
00022 *     A = Q * B * P'
00023 *  where Q (m by min(m,n)) and P' (min(m,n) by n) are unitary
00024 *  matrices and B is bidiagonal.
00025 *
00026 *  The test ratio to test the reduction is
00027 *     RESID = norm( A - Q * B * PT ) / ( n * norm(A) * EPS )
00028 *  where PT = P' and EPS is the machine precision.
00029 *
00030 *  Arguments
00031 *  =========
00032 *
00033 *  M       (input) INTEGER
00034 *          The number of rows of the matrices A and Q.
00035 *
00036 *  N       (input) INTEGER
00037 *          The number of columns of the matrices A and P'.
00038 *
00039 *  KD      (input) INTEGER
00040 *          If KD = 0, B is diagonal and the array E is not referenced.
00041 *          If KD = 1, the reduction was performed by xGEBRD; B is upper
00042 *          bidiagonal if M >= N, and lower bidiagonal if M < N.
00043 *          If KD = -1, the reduction was performed by xGBBRD; B is
00044 *          always upper bidiagonal.
00045 *
00046 *  A       (input) COMPLEX array, dimension (LDA,N)
00047 *          The m by n matrix A.
00048 *
00049 *  LDA     (input) INTEGER
00050 *          The leading dimension of the array A.  LDA >= max(1,M).
00051 *
00052 *  Q       (input) COMPLEX array, dimension (LDQ,N)
00053 *          The m by min(m,n) unitary matrix Q in the reduction
00054 *          A = Q * B * P'.
00055 *
00056 *  LDQ     (input) INTEGER
00057 *          The leading dimension of the array Q.  LDQ >= max(1,M).
00058 *
00059 *  D       (input) REAL array, dimension (min(M,N))
00060 *          The diagonal elements of the bidiagonal matrix B.
00061 *
00062 *  E       (input) REAL array, dimension (min(M,N)-1)
00063 *          The superdiagonal elements of the bidiagonal matrix B if
00064 *          m >= n, or the subdiagonal elements of B if m < n.
00065 *
00066 *  PT      (input) COMPLEX array, dimension (LDPT,N)
00067 *          The min(m,n) by n unitary matrix P' in the reduction
00068 *          A = Q * B * P'.
00069 *
00070 *  LDPT    (input) INTEGER
00071 *          The leading dimension of the array PT.
00072 *          LDPT >= max(1,min(M,N)).
00073 *
00074 *  WORK    (workspace) COMPLEX array, dimension (M+N)
00075 *
00076 *  RWORK   (workspace) REAL array, dimension (M)
00077 *
00078 *  RESID   (output) REAL
00079 *          The test ratio:  norm(A - Q * B * P') / ( n * norm(A) * EPS )
00080 *
00081 *  =====================================================================
00082 *
00083 *     .. Parameters ..
00084       REAL               ZERO, ONE
00085       PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0 )
00086 *     ..
00087 *     .. Local Scalars ..
00088       INTEGER            I, J
00089       REAL               ANORM, EPS
00090 *     ..
00091 *     .. External Functions ..
00092       REAL               CLANGE, SCASUM, SLAMCH
00093       EXTERNAL           CLANGE, SCASUM, SLAMCH
00094 *     ..
00095 *     .. External Subroutines ..
00096       EXTERNAL           CCOPY, CGEMV
00097 *     ..
00098 *     .. Intrinsic Functions ..
00099       INTRINSIC          CMPLX, MAX, MIN, REAL
00100 *     ..
00101 *     .. Executable Statements ..
00102 *
00103 *     Quick return if possible
00104 *
00105       IF( M.LE.0 .OR. N.LE.0 ) THEN
00106          RESID = ZERO
00107          RETURN
00108       END IF
00109 *
00110 *     Compute A - Q * B * P' one column at a time.
00111 *
00112       RESID = ZERO
00113       IF( KD.NE.0 ) THEN
00114 *
00115 *        B is bidiagonal.
00116 *
00117          IF( KD.NE.0 .AND. M.GE.N ) THEN
00118 *
00119 *           B is upper bidiagonal and M >= N.
00120 *
00121             DO 20 J = 1, N
00122                CALL CCOPY( M, A( 1, J ), 1, WORK, 1 )
00123                DO 10 I = 1, N - 1
00124                   WORK( M+I ) = D( I )*PT( I, J ) + E( I )*PT( I+1, J )
00125    10          CONTINUE
00126                WORK( M+N ) = D( N )*PT( N, J )
00127                CALL CGEMV( 'No transpose', M, N, -CMPLX( ONE ), Q, LDQ,
00128      $                     WORK( M+1 ), 1, CMPLX( ONE ), WORK, 1 )
00129                RESID = MAX( RESID, SCASUM( M, WORK, 1 ) )
00130    20       CONTINUE
00131          ELSE IF( KD.LT.0 ) THEN
00132 *
00133 *           B is upper bidiagonal and M < N.
00134 *
00135             DO 40 J = 1, N
00136                CALL CCOPY( M, A( 1, J ), 1, WORK, 1 )
00137                DO 30 I = 1, M - 1
00138                   WORK( M+I ) = D( I )*PT( I, J ) + E( I )*PT( I+1, J )
00139    30          CONTINUE
00140                WORK( M+M ) = D( M )*PT( M, J )
00141                CALL CGEMV( 'No transpose', M, M, -CMPLX( ONE ), Q, LDQ,
00142      $                     WORK( M+1 ), 1, CMPLX( ONE ), WORK, 1 )
00143                RESID = MAX( RESID, SCASUM( M, WORK, 1 ) )
00144    40       CONTINUE
00145          ELSE
00146 *
00147 *           B is lower bidiagonal.
00148 *
00149             DO 60 J = 1, N
00150                CALL CCOPY( M, A( 1, J ), 1, WORK, 1 )
00151                WORK( M+1 ) = D( 1 )*PT( 1, J )
00152                DO 50 I = 2, M
00153                   WORK( M+I ) = E( I-1 )*PT( I-1, J ) +
00154      $                          D( I )*PT( I, J )
00155    50          CONTINUE
00156                CALL CGEMV( 'No transpose', M, M, -CMPLX( ONE ), Q, LDQ,
00157      $                     WORK( M+1 ), 1, CMPLX( ONE ), WORK, 1 )
00158                RESID = MAX( RESID, SCASUM( M, WORK, 1 ) )
00159    60       CONTINUE
00160          END IF
00161       ELSE
00162 *
00163 *        B is diagonal.
00164 *
00165          IF( M.GE.N ) THEN
00166             DO 80 J = 1, N
00167                CALL CCOPY( M, A( 1, J ), 1, WORK, 1 )
00168                DO 70 I = 1, N
00169                   WORK( M+I ) = D( I )*PT( I, J )
00170    70          CONTINUE
00171                CALL CGEMV( 'No transpose', M, N, -CMPLX( ONE ), Q, LDQ,
00172      $                     WORK( M+1 ), 1, CMPLX( ONE ), WORK, 1 )
00173                RESID = MAX( RESID, SCASUM( M, WORK, 1 ) )
00174    80       CONTINUE
00175          ELSE
00176             DO 100 J = 1, N
00177                CALL CCOPY( M, A( 1, J ), 1, WORK, 1 )
00178                DO 90 I = 1, M
00179                   WORK( M+I ) = D( I )*PT( I, J )
00180    90          CONTINUE
00181                CALL CGEMV( 'No transpose', M, M, -CMPLX( ONE ), Q, LDQ,
00182      $                     WORK( M+1 ), 1, CMPLX( ONE ), WORK, 1 )
00183                RESID = MAX( RESID, SCASUM( M, WORK, 1 ) )
00184   100       CONTINUE
00185          END IF
00186       END IF
00187 *
00188 *     Compute norm(A - Q * B * P') / ( n * norm(A) * EPS )
00189 *
00190       ANORM = CLANGE( '1', M, N, A, LDA, RWORK )
00191       EPS = SLAMCH( 'Precision' )
00192 *
00193       IF( ANORM.LE.ZERO ) THEN
00194          IF( RESID.NE.ZERO )
00195      $      RESID = ONE / EPS
00196       ELSE
00197          IF( ANORM.GE.RESID ) THEN
00198             RESID = ( RESID / ANORM ) / ( REAL( N )*EPS )
00199          ELSE
00200             IF( ANORM.LT.ONE ) THEN
00201                RESID = ( MIN( RESID, REAL( N )*ANORM ) / ANORM ) /
00202      $                 ( REAL( N )*EPS )
00203             ELSE
00204                RESID = MIN( RESID / ANORM, REAL( N ) ) /
00205      $                 ( REAL( N )*EPS )
00206             END IF
00207          END IF
00208       END IF
00209 *
00210       RETURN
00211 *
00212 *     End of CBDT01
00213 *
00214       END
 All Files Functions