⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsyevd.f

📁 网络带宽测试工具
💻 F
📖 第 1 页 / 共 5 页
字号:
      SUBROUTINE DSYEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK,     $                   LIWORK, INFO )! ----------------------------------------------------------------------      Use      numerics      Implicit None**  -- LAPACK driver routine (version 2.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     September 30, 1994**     .. Scalar Arguments ..      CHARACTER          JOBZ, UPLO      INTEGER            INFO, LDA, LIWORK, LWORK, N*     ..*     .. Array Arguments ..      INTEGER            IWORK( * )      Real(l_)   A( LDA, * ), W( * ), WORK( * )*     ..**  Purpose*  =======**  DSYEVD computes all eigenvalues and, optionally, eigenvectors of a*  real symmetric matrix A. If eigenvectors are desired, it uses a*  divide and conquer algorithm.**  The divide and conquer algorithm makes very mild assumptions about*  floating point arithmetic. It will work on machines with a guard*  digit in add/subtract, or on those binary machines without guard*  digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*  Cray-2. It could conceivably fail on hexadecimal or decimal machines*  without guard digits, but we know of none.**  Arguments*  =========**  JOBZ    (input) CHARACTER*1*          = 'N':  Compute eigenvalues only;*          = 'V':  Compute eigenvalues and eigenvectors.**  UPLO    (input) CHARACTER*1*          = 'U':  Upper triangle of A is stored;*          = 'L':  Lower triangle of A is stored.**  N       (input) INTEGER*          The order of the matrix A.  N >= 0.**  A       (input/output) Real(l_) array, dimension (LDA, N)*          On entry, the symmetric matrix A.  If UPLO = 'U', the*          leading N-by-N upper triangular part of A contains the*          upper triangular part of the matrix A.  If UPLO = 'L',*          the leading N-by-N lower triangular part of A contains*          the lower triangular part of the matrix A.*          On exit, if JOBZ = 'V', then if INFO = 0, A contains the*          orthonormal eigenvectors of the matrix A.*          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')*          or the upper triangle (if UPLO='U') of A, including the*          diagonal, is destroyed.**  LDA     (input) INTEGER*          The leading dimension of the array A.  LDA >= max(1,N).**  W       (output) Real(l_) array, dimension (N)*          If INFO = 0, the eigenvalues in ascending order.**  WORK    (workspace/output) Real(l_) array,*                                         dimension (LWORK)*          On exit, if LWORK > 0, WORK(1) returns the optimal LWORK.**  LWORK   (input) INTEGER*          The dimension of the array WORK.*          If N <= 1,               LWORK must be at least 1.*          If JOBZ = 'N' and N > 1, LWORK must be at least 2*N+1.*          If JOBZ = 'V' and N > 1, LWORK must be at least*                         1 + 5*N + 2*N*lg N + 3*N**2,*                         where lg( N ) = smallest integer k such*                                         that 2**k >= N.**  IWORK   (workspace/output) INTEGER array, dimension (LIWORK)*          On exit, if LIWORK > 0, IWORK(1) returns the optimal LIWORK.**  LIWORK  (input) INTEGER*          The dimension of the array IWORK.*          If N <= 1,                LIWORK must be at least 1.*          If JOBZ  = 'N' and N > 1, LIWORK must be at least 1.*          If JOBZ  = 'V' and N > 1, LIWORK must be at least 2 + 5*N.**  INFO    (output) INTEGER*          = 0:  successful exit*          < 0:  if INFO = -i, the i-th argument had an illegal value*          > 0:  if INFO = i, the algorithm failed to converge; i*                off-diagonal elements of an intermediate tridiagonal*                form did not converge to zero.**  =====================================================================**     .. Parameters ..      Real(l_)   ZERO, ONE, TWO      PARAMETER          ( ZERO = 0.0_l_, ONE = 1.0_l_, TWO = 2.0_l_ )*     ..*     .. Local Scalars ..*      LOGICAL            LOWER, WANTZ      INTEGER            IINFO, INDE, INDTAU, INDWK2, INDWRK, ISCALE,     $                   LGN, LIOPT, LIWMIN, LLWORK, LLWRK2, LOPT, LWMIN      Real(l_)   ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,     $                   SMLNUM*     ..*     .. External Functions ..      LOGICAL            LSAME      Real(l_)   DLAMCH, DLANSY      EXTERNAL           LSAME, DLAMCH, DLANSY*     ..*     .. External Subroutines ..      EXTERNAL           DLACPY, DLASCL, DORMTR, DSCAL, DSTEDC, DSTERF,     $                   DSYTRD, XERBLA*     ..*     .. Intrinsic Functions ..      INTRINSIC          DBLE, INT, LOG, MAX, SQRT*     ..*     .. Executable Statements ..**     Test the input parameters.*      WANTZ = LSAME( JOBZ, 'V' )      LOWER = LSAME( UPLO, 'L' )*      INFO = 0      IF( N.LE.1 ) THEN         LGN = 0         LIWMIN = 1         LWMIN = 1         LOPT = LWMIN         LIOPT = LIWMIN      ELSE         LGN = INT( LOG( DBLE( N ) ) / LOG( TWO ) )         IF( 2**LGN.LT.N )     $      LGN = LGN + 1         IF( 2**LGN.LT.N )     $      LGN = LGN + 1         IF( WANTZ ) THEN            LIWMIN = 2 + 5*N            LWMIN = 1 + 5*N + 2*N*LGN + 3*N**2         ELSE            LIWMIN = 1            LWMIN = 2*N + 1         END IF         LOPT = LWMIN         LIOPT = LIWMIN      END IF      IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN         INFO = -1      ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN         INFO = -2      ELSE IF( N.LT.0 ) THEN         INFO = -3      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN         INFO = -5      ELSE IF( LWORK.LT.LWMIN ) THEN         INFO = -8      ELSE IF( LIWORK.LT.LIWMIN ) THEN         INFO = -10      END IF*      IF( INFO.NE.0 ) THEN         CALL XERBLA( 'DSYEVD ', -INFO )         GO TO 10      END IF**     Quick return if possible*      IF( N.EQ.0 )     $   GO TO 10*      IF( N.EQ.1 ) THEN         W( 1 ) = A( 1, 1 )         IF( WANTZ )     $      A( 1, 1 ) = ONE         GO TO 10      END IF**     Get machine constants.*      SAFMIN = DLAMCH( 'Safe minimum' )      EPS = DLAMCH( 'Precision' )      SMLNUM = SAFMIN / EPS      BIGNUM = ONE / SMLNUM      RMIN = SQRT( SMLNUM )      RMAX = SQRT( BIGNUM )**     Scale matrix to allowable range, if necessary.*      ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )      ISCALE = 0      IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN         ISCALE = 1         SIGMA = RMIN / ANRM      ELSE IF( ANRM.GT.RMAX ) THEN         ISCALE = 1         SIGMA = RMAX / ANRM      END IF      IF( ISCALE.EQ.1 )     $   CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )**     Call DSYTRD to reduce symmetric matrix to tridiagonal form.*      INDE = 1      INDTAU = INDE + N      INDWRK = INDTAU + N      LLWORK = LWORK - INDWRK + 1      INDWK2 = INDWRK + N*N      LLWRK2 = LWORK - INDWK2 + 1*      CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),     $             WORK( INDWRK ), LLWORK, IINFO )      LOPT = 2*N + WORK( INDWRK )**     For eigenvalues only, call DSTERF.  For eigenvectors, first call*     DSTEDC to generate the eigenvector matrix, WORK(INDWRK), of the*     tridiagonal matrix, then call DORMTR to multiply it by the*     Householder transformations stored in A.*      IF( .NOT.WANTZ ) THEN         CALL DSTERF( N, W, WORK( INDE ), INFO )      ELSE         CALL DSTEDC( 'I', N, W, WORK( INDE ), WORK( INDWRK ), N,     $                WORK( INDWK2 ), LLWRK2, IWORK, LIWORK, INFO )         CALL DORMTR( 'L', UPLO, 'N', N, N, A, LDA, WORK( INDTAU ),     $                WORK( INDWRK ), N, WORK( INDWK2 ), LLWRK2, IINFO )         CALL DLACPY( 'A', N, N, WORK( INDWRK ), N, A, LDA )         LOPT = MAX( LOPT, 1+5*N+2*N*LGN+3*N**2 )      END IF**     If matrix was scaled, then rescale eigenvalues appropriately.*      IF( ISCALE.EQ.1 )     $   CALL DSCAL( N, ONE / SIGMA, W, 1 )   10 CONTINUE      IF( LWORK.GT.0 )     $   WORK( 1 ) = LOPT      IF( LIWORK.GT.0 )     $   IWORK( 1 ) = LIOPT      RETURN**     End of DSYEVD*      END! ----------------------------------------------------------------------      SUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB )! ----------------------------------------------------------------------      Use      numerics      Implicit None**  -- LAPACK auxiliary routine (version 2.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     February 29, 1992**     .. Scalar Arguments ..      CHARACTER          UPLO      INTEGER            LDA, LDB, M, N*     ..*     .. Array Arguments ..      Real(l_)   A( LDA, * ), B( LDB, * )*     ..**  Purpose*  =======**  DLACPY copies all or part of a two-dimensional matrix A to another*  matrix B.**  Arguments*  =========**  UPLO    (input) CHARACTER*1*          Specifies the part of the matrix A to be copied to B.*          = 'U':      Upper triangular part*          = 'L':      Lower triangular part*          Otherwise:  All of the matrix A**  M       (input) INTEGER*          The number of rows of the matrix A.  M >= 0.**  N       (input) INTEGER*          The number of columns of the matrix A.  N >= 0.**  A       (input) Real(l_) array, dimension (LDA,N)*          The m by n matrix A.  If UPLO = 'U', only the upper triangle*          or trapezoid is accessed; if UPLO = 'L', only the lower*          triangle or trapezoid is accessed.**  LDA     (input) INTEGER*          The leading dimension of the array A.  LDA >= max(1,M).**  B       (output) Real(l_) array, dimension (LDB,N)*          On exit, B = A in the locations specified by UPLO.**  LDB     (input) INTEGER*          The leading dimension of the array B.  LDB >= max(1,M).**  =====================================================================**     .. Local Scalars ..      INTEGER            I, J*     ..*     .. External Functions ..      LOGICAL            LSAME      EXTERNAL           LSAME*     ..*     .. Intrinsic Functions ..      INTRINSIC          MIN*     ..*     .. Executable Statements ..*      IF( LSAME( UPLO, 'U' ) ) THEN         DO 20 J = 1, N            DO 10 I = 1, MIN( J, M )               B( I, J ) = A( I, J )   10       CONTINUE   20    CONTINUE      ELSE IF( LSAME( UPLO, 'L' ) ) THEN         DO 40 J = 1, N            DO 30 I = J, M               B( I, J ) = A( I, J )   30       CONTINUE   40    CONTINUE      ELSE         DO 60 J = 1, N            DO 50 I = 1, M               B( I, J ) = A( I, J )   50       CONTINUE   60    CONTINUE      END IF      RETURN**     End of DLACPY*      END! ----------------------------------------------------------------------      SUBROUTINE DLAE2( A, B, C, RT1, RT2 )! ----------------------------------------------------------------------      Use      numerics      Implicit None**  -- LAPACK auxiliary routine (version 2.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     October 31, 1992**     .. Scalar Arguments ..      Real(l_)   A, B, C, RT1, RT2*     ..**  Purpose*  =======**  DLAE2  computes the eigenvalues of a 2-by-2 symmetric matrix*     [  A   B  ]*     [  B   C  ].*  On return, RT1 is the eigenvalue of larger absolute value, and RT2*  is the eigenvalue of smaller absolute value.**  Arguments*  =========**  A       (input) Real(l_)*          The (1,1) element of the 2-by-2 matrix.**  B       (input) Real(l_)*          The (1,2) and (2,1) elements of the 2-by-2 matrix.**  C       (input) Real(l_)*          The (2,2) element of the 2-by-2 matrix.**  RT1     (output) Real(l_)*          The eigenvalue of larger absolute value.**  RT2     (output) Real(l_)*          The eigenvalue of smaller absolute value.**  Further Details*  ===============**  RT1 is accurate to a few ulps barring over/underflow.**  RT2 may be inaccurate if there is massive cancellation in the*  determinant A*C-B*B; higher precision or correctly rounded or*  correctly truncated arithmetic would be needed to compute RT2*  accurately in all cases.**  Overflow is possible only if RT1 is within a factor of 5 of overflow.*  Underflow is harmless if the input data is 0 or exceeds*     underflow_threshold / macheps.** =====================================================================**     .. Parameters ..      Real(l_)   ONE      PARAMETER          ( ONE = 1.0_l_ )      Real(l_)   TWO      PARAMETER          ( TWO = 2.0_l_ )      Real(l_)   ZERO      PARAMETER          ( ZERO = 0.0_l_ )      Real(l_)   HALF      PARAMETER          ( HALF = 0.5_l_ )*     ..*     .. Local Scalars ..      Real(l_)   AB, ACMN, ACMX, ADF, DF, RT, SM, TB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -