MathGroup Archive 2004

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Question on Compile[]

  • To: mathgroup at smc.vnet.net
  • Subject: [mg49794] Re: [mg49786] Re: [mg49747] Question on Compile[]
  • From: DrBob <drbob at bigfoot.com>
  • Date: Sun, 1 Aug 2004 04:09:57 -0400 (EDT)
  • References: <200407301002.GAA26336@smc.vnet.net> <200407310714.DAA12055@smc.vnet.net>
  • Reply-to: drbob at bigfoot.com
  • Sender: owner-wri-mathgroup at wolfram.com

I think Fold is the way to go, here.

mukasa[cashFlow_,rate_]:=Module[{nvec=Range[Length[cashFlow]]},
     Total[cashFlow/(1.0+rate)^nvec]]
andrzej=Compile[{{cashFlow,_Real,1},{rate,_Real}},Module[{
         nvec=Range[Length[cashFlow]]},Total[cashFlow/(1.0+rate)^nvec]]];
treat[cc_List,r_]:=Block[{z=1/(1+r)},
     z Fold[#1 z+#2&,0,Reverse@cc]
     ]
cashFlow[n_]:=Table[Random[],{n}];

cc=cashFlow[100000];
r=0.1;
Timing@mukasa[cc,r]
Timing@andrzej[cc,r]
Timing@treat[cc,r]

{1.484 Second,3.44135}

\!\(\*
   RowBox[{\(CompiledFunction::"
       cfn"\), \(\(:\)\(\ \)\), "\<\"Numerical error encountered at
       instruction \\!\\(13\\);
     proceeding with uncompiled evaluation. \\!\\(\\*ButtonBox[\\\"Moreâ?¦\\\", \
ButtonStyle->\\\"RefGuideLinkText\\\", ButtonFrame->None, \
ButtonData:>\\\"CompiledFunction::cfn\\\"]\\)\"\>"}]\)

{1.547 Second,3.44135}

{0.031 Second,3.44135}

Bobby

On Sat, 31 Jul 2004 03:14:05 -0400 (EDT), Andrzej Kozlowski <akoz at mimuw.edu.pl> wrote:

> 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/
>
>
>



-- 
DrBob at bigfoot.com
www.eclecticdreams.net


  • Prev by Date: Re: Combining 2D graphs into a 3D graph
  • Next by Date: NthPermutation: how to change output format?
  • Previous by thread: Re: Re: Question on Compile[]
  • Next by thread: infinity expression from matrix inverse