LONG REAL PROCEDURE ALGOLPRAXIS (LONG REAL VALUE T, MACHEPS, H ;
INTEGER VALUE N, PRIN;
LONG REAL ARRAY X(*);
LONG REAL PROCEDURE F(long real array x(*);
integer value n));
BEGIN COMMENT:
THIS PROCEDURE MINIMIZES THE FONCTION F(X, N) OF N
VARIABLES X(1), ... X(N), USING THE PRINCIPAL AXIS METHOD.
ON ENTRY X HOLDS A GUESS, ON RETURN IT HOLDS THE ESTIMATED
POINT OF MINIMUM, WITH (HOPEFULLY) |ERROR| <
SQRT(MACHEPS)*|X| + T, WHERE MACHEPS IS THE MACHINE
PRECISION, THE SMALLEST NUMBER SUCH THAT 1 + MACHEPS > 1,
T IS A TOLERANCE, AND |.| IS THE 2-NORM. H IS THE MAXIMUM
STEP SIZE: SET TO ABOUT THE MAXIMUM EXPECTED DISTANCE FROM
THE GUESS TO THE MINIMUM (IF H IS SET TOO SMALL OR TOO
LARGE THEN THE INITIAL RATE OF CONVERGENCE WILL BE SLOW).
THE USER SHOULD OBSERVE THE COMMENT ON HEURISTIC NUMBERS
AFTER PROCEDURE QUAD.
PRIN CONTROLS THE PRINTING OF INTERMEDIATE RESULTS.
IF PRIN = 0, NO RESULTS ARE PRINTED.
IF PRIN = 1, F IS PRINTED AFTER EVERY N+1 OR N+2 LINEAR
MINIMIZATIONS, AND FINAL X IS PRINTED, BUT INTERMEDIATE
X ONLY IF N <= 4.
IF PRIN = 2, EIGENVALUES OF A AND SCALE FACTORS ARE ALSO PRINTED.
IF PRIN = 3, F AND X ARE PRINTED AFTER EVERY FEW LINEAR MINIMIZATIONS.
IF PRIN = 4, EIGENVECTORS ARE ALSO PRINTED.
FMIN IS A GLOBAL VARIABLE: SEE PROCEDURE PRINT.
RANDOM IS A PARAMETERLESS LONG REAL PROCEDURE WHICH RETURNS
A RANDOM NUMBER UNIFORMLY DISTRIBUTED IN (0, 1). ANY
INITIALIZATION MUST BE DONE BEFORE THE CALL TO PRAXIS.
THE PROCEDURE IS MACHINE-INDEPENDENT, APART FROM THE OUTPUT
STATEMENTS AND THE SPECIFICATION OF MACHEPS. WE ASSUME THAT
MACHEPS**(—4) DOES NOT OVERFLOW (IF IT DOES THEN MACHEPS MUST
BE INCREASED), AND THAT ON FLOATING-POINT UNDERFLOW THE
RESULT IS SET TO ZERO;
LONG REAL PROCEDURE RANDOM(INTEGER VALUE NAUGHT);
ALGOL "random";
PROCEDURE MINFIT (INTEGER VALUE N; LONG REAL VALUE EPS, TOL;
LONG REAL ARRAY AB(*,*); LONG REAL ARRAY Q(*));
BEGIN COMMENT: AN IMPROVED VERSION OF MINFIT, SEE GOLUB &
REINSCH (1969), RESTRICTED TO M = N, P = 0.
THE SINGULAR VALUES OF THE ARRAY AB ARE
RETURNED IN Q, AND AB IS OVERWRITTEN WITH
THE ORTHOGONAL MATRIX V SUCH THAT
U.DIAG(Q) = AB.V,
WHERE U IS ANOTHER ORTHOGONAL MATRIX;
INTEGER L, KT;
LONG REAL C,F,G,H,S,X,Y,Z;
LONG REAL ARRAY E(1::N);
COMMENT: HOUSEHOLDER'S REDUCTION TO BIDIAGONAL FORM;
G := X := 0;
FOR I := 1 UNTIL N DO
BEGIN
E(I) := G; S := 0; L := I+1;
FOR J := I UNTIL N DO S := S+AB(J,I)**2;
IF S<TOL THEN G := 0 ELSE
BEGIN
F := AB(I,I); G := IF F<0 THEN LONGSQRT(S)
ELSE -LONGSQRT(S);
H := F*G-S; AB(I,I) := F-G;
FOR J := L UNTIL N DO
BEGIN F := 0;
FOR K := I UNTIL N DO F := F + AB(K,I)*AB(K,J);
F := F/H;
FOR K := I UNTIL N DO AB(K,J) := AB(K,J) + F*AB(K,I)
END J
END S;
Q(I):=G; S:=0;
IF I<=N THEN FOR J := L UNTIL N DO
S:=S+AB(I,J)**2;
IF S<TOL THEN G := 0 ELSE
BEGIN
F := AB(I,I+1); G := IF F<0 THEN LONGSQRT(S)
ELSE -LONGSQRT(S);
H := F*G-S; AB(I,I+1) := F - G;
FOR J := L UNTIL N DO E(J) := AB(I,J)/H;
FOR J := L UNTIL N DO
BEGIN S := 0;
FOR K := L UNTIL N DO S := S + AB(J,K)*AB(I,K);
FOR K := L UNTIL N DO AB(J,K) := AB(J,K) + S*E(K)
END J
END S;
Y := ABS(Q(I)) + ABS(E(I)) ; IF Y >X THEN X := Y
END I;
COMMENT: ACCUMULATION OF RIGHT-HAND TRANSFORMATIONS;
FOR I := N STEP -1 UNTIL 1 DO
BEGIN
IF G not =0 THEN
BEGIN
H := AB(I,I+1)*G;
FOR J := L UNTIL N DO AB(J,I) := AB(I,J)/H;
FOR J := L UNTIL N DO
BEGIN S := 0;
FOR K := L UNTIL N DO S := S + AB(I,K)*AB(K,J);
FOR K := L UNTIL N DO AB(K,J) := AB(K,J) + S*AB(K,I)
END J
END G;
FOR J := L UNTIL N DO AB(I,J) := AB(J,I) := 0;
AB(I,I) := 1; G := E(I); L := I
END I;
COMMENT: DIAGONALIZATION OF THE BIDIAGONAL FORM;
EPS := EPS*X;
FOR K := N STEP -1 UNTIL 1 DO
BEGIN KT := 0;
TESTFSPLITTING:
KT := KT + 1; IF KT > 30 THEN
BEGIN E(K) := 0L;
WRITE ("QR FAILED")
END;
FOR L2 := K STEP -1 UNTIL 1 DO
BEGIN
L := L2;
IF ABS(E(L))<=EPS THEN GOTO TESTFCONVERGENCE;
IF ABS(Q(L-1))<=EPS THEN GOTO CANCELLATION
END L2;
COMMENT: CANCELLATION OF E(L) IF L>1;
CANCELLATION:
C := 0; S := 1;
FOR I := L UNTIL K DO
BEGIN
F := S*E(I); E(I) := C*E(I);
IF ABS(F)<=EPS THEN GOTO TESTFCONVERGENCE;
G := Q(I); Q(I) := H := IF ABS(F) < ABS(G) THEN
ABS(G)*LONGSQRT(1 + (F/G)**2) ELSE IF F = 0 THEN
ABS(F)*LONGSQRT(1 + (G/F)**2) ELSE 0;
IF H = 0 THEN G := H := 1;
COMMENT: THE ABOVE REPLACES Q(I):=H:=LONGSQRT(G*G+F*F)
WHICH MAY GIVE INCORRECT RESULTS IF THE
SQUARES UNDERFLOW OR IF F = G = 0;
C := G/H; S := -F/H
END I;
TESTFCONVERGENCE:
Z := Q(K); IF L=K THEN GOTO CONVERGENCE;
COMMENT: SHIFT FROM BOTTOM 2*2 MINOR;
X := Q(L); Y := Q(K-1); G := E(K-1); H := E(K);
F := ((Y-Z)*(Y+Z) + (G-H)*(G+H))/(2*H*Y);
G := LONGSQRT(F*F+1);
F := ((X-Z)*(X+Z)+H*(Y/(IF F<0 THEN F-G ELSE F+G)-H))/X;
COMMENT: NEXT QR TRANSFORMATION;
C := S := 1;
FOR I := L+1 UNTIL K DO
BEGIN
G := E(I); Y := Q(I); H := S*G; G := G*C;
E(I-1) := Z := IF ABS(F) < ABS(H) THEN
ABS(H)*LONGSQRT(1 + (F/H)**2) ELSE IF F not = 0 THEN
ABS(F)*LONGSQRT(1 + (H/F)**2) ELSE 0;
IF Z = 0 THEN Z := F := 1 ;
C := F/Z; S := H/Z;
F := X*C + G*S; G := -X*S +G*C; H := Y*S;
Y := Y*C;
FOR J := 1 UNTIL N DO
BEGIN
X := AB(J,I-1); Z := AB(J,I);
AB(J,I-1) := X*C + Z*S; AB(J,I) := -X*S + Z*C
END J;
Q(I-1) := Z := IF ABS(F) < ABS(H) THEN ABS(H)*
LONGSQRT (1 + (F/H)**2) ELSE IF F not = 0 THEN
ABS(F)*LONGSQRT(1 + (H/F)**2) ELSE 0;
IF Z = 0 THEN Z := F := 1;
C := F/Z; S := H/Z;
F := C*G + S*Y; X := -S*G + C*Y
END I ;
E(L) := 0; E(K) := F; Q(K) := X;
GO TO TESTFSPLITTING;
CONVERGENCE:
IF Z<0 THEN
BEGIN COMMENT: Q(K) IS MADE NON-NEG;
Q(K) := -Z;
FOR J := 1 UNTIL N DO AB(J,K) := -AB(J,K)
END Z
END K
END MINFIT;
PROCEDURE SORT;
BEGIN COMMENT: SORTS THE ELEMENTS OF D AND CORRESPONDING
COLUMNS OF V INTO DESCENDING ORDER;
INTEGER K;
LONG REAL S;
FOR I := 1 UNTIL N - 1 DO
BEGIN K := I; S := D(I); FOR J := I + 1 UNTIL N DO
IF D(J) > S THEN
BEGIN K := J; S := D(J) END;
IF K > I THEN
BEGIN D(K) := D(I); D(I) := S; FOR J := 1 UNTIL N DO
BEGIN S := V(J,I); V(J,I) := V(J,K); V(J,K) := S
END
END
END
END SORT;
PROCEDURE MATPRINT (STRING(80) VALUE S; LONG REAL ARRAY
V(*,*); INTEGER VALUE M, N);
BEGIN COMMENT: PRINTS M X N MATRIX V COLUMN BY COLUMN;
WRITE (S);
FOR K := 1 UNTIL (N + 7) DIV 8 DO
BEGIN FOR I := 1 UNTIL M DO
BEGIN IOCONTROL(2);
FOR J := 8*K - 7 UNTIL (IF N < (8*K) THEN N ELSE 8*K)
DO WRITEON (ROUNDTOREAL (V (I,J)))
END;
WRITE (" "); IOCONTROL(2)
END
END MATPRINT;
PROCEDURE VECPRINT (STRING(32) VALUE S; LONG REAL ARRAY V(*);
INTEGER VALUE N);
BEGIN COMMENT: PRINTS THE HEADING S AND N-VECTOR V;
WRITE(S);
FOR I := 1 UNTIL N DO WRITEON(ROUNDTOREAL(V(I)))
END VECPRINT;
PROCEDURE MIN (INTEGER VALUE J, NITS; LONG REAL VALUE
RESULT D2, X1; LONG REAL VALUE F1; LOGICAL VALUE FK);
BEGIN COMMENT:
MINIMIZES F FROM X IN THE DIRECTION V(*,J)
UNLESS J<1, WHEN A QUADRATIC SEARCH IS DONE
IN THE PLANE DEFINED BY Q0, Q1 AND X.
D2 AN APPROXIMATION TO HALF F'' (OR ZERO),
X1 AN ESTIMATE OF DISTANCE TO MINIMUM,
RETURNED AS THE DISTANCE FOUND.
IF FK = TRUE THEN F1 IS FLIN(X1), OTHERWISE
X1 AND F1 ARE IGNORED ON ENTRY UNLESS FINAL
FX > F1. NITS CONTROLS THE NUMBER OF TIMES
AN ATTEMPT IS MADE TO HALVE THE INTERVAL.
SIDE EFFECTS: USES AND ALTERS X, FX, NF, NL.
IF J < 1 USES VARIABLES Q... .
USES H, N, T, M2, M4, LDT, DMIN, MACHEPS;
LONG REAL PROCEDURE FLIN (LONG REAL VALUE L);
COMMENT: THE FUNCTION OF ONE VARIABLE L WHICH IS
MINIMIZED BY PROCEDURE MIN;
BEGIN LONG REAL ARRAY T(1::N);
IF J > 0 THEN
BEGIN COMMENT: LINEAR SEARCH;
FOR I := 1 UNTIL N DO T(I) := X(I) + L*V(I,J)
END
ELSE
BEGIN COMMENT: SEARCH ALONG A PARABOLIC SPACE-CURVE;
QA := L*(L - QD1)/(QD0*(QD0 + QD1));
QB := (L + QD0)*(QD1 - L)/(QD0*QD1);
QC := L*(L + QD0)/(QD1*(QD0 + QD1));
FOR I := 1 UNTIL N DO T(I) := QA*Q0(I) + QB*X(I) + QC*Q1(I)
END;
COMMENT: INCREMENT FUNCTION EVALUATION COUNTER;
NF := NF + 1;
F(T,N)
END FLIN;
INTEGER K; LOGICAL DZ;
LONG REAL X2, XM, F0, F2, FM, D1, T2, S, SF1, SX1;
SF1 := F1; SX1 := X1;
K := 0; XM := 0; F0 := FM := FX; DZ := (D2 < MACHEPS);
COMMENT: FIND STEP SIZE;
S := 0; FOR I := 1 UNTIL N DO S := S + X(I)**2;
S := LONGSQRT(S);
T2:= M4*LONGSQRT(ABS(FX)/(IF DZ THEN DMIN ELSE D2)
+ S*LDT) + M2*LDT;
S := M4*S + T;
IF DZ AND (T2 > S) THEN T2 := S;
IF T2 < SMALL THEN T2 := SMALL;
IF T2 > (0.01*H) THEN T2 := 0.01*H;
IF FK AND (F1 <= FM) THEN BEGIN XM := X1; FM:=F1 END;
IF not FK OR (ABS(X1) < T2) THEN
BEGIN X1 := IF X1 >= 0L THEN T2 ELSE -T2;
F1 := FLIN(X1)
END;
IF F1 <= FM THEN BEGIN XM := X1; FM := F1 END;
L0: IF DZ THEN
BEGIN COMMENT: EVALUATE FLIN AT ANOTHER POINT AND
ESTIMATE THE SECONO DERIVATIVE;
X2 := IF F0 < F1 THEN -X1 ELSE 2*X1;F2:=FLIN(X2);
IF F2 <= FM THEN BEGIN XM := X2; FM := F2 END;
D2 := (X2*(F1 - F0) - X1*(F2 - F0))/(X1*X2*(X1 - X2))
END;
COMMENT: ESTIMATE FIRST DERIVATIVE AT 0;
D1 := (F1 - F0)/X1 - X1*D2; DZ := TRUE;
COMMENT: PREDICT MINIMUM;
X2 := IF D2 <- SMALL THEN (IF D1 < 0 THEN H ELSE -H) ELSE
-0.5L*D1/D2;
IF ABS(X2) > H THEN X2 := IF X2 > 0 THEN H ELSE -H;
COMMENT: EVALUATE F AT THE PREDICTED M(NIMUM;
L1: F2 := FLIN(X2);
IF (K < NITS) AND (F2 > F0) THEN
BEGIN COMMENT: NO SUCCESS SO TRY AGAIN; K := K + 1;
IF (F0 < F1) AND ((X1*X2) > 0) THEN GO TO L0;
X2 := 0.5L*X2; GO TO L1
END;
COMMENT: INCREMENT ONE-DIMENSIONAL SEARCH COUNTER;
NL := NL + 1;
IF F2 > FM THEN X2 := XM ELSE FM := F2;
COMMENT: GET NEW ESTIMATE OF SECUND DERIVATIVE;
D2 := IF ABS(X2*(X2 - X1)) > SMALL THEN
(X2*(F1 - F0) - X1*(FM - F0))/(X1*X2*(X1 - X2))
ELSE IF K > 0 THEN 0 ELSE D2;
IF D2 <= SMALL THEN D2 := SMALL;
X1 := X2; FX := FM;
IF SF1 < FX THEN BEGIN FX := SF1; X1 := SX1 END;
COMMENT: UPDATE X FOR LINEAR SEARCH BUT NOT FOR PARABOLIC
PARABOLIC SEARCH;
IF J > 0 THEN FOR I := 1 UNTIL N DO X(I) := X(I) + X1*V(I,J)
END MIN;
PROCEDURE QUAD;
BEGIN COMMENT: LOOKS FOR THE MINIMUM ALONG A CURVE
DEFINED BY Q0, Q1 AND X;
LONG REAL L, S;
S := FX; FX := QF1; QF1 := S; QD1 := 0;
FOR I := 1 UNTIL N DO
BEGIN S := X(I); X(I) := L := Q1(I); Q1(I):= S;
QD1 := QD1 + (S - L)**2
END;
L := QD1 := LONGSQRT(QD1); S := 0;
IF (QD0 > 0) AND (QD1 > 0) AND (NL >= (3*N*N)) THEN
BEGIN MIN (0, 2, S, L, QF1, TRUE);
QA := L*(L - QD1)/(QD0*(QD0 + QD1));
QB := (L + QD0)*(QD1 - L)/(QD0*QD1);
QC := L*(L + QD0)/(QD1*(QD0 + QD1))
END
ELSE BEGIN FX := QF1; QA := QB := 0; QC := 1 END;
QD0 := QD1; FOR I := 1 UNTIL N DO
BEGIN S := Q0(I); Q0(1) := X(I);
X(I) := QA*S + QB*X(I) + QC*Q1(I)
END
END QUAD;
PROCEDURE PRINT;
COMMENT: THE VARIABLE FMIN IS GLOBAL, AND ESTIMATES THE
VALUE OF F AT THE MINIMUM: USED ONLY FOR
PRINTING LOG(FX - FMIN);
IF PRIN > 0 THEN
BEGIN INTEGER SVINT; long real fmin;
SVINT := I_W;
I_W := 10; % print integers in 10 column fields %
WRITE (NL, NF, FX);
COMMENT: IF THE NEXT TWO LINES ARE OMITTED THEN FMIN IS
NOT REQUIRED;
IF FX <= FMIN THEN WRITEON (" UNDEFINED ") ELSE
WRITEON (ROUNDTOREAL (LONGLOG (FX - FMIN )));
COMMENT: "IOCONTROL(2)" MOVES TO THE NEXT LINE;
IF N > 4 THEN IOCONTROL(2);
IF (N <= 4) OR (PRIN > 2) THEN
FOR I := 1 UNTIL N DO WRITEON(ROUNDTOREAL(X(I)));
IOCONTROL(2);
I_W := SVINT
END PRINT;
LOGICAL ILLC;
INTEGER NL, NF, KL, KT, KTM;
LONG REAL S, SL, DN, DMIN, FX, F1, LDS, LDT, SF, DF,
QF1, QD0, QD1, QA, QB, QC,
M2, M4, SMALL, VSMALL, LARGE, VLARGE, SCBD, LDFAC, T2;
LONG REAL ARRAY D, Y, Z, Q0, Q1 (1::N);
LONG REAL ARRAY V (1::N, 1::N);
COMMENT: INITIALIZATION;
COMMENT: MACHINE DEPENDENT NUMBERS;
SMALL := MACHEPS**2; VSMALL := SMALL**2;
LARGE := 1L/SMALL; VLARGE := 1L/VSMALL;
M2 := LONGSQRT(MACHEPS); M4 := LONGSQRT(M2);
COMMENT: HEURISTIC NUMBERS
•••••••••••••
IF AXES MAY BE BADLY SCALED (WHICH IS TO BE AVOIDED IF
POSSIBLE! THEN SET SCBD := 10, OTHERWISE 1,
IF THE PROBLEM IS KNOWN TO BE ILLCONDITIONED SET
ILLC := TRUE, OTHERWISE FALSE,
KTM+1 IS THE NUMBER OF ITERATIONS WITHOUT IMPROVEMENT BEFORE
THE ALGORITHM TERMINATES (SEE SECTION 6). KTM = 4, IS VERY
CAUTIOUS: USUALLY KTM = 1 IS SATISFACTORY;
SCBD := 1; ILLC := FALSE; KTM := 1;
LDFAC := IF ILLC THEN 0.1 ELSE 0.01;
KT := NL := 0; NF := 1; QF1 := FX := F(X,N);
T := T2 := SMALL + ABS(T); DMIN := SMALL;
IF H < (100*T) THEN H := 100*T; LDT := H;
FOR I := 1 UNTIL N DO FOR J := 1 UNTIL N DO
V(I,J) := IF I = J THEN 1L ELSE 0L;
D(1) := QD0 := 0; FOR I := 1 UNTIL N DO Q1(I) := X(I);
PRINT;
COMMENT: MAIN LOOP;
L0: SF := D(1); D(1) := S := 0;
COMMENT: MINIMIZE ALONG FIRST DIRECTION;
MIN (1, 2, D(1), S, FX, FALSE);
IF S <= 0 THEN FOR I := 1 UNTIL N DO V(I,1) := -V(I,1);
IF (SF <= (0.9*D(1))) OR ((0.9*SF) >= D(1)) THEN
FOR I := 2 UNTIL N DO D(I) := 0;
FOR K := 2 UNTIL N DO
BEGIN FOR I := 1 UNTIL N DO Y(I) := X(I); SF := FX;
ILLC := ILLC OR (KT > 0);
L1: KL := K; DF := 0; IF ILLC THEN
BEGIN COMMENT: RANDOM STEP TO GET OFF RESOLUTION VALLEY;
FOR I := 1 UNTIL N DO
BEGIN S := Z(I) := (0.1*LDT + T2*10**KT)*(RANDOM(I)-0.5L);
COMMENT: PRAXIS ASSUMES THAT RANDOM RETURNS A RANDOM
NUMBER UNIFORMLY DISTRIBUTED IN (0, 1) AND
THAT ANY INITIALIZATION OF THE RANDOM NUMBER
GENERATOR HAS ALREADY BEEN DONE;
FOR J := 1 UNTIL N DO X(J) := X(J) + S*V(J,I)
END;
FX := F(X,N); NF := NF + 1
END;
FOR K2 := K UNTIL N DO
BEGIN SL := FX; S := 0;
COMMENT: MINIMIZE ALONG "NON-CONJUGATE" DIRECTIONS;
MIN (K2, 2, D(K2), S, FX, FALSE);
S := IF ILLC THEN D(K2)*(S + Z(K2))**2 ELSE SL - FX;
IF DF < S THEN
BEGIN DF := S; KL := K2
END
END;
IF not ILLC AND (DF < ABS( 100*MACHEPS*FX)) THEN
BEGIN COMMENT: NO SUCCESS ILLC = FALSE SO TRY ONCE
WITH ILLC = TRUE;
ILLC := TRUE; GO TO L1
END;
IF (K = 2) AND (PRIN > 1) THEN VECPRINT ("NEW D", D, N);
FOR K2 := 1 UNTIL K - 1 DO
BEGIN COMMENT: MINIMIZE ALONG "CONJUGATE" DIRECTIONS;
S := 0; MIN (K2, 2, D(K2), S, FX, FALSE)
END;
F1 := FX; FX := SF; LDS := 0;
FOR I := 1 UNTIL N DO
BEGIN SL := X(I); X(I) := Y(I); SL := Y(I) := SL - Y(I);
LDS := LDS + SL*SL
END;
LDS := LONGSQRT(LDS); IF LDS > SMALL THEN
BEGIN COMMENT: THROW AWAY DIRECTION KL AND MINIMIZE
ALONG THE NEW "CONJUGATE" DIRECTION;
FOR I := KL - 1 STEP -1 UNTIL K DO
BEGIN FOR J := 1 UNTIL N DO V(J,I + 1) := V(J,I);
D(I + 1) := D(I)
END;
D(K) := 0; FOR I := 1 UNTIL N DO V(I,K) := Y(I)/LDS;
MIN (K, 4, D(K), LDS, F1, TRUE);
IF LDS <= 0 THEN
BEGIN LDS := -LDS;
FOR I := 1 UNTIL N DO V(I,K) := -V(I,K)
END
END;
LDT := LDFAC*LDT; IF LDT < LDS THEN LDT := LDS;
PRINT;
T2 := 0; FOR I := 1 UNTIL N DO T2 := T2 + X(I)**2;
T2 := M2*LONGSQRT(T2) + T;
COMMENT: SEE IF STEP LENGTH EXCEEDS HALF THE TOLERANCE;
KT := IF LDT > (0.5*T2) THEN 0 ELSE KT + 1;
IF KT > KTM THEN GO TO L2
END;
COMMENT: TRY QUADRATIC EXTRAPOLATION IN CASE WE ARE STUCK
IN A CURVED VALLEY;
QUAD;
DN := 0; FOR I := 1 UNTIL N DO
BEGIN D(I) := 1/LONGSQRT(D(I));
IF DN < D(I) THEN DN : = D(I)
END;
IF PRIN > 3 THEN MATPRINT ("NEW DIRECTIONS", V, N, N);
FOR J := 1 UNTIL N DO
BEGIN S := D(J)/DN;
FOR I := 1 UNTIL N DO V(I,J) := S*V(I,J)
END;
IF SCBD > 1 THEN
BEGIN COMMENT: SCALE AXES TO TRY TO REDUCE CONDITION
NUMBER;
S := VLARGE; FOR I := 1 UNTIL N DO
BEGIN SL := 0; FOR J := 1 UNTIL N DO SL := SL+V(I,J)**2;
Z(I) := LONGSQRT(SL);
IF Z(I) < M4 THEN Z(I) := M4; IF S > Z(I) THEN S := Z(I)
END;
FOR I := 1 UNTIL N DO
BEGIN SL := S/Z(I); Z(I) := 1/SL; IF Z(I) > SCBD THEN
BEGIN SL := 1/SCBD; Z(I) := SCBD
END;
FOR J := 1 UNTIL N DO V(I,J) := SL*V(I,J)
END
END;
COMMENT: TRANSPOSE V FOR MINFIT LINE BEFORE WAS OMMITTED IN PUBLICATION;
FOR I := 2 UNTIL N DO FOR J := 1 UNTIL I - 1 DO
BEGIN S := V(I,J); V(I,J) := V(J,I); V(J,I) := S END;
COMMENT: FIND THE SINGULAR VALUE DECOMPOSITION OF V, THIS
GIVES THE EIGENVALUES AND PRINCIPAL AXES OF THE
APPROXIMATING QUADRATIC FORM WITHOUT SQUARING THE
CONDITION NUMBER;
MINFIT (N, MACHEPS, VSMALL, V, D);
IF SCBD > 1 THEN
BEGIN COMMENT: UNSCALlNG; FOR I := 1 UNTIL N DO
BEGIN S := Z(I) ;
FOR J := 1 UNTIL N DO V(I,J) := S*V(I,J)
END;
FOR I := 1 UNTIL N DO
BEGIN S := 0; FOR J := 1 UNTIL N DO S := S + V(J,I)**2;
S := LONGSQRT(S); D(I) := S*D(I); S := 1/S;
FOR J := 1 UNTIL N DO V(J,I) := S*V(J,I)
END
END;
FOR I := 1 UNTIL N DO
BEGIN D(I) := IF (DN*D(I)) > LARGE THEN VSMALL ELSE
IF (DN*D(I)) < SMALL THEN VLARGE ELSE (DN*D(I))**(-2)
END;
COMMENT: SORT NEW EIGENVALUES AND EIGENVECTORS;
SORT;
DMIN := D(N) ; IF DMIN < SMALL THEN DMIN := SMALL;
ILLC := (M2*D(1)) > DMIN;
IF (PRIN > 1) AND (SCBD > 1) THEN
VECPRINT ("SCALE FACTORS", Z, N);
IF PRIN > 1 THEN VECPRINT ("EIGENVALUES OF A", D, N);
IF PRIN > 3 THEN MATPRINT ("EIGENVECTORS OF A", V, N, N);
COMMENT: GO BACK TO MAIN LOOP;
GO TO L0;
L2: IF PRIN > 0 THEN VECPRINT ("X IS", X, N);
FX
END ALGOLPRAXIS.
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>