Inserting elements of a cell array into another cell array - matlab

How to insert elements of a cell array into another cell array without a for loop?
The elements of the cell A are all integers.
Input:
A = [1x2 double] [1x2 double]
[1x2 double] [1x2 double]
[1x2 double] [1x2 double]
[1x2 double] [1x2 double]
[1x2 double] [1x2 double]
[1x2 double] [1x2 double]
A{1}=[2 5]
A{2}=[6 8]
B=[8] [7]
[7] [0]
[4] [3]
[7] [0]
[2] [1]
[1] [2]
C=cell(6,2);
Output:
C{1}=[A{1} B{1}];
C{2}=[A{2} B{2}];

Some classic use of cellfun maybe
C=cellfun(#horzcat, A, B, 'uni', 0)

Is that possible:
B = reshape(B, [], 1);
C = [A(:) B(1:length(A))];

Related

cellarray of matrix multiplication vectorization

I have A and B a cell array of matrices inside. I want to obtain C
A =
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
B =
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
K = magic(18);
In for loop:
C = cell(8,1);
for ii = 1:8
C{ii} = K*A{ii}'*B{ii};
end
How can I do this in a vectorized form (cell)?
Although it's possible,
K = repmat({K}, 8,1);
C = spblkdiag(K{:}) * spblkdiag(A{:}).' * spblkdiag(B{:});
C = reshape(nonzeros(C), 18,[]);
C = mat2cell(C, 18,18 * ones(8,1))';
I'd still suggest you use a loop.

Indexing Cell arrays for more efficient performance

I have the following code to display a 9-by-3 cell array:
data = cell (9,3);
col1 = [2, 3, 5, 7, 8, 11, 12, 15, 16];
col2 = {[1 1], [1 5], [3 9], [4 2], [4 6], [6 2], [7 6], [6 9], [9 9]};
col3 = {[2 3 4 5 8],[1 3 5 8],[1 2 5 7 8],[1 2 3 6 7],[3 4 7 8],[2 4 8 9],[2 4 5 9],[4 5 7 9],[2 6 7 8]};
k = length(data);
for i = 1:k
data{i,1} = col1(i);
data{i,2} = col2{i};
data{i,3} = col3{i};
end
data
Please, can this code be more efficiently written using a form of indexing? Thanks.
Your have written code to assign a 9 x 3 cell array, which can also be written as:
data2 = [num2cell(col1') col2' col3']
data2 =
[ 2] [1x2 double] [1x5 double]
[ 3] [1x2 double] [1x4 double]
[ 5] [1x2 double] [1x5 double]
[ 7] [1x2 double] [1x5 double]
[ 8] [1x2 double] [1x4 double]
[11] [1x2 double] [1x4 double]
[12] [1x2 double] [1x4 double]
[15] [1x2 double] [1x4 double]
[16] [1x2 double] [1x4 double]

matrix operation where the values can be expressed as a set

Is it possible to obtain a matrix as follows??
The input vectors are X(column vector) and Y(row vector)
X=[2 Y=[5 3 1 2 4]-1*5 vector
4
5
3
1]-5*1 vector
both vectors have the index values as elements. Now I want to have a 5*5 matrix which is as follows:
Z= (2,5) (2,3) (2,1) (2,2) (2,4)
(4,5) (4,3) (4,1) (4,2) (4,4)
(5,5) (5,3) (5,1) (5,2) (5,4)
(3,5) (3,3) (3,1) (3,2) (3,4)
(1,5) (1,3) (1,1) (1,2) (1,4)
Z-5*5 matrix
is it possible to obtain a matrix like this using matlab...pls help....i have no idea how to do this....thanks in advance...
Here's an alternative solution using a cell array instead of a regular array:
XX=meshgrid(X);
YY=meshgrid(Y);
C=reshape(num2cell([XX(:) YY(:)],2),numel(X),[]);
The outcome will be a 5x5 cell array,
C =
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
each element will contain the 2 numbers. For example:
C{2,2}
ans =
4 3
Maybe this is what you want:
Z = cat(3, repmat(X, 1, size(Y,2)), repmat(Y, size(X,1), 1));
This builds a 3D-array Z such that Z(m,n,:) gives the m,n entry of your "matrix".
However, depending on what you want to achieve, there are probably better ways to do it.

All possible Intersections of cells in cell array : MATLAB.

Consider a cell array ,
H = [ {N1x1} {N2x1} {N3x1} ...{Nmx1} ]
How does get (efficiently) all pairwise intersections of these cells?
Not sure how efficient this will be.
N = numel(H);
[ii jj] = ndgrid(1:N);
result = arrayfun(#(n) intersect(H{ii(n)},H{jj(n)}), 1:N^2, 'uni', 0);
result = reshape(result,N,N);
Example:
H = {[1 2 3], [2 3], [4 5]};
gives
result =
[1x3 double] [1x2 double] [1x0 double]
[1x2 double] [1x2 double] [1x0 double]
[1x0 double] [1x0 double] [1x2 double]
>> result{1,1}
ans =
1 2 3
>> result{1,2}
ans =
2 3
>> result{1,3}
ans =
Empty matrix: 1-by-0
[..]
This also works if H is a multidimensional cell array.
You could also use two for loops. Then you could save half operations explotiing the symmetry of the result.

select entries and put in a matrix without loop

I have the following:
b = [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double]
whose dimensions are variable.
b{1}
ans =
0 0 0 0
I want to put the first entry of each of the 10 vectors as the first column of matrix A
2nd column of matrix A will be as v the 1st entry of each of the 10 vectors of r:
r =
[1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double] [1x4 double]
r{1} --> ans = 10 10 10 10
This is what i need to get:
A =
v{1}(1) r{1}(1)
v{2}(1) r{2}(1)
v{3}(1) r{3}(1)
How to do that without a loop is there a way?
Some example data:
b = {[ 101:104 ], [ 201:204 ], [ 301:304 ], [ 401:404 ], [ 501:504 ], [ 601:604 ], [ 701:704 ], [ 801:804 ], [ 901:904 ], [ 1001:1004 ]};
r = {[ 2101:2104 ], [ 2201:2204 ], [ 2301:2304 ], [ 2401:2404 ], [ 2501:2504 ], [ 2601:2604 ], [ 2701:2704 ], [ 2801:2804 ], [ 2901:2904 ], [ 3001:3004 ]};
Edit: a lot faster solution without looping by using vertcat.
Edit: corrected a typo in code.
bMatrix = vertcat(b{:});
rMatrix = vertcat(r{:});
A = [ bMatrix(:,1), rMatrix(:,1) ];
A lot slower solution by using cellfun (cellfun does loop) :
A = [ cellfun(#(x) x(1), b)', cellfun(#(x) x(1), r)' ];
Or in parts:
ColumnOneOfMatrixA = cellfun(#(x) x(1), b)';
ColumnTwoOfMatrixA = cellfun(#(x) x(1), r)';
A = [ ColumnOneOfMatrixA, ColumnTwoOfMatrixA ];
Both ways give the same result.
A =
101 2101
201 2201
301 2301
401 2401
501 2501
601 2601
701 2701
801 2801
901 2901
1001 3001
As Dan notes, cellfun is the trick to avoiding this loop.
%Setup test data
for ix = 1:10
b{ix} = ones(1,4)*(ix-1);
r{ix} = ones(1,4)*(ix+9);
end
%Cellfun based definition of the "A" matrix
A = [...
cellfun( #(x)x(1), b(1:10) ); ...
cellfun( #(x)x(1), r(1:10) ); ...
]';
Here the cellfun calls have been set up to return a numeric array containikng the first element of each numeric array in the cell array. The anonymous function #(x)x(1) serves as the core, just returning the first element, and cellfun takes care of implementing the appropriate looping without bothering you with the details.
Note that cellfun is usually not any faster than the loop that it replaces. It simply requires less typing, and is arguably easier to read after you learn to work with it.