Reputation: 38032
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:
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?
Upvotes: 4
Views: 2176
Reputation: 10355
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.
Upvotes: 1