Need code for Inverse Error Function

前端 未结 7 1874
清歌不尽
清歌不尽 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:52

    Here is what I have from spe. To me it looks like they tried to speed it up by dragging all functions into one big polynomal. Keep in mind this is code from the 386 era

    // Extract from package Numlib in the Free Pascal sources (http://www.freepascal.org)
    // LGPL-with-static-linking-exception, see original source for exact license.
    // Note this is usually compiled in TP mode, not in Delphi mode.
    
    Const highestElement = 20000000;
    
    Type ArbFloat = double;  // can be extended too.
         ArbInt   = Longint;
         arfloat0   = array[0..highestelement] of ArbFloat;
    
    function spesgn(x: ArbFloat): ArbInt;
    
    begin
      if x<0
      then
        spesgn:=-1
      else
        if x=0
        then
          spesgn:=0
        else
          spesgn:=1
    end; {spesgn}
    
    function spepol(x: ArbFloat; var a: ArbFloat; n: ArbInt): ArbFloat;
    var   pa : ^arfloat0;
           i : ArbInt;
        polx : ArbFloat;
    begin
      pa:=@a;
      polx:=0;
      for i:=n downto 0 do
        polx:=polx*x+pa^[i];
      spepol:=polx
    end {spepol};
    
    function speerf(x : ArbFloat) : ArbFloat;
    const
    
            xup = 6.25;
         sqrtpi = 1.7724538509055160;
         c : array[1..18] of ArbFloat =
         ( 1.9449071068178803e0,  4.20186582324414e-2, -1.86866103976769e-2,
           5.1281061839107e-3,   -1.0683107461726e-3,   1.744737872522e-4,
          -2.15642065714e-5,      1.7282657974e-6,     -2.00479241e-8,
          -1.64782105e-8,         2.0008475e-9,         2.57716e-11,
          -3.06343e-11,           1.9158e-12,           3.703e-13,
          -5.43e-14,             -4.0e-15,              1.2e-15);
    
         d : array[1..17] of ArbFloat =
         ( 1.4831105640848036e0, -3.010710733865950e-1, 6.89948306898316e-2,
          -1.39162712647222e-2,   2.4207995224335e-3,  -3.658639685849e-4,
           4.86209844323e-5,     -5.7492565580e-6,      6.113243578e-7,
          -5.89910153e-8,         5.2070091e-9,        -4.232976e-10,
           3.18811e-11,          -2.2361e-12,           1.467e-13,
          -9.0e-15,               5.0e-16);
    
      var t, s, s1, s2, x2: ArbFloat;
             bovc, bovd, j: ArbInt;
    begin
      bovc:=sizeof(c) div sizeof(ArbFloat);
      bovd:=sizeof(d) div sizeof(ArbFloat);
      t:=abs(x);
      if t <= 2
      then
        begin
          x2:=sqr(x)-2;
          s1:=d[bovd]; s2:=0; j:=bovd-1;
          s:=x2*s1-s2+d[j];
          while j > 1 do
            begin
              s2:=s1; s1:=s; j:=j-1;
              s:=x2*s1-s2+d[j]
            end;
          speerf:=(s-s2)*x/2
        end
      else
        if t < xup
        then
          begin
            x2:=2-20/(t+3);
            s1:=c[bovc]; s2:=0; j:=bovc-1;
            s:=x2*s1-s2+c[j];
            while j > 1 do
              begin
                s2:=s1; s1:=s; j:=j-1;
                s:=x2*s1-s2+c[j]
              end;
            x2:=((s-s2)/(2*t))*exp(-sqr(x))/sqrtpi;
            speerf:=(1-x2)*spesgn(x)
          end
        else
          speerf:=spesgn(x)
    end;  {speerf}
    
    function spemax(a, b: ArbFloat): ArbFloat;
    begin
      if a>b
      then
        spemax:=a
      else
        spemax:=b
    end; {spemax}
    
    function speefc(x : ArbFloat) : ArbFloat;
    const
    
       xlow = -6.25;
      xhigh = 27.28;
          c : array[0..22] of ArbFloat =
          ( 1.455897212750385e-1, -2.734219314954260e-1,
            2.260080669166197e-1, -1.635718955239687e-1,
            1.026043120322792e-1, -5.480232669380236e-2,
            2.414322397093253e-2, -8.220621168415435e-3,
            1.802962431316418e-3, -2.553523453642242e-5,
           -1.524627476123466e-4,  4.789838226695987e-5,
            3.584014089915968e-6, -6.182369348098529e-6,
            7.478317101785790e-7,  6.575825478226343e-7,
           -1.822565715362025e-7, -7.043998994397452e-8,
            3.026547320064576e-8,  7.532536116142436e-9,
           -4.066088879757269e-9, -5.718639670776992e-10,
            3.328130055126039e-10);
    
      var t, s : ArbFloat;
    begin
      if x <= xlow
      then
        speefc:=2
      else
      if x >= xhigh
      then
        speefc:=0
      else
        begin
          t:=1-7.5/(abs(x)+3.75);
          s:=exp(-x*x)*spepol(t, c[0], sizeof(c) div sizeof(ArbFloat) - 1);
          if x < 0
          then
            speefc:=2-s
          else
            speefc:=s
        end
    end {speefc};
    

提交回复
热议问题