qzredu
C QZREDU SOURCE BP208322 12/10/03 21:15:29 7517 c SUBROUTINE QZREDU (XMATA, XMATB, EPS1, CALV, XMATZ,NM,N, CERR) IMPLICIT INTEGER(I-N) IMPLICIT REAL*8 (A-H,O-Z) * ************************************************************************* * * * MISE SOUS FORME QUASI-TRIANGULAIRE SUPERIEURE * * D'UNE MATRICE DE HESSENBERG SUPERIEURE (MATA) * * ET TRIANGULARISATION SUPERIEURE SIMULTANEE DE MATB * * ( DEUXIEME PAS DE LA METHODE "QZ" POUR LE CALCUL MODAL COMPLEXE ) * * _____________________________________________________________________ * * * * * * DATE : le 27 Mars 1995 * * AUTEURS : J.ANTUNES , Nicolas BENECH * * _____________________________________________________________________ * * * * MODULE(S) APPELANT(S) : VIBRAC * * * * MODULE(S) APPELE(S) : * * _____________________________________________________________________ * * * * EN ENTREE : * * - MATA : matrice reelle Hessenberg superieure (XMATRI) * * - MATB : matrice reelle triangulaire superieure (XMATRI) * * - EPS1 : tolerance pour les elements negligeables * * si EPS1 = 0. ou EPS1 < 0., un element est neglige * * s'il est inferieur a l'erreur d'arrondi multiplie * * par la norme de la matrice * * si EPS1 > 0., un element est neglige s'il est inferieur * * a EPS1 multiplie par la norme de la matrice * * (plus rapide mais moins fiable) * * - CALV : indique si l'on calcule ou non les vecteurs propres * * * * EN SORTIE : * * - MATA : matrice quasi-triangulaire superieure * * - MATB : matrice sous forme triangulaire superieure * * - MATZ : produit des transformations effectuees (si CALV=.TRUE.)* * - CERR : code des erreurs * * CERR = 0 : retour normal * * CERR = J : plus de 30*N iterations pour le calcul * * de la valeur propre J * * * ************************************************************************* * -INC PPARAM -INC CCOPTIO -INC SMRIGID C INTEGER I , J , K , L , EN , K1 , K2 , LD , LL , L1 , NA , & ISH , ITN , ITS , KM1 , LM1 , ENM2 , CERR , LOR1 , & ENORN C LOGICAL CALV , NOTLAS C----------------------------------------------------------------------- POINTEUR MATA.XMATRI, MATB.XMATRI, MATZ.XMATRI c REAL*8 XMATA(NM,N),XMATB(NM,N),XMATZ(NM,N) C c SEGACT , MATA*mod c SEGACT , MATB*mod c SEGACT , MATZ*mod NM=MATA.RE(/1) N=MATA.RE(/2) C----------------------------------------------------------------------- C if(iimpi.ge.6) then write(ioimp,*) 'A=' do iou=1,N write(ioimp,*) (MATA.RE(iou,jou,1),jou=1,N) enddo write(ioimp,*) 'B=' do iou=1,N write(ioimp,*) (MATB.RE(iou,jou,1),jou=1,N) enddo endif C*********************************************************************** C*********************************************************************** C*********************************************************************** C C======================================================================= C========================= DEBUT DES CALCULS =========================== C======================================================================= C CERR = 0 C C----------------------------------------------------------------------- C---------------------- CALCUL DE EPSA ET EPSB ---------------------- C----------------------------------------------------------------------- C ANORM = 0.0D0 BNORM = 0.0D0 C DO 30 I = 1, N ANI = 0.0D0 IF ( I .NE. 1 ) ANI = ABS(MATA.RE(I,I-1,1)) BNI = 0.0D0 C DO 20 J = I, N ANI = ANI + ABS(MATA.RE(I,J,1)) BNI = BNI + ABS(MATB.RE(I,J,1)) 20 CONTINUE C IF ( ANI .GT. ANORM ) ANORM = ANI 30 CONTINUE C IF ( ANORM .EQ. 0.0D0 ) ANORM = 1.0D0 EP = EPS1 IF ( EP .GT. 0.0D0 ) GOTO 50 C IF (EP .GT. 0.0D0) GO TO 50 C ********** COMPUTE ROUNDOFF LEVEL IF EPSLON(1.) IS ZERO ********** EP = 1.0D0 40 EP = EP / 2.0 IF (1.0D0 + EP .GT. 1.0D0) GO TO 40 50 EPSA = EP * ANORM C ********** REDUCE A TO QUASI-TRIANGULAR FORM, WHILE C KEEPING B TRIANGULAR ********** LOR1 = 1 ENORN = N EN = N c ITN = 30*N c bp 2012-10-02 : on augmente le nombre d'iterations max ITN = 60*N C C----------------------------------------------------------------------- C------------------------- DEBUT DU PAS QZ --------------------------- C----------------------------------------------------------------------- C 60 IF ( EN .LE. 2 ) GOTO 1001 IF ( .NOT. CALV ) ENORN = EN ITS = 0 NA = EN - 1 ENM2 = NA - 1 70 ISH = 2 C C----------------------------------------------------------------------- C------------------- VERIFICATION DE LA CONVERGENCE -------------------- C----------------------------------------------------------------------- C DO 80 LL = 1, EN LM1 = EN - LL L = LM1 + 1 IF ( L .EQ. 1 ) GOTO 95 IF ( ABS(MATA.RE(L,LM1,1)) .LE. EPSA ) GOTO 90 80 CONTINUE C 90 MATA.RE(L,LM1,1) = 0.0D0 IF ( L .LT. NA ) GOTO 95 C ********** 1-BY-1 OR 2-BY-2 BLOCK ISOLATED ********** EN = LM1 GOTO 60 C ********** CHECK FOR SMALL TOP OF B ********** 95 LD = L 100 L1 = L + 1 C B11 = MATB.RE(L,L,1) IF ( ABS(B11) .GT. EPSB ) GOTO 120 MATB.RE(L,L,1) = 0.0D0 C S = ABS(MATA.RE(L,L,1)) + ABS(MATA.RE(L1,L,1)) U1 = MATA.RE(L,L,1) / S U2 = MATA.RE(L1,L,1) / S C C R = SIGN(SQRT(U1*U1+U2*U2),U1) V1 = -(U1 + R) / R V2 = -U2 / R U2 = V2 / V1 C DO 110 J = L, ENORN T = MATA.RE(L,J,1) + U2 * MATA.RE(L1,J,1) MATA.RE(L,J,1) = MATA.RE(L,J,1) + T * V1 MATA.RE(L1,J,1) = MATA.RE(L1,J,1) + T * V2 T = MATB.RE(L,J,1) + U2 * MATB.RE(L1,J,1) MATB.RE(L,J,1) = MATB.RE(L,J,1) + T * V1 MATB.RE(L1,J,1) = MATB.RE(L1,J,1) + T * V2 110 CONTINUE C IF ( L .NE. 1 ) MATA.RE(L,LM1,1) = -MATA.RE(L,LM1,1) LM1 = L L = L1 GOTO 90 120 CONTINUE A11 = MATA.RE(L,L,1) / B11 A21 = MATA.RE(L1,L,1) / B11 IF ( ISH .EQ. 1 ) GOTO 141 C C----------------------------------------------------------------------- C---------------------- STRATEGIE DE L ITERATION ----------------------- C----------------------------------------------------------------------- C C ********** ITERATION STRATEGY ********** IF ( ITN .EQ. 0 ) GOTO 1000 c bp 2012-10-02 : on change le moment d'appel au "ad hoc shift" dont on c ne trouve pas de justification mathematique mais on la cale c numeriquement sur un cas test problematique : brasero_tube3D.dgibi c l'ideal serait d'avoir un critere qui permet de declencher de shift c (ou bien de passer a linpack et DHGEQZ) c IF ( ITS .EQ. 10 ) GOTO 155 IF ( ITS .EQ. 10*N) GOTO 155 C C ********** DETERMINE TYPE OF SHIFT ********** B22 = MATB.RE(L1,L1,1) IF ( ABS(B22) .LT. EPSB ) B22 = EPSB B33 = MATB.RE(NA,NA,1) IF ( ABS(B33) .LT. EPSB ) B33 = EPSB B44 = MATB.RE(EN,EN,1) IF ( ABS(B44) .LT. EPSB ) B44 = EPSB A33 = MATA.RE(NA,NA,1) / B33 A34 = MATA.RE(NA,EN,1) / B44 A43 = MATA.RE(EN,NA,1) / B33 A44 = MATA.RE(EN,EN,1) / B44 B34 = MATB.RE(NA,EN,1) / B44 T = 0.5D0 * (A43 * B34 - A33 - A44) R = T * T + A34 * A43 - A33 * A44 IF ( R .LT. 0.0D0 ) GOTO 150 C C ********** DETERMINE SINGLE SHIFT ZEROTH COLUMN OF A ********** ISH = 1 R = SQRT(R) SH = -T + R S = -T - R IF ( ABS(S-A44) .LT. ABS(SH-A44) ) SH = S C C ********** LOOK FOR TWO CONSECUTIVE SMALL C SUB-DIAGONAL ELEMENTS OF A. C FOR L=EN-2 STEP -1 UNTIL LD DO -- ********** DO 130 LL = LD, ENM2 L = ENM2 + LD - LL IF ( L .EQ. LD ) GOTO 140 LM1 = L - 1 L1 = L + 1 T = MATA.RE(L,L,1) IF ( ABS(MATB.RE(L,L,1)) .GT. EPSB ) & T = T - SH * MATB.RE(L,L,1) IF (ABS(MATA.RE(L,LM1,1)).LE.ABS(T/MATA.RE(L1,L,1))*EPSA) & GOTO 100 130 CONTINUE 140 continue C 141 A1 = A11 - SH A2 = A21 IF ( L .NE. LD ) MATA.RE(L,LM1,1) = -MATA.RE(L,LM1,1) GOTO 160 C C ********** DETERMINE DOUBLE SHIFT ZEROTH COLUMN OF A ********** 150 continue A12 = MATA.RE(L,L1,1) / B22 A22 = MATA.RE(L1,L1,1) / B22 B12 = MATB.RE(L,L1,1) / B22 A1 = ((A33 - A11) * (A44 - A11) - A34 * A43 + A43 * B34 * A11) & / A21 + A12 - A11 * B12 A2 = (A22 - A11) - A21 * B12 - (A33 - A11) - (A44 - A11) & + A43 * B34 A3 = MATA.RE(L1+1,L1,1) / B22 GOTO 160 C C ********** AD HOC SHIFT ********** 155 A1 = 0.0D0 A2 = 1.0D0 A3 = 1.1605D0 160 ITS = ITS + 1 ITN = ITN - 1 if(iimpi.ge.6) write(*,*)'iteration ',ITS,' A1,A2,A3=',A1,A2,A3 IF ( .NOT. CALV ) LOR1 = LD C C----------------------------------------------------------------------- C------------------------- BOUCLE PRINCIPALE --------------------------- C----------------------------------------------------------------------- C DO 260 K = L, NA NOTLAS = K .NE. NA .AND. ISH .EQ. 2 K1 = K + 1 K2 = K + 2 KM1 = MAX0(K-1,L) LL = MIN0(EN,K1+ISH) IF ( NOTLAS ) GOTO 190 C C ********** ZERO A(K+1,K-1) ********** IF ( K .EQ. L ) GOTO 170 A1 = MATA.RE(K,KM1,1) A2 = MATA.RE(K1,KM1,1) 170 S = ABS(A1) + ABS(A2) IF ( S .EQ. 0.0D0 ) GOTO 70 U1 = A1 / S U2 = A2 / S R = SIGN(SQRT(U1*U1+U2*U2),U1) V1 = -(U1 + R) / R V2 = -U2 / R U2 = V2 / V1 C DO 180 J = KM1, ENORN T = MATA.RE(K,J,1) + U2 * MATA.RE(K1,J,1) MATA.RE(K,J,1) = MATA.RE(K,J,1) + T * V1 MATA.RE(K1,J,1) = MATA.RE(K1,J,1) + T * V2 T = MATB.RE(K,J,1) + U2 * MATB.RE(K1,J,1) MATB.RE(K,J,1) = MATB.RE(K,J,1) + T * V1 MATB.RE(K1,J,1) = MATB.RE(K1,J,1) + T * V2 180 CONTINUE C IF ( K .NE. L ) MATA.RE(K1,KM1,1) = 0.0D0 GOTO 240 C C ********** ZERO A(K+1,K-1) AND A(K+2,K-1) ********** 190 IF ( K .EQ. L ) GOTO 200 A1 = MATA.RE(K,KM1,1) A2 = MATA.RE(K1,KM1,1) A3 = MATA.RE(K2,KM1,1) 200 S = ABS(A1) + ABS(A2) + ABS(A3) IF ( S .EQ. 0.0D0 ) GOTO 260 U1 = A1 / S U2 = A2 / S U3 = A3 / S R = SIGN(SQRT(U1*U1+U2*U2+U3*U3),U1) V1 = -(U1 + R) / R V2 = -U2 / R V3 = -U3 / R U2 = V2 / V1 U3 = V3 / V1 C DO 210 J = KM1, ENORN T = MATA.RE(K,J,1) + U2 * MATA.RE(K1,J,1) & + U3 * MATA.RE(K2,J,1) MATA.RE(K,J,1) = MATA.RE(K,J,1) + T * V1 MATA.RE(K1,J,1) = MATA.RE(K1,J,1) + T * V2 MATA.RE(K2,J,1) = MATA.RE(K2,J,1) + T * V3 T = MATB.RE(K,J,1) + U2 * MATB.RE(K1,J,1) & + U3 * MATB.RE(K2,J,1) MATB.RE(K,J,1) = MATB.RE(K,J,1) + T * V1 MATB.RE(K1,J,1) = MATB.RE(K1,J,1) + T * V2 MATB.RE(K2,J,1) = MATB.RE(K2,J,1) + T * V3 210 CONTINUE C IF ( K .EQ. L ) GOTO 220 MATA.RE(K1,KM1,1) = 0.0D0 MATA.RE(K2,KM1,1) = 0.0D0 C C ********** ZERO B(K+2,K+1) AND B(K+2,K) ********** 220 continue S = ABS(MATB.RE(K2,K2,1)) + ABS(MATB.RE(K2,K1,1)) & + ABS(MATB.RE(K2,K,1)) IF ( S .EQ. 0.0D0 ) GOTO 240 U1 = MATB.RE(K2,K2,1) / S U2 = MATB.RE(K2,K1,1) / S U3 = MATB.RE(K2,K,1) / S R = SIGN(SQRT(U1*U1+U2*U2+U3*U3),U1) V1 = -(U1 + R) / R V2 = -U2 / R V3 = -U3 / R U2 = V2 / V1 U3 = V3 / V1 C DO 230 I = LOR1, LL T = MATA.RE(I,K2,1) + U2 * MATA.RE(I,K1,1) & + U3 * MATA.RE(I,K,1) MATA.RE(I,K2,1) = MATA.RE(I,K2,1) + T * V1 MATA.RE(I,K1,1) = MATA.RE(I,K1,1) + T * V2 MATA.RE(I,K,1) = MATA.RE(I,K,1) + T * V3 T = MATB.RE(I,K2,1) + U2 * MATB.RE(I,K1,1) & + U3 * MATB.RE(I,K,1) MATB.RE(I,K2,1) = MATB.RE(I,K2,1) + T * V1 MATB.RE(I,K1,1) = MATB.RE(I,K1,1) + T * V2 MATB.RE(I,K,1) = MATB.RE(I,K,1) + T * V3 230 CONTINUE C MATB.RE(K2,K,1) = 0.0D0 MATB.RE(K2,K1,1) = 0.0D0 IF ( .NOT. CALV ) GOTO 240 C DO 235 I = 1, N T = MATZ.RE(I,K2,1) + U2 * MATZ.RE(I,K1,1) & + U3 * MATZ.RE(I,K,1) MATZ.RE(I,K2,1) = MATZ.RE(I,K2,1) + T * V1 MATZ.RE(I,K1,1) = MATZ.RE(I,K1,1) + T * V2 MATZ.RE(I,K,1) = MATZ.RE(I,K,1) + T * V3 235 CONTINUE C C ********** ZERO B(K+1,K) ********** 240 CONTINUE S = ABS(MATB.RE(K1,K1,1)) + ABS(MATB.RE(K1,K,1)) IF ( S .EQ. 0.0D0 ) GOTO 260 U1 = MATB.RE(K1,K1,1) / S U2 = MATB.RE(K1,K,1) / S R = SIGN(SQRT(U1*U1+U2*U2),U1) V1 = -(U1 + R) / R V2 = -U2 / R U2 = V2 / V1 C DO 250 I = LOR1, LL T = MATA.RE(I,K1,1) + U2 * MATA.RE(I,K,1) MATA.RE(I,K1,1) = MATA.RE(I,K1,1) + T * V1 MATA.RE(I,K,1) = MATA.RE(I,K,1) + T * V2 T = MATB.RE(I,K1,1) + U2 * MATB.RE(I,K,1) MATB.RE(I,K1,1) = MATB.RE(I,K1,1) + T * V1 MATB.RE(I,K,1) = MATB.RE(I,K,1) + T * V2 250 CONTINUE C MATB.RE(K1,K,1) = 0.0D0 C IF ( .NOT. CALV ) GOTO 260 C DO 255 I = 1, N T = MATZ.RE(I,K1,1) + U2 * MATZ.RE(I,K,1) MATZ.RE(I,K1,1) = MATZ.RE(I,K1,1) + T * V1 MATZ.RE(I,K,1) = MATZ.RE(I,K,1) + T * V2 255 CONTINUE C 260 CONTINUE C GOTO 70 C C----------------------------------------------------------------------- C---- INDICATION D ERREUR SI PAS DE CONVERGENCE EN 30*N ITERATIONS ----- C----------------------------------------------------------------------- C 1000 CERR = EN C C----------------------------------------------------------------------- C------ ON SAUVE EPSB POUR UTILISATION DANS QZVALP ET QZVECP ------ C----------------------------------------------------------------------- C 1001 IF ( N .LE. 1 ) GOTO 1002 MATB.RE(N,1,1) = EPSB c SEGDES , MATA,MATB,MATZ C C======================================================================= C========================== FIN DES CALCULS ============================ C======================================================================= C if(iimpi.ge.4) then if(CERR.eq.0) then write(ioimp,*)'convergence en',ITS,' iterations ITN=',ITN else write(ioimp,*)'NON convergence en',ITS,' iterations ITN=',ITN write(ioimp,*) 'A=' do iou=1,N write(ioimp,*) (MATA.RE(iou,jou,1),jou=1,N) enddo write(ioimp,*) 'B=' do iou=1,N write(ioimp,*) (MATB.RE(iou,jou,1),jou=1,N) enddo endif endif 1002 RETURN END
© Cast3M 2003 - Tous droits réservés.
Mentions légales