I recently was asked the best way to create function handles, given the names of functions. This came up because I recommended that we should generally remove instances of feval in our code since it is often not required and adds an extra level of function calls. I will show you several ways to work with a "list" of functions and tell you which ones I prefer and why.
Contents
Avoiding Function Handles Altogether (Not Recommended)
As I said above, I recommend not using feval because it introduces extra function call overhead, and is usually unnecessary. In addition, code is generally more robust with function handles instead of strings for representing functions.
funcList = {'sin','cos','tan'};
for i=1:numel(funcList)
f = feval(funcList{i},1.0);
endFirst Alternative (Not Recommended)
Here's a method that constructs function handles from strings using eval, a function that has a deservedly bad reputation for most applications (see these two articles: Evading Eval and More on Eval).
funcList = {'sin','cos','tan'};
for i=1:numel(funcList)
func = eval(['@' funcList{i}]);
f = func(1.0)
endf =
0.8415
f =
0.5403
f =
1.5574
Acceptable Methods
If you have to start off with strings at all, such as having them passed in as arguments, you can convert them immediately to function handles and then proceed, by using str2func.
funcList = {'sin','cos','tan'};
for i= 1:numel(funcList)
fh = str2func(funcList{i});
f = fh(1.0);
endIf you have a fixed function list, simply create the function handles to start and use them. One way is to use feval and cellfun.
funcList = {@sin, @cos, @tan};
vals = repmat({1.0},size(funcList));
f = cellfun(@feval, funcList, vals);Best Method, When Possible
My favorite method, when I can choose to create function handles from the start, is to just iterate over the list. I find that more readable than the cellfun code and I get to avoid the extra feval call. The expense comes at the for-loop. Preallocation when you plan to actually use the results (unlike these examples) often mitigates the downsides of the loop.
funcList = {@sin, @cos, @tan};
for i = 1:numel(funcList)
f = funcList{i}(1.0);
endYour Preferences?
I've told you my preferences. What are yours for creating function handles? Let me know.
Get
the MATLAB code
Published with MATLAB® 7.3



