4

I never liked Embedded MATLAB much, precisely because of situations like what I'm about to ask :) In my experience, conversion to Embedded MATLAB often takes a lot more effort than simply re-writing the thing in C (when you know C and the MATLAB API well enough).

But oh well, I guess some things just can't be avoided.

Anyway, here's my problem. In Embedded MATLAB, as it is in R2010a, you can't do this:

for ii = <some range>

    parameter = <some string> 

    switch parameter

        case 'first_string'
            % do stuff

        case 'another_string_that''s_larger_than_first_string'
            % do other stuff
    end

    % ...continue here

end

where <some string> changes every iteration. This is because the length of the string parameter is variable, meaning that this definition of parameter is beyond Embedded Matlab's capabilities:

??? Non-constant expression or empty matrix. This expression must be constant because its value determines the size or class of some expression. The limitation to constant strings applies only for switches on strings, not switches on numbers.

Changing the switch to its more direct form

switch <some string> 
    ...
end

doesn't help of course:

??? Expected a numeric value. Found a mxArray

Even constraining the size of the string to a known constant length does not help:

parameter = char_array(ii, 1:4);  % <--- NOTE: length is 4 characters

switch parameter
    ...
end

but no luck:

??? Non-constant expression or empty matrix. This expression must be constant because its value determines the size or class of some expression. The limitation to constant strings applies only for switches on strings, not switches on numbers.

I see two ways out:

  1. Map all permissible strings to some numeric representation, and use a switch on the numbers
  2. Use strcmp(i) inside a huge if-elseif-elseif-...-else-end construct.

Both are equally ugly IMHO, with 2. perhaps being uglier (you'd need another extrinsic function, strcmp)...

So, is there any elegant way out of this?

Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
  • I guess padding the string with space to equal length would work? (It isn't the elegant solution you were looking for though.) – user1884905 Jun 12 '13 at 09:48
  • @user1884905: no, I tried that...in fact, in my real function the first 4 characters uniquely determine the strings, so I tried just using the first 4 characters; no luck, same error message. – Rody Oldenhuis Jun 12 '13 at 10:02

1 Answers1

1

Unfortunately I don't know of any other method except the alternatives you mention.

To make things worse, MATLAB has no built-in char array to double scalar hash function. Hence, if you want to map strings to numbers then you need to provide a custom hash function.

Personally, I'd go with your second method. It's ugly but readable.

Since you say that you only need to consider the first 4 chars of each string, another option to map your strings to numbers is by explicit lookup:

function y = fcn(u)
%#codegen

    y = u;

    cases = [
        '1111'
        '2222'
        '3333'
    ];

    for i = 1 : 3
        switch i
            case 1                
                p = '1111a';
            case 2
                p = '2222bb';
            otherwise
                p = '3333ccc';
        end      

        for j = 1 : size(cases, 1)
            if isequal(cases(j, 1 : 4), p)
                switch j
                    case 1
                        y = y + 1;
                    case 2
                        y = y + 2;
                    case 3
                        y = y + 3;
                end
            end
        end        
    end
end

In my opinion this is not really readable and probably wastes a lot of time if you have a large number of strings. You may come up with something more performant, but I'd still consider this a hack.

Florian Brucker
  • 9,621
  • 3
  • 48
  • 81
  • Thanks, it's what I was afraid of. I solved it with the fugly `if-elseif-...-else-end` construct, which I thought was indeed the most readable alternative. Mapping strings to some arbitrary number felt a bit like forcing a Volkswagen Beetle into low Earth orbit...just slightly beyond its design constraints :) – Rody Oldenhuis Jun 12 '13 at 14:06