C C ________________________________________________________ C | | C | SOLVE F(X) = 0. | C | | C | INPUT: | C | | C | Y,Z --STARTING GUESS CHOSEN SO THAT F(Y)*F(Z)<0 | C | | C | T --TOLERANCE (ITERATIONS CONTINUE UNTIL | C | THE ERROR IN THE ROOT IS .LE. T | C | | C | F --FUNCTION (EXTERNAL IN MAIN PROGRAM) | C | | C | OUTPUT: | C | | C | ROOT --SOLUTION | C | | C | BUILTIN FUNCTIONS: ABS,AMAX1,SIGN,SQRT | C | PACKAGE SUBROUTINES: INP | C |________________________________________________________| C FUNCTION ROOT(Y,Z,T,F) REAL A,B,C,D,E,F,FL,FR,L,P,Q,R,S,T,U,V,W,Y,Z REAL D2,D3,D4,FA,FB,FC,FD,P2,P3,P4,D34,D42,D23 L = Y R = Z IF ( L .LE. R ) GOTO 10 A = L L = R R = A 10 FL = F(L) FR = F(R) IF ( SIGN(FL,FR) .EQ. FL ) GOTO 220 Q = FL/ABS(FL) C ----------------------------------- C |*** COMPUTE MACHINE PRECISION ***| C ----------------------------------- S = T + T U = 1. 20 U = .5*U A = 1. + U IF ( A .GT. 1. ) GOTO 20 U = 5.*U V = .5*U 30 E = R - L IF ( E .LE. S ) GOTO 210 IF ( E .LE. U*(ABS(L)+ABS(R)) ) GOTO 210 IF ( ABS(FL) .GT. ABS(FR) ) GOTO 40 A = L FA = FL B = R FB = FR GOTO 50 40 A = R FA = FR B = L FB = FL C --------------------- C |*** SECANT STEP ***| C --------------------- 50 C = A - FA*(A-B)/(FA-FB) P = C W = AMAX1(T,V*(ABS(L)+ABS(R))) IF ( ABS(C-L) .LT. W ) C = L + W IF ( ABS(C-R) .LT. W ) C = R - W FC = F(C) IF ( SIGN(FC,Q) .EQ. FC ) GOTO 60 R = C FR = FC GOTO 70 60 L = C FL = FC 70 W = R - L IF ( W .LE. S ) GOTO 250 IF ( W .LE. U*(ABS(L)+ABS(R)) ) GOTO 250 IF ( ABS(FC) .GE. ABS(FB) ) GOTO 90 IF ( ABS(FC) .GT. ABS(FA) ) GOTO 80 W = C C = B B = A A = W W = FC FC = FB FB = FA FA = W GOTO 90 80 W = C C = B B = W W = FC FC = FB FB = W 90 IF ( A .LT. L ) GOTO 190 IF ( A .GT. R ) GOTO 190 C -------------------------------------- C |*** QUADRATIC INTERPOLATION STEP ***| C -------------------------------------- CALL INP(D,A,B,C,FA,FB,FC,L,R) C ------------------------------------ C |*** APPLY PSEUDO-NEWTON METHOD ***| C ------------------------------------ 100 P = D W = AMAX1(T,V*(ABS(L)+ABS(R))) IF ( ABS(L-D) .LT. W ) GOTO 110 IF ( ABS(R-D) .GT. W ) GOTO 130 110 IF ( D+D .GT. L+R ) GOTO 120 D = L + W GOTO 130 120 D = R - W 130 IF ( D .LE. L ) GOTO 190 IF ( D .GE. R ) GOTO 190 E = .5*E IF ( E .LT. ABS(A-D) ) GOTO 190 FD = F(D) IF ( SIGN(FD,Q) .EQ. FD ) GOTO 140 R = D FR = FD GOTO 150 140 L = D FL = FD 150 W = R - L IF ( W .LE. S ) GOTO 250 IF ( W .LE. U*(ABS(L)+ABS(R)) ) GOTO 250 W = ABS(FD) IF ( W .LE. ABS(FA) ) GOTO 170 IF ( W .LE. ABS(FB) ) GOTO 160 IF ( W .GE. ABS(FC) ) GOTO 180 W = D D = C C = W W = FD FD = FC FC = W GOTO 180 160 W = D D = C C = B B = W W = FD FD = FC FC = FB FB = W GOTO 180 170 W = D D = C C = B B = A A = W W = FD FD = FC FC = FB FB = FA FA = W 180 D4 = D - A D3 = C - A D2 = B - A D34 = C - D D42 = D - B D23 = B - C P2 = 0. P3 = 0. P4 = 0. IF ( D34 .NE. 0. ) P2 = 1./D34 IF ( D42 .NE. 0. ) P3 = 1./D42 IF ( D23 .NE. 0. ) P4 = 1./D23 P2 = (FB-FA)/(D2*(1.+(D2/D3)*P2*D42+(D2/D4)*P2*D23)) P3 = (FC-FA)/(D3*(1.+(D3/D2)*P3*D34+(D3/D4)*P3*D23)) P4 = (FD-FA)/(D4*(1.+(D4/D2)*P4*D34+(D4/D3)*P4*D42)) P2 = P2 + P3 + P4 IF ( P2 .EQ. 0. ) GOTO 190 D = A - FA/P2 GOTO 100 C -------------------------- C |*** BISECTION METHOD ***| C -------------------------- 190 D = .5*(L+R) FD = F(D) IF ( SIGN(FD,Q) .EQ. FD ) GOTO 200 R = D FR = FD GOTO 30 200 L = D FL = FD GOTO 30 210 ROOT = .5*(L+R) RETURN 220 IF ( FL. EQ. 0. ) GOTO 230 IF ( FR .EQ. 0. ) GOTO 240 WRITE(6,*) 'ERROR: FUNCTION HAS SAME SIGN AT BOTH STARTING POINTS' STOP 230 ROOT = L RETURN 240 ROOT = R RETURN 250 IF ( P .LT. L ) GOTO 210 IF ( P .GT. R ) GOTO 210 ROOT = P RETURN END C% SUBROUTINE INP(A,X,Y,Z,U,V,W,L,R) REAL A,B,C,L,P,Q,R,S,T,U,V,W,X,Y,Z S = Z - X T = (Y-X)/S A = (U-V)/T + (W-V)/(1.-T) IF ( A .EQ. 0. ) GOTO 40 B = .5*(W-U)/A - .5 C = U/A T = SQRT(ABS(C)) IF ( ABS(B) .LT. SIGN(T,C) ) GOTO 60 T = AMAX1(T,ABS(B)) IF ( T .EQ. 0. ) GOTO 50 Q = 1./T P = SQRT((Q*B)**2 - Q*C*Q) P = T*P IF ( ABS(P+B) .GT. ABS(P-B) ) GOTO 10 Q = P - B GOTO 20 10 Q = -(B+P) 20 P = C/Q Q = X + S*Q P = X + S*P IF ( Q .LT. L ) GOTO 30 IF ( Q .GT. R ) GOTO 30 A = Q RETURN 30 A = P RETURN 40 IF ( U .EQ. W ) GOTO 50 A = X + S*U/(U-W) RETURN 50 A = L RETURN 60 A = X - S*B RETURN END