How to compare two cell elements in matlab? - 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.

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.

Avoid looping in matlab when creating cells containing cell arrays

I'm trying to create a map that has two-element cell arrays as values. Map expects that keys and values have the same number of elements. This code packs those cell arrays into cells in a loop, but I'm suspecting that it can be simplified somehow. Example code:
cells1={'foo1';'foo2';'foo3'};
cells2={'bar1';'bar2';'bar3'};
cells3={'baz1';'baz2';'baz3'};
values=cell(size(cells1));
for ii=1:size(cells1,1)
values{ii}={{cells2{ii},cells3{ii}}};
end
keys=cells1;
containers.Map(keys,values);
you can use vector concatenation and num2cell with 2nd dimension argument (twice if you want to obtain identical result):
% your code
cells1={'foo1';'foo2';'foo3'};
cells2={'bar1';'bar2';'bar3'};
cells3={'baz1';'baz2';'baz3'};
values=cell(size(cells1));
for ii=1:size(cells1,1)
values{ii}={{cells2{ii},cells3{ii}}};
end
% simplified
c = num2cell(num2cell([cells2,cells3],2),2);
% you can also do c = num2cell([cells2,cells3],2); which isn't identical but may be suficcient
isequal(c,values) % yes

Adding 0's to cell array such that each column contains an equal number of entries - MATLAB

I have a 16x100 (varies in size) cell array and I would like to extract each of it's columns into a column of a matrix. When each column of the cell array contains an identical number of entries I can use:
elem = numel([dist{:,1}]);
repeat = size(dist,2);
data = zeros(elem,repeat);
for k=1:repeat
results(:,k) = [dist{:,k}]';
end
However there are some instances where there are not an equal number thus it returns the error:
Subscripted assignment dimension mismatch.
What is the best way around this? Is there a way to add zeroes to equalise the number of entries?
Perfect setup for bsxfun's masking capability here!
Now, I am assuming your data is setup as described in your previous question -
To solve the case of filling up "empty spaces" with zeros, you can setup an output array with maximum possible number of elements in each column and then fillup the valid spaces with the values from the input cell array, with the valid spaces being detected by the logical mask created with bsxfun. Read on through the comments inlined within the code listed next to find out the exact ideas on solving it -
%// Get the number of elements in each column of the input cell array
lens = sum(cellfun('length',a),1)
%// Store the maximum number of elements possible in any column of output array
max_lens = max(lens)
%// Setup output array, with no. of rows as max number of elements in each column
%// and no. of columns would be same as the no. of columns in input cell array
results = zeros(max_lens,numel(lens))
%// Create as mask that has ones to the "extent" of number of elements in
%// each column of the input cell array using the lengths
mask = bsxfun(#le,[1:max_lens]',lens) %//'
%// Finally, store the values from input cell array into masked positions
results(mask) = [a{:}]

using ismember for numeric values

I have a 4554 x 1 vector of type double, called company_info,ind_vec. I also have a another 25 x 1 vector which is of type cell array called groups.industy_labels.
groups.industy_labels contains a list of codes which are numeric.
company_info,ind_vec contains the same numeric codes.
I was planning on doing the below, where I use ismember to return the indices for each numeric code in groups.industy_labels and then do a sum on another vector which is realted to company_info,ind_vec, i.e. another 4554 x 1 vector.
[~, index_sub] = ismember(company_info.ind_vec, groups.industy_labels);
groups.industy_exps(:, 1) = accumarray(index_sub, pwgt , [], #sum, 0);
However Matlab is telling me that ismember only takes cell arrays of string. Is there another way of doing this?
Actually the error message is a bit deceptive as you can use ismember for numeric values:
x=[1 3]
y=[1 2]
ismember(x,y) %This will work
You can also use it for cell arrays, but only for strings:
x=[{'a'},{'c'}]
y=[{'a'},{'b'}]
ismember(x,y) %This will work
x=[{1},{3}]
y=[{1},{2}]
ismember(x,y) %This will fail
So in your case, you would want to use it on 2 numeric vectors, rather than 1 numeric vector and 1 cell array:
x=[1,2] %Numeric vector
y=[{1},{2}] %Cell array
y_numeric = [y{:}] %Made into a numeric vector
ismember(x,y_numeric) %This will work
Note that this assumes that each entry in the cell array only contains a number.

Compare length of multiple array and display error if unequal

I have multiple array of real numbers.
Eg.
a = [1:5]
b = [11:15]
c = [100:105]
d = [200:210]
I want a shorter code, if number of arrays are in 100's. What i know is,
if length(a) == length(b) && length(b) == length(c) && length(c)== length(d)
else
error ('Length of data series is unequal. Correct it.')
end
This will display an error if length if all series is not equal but how could it be done in small code when array number and size is very large (in 100's) ?
Thank you.
Code
%%// Get all the arrays/vectors into a cell array, with each element in each cell
A = [{a},{b},{c},{d}]
%%// Get the number of elements of all the cells, that is number of elements
%%// of all vectors into an array. This, this array could be thought of as an
%%// array of sizes
numels = cellfun(#numel,A)
%%// Now that we have an array of sizes, we need to make sure that
%%//all the sizes are same. So when we compare all sizes to
%%// any randomly picked one (first one in this case), must be matching,
%%// which is being covered by the command - all.
if ~all(numels==numels(1))
error ('Length of data series is unequal. Correct it.')
end