MATLAB cell array and array - error - matlab

I'd like to understand why the following code works:
close all
clear all
t=[0:0.1:10];
x=figure(1);
plot(t,t.^2)
a=getframe(gcf);
b{1}=frame2im(a);
instead the following code does not work:
close all
clear all
t=[0:0.1:10];
x=figure(1);
plot(t,t.^2)
a=getframe(gcf);
b(1)=frame2im(a);
If I use "b(1)=x;" it works.
Thank you very much.

In an array, you can store only one 1x1 value of any class at a single index but the class of all elements of an array must be same. In a cell array, there is no such restriction.
frame2im(a) is [525x700x3 uint8] and hence you can store it in a cell and not in a simple array if you want to store it at a single index.
b(1)=x; works because x is 1x1 matlab.ui.Figure. You can also store x in a cell array.

To my understanding, you need to know what cells are meant for in MATLAB. If you happen to know Python, you probably will think in a "list"-type way. MATLAB cell can store numbers, strings, etc. However its array is meant to store numbers.
That's why your structure from fram2im can't work.

Related

Converting cells within cells to single cells

I have a 1X100 cell which contains exclusivly 1X24 cells. I need to extract these 100 cells and join them together to form a 100X24 cell, how can this be done?
I have been playing around with the 'cellfun' function and also using for loops to try an perform the operations required but without success. I understand I could just join these cells one by one but would prefer a more efficient approach. Any help would be appreciated.
The cell is generated from raw data using the following:
for i = 1:100
band{i} = prctile(e-data,i);
end
where e_data is a 62X24 double
The second input to prctile can be an array of percentages so your code can be replaced with
band = prctile(e - data, 1:100).';
This will create a 100 x 24 numeric array which is going to be more performant than a cell array.
In general though, if you need to concatenate the contents of multiple cells together, you can use {:} indexing to yield a comma separated list which can then be passed to cat
result = cat(1, band{:});
If I understood your purpose correctly, you need to use iscell() and retrieve what you want subsequently:
R=cellfun(#iscell, YourCell);
Demanded_Cell=YourCell(R);

How to access array/cell element in a uniform way

In MATLAB, the i-th element of an array is accessed by a(i), while the i-th element of a cell is accessed by a{i}. So my code has to do different things in terms of whether a is a cell or not.
Is there a better way to do it? so we can access the i-th element in a 'same'? way.
You can access the ith element of any array in the same way, a(i), and the behaviour is completely uniform: you get back an object of the same class as a. So if a is a 5x5 double array, a(i) is a 1x1 double. Similarly, if a is a cell array, then a(i) is a 1x1 cell. So far, so logical and consistent.
Now, if you want to look inside a cell, you use a{i} but that is a fundamentally different operation. Your question seems to imply that it would be "better" if these two fundamentally different operations had the same syntax. It wouldn't: if this were the case, then the ability to slice a cell array into arbitrary shapes (including 1x1) would be overshadowed.
But you can always write a custom function. Among the many Matlab workarounds I carry with me everywhere, I have the following pair of functions:
function a = ascell(a)
if ~iscell(a), a = {a}; end
and
function a = uncell(a)
if iscell(a) & numel(a) == 1, a = a{1}; end
With uncell.m on your path, b = uncell(a(i)); would give you the ith element of a with the cell wrapping, if any, stripped off.
It is good to have the call to uncell visible in the code because it alerts you (or another maintainer) to the possibility that a might legally be a cell or a non-cell—this is by no means necessarily true in everybody's coding strategy. Nor will my code necessarily follow the same convention as yours when it comes to interpreting the meaning and correct treatment of a cell array where a non-cell was expected, or a non-cell where a cell was expected (and this is another way of explaining why there's no common syntax). This leads me to the question: if the design of your application is such that a can by its nature contain elements with mismatched shapes or types, then why not simply decree that it is always a cell, never a non-cell, and always access the ith element as a{i}?

"some_variable = []" type of statement in matlab

Hello and thanks for the help,
I have seen that you can make this statement:
some_variable = []
from what I see, this makes like a void variable for later use.
The thing is I want to make it an array (and that is the problem). I made this
some_variable(:) = []
but there is an error:
In an assignment A(:) = B, the number of elements in A and B must be the same
Thanks
Actually everything in MATLAB is an array, sometimes the arrays are just 1x1, but they are arrays nevertheless (unlike in C/C++ where you have int or int*).
So, when you do var=[] you initialize an empty array, an array of size 0*.
After that, its up to you to initialize it with whatever size you want. var=0 will initialize it as an array of 1x1 size, but you can go bigger, using zeros(size).
Adittionally, if you want to create empty variables of another class, just use <classname>.empty, such as in var=uint32.empty;
*Note that in MATLAB, an array is also infinite dimensional. It's not size 0, its 0x0x0x0x0x.....x0x0. If you want to prove this, try size(var,999999999999) in MATLAB.

Delete vectors from cell array elements in MATLAB

I have a cell array containing double arrays like:
x = {[4,1] [4,3] [1,1] [2,3] [2,1]};
I would like to check if [1,1] is contained in the cell array and if so, delete it. I get it done like this:
x(find(cellfun(#all,cellfun(#(x)x==[1,1],x(:),'UniformOutput', false))==1)) = []
Seems overy complicated though, any suggestions for simplification? thanks in advance!
Without using cellfun, one can use ismember to detect the matching rows and remove them -
x(ismember(vertcat(x{:}),[1 1],'rows'))=[]
Basically the same code you used, but removing everything unnecessary. You don't need to apply cellfun twice to apply two nested functions. Pass the nested function instead.
x(cellfun(#(x)all(x==[1,1]),x)=[]
Besides this, take a look at "logical indexing", you don't need find in such cases.

Matlab: Matrix of ClassificationKNN class objects

For classification I'm building a number of models for a classifier in MATLAB. I use the class ClassificationKNN for this.
I would very much like to store multiple models (or objects of this class) inside a matrix.
Normally you could access and create matrices inside a matrix with the curly braces ({}).
My loop looks like this:
models = []
for i = 1:length(x)
models = [models, {ClassificationKNN.fit(x,y)}]
end
Unfortunately this returns a matrix models of size (1,3) but all cells are empty which means the models are lost...
How can I make sure every model is stored in a matrix? I need to do this because I need all models later in my calculations and the position in the matrix is important...
Any ideas?
You want a cell array of models, right? It sure looks that way, if that will work try this:
models = {}
for ii = 1:length(x)
models = [models, {ClassificationKNN.fit(x,y)}]
end
Also, you loop through calling ClassificationKNN.fit(x,y) with the same arguments every time, is this just a test, or pseudo-code for an example. Like the comment says, it's best to preallocate like:
models = cell(length(x),1);
for ii = 1:length(x)
models{ii} = ClassificationKNN.fit(x,y);
end
But, either way is likely fine.
Thanks to macduffs post I finally figured out what was going on. Whilest reading his proposition I realised that that indeed should be the correct way if getting a cell array of objects.
After trying it, the array again seemed empty when opening it in the variable editor. I tried calling the first cell in the array to see if it was indeed empty and it was not. It returned the object I had stored in it. This means the question was answered.
I then reverted back to my own method to see if that worked as well and it did. When calling a cell it also returned an object.
Bottom line:
Do not trust the variable editor ^^.