home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Education
/
collectionofeducationcarat1997.iso
/
SCIENCE
/
PRAXIS.ZIP
/
PRAXIS.INC
< prev
next >
Wrap
Text File
|
1987-07-15
|
24KB
|
565 lines
(****************************************************************************)
(* P R O C E D U R E P R A X I S *)
(* *)
(* P R A X I S is for the minimization of a function in several *)
(* variables. The algorithm used is a modification of a conjugate *)
(* gradient method developed by Powell. Changes are due to Brent, *)
(* who gives an ALGOL W program. *)
(* Users who are interested in more of the details should read *)
(* - Powell, M. J. D., 1962. An efficient method for finding *)
(* the minimum of a function of several variables without *)
(* calculating derivatives, Computer Journal 7, 155-162. *)
(* - Brent, R. P., 1973. Algorithms for minimization without *)
(* derivatives. Prentice Hall, Englewood Cliffs. *)
(* If you have any further comments, questions, etc. please feel free *)
(* and contact me. *)
(* *)
(* Karl Gegenfurtner 02/17/86 *)
(* TURBO - P Version 1.0 *)
(****************************************************************************)
(* The use of PRAXIS is fairly simple. There are only two parameters: *)
(* - X is of type vector and contains on input an initial guess *)
(* of the solution. on output X holds the final solution of the *)
(* system of equations. *)
(* - N is of type integer and gives the number of unknown parameters *)
(* The result of PRAXIS is the least calculated value of the function F *)
(* F is one of the global parameters used by PRAXIS: *)
(* - F(X,N) is declared forward and is the function to be minimized *)
(* All other globals are optional, i.e. you can change them or else *)
(* PRAXIS will use some default values, which are adequate for most *)
(* problems under consideration. *)
(* - Prin controls the printout from PRAXIS *)
(* 0: no printout at all *)
(* 1: only initial and final values *)
(* 2: detailed map of the minimization process *)
(* 3: also prints eigenvalues and eigenvectors of the *)
(* direction matices in use (for insiders only). *)
(* - T is the tolerance for the precision of the solution *)
(* PRAXIS returns if the criterion *)
(* 2 * ||x(k)-x(k-1)|| <= Sqrt(MachEps) * ||x(k)|| + T *)
(* is fulfilled more than KTM times, where *)
(* - KTM is another global parameter. It's default value is 1 and *)
(* a value of 4 leads to a very(!) cautious stopping criterion *)
(* - MachEps is the relative machine precision and is *)
(* 1.0 E-15 using an 8087 and TURBO-87 and *)
(* 1.0 E-06 without 8087. *)
(* - H is a steplength parameter and shoul be set to the expected *)
(* distance to the solution. An exceptional large or small value *)
(* of H leads to slower convergence on the first few iterations. *)
(* - Scbd is a scaling parameter and should be set to about 10. *)
(* The default is 1 and with that value no scaling is done at all *)
(* It's only necessary when the parameters are scaled very different *)
(* - IllC is a Boolean variable and should be set to TRUE if the *)
(* problem is known to be illconditioned. *)
(****************************************************************************)
CONST MaxPar = 20;
TYPE Vector = ARRAY[1..MaxPar] OF REAL;
Matrix = ARRAY[1..MaxPar] OF Vector;
PrString = STRING[80];
CONST Macheps: REAL = 1.0E-08; (* set to 1.0E-13 for TURBO-87 *)
H: REAL = 1.0E+00;
T: REAL = 1.0E-05;
Prin: INTEGER = 2;
IllC: BOOLEAN = FALSE;
Scbd: REAL = 1;
Ktm: INTEGER = 2;
FUNCTION F(VAR x:Vector;n:INTEGER):REAL; FORWARD;
FUNCTION Power(a,b: REAL):REAL;
BEGIN Power := Exp(b*Ln(a));
END; (* Power *)
PROCEDURE MinFit(N:INTEGER;Eps,Tol:REAL;VAR ab:Matrix;VAR q:Vector);
LABEL TestFsplitting,
TestFconvergence,
Convergence,
Cancellation;
VAR l, kt,
l2,
i, j, k: INTEGER;
c, f, g,
h, s, x,
y, z: REAL;
e: Vector;
BEGIN (* Householders reduction to bidiagonal form *)
x:= 0; g:= 0;
FOR i:= 1 TO N DO
BEGIN e[i]:= g; s:= 0; l:= i+1;
FOR j:= i TO N DO
s:= s + Sqr(ab[j,i]);
IF s<Tol THEN g:= 0 ELSE
BEGIN f:= ab[i,i];
IF f<0
THEN g:= Sqrt(s)
ELSE g:= - Sqrt(s);
h:= f*g-s; ab[i,i]:= f - g;
FOR j:= l TO N DO
BEGIN f:= 0;
FOR k:= i TO N DO
f:= f + ab[k,i]*ab[k,j];
f:= f/h;
FOR k:= i TO N DO
ab[k,j]:= ab[k,j] + f*ab[k,i];
END; (* j *)
END; (* IF *)
q[i]:= g; s:= 0;
IF i<=N
THEN FOR j:= l TO N DO
s:= s + Sqr(ab[i,j]);
IF s<Tol THEN g:= 0 ELSE
BEGIN f:= ab[i,i+1];
IF f<0
THEN g:= Sqrt(s)
ELSE g:= - Sqrt(s);
h:= f*g-s; ab[i,i+1]:= f-g;
FOR j:= l TO N DO e[j]:= ab[i,j]/h;
FOR j:= l TO N DO
BEGIN s:= 0;
FOR k:= l TO N DO s:= s + ab[j,k]*ab[i,k];
FOR k:= l TO N DO ab[j,k]:= ab[j,k] + s*e[k];
END; (* J *)
END; (* IF *)
y:= Abs(q[i])+Abs(e[i]);
IF y > x THEN x:= y;
END; (* I *)
(* accumulation of right hand transformations *)
FOR i:= N DOWNTO 1 DO
BEGIN IF g<>0.0 THEN
BEGIN h:= ab[i,i+1]*g;
FOR j:= l TO N DO ab[j,i]:= ab[i,j]/h;
FOR j:= l TO N DO
BEGIN s:= 0;
FOR k:= l TO N DO s:= s + ab[i,k]*ab[k,j];
FOR k:= l TO N DO ab[k,j]:= ab[k,j] + s*ab[k,i];
END; (* J *)
END; (* IF *)
FOR j:= l TO N DO
BEGIN ab[j,i]:= 0;
ab[i,j]:= 0;
END;
ab[i,i]:= 1; g:= e[i]; l:= i;
END; (* I *)
(* diagonalization to bidiagonal form *)
eps:= eps*x;
FOR k:= N DOWNTO 1 DO
BEGIN kt:= 0;
TestFsplitting: kt:= kt + 1;
IF kt > 30 THEN
BEGIN e[k]:= 0;
WriteLn('+++ QR failed');
END;
FOR l2:= k DOWNTO 1 DO
BEGIN l:= l2;
IF Abs(e[l])<=Eps THEN Goto TestFconvergence;
IF Abs(q[l-1])<=Eps THEN Goto Cancellation;
END; (* L2 *)
C