matlab中具有多个匹配项的开关盒以生成代码 [英] switch-case with multiple matches in matlab for code generation
问题描述
以下代码是有效的matlab语法,用于检查b
是否与a
中的任何元素匹配.但是,如果将代码用于代码生成(即simulink),则会收到错误消息:
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
您可以通过在脚本顶部添加%#codegen
进行检查.)
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
我应该怎么做才能在代码生成兼容代码中匹配case
语句中的多个模式?
What should I do to match multiple patterns in a case
statement in code-generation compatible code?
以下对我不起作用:
case a(1) || a(2) %//with a=[2, 3] above, since cells not allowed
case a(:)
推荐答案
Matlab编码器不支持单元数组",并且可以处理的功能集有限.请记住,C
并不像Matlab那样灵活,特别是关于它处理的数据type
. C
不执行动态类型(结构应该被定义一次,并且定义不能在代码中更改).因此Matlab不能让您使用类型非常松散的cell array
,并且要添加到cell
数组中的下一个元素的类型将不同于其他元素.
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.
因此,在某些情况下,如果您希望Matlab将其转换为可能的C
语言,则必须对其进行显式显示.
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:
如果不必过于重复使用a
进行比较,则可以将case a
替换为诸如case {2,3,4,5}
的显式列表:
If 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
它看起来像一个单元格数组,但不是.因为它足够明确(变量仅保留4个double
类型),Matlab将在内部使用数组并将b
与每个元素进行比较(它将扩展" case
语句).确实,生成的代码的这一部分看起来像( pure C
方式):
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
.
函数 ismember
是
use 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
但是请注意,编码器要求对发送到ismember
的数组进行排序,否则将引发错误.
Note however that the coder requires the arrays sent to ismember
to be sorted otherwise it will throw an error.
如果您需要进行大量比较,则可以使用此方法,但是鉴于所生成代码的复杂性,我建议仅在确实需要时使用ismember
.
当您的案例足够简单时,我建议您为cases
进行明确声明(如果需要,可以使用{...}
快捷方式".
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.
还请务必注意查看您生成的代码:
在您的第一个示例中,当您在代码中指定b=3
时,Matlab会检测到该错误,并检测到该代码将始终以这种方式流动,因此甚至没有对比较逻辑进行编码.代码只是一个快速的disp yay
...
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
...
我必须放置b
作为输入,以使Matlab实际对比较逻辑进行编码.要编译上面的代码,您必须指定输入变量b
将是哪种类型.因此,我使用以下代码编译了上面的代码:
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}
这篇关于matlab中具有多个匹配项的开关盒以生成代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!