Say that I have a list of returns on a financial asset over time and want to know the total compounded return. To get the answer, I need to add 1 to each return and then calculate the product of all of them. So, I'm looking for a function like Total
, except that it computes the product. The Product
function works, but seems clumsy and slower than my alternatives (at first, I was having trouble getting Product
to work, so I wrote a few of my own functions). Here are the alternatives:
listProduct[x_List] := Exp[Total[Log[x]]];
listProduct2[x_List] := Last[FoldList[Times, 1, x]];
listProduct3[x_List] := Fold[Times, 1, x];
listProduct4[x_List] := Product[x[[i]], {i, 1, Length[x]}];
Those are in the order that I thought of them. A couple of surprising things: The first seems to be the fastest by quite a lot (though none are super slow). The slowest is the last one using Product
, which I thought would be highly optimized and fast.
Here are my tests:
s = RandomVariate[NormalDistribution[0.05, 0.1], 10^6];
listProduct[1 + s] - 1; // AbsoluteTiming
listProduct2[1 + s] - 1; // AbsoluteTiming
listProduct3[1 + s] - 1; // AbsoluteTiming
listProduct4[1 + s] - 1; // AbsoluteTiming
which produces these results:
{0.0312000, Null} {1.4820026, Null} {1.4040025, Null} {1.8252032, Null}
So, the question is: Is there a faster way, and am I missing some built-in function that would do this better? I won't be using lists this long, but I may be doing a lot of lists if I can get the rest of my idea implemented.
Answer
The function you're looking for is Times
. Use it as Times@@list
, or keeping in line with your functions,
listProduct[x_List] := Times @@ x
Comments
Post a Comment