cra*_*raq 3 matlab code-generation simulink switch-statement matlab-coder
以下代码是有效的matlab sytax,用于检查是否b匹配中的任何元素a.但是,如果代码用于代码生成(即simulink),那么我得到错误:
'code generation only supports cell operations for varargin and varargout
Run Code Online (Sandbox Code Playgroud)
您可以通过%#codegen在脚本顶部添加来检查这一点.)
a={2 3};
b=3;
switch b
case a
disp yay
otherwise
disp boo
end
Run Code Online (Sandbox Code Playgroud)
case在代码生成兼容代码中,我应该如何匹配语句中的多个模式?
以下内容对我不起作用:
case a(1) || a(2) %//with a=[2, 3] above, since cells not allowed
case a(:)
Run Code Online (Sandbox Code Playgroud)
Matlab编码器不支持"单元阵列",并且具有一组有限的功能.请记住,C不要像Matlab那样灵活,特别是关于type它处理的数据.C不做动态类型(结构应该定义一次,定义不能在代码中改变).因此,Matlab不能让你使用cell array非常宽松的类型,并且你要添加到cell数组中的下一个元素与其他元素的类型不同.
因此,如果您希望将Matlab转换为可能的C语言,那么有些情况下您将不得不为Matlab提供明确的内容.
对于您的情况,不同的选择:
case语句中如果您不必a经常重复使用以进行比较,则可以case a使用以下显式列表替换case {2,3,4,5}:
function test_coder(b)
switch b
case {2,3,4,5}
disp yay
otherwise
disp boo
end
Run Code Online (Sandbox Code Playgroud)
它看起来像一个单元阵列,但事实并非如此.因为它足够明确(变量只保持4 double种类型)Matlab将在内部使用数组并与b每个元素进行比较(它将"扩展" case语句).实际上,这部分生成的代码看起来像(纯粹的C方式):
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
Run Code Online (Sandbox Code Playgroud)
ismember与数组一起使用.该功能ismember是由代码生成的支持.所以下面的代码也适用:
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
Run Code Online (Sandbox Code Playgroud)
但请注意,编码器要求对发送的数组ismember进行排序,否则会引发错误.
如果你有很多比较,这是有效的,但是考虑到生成的代码的复杂性,我建议ismember只在你真正需要的时候使用它.
当你的案例足够简单时我会建议你明确声明你的cases({...}如果你需要的话,使用"快捷方式").
另外要小心,看看你生成的代码:
在你的初始例子中,当你b=3在代码中指定时,Matlab检测到,检测到代码将始终以这种方式流动,因此它甚至不编码比较逻辑......生成的代码只是一个快速disp yay...
我不得不将其b作为输入来让Matlab实际编写比较逻辑.要编译上面的代码,您必须指定输入变量的类型b.所以我用以下方法编译了上面
codegen test_coder.m -args {0}
Run Code Online (Sandbox Code Playgroud)