While in this case there does happen to be a standard-library function (cumsum
) that does exactly what you want, if you are “struggling” with this problem then I suspect that you may be approaching Julia in the wrong way.
In some other languages, numerical programming is an exercise in “mining” a set of “standard” libraries, since these are the only fast operations, so even doing something very basic can be a struggle if you don’t know exactly which library function to call.
In Julia, re-using mature library code is still a good thing to do! But it is not your only choice — there is absolutely nothing wrong with writing your own loops. And implementing a trivial function like cumsum
should not be a struggle unless you are an absolute beginner at programming. For example:
function my_cumsum(a)
s = copy(a)
for i = firstindex(s)+1:lastindex(s)
s[i] += s[i-1]
end
return s
end
is a perfectly reasonable implementation. It is a bit slower than Base.cumsum
, but most of that difference can be made up by adding @inbounds
to the s[i] += s[i-1]
line. If this were performance-critical for you (unlikely), the rest of the difference could be made up by avoiding the separate copy
step (combining the copy
with the sum):
function my_cumsum_faster(a)
s = similar(a)
isempty(s) && return s
sum = first(a)
for i = firstindex(s)+1:lastindex(s)
@inbounds s[i] = (sum += a[i])
end
return s
end
This loop is also less accurate than Base.cumsum
, because the latter uses a recursive algorithm called pairwise summation that accumulates roundoff errors much more slowly. Taking advantage of non-obvious algorithms like that written by experienced developers is indeed an advantage of utilizing mature libraries!
However, in a real application you are probably not just doing cumsum
. Probably you are doing additional operations on the data before or after the summation. In that case, there is often a real advantage in writing your own loop, in order to avoid multiple passes over the same data or, worse, allocating lots of temporary arrays (one for each “vectorized” operation). So, there is a tradeoff, even for using optimized libraries, compared to writing your own code.
Programming is hard for complicated problems! But if you find yourself struggling to code a simple problem, then maybe you are trying too hard to shoehorn your problem into an existing library function rather than just writing your own loop (or recursion, or …). Languages like R, Python, and Matlab train you to “never” write your own inner loops, but in Julia you should unlearn that lesson.