Create new matrix with compine values
1 view (last 30 days)
Show older comments
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
6 Comments
Guillaume
on 7 Feb 2020
Edited: Guillaume
on 7 Feb 2020
As an engineer I've never heard of that abbreviation. It's not much an abbreviation, since ace and one have as many letters! Anyway,
Why is [c c c] valid when the number of ones sum up to 9 which is clearly greater than 6? In fact, it doesn't appear that any combination of 3 matrices would be valid since the combination with the least ones, [c c c], is already above your threshold.
Accepted Answer
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);
0 Comments
More Answers (1)
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
1 Comment
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.
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!