Matlab arrayfun with array of elements that are [1x4 struct] - arrays

I have a array, 'MY_STRUCTURES_Array', with single row and N columns. Each element is a [1x4 struct]. I want to extract a numeric valued 'thisField' from each structure of each [1x4 struct] element.
The result I am looking for is a 4xN array of the values for each 'thisField' value, where each row in this result corresponds to a colum in the [1x4 struct].
The code I am using is this:
arrayfun(#(x) (x.thisField), MY_STRUCTURES_Array);
Matlab returns the error
Attempt to reference field of non-structure array.
If I put the following in the command line,
MY_STRUCTURES_Array{1}
I get a list of all of the fields of the [1x4 struct].
If I put this in the command line,
MY_STRUCTURES_Array{1}.thisField
I get four answers, like this:
ans =
1
ans =
1
ans =
1
ans =
0
If I look at the size
size(MY_STRUCTURES_Array{1}.thisField)
Matlab says "Error using size", so I see this is not an array. But I'm not sure what it is.
I am not sure how to proceed to get the 4xN array I am looking for.
UPDATE
Output from command MY_STRUCTURES_Array returns a row array of [1x4 struct].
Output from whos MY_STRUCTURES_Array{1} returns nothing
Output from whos MY_STRUCTURES_Array returns:
Name Size Bytes Class Attributes
MY_STRUCTURES_Array 1x103 1371136 cell
Output from whos MY_STRUCTURES_Array{1}.thisField returns nothing
Output from MY_STRUCTURES_Array{1}.thisField was shown in the original post.

The fact that you're accessing MY_STRUCTURES_Array as MY_STRUCTURES_Array{1} indicates that it's a cell array, so I'll answer based on that.
Say we have MY_STRUCTURES_Array as a cell array of struct arrays:
MY_STRUCTURES_Array = {[1x4 struct], [1x4 struct], [1x4 struct]}
It contains N elements (here N = 3). Each element is a struct array with 4 elements and various fields. We want to extract the value of field foo, which contains a single number.
out = zeros(4, N);
for it = 1 : N
out(:, it) = [MY_STRUCTURES_Array{it}.foo];
end
out(i, j) now contains the value of MY_STRUCTURES_Array{j}(i).foo
EDIT:
Using arrayfun():
out = arrayfun(#(x) x.foo, cell2mat(MY_STRUCTURES_Array')')
This converts the cell array of struct arrays into a 2d struct array, then extracts field foo from each element.

Related

Get specific cells from a cell array

I have a numeric array sized 1000x1 which have values 0 and 1, called conditionArray.
I have a cell array called netNames with the same size (1000x1) and its cells contain string values (which are name of some circuit nets).
I want to extract net names which from netNames which their pairwise condition bit is 1 in conditionArray.
E.g. if conditionArray(100) is equal to extract its net name from netNames{100}.
Output of this process can be stored in an string array or cell array.
Are there any ways to do this operation with pairwise operations or I should use a for statement for this?
You shall check out cellfun in Matlab anytime you want to manipulate each element inside a cellarray without using a for loop.
As I understand, you have:
N = 1000;
% an array with 0s and 1s (this generates random 0s and 1s):
conditionArray = randi([0,1],N);
% a cell array with strings (this generates random 5-character strings):
netNames = cell(N);
netNames = cellfun(#(c)char(randi([double('a'),double('z')],1,5)), netNames, 'UniformOutput',false);
To extract the elements from netNames where conditionArray is 1, you can do:
netNames(conditionArray==1)
This uses logical indexing into the cell array.

Prevent MATLAB from turning single element arrays into a non-array type

I have a cell array, where each cell contains an array of strings. An example is as follows:
example = {{['a'], ['b']}, {['c']}}
However,
example{1}
returns a 1x2 cell array, whereas
example{2}
returns a cell, NOT a 1x1 cell array as expected. This single cell value is then not in the same format as the encapsulating example cell array, which breaks calculations further down the line.
How do I fix this? Ideally, I'd like to be able to have a 1x1 cell array and avoid any nasty special cases.
In MATLAB, there is no difference between a scalar entity and a 1 x 1 array. The scalar is simply a 1 x 1 version of the array. There is no special array class, instead an array is simply a list of objects that have the same class. This holds true regardless of whether it's a double array, a char array, a struct array, or in your case a cell array (more info here).
As such, example{2} does return a 1 x 1 cell array. You can test example{2} actually is a 1 x 1 cell by using class , size, iscell, and/or whos
class(example{2})
% cell
size(example{2})
% 1 1
iscell(example{2})
% 1
tmp = example{2};
whos('tmp')
% Name Size Bytes Class Attributes
%
% tmp 1x1 114 cell
Since it is a 1 x 1 cell array, the rest of your code should be able to handle it without any problems (assuming you wrote the rest of the code correctly).
A one-element cell array is still a cell array of size 1x1. Observe:
>> class(example{1})
ans =
cell
>> class(example{2})
ans =
cell
>> size(example{1})
ans =
1 2
>> size(example{2})
ans =
1 1
You can either test separately if your array is of size 1x1 in particular further down your code, or, consider whether indexing the cell array by () syntax somehow is more beneficial for you, e.g.:
>> example(1)
ans =
{1x2 cell}
>> example(2)
ans =
{1x1 cell}

Matlab- Create cell confusion matrix

I have the following cell matrix, which will be used as a confusion matrix:
confusion=cell(25,25);
Then, I have two other cell arrays, on which each line contains predicted labels (array output) and another cell matrix containing the real labels (array groundtruth).
whos output
Name Size Bytes Class Attributes
output 702250x1 80943902 cell
whos groundtruth
Name Size Bytes Class Attributes
groundtruth 702250x1 84270000 cell
Then, I created the following script to create the confusion matrix
function confusion=write_confusion_matrix(predict, groundtruth)
confusion=cell(25,25);
for i=1:size(predict,1)
confusion{groundtruth{i},predict{i}}=confusion{groundtruth{i}, predict{i}}+1;
end
end
But when I run it in matlab I have the following error:
Index exceeds matrix dimensions.
Error in write_confusion_matrix (line 4)
confusion{groundtruth{i},predict{i}}=confusion{groundtruth{i}, predict{i}}+1;
I was curious to print output's and groundtruth's values to see what was happening
output{1}
ans =
2
groundtruth{1}
ans =
1
So, nothing seems to be wrong with the values, so what is wrong here? is the confusion matrix's indexing right in the code?
The error occurs in a for loop. Checking the first iteration of the loop is not sufficient in this case. Index exceeds matrix dimensions means there exists an i in the range of 1:size(output,1) for which either groundtruth{i} or output{i} is greater than 25.
You can find out which one has at least one element bigger than the range:
% 0 means no, there is none above 25. 1 means yes, there exists at least one:
hasoutlier = any(cellfun(#(x) x > 25, groundtruth)) % similar for 'output'
Or you can count them:
outliercount = sum(cellfun(#(x) x > 25, groundtruth))
Maybe you also want to find these elements:
outlierindex = find(cellfun(#(x) x > 25, groundtruth))
By the way, I am wondering why are you working with cell arrays in this case? Why not numeric arrays?

Matlab replacing 0 with empty cell in Cell array

I have a 10,000 x 65 Cell with 0's and 1's so for example if I type
C(1,1) I get [0] returned or likewise C(3,4) a [1] is returned
I need a way to turn every 0 into a blank cell and every 1 into a char t
I've tried the following with little success
[rows, cols] = size(M);
for i = 1:rows
for j = 1:cols
if strcmp(M(i,j), 1)
M(i,j) = 't';
end
end
end
It returns the same thing, I'm guessing its not recognising the 1's as strings. Any idea sort of simply doing the conversion straight in Excel.
thanks
You are not accessing the cell data-structure correctly.
First of all, if M really is a cell array, you will have to use M{i,j} to access the data.
What M(i,j)does is just create a sub-cell-array, which contains M{i,j} as entry.
Also strcmp isn't used correctly, if your cell array contains strings you should use strcmp(M{i,j}, '1').
If your cell array on the other hand contains integers, you would have to use: M{i,j}==1.

Struct array initialization without values

I have a structure
AStructX : 7x1 struct array with fields:
field1
field2
field3
field4
field5
Now I want to generate an empty 1x7 that looks like the previous struct, but with empty values.
I tried
AStructY = repmat(AStructX(1),1,7); but the values of AStructX is copied.
I tried
AStructY = repmat(AStructX(1),1,0); when I add values to it, it pass with MATLAB, but Coder generation fails with the following error message
??? Subscripting into an empty matrix is not supported.
Use cell2struct:
len = 7;
fn = fieldnames(AStructX)
AStructY = cell2struct(repmat({[]},numel(fn),len),fn)
That gives a 7x1 struct array with the same fields, empty contents. If you want a 1x7, simply transpose the array (i.e. AStructY = cell2struct(...).').
I'll make the following assumptions:
1. AStructX is 2-D.
2. You want the new structure to have the size size(AStructX').
3. The field names are not fixed.
To do this, you first need the fieldnames, then create a new struct with empty cells as values:
names = fieldnames(AStructX)'; %'// row vector
len = length(names); %// number of fields
for i=1:len
names{2,i} = cell(size(AStructX')); %'// the contents are empty
end
AStructY = struct( names{:} ); %// will take the names matrix columnwise
This will result in completely empty entries ([]), if you want to initialize the values to 0 instead, the line inside the loop becomes
names{2,i} = num2cell(zeros(size(AStructX'))); %'// initialize values to 0

Resources