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?
As in MATLAB®, you index substructures and fields structures in MATLAB Function blocks by using dot notation.
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.
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)
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With