Some Ways to Create Function Handles
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); end
First 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) end
f = 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); end
If 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); end
Your Preferences?
I've told you my preferences. What are yours for creating function handles? Let me know.