How to make a copy of a built-in function and get it to work?
12 views (last 30 days)
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
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
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
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.
dpb
on 1 Sep 2014
Edited: dpb
on 1 Sep 2014
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...
0 Comments
Imam
on 1 Sep 2014
3 Comments
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
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,...).
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!