where do I use the toolboxes?

Viewed 96

I'm working on a scientific application which is now over 10 years in development by multiple people.

Recently, we found out that our application requires multiple toolboxes, which are not part of the default MATLAB installation. Since we are developing it with a University license, we have access to all toolboxes and therefore we never noticed this so far. However, we want to reduce the number of toolboxes to a minimum to make it easier and cheaper for other groups to use our software.

when I run

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

pList list a couple of toolboxes like:

 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

I'm sure that at least 'Finacial Toolbox' and 'Aerospace Toolbox' are not really required and we only use it through copy-pasting of online solutions into our software without thinking.

For example, we are using a function called degrees2dms which is part of a toolbox and simply converts decimal degrees into degrees, minutes and seconds. This could easily be implemented by our self without the use of additional toolboxes.

My question is now the following:

I know which toolboxes are used from matlab.codetools.requiredFilesAndProducts. How can I find out which functions from these toolboxes are used to replace those functions with our own code.

2 Answers

Go through the fList output: it's the list of your own MATLAB program files required to run myFile.m. Loop through them and for each one, run matlab.codetools.requiredFilesAndProducts to find out which product(s) is/are required for each file in the code base. That will help you to narrow down which files to focus on.

You can also try to run the dependency report on your code, that might provide a nicer interface for you to explore which file(s) use which toolbox(es).

This is not totally automatic, and uses the semi-documented function getcalliinfo, but perhaps it may help.

From 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.

Consider this example function, which uses several toolboxes and contains a local function:

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

Saving this function to file example.m and running getcallinfo gives

>> 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

The result is a struct array with two entries: the first for the main function and the second for the local function. Observe the first entry:

>> 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]

The called functions are in

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

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

Specifically, in this case the only two non-empty structs are

>> 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

To see where the called functions are defined you can apply which to each of the cells in the cell array contained in the field 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

To automate the process you need to know the name of the toolbox folder (this is easily seen from your Matlab installation). For example, it is 'images' for the Image Processing Toolbox (or you may prefer to use the full path to avoid false positives):

>> 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'}

The procedure is the same for other toolboxes. For example, the folder of the Signal Processing Toolbox is called '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'}

Similarly, for other types of calls:

>> 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'}

Or for the local function:

>> 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'}
Related