Delete vectors from cell array elements in MATLAB - 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.

Related

MATLAB cell array and array - error

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.

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);

Create a loop using part of variable name in MATLAB

I am a beginner in Matlab and have not been able to find an answer to my question so far. Your help will definitely be very much appreciated.
I have 70 matrices (100x100), named SUBJ_1, SUBJ_2 etc. I would like to create a loop so that I would calculate some metrics (i.e. max and min values) for each matrix, and save the output in a 70x2 result matrix (where each row would correspond to the consecutively named SUBJ_ matrix).
I am struggling with both stages - how to use the names of individual variables in a 'for' loop and how to properly save individual outputs in a combined array.
Many thanks and all the best!
Don't use such variable names, create a big cell array named SUBJ and put each Matrix in it.
r=zeros(numel(SUBJ),2)
for idx=1:numel(SUBJ)
r(idx,1)=min(min(SUBJ{idx}))
r(idx,2)=max(max(SUBJ{idx}))
end
min and max are called twice because first call creates maximum among rows, second call among columns.
Even though this is in principle possible in Matlab, I would not recommend it: too slow and cumbersome to implement.
You could instead use a 3-D matrix (100x100x70) SUBJ which would contain all the SUBJ_1 etc. in one matrix. This would allow you to calculate min/max etc. with just one line of code. Matlab will take care of the loops internally:
OUTPUT(:,1) = min(min(SUBJ,[],1)[],2);
OUTPUT(:,2) = max(max(SUBJ,[],1)[],2);
Like this, OUTPUT(1,1) contains min(min(SUBJ(:,:,1))) and so on...
As to how to use the names of individual variables in a 'for' loop, here gives an example:
SUBJ = [];
for idx = 1:70
term = eval(['SUBJ_',num2str(idx)]);
SUBJ = [SUBJ; max(max(term)),min(min(term))];
end

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 ^^.

How to change dimenssion of a n-d array without using reshape function in matlab?

I have an array of kxnxmxt. When i retrieve one element it is like A(i,:,:,:) and the result is 1xnxmxt array. I want it to be only nxmxt and i dont want to use reshape for efficiency reasons.
Thanks
Try this
squeeze(A(i,:,:,:))
It removes the additional dimension