How to concatenate matrices horizontally? - matlab

I have two 3-by-3 matrices:
A= [ 1 2 3
1 1 1
0 1 1]
B= [ 1 2 1
1 1 1
2 2 2]
How do I concatenate the A and B matrices to create the concat matrix as seen below?
concat= [1 2 3 1 2 1
1 1 1 1 1 1
0 1 1 2 2 2]

Simply do:
concat = [A B];
This will make a new matrix that pieces A and B together horizontally (i.e. concatenates).
Another possibility is to use cat where you specify the second dimension (column-wise) to concatenate the two matrices together.
concat = cat(2, A, B);
Alternatively you can use horzcat as alluded by a few people here. This essentially is syntactic sugar for cat in the second dimension.
concat = horzcat(A, B);

There are a few possibilities here. The easiest, and most common one:
concat = [A, B]
The following is considered more robust by some, (because one might, on accident, do concat = [A; B], which would concatenate them vertically):
concat = horzcat(A, B)

Related

generate Combinations from a value in matlab

How to generate the different combinations possible for a certain number
Example:
m=2 gives:
[1 1;1 2;2 1;2 2]
m=3 gives:
[1 1;1 2;1 3;2 1;2 2;2 3;3 1;3 2;3 3]
and so on...
using perms([1 2]) generates [1 2;2 1] only
You can use ndgrid:
m = 3;
[A,B] = ndgrid(1:m);
Here A and B look like this:
A =
1 1 1
2 2 2
3 3 3
B =
1 2 3
1 2 3
1 2 3
So you can concatenate them vertically to get the combinations. Using the colon operator transforms the matrices into column-vectors, i.e. listing all the elements column-wise. Therefore, you could use either
P = sortrows([A(:), B(:)])
or
P = [B(:) A(:)] %// Thanks #knedlsepp :)
to get sorted combinations.
P now looks like this:
P =
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
Note that your question is highly related to the following, where the goal is to find combinations from 2 vectors.: How to generate all pairs from two vectors in MATLAB using vectorised code?. I suggest you look at it as well to get more ideas.
That being said the question might be a duplicate...anyhow hope that helps.
It's a little tricky, as nchoosek can not be used straight out of the box:
n = 3;
X = nchoosek([1:n, n:-1:1],2);
Y = unique(X,'rows','legacy');
respectively in one line:
Y = unique(nchoosek([1:n, n:-1:1],2),'rows','legacy');

matlab indexing with multiple condition

I can't figure out how to create a vector based on condition on more than one other vectors. I have three vectors and I need values of one vector if values on other vectors comply to condition.
As an example below I would like to choose values from vector a if values on vector b==2 and values on vector c==0 obviously I expect [2 4]
a = [1 2 3 4 5 6 7 8 9 10];
b = [1 2 1 2 1 2 1 2 1 2];
c = [0 0 0 0 0 1 1 1 1 1]
I thought something like:
d = a(b==2) & a(c==0)
but I have d = 1 1 1 1 1 not sure why.
It seems to be basic problem but I can find solution for it.
In your case you can consider using a(b==2 & c==0)
Use ismember to find the matching indices along the rows after concatenating b and c and then index to a.
Code
a(ismember([b;c]',[2 0],'rows'))
Output
ans =
2
4
You may use bsxfun too for the same result -
a(all(bsxfun(#eq,[b;c],[2 0]'),1))
Or you may just tweak your method to get the correct result -
a(b==2 & c==0)

Using find function

Consider the following arrays:
A = [1 3 4 5 6 7 1 3 7];
B = [1 4 7];
I want to find all elements of B in array A. So, my final output array will look something like:
C = [1 7 3 6 9];
First element of B is at locations 1 and 7 in array A, so C has 1 and 7 as first two elements. Element 4 of B is at location 3, so array C has 3 as its third element and so on.
The order of C is required?
Fast, but another order:
find(ismember(A,B))
Slower, but the order you want:
cell2mat(arrayfun(#(x)(find(A==x)),B,'UniformOutput',false))
Basically, the second solution iterates over all elements of B and applies find(A==x) in a loop.
You may also delete the cell2mat, then a cell is returned. First element -> Occurrences of 1, second element-> occurrences of 4 etc.
If you need the result in that order: you can use the two outputs of ismember. This may be faster than Daniel's answer (second part) as it avoids arrayfun:
[tf, loc] = ismember(A,B);
loc = loc(tf);
ind = find(tf);
[~, order] = sort(loc);
C = ind(order);
Second output of ismember will give a map for each element of B
>> [~,ic] = ismember(A,B)
ic =
1 0 2 0 0 3 1 0 3
Then element-wise test against each element of B:
>> [C,~] = find(bsxfun(#eq,ic.',1:numel(B)))
C =
1
7
3
6
9
And because I'm require to do so, an alternative method following ismember:
c = accumarray(nonzeros(ic),find(ic),[],#(x) {sort(x)});
C = vertcat(c{:})

cumsum only within groups?

Lets say I have 2 vectors:
a=[0 1 0 1 1 0 1 0 0 0 1 1 1];
b=[1 1 1 1 1 1 2 2 2 3 3 3 3];
For every group of numbers in b I want to cumsum, so that the result should look like that:
c=[1 3;2 1;3 3]
That means that I have for the ones in b 3 ones in a, for group two in b I have only one one in a etc.
There have been some complicated answers so far. Try accumarray(b',a').
If you're looking for a solution where b can be anything, then a combination of hist and unique will help:
num = unique(b(logical(a))); %# identify the numbers in b with non-zero counts
cts = hist(b(logical(a)),num); %# count
c = [num(:),cts(:)]; %# combine.
If you want the first column of c to go from 1 to the maximum of b, then you can rewrite the first line as num=1:max(b), and you'll also get rows in c where the counts are zero.
Assuming that b is monotonically increasing by 1:
c = cell2mat(transpose(arrayfun( #(x) [ x sum(a(find( b == x ))) ], min(b):max(b), 'UniformOutput',false)))
should give the right answer in a one liner format, or:
for ii=min(b):max(b)
II = find( b == ii );
v = sum(a(II));
c(ii,:) = [ii v];
end
which is a bit easier to read. Hope this helps.

What are the differences between these array definitions in MATLAB?

I am trying to understand the differences between these array definitions:
abc=[ 0 0 0 0 0 0]
and
abc=[0;0;0;0;0;0]
In C, first definition is
int abc[]={0,0,0,0,0,0};
second definition is
int [6][1]= {{0},{0},{0},{0},{0},{0}};
Am I correct about that?
abc = [1 2 3 4]
Is a "row vector".
abc = [1 2; 3 4]
Is a 2x2 matrix, because semicolons inside brackets separate rows.
abc = [1; 2; 3; 4]
Is a 4x1 matrix, aka "column vector". It's a special case of a matrix, really. You can also get it by transposing the corresponding row vector:
abc = [1 2 3 4]'
(note the quote at the end - this is the transpose)
P.S.: Yes, your interpretation to C is correct in this case.