Problem using str2func for creating a function handle
4 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Pedro
el 28 de En. de 2014
Hello!
I have two functions:
%---------
function [ handle_res ] = handle_fun_creation_2( File_String,Type_identifier,Value )
if Type_identifier == 0
handle_res = str2func(['@' File_String]);
elseif Type_identifier == 1
handle_res = str2func(['@(t,y)' File_String '(t,y,Value)'] );
end
end
%-------------
and:
%-------------
function [ y ] = test_3( t,x,Var_opt )
y=x+Var_opt(1)+Var_opt(2);
end
%---------------
Could anyone explain me why the following code doesn't work:
%---------------------------
Var_opt = [30 40]';
[handle_4] = handle_fun_creation_2('test_3',1,Var_opt);
[t6,y6] = ode15s(handle_4,[0:1],0);
Undefined function or variable 'Value'.
Error in @(t,y)test_3(t,y,Value)
%---------
But this one does?
%---------
handle_5 = @(t,y)test_3(t,y,Var_opt);
[t7,y7] = ode15s(handle_5,[0:1],0);
I think I'm missing some detail on how str2func works maybe? Thanks in advance.
1 comentario
Stephen23
el 1 de En. de 2022
This is just a very indirect and inefficient approach to parameterize a function. Simpler and more efficient:
Respuesta aceptada
Walter Roberson
el 28 de En. de 2014
str2func() does not execute the content of any strings it is passed so it has no idea that the string 'Value' should relate to the parameter named Value.
if isnumeric(Value)
valstr = sprintf('%g', Value);
else
valstr = char(Value);
end
handle_res = str2func(sprintf('@(t,y)%s(t,y,%s)', File_String, valstr));
4 comentarios
Stephen23
el 1 de En. de 2022
Editada: Stephen23
el 1 de En. de 2022
"Although I'm not sure about this code's efficiency, it works"
It is not efficient, nor does it work as you think it does.
For example, although you pass the input argument Value to handle_fun_creation_2 it remains totally unused, it is only when you later EVAL the string in the caller workspace that MATLAB will look for a function or variable named Value. You can easily test this by calling handle_fun_creation_2 with complete nonsense for the third input argument and everything will work (as long as the correct Value is defined in the caller workspace!):
sprint_4 = handle_fun_creation_2('test_3',1,{'hello world'}) % 3rd arg = silly cell array
Value = [pi,2/3]; % <----------- must be defined in the calling workspace...
handle_4 = eval(sprint_4) % <--- because this is actually where Value is included.
[t6,y6] = ode15s(handle_4,0:1,0); % no errors
If Value is not defined in the caller workspace then your code will not work, it will throw an error about Value being undefined (see bottom of this comment). It is clear that my silly Hello World cell array actually does nothing.
But this just seems to be a very indirect and inefficient approach to parameterize a function:
As the documentation shows, a much simpler and more efficient approach is to use an anonymous function:
fn1 = @(x,y)test_3(x,y,Value);
[t7,y7] = ode15s(fn1,0:1,0);
isequal(t6,t7)
isequal(y6,y7)
and if the function name really is provided as text (suboptimal design, but still simpler and more direct than a special "creation" function returning a string and evaluating it to get a function handle):
fns = 'test_3';
fn2 = str2func(fns);
fn3 = @(x,y)fn2(x,y,Value);
[t8,y8] = ode15s(fn3,0:1,0);
isequal(t6,t8)
isequal(y6,y8)
And finally, lets try your code when Value is not defined in the caller workspace:
clearvars Value
handle_4 = eval(sprint_4) % looks the same... but is it?
[t6,y6] = ode15s(handle_4,0:1,0); % nope.
Más respuestas (0)
Ver también
Categorías
Más información sobre Loops and Conditional Statements en Help Center y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!