【问题标题】:where do I use the toolboxes?我在哪里使用工具箱?
【发布时间】:2019-06-18 00:32:04
【问题描述】:

我正在开发一个科学应用程序,该应用程序现已由多人开发超过 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 知道使用了哪些工具箱。如何找出这些工具箱中的哪些函数用于用我们自己的代码替换这些函数。

【问题讨论】:

    标签: matlab dependencies


    【解决方案1】:

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

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

    【讨论】:

    • 这是个好主意,当然有助于缩小问题范围。但是,我希望有一个替代方案,因为我们的一些函数有 1000 行长......
    • 依赖报告将告诉您代码库中的每个文件调用每个工具箱中的哪个文件/函数。然后,您可以在文本编辑器中搜索该功能并将其替换为不需要工具箱的功能
    • 是的,依赖报告可以解决问题。这有点费时间,因为有很多不同的文件夹,但我想我可以管理它。
    【解决方案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'}
    

    其他工具箱的过程相同。比如Signal Processing Toolbox的文件夹叫'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'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 2016-03-20
      相关资源
      最近更新 更多