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[]