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

📄 dtgevc.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
📖 第 1 页 / 共 3 页
字号:
*           (b) this would be the second of a complex pair.*           Check for complex eigenvalue, so as to be sure of which*           entry(-ies) of SELECT to look at -- if complex, SELECT(JE)*           or SELECT(JE-1).*           If this is a complex pair, the 2-by-2 diagonal block*           corresponding to the eigenvalue is in rows/columns JE-1:JE*            IF( ILCPLX ) THEN               ILCPLX = .FALSE.               GO TO 500            END IF            NW = 1            IF( JE.GT.1 ) THEN               IF( A( JE, JE-1 ).NE.ZERO ) THEN                  ILCPLX = .TRUE.                  NW = 2               END IF            END IF            IF( ILALL ) THEN               ILCOMP = .TRUE.            ELSE IF( ILCPLX ) THEN               ILCOMP = SELECT( JE ) .OR. SELECT( JE-1 )            ELSE               ILCOMP = SELECT( JE )            END IF            IF( .NOT.ILCOMP )     $         GO TO 500**           Decide if (a) singular pencil, (b) real eigenvalue, or*           (c) complex eigenvalue.*            IF( .NOT.ILCPLX ) THEN               IF( ABS( A( JE, JE ) ).LE.SAFMIN .AND.     $             ABS( B( JE, JE ) ).LE.SAFMIN ) THEN**                 Singular matrix pencil -- returns unit eigenvector*                  IEIG = IEIG - 1                  DO 230 JR = 1, N                     VR( JR, IEIG ) = ZERO  230             CONTINUE                  VR( IEIG, IEIG ) = ONE                  GO TO 500               END IF            END IF**           Clear vector*            DO 250 JW = 0, NW - 1               DO 240 JR = 1, N                  WORK( ( JW+2 )*N+JR ) = ZERO  240          CONTINUE  250       CONTINUE**           Compute coefficients in  ( a A - b B ) x = 0*              a  is  ACOEF*              b  is  BCOEFR + i*BCOEFI*            IF( .NOT.ILCPLX ) THEN**              Real eigenvalue*               TEMP = ONE / MAX( ABS( A( JE, JE ) )*ASCALE,     $                ABS( B( JE, JE ) )*BSCALE, SAFMIN )               SALFAR = ( TEMP*A( JE, JE ) )*ASCALE               SBETA = ( TEMP*B( JE, JE ) )*BSCALE               ACOEF = SBETA*ASCALE               BCOEFR = SALFAR*BSCALE               BCOEFI = ZERO**              Scale to avoid underflow*               SCALE = ONE               LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL               LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.     $               SMALL               IF( LSA )     $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )               IF( LSB )     $            SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*     $                    MIN( BNORM, BIG ) )               IF( LSA .OR. LSB ) THEN                  SCALE = MIN( SCALE, ONE /     $                    ( SAFMIN*MAX( ONE, ABS( ACOEF ),     $                    ABS( BCOEFR ) ) ) )                  IF( LSA ) THEN                     ACOEF = ASCALE*( SCALE*SBETA )                  ELSE                     ACOEF = SCALE*ACOEF                  END IF                  IF( LSB ) THEN                     BCOEFR = BSCALE*( SCALE*SALFAR )                  ELSE                     BCOEFR = SCALE*BCOEFR                  END IF               END IF               ACOEFA = ABS( ACOEF )               BCOEFA = ABS( BCOEFR )**              First component is 1*               WORK( 2*N+JE ) = ONE               XMAX = ONE**              Compute contribution from column JE of A and B to sum*              (See "Further Details", above.)*               DO 260 JR = 1, JE - 1                  WORK( 2*N+JR ) = BCOEFR*B( JR, JE ) -     $                             ACOEF*A( JR, JE )  260          CONTINUE            ELSE**              Complex eigenvalue*               CALL DLAG2( A( JE-1, JE-1 ), LDA, B( JE-1, JE-1 ), LDB,     $                     SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,     $                     BCOEFI )               IF( BCOEFI.EQ.ZERO ) THEN                  INFO = JE - 1                  RETURN               END IF**              Scale to avoid over/underflow*               ACOEFA = ABS( ACOEF )               BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )               SCALE = ONE               IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )     $            SCALE = ( SAFMIN / ULP ) / ACOEFA               IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )     $            SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )               IF( SAFMIN*ACOEFA.GT.ASCALE )     $            SCALE = ASCALE / ( SAFMIN*ACOEFA )               IF( SAFMIN*BCOEFA.GT.BSCALE )     $            SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )               IF( SCALE.NE.ONE ) THEN                  ACOEF = SCALE*ACOEF                  ACOEFA = ABS( ACOEF )                  BCOEFR = SCALE*BCOEFR                  BCOEFI = SCALE*BCOEFI                  BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )               END IF**              Compute first two components of eigenvector*              and contribution to sums*               TEMP = ACOEF*A( JE, JE-1 )               TEMP2R = ACOEF*A( JE, JE ) - BCOEFR*B( JE, JE )               TEMP2I = -BCOEFI*B( JE, JE )               IF( ABS( TEMP ).GE.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN                  WORK( 2*N+JE ) = ONE                  WORK( 3*N+JE ) = ZERO                  WORK( 2*N+JE-1 ) = -TEMP2R / TEMP                  WORK( 3*N+JE-1 ) = -TEMP2I / TEMP               ELSE                  WORK( 2*N+JE-1 ) = ONE                  WORK( 3*N+JE-1 ) = ZERO                  TEMP = ACOEF*A( JE-1, JE )                  WORK( 2*N+JE ) = ( BCOEFR*B( JE-1, JE-1 )-ACOEF*     $                             A( JE-1, JE-1 ) ) / TEMP                  WORK( 3*N+JE ) = BCOEFI*B( JE-1, JE-1 ) / TEMP               END IF*               XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),     $                ABS( WORK( 2*N+JE-1 ) )+ABS( WORK( 3*N+JE-1 ) ) )**              Compute contribution from columns JE and JE-1*              of A and B to the sums.*               CREALA = ACOEF*WORK( 2*N+JE-1 )               CIMAGA = ACOEF*WORK( 3*N+JE-1 )               CREALB = BCOEFR*WORK( 2*N+JE-1 ) -     $                  BCOEFI*WORK( 3*N+JE-1 )               CIMAGB = BCOEFI*WORK( 2*N+JE-1 ) +     $                  BCOEFR*WORK( 3*N+JE-1 )               CRE2A = ACOEF*WORK( 2*N+JE )               CIM2A = ACOEF*WORK( 3*N+JE )               CRE2B = BCOEFR*WORK( 2*N+JE ) - BCOEFI*WORK( 3*N+JE )               CIM2B = BCOEFI*WORK( 2*N+JE ) + BCOEFR*WORK( 3*N+JE )               DO 270 JR = 1, JE - 2                  WORK( 2*N+JR ) = -CREALA*A( JR, JE-1 ) +     $                             CREALB*B( JR, JE-1 ) -     $                             CRE2A*A( JR, JE ) + CRE2B*B( JR, JE )                  WORK( 3*N+JR ) = -CIMAGA*A( JR, JE-1 ) +     $                             CIMAGB*B( JR, JE-1 ) -     $                             CIM2A*A( JR, JE ) + CIM2B*B( JR, JE )  270          CONTINUE            END IF*            DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )**           Columnwise triangular solve of  (a A - b B)  x = 0*            IL2BY2 = .FALSE.*           ------------------- Begin Timing Code ----------------------            OPST = ZERO            IN2BY2 = 0*           -------------------- End Timing Code -----------------------            DO 370 J = JE - NW, 1, -1*              ------------------- Begin Timing Code -------------------               OPSSCA = DBLE( NW*JE+1 )*              -------------------- End Timing Code --------------------**              If a 2-by-2 block, is in position j-1:j, wait until*              next iteration to process it (when it will be j:j+1)*               IF( .NOT.IL2BY2 .AND. J.GT.1 ) THEN                  IF( A( J, J-1 ).NE.ZERO ) THEN                     IL2BY2 = .TRUE.*                    -------------- Begin Timing Code -----------------                     IN2BY2 = IN2BY2 + 1*                    --------------- End Timing Code -------------------                     GO TO 370                  END IF               END IF               BDIAG( 1 ) = B( J, J )               IF( IL2BY2 ) THEN                  NA = 2                  BDIAG( 2 ) = B( J+1, J+1 )               ELSE                  NA = 1               END IF**              Compute x(j) (and x(j+1), if 2-by-2 block)*               CALL DLALN2( .FALSE., NA, NW, DMIN, ACOEF, A( J, J ),     $                      LDA, BDIAG( 1 ), BDIAG( 2 ), WORK( 2*N+J ),     $                      N, BCOEFR, BCOEFI, SUM, 2, SCALE, TEMP,     $                      IINFO )               IF( SCALE.LT.ONE ) THEN*                  DO 290 JW = 0, NW - 1                     DO 280 JR = 1, JE                        WORK( ( JW+2 )*N+JR ) = SCALE*     $                     WORK( ( JW+2 )*N+JR )  280                CONTINUE  290             CONTINUE               END IF               XMAX = MAX( SCALE*XMAX, TEMP )*              ------------------ Begin Timing Code -----------------               OPST = OPST + OPSSCA*              ------------------- End Timing Code ------------------*               DO 310 JW = 1, NW                  DO 300 JA = 1, NA                     WORK( ( JW+1 )*N+J+JA-1 ) = SUM( JA, JW )  300             CONTINUE  310          CONTINUE**              w = w + x(j)*(a A(*,j) - b B(*,j) ) with scaling*               IF( J.GT.1 ) THEN**                 Check whether scaling is necessary for sum.*                  XSCALE = ONE / MAX( ONE, XMAX )                  TEMP = ACOEFA*WORK( J ) + BCOEFA*WORK( N+J )                  IF( IL2BY2 )     $               TEMP = MAX( TEMP, ACOEFA*WORK( J+1 )+BCOEFA*     $                      WORK( N+J+1 ) )                  TEMP = MAX( TEMP, ACOEFA, BCOEFA )                  IF( TEMP.GT.BIGNUM*XSCALE ) THEN*                     DO 330 JW = 0, NW - 1                        DO 320 JR = 1, JE                           WORK( ( JW+2 )*N+JR ) = XSCALE*     $                        WORK( ( JW+2 )*N+JR )  320                   CONTINUE  330                CONTINUE                     XMAX = XMAX*XSCALE*                    ----------------- Begin Timing Code ---------------                     OPST = OPST + OPSSCA*                    ------------------ End Timing Code ----------------                  END IF**                 Compute the contributions of the off-diagonals of*                 column j (and j+1, if 2-by-2 block) of A and B to the*                 sums.**                  DO 360 JA = 1, NA                     IF( ILCPLX ) THEN                        CREALA = ACOEF*WORK( 2*N+J+JA-1 )                        CIMAGA = ACOEF*WORK( 3*N+J+JA-1 )                        CREALB = BCOEFR*WORK( 2*N+J+JA-1 ) -     $                           BCOEFI*WORK( 3*N+J+JA-1 )                        CIMAGB = BCOEFI*WORK( 2*N+J+JA-1 ) +     $                           BCOEFR*WORK( 3*N+J+JA-1 )                        DO 340 JR = 1, J - 1                           WORK( 2*N+JR ) = WORK( 2*N+JR ) -     $                                      CREALA*A( JR, J+JA-1 ) +     $                                      CREALB*B( JR, J+JA-1 )                           WORK( 3*N+JR ) = WORK( 3*N+JR ) -     $                                      CIMAGA*A( JR, J+JA-1 ) +     $                                      CIMAGB*B( JR, J+JA-1 )  340                   CONTINUE                     ELSE                        CREALA = ACOEF*WORK( 2*N+J+JA-1 )                        CREALB = BCOEFR*WORK( 2*N+J+JA-1 )                        DO 350 JR = 1, J - 1                           WORK( 2*N+JR ) = WORK( 2*N+JR ) -     $                                      CREALA*A( JR, J+JA-1 ) +     $                                      CREALB*B( JR, J+JA-1 )  350                   CONTINUE                     END IF  360             CONTINUE               END IF*               IL2BY2 = .FALSE.  370       CONTINUE**           Copy eigenvector to VR, back transforming if*           HOWMNY='B'.*            IEIG = IEIG - NW            IF( ILBACK ) THEN*               DO 410 JW = 0, NW - 1                  DO 380 JR = 1, N                     WORK( ( JW+4 )*N+JR ) = WORK( ( JW+2 )*N+1 )*     $                                       VR( JR, 1 )  380             CONTINUE**                 A series of compiler directives to defeat*                 vectorization for the next loop**                  DO 400 JC = 2, JE                     DO 390 JR = 1, N                        WORK( ( JW+4 )*N+JR ) = WORK( ( JW+4 )*N+JR ) +     $                     WORK( ( JW+2 )*N+JC )*VR( JR, JC )  390                CONTINUE  400             CONTINUE  410          CONTINUE*               DO 430 JW = 0, NW - 1                  DO 420 JR = 1, N                     VR( JR, IEIG+JW ) = WORK( ( JW+4 )*N+JR )  420             CONTINUE  430          CONTINUE*               IEND = N            ELSE               DO 450 JW = 0, NW - 1                  DO 440 JR = 1, N                     VR( JR, IEIG+JW ) = WORK( ( JW+2 )*N+JR )  440             CONTINUE  450          CONTINUE*               IEND = JE            END IF**           Scale eigenvector*            XMAX = ZERO            IF( ILCPLX ) THEN               DO 460 J = 1, IEND                  XMAX = MAX( XMAX, ABS( VR( J, IEIG ) )+     $                   ABS( VR( J, IEIG+1 ) ) )  460          CONTINUE            ELSE               DO 470 J = 1, IEND                  XMAX = MAX( XMAX, ABS( VR( J, IEIG ) ) )  470          CONTINUE            END IF*            IF( XMAX.GT.SAFMIN ) THEN               XSCALE = ONE / XMAX               DO 490 JW = 0, NW - 1                  DO 480 JR = 1, IEND                     VR( JR, IEIG+JW ) = XSCALE*VR( JR, IEIG+JW )  480             CONTINUE  490          CONTINUE            END IF**           ------------------- Begin Timing Code ----------------------*           Opcounts for each eigenvector**                                Real                Complex*           Initialization       8--16 + 3*(JE-1)    71--87+16+14*(JE-2)**           Solve (per iter)     NA*(5 + 7*(NA-1))   NA*(17 + 17*(NA-1))*                                + scaling           + scaling*           column add (per iter)*                                2 + 5*NA            2 + 11*NA*                                + 4*NA*(J-1)        + 8*NA*(J-1)*                                + scaling           + scaling*           iteration:           J=JE-1,...,1        J=JE-2,...,1**           Back xform           2*N*JE - N          4*N*JE - 2*N*           Scaling (w/back x.)  N                   3*N*           Scaling (w/o back)   JE                  3*JE*            IF( .NOT.ILCPLX ) THEN               OPST = OPST + DBLE( ( 2*JE+11 )*( JE-1 )+12+8*IN2BY2 )               IF( ILBACK ) THEN                  OPST = OPST + DBLE( 2*N*JE )               ELSE                  OPST = OPST + DBLE( JE )               END IF            ELSE               OPST = OPST + DBLE( ( 4*JE+32 )*( JE-2 )+95+24*IN2BY2 )               IF( ILBACK ) THEN                  OPST = OPST + DBLE( 4*N*JE+N )               ELSE                  OPST = OPST + DBLE( 3*JE )               END IF            END IF            OPS = OPS + OPST**           -------------------- End Timing Code -----------------------*  500    CONTINUE      END IF*      RETURN**     End of DTGEVC*      END

⌨️ 快捷键说明

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