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

📄 lapacksubs.f

📁 利用离散偶极近似方法计算散射体的电磁场。 DDA 方法
💻 F
📖 第 1 页 / 共 5 页
字号:
      SUBROUTINE SGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,     $                  LDVR, WORK, LWORK, INFO )**  -- LAPACK driver routine (version 3.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     December 8, 1999**     .. Scalar Arguments ..      CHARACTER          JOBVL, JOBVR      INTEGER            INFO, LDA, LDVL, LDVR, LWORK, N*     ..*     .. Array Arguments ..      REAL               A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),     $                   WI( * ), WORK( * ), WR( * )*     ..**  Purpose*  =======**  SGEEV computes for an N-by-N real nonsymmetric matrix A, the*  eigenvalues and, optionally, the left and/or right eigenvectors.**  The right eigenvector v(j) of A satisfies*                   A * v(j) = lambda(j) * v(j)*  where lambda(j) is its eigenvalue.*  The left eigenvector u(j) of A satisfies*                u(j)**H * A = lambda(j) * u(j)**H*  where u(j)**H denotes the conjugate transpose of u(j).**  The computed eigenvectors are normalized to have Euclidean norm*  equal to 1 and largest component real.**  Arguments*  =========**  JOBVL   (input) CHARACTER*1*          = 'N': left eigenvectors of A are not computed;*          = 'V': left eigenvectors of A are computed.**  JOBVR   (input) CHARACTER*1*          = 'N': right eigenvectors of A are not computed;*          = 'V': right eigenvectors of A are computed.**  N       (input) INTEGER*          The order of the matrix A. N >= 0.**  A       (input/output) REAL array, dimension (LDA,N)*          On entry, the N-by-N matrix A.*          On exit, A has been overwritten.**  LDA     (input) INTEGER*          The leading dimension of the array A.  LDA >= max(1,N).**  WR      (output) REAL array, dimension (N)*  WI      (output) REAL array, dimension (N)*          WR and WI contain the real and imaginary parts,*          respectively, of the computed eigenvalues.  Complex*          conjugate pairs of eigenvalues appear consecutively*          with the eigenvalue having the positive imaginary part*          first.**  VL      (output) REAL array, dimension (LDVL,N)*          If JOBVL = 'V', the left eigenvectors u(j) are stored one*          after another in the columns of VL, in the same order*          as their eigenvalues.*          If JOBVL = 'N', VL is not referenced.*          If the j-th eigenvalue is real, then u(j) = VL(:,j),*          the j-th column of VL.*          If the j-th and (j+1)-st eigenvalues form a complex*          conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and*          u(j+1) = VL(:,j) - i*VL(:,j+1).**  LDVL    (input) INTEGER*          The leading dimension of the array VL.  LDVL >= 1; if*          JOBVL = 'V', LDVL >= N.**  VR      (output) REAL array, dimension (LDVR,N)*          If JOBVR = 'V', the right eigenvectors v(j) are stored one*          after another in the columns of VR, in the same order*          as their eigenvalues.*          If JOBVR = 'N', VR is not referenced.*          If the j-th eigenvalue is real, then v(j) = VR(:,j),*          the j-th column of VR.*          If the j-th and (j+1)-st eigenvalues form a complex*          conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and*          v(j+1) = VR(:,j) - i*VR(:,j+1).**  LDVR    (input) INTEGER*          The leading dimension of the array VR.  LDVR >= 1; if*          JOBVR = 'V', LDVR >= N.**  WORK    (workspace/output) REAL array, dimension (LWORK)*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.**  LWORK   (input) INTEGER*          The dimension of the array WORK.  LWORK >= max(1,3*N), and*          if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N.  For good*          performance, LWORK must generally be larger.**          If LWORK = -1, then a workspace query is assumed; the routine*          only calculates the optimal size of the WORK array, returns*          this value as the first entry of the WORK array, and no error*          message related to LWORK is issued by XERBLA.**  INFO    (output) INTEGER*          = 0:  successful exit*          < 0:  if INFO = -i, the i-th argument had an illegal value.*          > 0:  if INFO = i, the QR algorithm failed to compute all the*                eigenvalues, and no eigenvectors have been computed;*                elements i+1:N of WR and WI contain eigenvalues which*                have converged.**  =====================================================================**     .. Parameters ..      REAL               ZERO, ONE      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )*     ..*     .. Local Scalars ..      LOGICAL            LQUERY, SCALEA, WANTVL, WANTVR      CHARACTER          SIDE      INTEGER            HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,     $                   MAXB, MAXWRK, MINWRK, NOUT      REAL               ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,     $                   SN*     ..*     .. Local Arrays ..      LOGICAL            SELECT( 1 )      REAL               DUM( 1 )*     ..*     .. External Subroutines ..      EXTERNAL           SGEBAK, SGEBAL, SGEHRD, SHSEQR, SLABAD, SLACPY,     $                   SLARTG, SLASCL, SORGHR, SROT, SSCAL, STREVC,     $                   XERBLA*     ..*     .. External Functions ..      LOGICAL            LSAME      INTEGER            ILAENV, ISAMAX      REAL               SLAMCH, SLANGE, SLAPY2, SNRM2      EXTERNAL           LSAME, ILAENV, ISAMAX, SLAMCH, SLANGE, SLAPY2,     $                   SNRM2*     ..*     .. Intrinsic Functions ..      INTRINSIC          MAX, MIN, SQRT*     ..*     .. Executable Statements ..**     Test the input arguments*      INFO = 0      LQUERY = ( LWORK.EQ.-1 )      WANTVL = LSAME( JOBVL, 'V' )      WANTVR = LSAME( JOBVR, 'V' )      IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THEN         INFO = -1      ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THEN         INFO = -2      ELSE IF( N.LT.0 ) THEN         INFO = -3      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN         INFO = -5      ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THEN         INFO = -9      ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THEN         INFO = -11      END IF**     Compute workspace*      (Note: Comments in the code beginning "Workspace:" describe the*       minimal amount of workspace needed at that point in the code,*       as well as the preferred amount for good performance.*       NB refers to the optimal block size for the immediately*       following subroutine, as returned by ILAENV.*       HSWORK refers to the workspace preferred by SHSEQR, as*       calculated below. HSWORK is computed assuming ILO=1 and IHI=N,*       the worst case.)*      MINWRK = 1      IF( INFO.EQ.0 .AND. ( LWORK.GE.1 .OR. LQUERY ) ) THEN         MAXWRK = 2*N + N*ILAENV( 1, 'SGEHRD', ' ', N, 1, N, 0 )         IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THEN            MINWRK = MAX( 1, 3*N )            MAXB = MAX( ILAENV( 8, 'SHSEQR', 'EN', N, 1, N, -1 ), 2 )            K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'SHSEQR', 'EN', N, 1,     $          N, -1 ) ) )            HSWORK = MAX( K*( K+2 ), 2*N )            MAXWRK = MAX( MAXWRK, N+1, N+HSWORK )         ELSE            MINWRK = MAX( 1, 4*N )            MAXWRK = MAX( MAXWRK, 2*N+( N-1 )*     $               ILAENV( 1, 'SORGHR', ' ', N, 1, N, -1 ) )            MAXB = MAX( ILAENV( 8, 'SHSEQR', 'SV', N, 1, N, -1 ), 2 )            K = MIN( MAXB, N, MAX( 2, ILAENV( 4, 'SHSEQR', 'SV', N, 1,     $          N, -1 ) ) )            HSWORK = MAX( K*( K+2 ), 2*N )            MAXWRK = MAX( MAXWRK, N+1, N+HSWORK )            MAXWRK = MAX( MAXWRK, 4*N )         END IF         WORK( 1 ) = MAXWRK      END IF      IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN         INFO = -13      END IF      IF( INFO.NE.0 ) THEN         CALL XERBLA( 'SGEEV ', -INFO )         RETURN      ELSE IF( LQUERY ) THEN         RETURN      END IF**     Quick return if possible*      IF( N.EQ.0 )     $   RETURN**     Get machine constants*      EPS = SLAMCH( 'P' )      SMLNUM = SLAMCH( 'S' )      BIGNUM = ONE / SMLNUM      CALL SLABAD( SMLNUM, BIGNUM )      SMLNUM = SQRT( SMLNUM ) / EPS      BIGNUM = ONE / SMLNUM**     Scale A if max element outside range [SMLNUM,BIGNUM]*      ANRM = SLANGE( 'M', N, N, A, LDA, DUM )      SCALEA = .FALSE.      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN         SCALEA = .TRUE.         CSCALE = SMLNUM      ELSE IF( ANRM.GT.BIGNUM ) THEN         SCALEA = .TRUE.         CSCALE = BIGNUM      END IF      IF( SCALEA )     $   CALL SLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )**     Balance the matrix*     (Workspace: need N)*      IBAL = 1      CALL SGEBAL( 'B', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )**     Reduce to upper Hessenberg form*     (Workspace: need 3*N, prefer 2*N+N*NB)*      ITAU = IBAL + N      IWRK = ITAU + N      CALL SGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),     $             LWORK-IWRK+1, IERR )*      IF( WANTVL ) THEN**        Want left eigenvectors*        Copy Householder vectors to VL*         SIDE = 'L'         CALL SLACPY( 'L', N, N, A, LDA, VL, LDVL )**        Generate orthogonal matrix in VL*        (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)*         CALL SORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),     $                LWORK-IWRK+1, IERR )**        Perform QR iteration, accumulating Schur vectors in VL*        (Workspace: need N+1, prefer N+HSWORK (see comments) )*         IWRK = ITAU         CALL SHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,     $                WORK( IWRK ), LWORK-IWRK+1, INFO )*         IF( WANTVR ) THEN**           Want left and right eigenvectors*           Copy Schur vectors to VR*            SIDE = 'B'            CALL SLACPY( 'F', N, N, VL, LDVL, VR, LDVR )         END IF*      ELSE IF( WANTVR ) THEN**        Want right eigenvectors*        Copy Householder vectors to VR*         SIDE = 'R'         CALL SLACPY( 'L', N, N, A, LDA, VR, LDVR )**        Generate orthogonal matrix in VR*        (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)*         CALL SORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),     $                LWORK-IWRK+1, IERR )**        Perform QR iteration, accumulating Schur vectors in VR*        (Workspace: need N+1, prefer N+HSWORK (see comments) )*         IWRK = ITAU         CALL SHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,     $                WORK( IWRK ), LWORK-IWRK+1, INFO )*      ELSE**        Compute eigenvalues only*        (Workspace: need N+1, prefer N+HSWORK (see comments) )*         IWRK = ITAU         CALL SHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,     $                WORK( IWRK ), LWORK-IWRK+1, INFO )      END IF**     If INFO > 0 from SHSEQR, then quit*      IF( INFO.GT.0 )     $   GO TO 50*      IF( WANTVL .OR. WANTVR ) THEN**        Compute left and/or right eigenvectors*        (Workspace: need 4*N)*         CALL STREVC( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,     $                N, NOUT, WORK( IWRK ), IERR )      END IF*      IF( WANTVL ) THEN**        Undo balancing of left eigenvectors*        (Workspace: need N)*         CALL SGEBAK( 'B', 'L', N, ILO, IHI, WORK( IBAL ), N, VL, LDVL,     $                IERR )**        Normalize left eigenvectors and make largest component real*         DO 20 I = 1, N            IF( WI( I ).EQ.ZERO ) THEN               SCL = ONE / SNRM2( N, VL( 1, I ), 1 )               CALL SSCAL( N, SCL, VL( 1, I ), 1 )            ELSE IF( WI( I ).GT.ZERO ) THEN               SCL = ONE / SLAPY2( SNRM2( N, VL( 1, I ), 1 ),     $               SNRM2( N, VL( 1, I+1 ), 1 ) )               CALL SSCAL( N, SCL, VL( 1, I ), 1 )               CALL SSCAL( N, SCL, VL( 1, I+1 ), 1 )               DO 10 K = 1, N                  WORK( IWRK+K-1 ) = VL( K, I )**2 + VL( K, I+1 )**2   10          CONTINUE               K = ISAMAX( N, WORK( IWRK ), 1 )               CALL SLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )               CALL SROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )               VL( K, I+1 ) = ZERO            END IF   20    CONTINUE      END IF*      IF( WANTVR ) THEN**        Undo balancing of right eigenvectors*        (Workspace: need N)*         CALL SGEBAK( 'B', 'R', N, ILO, IHI, WORK( IBAL ), N, VR, LDVR,     $                IERR )**        Normalize right eigenvectors and make largest component real*         DO 40 I = 1, N            IF( WI( I ).EQ.ZERO ) THEN               SCL = ONE / SNRM2( N, VR( 1, I ), 1 )               CALL SSCAL( N, SCL, VR( 1, I ), 1 )            ELSE IF( WI( I ).GT.ZERO ) THEN               SCL = ONE / SLAPY2( SNRM2( N, VR( 1, I ), 1 ),     $               SNRM2( N, VR( 1, I+1 ), 1 ) )               CALL SSCAL( N, SCL, VR( 1, I ), 1 )               CALL SSCAL( N, SCL, VR( 1, I+1 ), 1 )               DO 30 K = 1, N                  WORK( IWRK+K-1 ) = VR( K, I )**2 + VR( K, I+1 )**2   30          CONTINUE               K = ISAMAX( N, WORK( IWRK ), 1 )               CALL SLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )               CALL SROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )               VR( K, I+1 ) = ZERO            END IF   40    CONTINUE      END IF**     Undo scaling if necessary*   50 CONTINUE      IF( SCALEA ) THEN         CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),     $                MAX( N-INFO, 1 ), IERR )         CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),     $                MAX( N-INFO, 1 ), IERR )         IF( INFO.GT.0 ) THEN            CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,     $                   IERR )            CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,     $                   IERR )         END IF      END IF*      WORK( 1 ) = MAXWRK      RETURN**     End of SGEEV*      END      INTEGER          FUNCTION IEEECK( ISPEC, ZERO, ONE )**  -- LAPACK auxiliary routine (version 3.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     June 30, 1998**     .. Scalar Arguments ..      INTEGER            ISPEC      REAL               ONE, ZERO*     ..**  Purpose*  =======**  IEEECK is called from the ILAENV to verify that Infinity and

⌨️ 快捷键说明

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