user3813057
user3813057

Reputation: 911

How to increment some of elements in an array by specific values in MATLAB

Suppose we have an array

A = zeros([1,10]);

We have several indexes with possible duplicate say:

indSeq = [1,1,2,3,4,4,4];

How can we increase A(i) by the number of i in the index sequence i.e. A(1) = 2, A(2) = 1, A(3) = 1, A(4) = 3?

The code A(indSeq) = A(indSeq)+1 does not work.

I know that I can use the following for loop to achieve the goal, but I wonder if there is anyway that we can avoid for-loop? We can assume that the indSeq is sorted.

A for-loop solution:

for i=1:length(indSeq)
  A(indSeq(i)) = A(indSeq(i))+1;
end;

Upvotes: 2

Views: 1100

Answers (3)

Divakar
Divakar

Reputation: 221504

You can use accumarray for such a label based counting job, like so -

accumarray(indSeq(:),1)

Benchmarking

As suggested in the other answer, you can also use hist/histc. Let's benchmark these two for a large datasize. The benchmarking code I used had -

%// Create huge random array filled with ints that are duplicated & sorted
maxn = 100000;
N = 10000000;
indSeq = sort(randi(maxn,1,N));

disp('--------------------- With HISTC')
tic,histc(indSeq,unique(indSeq));toc

disp('--------------------- With ACCUMARRAY')
tic,accumarray(indSeq(:),1);toc

Runtime output -

--------------------- With HISTC
Elapsed time is 1.028165 seconds.
--------------------- With ACCUMARRAY
Elapsed time is 0.220202 seconds.

Upvotes: 3

jfish003
jfish003

Reputation: 1332

I think what you are looking for is the number of occurences of unique values of the array. This can be accomplished with:

[num, val] = hist(indSeq,unique(indSeq));

the output of your example is:

num = 2 1 1 3
val = 1 2 3 4

so num is the number of times val occurs. i.e. the number 1 occurs 2 times in your example

Upvotes: 1

David
David

Reputation: 8459

This is run-length encoding, and the following code should do the trick for you.

A=zeros(1,10);
indSeq = [1,1,2,3,4,4,4,7,1];
indSeq=sort(indSeq); %// if your input is always sorted, you don't need to do this
pos = [1; find(diff(indSeq(:)))+1; numel(indSeq)+1];
A(indSeq(pos(1:end-1)))=diff(pos)

which returns

A =
     3     1     1     3     0     0     1     0     0     0

This algorithm was written by Luis Mendo for MATL.

Upvotes: 1

Related Questions