필터 지우기
필터 지우기

How to find a vector in a matrix?

조회 수: 3 (최근 30일)
Raymond
Raymond 2013년 1월 16일
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
Shashank Prasanna
Shashank Prasanna 2013년 1월 16일
Just to clarify, you don't want to do this using a for loop? that would be fairly straightforward

댓글을 달려면 로그인하십시오.

채택된 답변

Matt J
Matt J 2013년 1월 16일
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

추가 답변 (5개)

Andrei Bobrov
Andrei Bobrov 2013년 1월 17일
편집: Andrei Bobrov 2013년 1월 17일
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 2013년 1월 16일
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 2013년 1월 16일
편집: Matt J 2013년 1월 16일
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 2013년 1월 17일
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 2013년 1월 17일
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
Sean de Wolski
Sean de Wolski 2013년 1월 17일
@Raymond, The for-loops will smoke ind2sub() any day of the week for large arrays. ind2sub() is convenient not fast.
Matt J
Matt J 2013년 1월 17일
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.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Mathematics에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by