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).

Was it helpful?

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

OTHER TIPS

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));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top