How to find a vector in a matrix?

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!

1 Kommentar

Shashank Prasanna
Shashank Prasanna am 16 Jan. 2013
Just to clarify, you don't want to do this using a for loop? that would be fairly straightforward

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

Matt J
Matt J am 16 Jan. 2013

1 Stimme

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

Weitere Antworten (5)

Andrei Bobrov
Andrei Bobrov am 17 Jan. 2013
Bearbeitet: Andrei Bobrov am 17 Jan. 2013

1 Stimme

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
José-Luis
José-Luis am 16 Jan. 2013

0 Stimmen

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)';
Matt J
Matt J am 16 Jan. 2013
Bearbeitet: Matt J am 16 Jan. 2013

0 Stimmen

N=sqrt( conv2(A.^2,ones(size(B)), 'valid' ));
[i,j]=find(abs( conv2(A,fliplr(B)/norm(B),'valid')./N - 1)<=1e-6)
Roger Stafford
Roger Stafford am 17 Jan. 2013

0 Stimmen

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
Raymond
Raymond am 17 Jan. 2013

0 Stimmen

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.

2 Kommentare

Sean de Wolski
Sean de Wolski am 17 Jan. 2013
@Raymond, The for-loops will smoke ind2sub() any day of the week for large arrays. ind2sub() is convenient not fast.
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.

Melden Sie sich an, um zu kommentieren.

Kategorien

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by