Filter löschen
Filter löschen

How to find a vector in a matrix?

3 Ansichten (letzte 30 Tage)
Raymond
Raymond am 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!
  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
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
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
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
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
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
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.
Matt J
Matt J am 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.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Mathematics finden Sie in Help Center und File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by