【问题标题】:Matlab Code Generation for Recursive Functions递归函数的 Matlab 代码生成
【发布时间】:2021-01-11 07:33:36
【问题描述】:

我正在尝试使用 Matlab 的 Coder 应用程序将 Matlab 中的递归函数转换为 C/C++ 代码。一般来说,Coder 会给出一个错误,指出不允许使用递归函数。但是,Matlab 帮助页面说,如果您遵循以下准则,您可以从递归函数生成代码:

“当您在用于代码生成的 MATLAB 代码中使用递归时,请遵循以下限制:”

  1. MATLAB Function 模块中的顶级函数不能是递归函数,但可以调用递归函数。
  2. 在函数中的第一次递归调用之前分配运行时递归函数的所有输出。
  3. 分配运行时递归函数的元胞数组输出的所有元素。
  4. 运行时递归函数的输入和输出不能是类。
  5. 最大堆栈大小参数在运行时递归中被忽略。

我基本了解条件,但我不知道如何让 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&lt;T&gt;,其中T是一个保存所有必要输入和输出参数的项。
  • 我应该提到我知道递归调用的缺点并且可以使用堆栈(我没有在这个程序中这样做,但我已经在 Matlab 中创建了堆栈和双端队列.. .所以有可能)。我提供的示例显示为简单示例,有使用 Matlab 的 Coder 应用程序为递归函数生成 C/C++ 代码经验的人可以轻松地向我展示如何做到这一点。这些功能本身并不有意义。它们只是为了展示简单递归函数的示例。
  • 递归有优点也有缺点,特别是在这种情况下,一个主要优点是代码维护。代码的形式紧凑且易于理解。我不关心堆栈问题或调用效率低下。正如我在原始问题中提到的,我们知道递归调用的最大数量和堆栈的最大大小。调试不是那么愉快,但它伴随着领土而来,它现在运行完美。所以,需要明确的是,我不是在寻找解决方法,我想知道如何使用 Matlab 的 Coder 应用程序转换递归函数。
  • 我能够在 MATLAB R2020a 中的该代码上成功运行 codegen recursive_test。您使用的是哪个 MATLAB 版本? Codegen 对递归的支持是 added in R2016b
  • 不错的收获...!我正在使用 R2015(b?)。我想我正在查看的帮助是针对最新版本的,而我没有查看添加功能的时间。 (我的错!)我真的很想保留 2015(b?)以向后兼容一些旧代码,但我想我会硬着头皮升级 Matlab 并更新旧代码。乐趣。我会升级 Matlab 看看我得到了什么,希望记得更新这篇文章。

标签: c++ matlab recursion


【解决方案1】:

Matlab Coder 为 Matlab 2020b 中的函数中的递归函数生成 C 代码,根据 Ryan Livingston 的评论,它可能适用于 Matlab 2016b 及更高版本,很可能不适用于 Matlab 2016a 及更早版本。它不适用于 Matlab 2015b。这里是Matlab's recursion-related release notes,它表明在 Matlab 2016b 中添加了递归代码生成。

如果您在为递归函数生成代码时遇到问题,Matlab Coder 应用程序将从以下递归 Matlab 代码生成 C 代码(请注意,该代码有效,但不应做任何有用的事情,仅用于提供递归的简单示例)。您可以将其用作模板并从那里构建。

%------------------------
function recursion_test()
   %clear all %<-uncomment this line to generate a conversion error 
   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
%------------------------

【讨论】:

猜你喜欢
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
  • 1970-01-01
  • 2015-05-14
  • 1970-01-01
  • 2018-02-06
  • 1970-01-01
相关资源
最近更新 更多