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

📄 dhgeqz.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 4 页
字号:
*           (Single shift only.)*            IF( ( DBLE( MAXIT )*SAFMIN )*ABS( A( ILAST-1, ILAST ) ).LT.     $          ABS( B( ILAST-1, ILAST-1 ) ) ) THEN               ESHIFT = ESHIFT + A( ILAST-1, ILAST ) /     $                  B( ILAST-1, ILAST-1 )            ELSE               ESHIFT = ESHIFT + ONE / ( SAFMIN*DBLE( MAXIT ) )            END IF            S1 = ONE            WR = ESHIFT**           ------------------- Begin Timing Code ----------------------            OPST = OPST + DBLE( 4 )*           -------------------- End Timing Code -----------------------*         ELSE**           Shifts based on the generalized eigenvalues of the*           bottom-right 2x2 block of A and B. The first eigenvalue*           returned by DLAG2 is the Wilkinson shift (AEP p.512),*            CALL DLAG2( A( ILAST-1, ILAST-1 ), LDA,     $                  B( ILAST-1, ILAST-1 ), LDB, SAFMIN*SAFETY, S1,     $                  S2, WR, WR2, WI )*            TEMP = MAX( S1, SAFMIN*MAX( ONE, ABS( WR ), ABS( WI ) ) )**           ------------------- Begin Timing Code ----------------------            OPST = OPST + DBLE( 57 )*           -------------------- End Timing Code -----------------------*            IF( WI.NE.ZERO )     $         GO TO 200         END IF**        Fiddle with shift to avoid overflow*         TEMP = MIN( ASCALE, ONE )*( HALF*SAFMAX )         IF( S1.GT.TEMP ) THEN            SCALE = TEMP / S1         ELSE            SCALE = ONE         END IF*         TEMP = MIN( BSCALE, ONE )*( HALF*SAFMAX )         IF( ABS( WR ).GT.TEMP )     $      SCALE = MIN( SCALE, TEMP / ABS( WR ) )         S1 = SCALE*S1         WR = SCALE*WR**        Now check for two consecutive small subdiagonals.*         DO 120 J = ILAST - 1, IFIRST + 1, -1            ISTART = J            TEMP = ABS( S1*A( J, J-1 ) )            TEMP2 = ABS( S1*A( J, J )-WR*B( J, J ) )            TEMPR = MAX( TEMP, TEMP2 )            IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN               TEMP = TEMP / TEMPR               TEMP2 = TEMP2 / TEMPR            END IF            IF( ABS( ( ASCALE*A( J+1, J ) )*TEMP ).LE.( ASCALE*ATOL )*     $          TEMP2 )GO TO 130  120    CONTINUE*         ISTART = IFIRST  130    CONTINUE**        Do an implicit single-shift QZ sweep.**        Initial Q*         TEMP = S1*A( ISTART, ISTART ) - WR*B( ISTART, ISTART )         TEMP2 = S1*A( ISTART+1, ISTART )         CALL DLARTG( TEMP, TEMP2, C, S, TEMPR )**        Sweep*         DO 190 J = ISTART, ILAST - 1            IF( J.GT.ISTART ) THEN               TEMP = A( J, J-1 )               CALL DLARTG( TEMP, A( J+1, J-1 ), C, S, A( J, J-1 ) )               A( J+1, J-1 ) = ZERO            END IF*            DO 140 JC = J, ILASTM               TEMP = C*A( J, JC ) + S*A( J+1, JC )               A( J+1, JC ) = -S*A( J, JC ) + C*A( J+1, JC )               A( J, JC ) = TEMP               TEMP2 = C*B( J, JC ) + S*B( J+1, JC )               B( J+1, JC ) = -S*B( J, JC ) + C*B( J+1, JC )               B( J, JC ) = TEMP2  140       CONTINUE            IF( ILQ ) THEN               DO 150 JR = 1, N                  TEMP = C*Q( JR, J ) + S*Q( JR, J+1 )                  Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )                  Q( JR, J ) = TEMP  150          CONTINUE            END IF*            TEMP = B( J+1, J+1 )            CALL DLARTG( TEMP, B( J+1, J ), C, S, B( J+1, J+1 ) )            B( J+1, J ) = ZERO*            DO 160 JR = IFRSTM, MIN( J+2, ILAST )               TEMP = C*A( JR, J+1 ) + S*A( JR, J )               A( JR, J ) = -S*A( JR, J+1 ) + C*A( JR, J )               A( JR, J+1 ) = TEMP  160       CONTINUE            DO 170 JR = IFRSTM, J               TEMP = C*B( JR, J+1 ) + S*B( JR, J )               B( JR, J ) = -S*B( JR, J+1 ) + C*B( JR, J )               B( JR, J+1 ) = TEMP  170       CONTINUE            IF( ILZ ) THEN               DO 180 JR = 1, N                  TEMP = C*Z( JR, J+1 ) + S*Z( JR, J )                  Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )                  Z( JR, J+1 ) = TEMP  180          CONTINUE            END IF  190    CONTINUE**        --------------------- Begin Timing Code -----------------------         OPST = OPST + DBLE( 6+( ILAST-ISTART )*     $          ( 8+14+36+12*( ILASTM-IFRSTM )+6*( NQ+NZ ) ) )*        ---------------------- End Timing Code ------------------------*         GO TO 350**        Use Francis double-shift**        Note: the Francis double-shift should work with real shifts,*              but only if the block is at least 3x3.*              This code may break if this point is reached with*              a 2x2 block with real eigenvalues.*  200    CONTINUE         IF( IFIRST+1.EQ.ILAST ) THEN**           Special case -- 2x2 block with complex eigenvectors**           Step 1: Standardize, that is, rotate so that**                       ( B11  0  )*                   B = (         )  with B11 non-negative.*                       (  0  B22 )*            CALL DLASV2( B( ILAST-1, ILAST-1 ), B( ILAST-1, ILAST ),     $                   B( ILAST, ILAST ), B22, B11, SR, CR, SL, CL )*            IF( B11.LT.ZERO ) THEN               CR = -CR               SR = -SR               B11 = -B11               B22 = -B22            END IF*            CALL DROT( ILASTM+1-IFIRST, A( ILAST-1, ILAST-1 ), LDA,     $                 A( ILAST, ILAST-1 ), LDA, CL, SL )            CALL DROT( ILAST+1-IFRSTM, A( IFRSTM, ILAST-1 ), 1,     $                 A( IFRSTM, ILAST ), 1, CR, SR )*            IF( ILAST.LT.ILASTM )     $         CALL DROT( ILASTM-ILAST, B( ILAST-1, ILAST+1 ), LDB,     $                    B( ILAST, ILAST+1 ), LDA, CL, SL )            IF( IFRSTM.LT.ILAST-1 )     $         CALL DROT( IFIRST-IFRSTM, B( IFRSTM, ILAST-1 ), 1,     $                    B( IFRSTM, ILAST ), 1, CR, SR )*            IF( ILQ )     $         CALL DROT( N, Q( 1, ILAST-1 ), 1, Q( 1, ILAST ), 1, CL,     $                    SL )            IF( ILZ )     $         CALL DROT( N, Z( 1, ILAST-1 ), 1, Z( 1, ILAST ), 1, CR,     $                    SR )*            B( ILAST-1, ILAST-1 ) = B11            B( ILAST-1, ILAST ) = ZERO            B( ILAST, ILAST-1 ) = ZERO            B( ILAST, ILAST ) = B22**           If B22 is negative, negate column ILAST*            IF( B22.LT.ZERO ) THEN               DO 210 J = IFRSTM, ILAST                  A( J, ILAST ) = -A( J, ILAST )                  B( J, ILAST ) = -B( J, ILAST )  210          CONTINUE*               IF( ILZ ) THEN                  DO 220 J = 1, N                     Z( J, ILAST ) = -Z( J, ILAST )  220             CONTINUE               END IF            END IF**           Step 2: Compute ALPHAR, ALPHAI, and BETA (see refs.)**           Recompute shift*            CALL DLAG2( A( ILAST-1, ILAST-1 ), LDA,     $                  B( ILAST-1, ILAST-1 ), LDB, SAFMIN*SAFETY, S1,     $                  TEMP, WR, TEMP2, WI )**           ------------------- Begin Timing Code ----------------------            OPST = OPST + DBLE( 103+12*( ILASTM+ILAST-IFIRST-IFRSTM )+6*     $             ( NQ+NZ ) )*           -------------------- End Timing Code -----------------------**           If standardization has perturbed the shift onto real line,*           do another (real single-shift) QR step.*            IF( WI.EQ.ZERO )     $         GO TO 350            S1INV = ONE / S1**           Do EISPACK (QZVAL) computation of alpha and beta*            A11 = A( ILAST-1, ILAST-1 )            A21 = A( ILAST, ILAST-1 )            A12 = A( ILAST-1, ILAST )            A22 = A( ILAST, ILAST )**           Compute complex Givens rotation on right*           (Assume some element of C = (sA - wB) > unfl )*                            __*           (sA - wB) ( CZ   -SZ )*                     ( SZ    CZ )*            C11R = S1*A11 - WR*B11            C11I = -WI*B11            C12 = S1*A12            C21 = S1*A21            C22R = S1*A22 - WR*B22            C22I = -WI*B22*            IF( ABS( C11R )+ABS( C11I )+ABS( C12 ).GT.ABS( C21 )+     $          ABS( C22R )+ABS( C22I ) ) THEN               T = DLAPY3( C12, C11R, C11I )               CZ = C12 / T               SZR = -C11R / T               SZI = -C11I / T            ELSE               CZ = DLAPY2( C22R, C22I )               IF( CZ.LE.SAFMIN ) THEN                  CZ = ZERO                  SZR = ONE                  SZI = ZERO               ELSE                  TEMPR = C22R / CZ                  TEMPI = C22I / CZ                  T = DLAPY2( CZ, C21 )                  CZ = CZ / T                  SZR = -C21*TEMPR / T                  SZI = C21*TEMPI / T               END IF            END IF**           Compute Givens rotation on left**           (  CQ   SQ )*           (  __      )  A or B*           ( -SQ   CQ )*            AN = ABS( A11 ) + ABS( A12 ) + ABS( A21 ) + ABS( A22 )            BN = ABS( B11 ) + ABS( B22 )            WABS = ABS( WR ) + ABS( WI )            IF( S1*AN.GT.WABS*BN ) THEN               CQ = CZ*B11               SQR = SZR*B22               SQI = -SZI*B22            ELSE               A1R = CZ*A11 + SZR*A12               A1I = SZI*A12               A2R = CZ*A21 + SZR*A22               A2I = SZI*A22               CQ = DLAPY2( A1R, A1I )               IF( CQ.LE.SAFMIN ) THEN                  CQ = ZERO                  SQR = ONE                  SQI = ZERO               ELSE                  TEMPR = A1R / CQ                  TEMPI = A1I / CQ                  SQR = TEMPR*A2R + TEMPI*A2I                  SQI = TEMPI*A2R - TEMPR*A2I               END IF            END IF            T = DLAPY3( CQ, SQR, SQI )            CQ = CQ / T            SQR = SQR / T            SQI = SQI / T**           Compute diagonal elements of QBZ*            TEMPR = SQR*SZR - SQI*SZI            TEMPI = SQR*SZI + SQI*SZR            B1R = CQ*CZ*B11 + TEMPR*B22            B1I = TEMPI*B22            B1A = DLAPY2( B1R, B1I )            B2R = CQ*CZ*B22 + TEMPR*B11            B2I = -TEMPI*B11            B2A = DLAPY2( B2R, B2I )**           Normalize so beta > 0, and Im( alpha1 ) > 0*            BETA( ILAST-1 ) = B1A            BETA( ILAST ) = B2A            ALPHAR( ILAST-1 ) = ( WR*B1A )*S1INV            ALPHAI( ILAST-1 ) = ( WI*B1A )*S1INV            ALPHAR( ILAST ) = ( WR*B2A )*S1INV            ALPHAI( ILAST ) = -( WI*B2A )*S1INV**           ------------------- Begin Timing Code ----------------------            OPST = OPST + DBLE( 93 )*           -------------------- End Timing Code -----------------------**           Step 3: Go to next block -- exit if finished.*            ILAST = IFIRST - 1            IF( ILAST.LT.ILO )     $         GO TO 380**           Reset counters*            IITER = 0            ESHIFT = ZERO            IF( .NOT.ILSCHR ) THEN               ILASTM = ILAST               IF( IFRSTM.GT.ILAST )     $            IFRSTM = ILO

⌨️ 快捷键说明

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