How to use str2func with a function handle in the string

Hi,
I want to insert a function handle in the input string of str2func but I get an error.
string1 = '@(x)sin(x)';
A = str2func(string1);
string2 = '@(x,y)(A(x) + sin(y))'
B = str2func(string2);
B(pi/2,pi/2)
It says: Undefined function or variable 'A'.
How can I fix it?
Thanks

 Réponse acceptée

"Workspace variables are not available to the str2func function."
See this answer. You could do something like this:
string1 = '@(x)sin(x)';
A = str2func(string1);
string2 = ['@(y)(' num2str(feval(A,pi/2)) ' + sin(y))'];
B = str2func(string2);
B(pi/2)

6 commentaires

Thanks Tommy,
yes, I was having a look about the workspace issue.
But how to keep both variables in B: B(x,y)?
dario
dario le 29 Mai 2020
Modifié(e) : dario le 29 Mai 2020
string1 = '@(x)sin(x)';
A = str2func(string1);
A = func2str(A)
A = A(5:end);
string2 = ['@(x,y)(', A, '+ sin(y))']
B = str2func(string2);
B(pi/2,pi/2)
Not sure if there is anything neater and it still does not allow me to use a function handle defined in the main worksapce.
That was going to be my suggestion, although using strfind to find the relevant part of A rather than assuming there is only a single character of input arguments:
string1 = '@(x)sin(x)';
idx = strfind(string1, ')');
string2 = ['@(x,y)(' string1(idx+1:end) ' + sin(y))'];
B = str2func(string2);
B(pi/2,pi/2)
Either way, I think you might only have the two options: (1) evaluate the function before constructing B (like in my original answer) or (2) trim A to just the executable part (like in our comments). There may be some other way, but I can't think of it off the top of my head.
Can you explain what you mean by "it still does not allow me to use a function handle defined in the main workspace"?
Thanks.
I mean that I'd prefer to work directly on the handle instead of retreiving the original function.
I'll leave it as not answered for now in case someone has a better idea.
Gotcha. There's always eval...
string1 = '@(x)sin(x)';
A = str2func(string1);
string2 = '@(x,y)(A(x) + sin(y))';
B = eval(string2);
B(pi/2,pi/2)
I guess I ignore eval by default, but it definitely works here. I would still recommend either of the previous answers.
Or here's a somewhat interesting possibility:
string1 = '@(x)sin(x)';
A = str2func(string1);
string2 = @(x) (['@(y)(' num2str(feval(A,x)) ' + sin(y))']);
B = @(x,y) feval(str2func(string2(x)), y);
B(pi/2, pi/2)
Maybe it can be simplified.
Good idea, I'm curious!
Thanks for your support

Connectez-vous pour commenter.

Plus de réponses (0)

Produits

Version

R2019a

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by