Ideas for vectorizing? (Computing multiple sumations simultaneously even though the max and min are different for each)

Asked by Oliver about 12 hours ago
Latest activity Commented on by Cedric Wannaz about 11 hours ago

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   NaN

In 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.0625

This 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?

2 Comments

Cedric Wannaz about 11 hours ago

What would be typical values for min(nmin) and max(nmax)?

Oliver about 11 hours ago

Typical values are min(nmin) = 1; and max(nmax) = 32;

Oliver

Products

1 Answer

Answer by Matt J about 11 hours ago
Edited by Matt J about 11 hours ago
Accepted answer
 ub=max(nmax);
 n=1:ub;
 T=cumsum((-1).^(n)./n);
 S=T(nmax)-T(nmin-1)

3 Comments

Matt J about 11 hours ago

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)
Oliver about 11 hours ago

Genius! Thanks, great insight.

Cedric Wannaz about 11 hours ago

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!

Matt J

Contact us