The following code is valid matlab sytax to check whether b
matches any elements in a
. However, if the code is used for code generation (i.e. simulink) then I get the error:
'code generation only supports cell operations for varargin and varargout
You can check this by adding %#codegen
at the top of the script.)
a={2 3};
b=3;
switch b
case a
disp yay
otherwise
disp boo
end
What should I do to match multiple patterns in a case
statement in code-generation compatible code?
The following don't work for me:
case a(1) || a(2) %//with a=[2, 3] above, since cells not allowed
case a(:)
Matlab coder does not support 'cell arrays', and has a limited set of functions it can handle. Remember than C
is not as flexible as Matlab, specially regarding the type
of data it handles. C
does not do dynamic type (a structure should be defined once and the definition cannot change in the code). So Matlab cannot let you use cell array
which is very loosely typed and where the next element you would add to your cell
array would be of different type than the other ones.
So there will be cases where you will have to explicit things for Matlab if you expect it to convert it into possible C
language.
For your case, different options:
case
statementIf you do not have to reuse a
for comparison too often, you can replace case a
with an explicit list like case {2,3,4,5}
:
function test_coder(b)
switch b
case {2,3,4,5}
disp yay
otherwise
disp boo
end
It looks like a cell array but it isn't. Because it is explicit enough (the variable just hold 4 double
type) Matlab will internally use an array and compare b
to each element (it will "expand" the case
statements). Indeed, this part of the generated code look like (pure C
way):
guard1 = FALSE;
switch ((int32_T)emlrtIntegerCheckFastR2012b(b, &emlrtDCI, emlrtRootTLSGlobal))
{
case 2:
guard1 = TRUE;
break;
case 3:
guard1 = TRUE;
break;
case 4:
guard1 = TRUE;
break;
case 5:
guard1 = TRUE;
break;
... // and so on
ismember
with arrays.The function ismember
is supported by the code generator. So the code below works too:
function test_coder(b)
a=[2 3 4 5] ; %// define array "a"
c=[8 9 10] ; %// define array "c"
if ismember(b,a)
disp yay
elseif ismember(b,c)
disp youhou
else
disp boo
end
Note however that the coder requires the arrays sent to ismember
to be sorted otherwise it will throw an error.
This works if you have a lot of comparison to do, however given the complexity of the generated code, I would advise using ismember
only when you really need it.
when your cases are simple enough I would recommend to go for explicit declarations of your cases
(using the {...}
"shortcut" if you need it.
Also be careful always to look at your generated code:
In you initial example, when you specify b=3
in the code, Matlab detect that, detect that the code will always flow this way so it wasn't even coding the comparison logic ... The generated code was just a quick disp yay
...
I had to place b
as an input to get Matlab to actually code the comparison logic. To compile the code above, you have to specify which type the input variable b
will be. So I compiled the above using:
codegen test_coder.m -args {0}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With