0

Let's say I have a vector named vect = [1 2 3 4 5 6 7 8 9] and another vector named intervals = [1 3 6 9]. Is it possible to get another vector of partial sums of elements in vest, using intervals? I want to do something like this:

Partial sum 1 = 1 + 2 + 3 (elements from vect(1) to vect(3))

Partial sum 2 = 4 + 5 + 6 (elements from vect(3 + 1) to vect(6))

Partial sum 3 = 7 + 8 + 9 (elements from vect(6 + 1) to vect(9))

So what I want to do is to obtain the sum of the first k elements, then the sum of another k elements starting from the first one not in the previous sum etc.

Original problem: The original problem was like this: I receive a vector with n values and a value k. Let's do t = max(v) / k intervals. Now, how many values from n are in the interval [0, t)? What about [t, t * 2)? What about [2 * t, 3 * t)? etc. Until now, I used accumarray(v, 1) to find how many values of each do I have and int = (0:max(v)/k:max(v)) to build the invervals vector, but now I have to sum(accumarray(v, 1)) in a way to get those partial sums.

If you want to test, using this (http://pastebin.com/jCZ3qYhz : generated with accumarray) and k = 16, the partial sums have to be: 157, 167, 136, 251, 726, 1300, 1152..I'd like to be able to do this without a for/while loop :) Vectorization is the key!

Edit: To get my first sum, I use this: sum(accumarray(v, 1)(1:16)), for the second one: sum(accumarray(v, 1)(17:32)), but I don't know how to vectorize this operation. I tried this: i = (1:16:500). Then sum(accumarray(v, 1)(i(1:length(i)) : i(2:length(i))) but it's not really working or I don't use the right thing.

zeeMonkeez
  • 5,057
  • 3
  • 33
  • 56
Adrian Pop
  • 1,879
  • 5
  • 28
  • 40
  • By the way, I have another question. I have now a big vector with decimals and as before, some limits. How can I count how many values are in each interval? Acumarray seems not to work with decimals, only positive integers. – Adrian Pop Mar 22 '16 at 01:36

1 Answers1

1

For the first problem I would use this:

cs = cumsum(vect);
i2 = intervals(2:end);
result = [cs(i2(1)), diff(cs(i2))]

result =

     6    15    24

This will build the cumulative sum of all elements, find the ends of the parts, and then find the differences between the sums at the end of the parts (which are precisely the sums of the elements in-between).

zeeMonkeez
  • 5,057
  • 3
  • 33
  • 56
  • Thanks! I adapted the code and it's working great. I did not know about the diff function. Have a nice day! – Adrian Pop Mar 21 '16 at 06:45
  • By the way, I have another question. I have now a big vector with decimals and as before, some intervals. How can I count how many values are in each interval? Acumarray seems not to work with decimals, only positive integers. – Adrian Pop Mar 22 '16 at 01:23
  • 1
    @Adi you could use `arrayfun` with `find` to find the last element of `intervals` strictly smaller than `x`, for all in `vect`, then `accumarray` to count. – zeeMonkeez Mar 22 '16 at 13:03
  • Yes, strictly smaller than x, but I also want bigger than another number. It would be something like x >= intervals(k) & x < intervals(k+1). Intervals(k) it's not a whole number (always). I can't really achieve that easily... – Adrian Pop Mar 22 '16 at 23:26
  • @Adi that's why I wrote *last*... That assumes that `intervals` is ordered, of course – zeeMonkeez Mar 22 '16 at 23:28
  • @Adi to get you started with an example: `intervals = 1:1.1:8; find(intervals < 5.3, 1, 'last')` – zeeMonkeez Mar 22 '16 at 23:31