Matlab How to perform substraction for multiple cell arrays? - matlab

The code below is only for 2 cell arrays, named B and C
A=cellfun(#minus, B, C, 'UniformOutput', false)
I want to perform a loop to be able to perform substraction for all my cell arrays.
Example of B{i} and C{i} are below:
B{1}=[0.435]
B{2}=[0.333] [0.532]
B{3}=[0.021] [0.432] [0.312] //command window output
C{1}=[0.211]
C{2}=[0.243] [0.116]
C{3}=[0.553] [0.212] [0.375] //command window output
B{1}-C{1}
B{2}-C{2}
B{3}-C{3}
I tried to include {i} behind A , B and C to become something like:
A{i}=cellfun(#minus, B{i}, C{i}, 'UniformOutput' , false)
However, it seems like it's not working. Is there any solution for this? Thanks

EDIT:
You have unnecessary nested cell-arrays, i.e B is a cell-array of cell-arrays, and B{i} is a cell-array of numbers.
If you want to keep that format, here is one way to compute the result using cellfun (A will also be a cell-array of cell-arrays of numbers):
% exiting data
B = cell(3,1);
B{1} = {0.435};
B{2} = {0.333, 0.532};
B{3} = {0.021, 0.432, 0.312};
C = cell(3,1);
C{1} = {0.211};
C{2} = {0.243, 0.116};
C{3} = {0.553, 0.212, 0.375};
A = cellfun(#(b,c)cellfun(#minus, b, c, 'Uniform',false), B, C, 'Uniform',false);
Otherwise I suggest you cut down on the level of nesting, and use this instead:
% note the difference between square-brackets and curly-brackets
B = cell(3,1);
B{1} = [0.435];
B{2} = [0.333, 0.532];
B{3} = [0.021, 0.432, 0.312];
C = cell(3,1);
C{1} = [0.211];
C{2} = [0.243, 0.116];
C{3} = [0.553, 0.212, 0.375];
Now you can compute the result using a single cellfun (no nesting):
A = cellfun(#minus, B, C, 'Uniform',false)

Related

Storing multiple 2d matricies in one cell array

I have multiple variables, which are 2x2 arrays. I would like to stored all these into one cell array is there a for loop that could be used for this
I do not recommend the following solutions because of the reasons summarised here: https://au.mathworks.com/help/matlab/matlab_prog/string-evaluation.html.
I'll leave it to you to decide whether it's worth using eval or avoiding it.
(1. Option) If you have A, B, and C representing your 2x2 arrays, then:
A = rand(2);
B = rand(2);
C = rand(2);
array_names = ["A", "B", "C"];
D = cell(1, numel(array_names));
for ii = 1:numel(D)
D{ii} = eval(array_names(ii));
end
Should you have more than 3 arrays, just extend array_names accordingly.
(2. Option) If you have A1, A2, and A3 representing your 2x2 arrays, then:
A1 = rand(2);
A2 = rand(2);
A3 = rand(2);
D = cell(1, 3);
for ii = 1:numel(D)
D{ii} = eval("A"+ii);
end
Should you have more than 3 arrays, just change the size of the allocated cell D accordingly.

Multipl matrix in cell

I have a matrix A=[1,2,3] and a cell B={[1,2,3],[1,2,5],[1,2,6]}.
I would like the product of the matrix elements of a similar cell
that's mean A * B ={1*[1,2,3],2*[1,2,5],3*[1,2,6]};
Without loop in matlab
Here a few ways to multiply as you described:
% inputs
A = [1,2,3];
B = {[1,2,3],[1,2,5],[1,2,6]};
using for-loop:
C1 = cell(size(B));
for i=1:numel(C1)
C1{i} = A(i) * B{i};
end
using cellfun:
C2 = cellfun(#(a,b)a*b, num2cell(A), B, 'Uniform',false);
using bsxfun:
C3 = bsxfun(#times, A(:), cat(1,B{:}));
C3 = num2cell(C3,2)';
All results should be equal (output being a cell array):
assert(isequal(C1,C2,C3))
If I were to choose, I would stick with the for-loop. In this case it's likely faster and easiest to read.

writing a matrix in a loop

I have a series of arrays of equal length, and want to make a matrix for each data point of these, and perform some sort of operation such a multiplying the matrices.
a=ones(1,10);
b=3*ones(1,10);
c=zeros(1,10);
for i=1:10
A(i)=[a(i) a(i);
b(i) b(i)];
B(i)=[c(i) c(i)];
C(i)=B(i)*A(i);
end
Is this possible without using cells?
A = zeros(2,2,length(a));
B = zeros(length(a),:);
C = zeros(size(B));
for i=1:10
A(:,:,i)=[a(i) a(i);
b(i) b(i)];
B(i,:)=[c(i) c(i)];
C(i,:)=B(i,:)*A(:,:,i);
end
Note you can make A and B without loops:
aa = permute(A, [3,2,1]);
bb = permute(B, [3,2,1]);
A = [aa,aa;bb,bb];
B = [c.', c.'];

How to convert an {Mx1} cell array of {1xN cell} arrays into a {1xN} cell array of {Mx1 cell} arrays?

Suppose that C is a cell array with shape M × 1 (i.e., size(C) returns [M 1]), and that each element of C is in turn a cell array with shape 1 × N.
I often want to convert such a cell array to a new cell array D having shape 1 × N, with elements being cell arrays with shape M × 1, and such that C{i}{j} equals D{j}{i} for all 0 < i &leq; M, and 0 < j &leq; N.
I use the following monstrosity for this
D = arrayfun(#(j) arrayfun(#(i) C{i}{j}, (1:M)', 'un', 0), 1:N, 'un', 0);
but the need for this operation arises often enough (after all, it's sort of a "cell array transpose") that I thought I'd ask:
is there a more standard way to do this operation?
Note that the desired D is different from
E = cat(2, C{:});
or, equivalently,
E = cat(1, D{:});
The E above is a two-dimensional (M × N) cell array, whereas both C and D are one-dimensional cell arrays of one-dimensional cell arrays. Of course, conversion of E back to either C or D is also another often needed operation (this sort of thing is never-ending with MATLAB), but I'll leave it for another post.
The motivation behind this question goes far beyond the problem described above. It turns out that a huge fraction of my MATLAB code, and an even larger fraction of my MATLAB programming time and effort, are devoted to this essentially unproductive chore of converting data from one format to another. Of course, format conversion is unavoidable when doing any kind of computational work, but with MATLAB I find myself doing it a lot more, or at least having to work a lot harder at it, than when I work in other systems (e.g., Mathematica or Python/NumPy). My hope is that by building up my repertoire of MATLAB "format conversion tricks" I will be able to bring down to a more reasonable level the fraction of my MATLAB programming time that I have to devote to format conversion.
P.S. The following code constructs a C like the one described above, for M = 5 and N = 2.
uc = ['A':'Z'];
randstr = #() uc(randi(26, [1 4]));
M = 5;
rng(0); % keep example reproducible
C = arrayfun(#(i) {randstr() i}, 1:M, 'un', 0)';
% C =
% {1x2 cell}
% {1x2 cell}
% {1x2 cell}
% {1x2 cell}
% {1x2 cell}
% >> cat(1, C{:});
% ans =
% 'VXDX' [1]
% 'QCHO' [2]
% 'YZEZ' [3]
% 'YMUD' [4]
% 'KXUY' [5]
%
N = 2;
D = arrayfun(#(j) arrayfun(#(i) C{i}{j}, (1:M)', 'un', 0), 1:N, 'un', 0);
% D =
% {5x1 cell} {5x1 cell}
Here's a little trick using num2cell, which actually works with cell array inputs – the key is to first expand C into a 5-by-2 cell array (equivalent to cell(5,2)).
% Your example to produce C
uc = ['A':'Z'];
randstr = #() uc(randi(26, [1 4]));
M = 5;
rng(0); % Keep example reproducible
C = arrayfun(#(i) {randstr() i}, 1:M, 'un', 0)';
% D = num2cell(reshape([C{:}],[N M]).',[1 M])
D = num2cell(reshape([C{:}],[size(C{1},2) size(C,1)]).',[1 size(C,1)])
or more simply
D = num2cell(cat(1,C{:}),1)
where D{:} returns:
ans =
'VXDX'
'QCHO'
'YZEZ'
'YMUD'
'KXUY'
ans =
[1]
[2]
[3]
[4]
[5]
The inverse operation to go from D back to C can be accomplished via:
% C = num2cell(reshape([D{:}],[N M]),[M N])
C = num2cell(reshape([D{:}],[size(D{1},1) size(D,2)]),[size(D,2) size(D{1},1)])
or
C = num2cell(cat(2,D{:}),2)
Thus you might be able to create a function like the following that would work in either direction:
transpose_cells = #(C)num2cell(cat(isrow(C)+1,C{:}),isrow(C)+1);
isequal(transpose_cells(transpose_cells(C)),C)

How can I convert a vector to a cell array?

I have a column vector I want to convert to a cell array such as:
A = rand(10,1);
B = cell(10,1);
for i=1:10
B{i} = A(i);
end
B =
[0.6221]
[0.3510]
[0.5132]
[0.4018]
[0.0760]
[0.2399]
[0.1233]
[0.1839]
[0.2400]
[0.4173]
How can I do this without an explicit for loop?
I tried:
B{:} = A(:)
and
[B{:}] = deal(A)
with no luck...
Also if possible, how can I do the same thing for a matrix, i.e. have each element in a cell by itself?
Use the function num2cell:
B = num2cell(A);
Works with matrices too.