Pattern from 1997: using feval
In the early 1990s, to avoid eval and all of its quirks (if you don't know about this, DON'T look it up - it's totally discouraged), we recommended using feval for evaluating functions that might not be known until supplied by the user running the code. We used this, for example, for evaluating numeric integrals. We wanted to leave the integrand completely flexible and up to the user. Yet the integrator had to be able to evaluate the user function, an unknown at the time of creating the integrator.
function I=integ(fcn,fmin,fmax,tol)
if ~ischar(fcn)
error(...)
end
% figure out some initial points to evaluate
pts = linspace(fmin, fmax, 20);
fv = feval(fcn,pts);
I = ...
:
end
This had the advantage of not asking MATLAB to "poof" any variables into the workspace. It helped also avoid situations where there was a possibility of a function and variable having the same name, thereby possibly not giving you the version of the name you expected. The way you used feval at that time was generally via a character array identifying the function to be called.
I am only considering the use of feval in the context of characters or strings in MATLAB, and not for some of the more specialized versions such as working with GPUs.
You would call the integration function like this.
area = integ('myfun', 0, pi);
Today, with function handles, we can bypass using feval and use the function handle directly.
function I=integ(fcn,fmin,fmax,tol)
if ~isa(fcn, 'function_handle')
% might still be nice to allow chars for backward compatiblity- but not be permissive about allowing new "strings".
% if ~isa(fcn, 'function_handle') || ~ischar(fcn)
error(...)
end
% figure out some initial points to evaluate
pts = linspace(fmin, fmax, 20);
fv = fcn(pts);
I = ...
:
end
Call it like this.
area = integ(@myfun, 0, pi);
This is useful for at least a couple of reasons:
- It is generally faster, if only by a bit, because there is one less indirection of function calls.
- It evaluates the function for the handle you supply - and can't get confused about other possible name conflicts as a result. Inside the integrator, we have complete control about the name of the function (called fcn in the code) and since it's a function handle, it can't conflict with anything else we may have around in the function or environment.
Thoughts
I know we use feval for some cases of working with GPUs, but I can't think of any typical MATLAB case where I still need to use feval instead of directly applying the function. Do you still use feval, perhaps where it's no longer needed? Let us know here.
Copyright 2022 The MathWorks, Inc.
- Category:
- Best Practice,
- History,
- How To