Create a cell with values from multiple cells - matlab

I have P being a 1x23 cell. In each cell of P, there is a bunch of numbers in nx1 dimension. Cells in P do not have the same row n (e.g., P{1,1} could be 16x1 and P{1,2} could be 17x1. Now, I'd like to put all the values from all the cells in P (P{1,1}, P{1,2}...P{1,23}) into cell D with the dimension of mx1. m never exceeds 1080 so I can do D=cell(1080,1) then eliminate empty cells later. Right now I am having trouble inputting all the values of P into D. Could anyone help?
Thanks.

Is this what you want?
>> P = {[1 2].', [3 4 5].'}
>> D = vertcat(P{:})
D =
1
2
3
4
5
If you really need D in cell form:
>> D = mat2cell(D,ones(1,size(D,1)),1)
D =
[1]
[2]
[3]
[4]
[5]

Related

Creating cells in Matlab

I want to create cells in matlab like the following:
Q{1,1,1}=1;
Q{1,1,2}=1;
Q{2,2,1}=1;
Q{2,1,2}=1;
However, I do not want to create this manually. In my application I have some vectors, one of which can be: x=[1 2 3 4]
And with this vector x I want to create
P{1,2,3,4}=1
So the vector x kind of dictates the coordinates of the cell (sorry for bad english).
Since I dont know the length of the vector (it can change from case to case) I cannot do this:
P{x(1,1),x(1,2),x(1,3),x(1,4)}=1;
What can I do here?
EDIT: I put the cells content with number "one" just for an example. The content of cell its gonna be linear matrix variable generated by the function sdpvar from the yalmip toolbox.
First, if you only have numeric content perhaps a matrix is better then a cell.
To populate the spaces within a cell with a certain input you could do the following:
x = [1 2 3 4];
P(x) = {1}
P =
[1] [1] [1] [1]
This also works when a index is skipped
x = [1 2 4 5]
P(x) = {1}
P =
[1] [1] [] [1] [1]
To create your Q cell you should preallocate it to get the correct size, then you could use sub2ind to point out correct indexes
Q = cell(2,2,2)
% To populate all with 1
Q(:) = {1}
Q(:,:,1) =
[1] [1]
[1] [1]
Q(:,:,2) =
[1] [1]
[1] [1]
% To populate only a certain indexes
idx = sub2ind( size(Q), [1 1 2 2], [1 1 2 1], [1 2 1 2]);
Q(idx) = {1}
Q(:,:,1) =
[1] []
[] [1]
Q(:,:,2) =
[1] []
[1] []
I am not sure you can do that without resorting to eval:
>>> x=[1,2,3,4];
>>> value=1 % or whatever you need here
>>> cmd=sprintf('%s%s%s','P{', strjoin(arrayfun(#(a) num2str(a),x,'UniformOutput',false),','), '}=value')
cmd = P{1,2,3,4}=1
>>> eval(cmd)
P = {1x2x3x4 Cell Array}
>>> P{1,2,3,4}
ans = 1
>>>

How to combine multiple row vectors into a single row vector using loop?

A= [1 2 3 4
2 3 4 5
4 5 6 7
.
....]
where each of the rows is stored in a separate vector as such
a1 = [1 2 3 4]
a2 = [2 3 4 5]
.
.
.
an = [1 2 3 4]
and I need to create new cells, using a loop, containing all previous row vectors as follows:
vectors = {a1, a2, a3, ......,an}
in the workspace I get vectors as a 1 x n cell and in each cell containing its own vector; e.g. the first cell contains vector a1, the second cell contains vector a2, etc. I don't want to copy the code every time I have a different number of vectors, so I'd like to automate this.
You'll want to not hand-copy each row into a separate variable before doing this. The proper way using your desired for loop would be thus
A = rand(15,39);
vectors = cell(1,size(A,1)); % initialise output
for ii = 1:size(A,1) % loop over all rows
vectors{1,ii} = A(ii,:); % store each row in the cell
end
To do this without a loop (thanks to #beaker)
B = mat2cell(A, ones(1,size(A,1)), size(A,2)).';
though a matrix (so your original A) would be the best overall, since MATLAB works best with matrices.

access cell array by two vector not pairwise

If I have a Cell array 2*2 where A{i,j} is a matrix, and I have two vectors v=1:2,c=1:2.
I want A(v,c) to return only A{1,1} and A{2,2} but matlab returns every combination of the two(aka also returns A{1,2} and A{2,1}).
Is there a way without using loops or cellfun ?
What I suspect you are doing is something like this:
B = A(v, c);
When you specify vectors to index into A, it finds the intersection of coordinates and gives you those elements. As such, with your indexing you are basically returning all of the elements in A.
If you want just the top left and lower right elements, use sub2ind instead. You can grab the column-major indices of those locations in your cell array, then slice into your cell array with these indices:
ind = sub2ind(size(A), v, c);
B = A(ind);
Example
Let's create a sample 2 x 2 cell array:
A = cell(2,2);
A{1,1} = ones(2);
A{1,2} = 2*ones(2);
A{2,1} = 3*ones(2);
A{2,2} = 4*ones(2);
Row 1, column 1 is a 2 x 2 matrix of all 1s. Row 1, column 2 is a 2 x 2 matrix of 2s, row 2 column 1 is a 2 x 2 matrix of all 3s and the last entry is a 2 x 2 matrix of all 4s.
With v = 1:2; c=1:2;, running the above code gives us:
>> celldisp(B)
B{1} =
1 1
1 1
B{2} =
4 4
4 4
As you can see, we picked out the top left and bottom right entries exactly.
Minor Note
If it's seriously just a cell array of 2 x 2, and you only want to pick out the top left and lower right elements, you can just do:
B = A([1 4]);
sub2ind would equivalently return 1 and 4 as the column major indices for the top left and lower right elements. This avoids the sub2ind call and still achieves what you want.

Find intersection of two cell arrays in mATLAB

I have two cell arrays C & D , they contains numerical data (but some cells are empty) . the data that is inside each cell may be a 2D array, I want to find the intersection of each cell in C with each cell in D
How can I do such thing?
for example : if the size of C & D is 10-by10
C= [ {1 2 } ,{ 3 4},.... etc]
D = [ { 1 34 7} , {2 5},... etc]
Out = c intersect D
out= [ { 1} , {},.... etc]
>> C = {1 [2 3 4; 5 6 7] [] [] 5};
>> D = {1:2 3:5 6 7:9 []};
>> R = cellfun(#(c, d) intersect(c(:), d(:)), C, D, 'uniformoutput', 0);
>> R{:}
ans =
1
ans =
3
4
5
ans =
Empty matrix: 1-by-0
ans =
Empty matrix: 0-by-1
ans =
Empty matrix: 1-by-0
If your data is only numeric (each cell contains a numeric value and empties) I suggest you to change that to a numeric array and use the intersect function. It is easy to represent missing values as NaN.
To convert to double:
tmp = {1, 2, 3, 4, 5, []};
% // Getting rid of the empties
index_empties = cellfun(#isempty, tmp);
tmp(index_empties) = {NaN};
% // converting to double
tmp_double = cellfun(#double, tmp);
Cell values are there to easily create a vector with non-homogeneous data types (Strings and numbers, for example). It is quite common see people using cells to store numbers. While this might be valid in some cases, using cells to store homogeneous data will waste memory and will complicate some operations. For example, you cannot easily sum two cell-vectors with numeric data while summing two double-vectors is trivial.

How can I insert each row of a matrix into cells in Matlab?

Suppose A = [1 2 3;4 5 6;7 8 9]
I want to convert it to B = [{[1,2,3]};{[4,5,6]};{[7,8,9]}]
How can I do that in an easy way?
You can use mat2cell function.
From the documentation:
C = mat2cell(A,dim1Dist,...,dimNDist) divides array A into smaller
arrays within cell array C. Vectors dim1Dist,...dimNDist specify how
to divide the rows, columns, and (when applicable) higher dimensions
of A.
You can do it like this:
A = [1 2 3; 4 5 6; 7 8 9];
B = mat2cell(A, [1 1 1], 3);
will give you:
B={[1 2 3];[4 5 6];[7 8 9]}
Documentation also says:
C = mat2cell(A,rowDist) divides array A into an n-by-1 cell array C,
where n == numel(rowDist).
So, if you are always going to split your matrix to rows, but not to columns, you can do it without the second parameter.
B = mat2cell(A, [1 1 1]);
A better, generalized way would be:
mat2cell(A, ones(1, size(A, 1)), size(A, 2));
You can't have a "matrix of cells" like your notation for B implied.
A cell array allows you to store "any data type" in the individual cells. You can't store a cell as a data type in an array.
So let's assume you meant to say you wanted B = {[1,2,3], [4,5,6], [7,8,9]};
If that is the case, then
B = cell(1,3);
for ii=1:3
B(ii) = {A(ii, :)};
end
should do the trick.
Note - edited based on Hadi's comment.