LAPACK 3.3.0

sdisna.f

Go to the documentation of this file.
00001       SUBROUTINE SDISNA( JOB, M, N, D, SEP, INFO )
00002 *
00003 *  -- LAPACK routine (version 3.2) --
00004 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00005 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00006 *     November 2006
00007 *
00008 *     .. Scalar Arguments ..
00009       CHARACTER          JOB
00010       INTEGER            INFO, M, N
00011 *     ..
00012 *     .. Array Arguments ..
00013       REAL               D( * ), SEP( * )
00014 *     ..
00015 *
00016 *  Purpose
00017 *  =======
00018 *
00019 *  SDISNA computes the reciprocal condition numbers for the eigenvectors
00020 *  of a real symmetric or complex Hermitian matrix or for the left or
00021 *  right singular vectors of a general m-by-n matrix. The reciprocal
00022 *  condition number is the 'gap' between the corresponding eigenvalue or
00023 *  singular value and the nearest other one.
00024 *
00025 *  The bound on the error, measured by angle in radians, in the I-th
00026 *  computed vector is given by
00027 *
00028 *         SLAMCH( 'E' ) * ( ANORM / SEP( I ) )
00029 *
00030 *  where ANORM = 2-norm(A) = max( abs( D(j) ) ).  SEP(I) is not allowed
00031 *  to be smaller than SLAMCH( 'E' )*ANORM in order to limit the size of
00032 *  the error bound.
00033 *
00034 *  SDISNA may also be used to compute error bounds for eigenvectors of
00035 *  the generalized symmetric definite eigenproblem.
00036 *
00037 *  Arguments
00038 *  =========
00039 *
00040 *  JOB     (input) CHARACTER*1
00041 *          Specifies for which problem the reciprocal condition numbers
00042 *          should be computed:
00043 *          = 'E':  the eigenvectors of a symmetric/Hermitian matrix;
00044 *          = 'L':  the left singular vectors of a general matrix;
00045 *          = 'R':  the right singular vectors of a general matrix.
00046 *
00047 *  M       (input) INTEGER
00048 *          The number of rows of the matrix. M >= 0.
00049 *
00050 *  N       (input) INTEGER
00051 *          If JOB = 'L' or 'R', the number of columns of the matrix,
00052 *          in which case N >= 0. Ignored if JOB = 'E'.
00053 *
00054 *  D       (input) REAL array, dimension (M) if JOB = 'E'
00055 *                              dimension (min(M,N)) if JOB = 'L' or 'R'
00056 *          The eigenvalues (if JOB = 'E') or singular values (if JOB =
00057 *          'L' or 'R') of the matrix, in either increasing or decreasing
00058 *          order. If singular values, they must be non-negative.
00059 *
00060 *  SEP     (output) REAL array, dimension (M) if JOB = 'E'
00061 *                               dimension (min(M,N)) if JOB = 'L' or 'R'
00062 *          The reciprocal condition numbers of the vectors.
00063 *
00064 *  INFO    (output) INTEGER
00065 *          = 0:  successful exit.
00066 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00067 *
00068 *  =====================================================================
00069 *
00070 *     .. Parameters ..
00071       REAL               ZERO
00072       PARAMETER          ( ZERO = 0.0E+0 )
00073 *     ..
00074 *     .. Local Scalars ..
00075       LOGICAL            DECR, EIGEN, INCR, LEFT, RIGHT, SING
00076       INTEGER            I, K
00077       REAL               ANORM, EPS, NEWGAP, OLDGAP, SAFMIN, THRESH
00078 *     ..
00079 *     .. External Functions ..
00080       LOGICAL            LSAME
00081       REAL               SLAMCH
00082       EXTERNAL           LSAME, SLAMCH
00083 *     ..
00084 *     .. Intrinsic Functions ..
00085       INTRINSIC          ABS, MAX, MIN
00086 *     ..
00087 *     .. External Subroutines ..
00088       EXTERNAL           XERBLA
00089 *     ..
00090 *     .. Executable Statements ..
00091 *
00092 *     Test the input arguments
00093 *
00094       INFO = 0
00095       EIGEN = LSAME( JOB, 'E' )
00096       LEFT = LSAME( JOB, 'L' )
00097       RIGHT = LSAME( JOB, 'R' )
00098       SING = LEFT .OR. RIGHT
00099       IF( EIGEN ) THEN
00100          K = M
00101       ELSE IF( SING ) THEN
00102          K = MIN( M, N )
00103       END IF
00104       IF( .NOT.EIGEN .AND. .NOT.SING ) THEN
00105          INFO = -1
00106       ELSE IF( M.LT.0 ) THEN
00107          INFO = -2
00108       ELSE IF( K.LT.0 ) THEN
00109          INFO = -3
00110       ELSE
00111          INCR = .TRUE.
00112          DECR = .TRUE.
00113          DO 10 I = 1, K - 1
00114             IF( INCR )
00115      $         INCR = INCR .AND. D( I ).LE.D( I+1 )
00116             IF( DECR )
00117      $         DECR = DECR .AND. D( I ).GE.D( I+1 )
00118    10    CONTINUE
00119          IF( SING .AND. K.GT.0 ) THEN
00120             IF( INCR )
00121      $         INCR = INCR .AND. ZERO.LE.D( 1 )
00122             IF( DECR )
00123      $         DECR = DECR .AND. D( K ).GE.ZERO
00124          END IF
00125          IF( .NOT.( INCR .OR. DECR ) )
00126      $      INFO = -4
00127       END IF
00128       IF( INFO.NE.0 ) THEN
00129          CALL XERBLA( 'SDISNA', -INFO )
00130          RETURN
00131       END IF
00132 *
00133 *     Quick return if possible
00134 *
00135       IF( K.EQ.0 )
00136      $   RETURN
00137 *
00138 *     Compute reciprocal condition numbers
00139 *
00140       IF( K.EQ.1 ) THEN
00141          SEP( 1 ) = SLAMCH( 'O' )
00142       ELSE
00143          OLDGAP = ABS( D( 2 )-D( 1 ) )
00144          SEP( 1 ) = OLDGAP
00145          DO 20 I = 2, K - 1
00146             NEWGAP = ABS( D( I+1 )-D( I ) )
00147             SEP( I ) = MIN( OLDGAP, NEWGAP )
00148             OLDGAP = NEWGAP
00149    20    CONTINUE
00150          SEP( K ) = OLDGAP
00151       END IF
00152       IF( SING ) THEN
00153          IF( ( LEFT .AND. M.GT.N ) .OR. ( RIGHT .AND. M.LT.N ) ) THEN
00154             IF( INCR )
00155      $         SEP( 1 ) = MIN( SEP( 1 ), D( 1 ) )
00156             IF( DECR )
00157      $         SEP( K ) = MIN( SEP( K ), D( K ) )
00158          END IF
00159       END IF
00160 *
00161 *     Ensure that reciprocal condition numbers are not less than
00162 *     threshold, in order to limit the size of the error bound
00163 *
00164       EPS = SLAMCH( 'E' )
00165       SAFMIN = SLAMCH( 'S' )
00166       ANORM = MAX( ABS( D( 1 ) ), ABS( D( K ) ) )
00167       IF( ANORM.EQ.ZERO ) THEN
00168          THRESH = EPS
00169       ELSE
00170          THRESH = MAX( EPS*ANORM, SAFMIN )
00171       END IF
00172       DO 30 I = 1, K
00173          SEP( I ) = MAX( SEP( I ), THRESH )
00174    30 CONTINUE
00175 *
00176       RETURN
00177 *
00178 *     End of SDISNA
00179 *
00180       END
 All Files Functions