📄 estimate.~dpr
字号:
library Estimate;
{可靠性参数估计}
uses
SysUtils,
Classes,
Math,
u_EstimateInt in 'u_EstimateInt.pas';
{$R *.RES}
{二项分布密度函数}
function BinDistf(r,n:Integer; p:Single):Double;StdCall;
var
i:integer;
temp:Double;
begin
temp:=1;
//计算C(n,r)
if (r=0) or (r=n) then
begin
temp:=n;
end
else
begin
for i:=n downto (n-r+1) do temp:=temp*i;
for i:=r downto 1 do temp:=temp/i;
end;
temp:=temp*Power(p,r)*Power(1-p,n-r);
result:=temp;
end;
{二项分布累计函数}
function BinDistFT(r,n:Integer; p:Single):Double;StdCall;
var
i:integer;
temp:Double;
begin
temp:=0;
for i:=0 to r do
begin
temp:=temp+BinDistf(i,n,p);
end;
result:=temp;
end;
{二项分布点估计}
function BinDistPointEsti(r,n:Integer):Double;StdCall;
begin
result:=r/n;
end;
{对数正态分布点估计}
function LogNormDistPointEsti(FixTime:TTimeList):Double;StdCall;
var
i,n:integer;
temp:Double;
begin
temp:=0;
n:=length(FixTime);
for i:=0 to n-1 do
temp:=temp+ln(FixTime[i].Time);
result:=temp/n;
end;
{指数分布密度函数}
function ExpDistf(lambda,t:Double):Double;StdCall;
begin
result:=lambda*Exp(-lambda*t);
end;
{指数分布累计函数}
function ExpDistFT(lambda,t:Double):Double;StdCall;
begin
result:=1-Exp(-lambda*t);
end;
{指数分布点估计}
function ExpDistPointEsti(WorkTime:TTimeList):Double;StdCall;
var
i,r:integer;
total:Double;
begin
r:=0;
total:=0;
for i:=0 to length(WorkTime) do
begin
total:=total+WorkTime[i].Time;
if WorkTime[i].Failed then Inc(r);
end;
if r>0 then
result:=total/r
else
result:=-1;
end;
{威布尔分布密度函数}
function WeibullDistf(beta,eta,gamma,t:Double):Double;StdCall;
var
temp1,temp2:Double;
begin
temp1:=(t-gamma)/eta;
if temp1=0 then temp1:=0.001;
if temp1>0 then
begin
temp2:=Power(temp1,beta-1);
result:=(beta/eta)*temp2*Exp(-temp2*temp1);
end
else
result:=0;
end;
{威布尔分布累计函数}
function WeibullDistFT(beta,eta,gamma,t:Double):Double;StdCall;
var
temp:Double;
begin
temp:=(t-gamma)/eta;
if temp>0 then
result:=1-Exp(-Power((t-gamma)/eta,beta))
else
result:=0;
end;
{威布尔分布累计函数反函数}
function WeibullDistFA(beta,eta,gamma,F:Double):Double;StdCall;
begin
result:=gamma+eta*Power(-ln(1-F),1/beta);
end;
{二参数威布尔分布点估计-最小二乘估计}
function Weibull2PointEstiLeast(WorkTime:TTimeList; var beta, eta:Double):Boolean;StdCall;
var
TimeR:TSampleRList;
PointList:TPointList;
i,n:integer;
a,b,r:Double;
begin
n:=length(WorkTime);
SetLength(TimeR,n);
n:=TruncationR(WorkTime,TimeR);
SetLength(TimeR,n);
SetLength(PointList,n);
for i:=0 to n-1 do
begin
PointList[i].X:=ln(TimeR[i].Time);
PointList[i].Y:=ln(-ln(TimeR[i].R));
end;
r:=LeastSquaresFit(PointList,a,b);
beta:=b;
eta:=exp(-a/b);
Result:=(r>0.999);
end;
{三参数威布尔分布点估计-最小二乘估计}
function Weibull3PointEstiLeast(WorkTime:TTimeList; var beta, eta, gamma:Double):Boolean;StdCall;
var
TimeR:TSampleRList;
PointList:TPointList;
i,n:integer;
a,b,r:Double;
gammaL,gammaR:Double;
rL,rR,deltaL,deltaR,delta:Double;
Flag:Boolean;
begin
n:=Length(WorkTime);
SetLength(TimeR,n);
n:=TruncationR(WorkTime,TimeR);
SetLength(TimeR,n);
SetLength(PointList,n);
gammaL:=0;
gammaR:=TimeR[0].Time-0.1;
for i:=0 to n-1 do
PointList[i].Y:=ln(-ln(TimeR[i].R));
Flag:=True;
//左侧斜率
for i:=0 to n-1 do
PointList[i].X:=ln(TimeR[i].Time-gammaL);
rL:=LeastSquaresFit(PointList,a,b);
for i:=0 to n-1 do
PointList[i].X:=ln(TimeR[i].Time-gammaL-0.001);
deltaL:=(LeastSquaresFit(PointList,a,b)-rL)*1000;
//右侧斜率
for i:=0 to n-1 do
PointList[i].X:=ln(TimeR[i].Time-gammaR);
rR:=LeastSquaresFit(PointList,a,b);
for i:=0 to n-1 do
PointList[i].X:=ln(TimeR[i].Time-gammaR-0.001);
deltaR:=(LeastSquaresFit(PointList,a,b)-rR)*1000;
//判断是否有最大值
if (deltaL*deltaR>0) then
begin
Flag:=False;
if (deltaL>0) then
gamma:=gammaR
else
gamma:=gammaL;
end;
while Flag do
begin
//估计最大值
gamma:=(gammaR*deltaL-gammaL*deltaR)/(deltaL-deltaR);
//计算该点斜率
for i:=0 to n-1 do
PointList[i].X:=ln(TimeR[i].Time-gamma);
r:=LeastSquaresFit(PointList,a,b);
for i:=0 to n-1 do
PointList[i].X:=ln(TimeR[i].Time-gamma-0.001);
delta:=(LeastSquaresFit(PointList,a,b)-r)*1000;
//判断逼近
if (delta*deltaL>0) then
begin
gammaL:=gamma;
deltaL:=delta;
end
else
begin
gammaR:=gamma;
deltaR:=delta;
end;
//判断迭代是否结束
if (gammaR-gammaL<0.01) then
begin
Flag:=False;
gamma:=(gammaR+gammaL)/2;
end;
end;
for i:=0 to n-1 do
PointList[i].X:=ln(TimeR[i].Time-gamma);
r:=LeastSquaresFit(PointList,a,b);
beta:=b;
eta:=exp(-a/b);
Result:=(r>0.999);
end;
{截尾数据可靠度计算}
function TruncationR(var WorkTime:TTimeList;CalResult:TSampleRList):integer;StdCall;
var
i,j,n:integer;
temp:TSample;
flag:Boolean;
r:Single;
begin
//按时间排序
flag:=True;
j:=length(WorkTime)-2;
while flag do
begin
flag:=False;
for i:=0 to j do
begin
if WorkTime[i].Time>WorkTime[i+1].Time then
begin
temp:=WorkTime[i];
WorkTime[i]:=WorkTime[i+1];
WorkTime[i+1]:=temp;
flag:=True;
end;
end;
Dec(j);
end;
//标记记录编号,计算R
j:=0;
r:=0;
n:=length(WorkTime);
for i:=0 to n-1 do
begin
if WorkTime[i].Failed then
begin
CalResult[j].Time:=WorkTime[i].Time;
r:=r+(n+1-r)/(n+1-i);
CalResult[j].R:=1-(r-0.3)/(n+0.4); //使用中位秩公式计算
Inc(j);
end;
end;
Result:=j;
end;
{最小二乘法直线拟合y=a+bx}
function LeastSquaresFit(PointList:TPointList;var a,b:Double):Double;StdCall;
var
i,n:integer;
sum_x,sum_y,sum_xy,sum_x2:Double;
avg_x,avg_y:Double;
delta_x,delta_y:Double;
sum_delta_xy,sum_delta_x2,sum_delta_y2:Double;
begin
n:=length(PointList);
sum_x:=0;
sum_y:=0;
sum_xy:=0;
sum_x2:=0;
for i:=0 to n-1 do
begin
sum_x:=sum_x+PointList[i].X;
sum_y:=sum_y+PointList[i].Y;
sum_xy:=sum_xy+PointList[i].X*PointList[i].Y;
sum_x2:=sum_x2+Power(PointList[i].X,2);
end;
a:=(sum_xy*sum_x-sum_y*sum_x2)/(Power(sum_x,2)-n*sum_x2);
b:=(sum_x*sum_y-n*sum_xy)/(Power(sum_x,2)-n*sum_x2);
avg_x:=sum_x/n;
avg_y:=sum_y/n;
sum_delta_xy:=0;
sum_delta_x2:=0;
sum_delta_y2:=0;
for i:=0 to n-1 do
begin
delta_x:=PointList[i].X-avg_x;
delta_y:=PointList[i].Y-avg_y;
sum_delta_xy:=sum_delta_xy+delta_x*delta_y;
sum_delta_x2:=sum_delta_x2+Power(delta_x,2);
sum_delta_y2:=sum_delta_y2+Power(delta_y,2);
end;
result:=sum_delta_xy/(Sqrt(sum_delta_x2)*Sqrt(sum_delta_y2));
end;
{引出函数名}
exports
BinDistf, BinDistFT, BinDistPointEsti,
LogNormDistPointEsti,
ExpDistf, ExpDistFT, ExpDistPointEsti,
WeibullDistf, WeibullDistFT, WeibullDistFA,
Weibull2PointEstiLeast,Weibull3PointEstiLeast,
TruncationR,
LeastSquaresFit;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -