Moh*_*nia 11 matlab code-generation matlab-coder
当使用MATLAB Coder生成C代码时,当if
在另一个if
或其else
部分的主体中发生时,行为是不同的.以下情况很容易创建输出大小为5x5的C代码:
function y = foo1(u)
if u > 0
y = zeros(2,2);
else
y = zeros(5,5);
end
Run Code Online (Sandbox Code Playgroud)
现在这个也适用
function y = foo2(u,v)
if u > 0
y = zeros(2,2);
else
y = zeros(5,5);
if v > 0
y = 2 * y;
end
end
Run Code Online (Sandbox Code Playgroud)
但是这个无法生成代码,抱怨大小不匹配:
function y = foo3(u,v)
if u > 0
y = zeros(2,2);
if v > 0
y = 2 * y;
end
else
y = zeros(5,5);
end
Run Code Online (Sandbox Code Playgroud)
这是命令行中的输出:
>> codegen foo1.m -args {0}
>> codegen foo2.m -args {0,0}
>> codegen foo3.m -args {0,0}
??? Size mismatch (size [2 x 2] ~= size [5 x 5]).
The size to the left is the size of the left-hand side of the assignment.
Error in ==> foo3 Line: 8 Column: 5
Code generation failed: Open error report.
Error using codegen (line 144)
Run Code Online (Sandbox Code Playgroud)
我在MATLAB R2013b和R2015a中看到过这种行为.
从文档中,Matlab codegen
必须在编译时知道矩阵的大小,除非 codegen
被告知或推断矩阵的大小可变.有几种方法可以让Matlab知道矩阵的大小可变:
coder.varsize
函数,可以显式声明矩阵具有可变大小.正如您的代码所暗示的那样,选项(2)显然并不健全.在某些情况下,Matlab会尝试推断出一个简单的if
else
语句,但这种推断似乎非常脆弱,如您的示例所示.
而不是依靠MATLAB来正确地推断矩阵是否是可变大小,解决方案是做出明确的声明:
function y = foo3(u,v)
coder.varsize('y', []); % Let codegen know y is variable sized
% and can be arbitrary dimensions
% an alternative is: coder.varsize('y',[5,5]);
if u > 0
y = zeros(2,2);
if v > 0
y = 2 * y;
end
else
y = zeros(5,5);
end
Run Code Online (Sandbox Code Playgroud)
为什么Matlab想知道这些信息?如果在编译时已知矩阵的大小,则可能进行各种额外的优化(循环展开等...).