Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
How to allocate repeated indices

Subject: How to allocate repeated indices

From: Donald

Date: 9 Mar, 2011 22:50:05

Message: 1 of 6

Suppose I have a vector, nVec = [2 7 5 4 2 4] and I want to count the number of occurences in this vector, so that I end up with yVec = [2 4 5 7]; numVec = [2 2 1 1]

Is there a fast way to do this, besides using unique or hist?

Here is what I"m doing now:

nVec = [2 7 5 4 2 4];
NVec = sort(nVec);
diffnVec = diff(NVec);
startnVec = [1 find(diffnVec~=0)+1];
endnVec = [startnVec(2:end)-1 length(NVec)];
numnVec = endnVec - startnVec+1;
yVec = NVec(startnVec);

Subject: How to allocate repeated indices

From: Think two, count blue.

Date: 9 Mar, 2011 23:12:38

Message: 2 of 6

On 11-03-09 04:50 PM, Donald wrote:
> Suppose I have a vector, nVec = [2 7 5 4 2 4] and I want to count the number
> of occurences in this vector, so that I end up with yVec = [2 4 5 7]; numVec =
> [2 2 1 1]
>
> Is there a fast way to do this, besides using unique or hist?
>
> Here is what I"m doing now:
>
> nVec = [2 7 5 4 2 4];
> NVec = sort(nVec);
> diffnVec = diff(NVec);
> startnVec = [1 find(diffnVec~=0)+1];
> endnVec = [startnVec(2:end)-1 length(NVec)];
> numnVec = endnVec - startnVec+1;
> yVec = NVec(startnVec);

It depends upon your constraints. If your values are integers, then

low = min(nVec);
numVec = accumarray((1-low)+nVec(:),1);
t = find(numVec);
yVec = reshape(low - 1 + t,1,length(t));
numVec = reshape(numVec(t),1,length(t));

You would need to time this against your version though.

Possibly some of the reshape() are not needed.

Subject: How to allocate repeated indices

From: dpb

Date: 9 Mar, 2011 23:12:52

Message: 3 of 6

On 3/9/2011 4:50 PM, Donald wrote:
> Suppose I have a vector, nVec = [2 7 5 4 2 4] and I want to count the
> number of occurences in this vector, so that I end up with yVec = [2 4 5
> 7]; numVec = [2 2 1 1]
>
> Is there a fast way to do this, besides using unique or hist?
...
I'd think unique() and hist() would be as fast as about
anything--certainly sort()ing isn't fastest thing in world.

W/ your example I'd just do what you say you don't want until I had
actual timing to prove to me it was a real issue that had to deal with
or else...

 >> nVec = [2 7 5 4 2 4];
 >> yVec = unique(nVec)
yVec =
      2 4 5 7
 >> numVec=hist(nVec,yVec)
numVec =
      2 2 1 1
 >>

In general I've found that for the most part just going to the native
vector functions does about as good as most anything else one can do w/o
writing mex files...

Maybe I'm overlooking something obvious but...

--

Subject: How to allocate repeated indices

From: Bruno Luong

Date: 10 Mar, 2011 07:34:05

Message: 4 of 6

dpb <none@non.net> wrote in message <il91hp$8ad$1@news.eternal-september.org>...
> On 3/9/2011 4:50 PM, Donald wrote:
> > Suppose I have a vector, nVec = [2 7 5 4 2 4] and I want to count the
> > number of occurences in this vector, so that I end up with yVec = [2 4 5
> > 7]; numVec = [2 2 1 1]
> >
> > Is there a fast way to do this, besides using unique or hist?
> ...
> I'd think unique() and hist() would be as fast as about
> anything--certainly sort()ing isn't fastest thing in world.

unique has a sort engine behind. hist is slower than accumarray. The fastest thing is sorting once.

I gave the three method here:

http://www.mathworks.com/matlabcentral/newsreader/view_thread/291578#782626

Bruno

Subject: How to allocate repeated indices

From: Donald

Date: 10 Mar, 2011 21:08:05

Message: 5 of 6

I haven't done a comprehensive test, but which method is faster depends on the input data vector. If the vector has a small number of elements, but those elements are widely dispersed, the sort method will be faster than then the accumarray method because accumarray will generate a large vector upon which a find will have to be done.

For example, if nVec = [-500 530 600], accumarray will generate an 1100 element array, whereas sort just sorts the 3 values.


"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <il9utd$7ej$1@fred.mathworks.com>...
> dpb <none@non.net> wrote in message <il91hp$8ad$1@news.eternal-september.org>...
> > On 3/9/2011 4:50 PM, Donald wrote:
> > > Suppose I have a vector, nVec = [2 7 5 4 2 4] and I want to count the
> > > number of occurences in this vector, so that I end up with yVec = [2 4 5
> > > 7]; numVec = [2 2 1 1]
> > >
> > > Is there a fast way to do this, besides using unique or hist?
> > ...
> > I'd think unique() and hist() would be as fast as about
> > anything--certainly sort()ing isn't fastest thing in world.
>
> unique has a sort engine behind. hist is slower than accumarray. The fastest thing is sorting once.
>
> I gave the three method here:
>
> http://www.mathworks.com/matlabcentral/newsreader/view_thread/291578#782626
>
> Bruno

Subject: How to allocate repeated indices

From: Bruno Luong

Date: 10 Mar, 2011 21:42:05

Message: 6 of 6

"Donald " <gt4715b@yahoo.com> wrote in message <ilbejl$hqe$1@fred.mathworks.com>...
> I haven't done a comprehensive test, but which method is faster depends on the input data vector. If the vector has a small number of elements, but those elements are widely dispersed, the sort method will be faster than then the accumarray method because accumarray will generate a large vector upon which a find will have to be done.
>
> For example, if nVec = [-500 530 600], accumarray will generate an 1100 element array, whereas sort just sorts the 3 values.

No, accumarray will also generate 3-element array. See my implementation.

Bruno

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us