wouldn’t it be nice if STR2FUNC was (finally) able to also use absolute paths to functions outside the current ML search path… still yearning
us
Loren,
Thanks for discussing function handles some more.
However, I still can’t imagine how function handles are useful. This isn’t new for me. It appears that I’ve never had a problem to solve where function handles would be useful and I can’t imagine a problem where they would be useful.
And, when I say useful, I mean in order, 1. It allows easier to understand code. 2. It requires less code. 3. The resulting code runs faster.
On the other hand, I learned something very useful with this week’s column: “repmat” works on cell arrays. I’d never get this from the documentation.
Which brings up a chronic shortcoming of most MatLab function reference pages: They don’t include a list of allowed variable classes for inputs and outputs.
Like Urs, I also need to call functions from a subdirectory sometimes. The only way I found to do this is to put the whole subdirectory onto the Matlab path. But this is actually a bit nasty.
Oliver, I can tell you that there are situations where function handles are useful. I have been testing a Kalman filter with different state space model functions. Of course I could use a switch-case-statement at every place I use the model functions. But 1. this would be ugly and 2. when introducing a new model function, I would have to update every single switch-case-statement where the model functions are used.
Regards
Markus
Wouldn’t the following way of iterating over the list be preferred?
funcList = {@sin, @cos, @tan};
for func = funcList
func{:}(1.0)
end
Btw, any idea why non-scalar function handles won’t be supported in the future?
Daniel-
You could also use your for-loop instead of mine. Depends which one seems clearer to the person writing the code.
Non-scalar function handles won’t be supported because otherwise how can I tell what f(1) means? Does it mean get me the first function handle or does it mean evaluate f with the value 1? We don’t want people to have to write conditional code:
Forcing function handles to be scalar gets rid of the ambiguity.
–Loren
Loren,
Thanks for your article; it has clarified my mental model of Matlab functions quite a bit.
I haven’t been able to solve the problem that led me here, though. I would like to call a function without knowing the number of input or output arguments at compile time. To be concrete, say I have a function handle func, a cell array inputArgs, and an integer numReturnValues, and I would like to do something that has the same effect as
[returnValues{1:nReturnValues}] = fn(inputArgs{1}, …, inputArgs{length(inputArgs)})
This construct solves my problem for the output arguments, but I don’t see how to do something similar for the input arguments. Am I missing something?
Thanks,
Steve
Steve-
I am not sure what you are trying to do. Can you just use a cell array for the inputs and then use the comma-separated list syntax to input them?
inputs = {1 magic(3) 'fred'}; [outputs{1:nout}] = fh(inputs{:});Or is your problem with function definition? And would varargin help there?
fh = @(varargin) myNewFunc(a,b,varargin{:});–Loren
Loren,
I have a matlab script that creates an M-file in the current directory that contains the function myodefunc, then attempts to run ode15s on the function, e.g. ode15s(@myodefunc,…). If the M-file does not yet exist, the first time I run the script I get an error:
>> script
??? Error using ==> feval
Undefined command/function ‘myodefunc’.
So the file exists but the handle doesn’t work. Oddly, I can clear the workspace and re-run the script:
>> clear
>> script
Now, no errors are returned. Do functions whose handles are used in a script have to exist before the script is run, and is there a workaround? I can’t seem to find Matlab documentation on this fine point.
Great blog…thanks for all the tips!
–Raymond
Raymond-
In your script, you can try, after creating the M-file and before creating the function handle, doing something to force MATLAB to relook at the directory, something like “which myNewMFile” or exist(’myNewMFilem’,2) and then have the script proceed. During a M-File, MATLAB tries to not refresh/reaccess directory information so it doesn’t slow things down. However, then you can have the issue you are seeing.
Thanks for the kind words on the blog!
–Loren
I would like to use function handles to wrap (aka decorate or advise) an existing function. For example, I’d like to capture all calls to the builtin dialog() function, and make them blue. One way to do this is to save off a new dialog.m in my path (see below), and then adjust the path within that function.
Another method I tried was storing off a handle to the built in dialog, then adding the new function to the path. Both of these methods work, but not when compiled.
Is there a way to wrap an existing function more explicitly than with path tricks? What I’d really like to do is:
orig_dialog = @dialog;
dialog = @new_dialog;
But that doesn’t behave as one might hope.
Ray Jones
——————————–
function H = dialog(varargin)
% play path tricks to wrap an existing function.
found = 0;
for i = 1:2:length(varargin),
if strcmp(varargin{i}, ‘Color’),
varargin{i+1} = [0.7 0.7 0.9];
found = 1;
end
end
if ~ found,
varargin{end+1} = ‘Color’;
varargin{end+1} = [0.7 0.7 0.9];
end
oldpath = path;
rmpath nd
H = dialog(varargin{:});
path(oldpath)
Ray-
I can’t think of anything offhand. You might be able to accomplish this with some indirection using private functions and more than 1 file to control the scoping. But I am not sure.
I’m assuming you want to do this because you don’t control all the code with instances for calling dialog. If that’s so, I think you’re only choice is to replace the one that’s there now with one earlier on the path. Otherwise, if you need both, you should have the code control to be able to manage two names, I would have thought.
–Loren
You are my hero!
I’m a student and have been trying to do this for a bit and here is the answer in front of me.
One perhaps related question: is there a way in matlab to generate variable names automatically or have users input them?
for example: could I do something like:
xvariablename=input(’input the name of the x-variable:’,’s’);
and then actually use this to set the x-variable in my graph say through a string comparison of some sort?
e.g. if xvariablename=temperature
plot(temperature)
end
but without using if statements because i’ll have a ton if I do this…
thanks a bunch,
Zahra
PS: I liked your talk about nested funcs etc at MIT in January. I’d never heard of them before so it was really useful.
Also, would like to be able to do something like generate names of the sort:
temperature1, temperature2, temperature3 automatically…
can this be done?
Zahra-
We recommend against you naming variables using temp1, temp2, etc. Instead, either make a cell array for each instance or a structure with dynamic fieldnames. Here’s a link to the FAQ:
http://matlabwiki.mathworks.com/MATLAB_FAQ#How_can_I_create_variables_A1.2C_A2.2C….2CA10_in_a_loop.3F
–Loren
Hi, I’ve been using matlab 7.5.0 (R2007b) for some time. I’ve been unit testing using mlUnit. mlUnit’s unit test template has a function which basically finds all the nested functions in a unit test program and creates handles to those nested files using a call something like:
function unit_test()
h = load_tests_from_mfile
function test_this()
…
end
end
function fun_handle = load_tests_from_mfile(…)
…
fun_handle = evalin(’caller’, [’@() @test_this’]);
fun_handle = fun_handle();
…
(note this is not the code, but some pseudo code, see mlUnit for complete example)
This worked great since ‘caller’ was the unit_test program and the handle was @unit_test\test_this
However I’ve just switched to matlab 7.6.0 (R2008a). Now, the functionality of evalin has changed (I think). In this version, the handle generated is @test_this and is no longer nested. Obviously, when I go to use that nested handle, Matlab can’t find it.
Do you have any ideas as to how I might work around this?
thanks
-Matt
Matt-
I am unaware of any change to evalin and don’t use mlUnit. I recommend you make a very small test example and contact technical support.
–Loren
Hi Matt
“evalin(’caller’, [’@() @test_this’]);” is a useful trick that was never intended to work. It’s in conflict with the static workspace of nested functions. That’s my mental model anyhow.
I fear that most of the unit testing tools available for Matlab rely on this trick. If the trick doesn’t work with R2008a that’s too bad for those of us who rely on unit testing.
/per
My initial impression with the new OOP framework in R2008a is that it should eliminate the need for the “trickery” to build a unit testing framework in MATLAB.
Loren, per, StephenLL,
Thank you for your quick responses. From all the searching on the web I’ve been able to do, it seems like mUnit and mlUnit are the two most widely used unit test frameworks. I’ve been using mlUnit in nested function mode. This has the issue that I’ve pointed out. mUnit also uses that same “trickery”. I found that mlUnit’s class mode does not use that trickery (obviously). I’ve tested it in ML7.5 and ML7.6 and it seems to work. So I guess for now, my solution is to convert to mlUnit class mode.
If anyone has any other unit test frameworks they could suggest, I’d appreciate the input.
Thanks.
-Matt
I was the author of mUnit
http://xtargets.com/cms/Tutorials/Matlab-Programming/MUnit-Matlab-Unit-Testing.html
and the
“evalin(’caller’, [’@() @test_this’]);”
hack and it is a pity that it no longer works anymore. StephenLL is correct in that the new OOPs framework should make that sort of coding obsolete. However many hundreds of people have downloaded mUnit and many are probably still using it.
Unfortunately I don’t have the time to debug the changes to mUnit at the moment. However it is open source GPL code and if anybody can figure out a way to fix it and send me the patches I’ll repost the new installer here.
http://xtargets.com/downloads/
Perhapps somebody at Mathworks could suggest the fix to keep mUnit working. As Matt says mUnit is used by many people. Encouraging test driven development can only be a good thing :)
Regards
Brad
Matt and Brad-
The restriction to not create handles to nested functions via eval or evalin is intentional and it was a bug that slipped through that allowed that construct to work in the first place. eval and evalin were intended to allow access to the workspace only, i.e., variables.
–Loren
Hi Loren,
It’s unfortunate that a feature Mathworks were aware its customers were using was classified as a bug and eliminated. I and others had conversations with Mike Karr at least as far back as 2005 noting that this was an important feature and asking that it be regression tested to avoid accidental breakage in a new release. Obviously Mike could not promise anything but it’s unfortunate that Mathworks was unable to preserve this feature.
The full details of the evalin trick I shared with Mike was posted sometime in 2005 here.
http://www.xtargets.com/snippets/posts/show/42
However I have an idea for a partial fix. Will eval still work. As in
fh = eval(’@foo’)
if foo is defined in the same workspace. I could modify the mUnit code slightly if that worked? Can anybody confirm this as I don’t have 2008a yet to play with.
Regards
Brad
Hi Brad
It took me long to answere your question because of problems with activating R2008a at our school.
EVAL seems to work. See my little test below. However, we might want to ask The Mathworks whether it will still work with R2008b.
>> version
ans =
7.6.0.324 (R2008a)
>> test4munit
foo is called successfully
>>
function test4munit
fh = eval( ‘@foo’ );
fh();
function foo()
disp( ‘foo is called successfully’ )
end
end
Regards
Per
I repeat my earlier comment:
The restriction to not create handles to nested functions via eval or evalin is intentional and it was a bug that slipped through that allowed that construct to work in the first place. eval and evalin were intended to allow access to the workspace only, i.e., variables.
–Loren
If your use of eval is doing more than accessing a variable in the workspace, don’t count on that to continue working. I am not sure when the bug will be fixed, but it is a bug based on the intent of the design.
–Loren
Hi Loren,
Is there any way of generating a function handle from a sym function?
I have several symbolic calculations (integrals, etc) to generate some functions, and I need to minimize these functions by “fminbnd”.
In my MatLab version (2007b) I can’t use matlabFunction.
Regards,
Warody
Warody-
I am not aware of anything before R2008b as you say, matlabFunction.
–Loren
Is there a way of making a function handle to a class function?
methods function hei(obj) % make function handle to obj.hopp()??? end function hopp(obj,p) disp(p) end endI don’t know the function name on before hand. I just have a string.
Grunde-
Take a look at str2func. Also in your hei method, just create the function handle you want: fh = @hopp. When you call it with an object of the correct class, the method will get called.
–Loren
Thanks a lot.
Didn’t realize that I can call the function with fn(obj) instead of obj.fn().
I find function handles very useful. I use them when I want the code to be flexible. For instance if I want to parse some text with headers. When the parser finds a header ‘HEI’ with some corresponding data, it calls the function parseHEI with the data as argument. This makes the code flexible. Whenever I need a new header I just implement the parsheNEWHEADER function and the everything else is ready to go.
Are there maybe function handles that are “local” to an .m file?
Example, if I have
in file qwe1.m:
function qwe1() q.fh = @qwe; save('qwe1', 'q'); qq = load('qwe1'); qq.q.fh(); end function qwe() disp('qwe from qwe1 called') endand in file qwe2.m:
function qwe2() qq = load('qwe1'); qq.q.fh(); end function qwe() disp('qwe from qwe2 called') endThen in Matlab Version 7.5.0.342 (R2007b) I get
i.e. the function handle de-serialised in qwe2 “remembers” it points to (private) function qwe in qwe1, not qwe2.
I was wondering if it is possible to make the handle local to the source file? Like if a was saving ‘qwe’ as a string and used feval latter to call the (private) function qwe when running qwe2 I would have called the function qwe from qwe2. :-)
Not sure if I am explaining what I know well, here is an example,
in file qwe3.m:
function qwe3 q.fs = 'qwe'; save('qwe3', 'q'); qq = load('qwe3'); feval(qq.q.fs); end function qwe() disp('qwe from qwe3 called') endin file qwe4.m:
function qwe4() qq = load('qwe3'); feval(qq.q.fs); end function qwe() disp('qwe from qwe4 called') endNow when I run in Matlab
i.e. the 2nd call goes to the qwe function in file qwe4.m (while if this were a file handle would have gone to qwe in qwe3.m).
Thanks for you help,
Ljubomir Josifovski
Ljubomir-
You can’t make the function handle local to the file. If you pass a function handle pointing to one file’s subfunction, then that subfunction will be called regardless of where the function handle is passed and whether or not that new context has a function of the same name in its scope. To get that behavior you have to use the strings as you note.
–Loren
Thanks Loren. Since I wrote my post I discovered in the help the “functions” function, which spells out the info the handle contains.
Regards,
Ljubomir
Hi!
MATLAB R2009a corresponds an error ‘Nonscalar arrays of function handles are not allowed; use cell arrays instead’, but it was working before? Is there some common solution how should i change the script to get it working?
Thanks for answers in advance!
Veronika-
I recommend following the advice of the error message. Place them in a cell array. E.g.,
fh = { @sin, @cos}; x = 0:.01:1; ysin = fh{1}(x);–Loren
I’m strugling with the error message:
‘Nonscalar arrays of function handles are not allowed; use cell arrays instead’
as well… please help me out with this application.
This is a modified version of my code part of my code:
for j=1:10; for i=1:10; aprox(i,j)=schumaker(vv(:,i,j),nod,agrid); aprox2(i,j)=@(x) ppval(aprox(i,j),x); a(i,j)=agrid(1); b(i,j)= agrid(10); [policya(i,j),vvaprox(i,j)]=golden(aprox2(i,j),a(i,j),b(i,j)); end; end;where both schumaker and golden are two functions defined in separate m-files. When I used the command:
aprox2(i,j)=@(x) ppval(aprox(i,j),x);
I get an error message instead of a warning as I did with the older version of matlab… I can’t figure out how to fix this.
Thanks in advance!