Векторизация многоуровневой индексации структур в MATLAB
Скажем, у меня есть следующее в MATLAB:
a(1).b.c = 4;
a(2).b.c = 5;
a(3).b.c = 7;
....
Я хотел бы собирать значения [4 5 7 ...]
в одном массиве без циклов и в векторном виде.
Я пробовал:
>> a(:).b.c
# Error: Scalar index required for this type of multi-level indexing.
и
>> a.b.c
# Error: Dot name reference on non-scalar structure.
но они не сработали. Лучшее, что я мог придумать, было:
arrayfun(@(x) x.b.c, a);
но насколько я понимаю arrayfun
не векторизован, или это?
Ответы
Ответ 1
a.b
возвращает несколько выходов, поэтому вы не можете ожидать вызова функции на нем. Лучший однострочный, о котором я могу думать без использования arrayfun
:
y = subsref([a.b], substruct('.', c));
Обратите внимание, что a.b.c
фактически совпадает с:
y = subsref(a.b, substruct('.', c))
Вот почему он не должен работать для нескалярного a
.
Ответ 2
Ваш вызов arrayfun
кажется мне настолько идиоматичным для меня в Matlab. Я не думаю, что это векторизованное, но оно хорошо оптимизировано и, возможно, самый быстрый способ.
Вы также должны попытаться сравнить с циклом, чтобы увидеть, хорошо ли работает JIT-компилятор. Трудно знать без тестирования.
Ответ 3
Вы можете сделать это в двух строках:
>> s = [a.b];
>> y = [s.c]
y =
4 5 7
Другой возможный однострочный (менее читаемый!):
>> y = squeeze(cell2mat( struct2cell([a.b]) ))
y =
4
5
7