Skip to main content

Assigning an analytical approximation to the error function erf(x)


Working with some iterative integral equations, I have Gaussian density functions involved therein. Integrating the Gaussian function I obtain the error function. When I take the second integration, Mathematica is not able to provide an analytical expression. Because apparently there is no closed-form expression for the integral of the error function.


Question: Is it possible the tell Mathematica to consider the error function as some given exact expression which is analytically integrable?


For example


$$\mathrm{erf}(x)=\frac{1}{(1+a_1x+a_2x^2+a_3x^3+a_4x^4)^4}$$


for some appropriate constants $a_1$, $a_2$, $a_3$, $a_4$?




Answer



You could unprotect Erf and redefine it as you like it.


Unprotect[Erf];
(* Here you define the constants and your erf approximation *)
a1=...; etc.
Erf[x_] := 1/(1 + a1 x + a2 x^2 + a3 x^3 + a4 x^4)^4;
(* Here you perform your calculations with the approximate value of erf *)
myComplexCalculation = Erf[x]/2
(* When you are done, clear your definition and reprotect Erf *)
Clear[Erf];

Protect[Erf];

This can be dangerous but, as long as you know what you are doing, it will work.


A more local workaround is to enclose your 'approximate' calculation within a Block that blocks the definition of Erf:


Block[ {Erf},
(* Here you define the constants and your erf approximation *)
a1=...; etc.
Erf[x_] := 1/(1 + a1 x + a2 x^2 + a3 x^3 + a4 x^4)^4;

(* Here you perform your calculations with the approximate value of erf *)

myComplexCalculation = Erf[x]/2
]

Is this what you were looking for or was it the actual expression for the approximation?


As a more general approach to temporarily modifying built-in functions within the walls of a scoping construct, you might also want to have a look at the undocumented function InheritedBlock, described in this post on Stack Overflow. It appears that it will copy all definitions associated with the symbol you want to block, so that you can change, within the block only the part you need to. Basically, while


Block[ {builtinFun},
code redefining builtinFun from scratch
and using the new builtinFun
]


would give you a completely clean symbol for builtinFun to code from scratch, using


Internal`InheritedBlock[ {builtinFun},
code redefining parts of the inherited builtinFun
and using the modified builtinFun
]

would give you a completely modifiable copy of builtinFun, so that you can modify only the parts you need to modify.


Comments

Popular posts from this blog

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...