I have been reading someone else's matlab code and I don't know how the code structured. I mean I would like to know the hierarchy of functions, which function uses which function. I am reading the code to figure that out but its taking a lot of time.
So is there any other way I can see this hierarchy without reading the whole thing? To be honest it is starting to get confusing. Maybe MatLab has a built in function for that! I found this:
How can I generate a list of function dependencies in MATLAB?
but this doesn't seem to be helpful!
The MATLAB profiler will show you what functions are called by your code (and much more information to boot) and allow you to click through the hierarchy of function calls. You can either call profile on and then run your code, then call profile off and profile viewer, or you can simply call profile viewer and type a single line of code to run in the edit box at the top.
Use the dependency report provided in MATLAB:
http://www.mathworks.co.uk/help/matlab/matlab_prog/identify-dependencies.html
There are also some tools on the File Exchange, such as fdep.
No idea about a function to show visible or depended-upon functions. However the basic rules are:
1) Only the first function in a .m file (normally has to have the same name as the file itself) is visible outside that file.
2) Any function can see any top level (see 1.) function if the file is in the matlab path. Matlab can show you the path so you know where it's hunting.
3) The order of the path is important, the first instance of a function called foo found in the path will be called. Obviously the current directory is at the top of the path.
3) All functions in a given file can see all other functions in that file.
That's the basics. No doubt there are other rules, and possibly exceptions to this. But that understanding generally serves me well.
Obviously the easiest way to work out which function is being called is to click on it in the editor and open it.
One thing I do is simply place in each function at the beginning fprintf("inside function <name>/n"); and at the end of the function fprintf("leaving function <name>/n"); where <name> is the name of the function.
This will give you a very specific list of which function is being called by which function (based on the order that they appear). Another thing like this would be to place fprintf("function <name1> calling function <name2>/n"); so you can be more explicit about which function is being called by which one.
Related
I am having a problem with the findpeaks function, this function is in the signal processing toolbox and also the program has another version of it (user defined function). I need to call the on in the signal processing toolbox not the user defined one, also I can't rename the user defined function for many reasons. Can anyone help me in calling the toolbox function.
The precedence order used by MATLAB is described in their help pages. It states that functions in the current folder (9.) are preferred over functions elsewhere in the path (10.). Then, the first appearance of the function in the path is chosen. This allows for a number of possible solutions:
1. cd to folder
A very simple method is simply to change the current workspace directory to the folder of the function you need to call, i.e. cd either to the place where your user-defined function is, or cd to the toolbox path. Note: This is rather inelegant, but probably sometimes the simplest solution.
2. Reorder path
As mentioned, MATLAB choses the first occurence of the function in the path. You can thus re-sort the path variable, so the folder where your user-defined function is, appears last. The path variable can be viewed and manipulated using the path function. Note: Then you can only call the toolbox function. Otherwise you'd have to resort the path again.
3. Function handles
If you need to be able to call both functions, it can be useful to create a function handle for both versions. For that, you have to cd into the folders where the functions are defined and create a new handle there:
cd('path/to/userdefined/function')
userFindPeaks = #findpeaks;
cd('path/to/MATLAB/installation/toolbox/signal/signal')
toolboxFindPeaks = #findpeaks;
You can then call the functions using feval.
Of course, as Adriaan mentions in the comments, it is best not to use the names of already defined functions for your own functions or for variable names.
I just came here looking for the same thing... I ended up using builtin.
https://uk.mathworks.com/help/matlab/ref/builtin.html
[y1,...,yn] = builtin(function,x1,...,xn)
#arr_sea actually posted a link in one of the folded comments which uses this function in a different context.
mapminmax is a builtin Matlab function. I am trying to implement something that does autocomplete for functions/subfunctions like this.
I've done a quick search but haven't really come up with what it's called. mapminmax is the only function I know of that implements this feature. It looks like a field of a function (like how a field of a struct).
I've used edit mapminmax to see the insides of Matlab's function but I haven't found anything leading to how this is possible. getParamStructFromArgs looks like it might be able to explain what this is, but it looks like it's related to NNs.
Question: What is this feature called and is there any documentation on this?
Looks like what #hypfco said was right. This "feature" is related to Matlab's package system. I'm sure there's a way to do it by creating a package, but for those who don't want to create such a package there's a simple way of doing this.
If you have a function such as untitled.m, you can create a folder called +untitled in your Matlab directory.
Function's .m file
+Function folder
Then when you do untitled. and press tab in the console, you'll get the following pop-up.
If anyone's got a way to do this inside the .m file, I'll accept that answer instead.
What do I want?
I am looking for a way to detect all points in my code where a specific function is called.
Why do I want it?
Some examples:
Some output comes out sorted or randomized, and I want to know where this happens
I am considering to change/overload a function and want to know in which part of my code this could have impact
What have I tried?
I tried placing a breakpoint in the file that was called. This only works for non builtin functions which are called from short running code that always executes everything.
I tried 'find files', this way I can easily find direct calls to sort but it is not so easy to find a call to sort invoked by unique for example.
I have tried depfun, it tells me:
whether something will be called
from where non-builtin functions will be called
I thought of overloading the builtin function, but feels like a last resort for me as I am afraid to make a mess. | Edit: Also it probably won't help due to function precedence.
The question
What is the best way to track all potential (in)direct function calls from a specific function to a specific (built-in)function.
I don't exactly understand your use case, but I guess most of the information you want can be obtained using dbstack, which gives you the call-stack of all the parent functions calling a certain function. I think the easiest way is to overload built-in functions something like this (I tried to overload min):
function varargout = min(varargin)
% print info before function call
disp('Wrapped function called with inputs:')
disp(varargin)
[stack,I] = dbstack();
disp('Call stack:')
for i=1:length(stack)
fprintf('level %i: called from line %i in file %s\n', ...
i, stack(i).line, stack(i).file);
end
% call original function
[varargout{1:nargout}] = builtin('min', varargin{:});
% print info after function call
disp('Result of wrapped function:')
disp(varargout)
I tried to test this, but I could not make it work unfortunately, matlab keeps on using the original function, even after playing a lot with addpath. Not sure what I did wrong there, but I hope this gets you started ...
Built-in functions take precedence over functions in local folder or in path. There are two ways you can overload a built-in for direct calls from your own code. By putting your function in a private folder under the same directory where your other MATLAB functions are. This is easier if you are not already using private folder. You can rename your private folder once you are done investigating.
Another way is to use packages and importing them. You put all your override functions in a folder (e.g. +do_not_use). Then in the function where you suspect built-in calls are made add the line "import do_not_use.*;". This will make calls go to the functions in +do_not_use directory first. Once you are done checking you can use "clear import" to clear all imports. This is not easy to use if you have too many functions and do not know in which function you need to add import.
In addition to this, for each of the function you need to follow Bas Swinckels answer for the function body.
Function precedence order.
Those two methods does not work for indirect calls which are not from your own code. For indirect calls I can only think of one way where you create your own class based on built-in type. For example, if you work only on double precision types, you need to create your own class which inherits from double and override the methods you want to detect. Then pass this class as input to your code. Your code should work fine (assuming you are not using class(x) to decide code paths) since the new class should behave like a double data type. This option will not work if your output data is not created from your input data. See subclassing built-in types.
Did you try depfun?
The doc shows results similar to the ones you request.
doc depfun:
...
[list, builtins, classes, prob_files, prob_sym, eval_strings, called_from, java_classes] = depfun('fun') creates additional cell arrays or structure arrays containing information about any problems with the depfun search and about where the functions in list are invoked. The additional outputs are ...
Looks to me you could just filter the results for your function.
Though need to warn you - usually it takes forever to analyze code.
Somehow my Matlab does not has the function nanvar_base, needed to use the function ttest2 to calculate the t and p value of two sample data. How do I install that function? Is it missing to anyone else?
I had this same issue, the ttest2 function calling a nanvar function from SPM rather than the MATLAB statistics folder. A simple fix is going into 'change paths' in MATLAB and moving the SPM paths to the bottom of the list.
The function ttest2 is part of the statistics toolbox.
However, when I try to edit it, it does not show any calls to nanvar_base.
Did you perhaps try to edit it yourself, and in the process made a mistake? If this is not the case, try edit ttest2 and see where it is located and show the line with the call to nanvar_base.
This function isn't part of MATLAB or any of its toolboxes/add-ons. It must be custom functions. There is a function call nanvar however, in the Statistics toolbox and also in the Financial toolbox. Is this maybe the one you're after? If so, do you actually have the Statistics Toolbox and/or the Financial Toolbox?
the problem is probably another toolbox (like SPM) getting in the way, with their own 'nanvar' function.
Move SPM to the bottom of the path definition list, or remove it completely.
In general moving SPM have a lot of conflicting functions, so always make sure their path is at the bottom.
I had the same issue when calling the function nanvar, and realised that there was a conflict with a function with the same name in the Fieldtrip toolbox (this Fieldtrip function calls nanvar_base). After removing the Fieldtrip/src folder from my paths, it worked fine.
Let us say that I have a Matlab function and I change its signature (i.e. add parameter). As Matlab does not 'compile' is there an easy way to determine which other functions do not use the right signature (i.e. submits the additional parameter). I do not want to determine this at runtime (i.e. get an error message) or have to do text searches. Hope this makes sense. Any feedback would be very much appreciated. Many thanks.
If I understand you correctly, you want to change a function's signature and find all functions/scripts/classes that call it in the "old" way, and change it to the "new" way.
You also indicated you don't want to do it at runtime, or do text searches, but there is no way to detect "incorrect" calls at "parse-time", so I'm afraid these demands leave no option at all to detect old function calls...
What I would do in that case is temporarily add a few lines to the new function:
function myFunc(param1, param2, newParam) % <-- the NEW signature
if nargin == 2
clc, error('old call detected.'); end
and then run the main script/function/whatever in which this function resides. You'll get one error for each time something calls the function incorrectly, along with the error stack in the Matlab command window.
It is then a matter of clicking on the link in the bottom of the error stack, correct the function call, and repeat from the top until no more errors occur.
Don't forget to remove these lines when you're done, or better, replace the word error with warning just to capture anything that was missed.
Better yet: if you're on linux, a text search would be a matter of
$ grep -l 'myFunc(.*,.*); *.m'
which will list all the files having the "incorrect" call. That's not too difficult I'd say...You can probably do a similar thing with the standard windows search, but I can't test that right now.
This is more or less what the dependency report was invented for. Using that tool, you can find what functions/scripts call your altered function. Then it is just a question of manually inspecting every occurrence.
However, I'd advise to make your changes to the function signature such that backwards compatibility is maintained. You can do so by specifying default values for new parameters and/or issuing a warning in those scenarios. That way, your code will run, and you will get run-time hints of deprecated code (which is more or less a necessary evil in interpreted/dynamic languages).
For many dynamic languages (and MATLAB specifically) it is generally impossible to fully inspect the code without the interpreter executing the code. Just imagine the following piece of code:
x = magic(10);
In general, you'd say that the magic function is called. However, magic could map to a totally different function. This could be done in ways that are invisible to a static analysis tool (such as the dependency report): e.g. eval('magic = 1:100;');.
The only way is to go through your whole code base, either inspecting every occurrence manually (which can be found easily with a text search) or by running a test that fully covers your code base.
edit:
There is however a way to access intermediate outputs of the MATLAB parser. This can be accessed using the undocumented and unsupported mtree function (which can be called like this: t = mtree(file, '-file'); for every file in your code base). Using the resulting structure you might be able to find calls with a certain amount of parameters.