1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| Unit LoiNormalInverse;
interface
Function LoiNormaleInverse(fProb : Single;dMean,dEcartType : Double) : Single ;
implementation
Const
gcUMax : Double = 55.5 ;
gcInvNCRMax : Single = 99;
Function IIf(bVal : Boolean; val1,val2 : Single) : Single;
begin
if bVal Then
result := val1
else
result := val2 ;
end;
Function CalculAireZ(z : Double) : Single;
var
f , u , s , t , s1 : Double;
fini : Boolean;
begin
u := z * z
If (u > gcUMax) Then
Result := IIf(z > 0, 1, 0)
Else
begin
Notfini := true;
t := 1;
f := 3;
While Notfini do
begin
s1 := s;
s := s + t;
t := t * u / f;
f := f + 2;
Notfini := s<>s1;
end
Result := z * s / ((8 * ArcTan(1) * Exp(u)) ^ 0.5) + 0.5
End
End;
Function LoiStdNormaleInverse(aProb : Single) : Single;
Const cdEPSILON : Double = 0.0000001;
ciMaxIter : Integer = 50;
Var
dMax , dMin, dCalcZ : Double;
i : Integer;
bSign :Boolean;
fProb : Single
begin
fProb := aProb
if fProb <= 0 Then
Result := -gcInvNCRMax
Else
If fProb >= 1 Then
Result := gcInvNCRMax
Else
begin
dMin := -Sqr(gcUMax)
If fProb > 0.5 Then
begin
fProb := 1 - fProb
bSign := True
End
While (Abs(dMax - dMin) >= cdEPSILON) And (i < ciMaxIter) do
begin
dCalcZ := (dMax + dMin) * 0.5
If CalculAireZ(dCalcZ) < fProb Then
dMin = dCalcZ
Else
dMax = dCalcZ ;
i = i + 1;
end
Result = IIf(bSign, -dCalcZ, dCalcZ)
End;
End;
Function LoiNormaleInverse(aProb : Single;dMean,dEcartType : Double) : Single
begin
Result := NormaleStdInverse(aProb)
If (Result > -gcInvNCRMax) And (Result < gcInvNCRMax) Then
Result := (Result * dEcartType) + dMean;
End;
end; |
Partager