Need code for Inverse Error Function

前端 未结 7 1871
清歌不尽
清歌不尽 2021-02-10 00:54

Does anyone know where I could find code for the \"Inverse Error Function?\" Freepascal/Delphi would be preferable but C/C++ would be fine too.

The TMath/DMath library d

7条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-02-10 01:35

    Here's an implementation of erfinv(). Note that for it to work well, you also need a good implementation of erf().

    function erfinv(const y: Double): Double;
    
    //rational approx coefficients
    const
      a: array [0..3] of Double = ( 0.886226899, -1.645349621,  0.914624893, -0.140543331);
      b: array [0..3] of Double = (-2.118377725,  1.442710462, -0.329097515,  0.012229801);
      c: array [0..3] of Double = (-1.970840454, -1.624906493,  3.429567803,  1.641345311);
      d: array [0..1] of Double = ( 3.543889200,  1.637067800);
    
    const
      y0 = 0.7;
    
    var
      x, z: Double;
    
    begin
      if not InRange(y, -1.0, 1.0) then begin
        raise EInvalidArgument.Create('erfinv(y) argument out of range');
      end;
    
      if abs(y)=1.0 then begin
        x := -y*Ln(0.0);
      end else if y<-y0 then begin
        z := sqrt(-Ln((1.0+y)/2.0));
        x := -(((c[3]*z+c[2])*z+c[1])*z+c[0])/((d[1]*z+d[0])*z+1.0);
      end else begin
        if y

    If you haven't got an implementation of erf() then you can try this one converted to Pascal from Numerical Recipes. It's not accurate to double precision though.

    function erfc(const x: Double): Double;
    var
      t,z,ans: Double;
    begin
      z := abs(x);
      t := 1.0/(1.0+0.5*z);
      ans := t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
        t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
        t*(-0.82215223+t*0.17087277)))))))));
      if x>=0.0 then begin
        Result := ans;
      end else begin
        Result := 2.0-ans;
      end;
    end;
    
    function erf(const x: Double): Double;
    begin
      Result := 1.0-erfc(x);
    end;
    

提交回复
热议问题