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.