3
$\begingroup$

I would like a time efficient way to calculate a sum of the following form:

y = ConstantArray[0,5];
x = {x1, x2, x3, x4, x5};
j = 2;

For[i = 1, i <= 5, i++,
 y[[i]] = x[[i]] + Sum[x[[n - 1]]*Exp[Sum[x[[m - 1]], {m, n, i}], {n, j, i}]
 ]

This produces an output of the following form:

{x1,
 x1*Exp[x1] + x2, 
 x1*Exp[x1 + x2] + x2*Exp[x2] + x3, 
 x1*Exp[x1 + x2 + x3] + x2*Exp[x2 + x3] + x3*Exp[x3] + x4,
 x1*Exp[x1 + x2 + x3 + x4] + x2*Exp[x2 + x3 + x4] + x3*Exp[x3 + x4] + x4*Exp[x4] + x5}

I would like to perform this sort of calculation for an array of about 300,000 data points to simulate cumulative decay. I am aware of the limitations of the Sum function with regards to computational speed, but I am struggling to recreate this sort of output structure with other functions such as Total or Accumulate. Can anyone suggest a better way?

$\endgroup$

2 Answers 2

4
$\begingroup$

An iterative algorithm can compute this in about a second on my machine.

n = 300000;
x = RandomReal[{-1., 1.}, n];
y = ConstantArray[0., n];

y = ConstantArray[0., Length[x]];
y[[1]] = x[[1]];
Do[
  y[[i + 1]] = Exp[x[[i]]] y[[i]] + x[[i + 1]], 
  {i, 1, Length[x] - 1}]; // AbsoluteTiming // First

0.758239

As many exponentials are involved, it is not unlikely that floating point over- or underflows occur. These would slow down the process a little.

$\endgroup$
5
$\begingroup$

@HenrikSchumacher's iteration expressed with FoldList:

n = 300000;
x = RandomReal[{-1, 1}, n];
y = FoldList[#1*E^#2[[1]] + #2[[2]] &, x[[1]], Partition[x, 2, 1]]; //AbsoluteTiming//First
(*    0.139428    *)

Unfortunately, the more natural FoldPairList is ten times slower:

n = 300000;
x = RandomReal[{-1, 1}, n];
y = FoldPairList[(#1 + #2) {1, E^#2} &, 0, x]; //AbsoluteTiming//First
(*    1.37965    *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.