Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to efficiently take a linear combination of two different structure arrays?

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

like image 967
Joachim Avatar asked Oct 20 '22 09:10

Joachim


1 Answers

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
like image 83
nkjt Avatar answered Nov 01 '22 10:11

nkjt