Reputation: 2299
I have a matrix suppX
in Matlab with size GxN
and a matrix A
with size MxN
. I would like your help to construct a matrix Xresponse
with size GxM
with Xresponse(g,m)=1
if the row A(m,:)
is equal to the row suppX(g,:)
and zero otherwise.
Let me explain better with an example.
suppX=[1 2 3 4;
5 6 7 8;
9 10 11 12]; %GxN
A=[1 2 3 4;
1 2 3 4;
9 10 11 12;
1 2 3 4]; %MxN
Xresponse=[1 1 0 1;
0 0 0 0;
0 0 1 0]; %GxM
I have written a code that does what I want.
Xresponsemy=zeros(size(suppX,1), size(A,1));
for x=1:size(suppX,1)
Xresponsemy(x,:)=ismember(A, suppX(x,:), 'rows').';
end
My code uses a loop. I would like to avoid this because in my real case this piece of code is part of another big loop. Do you have suggestions without looping?
Upvotes: 3
Views: 128
Reputation: 112769
Here's an alternative to @rayryeng's answer: reduce each row of the two matrices to a unique identifier using the third output of unique
with the 'rows'
input flag, and then compare the identifiers with singleton expansion (broadcast) using bsxfun
:
[~, ~, w] = unique([A; suppX], 'rows');
Xresponse = bsxfun(@eq, w(1:size(A,1)).', w(size(A,1)+1:end));
Upvotes: 2
Reputation: 104555
One way to do this would be to treat each matrix as vectors in N
dimensional space and you can find the L2 norm (or the Euclidean distance) of each vector. After, check if the distance is 0. If it is, then you have a match. Specifically, you can create a matrix such that element (i,j)
in this matrix calculates the distance between row i
in one matrix to row j
in the other matrix.
You can treat your problem by modifying the distance matrix that results from this problem such that 1 means the two vectors completely similar and 0 otherwise.
This post should be of interest: Efficiently compute pairwise squared Euclidean distance in Matlab.
I would specifically look at the answer by Shai Bagon that uses matrix multiplication and broadcasting. You would then modify it so that you find distances that would be equal to 0:
nA = sum(A.^2, 2); % norm of A's elements
nB = sum(suppX.^2, 2); % norm of B's elements
Xresponse = bsxfun(@plus, nB, nA.') - 2 * suppX * A.';
Xresponse = Xresponse == 0;
We get:
Xresponse =
3×4 logical array
1 1 0 1
0 0 0 0
0 0 1 0
Because you are using ismember
in your implementation, it's implicit to me that you expect all values to be integer. In this case, you can very much compare directly with the zero distance without loss of accuracy. If you intend to move to floating-point, you should always compare with some small threshold instead of 0, like Xresponse = Xresponse <= 1e-10;
or something to that effect. I don't believe that is needed for your scenario.
Upvotes: 3