Storing multiple 2d matricies in one cell array - matlab

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.

Related

Avoiding a for loop in Matlab with Kronecker product

If I have two sequences A and B containing the elements a1, a2, ... and b1,b2, ... where a_i and b_i are of dimension 1xn and 1xm, respectively, then I want to make a new sequence C which contains: a_i(1)*b_i, a_i(2)*b_i, ... , a_i(n)*b_i. So for the ith element of C, I want to have the Kronecker product of the elements a_i and b_i. I want to code this in Matlab, but without a for-loop. For the case when b_i are scalars, the desired result is achieved with
C = A.*B
However, this does not work for non-scalar b_i's. So what I do now is for sequences of length L:
C = [];
for ii = 1:L
C = [C; kron(A(ii,:),B(ii,:))];
end
But I have the idea that this must be possible without a for loop. Here is my code using the symbolic toolbox:
clc; clear;
L = 5;
syms('a1',[L,1]);
syms('a2',[L,1]);
syms('b1',[L,1]);
syms('b2',[L,1]);
A = [a1,a2];
B = [b1,b2];
C1 = A.*B % only for size(B,2)=1
C2 = [];
for ii = 1:L
C2 = [C2;kron(A(ii,:),B(ii,:))];
end
C2
C3 = kron(A,B) % does not work
Here reshape and implicit expansion are used to compute the result:
C = reshape(B .* reshape (A, L, 1, []), L, []);

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.'];

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!

Matlab How to perform substraction for multiple cell arrays?

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)