当使用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
现在这个也适用
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
但这个无法生成代码,抱怨大小不匹配:
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
这是命令行中的输出:
>> 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)
我在MATLAB R2013b和R2015a中看到过这种行为。
从 文档,Matlab codegen
必须在编译时知道矩阵的大小 除非 codegen
被告知或推断矩阵的大小可变。有几种方法可以让Matlab知道矩阵的大小可变:
- 运用
coder.varsize
函数,矩阵可以显式声明为可变大小。
- MATLAB可以根据代码的结构推断出矩阵的大小可变。
正如您的代码所暗示的,选项(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
为什么Matlab想知道这些信息?如果在编译时已知矩阵的大小,则可能进行各种额外的优化(循环展开等...)。
从 文档,Matlab codegen
必须在编译时知道矩阵的大小 除非 codegen
被告知或推断矩阵的大小可变。有几种方法可以让Matlab知道矩阵的大小可变:
- 运用
coder.varsize
函数,矩阵可以显式声明为可变大小。
- MATLAB可以根据代码的结构推断出矩阵的大小可变。
正如您的代码所暗示的,选项(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
为什么Matlab想知道这些信息?如果在编译时已知矩阵的大小,则可能进行各种额外的优化(循环展开等...)。
我同意Matthew Gunn的回答,这是为行为添加一些解释。关于Coder如何分析您的MATLAB代码的一个好的心理模型是它从上到下查看它。
在前两个示例中应用该心智模型,确定大小的分配 y
: y = zeros(2,2)
和 y = zeros(5,5)
,发生在价值之前 y
是用过的。因此Coder可以将两种尺寸合并为自动制作 y
一个可变大小的数组。在第三个例子中,赋值 y = zeros(2,2)
发生然后 y
用来: y = 2 * y
。此时,编码器需要确定乘法的大小和类型 2 * y
。只有 2-by-2
看到分配所以推断出 2 * y
还必须退货 2-by-2
矩阵。
执行此推断然后嵌入假设 y
是 2-by-2
进入代码并基本上锁定了大小 y
以便随后分配给 y
用一个 5-by-5
矩阵必须失败。