Multiplying structures together based on field names

Is there any method to multiply structures together according to their field names? For example,
struct1.a=1;
struct1.b=2;
struct2.a=3;
struct2.b=4;
And the result would be:
struct3.a=3
struct3.b=8

1 comentario

Stephen23
Stephen23 el 10 de Abr. de 2015
Editada: Stephen23 el 10 de Abr. de 2015
Note that storing sets of data in one variable makes more sense than lots of sequentially-named variables, and simplifies the code significantly over creating and using dynamically named variables. You might like to read this to learn some of the reasons why:
This is what David Young proposes in their second solution, and you should seriously consider using a non-scalar structure to store your data rather than multiple individual variables.

Iniciar sesión para comentar.

 Respuesta aceptada

David Young
David Young el 10 de Abr. de 2015
Editada: David Young el 10 de Abr. de 2015
A function to multiply two structures field by field. This needs to be copied into a file on your MATLAB path called multiplyStructs.m
function s3 = multiplyStructs(s1, s2)
%MULTIPLYSTRUCTS multiplies structures field by field
% S3 = MULTIPLYSTRUCTS(S1, S2) returns a structure S3 with those fields
% that are common to S1 and S2. The value of each such field is the
% matrix product of the values of the corresponding fields of S1 and S2.
% get common field names
f1 = fieldnames(s1);
fnames = f1(ismember(f1, fieldnames(s2)));
% multiply
for k = 1:length(fnames)
fname = fnames{k};
s3.(fname) = s1.(fname) * s2.(fname); % matrix product
end
end
Test code:
struct1.a = 1;
struct1.b = 2;
struct1.c = 3; % will be ignored as no match
struct1.d = 4;
struct2.a = 3;
struct2.b = 4;
struct2.d = 10;
struct3 = multiplyStructs(struct1, struct2)
An alternative way, which works only if all the structures have the same fields, but which generalises more readily to multiple structures, is to use this function:
function s = structProd(svec)
%STRUCTPROD returns the field-by-field products of a structure array
% S = STRUCTPROD(SARR) takes a structure array and returns a scalar
% structure with the same fields. The value of each field of S is the
% product of the values of the corresponding fields of SARR, which must
% all be numerical scalars.
%
% See also: prod
fnames = fieldnames(svec);
for k = 1:length(fnames)
fname = fnames{k};
s.(fname) = prod([svec.(fname)]);
end
end
and then put the structures into an array (which indeed might be the best way to store them to start with. Here's the test code:
struct1.a = 1;
struct1.b = 2;
struct1.d = 4;
struct2.a = 3;
struct2.b = 4;
struct2.d = 10;
struct3.a = -1;
struct3.b = -1;
struct3.d = -1;
struct4.a = 4;
struct4.b = 1;
struct4.d = 2;
struct5 = structProd([struct1 struct2 struct3 struct4])

2 comentarios

Note that my second method is equivalent to Stephen Cobeldick's approach - the difference is just that it uses an explicit loop rather than cellfun to iterate over field names.
Oliz
Oliz el 10 de Abr. de 2015
Thank you very much for the detailed answer. Your first solution solves my problem :)
It is generic and easily modified for similar purposes.

Iniciar sesión para comentar.

Más respuestas (1)

Hello Oliz,
I've played around with your structures, and I have multiplied struct1.a through struct2.b in the following way:
struct1.a=1
struct1.b=2
struct2.a=3
struct2.b=4
struct3.a=struct2.a*struct1.a %The multiplication operator provides the right solution.
struct3.b=struct2.b*struct1.b
Once run, the script yields the following results:
struct1 =
a: 1
struct1 =
a: 1
b: 2
struct2 =
a: 3
struct2 =
a: 3
b: 4
struct3 =
a: 3
struct3 =
a: 3
b: 8
Keep having fun with these things.
Best regards,
Jonathan Campelli

3 comentarios

Oliz
Oliz el 9 de Abr. de 2015
Hi Jonathan,
Thanks for taking the time to answer my question, however the reason I used an example was because my data is a lot more complex. I have around 15 structures each with 12 fieldnames.
As you can imagine, using this method is quite tedious and is the way I am currently implementing it.
I am looking to find an alternative method where I can use something along the lines of struct1*struct2 gives another structure with all the fields or some kind of loop which can recognise the field names and only multiply when they match.
Oliz
Oliz el 9 de Abr. de 2015
Thanks for this, I saw this earlier when searching through the forum. Unfortunately, I don't think it applies to my case since I don't want to multiply each field in my structure by a constant, but rather dynamically based on values inside another structure sharing the same field name.

Iniciar sesión para comentar.

Categorías

Más información sobre Data Preprocessing en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 9 de Abr. de 2015

Editada:

el 10 de Abr. de 2015

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by