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

📄 chgeqz.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 2 页
字号:
         END IF**        General case: j<ILAST*         DO 40 J = ILAST - 1, ILO, -1**           Test 1: for A(j,j-1)=0 or j=ILO*            IF( J.EQ.ILO ) THEN               ILAZRO = .TRUE.            ELSE               IF( ABS1( A( J, J-1 ) ).LE.ATOL ) THEN                  A( J, J-1 ) = CZERO                  ILAZRO = .TRUE.               ELSE                  ILAZRO = .FALSE.               END IF            END IF**           Test 2: for B(j,j)=0*            IF( ABS( B( J, J ) ).LT.BTOL ) THEN               B( J, J ) = CZERO**              Test 1a: Check for 2 consecutive small subdiagonals in A*               ILAZR2 = .FALSE.               IF( .NOT.ILAZRO ) THEN                  IF( ABS1( A( J, J-1 ) )*( ASCALE*ABS1( A( J+1,     $                J ) ) ).LE.ABS1( A( J, J ) )*( ASCALE*ATOL ) )     $                ILAZR2 = .TRUE.               END IF**              If both tests pass (1 & 2), i.e., the leading diagonal*              element of B in the block is zero, split a 1x1 block off*              at the top. (I.e., at the J-th row/column) The leading*              diagonal element of the remainder can also be zero, so*              this may have to be done repeatedly.*               IF( ILAZRO .OR. ILAZR2 ) THEN                  DO 20 JCH = J, ILAST - 1                     CTEMP = A( JCH, JCH )                     CALL CLARTG( CTEMP, A( JCH+1, JCH ), C, S,     $                            A( JCH, JCH ) )                     A( JCH+1, JCH ) = CZERO                     CALL CROT( ILASTM-JCH, A( JCH, JCH+1 ), LDA,     $                          A( JCH+1, JCH+1 ), LDA, C, S )                     CALL CROT( ILASTM-JCH, B( JCH, JCH+1 ), LDB,     $                          B( JCH+1, JCH+1 ), LDB, C, S )                     IF( ILQ )     $                  CALL CROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,     $                             C, CONJG( S ) )                     IF( ILAZR2 )     $                  A( JCH, JCH-1 ) = A( JCH, JCH-1 )*C                     ILAZR2 = .FALSE.*                    --------------- Begin Timing Code -----------------                     OPST = OPST + REAL( 32+40*( ILASTM-JCH )+20*NQ )*                    ---------------- End Timing Code ------------------                     IF( ABS1( B( JCH+1, JCH+1 ) ).GE.BTOL ) THEN                        IF( JCH+1.GE.ILAST ) THEN                           GO TO 60                        ELSE                           IFIRST = JCH + 1                           GO TO 70                        END IF                     END IF                     B( JCH+1, JCH+1 ) = CZERO   20             CONTINUE                  GO TO 50               ELSE**                 Only test 2 passed -- chase the zero to B(ILAST,ILAST)*                 Then process as in the case B(ILAST,ILAST)=0*                  DO 30 JCH = J, ILAST - 1                     CTEMP = B( JCH, JCH+1 )                     CALL CLARTG( CTEMP, B( JCH+1, JCH+1 ), C, S,     $                            B( JCH, JCH+1 ) )                     B( JCH+1, JCH+1 ) = CZERO                     IF( JCH.LT.ILASTM-1 )     $                  CALL CROT( ILASTM-JCH-1, B( JCH, JCH+2 ), LDB,     $                             B( JCH+1, JCH+2 ), LDB, C, S )                     CALL CROT( ILASTM-JCH+2, A( JCH, JCH-1 ), LDA,     $                          A( JCH+1, JCH-1 ), LDA, C, S )                     IF( ILQ )     $                  CALL CROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,     $                             C, CONJG( S ) )                     CTEMP = A( JCH+1, JCH )                     CALL CLARTG( CTEMP, A( JCH+1, JCH-1 ), C, S,     $                            A( JCH+1, JCH ) )                     A( JCH+1, JCH-1 ) = CZERO                     CALL CROT( JCH+1-IFRSTM, A( IFRSTM, JCH ), 1,     $                          A( IFRSTM, JCH-1 ), 1, C, S )                     CALL CROT( JCH-IFRSTM, B( IFRSTM, JCH ), 1,     $                          B( IFRSTM, JCH-1 ), 1, C, S )                     IF( ILZ )     $                  CALL CROT( N, Z( 1, JCH ), 1, Z( 1, JCH-1 ), 1,     $                             C, S )   30             CONTINUE**                 ---------------- Begin Timing Code -------------------                  OPST = OPST + REAL( 64+40*( ILASTM+1-IFRSTM )+20*     $                   ( NQ+NZ ) )*REAL( ILAST-J )*                 ----------------- End Timing Code --------------------*                  GO TO 50               END IF            ELSE IF( ILAZRO ) THEN**              Only test 1 passed -- work on J:ILAST*               IFIRST = J               GO TO 70            END IF**           Neither test passed -- try next J*   40    CONTINUE**        (Drop-through is "impossible")*         INFO = 2*N + 1         GO TO 210**        B(ILAST,ILAST)=0 -- clear A(ILAST,ILAST-1) to split off a*        1x1 block.*   50    CONTINUE         CTEMP = A( ILAST, ILAST )         CALL CLARTG( CTEMP, A( ILAST, ILAST-1 ), C, S,     $                A( ILAST, ILAST ) )         A( ILAST, ILAST-1 ) = CZERO         CALL CROT( ILAST-IFRSTM, A( IFRSTM, ILAST ), 1,     $              A( IFRSTM, ILAST-1 ), 1, C, S )         CALL CROT( ILAST-IFRSTM, B( IFRSTM, ILAST ), 1,     $              B( IFRSTM, ILAST-1 ), 1, C, S )         IF( ILZ )     $      CALL CROT( N, Z( 1, ILAST ), 1, Z( 1, ILAST-1 ), 1, C, S )*        --------------------- Begin Timing Code -----------------------         OPST = OPST + REAL( 32+40*( ILAST-IFRSTM )+20*NZ )*        ---------------------- End Timing Code ------------------------**        A(ILAST,ILAST-1)=0 -- Standardize B, set ALPHA and BETA*   60    CONTINUE         ABSB = ABS( B( ILAST, ILAST ) )         IF( ABSB.GT.SAFMIN ) THEN            SIGNBC = CONJG( B( ILAST, ILAST ) / ABSB )            B( ILAST, ILAST ) = ABSB            IF( ILSCHR ) THEN               CALL CSCAL( ILAST-IFRSTM, SIGNBC, B( IFRSTM, ILAST ), 1 )               CALL CSCAL( ILAST+1-IFRSTM, SIGNBC, A( IFRSTM, ILAST ),     $                     1 )*              ----------------- Begin Timing Code ---------------------               OPST = OPST + REAL( 12*( ILAST-IFRSTM ) )*              ------------------ End Timing Code ----------------------            ELSE               A( ILAST, ILAST ) = A( ILAST, ILAST )*SIGNBC            END IF            IF( ILZ )     $         CALL CSCAL( N, SIGNBC, Z( 1, ILAST ), 1 )*           ------------------- Begin Timing Code ----------------------            OPST = OPST + REAL( 6*NZ+13 )*           -------------------- End Timing Code -----------------------         ELSE            B( ILAST, ILAST ) = CZERO         END IF         ALPHA( ILAST ) = A( ILAST, ILAST )         BETA( ILAST ) = B( ILAST, ILAST )**        Go to next block -- exit if finished.*         ILAST = ILAST - 1         IF( ILAST.LT.ILO )     $      GO TO 190**        Reset counters*         IITER = 0         ESHIFT = CZERO         IF( .NOT.ILSCHR ) THEN            ILASTM = ILAST            IF( IFRSTM.GT.ILAST )     $         IFRSTM = ILO         END IF         GO TO 160**        QZ step**        This iteration only involves rows/columns IFIRST:ILAST.  We*        assume IFIRST < ILAST, and that the diagonal of B is non-zero.*   70    CONTINUE         IITER = IITER + 1         IF( .NOT.ILSCHR ) THEN            IFRSTM = IFIRST         END IF**        Compute the Shift.**        At this point, IFIRST < ILAST, and the diagonal elements of*        B(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in*        magnitude)*         IF( ( IITER / 10 )*10.NE.IITER ) THEN**           The Wilkinson shift (AEP p.512), i.e., the eigenvalue of*           the bottom-right 2x2 block of A inv(B) which is nearest to*           the bottom-right element.**           We factor B as U*D, where U has unit diagonals, and*           compute (A*inv(D))*inv(U).*            U12 = ( BSCALE*B( ILAST-1, ILAST ) ) /     $            ( BSCALE*B( ILAST, ILAST ) )            AD11 = ( ASCALE*A( ILAST-1, ILAST-1 ) ) /     $             ( BSCALE*B( ILAST-1, ILAST-1 ) )            AD21 = ( ASCALE*A( ILAST, ILAST-1 ) ) /     $             ( BSCALE*B( ILAST-1, ILAST-1 ) )            AD12 = ( ASCALE*A( ILAST-1, ILAST ) ) /     $             ( BSCALE*B( ILAST, ILAST ) )            AD22 = ( ASCALE*A( ILAST, ILAST ) ) /     $             ( BSCALE*B( ILAST, ILAST ) )            ABI22 = AD22 - U12*AD21*            T = HALF*( AD11+ABI22 )            RTDISC = SQRT( T**2+AD12*AD21-AD11*AD22 )            TEMP = REAL( T-ABI22 )*REAL( RTDISC ) +     $             AIMAG( T-ABI22 )*AIMAG( RTDISC )            IF( TEMP.LE.ZERO ) THEN               SHIFT = T + RTDISC            ELSE               SHIFT = T - RTDISC            END IF**           ------------------- Begin Timing Code ----------------------            OPST = OPST + REAL( 116 )*           -------------------- End Timing Code -----------------------*         ELSE**           Exceptional shift.  Chosen for no particularly good reason.*            ESHIFT = ESHIFT + CONJG( ( ASCALE*A( ILAST-1, ILAST ) ) /     $               ( BSCALE*B( ILAST-1, ILAST-1 ) ) )            SHIFT = ESHIFT**           ------------------- Begin Timing Code ----------------------            OPST = OPST + REAL( 15 )*           -------------------- End Timing Code -----------------------*         END IF**        Now check for two consecutive small subdiagonals.*         DO 80 J = ILAST - 1, IFIRST + 1, -1            ISTART = J            CTEMP = ASCALE*A( J, J ) - SHIFT*( BSCALE*B( J, J ) )            TEMP = ABS1( CTEMP )            TEMP2 = ASCALE*ABS1( A( J+1, J ) )            TEMPR = MAX( TEMP, TEMP2 )            IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THEN               TEMP = TEMP / TEMPR               TEMP2 = TEMP2 / TEMPR            END IF            IF( ABS1( A( J, J-1 ) )*TEMP2.LE.TEMP*ATOL )     $         GO TO 90   80    CONTINUE*         ISTART = IFIRST         CTEMP = ASCALE*A( IFIRST, IFIRST ) -     $           SHIFT*( BSCALE*B( IFIRST, IFIRST ) )**        --------------------- Begin Timing Code -----------------------         OPST = OPST - REAL( 6 )*        ---------------------- End Timing Code ------------------------*   90    CONTINUE**        Do an implicit-shift QZ sweep.**        Initial Q*         CTEMP2 = ASCALE*A( ISTART+1, ISTART )**        --------------------- Begin Timing Code -----------------------         OPST = OPST + REAL( 2+( ILAST-ISTART )*18 )*        ---------------------- End Timing Code ------------------------*         CALL CLARTG( CTEMP, CTEMP2, C, S, CTEMP3 )**        Sweep*         DO 150 J = ISTART, ILAST - 1            IF( J.GT.ISTART ) THEN               CTEMP = A( J, J-1 )               CALL CLARTG( CTEMP, A( J+1, J-1 ), C, S, A( J, J-1 ) )               A( J+1, J-1 ) = CZERO            END IF*            DO 100 JC = J, ILASTM               CTEMP = C*A( J, JC ) + S*A( J+1, JC )               A( J+1, JC ) = -CONJG( S )*A( J, JC ) + C*A( J+1, JC )               A( J, JC ) = CTEMP               CTEMP2 = C*B( J, JC ) + S*B( J+1, JC )               B( J+1, JC ) = -CONJG( S )*B( J, JC ) + C*B( J+1, JC )               B( J, JC ) = CTEMP2  100       CONTINUE            IF( ILQ ) THEN               DO 110 JR = 1, N                  CTEMP = C*Q( JR, J ) + CONJG( S )*Q( JR, J+1 )                  Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )                  Q( JR, J ) = CTEMP  110          CONTINUE            END IF*            CTEMP = B( J+1, J+1 )            CALL CLARTG( CTEMP, B( J+1, J ), C, S, B( J+1, J+1 ) )            B( J+1, J ) = CZERO*            DO 120 JR = IFRSTM, MIN( J+2, ILAST )               CTEMP = C*A( JR, J+1 ) + S*A( JR, J )               A( JR, J ) = -CONJG( S )*A( JR, J+1 ) + C*A( JR, J )               A( JR, J+1 ) = CTEMP  120       CONTINUE            DO 130 JR = IFRSTM, J               CTEMP = C*B( JR, J+1 ) + S*B( JR, J )               B( JR, J ) = -CONJG( S )*B( JR, J+1 ) + C*B( JR, J )               B( JR, J+1 ) = CTEMP  130       CONTINUE            IF( ILZ ) THEN               DO 140 JR = 1, N                  CTEMP = C*Z( JR, J+1 ) + S*Z( JR, J )                  Z( JR, J ) = -CONJG( S )*Z( JR, J+1 ) + C*Z( JR, J )                  Z( JR, J+1 ) = CTEMP  140          CONTINUE            END IF  150    CONTINUE**        --------------------- Begin Timing Code -----------------------         OPST = OPST + ( REAL( ILAST-ISTART )*     $          REAL( 120+64+40*( ILASTM-IFRSTM )+20*( NQ+NZ ) )-20 )*        ---------------------- End Timing Code ------------------------*  160    CONTINUE**        --------------------- Begin Timing Code -----------------------*        End of iteration -- add in "small" contributions.         OPS = OPS + OPST         OPST = ZERO*        ---------------------- End Timing Code ------------------------**  170 CONTINUE**     Drop-through = non-convergence*  180 CONTINUE      INFO = ILAST**     ---------------------- Begin Timing Code -------------------------      OPS = OPS + OPST      OPST = ZERO*     ----------------------- End Timing Code --------------------------*      GO TO 210**     Successful completion of all QZ steps*  190 CONTINUE**     Set Eigenvalues 1:ILO-1*      DO 200 J = 1, ILO - 1         ABSB = ABS( B( J, J ) )         IF( ABSB.GT.SAFMIN ) THEN            SIGNBC = CONJG( B( J, J ) / ABSB )            B( J, J ) = ABSB            IF( ILSCHR ) THEN               CALL CSCAL( J-1, SIGNBC, B( 1, J ), 1 )               CALL CSCAL( J, SIGNBC, A( 1, J ), 1 )*              ----------------- Begin Timing Code ---------------------               OPST = OPST + REAL( 12*( J-1 ) )*              ------------------ End Timing Code ----------------------            ELSE               A( J, J ) = A( J, J )*SIGNBC            END IF            IF( ILZ )     $         CALL CSCAL( N, SIGNBC, Z( 1, J ), 1 )*           ------------------- Begin Timing Code ----------------------            OPST = OPST + REAL( 6*NZ+13 )*           -------------------- End Timing Code -----------------------         ELSE            B( J, J ) = CZERO         END IF         ALPHA( J ) = A( J, J )         BETA( J ) = B( J, J )  200 CONTINUE**     Normal Termination*      INFO = 0**     Exit (other than argument error) -- return optimal workspace size*  210 CONTINUE**     ---------------------- Begin Timing Code -------------------------      OPS = OPS + OPST      OPST = ZERO      ITCNT = JITER*     ----------------------- End Timing Code --------------------------*      WORK( 1 ) = CMPLX( N )      RETURN**     End of CHGEQZ*      END

⌨️ 快捷键说明

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