Per my previous question, I have several mx2 matrices with rows from (0,1), (-1,0), (0,1), (0,-1), (1,1), (-1,1), (1,-1),(-1,-1) and I would like to find the frequency of each of above coordinates, I used unique and hisc to give me the frequency of each row. Now, since I would like to compare different matrices, I would like for each matrix have a corresponding output of 8 rows, where each row indicates the number of times that each of above coordinates appear. In particular, if e.g (0,1) is not among the rows of my matrix, I would like to see zero frequency.
For instance, if A=[1 1; 0 1; 1 0; -1 1;-1 1;0 1;0 1]
I would like to see something like:
-1 -1 0
-1 0 0
-1 1 2
0 -1 0
0 1 3
1 -1 0
1 0 1
1 1 1
Is there a way to do it? Thanks.
A = [ 1 1
0 1
1 0
-1 1
-1 1
0 1
0 1 ];
rows = [ -1 -1
-1 0
-1 1
0 -1
0 1
1 -1
1 0
1 1 ];
count = sum(squeeze(all(bsxfun(#eq, A.', permute(rows, [2 3 1])))));
Of course, if you need the result in the form shown in your question, just build the matrix result = [rows count.'].
Related
This question already exists:
How to select bits of a matrix in a particular pattern? [closed]
Closed 2 years ago.
Let A = 6x6 matrix,
which contains binary bits (nXn matrix).`
A=[ 1 0 1 0 1 0 ; 0 1 1 0 1 1;1 1 0 1 1 0; 0 0 1 0 0 1;0 1 1 0 1 1;0 1 0 1 1 1];
Let B be a 3x3sub matrix of A
B = [1 0 1;0 1 1;1 1 0];
Now, I want to select the bits 1 0 1 1 0, i.e, need to select bits present in positions (1,1) (1,2) (2,2) (3,2) (3,3).
Next I need to traverse this pattern in main Matrix A.
So, with the above pattern total bits selected will be 20 and remaining positions bits will be 16.
I want store the pattern wise selected values in one array and the values of remaining position values in another array.
Pattern wise selected values,
`p1=[1 0 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 1 1 1];`
values of remaining position,
p2=[1 0 1 1 0 0 1 1 1 0 1 0 1 0 1 1];
It would be more helpful if the code is generalized for nXn main matrix.
I have attached the pattern and the procedure as an image.
Can some one help me out?
[Procedure] 1
[Pattern] 2
I think this is what you want. It gives the same answers that you have at least. It should work for any size matrix A. It assumes that the pattern is always 3x3, but that could easily be generalised.
A = [1 0 1 0 1 0;0 1 1 0 1 1;1 1 0 1 1 0;0 0 1 0 0 1;0 1 1 0 1 1;0 1 0 1 1 1];
pattern = logical([1 1 0;0 1 0;0 1 1]);
% Split A into 3x3 sub matrices
subs = mat2cell(A, [3,3], [3,3])';
s = size(subs);
p1=[];
p2=[];
for i = 1 : s(1)*s(2)
sub = subs{i};
p1 = [p1 sub'(pattern')'];
p2 = [p2 sub'(~pattern')'];
end
p1
p2
Suppose you have an initial N-by-N matrix, with all diagonal elements equal to zero. You want to generate all possible N-by-N matrices such that:
all diagonal elements continue to be zero
columns and rows keep the sum from the initial matrix
all elements are positive integers (including zero)
For example, for this 3-by-3 initial matrix:
0 1 3
2 0 1
3 2 0
one possible variation is:
0 0 4
3 0 0
2 3 0
An initial idea for an answer, which can certainly be further improved.
You can start thinking of a way to make matrices that have zeros on the diagonal and where rows and columns sum to zeros. If these can be constructed easily, then you can obtain your result by adding your initial matrix with all of them.
e.g.:
[ 0 1 -2 1;
1 0 -1 0;
-1 2 0 -1;
0 -3 3 0];
You can even restrict these 'helper' matrices to have maximally a single 1 and a single -1 on each row/column. All others can be constructed from them.
e.g.
A = [ 0 -1 2 -1;
2 0 -2 0;
-2 1 0 1;
0 0 0 0];
B = [ 0 -1 1 0;
1 0 -1 0;
-1 1 0 0;
0 0 0 0];
C = [ 0 0 1 -1;
1 0 -1 0;
-1 0 0 1;
0 0 0 0];
% A equals B+C
I think this at least reduces your problem a bit. Good luck!
I want to find the index of all linear columns in matrix. The output is a vector in which gives 1 for independent columns and -1 for all linear dependency columns. For example, I have a matrix A that is
A =
1 0 0 0 0 1 1
1 0 0 1 0 1 1
1 1 1 0 1 1 1
1 1 1 0 1 1 0
We can see that column dependency are 1,2,3,5,6. Hence my expected result are
output=[-1 -1 -1 1 -1 -1 1];
And the independent matrix remains
A =
0 1
1 1
0 1
0 0
How to implement it by matlab ?
How about with linear rows?
I think you are looking for something like this -
out = ones(1,size(A,2))
out(sum(all(bsxfun(#eq,A,permute(A,[1 3 2])),1),2)>=2)=-1
So, basically for each column, it finds if there are any other matching columns and if there are, it identifies that as a "dependent" (from what I could gather as the definition for this problem) column.
Output -
out =
-1 -1 -1 1 -1 -1 1
For finding "dependency" across rows, use this -
out = ones(1,size(A,1))
out(sum(all(bsxfun(#eq,A,permute(A,[3 2 1])),2),1)>=2)=-1
Per my previous question couple days ago, now, I have several mx3 matrices with rows from (0,1,num), (-1,0,num), (0,1,num), (0,-1,num), (1,1,num), (-1,1,num), (1,-1,num),(-1,-1,num), where num is an integer which can take any values between 0 to 3.
I would like to create a new matrix, with 8 rows, and 6 columns, where the the first two columns represent each of the above coordinates, and each of the remaining columns indicate the frequency
of each of the above coordinates at each num values. i.e. columns 3 of each row indicates the number of times we see the coordinate corresponding to that row with and num=0. columns 4 of each row indicates the number of times we see the coordinate corresponding to that row with and num=1.
columns 5 of each row indicates the number of times we see the coordinate corresponding to that row with and num=2, and columns 6 of each row indicates the number of times we see the coordinate corresponding to that row with and num=3.
For instance, if A=[0 1 1
1 1 1
1 1 0
1 0 0
1 1 0
1 1 0
1 1 0
1 1 0
1 1 0
1 -1 0
1 1 0
1 1 3
1 1 2
1 1 3
1 1 3]
I would like to see something like:
-1 -1 0 0 0 0
-1 0 0 0 0 0
-1 1 0 0 0 0
0 -1 0 0 0 0
0 1 0 1 0 0
1 -1 1 0 0 0
1 0 1 0 0 0
1 1 7 1 1 3
Is there a way to do it? Thanks.
Try this:
counts = zeros(9, 6); % Initialize output matrix
k = 1;
for ii = -1:1
for jj = -1:1
ijCoords = (A(:,1) == ii) & (A(:,2) == jj); % Find rows containing coordinate (ii,jj)
ijCount = histc(A(ijCoords,3), 0:3); % Count how many 0,1,2,3 in these rows
counts(k,:) = [ii, jj, ijCount(:)']; % Add the counts to the next row of the output matrix
k = k + 1;
end
end
counts(5, :) = []; % Remove coordinate (0,0) because you don't want it.
I want to create a matrix A [4x8] as follows.
The matrix A always has 1 as its diagonal. A11,A22,A33,A44 = 1
This matrix can be considered as two halves with first half being the first 4 columns and the second half being the second 4 columns like something below :
1 -1 -1 -1 1 0 0 1
A = -1 1 -1 0 0 1 0 0
-1 -1 1 0 1 0 0 0
-1 -1 -1 1 1 1 0 0
Each row in the first half can have either two or three -1's:
if it has two -1's then that corresponding row in the second half should have one 1
if any row has three -1's the second half of the matrix should have two 1's.
The overall objective is to have the sum of each row to be 0. I need to generate all possible combinations of a matrix like this.
It will be better if the matrix with new combination be created at each iteration so that after using it I can discard it or else storing all the combinations is very space intensive. Can anybody help me ?
one possible solution I could think of is to generate all possible combinations of row1, row2, row3 and row4 and create a matrix in each iteration. Does that look feasible?
Here's one possible solution. If you ignore the diagonal ones for the moment, you can generate all possible patterns for the other 7 values using the functions KRON, REPMAT, PERMS, UNIQUE, EYE, and ONES:
>> rowPatterns = [kron(eye(3)-1,ones(4,1)) ... %# For 2 out of 3 as -1
repmat(eye(4),3,1); ... %# For 1 out of 4 as 1
repmat([-1 -1 -1],6,1) ... %# For 3 out of 3 as -1
unique(perms([1 1 0 0]),'rows')] %# For 2 out of 4 as 1
rowPatterns =
0 -1 -1 1 0 0 0
0 -1 -1 0 1 0 0
0 -1 -1 0 0 1 0
0 -1 -1 0 0 0 1
-1 0 -1 1 0 0 0
-1 0 -1 0 1 0 0
-1 0 -1 0 0 1 0
-1 0 -1 0 0 0 1
-1 -1 0 1 0 0 0
-1 -1 0 0 1 0 0
-1 -1 0 0 0 1 0
-1 -1 0 0 0 0 1
-1 -1 -1 0 0 1 1
-1 -1 -1 0 1 0 1
-1 -1 -1 0 1 1 0
-1 -1 -1 1 0 0 1
-1 -1 -1 1 0 1 0
-1 -1 -1 1 1 0 0
Note that this is 18 possible patterns for any given row, so your matrix A can have 18^4 = 104,976 possible row patterns (quite a bit). You can generate every possible 4-wise row pattern index by using the functions NDGRID, CAT, and RESHAPE:
[indexSets{1:4}] = ndgrid(1:18);
indexSets = reshape(cat(5,indexSets{:}),[],4);
And indexSets will be a 104,976-by-4 matrix with each row containing one combination of 4 values between 1 and 18, inclusive, to be used as indices into rowPatterns to generate a unique matrix A. Now you can loop over each set of 4-wise row pattern indices and generate the matrix A using the functions TRIL, TRIU, EYE, and ZEROS:
for iPattern = 1:104976
A = rowPatterns(indexSets(iPattern,:),:); %# Get the selected row patterns
A = [tril(A,-1) zeros(4,1)] + ... %# Separate the 7-by-4 matrix into
[zeros(4,1) triu(A)] + ... %# lower and upper parts so you
[eye(4) zeros(4)]; %# can insert the diagonal ones
%# Store A in a variable or perform some computation with it here
end
Here is another solution (with minimal looping):
%# generate all possible variation of first/second halves
z = -[0 1 1; 1 0 1; 1 1 0; 1 1 1]; n = -sum(z,2);
h1 = {
[ ones(4,1) z(:,1:3)] ;
[z(:,1:1) ones(4,1) z(:,2:3)] ;
[z(:,1:2) ones(4,1) z(:,3:3)] ;
[z(:,1:3) ones(4,1) ] ;
};
h2 = arrayfun(#(i) unique(perms([zeros(1,4-i) ones(1,i)]),'rows'), (1:2)', ...
'UniformOutput',false);
%'# generate all possible variations of complete rows
rows = cell(4,1);
for r=1:4
rows{r} = cell2mat( arrayfun( ...
#(i) [ repmat(h1{r}(i,:),size(h2{n(i)-1},1),1) h2{n(i)-1} ], ...
(1:size(h1{r},1))', 'UniformOutput',false) );
end
%'# generate all possible matrices (pick one row from each to form the matrix)
sz = cellfun(#(M)1:size(M,1), rows, 'UniformOutput',false);
[X1 X2 X3 X4] = ndgrid(sz{:});
matrices = cat(3, ...
rows{1}(X1(:),:), ...
rows{2}(X2(:),:), ...
rows{3}(X3(:),:), ...
rows{4}(X4(:),:) );
matrices = permute(matrices, [3 2 1]); %# 4-by-8-by-104976
%#clear X1 X2 X3 X4 rows h1 h2 sz z n r
Next you can access the 4-by-8 matrices as:
>> matrices(:,:,500)
ans =
1 -1 -1 -1 0 1 0 1
-1 1 -1 0 0 0 1 0
0 -1 1 -1 0 0 1 0
0 -1 -1 1 0 0 0 1
We could also confirm that all rows in all matrices sum to zero:
>> all(all( sum(matrices,2)==0 ))
ans =
1