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

Keep only elements that appear multiple times

Asked by Ryan Magee on 12 Jun 2013

Hey everyone, been banging my head against this for awhile and can't come up with something efficient.

I have a large matrix, roughly 1000x1000, and I want to discard all elements (or replace with 0) that don't appear in the matrix at least three times. Additionally, I'm trying to allow for an error range so that, say, 10.1 and 9.9 (some arbitrary interval) will count as "10" (but this is secondary to the original problem).

I'm guessing that my main issue is that rewriting/editing a matrix is computationally expensive. The only solution I came up with involved numel in a loop, which is dreadfully slow.

Thanks for looking, advice is appreciated!

0 Comments

Ryan Magee

Products

No products are associated with this question.

5 Answers

Answer by Roger Stafford on 13 Jun 2013
Accepted answer

Actually I didn't need to find the inverse of permutation p. The following is one step shorter:

 [B,p] = sort(A(:));
 t = [true;diff(B)~=0;true];
 q = cumsum(t(1:end-1));
 t = diff(find(t))<3;
 A(p(t(q))) = 0;

2 Comments

Ryan Magee on 15 Jun 2013

I wound up going with this one as it was fastest. I'm pretty sure you permuted p,t,q from t,p,q in that last line though. Thanks for your help!

Roger Stafford on 15 Jun 2013

In the previous version I first took the inverse of p with the line

 p(p) = 1:length(p);

and subsequently did this

 A(t(q(p))) = 0;

It only occurred to me later that the inverse operation is not needed if we do the last step this way:

 A(p(t(q))) = 0;

Without that inverse operation this last order p(t(q)) is essential. It wouldn't work otherwise.

Roger Stafford
Answer by Roger Stafford on 12 Jun 2013

Here's a modification of Azzi's code that avoids the 'ismember' call.

 [B,~,p] = unique(A(:));
 t = histc(A(:),B)<3;
 A(t(p)) = 0;

0 Comments

Roger Stafford
Answer by Roger Stafford on 13 Jun 2013

This version uses the 'sort' function instead of 'unique' and 'histc'. Consequently it might be faster.

 [B,p] = sort(A(:));
 p(p) = 1:length(p);
 t = [true;diff(B)~=0;true];
 q = cumsum(t);
 t = diff(find(t))<3;
 A(t(q(p))) = 0;

0 Comments

Roger Stafford
Answer by Andrei Bobrov on 13 Jun 2013
[a,b] = histc(A(:),unique(A));
A(a(b) < 3) = 0;

0 Comments

Andrei Bobrov
Answer by Azzi Abdelmalek on 12 Jun 2013
Edited by Azzi Abdelmalek on 12 Jun 2013
A=[1 2 1 1;1 2 3 1;3 3 3 3;3 0 0 1];
B=unique(A(:));
A(ismember(A(:),B(histc(A(:),B)<3)))=0

0 Comments

Azzi Abdelmalek

Contact us