matlab中具有多个匹配项的开关盒以生成代码 [英] switch-case with multiple matches in matlab for code generation

查看:139
本文介绍了matlab中具有多个匹配项的开关盒以生成代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是有效的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