Re: Question on Compile[]
- To: mathgroup at smc.vnet.net
- Subject: [mg49786] Re: [mg49747] Question on Compile[]
- From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
- Date: Sat, 31 Jul 2004 03:14:05 -0400 (EDT)
- References: <200407301002.GAA26336@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
On 30 Jul 2004, at 12:02, Mark Coleman wrote:
>
> Greetings,
>
> I am doing some research in finance, translating some visual basic code
> into Mathematica, and attempting to optimize it. Most of this is quite
> straightforward, and by Compiling[] functions, execution is quite fast.
> I did run into an instance where the compilied code ran a bit slower
> than the uncompiled code. I am sure this has something to do with some
> additional work that Mathematica is doing internally to expand the
> expression I
> am using, but I was hoping someone on the list could help me understand
> and if possible fix, this behavior.
>
> Specifically I am calculating a standard discounted cash flow. The
> computation is quite simple, Let
>
> cashFlow be a list of real numbers of length n and let nvec=Range[n],
> then the discounted cash flow is the sum over i=1,n of
>
> cashFlow(i)/(1+r)^i
>
> where r is a real number with 0 < r < 1.
>
> The final Mathematica code is:
>
>
> Clear[dcf];
> dcf[cashFlow_, rate_] := Module[{nvec = Range[Length[cashFlow]]},
> Total[cashFlow/(1.0 + rate)^nvec]
> ]
>
>
> On my 800 Mhz Powerbook G4, 5000 trials of this takes 3.72 seconds,
> while the compiled version takes 4.2 seconds.
>
> Any ideas how I can speed this up, to get the usual gains one typically
> sees in compiled code?
>
> Thanks,
>
> -Mark
>
>
Here is what I see on my machine (also a Mac PowerBook):
We compare two functions:
dcf[cashFlow_, rate_] := Module[{nvec = Range[Length[cashFlow]]},
Total[cashFlow/(1.0 + rate)^nvec]
]
dcf1 = Compile[{{cashFlow, _Real, 1}, {rate, _Real}}, Module[{nvec =
Range[
Length[cashFlow]]},
Total[cashFlow/(1.0 + rate)^nvec]
]]
Lets also define
cashFlow[n_]:=Table[Random[],{n}];
and lets take
r=0.1;
Now try
cc=cashFlow[5000];
dcf[cc,r]//Timing
{0.01 Second,5.65194}
dcf1[cc,r]//Timing
{0. Second,5.65194}
As expected the compiled code is faster. The problem occurs only when
we take a larger n
In[39]:=
cc=cashFlow[8000];
dcf[cc,r]//Timing
{0.15 Second,4.39072}
dcf1[cc,r]//Timing
"Numerical error encountered at
instruction 1; proceeding with uncompiled evaluation.
{0.19 Second,4.39072}
So it is not the case here that the compiled code is slower, rather an
error occurred and a non-compiled version of the function was used. I
think the reason why it fails is that in the body of your function you
have numbers of the form
c/(rate + 1.)^v
and when v becomes very large 1/(rate + 1.)^v becomes smaller than
$MinMachineNumber . Since Compile can only work with numerical
quantities that satisfy the usual restriction on machine arithmetic the
compiled function cannot be used and Mathematica switches to compiled
code. Having considered this only briefly I can't yet see as yet any
very satisfactory remedy. The only one I can think of is based on
breaking your function into a linear combination of functions, each of
which is compiled separately in such a way that no numbers smaller than
$MinMachineNumber occur during the computation. Unfortunately the
splitting will have to depend on the length of cashFlow, and it may be
tricky to write such a function that would avoid above difficulty for
all n.
All this assumes that the problem you have encountered is the same one
I have been discussing. That is not quite obvious from your posting
since you do not mention getting any messages about "proceeding with
uncompiled evaluation". It may be that there is something I have
misunderstood.
Andrzej Kozlowski
Chiba, Japan
http://www.mimuw.edu.pl/~akoz/
- References:
- Question on Compile[]
- From: Mark Coleman <mark@markscoleman.com>
- Question on Compile[]