我在哪里使用工具箱?

时间:2019-06-17 14:59:43

标签: matlab dependencies

我正在研究一种科学应用程序,目前该应用程序已经由多个人开发了10多年。

最近,我们发现我们的应用程序需要多个工具箱,这不是默认MATLAB安装的一部分。 由于我们是使用大学许可证开发的,因此我们可以使用所有工具箱,因此到目前为止我们从未注意到这一点。 但是,我们希望将工具箱的数量减少到最少,以使其他小组更轻松,更便宜地使用我们的软件。

我跑步时

[fList,pList] = matlab.codetools.requiredFilesAndProducts('myFile.m')

pList列出了几个工具箱,例如:

 NAME                                  Version  id  Certain
'MATLAB'                                 '9.4'  1   true
'Robust Control Toolbox'               '6.4.1'  5   true
'Mapping Toolbox'                        '4.6'  11  true
'Financial Toolbox'                     '5.11'  30  true
'Aerospace Toolbox'                     '2.21'  108 true
'Parallel Computing Toolbox'            '6.12'  80  false
'MATLAB Distributed Computing Server'   '6.12'  94  false

我确信至少不需要“金融工具箱”和“航空航天工具箱”,我们只是通过将在线解决方案复制粘贴到我们的软件中来使用它。

例如,我们使用的是名为degrees2dms的函数,该函数是工具箱的一部分,可以将十进制度数转换为度,分和秒。这可以由我们自己轻松实现,而无需使用其他工具箱。

我的问题如下:

我知道matlab.codetools.requiredFilesAndProducts中使用了哪些工具箱。我如何才能找到这些工具箱中的哪些函数将其替换为我们自己的代码。

2 个答案:

答案 0 :(得分:3)

查看fList输出:这是运行myFile.m所需的MATLAB程序文件列表。遍历它们,对于每个,循环运行matlab.codetools.requiredFilesAndProducts,以找出代码库中每个文件所需的产品。这将帮助您缩小要关注的文件的范围。

您也可以尝试在代码上运行dependency report,这可能会为您提供一个更好的界面,供您探索哪些文件使用了哪个工具箱。

答案 1 :(得分:2)

这不是并非完全,并且使用了半文档功能getcalliinfo,但也许有帮助。

来自help getcallinfo

GETCALLINFO  Returns called functions and their first and last lines
    This function is unsupported and might change or be removed without
    notice in a future version.

考虑此示例函数,该函数使用多个工具箱并包含一个本地函数:

function y = example(x)
a = sinc(2);
b = example_local_function(pi);
c = @xcorr;
d = c([1 2 3], [4 5 6]);
y = imdilate(x,[1 1; 1 1]);
end

function z = example_local_fun(t)
z = t.^2 + exprnd(1);
end

将此功能保存到文件example.m并运行getcallinfo会得到

>> getcallinfo('example.m')
Name                 Type                 Starts Ends Length Full Name           
----                 ----                 ------ ---- ------ ---------           
example              function                1     7      7 example             
example_local_fun    subfunction             9    11      3 example>example_local_fun
ans = 
  1×2 struct array with fields:
    type
    name
    fullname
    functionPrefix
    calls
    firstline
    lastline
    linemask

结果是具有两个条目的结构数组:第一个条目用于主函数,第二个条目用于局部函数。观察第一项:

>> t(1)
ans = 
  struct with fields:

              type: [1×1 internal.matlab.codetools.reports.matlabType.Function]
              name: 'example'
          fullname: 'example'
    functionPrefix: 'example>'
             calls: [1×1 struct]
         firstline: 1
          lastline: 7
          linemask: [11×1 logical]

被调用的函数在

>> t(1).calls
ans = 
  struct with fields:

      fcnCalls: [1×1 struct]
    innerCalls: [1×1 struct]
      dotCalls: [1×1 struct]
       atCalls: [1×1 struct]

具体来说,在这种情况下,只有两个非空结构是

>> t(1).calls.fcnCalls
ans = 
  struct with fields:    
    names: {'sinc'  'example_local_function'  'pi'  'imdilate'}
    lines: [2 3 3 6]

>> t(1).calls.atCalls
ans = 
  struct with fields:    
    names: {'xcorr'}
    lines: 4

要查看被调用函数的定义位置,可以将which应用于字段names中包含的单元格数组中的每个单元格:

C:\Program Files\MATLAB\R2018b\toolbox\signal\signal\sinc.m
'example_local_function' not found.
built-in (C:\Program Files\MATLAB\R2018b\toolbox\matlab\elmat\pi)
C:\Program Files\MATLAB\R2018b\toolbox\images\images\imdilate.m

要自动化该过程,您需要知道工具箱文件夹的名称(从Matlab安装中很容易看到)。例如,对于图像处理工具箱,它是'images'(或者您可能更喜欢使用完整路径来避免误报):

>> s = cellfun(@which, t(1).calls.fcnCalls.names, 'UniformOutput', false);
>> ind = ~cellfun(@isempty, regexp(s, 'images', 'once'));
>> t(1).calls.fcnCalls.names(ind)
>> t(1).calls.fcnCalls.names(ind)
ans =
  1×1 cell array
    {'imdilate'}

其他工具箱的过程相同。例如,信号处理工具箱的文件夹称为'signals'

>> s = cellfun(@which, t(1).calls.fcnCalls.names, 'UniformOutput', false);
>> ind = ~cellfun(@isempty, regexp(s, 'signal', 'once'));
>> t(1).calls.fcnCalls.names(ind)
ans =
  1×1 cell array
    {'sinc'}

类似地,对于其他类型的通话:

>> s = cellfun(@which, t(1).calls.atCalls.names, 'UniformOutput', false);
>> ind = ~cellfun(@isempty, regexp(s, 'signal', 'once'));
>> t(1).calls.atCalls.names(ind)
ans =
  1×1 cell array
    {'xcorr'}

或者对于本地功能:

>> s = cellfun(@which, t(2).calls.fcnCalls.names, 'UniformOutput', false)
>> ind = ~cellfun(@isempty, regexp(s, 'stats', 'once'));
>> t(2).calls.fcnCalls.names(ind)
ans =
  1×1 cell array
    {'exprnd'}