Question

let's say that i have two structure arrays with matching fields, and also the contents of both arrays in a given field are of the same size:

A.field1 = [1,2,3]
A.field2 = 5

B.field1 = [4,5,6]
B.field2 = 9

I would like to take a linear combination of all the data in each field. In our example, this would mean that if x and y are constants, i would like to get a structure array C such that

C.field1 = x*(A.field1) + y*(B.field1)
C.field2 = x*(A.field2) + y*(B.field2)

My first guess was to use the command structfun but this only seems to take a single structure array as input, where i would need both A and B to be input.

A blunt way is extracting all the data and storing them in separate variables, take the linear combination, and put them back together in a structure array. But it seems there must be a simpler way (or at least one that is quicker to type, my arrays are not that small).

Était-ce utile?

La solution

Following assumes you have two structure arrays with an arbitrary number of matching fields (n - the same for both structs) which is not nested (no A.field1.field2)

Vanilla loop:

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

Output:

C = 

    field1: [14 19 24]
    field2: 37

Alternative using 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)

Output:

C2 = 

    field1: [14 19 24]
    field2: 37

Autres conseils

Code

%%// 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))

You could convert them to cell arrays, which support multiple arguments:

result = cell2struct( cellfun(@(x,y){1/4*x+3/4*y}, struct2cell(A),struct2cell(B)), fieldnames(A));

Same code, but with better style (I hate one-liners):

 cellA = struct2cell(A);
 cellB = struct2cell(B);
 cellResult = cellfun(@(x,y){1/4*x+3/4*y},cellA,cellB);
 result = cell2struct(cellResult , fieldnames(A));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top