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