How to make a copy of a built-in function and get it to work?
Show older comments
I would like to change a built-in function of MATLAB, the histfit function. The problem is this function always give me the same number of points, which is 100, on the fitted curve. I want to change it so that I can specify the number of points on my own. I know I can't make any change on a built-in function, therefore I tried to make a copy of the histfit file, with different file name of course. But when I tried to use it it doesn't work saying
"Undefined function 'dfgetdistributions' for input arguments of type 'char'".
I know this must have to do with the built-in nature of histfit function. But is there still other ways to get around this? Seriously I wonder why MATLAB didn't give the user freedom to set the number of points in histfit on their own, it's really getting on my nerves.
8 Comments
Imam
on 1 Sep 2014
Adam
on 1 Sep 2014
I had no problem creating a copy of the file with a different name and running that.
Imam
on 1 Sep 2014
dpb
on 1 Sep 2014
Hmmmm....the function dfgetdistributions is in the private subdirectory to the stats subdirectory which contains histfit. Hence, unless your revised function is in the same directory it won't be able to find these helper functions.
While it's not recommended practice in general, I've been know to make such modifications in the actual routines on occasion...
Imam
on 1 Sep 2014
Adam
on 1 Sep 2014
I just saved a copy of histfit in my local directory and ran it to check it did the same as the builtin, but I didn't go as far as editing it.
I'd be hesitant about messing around with adding things to the folder structure of a builtin toolbox or mass-copying its folders elsewhere.
However, if you put your version of the function in the same folder as the builtin histfit function then it should itself be able to access the same private functions as the builtin whilst also being able to be called from anywhere just like the builtin since the toolbox is on your path.
Answers (4)
Guillaume
on 1 Sep 2014
1 vote
Most likely (I don't have the stat toolbox), dfgetdistributions is a function in a subfolder called private in the same folder as histfit. Thus it is a private function not visible to files outside the stat toolbox.
You could copy dfgetdistributions and all the other files that it call within that private folder but you may be going down a rabbit hole.
Could you not just:
- Use hist to build your histogram,
- Get the fit parameters for whatever fit you're using (e.g. normfit),
- Use normal plot to plot that curve?
3 Comments
Guillaume
on 1 Sep 2014
Another option, rather than trying to put your new function in the matlab folder (which is a very bad idea) is to copy the content of dfgetdistributions as a private function with your new histfit file. Thus, you would have in myhistfit.m:
function [varargout] = myhistfit(varargin)
%your modified histfit
%...
end
function [out] = dfgetdistributions(in1, in2)
%copied from dfgetdistributions.m but now in the same file as myhistfit
%...
end
function [out] = otherneededfunctioninprivate(in)
%...
end
Imam
on 1 Sep 2014
Guillaume
on 1 Sep 2014
There are two ways of defining private functions in matlab. You either put them in a folder called private (in which case, they're private to all files in the folder containing that private folder), or you put them at the end of your function file (in which case they're private to just that function).
So my suggestion was just to paste the whole of dfgetdistributions.m at the bottom of myhistfit.m.
Glad you've got it sorted anyway.
First, read
<http://www.mathworks.com/help/matlab/matlab_prog/private-functions.html>
on private functions and resolving calls to same...
It's not clear from your description of what you did, precisely, that didn't work with the revised function in the same subdirectory as the original but it had to be something other than resolution to the private function.
What I would really suggest is the better way is to copy the original to an appropriately-named subdirectory in your matlabpath, and making modifications there. Then, you do have to get the private helper functions needed to where they're also visible. The simplest way to do that is to create the @private private subdirectory under your new target directory and copy what is referenced from the main function therein. It does create a second copy, granted, but that's the price to be paid for making the modification to the copy of the original--somewhere it's got to have access to the required functions it calls.
Alternatively as another suggested but that is much more work and error-prone is to insert the source from the helper function into the main function m-file which also has the effect of limiting its scope to within the file, effectively making it private. The biggest problem with this is the likelihood there is more than just the one so it's potentially quite a lot of effort to do all the edits rather than simply making the copies.
In skimming the code, it looks like the most probable answer to your last question regarding that you were successful in using the modified function in another directory is that it appears the private function isn't called if you use the default syntax; iow, if you don't explicitly specify a distribution in the call there's no need for the distribution resolution so the private function isn't called--hence, in that case there's no resolution error.
BTW, histfit isn't really a "builtin" function; it's just an ordinary m-file that just happens to be in the Stats Toolbox. A 'builtin' function is one that is compiled source such as the basic operators and the like. To see the difference try
>> which histfit
C:\ML_R2012b\toolbox\stats\stats\histfit.m
>> which plus
built-in (C:\ML_R2012b\toolbox\matlab\ops\@single\plus) % single method
>>
Functions such as histfit are "distributed" functions, not "builtin". The key point is that there is no magic with the fact it is a component of the Statistics Toolbox that comes directly from TMW; its behavior with respect to resolution of being called and calling is absolutely no different than an m-file you write so this idea of it somehow being different is erroneous and you need to break that thought process.
You wrote in one of the previous comments "...is there a way to make my edited function to become just like a built-in function, that is I can call this function regardless my current active folder[?]"
The answer to that is "Yes, of course!" and there's nothing magic therein. Simply, as I suggested earlier, put your copy of the file in a subdirectory and then add that subdirectory to matlabpath. That's all that the toolboxes do to cause themselves to be resolvable from any location; it has nothing whatsoever to do with the fact they're distributed by TMW. Read the section on the more basic resolution of calling m-files at
ADDENDUM
Btw, I'd consider the point of this whole exercise a worthwhile enhancement request to submit to TMW at www.mathworks.com
ADDENDUM 2
On reflection, since the Stats Toolbox is in the matlabpath, fitdist would be resolved and if dfgetdistributions is called from within, it should also then be resolved as being within the @private subdirectory for it (this is what Adam alluded to above). In order for the private function to not be resolved, it would have to be called by something else not in the inherited scope. I didn't do a search for this path so not sure what conditions it would be under that the error did occur.
So, the upshot is, the first thing to do is to make the copy in a new subdirectory and place that in the search path. Don't mess with the private functions at all unless and until it becomes apparent there is another calling path that requires them which it doesn't seem there should be.
So, in the end, I'm also puzzled...
Imam
on 1 Sep 2014
0 votes
3 Comments
Adam
on 1 Sep 2014
I'm not sure why it didn't work first time to be honest. I have only glanced through the function in question, but the call to the function that caused the problem appears to be made from the
fitdist
function (though there may be other calls to it too). This function is also at the same level as histfit, not in one of the private folders so it can access the private folders as normal and any function or yours can call it just as you would any public builtin function (e.g. just like histfit itself).
Imam
on 1 Sep 2014
Adam
on 1 Sep 2014
Well, I'm not sure why it would be the source of the problem, it is just the source of the function call to that private function that caused your error the first time.
But I see no reason why it would have given that error the first time and very reason why it worked fine on your second try.
Stephen23
on 16 Sep 2014
0 votes
A bit late to the party, but one work-around would be to use the standard histfit function, and interpolate the 100 data points using spline or interp1 . I know that this doesn't address the issue directly, but sometimes sticking to the standard functions has other benefits (portability, no introduced bugs,...).
Categories
Find more on Half-Normal Distribution in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!