【发布时间】:2021-01-11 07:33:36
【问题描述】:
我正在尝试使用 Matlab 的 Coder 应用程序将 Matlab 中的递归函数转换为 C/C++ 代码。一般来说,Coder 会给出一个错误,指出不允许使用递归函数。但是,Matlab 帮助页面说,如果您遵循以下准则,您可以从递归函数生成代码:
“当您在用于代码生成的 MATLAB 代码中使用递归时,请遵循以下限制:”
- MATLAB Function 模块中的顶级函数不能是递归函数,但可以调用递归函数。
- 在函数中的第一次递归调用之前分配运行时递归函数的所有输出。
- 分配运行时递归函数的元胞数组输出的所有元素。
- 运行时递归函数的输入和输出不能是类。
- 最大堆栈大小参数在运行时递归中被忽略。
我基本了解条件,但我不知道如何让 Matlab 接受递归代码。我使用了 Matlab 中的一个例子:
function y = call_recursive()
n =35;
x = 10;
y = myrecursive(x,n);
end
function y = myrecursive(x,n)
coder.inline('never')
if x > 1
y = n + myrecursive(x-1,n-1);
else
y = n;
end
end
但我仍然收到“不允许递归函数”错误。我自己的代码的剥离版本是:
%------------------------
function recursion_test()
recursive_fn();
end %recursive caller
%------------------------
%------------------------
function recursive_fn()
persistent mycount;
if isempty(mycount) %initialize the persistent variable
mycount = 0;
end
counter = 0;
while(counter<300)
mycount = mycount + 1;
if mycount<100 %some generic test condition
recursive_fn();
end
if mycount<200 %another generic test condition
recursive_fn();
end %if
counter = counter+1;
end
disp(counter);
end %recursive function
%------------------------
我的代码给出了与 Matlab 示例相同的错误。我的特定应用程序的递归次数不应超过 300 次……通常约为 50-90 次。请注意,上面的代码并不能准确地跟踪递归,但我确实在实际代码中进行了跟踪。我可以将递归限制为 300 次,并强制编译器制作 300 个递归基本代码副本(我不知道该怎么做……但现在这是一个不同的问题)。首先,我希望能够使用 Coder 应用程序使用上述函数生成 C/C++ 代码。
那么,谁能解释一下如何为上面的递归函数生成 C/C++ 代码。最低限度,我想调用时间递归,但理想情况下,我也想知道运行时递归。注意我已经浏览了 Matlab 的代码生成和递归帮助页面,并使用我最喜欢的搜索引擎搜索了一个解决方案,但是我无法找到一个清晰的、逐步的过程。非常感谢您的帮助。
【问题讨论】:
-
你知道你永远不需要递归调用,不是吗?递归函数调用很容易导致堆栈溢出。通常更好的方法是使用堆栈数据结构,其中包含每个项目的必要参数,以及一个循环来控制从堆栈中推入和弹出并使用当前项目调用函数。我不知道matlab的脚本语言是否提供了类似堆栈的数据结构,在c++中你可以使用
std::stack<T>,其中T是一个保存所有必要输入和输出参数的项。 -
我应该提到我知道递归调用的缺点并且可以使用堆栈(我没有在这个程序中这样做,但我已经在 Matlab 中创建了堆栈和双端队列.. .所以有可能)。我提供的示例显示为简单示例,有使用 Matlab 的 Coder 应用程序为递归函数生成 C/C++ 代码经验的人可以轻松地向我展示如何做到这一点。这些功能本身并不有意义。它们只是为了展示简单递归函数的示例。
-
递归有优点也有缺点,特别是在这种情况下,一个主要优点是代码维护。代码的形式紧凑且易于理解。我不关心堆栈问题或调用效率低下。正如我在原始问题中提到的,我们知道递归调用的最大数量和堆栈的最大大小。调试不是那么愉快,但它伴随着领土而来,它现在运行完美。所以,需要明确的是,我不是在寻找解决方法,我想知道如何使用 Matlab 的 Coder 应用程序转换递归函数。
-
我能够在 MATLAB R2020a 中的该代码上成功运行
codegen recursive_test。您使用的是哪个 MATLAB 版本? Codegen 对递归的支持是 added in R2016b -
不错的收获...!我正在使用 R2015(b?)。我想我正在查看的帮助是针对最新版本的,而我没有查看添加功能的时间。 (我的错!)我真的很想保留 2015(b?)以向后兼容一些旧代码,但我想我会硬着头皮升级 Matlab 并更新旧代码。乐趣。我会升级 Matlab 看看我得到了什么,希望记得更新这篇文章。