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

Learn moreOpportunities for recent engineering grads.

Apply Today
Asked by Raymond on 16 Jan 2013

Hi all, I just wonder whether there are Matlab functions which can deal with the problem. Say,

A=[1 1 1 1; ... 1 1 2 3; ... 1 2 3 1; ... 1 1 1 2]; B=[1 2 3]

So B appears twice in A.

I tried ismember, but it finds all the elements of B in A, regardless of the sequence.

Thanks!

*No products are associated with this question.*

Answer by Matt J on 16 Jan 2013

Accepted answer

A=[1 1 1 1; 1 1 2 3; 1 2 3 1; 1 1 1 2]; B=[1 2 3];

[j,i]=ind2sub(fliplr(size(A)), strfind(reshape(A.',1,[]),B).' );

>> [i,j]

ans =

2 2 3 1

Answer by Andrei Bobrov on 17 Jan 2013

Edited by Andrei Bobrov on 17 Jan 2013

s = size(B) - 1; n = size(A) - s; out = []; for ii = 1:n(1) i1 = ii : ii + s(1); for jj = 1:n(2) if isequal(A(i1,jj : jj + s(2)),B) out = [out;[ii,jj]]; end end end

Answer by José-Luis on 16 Jan 2013

A=[1 1 1 1; 1 1 2 3; 1 2 3 1; 1 1 1 2]; B=[1 2 3];

isSubStr = @(x,y) ~isempty(strfind(x,y)); getStr = @(x) sprintf('%d',x); numVals = size(A,2);

logical_index = arrayfun(@(idx) isSubStr(getStr(A(idx,:)),getStr(B)),1:numVals)';

Answer by Roger Stafford on 17 Jan 2013

Another way:

[m,n] = size(A); k = length(B(:)); p = hankel(1:k,k:n); f = find(all(bsxfun(@eq,reshape(A(:,p).',k,n-k+1,m),B(:)),1)); [c,r] = ind2sub([n-k+1,m],f);

where c gives the column indices and r the row indices in A where a match with B begins. In your example these would be

r c - - 2 2 3 1

Answer by Raymond on 17 Jan 2013

Thanks all! All the solutions work, but Matt's looks simpler and more efficient.

I want to avoid for loops since I have to deal with big matrix.

Sean de Wolski on 17 Jan 2013

@Raymond, The `for`-loops will smoke `ind2sub()` any day of the week for large arrays. `ind2sub()` is convenient not fast.

Matt J on 17 Jan 2013

Don't know what ind2sub has to do with anything, but the for-loop approach is definitely not faster:

A=[1 1 1 1; 1 1 2 3; 1 2 3 1; 1 1 1 2]; B=[1 2 3]; A(10000,1)=0;

tic; [j,i]=ind2sub(fliplr(size(A)), strfind(reshape(A.',1,[]),B).' ); toc %Elapsed time is 0.001019 seconds.

####################

tic s = size(B) - 1; n = size(A) - s; out = []; for ii = 1:n(1) i1 = ii : ii + s(1); for jj = 1:n(2) if isequal(A(i1,jj : jj + s(2)),B) out = [out;[ii,jj]]; end end end toc; %Elapsed time is 0.039563 seconds.

## 1 Comment

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/59025#comment_123034

Just to clarify, you don't want to do this using a for loop? that would be fairly straightforward