0

I'm looking for a very simple method to sum structures
which have identical substructure hierarchies.

Note: This began with an attempt to sum bus structures in Simulink.

MWE

Assume I have 2 structures red and blue.
Each structure has subfields a, b, and c.
Each subfield has subfields x1 and x2.

This is drawn below:

red. [a, b, c].[x1, x2]
blue.[a, b, c].[x1, x2]

Does a function exist such that a mathematical operator
may be applied to each parallel element of red and blue?

Something along the lines of:

purple = arrayfun( @(x,y) x+y, red, blue)

Community
  • 1
  • 1
kando
  • 441
  • 4
  • 16
  • You probably want to add a limitation to your question: Only code which supports code generation may be used. `fieldnames` would easily solve this, but it is not supported. – Daniel Mar 07 '16 at 20:38
  • @Daniel If code generation is not supported, does that signify that it will not function in Simulink in (rapid) accelerator mode? If so, I definitely would like that constraint. – kando Mar 07 '16 at 20:47
  • @Daniel I was looking at `fieldnames`. I couldn't get it to go beyond a single level. For example: `fieldnames(red)` functioned; however, `fieldnames(red.a)` did not. Is this a simple syntax error, or would it be worth creating a separate question? – kando Mar 07 '16 at 20:48
  • I think even running in normal mode would be blocked having incompatible code. Not sure what went wrong with your example, `fieldnames(red.a)` should be right. What error do you get? – Daniel Mar 07 '16 at 20:56
  • @Daniel . I figured `fieldnames` issue out: I'm not using `red` and `blue`; I'm using `y(1)` and `y(2)`. Needed `fieldnames(y(1).a)` rather than `fieldnames(y.a)`. I incorrectly assumed that since `y(1)` and `y(2)` had equivalent substructures, that I could skip the index value. – kando Mar 07 '16 at 21:00
  • what about `structun`? – Ander Biguri Mar 07 '16 at 21:51
  • 1
    @Ander: good catch, to my surprise `structfun` is supported. Anonymous functions aren't allowed, but still very useful. – Daniel Mar 07 '16 at 22:51
  • I finally gave up, don't see a possibility using dynamic code. Maybe generating the code is the only possibility. – Daniel Mar 07 '16 at 23:14

1 Answers1

0

Realizing that dynamic code which does support arbitrary structs and supports code generation is impossible (afaik), the best possibility to simplify coding is a function which generates the code:

function f=structm2(s)
    e=structm3(s);
    f=strcat('y.',e,'=plus(u.',e,',v.',e,');');
    f=sprintf('%s\n',f{:});
end

function e=structm3(s)
e={};
for f=fieldnames(s).'
    f=f{1};
    if isstruct(s.(f))
        e=[e,strcat([f,'.'],structm3(s.(f)))];
    else
        e{end+1}=f;
    end

end
end

You call structm2 inputting a struct and it returns the code:

y.a.x1=plus(u.a.x1,v.a.x1);
y.a.x2=plus(u.a.x2,v.a.x2);
y.b.x1=plus(u.b.x1,v.b.x1);
y.b.x2=plus(u.b.x2,v.b.x2);
Daniel
  • 36,610
  • 3
  • 36
  • 69