I use combnk to generate a list of combinations. But, the result shape is not my required data. I want for example for combnk(1:3,2):
1 1 0
0 1 1
1 0 1
not
1 2
1 3
2 3
How can i do it? How can i change the combnk in optimal way to give results?
Don't you mean you want
1 1 0
1 0 1
0 1 1
instead of
1 2
1 3
2 3
So that each row is a logical selection vector for the original vector v?
You can get this with the following:
v = 1:3;
k = 2;
tmp = combnk(v,k);
M = size(tmp,1);
output = false(M,numel(v));
output(sub2ind(size(output),repmat((1:M)',1,k),tmp))=true;
result:
output =
1 1 0
1 0 1
0 1 1
Another solution:
c = combnk(1:3,2);
r = repmat(1:size(c,1), [1 size(c,2)]);
output = full(sparse(r,c(:),1))
result:
output =
1 1 0
1 0 1
0 1 1
Related
In Matlab, im looking for a way to solve the following issue in an a bit more elegant way:
In an threedimensional array, on one dimension (i.e. time in my case), from some index on all values equal zero, e.g. the following example array a is 0 for an index of 3 for the second dimension (i.e. a(:,3:end,: == 0)):
a(:,:,1) =
1 1 0
1 0 0
1 0 0
a(:,:,2) =
1 1 0
1 0 0
1 1 0
a(:,:,3) =
1 1 0
1 1 0
1 1 0
[edit, was asked for expected outcome]
expected outcome is:
o(:,:,1) =
1 1
1 0
1 0
o(:,:,2) =
1 1
1 0
1 1
o(:,:,3) =
1 1
1 1
1 1
now of course i could just check for each index in dimension 2, whether it actually is zero everywhere, which is what i'm doing right now, but i feel like there is some better way of solving this issue in matlab in some more elegant way (and possibly even for any multidimensional array). Thanks for helping!
function req = removeColwithSpecVal(a,spec_val)
req=num2cell(a,[1 2]); %Converting to cell keeping the order of rows & columns same
req=vertcat(req{:}); %Stacking multidimensional slices vertically
ind= ~all(req==spec_val,1);%Finding logical indices of the required columns
req = req(:,ind); %The matrix after removal of the not required columns
%Finding the size of the input matrix 'a'; stacking with 1 so that
%it is applicable on 1-D/2-D matrices as well
sz =[size(a) 1];
%Finding the # of columns that the required multi-dimensional matrix will have
sz(2)= numel(req)/prod([sz(1), sz(3:end)]);
%Reshaping to the desired result
req=reshape(permute(reshape(req.', sz(2),sz(1),[]),[2 1 3]),sz);
end
Sample Runs:
%1-D Example
spec_val=5;
a=[1 4 5 2 5];
req = removeColwithSpecVal(a,spec_val)
req =
1 4 2
%2-D Example
spec_val=0;
a=[1 1 0 ;
1 0 0 ;
1 0 0 ];
req = removeColwithSpecVal(a,spec_val)
req =
1 1
1 0
1 0
%Your example (3-D)
spec_val=0;
a(:,:,1) = [1 1 0;
1 0 0;
1 0 0];
a(:,:,2) = [1 1 0;
1 0 0;
1 1 0];
a(:,:,3) = [1 1 0;
1 1 0;
1 1 0];
req = removeColwithSpecVal(a,spec_val)
req(:,:,1) =
1 1
1 0
1 0
req(:,:,2) =
1 1
1 0
1 1
req(:,:,3) =
1 1
1 1
1 1
Also applicable on higher dimensional matrices.
I want to create a matrix from all combinations of elements of one vector that fulfill a condition
For example, I have this vector
a = [1 2 3 4 5]
and want to create a matrix like
a = [1 0 0 0 0;
1 2 0 0 0;
1 2 3 0 0;
1 2 3 4 0;
1 2 3 4 5;
0 2 0 0 0;
0 2 3 0 0;
........;]
and then get the rows that fulfill the condition I can use the command:
b = sum(a')' > value
but I don't know how to generate the matrix
You can generate all possible binary combinations to determine the matrix you want:
a = [1 2 3];
n = size(a,2);
% generate bit combinations
c =(dec2bin(0:(2^n)-1)=='1');
% remove first line
c = c(2:end,:)
n_c = size(c,1);
a_rep = repmat(a,n_c,1);
result = c .* a_rep
Output:
c =
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
result =
0 0 3
0 2 0
0 2 3
1 0 0
1 0 3
1 2 0
1 2 3
Given a square binary matrix. I want to get all possible binary matrices which are at d Hamming distance apart.
Suppose
A=[1 0 1;
0 1 1;
1 1 0].
Then a matrix which is one (d) Hamming distance apart is
[0 0 1;
0 1 1;
1 1 0].
Any help in Matlab base coding?
I am hoping that I got the definition of hamming weight right in the given context. Based on that hope/assumption, this might be what you were after -
combs = dec2base(0:2^9-1,2,9)-'0'; %//'# Find all combinations
combs_3d = reshape(combs',3,3,[]); %//'# Reshape into a 3D array
%// Calculate the hamming weights between A and all combinations.
%// Choose the ones with hamming weights equal to `1`
out = combs_3d(:,:,sum(sum(abs(bsxfun(#minus,A,combs_3d)),2),1)==1)
Thus, each 3D slice of out would give you such a 3 x 3 matrix with 1 hamming weight between them and A.
It looks like you have 9 such matrices -
out(:,:,1) =
0 0 1
0 1 1
1 1 0
out(:,:,2) =
1 0 1
0 1 1
0 1 0
out(:,:,3) =
1 0 1
0 0 1
1 1 0
out(:,:,4) =
1 0 1
0 1 1
1 0 0
out(:,:,5) =
1 0 0
0 1 1
1 1 0
out(:,:,6) =
1 0 1
0 1 0
1 1 0
out(:,:,7) =
1 0 1
0 1 1
1 1 1
out(:,:,8) =
1 1 1
0 1 1
1 1 0
out(:,:,9) =
1 0 1
1 1 1
1 1 0
Edit
For big n, you need to use loops it seems -
n = size(A,1);
nsq = n^2;
A_col = A(:).';
out = zeros(n,n,nsq);
count = 1;
for k1 = 0:2^nsq-1
match1 = dec2bin(k1,nsq)-'0';
if sum(abs(match1-A_col))==1
out(:,:,count) = reshape(match1,n,n);
count = count + 1;
end
end
I'm trying to write a program to check the results of all possible combinations of 5 separate 5x5 matrices, where each element in all the matrices are booleans. However, my problem is I can't figure out a way to cause the matrices to check through every combination.
Illustrating what I would like to happen for a 2x2 matrix. I want my program to produce the matrix as follow:
(1) [0 0;0 0]
(2) [1 0;0 0]
(3) [1 1;0 0]
(4) [1 1;1 0]
(5) [1 1;1 1]
(6) [1 0;0 1]
(7) [1 1;0 1]
…
and so on until every possible matrix has been done. How I may achieve this, so that I do some operation with every one of these matrix combinations?
(I realise this will probably take an impossibly long time to completely cycle through 5 5x5 matrices, however I also wish to do it for smaller matrices (3 3x3's) and I would also like to just leave it running as long as possible to check through as many possible 5 5x5's and seeing, out of the ones I've checked, which is the best result.)
So, as you can see, you have several combinations of a zero matrix you want to add a one, right?
We could say that you have the following possible combinations you want to add a one. For the 2 dimensional case:
addOnes =
Empty matrix: 1-by-0
onePossibleCombination =
0 0
0 0
addOnes =
1
onePossibleCombination =
1 0
0 0
addOnes =
2
onePossibleCombination =
0 0
1 0
addOnes =
3
onePossibleCombination =
0 1
0 0
addOnes =
4
onePossibleCombination =
0 0
0 1
addOnes =
1 2
onePossibleCombination =
1 0
1 0
addOnes =
1 3
onePossibleCombination =
1 1
0 0
addOnes =
1 4
onePossibleCombination =
1 0
0 1
addOnes =
2 3
onePossibleCombination =
0 1
1 0
addOnes =
2 4
onePossibleCombination =
0 0
1 1
addOnes =
3 4
onePossibleCombination =
0 1
0 1
addOnes =
1 2 3
onePossibleCombination =
1 1
1 0
addOnes =
1 2 4
onePossibleCombination =
1 0
1 1
addOnes =
1 3 4
onePossibleCombination =
1 1
0 1
addOnes =
2 3 4
onePossibleCombination =
0 1
1 1
addOnes =
1 2 3 4
onePossibleCombination =
1 1
1 1
How can we achieve that? All we need is to take all combinations taken by 0, 1, 2, 3 and 4. For that we use the nchoosek method as follows:
matrixSize = 2;
for k=0:matrixSize^2
combinations=nchoosek(1:matrixSize^2,k);
for m = 1:size(combinations,1)
addOnes = combinations(m,:);
onePossibleCombination = zeros(matrixSize,matrixSize);
onePossibleCombination(addOnes) = 1;
% Do your operation here with the matrix onePossibleCombination
end
end
I have this matrix:
A = [1 3
5 7
9 10];
And this vector:
B = zeros(1,10);
Now I want to change the elements in the ranges of [1:3],[5:7] and [9:10] to 1 .
So, to get this:
C = [1 1 1 0 1 1 1 0 1 1];
I tried:
B(A(:,1):A(:,2)) = 1;
but it just changes the zeros in the first range.
Can it be done without a for loop?
Thanks.
The first column of A are starting positions and the second one are ending positions of each sequence of 1s. To denote a beginning use 1 and for the end -1, then cumsum().
% Preallocate
N = 10;
B = zeros(1,N);
B(A(:,1)) = 1
B =
1 0 0 0 1 0 0 0 1 0
B(A(:,2)+1) = -1
B =
1 0 0 -1 1 0 0 -1 1 0 -1
B = cumsum(B)
B =
1 1 1 0 1 1 1 0 1 1 0
B(1:N)
ans =
1 1 1 0 1 1 1 0 1 1
Would something like this be appropriate?
>> f = #(x)(any(A(:,1)<=x & x<=A(:,2)));
>> i = 1:length(B)
i =
1 2 3 4 5 6 7 8 9 10
>> arrayfun(f,i)
ans =
1 1 1 0 1 1 1 0 1 1
Hello you can try this:
B([A(1,1):A(1,2) A(2,1):A(2,2) A(3,1):A(3,2)]) = 1;