Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
[need help]: comparing matrices by rows

Subject: [need help]: comparing matrices by rows

From: Bree

Date: 7 Oct, 2010 06:33:41

Message: 1 of 8

Dear experts,

I have two different matrices which are needed to be compared.
For example:
A = [1 2 4; 5 4 3; 6 7 8];
B = [2 1 3; 6 5 1; 7 8 6];
What I would like to do is just finding the intersection of rows matrix A and rows matrix B, regardless the position of their component.
To make it clear, the output I want is:
output = [2;1;3]
where output(1) = 2 comes from the length of intersect(A(1,:),B(1,:)).

I used my script as follows:
%%%%%%%%%%%%%%%
oput = zeros(size(A,1),1);
for itr = 1:size(A,1)
     oput(itr,1) = length(intersect(A(itr,:),B(itr,:)));
end
%%%%%%%%%%%%%%%

but my script consumes so much times due to my huge data.

Any idea for better script and less time consumes?

best,
-Bree

Subject: [need help]: comparing matrices by rows

From: Sean

Date: 7 Oct, 2010 13:26:03

Message: 2 of 8

> I have two different matrices which are needed to be compared.
> For example:
> A = [1 2 4; 5 4 3; 6 7 8];
> B = [2 1 3; 6 5 1; 7 8 6];
> What I would like to do is just finding the intersection of rows matrix A and rows matrix B, regardless the position of their component.
> To make it clear, the output I want is:
> output = [2;1;3]
> where output(1) = 2 comes from the length of intersect(A(1,:),B(1,:)).
>
> I used my script as follows:
> %%%%%%%%%%%%%%%
> oput = zeros(size(A,1),1);
> for itr = 1:size(A,1)
> oput(itr,1) = length(intersect(A(itr,:),B(itr,:)));
> end
> %%%%%%%%%%%%%%%
>
> but my script consumes so much times due to my huge data.
>
> Any idea for better script and less time consumes?

Here's a way that will use about 55-60% of the time:
%Instead of counting the intersection, subtract the difference from the original quantity to the union quantity
%Data
A = repmat([1 2 4; 4 3 8; 6 7 8],100,1);
B = repmat([2 1 3; 6 5 1; 7 8 6],100,1);

%Preallocate
inte = zeros(300,1);
un = zeros(300,1);
itime =0;
utime =0;

%Time Tester
for ii = 1:10
    tic
    for jj = 1:300
        inte(jj) = numel(intersect(A(jj,:),B(jj,:)));
    end
    itime = itime+toc;
    tic
    for jj = 1:300
        un(jj) = numel(union(A(jj,:),B(jj,:)));
    end
    un = 6-un;
    utime = utime+toc;
end
%Results
isequal(inte,un)
utime/itime

Subject: [need help]: comparing matrices by rows

From: Bree

Date: 8 Oct, 2010 05:19:03

Message: 3 of 8

Dear Sean,

Thanks alot for the reply.
Your sample is faster than mine, but I still could not understand the logic behind it. Mind if you explain it to me? why matlab does faster in taking the union first then taking the substraction process compares with directly taking the intersection?

What I really like to do in my algorithm is trying to exclude any loop function.
Have another idea?

best,
-Bree


"Sean " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <i8khpb$b1s$1@fred.mathworks.com>...
> > I have two different matrices which are needed to be compared.
> > For example:
> > A = [1 2 4; 5 4 3; 6 7 8];
> > B = [2 1 3; 6 5 1; 7 8 6];
> > What I would like to do is just finding the intersection of rows matrix A and rows matrix B, regardless the position of their component.
> > To make it clear, the output I want is:
> > output = [2;1;3]
> > where output(1) = 2 comes from the length of intersect(A(1,:),B(1,:)).
> >
> > I used my script as follows:
> > %%%%%%%%%%%%%%%
> > oput = zeros(size(A,1),1);
> > for itr = 1:size(A,1)
> > oput(itr,1) = length(intersect(A(itr,:),B(itr,:)));
> > end
> > %%%%%%%%%%%%%%%
> >
> > but my script consumes so much times due to my huge data.
> >
> > Any idea for better script and less time consumes?
>
> Here's a way that will use about 55-60% of the time:
> %Instead of counting the intersection, subtract the difference from the original quantity to the union quantity
> %Data
> A = repmat([1 2 4; 4 3 8; 6 7 8],100,1);
> B = repmat([2 1 3; 6 5 1; 7 8 6],100,1);
>
> %Preallocate
> inte = zeros(300,1);
> un = zeros(300,1);
> itime =0;
> utime =0;
>
> %Time Tester
> for ii = 1:10
> tic
> for jj = 1:300
> inte(jj) = numel(intersect(A(jj,:),B(jj,:)));
> end
> itime = itime+toc;
> tic
> for jj = 1:300
> un(jj) = numel(union(A(jj,:),B(jj,:)));
> end
> un = 6-un;
> utime = utime+toc;
> end
> %Results
> isequal(inte,un)
> utime/itime

