📄 unit2.pas
字号:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, unit1,Controls, Forms, Dialogs;
Function F1DIM(X:real):real;
Procedure POWELL(var P:array of real;var XI:matrx2;
N, NP:integer; FTOL:real;var ITER:integer;var FRET:real);
Function BESSJ0(X:real):real;
implementation
Function F1DIM(X:real):real;
var
XT:array[0..50] of real;
J:integer;
begin
For J:=1 To NCOM do
XT[J]:=PCOM[J] + X * XICOM[J];
F1DIM:=FUNC2(XT, NCOM);
end;
Procedure MNBRAK(var AX, BX, CX, FA, FB, FC:real);
const
GOLD = 1.618034; GLIMIT = 100; TINY = 1E-20;
var
DUM,R,Q,U,ULIM,FU:real; DONE:boolean;
begin
FA:=FUNC(AX);
FB:=FUNC(BX);
If FB > FA Then
begin
DUM:=AX;
AX:=BX;
BX:=DUM;
DUM:=FB;
FB:=FA;
FA:=DUM;
end;
CX:=BX + GOLD * (BX - AX);
FC:=FUNC(CX);
repeat
If FB < FC Then break;
DONE:=true;
R:=(BX - AX) * (FB - FC);
Q:=(BX - CX) * (FB - FA);
DUM:=Q - R;
If Abs(DUM) < TINY Then DUM:=TINY;
U:=BX - ((BX - CX) * Q - (BX - AX) * R) / (2 * DUM);
ULIM:=BX + GLIMIT * (CX - BX);
If (BX - U) * (U - CX) > 0 Then
begin
FU:=FUNC(U);
If FU < FC Then
begin
AX:=BX;
FA:=FB;
BX:=U;
FB:=FU;
Exit;
end
Else If FU > FB Then
begin
CX:=U;
FC:=FU;
Exit;
end;
U:=CX + GOLD * (CX - BX);
FU:=FUNC(U);
end
Else If (CX - U) * (U - ULIM) > 0 Then
begin
FU:=FUNC(U);
If FU < FC Then
begin
BX:=CX;
CX:=U;
U:=CX + GOLD * (CX - BX);
FB:=FC;
FC:=FU;
FU:=FUNC(U);
end;
end
Else If (U - ULIM) * (ULIM - CX) >= 0 Then
begin
U:=ULIM;
FU:=FUNC(U);
end
Else
begin
U:=CX + GOLD * (CX - BX);
FU:=FUNC(U);
end;
If DONE Then
begin
AX:=BX;
BX:=CX;
CX:=U;
FA:=FB;
FB:=FC;
FC:=FU;
end
Else
DONE:=false;
until not DONE
end;
Function BRENT(AX, BX, CX, TOL:real;var XMIN:real):real;
label 1,2,3;
const
ITMAX = 100; CGOLD = 0.381966; ZEPS = 0.1e-9;
var
A,B,D,V,X,W,E,FV1,XM,TOL1,TOL2,FX,FW,P,Q,R,ETEMP,DUM,U,ZZ,FU:real;
ITER,I:integer;
begin
A:=AX;
If CX < AX Then A:=CX;
B:=AX;
If CX > AX Then B:=CX;
V:=BX;
W:=V;
X:=V;
E:=0;
FX:=FUNC(X);
FV1:=FX;
FW:=FX;
For ITER:=1 To ITMAX do
begin
XM:=0.5 * (A + B);
TOL1:=TOL * Abs(X) + ZEPS;
TOL2:=2 * TOL1;
If Abs(X - XM) <= TOL2 - 0.5 * (B - A) Then goto 3;
If Abs(E) > TOL1 Then
begin
R:=(X - W) * (FX - FV1);
Q:=(X - V) * (FX - FW);
P:=(X - V) * Q - (X - W) * R;
Q:=2 * (Q - R);
If Q > 0 Then P:=-P;
Q:=Abs(Q);
ETEMP:=E;
E:=D;
DUM:=Abs(0.5 * Q * ETEMP);
If (Abs(P)>=DUM) or (P<=Q*(B - X)) or (P>=Q*(B - X)) Then
GOTO 1;
D:=P / Q;
U:=X + D;
If (U - A < TOL2) Or (B - U < TOL2) Then
begin
if XM-X>=0 then
ZZ:=1
else
ZZ:=-1;
D:=Abs(TOL1) * ZZ;
end;
goto 2;
end;
1: If X >= XM Then
E:=A - X
Else
E:=B - X;
D:=CGOLD * E;
2: If Abs(D) >= TOL1 Then
U:=X + D
Else
begin
if D >= 0 THEN
ZZ:=1
else
ZZ:=-1;
U:=X + Abs(TOL1) * ZZ;
end;
FU:=FUNC(U);
If FU <= FX Then
begin
If U >= X Then
A:=X
Else
B:=X;
V:=W;
FV1:=FW;
W:=X;
FW:=FX;
X:=U;
FX:=FU;
end
else
begin
If U < X Then
A:=U
else
B:=U;
If (FU <= FW) Or (W = X) Then
begin
V:=W;
FV1:=FW;
W:=U;
FW:=FU;
end
Else If (FU <= FV1) Or (V = X) Or (V = W) Then
begin
V:=U;
FV1:=FU;
end;
end;
end;
If ITER > ITMAX Then ShowMessage('Brent exceed maximum iterations.');
3: XMIN:=X;
BRENT:=FX;
end;
Procedure LINMIN(var P,XI:array of real; N:integer;var FRET:real);
var
TOL,AX,BX,XX,FA,FB,FX,XMIN:real; J:integer;
begin
TOL:=0.0001;
NCOM:=N;
For J:=1 To N do
begin
PCOM[J]:=P[J];
XICOM[J]:=XI[J];
end;
AX:=0 ;
XX:=1;
MNBRAK(AX, XX, BX, FA, FX, FB);
FRET:=BRENT(AX, XX, BX, TOL, XMIN);
For J:=1 To N do
begin
XI[J]:=XMIN * XI[J];
P[J]:=P[J] + XI[J];
end;
end;
Procedure POWELL(var P:array of real;var XI:matrx2;
N, NP:integer; FTOL:real;var ITER:integer;var FRET:real);
const
ITMAX = 200;
var
PT, PTT, XIT:array[0..20] of real;
I,J,IBIG:integer; FP,DEL,FPTT,DUM,T:real;
begin
FRET:=FUNC2(P, N);
For J:=1 To N do
PT[J]:=P[J];
ITER:=0;
while true do
begin
repeat
repeat
ITER:=ITER + 1;
FP:=FRET;
IBIG:=0;
DEL:=0;
For I:=1 To N do
begin
For J:=1 To N do
XIT[J]:=XI[J, I];
FPTT:=FRET;
LINMIN(P, XIT, N, FRET);
If Abs(FPTT - FRET) > DEL Then
begin
DEL:=Abs(FPTT - FRET);
IBIG:=I;
end;
end;
If 2 * Abs(FP - FRET) <= FTOL * (Abs(FP) + Abs(FRET)) Then
Exit;
If ITER = ITMAX Then
begin
ShowMessage('POWELL exceeding maximum iterations');
Exit;
end;
For J:=1 To N do
begin
PTT[J]:=2 * P[J] - PT[J];
XIT[J]:=P[J] - PT[J];
PT[J]:=P[J];
end;
FPTT:=FUNC2(PTT, N);
until FPTT >= FP;
DUM:=FP - 2 * FRET + FPTT;
T:=2 * DUM * Sqr(FP - FRET - DEL) - DEL * Sqr(FP - FPTT);
until T >= 0;
LINMIN(P, XIT, N, FRET);
For J:=1 To N do
XI[J, IBIG]:=XIT[J]
end;
end;
Function BESSJ0(X:real):real;
var
AAA,BBB,CCC,Y,AX,Z,DDD,EEE,XX:real;
const
P1=1; P2=-0.001098628627;
P3=0.2734510407e-4; P4=-0.2073370639e-5;
P5=2.093887211E-07;
Q1=-0.1562499995e-1; Q2=0.1430488765e-3;
Q3=-0.6911147651e-5; Q4=7.621095161E-07;
Q5=-9.34945152E-08;
R1=57568490574; R2=-13362590354;
R3=651619640.7; R4=-11214424.18;
R5=77392.33017; R6=-184.9052456;
S1=57568490411; S2=1029532985;
S3=9494680.718; S4=59272.64853;
S5=267.8532712; S6=1;
begin
If Abs(X) < 8 Then
begin
Y:=X * X;
BBB:=Y* (R4+ Y* (R5+ Y* R6));
AAA:=R1+ Y* (R2+ Y* (R3+ BBB));
CCC:=Y* (S3+ Y* (S4+ Y* (S5+ Y* S6)));
BESSJ0:= AAA / (S1+ Y* (S2+ CCC));
end
Else
begin
AX:=Abs(X);
Z:=8/ AX;
Y:=Z* Z;
XX:= AX- 0.785398164;
CCC:=Y* (P3+ Y* (P4+ Y* P5));
AAA:=P1+ Y* (P2+ CCC);
DDD:=Y* (Q3+ Y* (Q4+ Y* Q5));
EEE:=Z* Sin(XX) * (Q1+ Y* (Q2+ DDD));
BESSJ0:= Sqrt(0.636619772 / AX) * (Cos(XX) * AAA- EEE);
End;
End;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -