How can I calculate all of the possible combinations of two 1x6 vectors in MATLAB? - matlab

I have two 1x6 vectors that I am eventually trying to just sum up, but I need to get all of the possible combinations of these vectors before doing so. The vectors will look like so:
V1=[a b c d e f];
V2=[A B C D E F];
What I need is to find all possible combinations of variables that will remain a 1x6 vector. I have been messing around for a while now and I think I have found a way by using various matrices but it seems terribly inefficient. An example of what I am looking for is as follows.
M=[a b c d e f;
A b c d e f;
A B c d e f;
A B C d e f;
A B C D e f;
A B C D E f;
A B C D E F;
. . .]
And so on and so forth until all combinations are found. Unfortunately I am not a MATLAB whiz hence the reason I'm reaching out. I'm sure there has to be a much simpler way than what I have been trying. I hope that my question was relatively clear. Any help is much appreciated! Thanks!

I used cellfun to create the indexes:
V1=['abcdef'];
V2=['ABCDEF'];
VV = [V1;V2];
l = length(V1);
pows = 0:l-1;
x = num2cell(2.^pows);
L = x{end};
rows = cellfun(#(x) reshape([ones(x,L/x);2*ones(x,L/x)],[2*L 1]),x,'Uniformoutput',0);
rows = cell2mat(rows);
cols = repmat(1:l,[2*L 1]);
idxs = sub2ind(size(VV),rows,cols);
M = VV(idxs);
and you get:
M =
abcdef
Abcdef
aBcdef
ABcdef
abCdef
AbCdef
aBCdef
ABCdef
abcDef
AbcDef
...

Related

How can I show the equality between two symbolic matrices?

I need to prove that formula with using symbolic elements : (A*B)^-1 = B^-1 * A^-1
I couldn't figure out what is the problem but matlab does not show that these two matrices are equal.
Here is my code:
syms a b c d
A = [a b ; c d];
B = [c a ; b d];
F = simplify(inv(A*B));
G = simplify(inv(B) * inv(A));
isequal(F,G)
The result is 0 as I said above. Can anyone help me?

MATLAB boxplot of high dimensional vectors with different lengths

I have been looking for a way to use boxplot for different length vectors. thanx for stackoverflow helpers, they give this solution:
A = randn(10, 1); B = randn(12, 1); C = randn(4, 1);
g = [repmat(1, [10, 1]) ; repmat(2, [12, 1]); repmat(3, [4, 1])];
figure; boxplot([A; B; C], g);
unfortunately, my data contains over 100 vectors with different lengths, I wonder if it can be done without repeating the repmat for over 100 times.
As long as your vectors have different lengths, store it in a cell array.
There are plenty was of doing it, here are 3 examples
1) "Naive" for loop
g = [];
vars_cell = {A, B, C, ....};
for it = 1 : length(vars_cell)
g = [g; repmat(it,size(vars_cell{it}))];
end
This way of doing it works but is very slow with big quantites of vectors or big vectors! It comes from the fact that you are re-defining g at each iteration, changing its size each time.
2) Not-naive for loop
vars_cell = {A, B, C, ....};
%find the sum of the length of all the vectors
total_l = sum(cellfun(#(x) length(x),vars_cell));
g = zeros(total_l,1);
acc = 1;
for it = 1 : length(vars_cell)
l = size(vars_cell{it});
g(acc:acc+l-1) = repmat(it,l);
acc = acc+l;
end
This method will be much faster than the 1st one because it defines g only once
3) The "one-liner"
vars_cell = {A, B, C, ....};
g = cell2mat(arrayfun(#(it) repmat(it, size(vars_cell{it})),1:length(vars_cell),'UniformOutput',0)');
This is qute equivalent to the 2nd solution, but if you like one line answers this is what you are looking for!

Changing the size of a matrix in MATLAB

I am given the following matrices A of size 3x1 and B of size 5x1
A = B=
1 A
2 B
3 C
D
E
I want to convert matrix C in a 15x2 matrix
C =
1 A
1 B
1 C
1 D
1 E
2 A
.
.
.
3 E
How can I make it?
Can be done with repmat
D = repmat(A',size(B,1),1);
C = [D(:),repmat(B,size(A,1),1)]
Here's a different alternative based on code for generating truth tables from Generate All Possible combinations of a Matrix in Matlab
ind = dec2base(0:power(5,2)-1,5)-47;
C = [A(ind(1:15,1) + 48, B(ind(1:15,2)];
And if you want to generalize it
m = max(size(A,1),size(B,1));
n = size(A,1)*size(B,1);
col = 2;
ind = dec2base(0:power(n,col)-1,n)-47;
ind = ind(1:n,:);
C = [A(ind(:,1) + 48, B(ind(:,2)];
The + 48 is just to convert your A matrix from a numerical matrix to a char matrix so that C can hold both number and letters. You can leave it out if A was already a char matrix.
What's useful about this technique is that by changing col, this generalizes to combing more than just 2 vectors in a similar fashion

How to vectorize vector-matrix element-by-element operation?

I have the following code:
A = rand(N1,N2);
b = rand(1,N1);
B = zeros(N1,N2);
for i=1:N1
for j=1:N2
B(i,j) = A(i,j)*b(i);
end
end
The question is how to write it in vector operation form? Something like B(:,:) = A(:,:).*b(:).
Simple use for bsxfun:
B = bsxfun(#times, A, b')
You can also try:
B = A*.(repmat(b,N2,1))';
Here, firstly you produce N2 repeated version of vector b and multiply it with A in an elementwise manner

How to add a matrix( not the same dimension) below another matrix

I know how to add a matrix below another matrix.
e.g A = [A; B];
I have two matrixes of different dimensions(both different number of columns and rows) and i need to add them up together. One matrix is the main one and the other one is being added to it. Both of them are in a for loop and so the dimension of the first matrix is keep changing.
e.g for i = 1 :3
AngerHist = [AngerHist;Hist];
end
When I run it is giving me this error :
??? Error using ==> vertcat CAT arguments dimensions are not consistent. –
How do i do it? Any suggestions?
AngerHist = {}; DisgustHist = {};FearHist = {}; HappyHist = {}; SadHist = {};SurpriseHist = {};
Images = 'C:\Users\HP\Documents\MATLAB\Images';
List = dir(Images);
n= size(List,1);
for i = 3:n
List1 = dir(fullfile(Images,List(i).name));
m= size(List1,1);
BASE_DIR = fullfile(Images,List(i).name);
for j = 3: m
I=List1(j).name;
I1= imread(fullfile(BASE_DIR,I),'jpg');
Name = List(i).name;
switch (Name)
case 'Anger'
Hist = UniformLBP(I1);
AngerHist = {AngerHist;Hist};
break;
case 'Disgust'
Hist = UniformLBP(I1);
DisgustHist = {DisgustHist;Hist};
break;
case 'Fear'
Hist = UniformLBP(I1);
FearHist = {FearHist;Hist};
break;
case 'Happy'
Hist = UniformLBP(I1);
HappyHist = {HappyHist;Hist};
break;
case 'Sad'
Hist = UniformLBP(I1);
SadHist = {SadHist;Hist};
break;
case 'Surprise'
Hist = UniformLBP(I1);
SurpriseHist = {SurpriseHist;Hist};
break;
end
end
end
I think that you need to use cells:
A={};
A=[A;rand(2,3)];
A=[A;rand(3,4)];
A=[A;rand(4,5)];
A=[A;rand(6,5)];
The result is:
A =
[2x3 double]
[3x4 double]
[4x5 double]
[6x5 double]
To vertically stack two matrices, they must have the same number of columns. For instance:
A = rand(3,2);
for ctr = 1:3
B = rand(4,2);
A = [A ; B];
end
At the end, A will be 15x2. Similarly, if the matrices have the same number of rows, you can horizontally stack them.
If the matrices have different numbers of rows and columns, then it does not make sense to use a matrix to represent their collection. You might consider making each matrix an entry in a cell array instead. See the documentation for more information.
The problem is not that the matrix size is changing inside the loop. That is allowed. The problem is that to vertically stack two matrices, they each need to have the same number of columns.
Imagine having two matrices:
A = [ a b c ;
d e f ;
g h i ]
B = [ q r;
s t ]
and you try to perform:
C = [A;B]
what dimensions would C have? It's undefined.
You could pad B with a column of zeros (or something) to make it the right width so C would end up looking like:
| a b c |
| d e f |
| g h i |
| q r 0 |
| s t 0 |
or
| a b c |
| d e f |
| g h i |
| 0 q r |
| 0 s t |
but that is just a hack to make the matrix stacking operation work.
If the matrices are always different widths you should think about what you're actually trying to do with them and perhaps consider storing them inside a cell array.