I have two vectors, "nmin" and "nmax" which respectively contain the starting and ending indices for numel(nmin) sums that I need to compute. I would like to compute all of them simultaneously (i.e. vectorize). This is my current solution:
nmin = [3; 2; 16]; nmax = [5; 7; 16];
nsums = numel(nmin); %number of sums to be computed simultaneously nn = nmax-nmin+1; %number of terms in the sum maxnn = max(nn); %largest number of terms for any given sum
n = NaN(nsums,maxnn); %initialize as NaNs
for i = 1:nsums
n(i,1:nn(i)) = nmin(i):nmax(i);
end
S = ((-1).^n)./n; %vectorized evaluation of each term in the sum S(isnan(S)) = 0; %set the NaNs to zero now before performing the summation S = sum(S,2); %perform the sums simultaneously
Basically, the idea is to create an array, "n" that contains all of the summation indices, but since each summation (rows of n) contains a different number of terms, I pad with NaNs:
n =
3 4 5 NaN NaN NaN
2 3 4 5 6 7
16 NaN NaN NaN NaN NaNIn this example I have a sum from 3:5, another one from 2:7, and another one from 16:16 (i.e. only one term). After evaluating the terms, I set the NaNs to zero so that they don't contribute to the sum. For the example given above the result would be:
S =
-0.2833
0.2405
0.0625This works, but there are two performance problems:
(1) often times this algorithm produces a matrix "n" that has ~60% of its elements as NaNs, thus this is wasting memory and there are a lot of wasted computations when evaluating "S = ((-1).^n)./n;"
(2) if "nsums" is very large (and often it is on the order of 1e6) then I have a long for loop, which takes forever to evaluate.
Any ideas on how to avoid the for loop, or improve the performance in general?
ub=max(nmax);
n=1:ub; T=cumsum((-1).^(n)./n);
S=T(nmax)-T(nmin-1)
Somewhat more optimized, if min(nmin) is large.
lb=min(nmin)-1; ub=max(nmax);
n=lb:ub, T=cumsum((-1).^(n)./n), S=T(nmax-(lb+1))-T(nmin-lb)
I was about to submit a solution based on CUMSUM as well, which would have brought eternal shame on me after comparing with this one!
2 Comments
Direct link to this comment:
http://www.mathworks.com/matlabcentral/answers/74265#comment_146655
What would be typical values for min(nmin) and max(nmax)?
Direct link to this comment:
http://www.mathworks.com/matlabcentral/answers/74265#comment_146661
Typical values are min(nmin) = 1; and max(nmax) = 32;