> restart:
> # STEEPEST DESCENT ALGORITHM 10.3
> #
> # To approximate a solution P to the minimization problem
> #                G(P) = MIN( G(X) : X in R(n) )
> # given an initial approximation X:
> #
> # INPUT:   Number n of variables: initial approximation X:
> #          tolerance TOL: maximum number of iterations N.
> #
> # OUTPUT:  Approximate solution X or a message of failure.
> F := proc(X,N) local D, I2, f:
> D := 0:
> for I2 from 1 to N do
> D := D+(CF[I2](seq(X[i],i=0..N-1)))*(CF[I2](seq(X[i],i=0..N-1))):
> od:
> f := D:
> RETURN(evalf(f)):
> end:
> print(`This is the Steepest Descent Method.`):
> OK := FALSE:
> while OK = FALSE do
> print(`Input the number n of equations.`):
> N := scanf(`%d`)[1]: print(`n = `):print(N):
> if N >= 2 then
> OK := TRUE:
> else
> print(`N must be an integer greater than 1.`):
> fi:
> od:
> print(`The functions CF represent the components of F(X).`):
> for I2 from 1 to N do
> print(`Input the function CF[I](x1..xn) for I = `,I2):
> CF[I2] := scanf(`%a`)[1]: print(`Function is `):print(CF[I2]):
> od:
> for I2 from 1 to N do
> P[I2] := 0:
> for J from 1 to N do
> P[I2] := P[I2]+2*CF[J]*diff(CF[J],evaln(x || I2)):
> od:
> P[I2] := unapply(P[I2],evaln(x || (1..N))):
> od:
> for I2 from 1 to N do
> CF[I2] := unapply(CF[I2],evaln(x || (1..N))):
> od:
> OK := FALSE:
> while OK = FALSE do
> print(`Input tolerance\n`):
> TOL := scanf(`%f`)[1]:print(`Tolerance = `):print(TOL):
> if TOL > 0 then
> OK := TRUE:
> else
> print(`Tolerance must be positive.`):
> fi:
> od:
> OK := FALSE:
> while OK = FALSE do
> print(`Input the maximum number of iterations.`):
> NN := scanf(`%d`)[1]:print(`Maximum number of iterations = `):print(NN):
> if NN > 0 then
> OK := TRUE:
> else
> print(`Must be a positive integer.`):
> fi:
> od:
> for I2 from 1 to N do
> print(`Input initial approximation X(I) for I = `, I2):
> X[I2-1] := scanf(`%f`)[1]:print(`Input = `):print(X[I2-1]):
> od:
> if OK = TRUE then
> print(`Select output destination`):
> print(`1. Screen`):
> print(`2. Text file`):
> print(`Enter 1 or 2`):
> FLAG1 := scanf(`%d`)[1]:print(`Your response is `):print(FLAG1):
> if FLAG1 = 2 then
> print(`Input the file name in the form - drive:\\name.ext`):
> print(`for example  A:\\OUTPUT.DTA`):
> NAME := scanf(`%s`)[1]:print(`Output file is `):print(NAME):
> OUP := fopen(NAME,WRITE,TEXT):
> else
> OUP := default:
> fi:
> print(`Select amount of output`):
> print(`1. Answer only`):
> print(`2. All intermediate approximations`):
> print(`Enter 1 or 2`):
> FLAG1 := scanf(`%d`)[1]:print(`Your response is `):print(FLAG1):
> fprintf(OUP, `STEEPEST DESCENT METHOD FOR NONLINEAR SYSTEMS\n\n`):
> if FLAG1 = 2 then
> fprintf(OUP, `Iteration, Approximation\n`):
> fi:
> # Step 1
> K := 1:
> # Step 2
> while OK = TRUE and K <= NN do
> # Step 3
> G[0] := evalf(F(X, N)):
> Z0 := 0:
> for I2 from 1 to N do
> Z[I2-1] := evalf(P[I2](seq(X[i],i=0..N-1))):
> Z0 := Z0+(Z[I2-1])*(Z[I2-1]):
> od:
> Z0 := sqrt(Z0):
> # Step 4
> if Z0 <= 1.0e-20 then
> OK := FALSE:
> fprintf(OUP, `0 qradient - may have a minimum\n`):
> else
> # Step 5
> for I2 from 1 to N do
> Z[I2-1] := Z[I2-1] / Z0:
> od:
> A[0] := 0:
> X0 := 1:
> for I2 from 1 to N do
> C[I2-1] := X[I2-1]-X0*Z[I2-1]:
> od:
> G0 := evalf(F(C, N)):
> # Step 6
> FLAG := TRUE:
> if G0 < G[0] then
> FLAG := FALSE:
> fi:
> while FLAG = TRUE and OK = TRUE do
> # Steps 7 and 8
> X0 := 0.5*X0:
> if X0 <= 1.0e-20 then
> OK := FALSE:
> fprintf(OUP, `No likely improvement - may\n`):
> fprintf(OUP, `have a minimum\n`):
> else
> for I2 from 1 to N do
> C[I2-1] := X[I2-1]-X0*Z[I2-1]:
> od:
> G0 := evalf(F(C, N)):
> fi:
> if G0 < G[0] then
> FLAG := FALSE:
> fi:
> od:
> if OK = TRUE then
> A[2] := X0:
> G[2] := G0:
> # Step 9
> X0 := 0.5*X0:
> for I2 from 1 to N do
> C[I2-1] := X[I2-1]-X0*Z[I2-1]:
> od:
> A[1] := X0:
> G[1] := evalf(F(C, N)):
> # Step 10
> H1 := (G[1]-G[0])/(A[1]-A[0]):
> H2 := (G[2]-G[1])/(A[2]-A[1]):
> H3 := (H2-H1)/(A[2]-A[0]):
> # Step 11
> X0 := 0.5*(A[0]+A[1]-H1/H3):
> for I2 from 1 to N do
> C[I2-1] := X[I2-1]-X0*Z[I2-1]:
> od:
> G0 := evalf(F(C, N)):
> # Step 12
> A0 := X0:
> for I2 from 1 to N do
> if abs(G[I2-1]) < abs(G0) then
> A0 := A[I2-1]:
> G0 := G[I2-1]:
> fi:
> od:
> if abs(A0) <= 1.0e-20 then
> OK := FALSE:
> fprintf(OUP, `No change likely\n`):
> fprintf(OUP, `- probably rounding error problems\n`):
> else
> # Step 13
> for I2 from 1 to N do
> X[I2-1] := evalf(X[I2-1]-A0*Z[I2-1]):
> od:
> # Step 14
> if FLAG1 = 2 then
> fprintf(OUP, ` %2d`, K):
> for I2 from 1 to N do
> fprintf(OUP, ` %11.8f`, X[I2-1]):
> od:
> fprintf(OUP, `\n`):
> fi:
> if abs(G0) < TOL or abs(G0-G[0]) < TOL then
> OK := FALSE:
> fprintf(OUP, `Iteration number %d\n`, K):
> fprintf(OUP, `gives solution\n\n`):
> for I2 from 1 to N do
> fprintf(OUP, ` %11.8f`, X[I2-1]):
> od:
> fprintf(OUP, `\n\nto within %.10e\n\n`, TOL):
> fprintf(OUP, `Process is complete\n`):
> else
> # Step 15
> K := K+1:
> fi:
> fi:
> fi:
> fi:
> od:
> if K > NN then
> # Step 16
> fprintf(OUP, `Process does not converge in %d\n`, NN):
> fprintf(OUP, ` iterations\n`):
> fi:
> if OUP <> default then
> fclose(OUP):
> print(`Output file `,NAME,` created successfully`):
> fi:
> fi:
