Re: Making Mathematica Functions Evaluate Rapidly?

*Subject*: [mg2274] Re: [mg2206] Making Mathematica Functions Evaluate Rapidly?*From*: hay at haystack.demon.co.uk (Allan Hayes)*Date*: Thu, 19 Oct 1995 05:35:14 GMT*Approved*: usenet@wri.com*Distribution*: local*Newsgroups*: wri.mathgroup*Organization*: Wolfram Research, Inc.*Sender*: daemon at wri.com ( )

"A. E. Siegman" <siegman at ee.stanford.edu> >Subject: [mg2206] Making Mathematica Functions Evaluate Rapidly? has some quesions using compiled functions in Compile; delayed and immediate evaluation; small imaginary values and making Pi,E.. numerical (see message attached). I hope that the following may be of use Allan Hayea hay at haystack.demon.co.uk ****** Compiling Compiled Functions ****** This is usually gives a much slower function than compiling the uncompiled version. Here are some comparisons (I turn off the messages that some of the following computations generate). Off[CompiledFunction::ccr,CompiledFunction::cfex, CompiledFunction::cfr ] (*preliminary symbol definition*) s = 1+x + x^2 + x^3 +x^4; (*some functions*) f = Function[x, 1+x + x^2 + x^3 + x^4]; c = Compile[x, 1+x + x^2 + x^3 + x^4]; dc := Compile[x, 1+x + x^2 + x^3 + x^4]; cc = Compile[x ,c[x]]; (*bad: c[x] not evaluated*) cf = Compile[x, f[x]]; (*bad: c[x] not evaluated*) cs = Compile[x ,s]; (*bad: e not evaluated*) (*timings*) TableForm[ (Timing[Do[#[1.2],{1000}]][[1]])&/@ToExpression/@(#), TableHeadings -> {#} ]&[{"f","c","dc","cc","cf", "cs"}] f 1.23333 Second c 0.116667 Second dc 0.133333 Second cc 0.733333 Second cf 1.75 Second cs 3.41667 Second (*ways out - beside manually typing in the uncompiled version*) A way out from the difficulties of cc, cf and cs is to force evaluation inside Compile (a compiled function given a symbolic input works like the corresponding uncompiled function: for example c[y] 2 3 4 1 + y + y + y + y ) Examples: Compile[x, Evaluate[c[x]]] 2 3 4 CompiledFunction[{x}, 1 + x + x + x + x , -CompiledCode-] Which is the same as c. Similarly Compile[x, Evaluate[e]] === c[x] Compile[x, Evaluate[f[x]]] === c[x] True True This also works in more complicated cases: Try Compile[x, Evaluate[c[x]/(1+ Sin[e]) + Take[f[x],-2]]] Evaluate affects the whole expression not just the outer function. Compile[x, Evaluate[f[1+c[x]]]] Sometimes more may be needed. Compile[x, Evaluate[ReleaseHold[f[1+Hold[c[x]]]]]] ***** Small Imaginary Parts ***** ((-1)^1.5)^6 -15 -1. + 1.10215 10 I You can use Chop Chop[%] -1. ***** Making Pi, E ... numerical ***** N[Pi] 3.14159 But Compile seems to cope Compile[x, Pi x][2] 6.28319 ******************************************************************** Begin forwarded message: >From: "A. E. Siegman" <siegman at ee.stanford.edu> >To: mathgroup at smc.vnet.net >Subject: [mg2206] Making Mathematica Functions Evaluate Rapidly? >Organization: Stanford University I frequently want to evaluate (plot, numerically integrate, calculate numerical moments of) functions which start out complex, e.g., something like f[x,y,z] = (1/ f1[x,y,z] ) Exp[ f2[x,y,z] ] where f1[x,y,z] and f2[x,y,z] may contain various purely real coefficients, call 'em a,b,c,... which have fixed (predefined) values, as well as the variables x,y,z , and some explicit I's (the imaginary unit I), and some standard functions, e.g., Cos[], Sin[], etc.. In other words, all input values are purely real, and all I's are explicit. Then, what I really want to do is to generate purely real outputs, either g1[x,y,z] = Abs[f[x,y,z]] or g2[x,y,z] = Abs[f[x,y,z]]^2 in a form that will evaluate as rapidly as possible (on a PowerMac). What's the best way to do this? Should I define the initial functions using = or := ? At what stage should I compile (and how)? Can I compile a function that contains other functions that have already been compiled? I sometimes seem to get very small complex values coming out of the compiled versions of g1 or g2 (i.e., the Abs[] functions), even though I've used _Real on x,y,z in the compilation, which makes me think they may being evaluated with complex values even though everything is supposedly real. Do I need to use ComplexExpand somehow on f[x,y,z] to separate it into Re and Im parts, then square them independently to get Abs[]^2 ? And finally, what if Pi or Sqrt[2] or ... are also contained in the functions f1, f2 ? Do I need to do something to force those into numerical form also? (My experience is that depending on just how I set up a calculation like the above I get wildly different speeds -- but there seems to be no systematic way to know how to get the fastest evaluation.) Email replies to siegman at ee.stanford.edu appreciated -- thanks.