Как эффективно взять линейную комбинацию из двух различных структурных массивов?
Предположим, что у меня есть два структурных массива с соответствующими полями, а также содержимое обоих массивов в данном поле одинакового размера:
A.field1 = [1,2,3]
A.field2 = 5
B.field1 = [4,5,6]
B.field2 = 9
Я хотел бы взять линейную комбинацию всех данных в каждом поле. В нашем примере это будет означать, что если x и y являются константами, я хотел бы получить структурный массив C такой, что
C.field1 = x*(A.field1) + y*(B.field1)
C.field2 = x*(A.field2) + y*(B.field2)
Моей первой догадкой было использовать команду structfun , но это, похоже, только один структурный массив в качестве входных данных, где мне понадобились бы и A, и B, чтобы быть входными данными.
Грубый способ-это извлечение всех данных и хранение их в отдельных переменных, взять линейную комбинацию и собрать их обратно в структурный массив. Но, похоже, должен быть более простой способ (или, по крайней мере, тот, который быстрее печатается, мои массивы не так малы).3 ответа:
Далее предполагается, что у вас есть два структурных массива с произвольным числом совпадающих полей (
n
- одинаковое для обеих структур), которые не являются вложенными (нетA.field1.field2
)Ванильная петля:
x = 2; y = 3; names = fieldnames(A); % returns n x 1 cell array for n = 1:length(names) C.(names{n}) = x*A.(names{n}) + y*B.(names{n}); end
Вывод:
C = field1: [14 19 24] field2: 37
Альтернатива с использованием cellfun:
x = 2; y = 3; names = fieldnames(A); A2 = struct2cell(A); B2 = struct2cell(B); C2 = cellfun(@(A,B) x*A+3*B, A2,B2,'UniformOutput',0); C2 = cell2struct(C2,names)
Вывод:
C2 = field1: [14 19 24] field2: 37
Код
%%// Input structs A.field1 = [1,2,3] A.field2 = 5 A.field3 = [8 9]; B.field1 = [4,5,6] B.field2 = 9 B.field3 = [11 12]; %%// Scaling factors scaling_factors = [2; 3]; %%// This is your [x y] cellA = cellfun(@(x) x*scaling_factors(1),struct2cell(A),'un',0) cellB = cellfun(@(x) x*scaling_factors(2),struct2cell(B),'un',0) cellC = cellfun(@plus, cellA, cellB,'uni',0) C = cell2struct(cellC, fieldnames(A))
Вы можете преобразовать их в массивы ячеек, которые поддерживают несколько аргументов:
result = cell2struct( cellfun(@(x,y){1/4*x+3/4*y}, struct2cell(A),struct2cell(B)), fieldnames(A));
Тот же код, но с лучшим стилем (я ненавижу однострочные):
cellA = struct2cell(A); cellB = struct2cell(B); cellResult = cellfun(@(x,y){1/4*x+3/4*y},cellA,cellB); result = cell2struct(cellResult , fieldnames(A));