Generate All Possible combinations of a Matrix in Matlab - matlab

How can I generate ALL possible values for an N*M matrix, knowing that elements of this matrix can only be either be 0 or 1?
For example if I want a 2*2 matrix, we get 16 matrices with the different possible combinations: [0 0;0 0], [1 1;1 1], [1 0;0 1],[1 1; 0 0],[0 0;1 1]...etc

Use dec2base -
combs = dec2base(0:power(2,N*M)-1,2) - '0'
This generates all the possible combinations in rows. So, to select any combination, you need to index into combs. Thus, the first combination [0,0,0,0] would be available at combs(1,:) and the last one [1,1,1,1] would be at comb(end,:).
If your possible values are from a different set, like 0,1,2,3 instead, make this edit -
combs = dec2base(0:power(4,N*M)-1,4) - '0'
If you would to get the combinations that would be sized identically to the input matrix, use this -
combs_matshaped = reshape(permute(combs,[3 2 1]),N,M,[])
This creates a 3D array of as many 2D slices as there are combinations and each combination for the matrix is "index-able" with the third dimension index. For example, if you intend to get the first combination, use combs_matshaped(:,:,1) and for the last one, use combs_matshaped(:,:,end).

Another possibility (although Divakar's answer is simpler and probably faster):
c = cell(1,N*M);
[c{end:-1:1}] = ndgrid([0 1 2 3 ]); %// or change set of values: [0 1 2 3] etc
combs = cell2mat(cellfun(#(x) x(:), c, 'uni', 0)); %// results as row vectors
combs = reshape(combs.',N,M,[]); %// NxM matrices: combs(:,:,1), combs(:,:,2),...

Related

Create trinomial tree scenarios in matrix rows

In Matlab I'm trying to create a 3^(n-1) by n matrix containing in each row a scenario of a trinomial tree. i.e. in total all the rows together contain all possible paths that can be followed in the tree. At each point in the tree the path goes either up, stay the same or go down. I want to denote this in the matrix with 1, 0 or -1 respectively. An example for n = 3 would be:
[0,-1,-1;
0,-1,0;
0,-1,1;
0,0,-1;
0,0,0;
0,0,1;
0,1,-1;
0,1,0;
0,1,1]
I want to generalize this for n steps.
Your question is basically answered here, written by Luis Mendo. Only minor adjustments required.
What you want are all combinations of:
vectors = { [0], [-1 0 1], [-1 0 1] }; %matching your example
Or more generally for arbitrary:
vectors = [0,repmat({[-1 0 1]},1,n-1)]; %start with 0, then repeat [-1,0,1] n times
Then you can continue with the linked answer, quoting here:
n = numel(vectors); %// number of vectors
combs = cell(1,n); %// pre-define to generate comma-separated list
[combs{end:-1:1}] = ndgrid(vectors{end:-1:1}); %// the reverse order in these two
%// comma-separated lists is needed to produce the rows of the result matrix in
%// lexicographical order
combs = cat(n+1, combs{:}); %// concat the n n-dim arrays along dimension n+1
combs = reshape(combs,[],n); %// reshape to obtain desired matrix

creating matrix from data-set

I have a network with edges and points. The FID shows the ID number of each edge that is created by Start_Point and End_Point. For example edge 3 is between the two points of 2 and 3 in the network.
FID Start_Point End_Point
1 1 2
2 1 4
3 2 3
4 2 4
I want to create a 4-by-4 matrix of these points. if there is an edge between 2 points the value is 1 else is inf:
[inf, 1, inf, 1;
1, inf, 1, 1;
inf, 1, inf, inf;
1, 1, inf, inf]
How can I create such a matrix in MATLAB?
You can convert it to a sparse matrix and then use full command to obtain adjacency matrix.
edges= [1 2;
3 4;
3 1
2 3];
n=size(edges,1);
% create sparse matrix with given edges and their reverse direction
A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]);
% create adjacency matrix
B=full(A);
% set zeros to inf
B(B==0)=inf;
and this is the result :
A =
(2,1) 1
(3,1) 1
(1,2) 1
(3,2) 1
(1,3) 1
(2,3) 1
(4,3) 1
(3,4) 1
>> B
B =
Inf 1 1 Inf
1 Inf 1 Inf
1 1 Inf 1
Inf Inf 1 Inf
Edit :
the sparse command create a sparse matrix with addressing values of its elements. One prototype for this command is as follow :
A=sparse(rows,cols,values);
for example A=sparse([1;2],[1,3],[10,5]) is a matrix which A(1,1)=10 and A(2,3)=5 and other elements are zero:
A=sparse([1;2],[1,3],[10,5]);
>> full(A)
ans =
10 0 0
0 0 5
In your case you have to add two directions to sparse matrix (symmetric) and all values are one. So you need to construct sparse matrix as :
A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]);
full command convert a sparse matrix to a dense one.
So you basically want to create an adjacency matrix from an adjacency list of edges? The number of your edges (i.e. your FID column) is irrelevant so I'm assuming your input data is of the form
edges = [1 2
1 4
2 3
2 4]
Now the first column of edges is the rows of your adjacency matrix and the second is the columns (or vice versa, it doesn't matter since your matrix is symmetrical)
The simplest solution is to use linear index which you would get via the sub2ind function:
adj = inf(size(edges,2));
idx = sub2ind(size(adj),edges(:,1), edges(:,2))
adj(idx) = 1;
I suspect your edges matrix will already be symmetrical but if it's not then just use
edges_sym = [edges; fliplr(edges)]
instead of edges
You can use accumarray:
edges1 = accumarray([startpoint endpoint]),1);
edges2 = edges1.'; % transpose your matrix, to obtain both edges
edges = edges1+edges2;
edges(edges==0)=inf;
accumarray gathers all points with common indices, pastes the value 1 on those indices. edges1 is the transpose of edges2, thus transpose, then add the two together. Find all indices on which the matrix is 0, then fill those values with inf.
Alternative:
edges= [1 2;
3 4;
3 1
2 3];
matrix = accumarray([edges;fliplr(edges)],1,[],[],inf);
fliplr flips your matrix left to right, to get all the desired combinations of indices. Then use accumarray to set a 1 on all locations specified by edges and put inf at the other locations.
If you are sure your matrix is symmetric, don't use fliplr, if you sure your matrix is non-symmetric, use fliplr and if you are not sure use this:
matrix = accumarray([edges;fliplr(edges)],1,[],#mean,inf);
where the #mean makes sure to set double entries to 1 anyway. For weighted edges do the following, where weights is an Nx1 array containing the weights and N is the number of edges.
matrix = accumarray([edges;fliplr(edges)],weights,[],#mean,inf);

Check element wise equality of a 3D matrix Matlab

I have a 3D matrix say for eg. A(10x5x8). I need to get a 2D matrix (Boolean) out of it of size 10x5.
True if its elemental 3 Dimensional values are all same. i.e. Result(1,1) = 1 if A(1,1,1) == A(1,1,2) == A(1,1,3) etc..
False if at least one is different.
I expect a vectored approach which is fast and efficient.
Sample input:
A(:,:,1) = 1 2
2 2
A(:,:,2) = 1 1
2 3
Expected Output:
Result = 1 0
1 0
Use bsxfun with the eq function and use the first slice as the first input and compare with the other slices for the second input. Allow the first input to broadcast itself over the multiple slices.
Once you do that, use all and check the third dimension:
ind1 = bsxfun(#eq, A(:,:,1), A(:,:,2:end);
ind2 = all(ind1, 3);
The logic behind the above is very simple. How the first line of code works is that you would create a temporary matrix that would take the first slice of A and let it duplicate itself for as many slices as you have in A, without the first slice. Once you do this, you would do an element-by-element equality with this temporary matrix and the other slices. If you had a 3D column that was all equal, the one element from the first slice would be compared with every single value that corresponds to the same 3D column. Should they all equal to each other, then you would get a 3D column of all logical 1s. Therefore, to have a 3D column that is all equal to each other, all of the values should be 1, which is why all is used - to check if all values in a 3D column are equal to 1. Should all of the 3D column be a logical 1, we have matched your criteria.
Example run
>> A1 = [1 2; 2 2];
>> A2 = [1 1; 2 3];
>> A3 = [1 3; 2 4];
>> A4 = [1 5; 2 6];
>> A = cat(3, A1, A2, A3, A4);
>> ind1 = bsxfun(#eq, A(:,:,1), A(:,:,2:end);
>> ind2 = all(ind1, 3)
ind2 =
1 0
1 0
I made a matrix of 4 slices where the 3D column at the top left corner and the bottom left corner have all of the same values. Once you run through the code at the beginning of the post, we get what you expect.
Here's with short and sweet diff and must be quite memory efficient -
out = ~any(diff(A,[],3),3)
So, basically with diff along the third dimension diff(..[],3), you would calculate differences between the same (i,j) but on different 3D slices. Thus, if all such diff outputs are zeros, that would indicate that all dim3 elements for the same (i,j) are the same. This all zeros information is then picked up by ~any() also along dim3 with ~any(.,3) for the desired 2D array output.

Matlab: Solve Exponential Equation with two unknown parameters

I have a Matrix called A. For example the following:
A = [1 2 3; 3 4 1; 2 4 4]
Now I have the following equation:
A(x,y) = (j^x)*(i^y)
j and i are normal values (dimension 1x1), not indices of a matrix. ^
Lets make an example:
A(1,1) = 1 (First value of the Matrix)
1 = (j^1)*(i^1)
And a second one:
A(1,2) = 3
3 = (j^1)*(i^2)
Is there a possibility to receive one solution for the two parameters using Matlab?
Here is some code that can find the best solution to your problem, if there is one. In this case, there is no reasonable solution, but defining A by M([4 2]) (for example) does work reasonably well.
A = [1 2 3; 3 4 1; 2 4 4] %// the A matrix
[C,R]=meshgrid(1:3) %// create matrices of row/column indices
M=#(xy) xy(2).^C.*xy(1).^R %// calculates matrix of elements j^x*i^y
d=#(xy) A-M(xy) %// calculates difference between A and the calculated i^x*y^j matrix
r=fsolve(#(xy) norm(d(xy)),[1 1]) %// use fsolve to attempt to find a solution
d(r) %// show resulting difference between target matrix and solution matrix
norm(d(r)) %// norm of that matrix
M(r) %// show the solution matrix

How to calculate the number of occurrences of each element in the 100000 vectors using Matlab? [duplicate]

This question already has answers here:
How can I count the number of elements of a given value in a matrix?
(7 answers)
Closed 8 years ago.
For 100000 vectors containing 40 different numbers between 1 and 100, how to calculate the number of occurrences of each element in the 100000 vectors.
example:
A = [2 5 6 9]; B = [3 6 9 1]
the result should be if the numbers are between 1 and 10: [1 2 3 4 5 6 7 8 9 10, 1 1 1 0 1 2 0 0 2 0]
It seems like you want to compute the histogram of all values.
Use hist command for that
n = hist( A(:), 1:100 );
Assuming that you have a variable A that stores all of these vectors (like in Shai's assumption), another alternative to hist is to use accumarray. This should automatically figure out the right amount of bins you have without specifying them like in hist. Try:
n = accumarray(A(:), 1);
You can also use the sparse function to do the counting:
% 100000x1 vector of integers in the range [1,100]
A = randi([1 100], [100000 1]);
% 100x1 array of counts
n = full(sparse(A, 1, 1, 100, 1));
As others have shown, this should give the same result as:
n = histc(A, 1:100);
or:
n = accumarray(A, 1, [100 1]);
(note that I explicitly specify the size in the sparse and accumarray calls. That's because if for a particular vector A values didn't go all the way up to 100, then the counts array n will be shorter than 100 in length).
All three methods are in fact mentioned in the tips section of the accumarray doc page, which is the most flexible of all three.
The behavior of accumarray is similar to that of the histc function.
Both functions group data into bins.
histc groups continuous values into a 1-D range using bin edges.
accumarray groups data using n-dimensional subscripts.
histc returns the bin counts using #sum.
accumarray can apply any function to the bins.
You can mimic the behavior of histc using accumarray with val = 1.
The sparse function also has accumulation behavior similar to that of accumarray.
sparse groups data into bins using 2-D subscripts, whereas accumarray groups data into bins using n-dimensional subscripts.
sparse adds elements that have identical subscripts into the output. accumarray adds elements that have identical subscripts into
the output by default, but can optionally apply any function to the bins.