# Create new matrix with compine values

1 view (last 30 days)
Ang Vas on 7 Feb 2020
Edited: Guillaume on 7 Feb 2020
Hi everybody I want your help. what I want to do is to have a program to produce a main matrix by using submatrices but by combine some values. For example, I have
a = [0 0 1; 1 0 0; 1 0 1] b = [1 0 1; 1 1 1;1 1 1] c= [0 0 0 ; 1 0 0 ; 0 1 1] d = [ 1 0 1;1 1 1; 1 0 0]
the matrix a has 9 elements which 4 of them are 1 the, b 9 elements with 8 of them are 1, c matrix has 3 elements of 1 and d 6 aces. My question is can I have a new matrix let say S that it has three elements of the above matrixes ( for instance S1 = [a d a] or S2 = [ d d d] or S3 = [ b c b] ) but S it will be accept only if contains from 3 up to 6 aces in average and that means the S1 and S2 matrix is acceptable but S3 in not. S1 - S2 - S3 are examples and might be a different one
Ang Vas on 7 Feb 2020
matrix c has 3 times one, the ccc is indeed 9 as a sum but I want the average which is 9/3=3 that's why is valid. Therefore for bcb is 8+3+8=19 the average is 6.33333 so is not valid

Guillaume on 7 Feb 2020
Edited: Guillaume on 7 Feb 2020
First, don't store your matrices in individual variables, it complicates everything. Since they're all the same size store them as pages of a 3D matrix:
M = cat(3, [0 0 1; 1 0 0; 1 0 1], [1 0 1; 1 1 1;1 1 1], [0 0 0 ; 1 0 0 ; 0 1 1], [ 1 0 1;1 1 1; 1 0 0])
With that it's trivial to choose a combination of any 3 of the matrices:
selectedindices = randi(size(M, 4), 1, 3); %select 3 indices at random
So, to get the result you want:
mean_ones = NaN; %initial condition will always result in false, so we go at least once through the loop
while mean_ones < 3 | mean_ones < 6 %while we don't have a set that matches the criteria
selectedindices = randi(size(M, 4), 1, 3); %select 3 indices at random
selectematrices = M(:, :, selectedindices);
mean_ones = nnz(selectedmatrices) / 3;
end
edit: and if you want to generate all possible combinations or 3 matrices that follow your criteria, like fred did in his answer:
%M: 3D matrix as above
allcombs = dec2bin(0:size(M, 3)^3-1, size(M, 3)) - '0' + 1; %works for up to 10 matrices
allmatcombs = reshape(M(:, :, allcombs'), size(M, 1), size(M, 2), size(M, 3), []);
meanmat = sum(allmatcombs, 1:3) / 3; %requires 2018b or later. Earlier versions: sum(sum(sum(allmatcombs, 1), 2, 3) / 3
selectedmatcombs = allmatcombs(:, :, :, meanmat >= 3 & meanmat <= 6);

fred ssemwogerere on 7 Feb 2020
Hello, this should do nicely using a 3D-cell array:
a = [0 0 1; 1 0 0; 1 0 1]; b = [1 0 1; 1 1 1;1 1 1];
c= [0 0 0 ; 1 0 0 ; 0 1 1]; d=[ 1 0 1;1 1 1; 1 0 0];
% Store your matrices in a cell array
M={a,b,c,d};
% Compute number of nonzero elements for each matrix and store them in a cell array
N={nnz(a),nnz(b),nnz(c),nnz(d)};
% for a concantenation of 3 matrices use 3 "for" loops
for i=1:size(M,2)
for j=1:size(M,2)
for k=1:size(M,2)
% Computing the mean of any 3 number non-zero elements
P{i,j,k}=mean([N{i},N{j},N{k}]);
% Set a conditional "if" to determine which average of nonzero numbers lies within 3-6 as you want
if 3<=P{i,j,k}&& P{i,j,k}<=6
% Arrays that meet the above condition are horizontally concatenated
L{i,j,k}=horzcat(M{i},M{j},M{k}); %#ok<*SAGROW>
else
% Cell arrays that don't meet the condition are set to zero (they are not required)
L{i,j,k}=0;
end
end
end
end
Guillaume on 7 Feb 2020
I would recommend using numel(M) rather than size(M, 2). That way the code works whether M is a row or column vector (or even a ND matrix).
The code would also be simpler if you used a 3D matrix instead of a cell array.