1

Is it possible to iterate through a MATLAB structure numerically like a vector instead of using the field names?

Simply, I am trying to do the following inside an EML block for Simulink:

S.a.type = 1;
S.a.val = 100;
S.a.somevar = 123;    
S.b.type = 2;
S.b.val = 200;
S.b.somevar2 = 234;
S.c.type = 3;
S.c.val = 300;
S.c.somevar3 = 345;

for i = 1:length(s)
    itemType = S(i).type;
    switch itemType
        case 1
            val = S(i).val * S(i).somevar1;
        case 2
            val = S(i).val * S(i).somevar2;
        case 3
            val = S(i).val * S(i).somevar3;
        otherwise
            val = 0
    end
end

disp(var);
tmar89
  • 33
  • 1
  • 6
  • See this question [How do I access MATLAB structure fields within a loop?](http://stackoverflow.com/questions/1882035/how-do-i-access-matlab-structure-fields-within-a-loop) – Aabaz Sep 21 '11 at 18:20

2 Answers2

2

You should be able to generate the fieldnames dynamically using sprintf using something like the following:

for i = 1:length(s)
    theFieldName = sprintf('somevar%d', S(i).type);
    val = S(i).val * getfield(S(i), theFieldName);
end
Matt
  • 2,339
  • 1
  • 21
  • 37
1

You need to use the field names, but you can do so dynamically. If you have a structure defined as:

s.field1 = 'foo';
s.field2 = 'bar';

Then you can access the field field1 with either

s.field1
s.('field1')

The only thing you need is the function fieldnames to dynamically get the field names such that your code example will look somewhat like

elements = fieldnames(S);
for iElement = 1:numel(elements)
   element = S.(elements{iElement});
   itemType = element.type;
   switch itemType
      case 1
          val = element.val * element.somevar1;
      case 2
          val = element.val * element.somevar2;
      case 3
          val = element.val * element.somevar3;

   end
end

If those are the exact field names, you should do some other things. First of all you would need to rethink your names and secondly you could use part of Matt's solution to simplify your code.

Egon
  • 4,757
  • 1
  • 23
  • 38
  • This is mostly what I have, but the problem is that Matlab Embedded function blocks in Simulink do not support this method. Firstly, fieldnames requires coder.instrinsic and then cell operations are not supported. I also tried doing something slightly different where I just increment the field names like you did, s.field1, s.field2 and in the code tried incrementing like: s.(['field' i]) but that fails also. Bummer! – tmar89 Sep 23 '11 at 15:30
  • @tmar89: oh, I see. I don't have that much experience with SimuLink and the coder to know what is or isn't supported, but I suppose if my solution doesn't work it might be something fundamental that's missing from the code generation. – Egon Sep 24 '11 at 09:49