I have a matrix index
in Matlab with size GxN
and a matrix A
with size MxN
.
Let me provide an example before presenting my question.
clear
N=3;
G=2;
M=5;
index=[1 2 3;
13 14 15]; %GxN
A=[1 2 3;
5 6 7;
21 22 23;
1 2 3;
13 14 15]; %MxN
I would like your help to construct a matrix Response
with size GxM
with Response(g,m)=1
if the row A(m,:)
is equal to index(g,:)
and zero otherwise.
Continuing the example above
Response= [1 0 0 1 0;
0 0 0 0 1]; %GxM
This code does what I want (taken from a previous question of mine - just to clarify: the current question is different)
Response=permute(any(all(bsxfun(@eq, reshape(index.', N, [], G), permute(A, [2 3 4 1])), 1), 2), [3 4 1 2]);
However, the command is extremely slow for my real matrix sizes (N=19, M=500, G=524288
). I understand that I will not be able to get huge speed but anything that can improve on this is welcome.
If you have the Statistics Toolbox:
Response = ~(pdist2(index, A));
or:
Response = ~(pdist2(index, A, 'hamming'));
This works because pdist2
computes the distance between each pair of rows. Equal rows have distance 0
. The logical negation ~
gives 1
for those pairs of rows, and 0
otherwise.
This approach is faster on my machine:
[~,~,u] = unique([index; A], 'rows');
Response = bsxfun(@eq, u(1:G), u(G+1:end).');
It works by reducing rows to unique integer labels (using the third output of unique
), and comparing the latter instead of the former.
For your size values this takes approximately 1 second on my computer:
clear
N = 19; M = 500; G = 524288;
index = randi(5,G,N); A = randi(5,M,N);
tic
[~,~,u] = unique([index; A], 'rows');
Response = bsxfun(@eq, u(1:G), u(G+1:end).');
toc
gives
Elapsed time is 1.081043 seconds.
MATLAB has a multitude of functions for working with sets, including setdiff
, intersect
, union
etc. In this case, you can use the ismember
function:
[~, Loc] = ismember(A,index,'rows');
Which gives:
Loc =
1
0
0
1
2
And Response
would be constructed as follows:
Response = (1:size(index,1) == Loc).';
Response =
2×5 logical array
1 0 0 1 0
0 0 0 0 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With