Input a function to a function function without using @ in front of the input

7 views (last 30 days)
I'm currently building a home-made numerical integration function that uses Simpson's rule to find the integral of an input function f, specified by the user, inside a given interval. While my function works fine, when I call it in the command line I have to use @f for the input function, for example:
MySimpson(@sin,0,pi)
I want to get rid of the need for the user to enter the @ symbol, and to also keep the function general, so that the user simply has to enter
MySimpson(sin,0,pi)
or
MySimpson(cos,-pi/2,pi/2)
or even
MySimpson(x.^2+3*x-1,-2,5)
However, I can't find a way to do this without getting input errors. I have tried using
fun=@(x) f(x);
and similar as well as feval, but so far cannot make this work. Any ideas?
I am using MATLAB R2017b.
Thanks in advance.
  2 Comments
Stephen23
Stephen23 on 5 Mar 2018
Edited: Stephen23 on 5 Mar 2018
"Any ideas?"
Well, that is how MATLAB works. You can either spend a huge amount of time creating some awkward hack that might do what you want, or you can simply write that one character and do better things with your time.
All programming languages have a specific syntax that the users are required to use, and it just so happens that to create a function handle in MATLAB one uses @. Is that so difficult for your users? It does not seem particularly onerous.
I promise you one thing: the solution using a standard function handle defined using @ is going to be the simplest, neatest, most efficient, easiest to debug, and waste less of your time than anything else. Even feval with a string is more complex, slower, and basically deprecated because handles are the best way to store functions (because that is specifically what they are designed for).
Oliver Bradley
Oliver Bradley on 5 Mar 2018
I was just wondering if there was another way to do it, I'm very new to MATLAB and this is an assessed piece of work so I didn't know if there is some obvious way to do it that I was unaware of. If not then I'll just comment on it in my script. Thanks for your help.

Sign in to comment.

Answers (1)

Benjamin Kraus
Benjamin Kraus on 5 Mar 2018
There is no obvious way to do this. There are a lot of ways you could attempt to sort of make this work, but they would not be simple to program, and because they would work differently than the rest of MATLAB they would not be intuitive for users (who are more familiar with MATLAB) to use.
Take this example you provided:
MySimpson(sin,0,pi)
MATLAB needs to convert the three characters 'sin' into something that can be passed as input to MySimpson. Because it identifies that sin is a function, MATLAB will first try to execute the sin function with no input arguments, which will error.
So, you need a way to tell MATLAB not to execute sin, but rather to pass the characters 'sin' into the function. You can do that by adding quotes:
MySimpson('sin',0,pi)
You could certainly do this, and some older MATLAB functions do this and support this syntax, but it is easier to just add @. In addition, passing a character vector means that now your function needs to read in 'sin' and convert it to a function which can be executed. There are ways to do this (such as str2func), but while that will work with sin, it won't work with x.^2+3*x-1. For that, you would need to call eval. However, determining which one (either str2func or eval) is not trivial, and you've already made the code quite complicated. It gets more complicated when you consider the user may have specified y.^2+3*y-1 (using y instead of x), but how would you know?
These are some of the reasons that function handles exist. It is probably not work the effort to work around them.
  1 Comment
Walter Roberson
Walter Roberson on 5 Mar 2018
eval() is not needed for x.^2+3*x-1:
S = 'x.^2+3*x-1';
fcn = str2func( ['@(', strjoin(symvar(S), ','), ') ' S]);
You can extend this to detect the presence of characters that cannot appear in identifiers to try to figure out whether you have a case like 'sin' where a function is named or a case where an expression has been given. However, there is an inherent ambiguity: if the user were to specify 'x' then is that an attempt to specify a function named x or is an attempt to specify the variable x equivalent to if the user had specified 'x+0' which is obviously an expression. Perhaps when the user specified 'sin' they did not intend to invoke the function named sin and instead intended to apply MySimpson to the scalar variable that happens to be named sin, equivalent to sin+0

Sign in to comment.

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!