从matlab源代码生成调用图

iklwldmw  于 2023-06-30  发布在  Matlab
关注(0)|答案(6)|浏览(199)

我正在尝试为大约500个matlab src文件创建一个函数调用图。我无法找到任何工具,可以帮助我做同样的多个src文件。
有人熟悉任何工具或插件吗?
如果没有任何这样的工具,任何关于阅读6000行matlab代码而不需要文档的建议都是受欢迎的。

bksxznpy

bksxznpy1#

让我推荐M2HTML,一个自动生成MATLAB m文件的HTML文档的工具。在其功能列表中:

  • 查找函数之间的依赖关系并生成依赖关系图(使用GraphViz的点工具)
  • 函数和子函数的自动交叉引用及其在源代码中的定义

查看demo页面,查看tool的输出示例。

s2j5cfk0

s2j5cfk02#

我建议使用depfun函数来构造调用图。有关详细信息,请参阅http://www.mathworks.com/help/techdoc/ref/depfun.html
特别是,我发现用'-toponly'参数调用depfun,然后迭代结果,是手工构造调用图的一种很好的方法。不幸的是,我再也不能访问我用它编写的任何代码了。

yuvru6vn

yuvru6vn3#

我认为你的意思是你想确切地看到你的代码是如何运行的--什么函数调用什么子函数,什么时候,以及这些函数运行了多长时间?
看看MATLAB Code Profiler。执行代码如下:

>> profile on -history; MyCode; profile viewer
>> p = profile('info');

p包含函数历史,从我上面链接的同一个帮助页面:
历史数据描述在执行期间进入和退出的函数的序列。profile命令在其返回的结构的FunctionHistory字段中返回历史数据。历史数据是一个2 × n数组。第一行包含布尔值,其中0表示进入函数,1表示退出函数。第二行通过FunctionTable字段中的索引标识正在进入或退出的函数。这个例子[下面]读取历史数据并将其显示在MATLAB命令窗口中。

profile on -history
plot(magic(4));
p = profile('info');

for n = 1:size(p.FunctionHistory,2)
 if p.FunctionHistory(1,n)==0
        str = 'entering function: ';
 else
        str = 'exiting function: ';
 end
 disp([str p.FunctionTable(p.FunctionHistory(2,n)).FunctionName])
end

您不一定需要像上面的示例那样显示入口和出口调用;只需查看p.FunctionTablep.FunctionHistory就足以显示代码何时进入和退出函数。

qvtsj1bj

qvtsj1bj4#

这个问题已经有很多答案了。然而,因为我喜欢这个问题,我喜欢拖延,下面是我回答这个问题的方式(它接近Dang Khoa提出的方法,但不同的是,在我看来):
我们的想法是运行profile函数,沿着一个digraph来表示数据。

profile on

Main % Code to be analized

p = profile('info');

p是一个结构。特别地,它包含字段FunctionTable,这是一个结构数组,其中每个结构包含有关Main.m执行期间的一个调用的信息。为了只保留函数,我们必须检查FunctionTable中的每个元素是否是函数,即如果p.FunctionTable(ii).Type'M-function'
为了表示信息,让我们使用MATLAB's digraph对象:

N = numel(p.FunctionTable);

G = digraph;

G = addnode(G,N);

nlabels = {};

for ii = 1:N
    
        Children = p.FunctionTable(ii).Children;
        
        if ~isempty(Children)
            
            for jj = 1:numel(Children)
                
                G = addedge(G,ii,Children(jj).Index);
                
            end
            
        end
end

Count = 1;

for ii=1:N

    if ~strcmp(p.FunctionTable(ii).Type,'M-function') % Keep only the functions    
        
        G = rmnode(G,Count);
    
    else
        
        Nchars = min(length(p.FunctionTable(ii).FunctionName),10);
        nlabels{Count} = p.FunctionTable(ii).FunctionName(1:Nchars);
        Count = Count + 1;
             
    end
    
end

plot(G,'NodeLabel',nlabels,'layout','layered')

G是一个有向图,其中node #i是指结构数组p.FunctionTable中的i-th元素,如果node #i表示的函数是node #j表示的函数的父函数,则边将node #i连接到node #j
当应用到我的大程序时,这个图非常难看,但对于较小的函数可能会更好:

放大图形的子部分:

unguejic

unguejic5#

我同意m2 html的回答,我只是想说下面的例子来自m2 html/mdot文档是好的:

mdot('m2html.mat','m2html.dot');
!dot -Tps m2html.dot -o m2html.ps
!neato -Tps m2html.dot -o m2html.ps

但我在导出到PDF时运气更好:

mdot('m2html.mat','m2html.dot');
!dot -Tpdf m2html.dot -o m2html.pdf

此外,在尝试上述命令之前,您必须发出以下命令:

m2html('mfiles','..\some\dir\with\code\','htmldir','doc_dir','graph','on')
sg2wtvxw

sg2wtvxw6#

我发现m2html非常有帮助(与Graphviz软件结合使用)。然而,在我的情况下,我想创建一个文件夹中包含的程序的文档,但忽略了一些子文件夹和.m文件。我发现,通过在m2html调用中添加“ignoreddir”标志,可以使程序忽略一些子文件夹。但是,我没有找到忽略.m文件的类似标志(“ignoreddir”标志也没有完成这项工作)。作为一种解决方法,在m2html.m文件中的第1306行之后添加以下行也允许使用“ignoreddir”标志来忽略.m文件:

d = {d{~ismember(d,{ignoredDir{:}})}};

因此,例如,为了生成文件夹“program_folder”中包含的程序的html文档,但忽略“subfolder_1”子文件夹和“test.m”文件,应该执行如下操作:

m2html( 'mfiles', 'program_folder', ...  % set program folder
        'save', 'on', ...  % provide the m2html.mat
        'htmldir', './doc', ...  % set doc folder
        'graph', 'on', ...  % produce the graph.dot file to be used for the visualization, for example, as a flux/block diagram
        'recursive', 'on', ...  % consider also all the subfolders inside the program folders
        'global', 'on', ...  % link also calls between functions in different folders, i.e., do not link only the calls for the functions which are in the same folder
        'ignoreddir', { 'subfolder_1' 'test.m' } );  % ignore the following folders/files

请注意,“program_folder”中所有名为“subfolder_1”的子文件夹和所有名为“test.m”的文件都将被忽略。

相关问题