Subject: [need help]: comparing matrices by rows

From: Bruno Luong

Date: 8 Oct, 2010 06:46:03

Message: 4 of 8

A = [1 2 4; 5 4 3; 6 7 8];
B = [2 1 3; 6 5 1; 7 8 6];

[AB loc] = sort([A B], 2);
inA = loc<=size(A,2);
ABeq = diff(AB,1,2)==0;
inboth = xor(inA(:,1:end-1),inA(:,2:end));
sum(ABeq & inboth,2)

ans =

     2
     1
     3

% Bruno

Subject: [need help]: comparing matrices by rows

From: Bruno Luong

Date: 8 Oct, 2010 07:05:19

Message: 5 of 8

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <i8menb$acd$1@fred.mathworks.com>...
> A = [1 2 4; 5 4 3; 6 7 8];
> B = [2 1 3; 6 5 1; 7 8 6];
>
> [AB loc] = sort([A B], 2);
> inA = loc<=size(A,2);
> ABeq = diff(AB,1,2)==0;
> inboth = xor(inA(:,1:end-1),inA(:,2:end));
> sum(ABeq & inboth,2)
>
> ans =
>
> 2
> 1
> 3
>
> % Bruno

I should note that the above works even when common element are repeated within A or B since Matlab SORT is a *stable* sorting algorithm, i.e., it will not create mess between A and B output locations.

Bruno

Subject: [need help]: comparing matrices by rows

From: Bree

Date: 8 Oct, 2010 07:34:06

Message: 6 of 8

Dear Bruno,

Though your algorithm hurts my eyes, but it's true faster and no-loop anymore.
thanks alot for the idea....

It's lovely for being "dirty" sometimes...

love it.
-Bree

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <i8menb$acd$1@fred.mathworks.com>...
> A = [1 2 4; 5 4 3; 6 7 8];
> B = [2 1 3; 6 5 1; 7 8 6];
>
> [AB loc] = sort([A B], 2);
> inA = loc<=size(A,2);
> ABeq = diff(AB,1,2)==0;
> inboth = xor(inA(:,1:end-1),inA(:,2:end));
> sum(ABeq & inboth,2)
>
> ans =
>
> 2
> 1
> 3
>
> % Bruno

Subject: [need help]: comparing matrices by rows

From: Bruno Luong

Date: 8 Oct, 2010 07:49:03

Message: 7 of 8

"Bree " <breezulmaid@gmail.com> wrote in message <i8mhhe$bpe$1@fred.mathworks.com>...

>
> It's lovely for being "dirty" sometimes...

Beauty is in the eye of beholder

Bruno

Subject: [need help]: comparing matrices by rows

From: Sean

Date: 8 Oct, 2010 12:32:04

Message: 8 of 8

> > A = [1 2 4; 5 4 3; 6 7 8];
> > B = [2 1 3; 6 5 1; 7 8 6];
> >
> > [AB loc] = sort([A B], 2);
> > inA = loc<=size(A,2);
> > ABeq = diff(AB,1,2)==0;
> > inboth = xor(inA(:,1:end-1),inA(:,2:end));
> > sum(ABeq & inboth,2)
> Bruno

Bruno, that is a gorgeous solution.

Bree, for your earlier question I think the reason a union is faster than an intersection is because it just has to call a unique of the two concatenated sets. It doesn't have to call unique and then figure out which elements come from which sets.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us