Problem using str2func for creating a function handle
조회 수: 4 (최근 30일)
이전 댓글 표시
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
Stephen23
2022년 1월 1일
This is just a very indirect and inefficient approach to parameterize a function. Simpler and more efficient:
채택된 답변
Walter Roberson
2014년 1월 28일
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
Stephen23
2022년 1월 1일
편집: Stephen23
2022년 1월 1일
"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.
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!