Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vectorization of multi-level indexing of structs in MATLAB

Tags:

matlab

Say I have the following in MATLAB:

a(1).b.c = 4;
a(2).b.c = 5;
a(3).b.c = 7;
....

I would like to collect the values [4 5 7 ...] in a single array, without looping and in a vectorized manner.

I have tried:

>> a(:).b.c 
# Error: Scalar index required for this type of multi-level indexing.

and

>> a.b.c
# Error: Dot name reference on non-scalar structure.

but they didn't work. The best I could come up with was:

arrayfun(@(x) x.b.c, a);

but as far as I understand arrayfun is not vectorized, or is it?

like image 846
Amelio Vazquez-Reina Avatar asked Oct 24 '11 16:10

Amelio Vazquez-Reina


People also ask

Are structures indexed in MATLAB?

As in MATLAB®, you index substructures and fields structures in MATLAB Function blocks by using dot notation.

What is cell2mat in MATLAB?

A = cell2mat( C ) converts a cell array into an ordinary array. The elements of the cell array must all contain the same data type, and the resulting array is of that data type. The contents of C must support concatenation into an N-dimensional rectangle. Otherwise, the results are undefined.

How do you use a mat2cell?

c = mat2cell(x,r) divides up an array x by returning a single column cell array containing full rows of x . The sum of the element values in vector r must equal the number of rows of x . The elements of r determine the size of each cell in c , subject to the following formula for i = 1:length(r) : size(c{i},1) == r(i)

How does indexing in MATLAB work?

In logical indexing, you use a single, logical array for the matrix subscript. MATLAB extracts the matrix elements corresponding to the nonzero values of the logical array. The output is always in the form of a column vector. For example, A(A > 12) extracts all the elements of A that are greater than 12.


2 Answers

Your call to arrayfun seems idiomatic enough to me in Matlab. I don't think this is vectorized but it's well optimized and maybe the fastest way. You should also try to benchmark with a loop to see if the JIT compiler performs well here. It's hard to know without testing.

like image 172
Clement J. Avatar answered Oct 14 '22 09:10

Clement J.


You can do it in two lines:

>> s = [a.b];
>> y = [s.c]
y =
     4     5     7

Another possible one-liner (less readable!):

>> y = squeeze(cell2mat( struct2cell([a.b]) ))
y =
     4
     5
     7
like image 30
Amro Avatar answered Oct 14 '22 10:10

Amro