convert 3d cell array in 2d cell array - matlab

I transformed a structure S (with 13 fields and 96 rows, some fields are made of numbers, others of strings) into a cell array:
myCell= struct2cell(S);
So, I obtained a 3d cell array myCell 13x1x96, and I would like to transform it in a 2d cell array 96x13. Any suggestion is welcome!

A more general solution than what was suggested would employ the permute function:
B = permute(A,order) rearranges the dimensions of A so that they are in the order specified by the vector order.
...
permute and ipermute are a generalization of transpose (.') for multidimensional arrays.
In your case, running the command new_Cell = permute(myCell,[3,1,2]) would make the 13x1x96 96x13. As you can see, permute removes trailing singleton dimensions (resembling squeeze).
(Tested on MATLAB 2015b)

Related

Manipulate values in Matlab cell array

Suppose I have a 3x1 cell array called subj that has the following elements:
cell 1: 300x20 double
cell 2: 300x15 double
cell 3: 300X18 double
I want to remove the last quarter rows from every element in each cell as follows:
subj{1}(length(subj{1})*0.25+1:end,:) = []
subj{2}(length(subj{2})*0.25+1:end,:) = []
subj{3}(length(subj{3})*0.25+1:end,:) = []
However I want to be do this in one line and can't figure out a way to do this in Matlab. I messed around with converting the cell array to a matrix, but since there different numbers of columns, it makes it slightly more complicated. Is there a vectorized way to do this in one line? I will be applying machine learning algorithms to each element of subj and it would be great to have this be vectorized for later parts of my code.
Better not assigning empty arrays to a matrix (actually that doesn't work) but reassign the matrix itself:
% loop over the cell array
for i = 1:length(subj)
% determine the index/number of rows. Don't forget to round as MATLAB requires integers for slicing!
idx = round( length(subj{i})*0.25 );
% get the new matrix
NewMat = subj{i}(1:idx,:);
% assign new matrix to the old address, i.e. the content of the cell
subj{i} = NewMat;
end
MATLAB allocates contiguous memory for matrices, so cropping it shouldn't cause much overhead. In particular not as it uses "lazy copying" and; therefore, only copies the matrix when you change any of its values.

How to sum up values in corresponding indexes of cells?

I have a 1x24 cell array called chaining, whose each cell contains a 119x119 matrix:
I want to find the sum of each corresponding elements of all the cells, and store them in a matrix called result. That is, the (j,k)th element of result should contains the sum of the (j,k)th elements of all the matrices in the cell array chaining.
The code I wrote to do this is:
for j=1:size(chaining,2)
for k=1:size(chaining,2)
result(j,k) = sum(chaining{1,:}(j,k));
end
end
But this gives error because apparently MATLAB can't aggregate cell arrays for some reason (i.e., the chaining{1,:} part).
Could anyone please show me how to go about doing this?
how about
result = sum( cat(3, chaining{:}), 3 );
What just happened here?
First, we convert the cell array into a 3D array by "stacking" the 2D cell elements on the third dimension:
cat(3, chaining{:})
Once we have a 3D array of size 119-by-119-by-24 we can sum along the third dimension and get result of size 119-by-119:
sum( ..., 3 );
For more info see cat and sum help pages.
BTW,
If you insist on chaining{1,:}(jj,kk) type of solution (not recommended), you might find subsref command useful.

How to compare two cell elements in matlab?

I am using two cells for storing the targeted and the expected value of a neural network process in matlab. I have used two 1*1 cell array for storing the values respectively. And here is my code.
cinfo=cell(1,2)
cinfo(1,1)=iter(1,10)%value is retrieved from a dataset iter
cinfo(1,2)=iter(1,11)
amp1=cinfo(1,1);
amp2=cinfo(1,2);
if amp1 == amp2
message=sprintf('NOT DETECTED BY THE DISEASE');
uiwait(msgbox(message));
But when i run the above code, the get the following error :
??? Undefined function or method 'eq' for input arguments of type 'cell'.
Error in ==> comparison at line 38
if amp1 == amp2
How to solve this problem?
The problem is how you indexed things. A 1x1 cell array does not make a lot of sense, instead get the actual element in the single cell, by indexing with curly brackets:
amp1=cinfo{1,1}; # get the actual element from the cell array, and not just a
amp2=cinfo{1,2}; # 1x1 cell array by indexing with {}
if (amp1 == amp2)
## etc...
However, note that if amp1 and amp2 are not scalars the above will act weird. Instead, do
if (all (amp1 == amp2))
## etc...
Use isequal. That will work even if the cell's contents have different sizes.
Example:
cinfo=cell(1,2);
cinfo(1,1) = {1:10}; %// store vector of 10 numbers in cell 1
cinfo(1,2) = {1:20}; %// store vector of 20 numbers in cell 2
amp1 = cinfo(1,1); %// single cell containing a length-10 numeric vector
amp2 = cinfo(1,2); %// single cell containing a length-20 numeric vector
if isequal(amp1,amp2)
%// ...
In this example, which parallels your code, amp1 and amp2 are cell arrays consisting of a single cell which contains a numeric vector. Another possibility is to directly store each cell's contents into amp1, amp2, and then compare them:
amp1 = cinfo{1,1}; %// length-10 numeric vector
amp2 = cinfo{1,2}; %// length-20 numeric vector
if isequal(amp1,amp2)
%// ...
Note that even in this case, the comparisons amp1==amp1 or all(amp1==amp2) would give an error, because the vectors have different sizes.

Create an 2-D empty array in Matlab

I would like to use union in Matlab to merge a series of 1-by-2 arrays for example [1,2] to an empty 2-D array U, i.e., U = union(U,[1,2],'rows'); But I'm confused how to initialize U, because U=[] didn't work, no luck with U=[[],[]] either. I tried U = [U,[1,2]], it works only when the 1-by-2 arrays in the series are all unique, or I would have duplicate entries in U.
So you want to get all the unique 1x2 arrays in a 2-D matrix? First, create a big 2-D array of all 1x2 arrays (including duplicates), then call unique.
C = unique(A,'rows')
As for using union, there is no way to have a empty 1x2 array. What you can do instead is initialize U to be the same as your first 1x2 array. Then loop over all the other 1x2 arrays and use union to build your output.
U = union(U, [1,2], 'rows')

How to do intersection of arrays of unknown size which are stored in cells of a matrix?

I have a matrix of cells, call it M. The matrix dimensions are n^3.
Each cell contains an array of indices (a result of a regexp query on some string, not that it matters).
I want to intersect the indices in the arrays in each cell of M.
How can I do that? If I use intersection function how does it know to take the indices from inside the arrays in each cell?
As I understand I have to use cells because the inner arrays are of unknown size.
Is this what you want to do?
A = M{1};
for i = 2:numel(M)
A = intersect(A, M{i});
end
I don't think there's a neat way to do this using a single intersect call, or with e.g. cellfun.
If you only want the intersection of specific indices, you can do:
A = indices(1);
for i = indices(2:end)
A = intersect(A, M{i});
end