How to make a new matrix with all common arrays from different matrices

Suppose I have some matrices as follow:
m1 = [1;2;3;4;5;6;7;8];
m2 = [2;3;4;6;7;8;9;10;11;12];
m3 = [4;5;6;7;8;9;1;;16];
m4 = [8;8;5;4;3;1;6;7];
I need a matrix which is included all common arrays in all matrices, such as:
m = [4;6;7;8];

Answers (3)

m1 = [1;2;3;4;5;6;7;8];
m2 = [2;3;4;6;7;8;9;10;11;12];
m3 = [4;5;6;7;8;9;1;;16];
m4 = [8;8;5;4;3;1;6;7];
a=intersect(m1,m2)
b=intersect(m3,m4)
out=intersect(a,b)

4 Comments

Thanks Mr. Azzi. Why we can't make all m1 to m4 in one matrix? In my case, I have odd numbers of matrices which they are updating in each iteration as well (dimension will be different in each iteration, so I have to use cell array {}).
Can you help with different way?
Ok, you can do it this way
m1 = [1;2;3;4;5;6;7;8];
m2 = [2;3;4;6;7;8;9;10;11;12];
m3 = [4;5;6;7;8;9;1;;16];
m4 = [8;8;5;4;3;1;6;7];
m={m1,m2,m3,m4}
a=[];
for k=1:numel(m)
a=intersect(a,m{k})
end
Result of this code is:
a =
Empty matrix: 0-by-1
Sorry
m1 = [1;2;3;4;5;6;7;8];
m2 = [2;3;4;6;7;8;9;10;11;12];
m3 = [4;5;6;7;8;9;1;;16];
m4 = [8;8;5;4;3;1;6;7];
m={m1,m2,m3,m4}
a=m{1}
for k=2:numel(m)
a=intersect(a,m{k})
end

Sign in to comment.

I don’t know why you have to use a cell array, but then I’m only slightly familiar with what you’re doing.
Using eval is not considered good programming style, but this code may work for you. (It does do what you want.) You can make ‘M’ a cell array if you like, but keeping it numeric might be better:
m1 = [1;2;3;4;5;6;7;8];
m2 = [2;3;4;6;7;8;9;10;11;12];
m3 = [4;5;6;7;8;9;1;;16];
m4 = [8;8;5;4;3;1;6;7];
n = 4;
M = m1;
for k1 = 2:n
M = intersect(M,eval(['m' num2str(k1)]));
end
See if it works for you.

6 Comments

Thanks Star.
I need something like M{j}. Because, all matrices (m1 to m4) will be updated in each iteration and then I'll have different M in each iteration. How can I have different M in each iteration?
If I use:
M{j} = intersect(M,eval(['m' num2str(k1)]));
It gives me the following error:
Error using
cell/intersect>cellintersectlegacy
(line 158)
Input A of class cell and input B
of class cell must be cell arrays
of strings, unless one is a string.
Error in cell/intersect (line 91)
[varargout{1:nlhs}] =
cellintersectlegacy(varargin{:});
Error in nov11112014 (line 2022)
mm{j} = intersect(mm,eval(['rm'
num2str(rk1)]));
My pleasure!
The errors you are getting are because you defined ‘M’ as a cell first. I suggest you keep everything as numeric arrays if you’re going to use them as numeric arrays. If you’re storing them as cell arrays, convert them to numeric arrays before you use them in this code and my other code.
I don’t know what you’re doing, but I don’t understand the need for cell arrays here, if you re-define your ‘m#’ vectors each time as numeric vectors. Cell arrays are quite useful, but primarily if you’re storing multiple vectors of different sizes or types in the same variable. If you are storing the vectors you are using later as elements of cell arrays, you can easily convert them to numeric arrays and then use them as numeric arrays.
Thanks Star!
I need to record M in each iteration, that's why I'm looking in some way to record M! However, I used the following code and seems that it works!
mm{j} = intersect(intersect(intersect(a{j},b{j}),c{j}),m7{j}); % for 7 different "m" matrices (a is intersect of m1 and m2 and...)
My pleasure!
I would calculate ‘M’ from your ‘m#’ numeric vectors for each iteration with the eval loop and save it as a an element of a cell array, since you need to save it. The loop is likely faster than nested intersect calls, and has the flexibility of your easily being able to vary the number of vectors to intersect by simply changing ‘n’.
Thanks Star!
Can you give a example of that code way you mentioned? Because I have more than 1000 iterations and computational time is very important in my code as well!
My pleasure!
I’m not certain that I understand exactly what you’re doing, but if you’re naming your vectors ‘m1’...‘m4’, use the code in my original answer (the eval loop) will sort them and take their intersections automatically.
You can wrap them in a function:
function M = vctintsct(m1,m2,m3,m4)
n = 4;
M = m1;
for k1 = 2:n
M = intersect(M,eval(['m' num2str(k1)]));
end
end
This works if you always have four vectors (you can name them anything in this instance, since the function will name them ‘m1’ etc.), then simply call the function as:
M = vctintsct(m1,m2,m3,m4);
and get ‘M’ as the output. It is a double-precision vector, but you can then assign it as an element of a cell array in your main script. If you have varying numbers of vectors, the function gets a bit more complicated but will still work.

Sign in to comment.

m1 = [1;2;3;4;5;6;7;8];
m2 = [2;3;4;6;7;8;9;10;11;12];
m3 = [4;5;6;7;8;9;1;;16];
m4 = [8;8;5;4;3;1;6;7];
MM = {m1,m2,m3,m4};
z = cat(1,MM{:});
[a,~,c] = unique(z);
nn = cellfun(@numel,MM);
ii = accumarray(cumsum([1,nn])',1);% Idea by Roger Stafford
ii = cumsum(ii(1:end-1)); %
out = a(all(accumarray([c,ii],1),2));

Asked:

Moe
on 11 Nov 2014

Edited:

on 12 Nov 2014

Community Treasure Hunt

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

Start Hunting!