如何以字符串形式安全地操作 MATLAB 匿名函数
How to safely manipulate MATLAB anonymous functions in string form
我有一个匿名函数,我想以字符串形式对其进行操作,然后与 fsolve 一起使用。
当我这样做时,匿名函数中对常量的引用丢失并且 fsolve 失败。
这个问题很容易说明。
以下作品:
A=3;
myfun=@(x)sin(A*x);
x = fsolve(@(x)myfun(x),[1 4],optimoptions('fsolve','Display','off'))
如解释的那样,以下抛出错误here:
A=3;
myfun=@(x)sin(A*x);
mystring=func2str(myfun);
%string operations would go here such as strrep(mystring,'A','A^2') or whatever
myfun2=str2func(mystring);
x = fsolve(@(x)myfun2(x),[1 4],optimoptions('fsolve','Display','off'))
有什么方法可以安全地操作匿名函数,同时保留对常量参数的引用?
更多信息
具体来说,我正在编写一个简单的包装器,以允许 fsolve 接受简单情况下的虚数。下面说明了一个 没有 常量参数的工作示例:
myeqn=@(x)0.5*x^2-5*x+14.5;
cX0=1+1*1i;
f1=strrep(func2str(myeqn),'@(x)','');
f2=strrep((f1),'x','(x(1)+(x(2))*1i)');
f3=strcat('@(x)[real(',f2,'); imag(',f2,')]');
fc=str2func(f3);
opts=optimoptions('fsolve','Display','off');
result=arrayfun(@(cinput)[1 1i]*(real(fsolve(fc,[real(cinput);imag(cinput)],opts))),cX0)
如上面的失败示例所示,如果我在我的包装器中包含一个参数,该过程将失败并出现与上面相同的错误。
尽管我不喜欢建议使用 eval
函数,但您可以这样做:
myfun2 = eval(mystring);
使用 eval
有点让人不悦,因为它使代码难以分析(因为该字符串中可能会出现任意乱七八糟的东西),但不要让其他人的编码风格阻止你做有效的事情:)
在您更长的示例中,这对应于更改行:
fc=str2func(f3);
至:
fc=eval(f3);
同样,强烈建议不要使用 eval
,因此您应该考虑替代这种函数定义的字符串操作。
我最初建议使用符号数学工具箱,但再次阅读你的问题我意识到这只是输入参数的简单替换。您可以使用函数句柄实现此目的而无需任何字符串处理。
myeqn=@(x)0.5*x^2-5*x+14.5;
cX0=1+1*1i;
wrapper=@(x,f)([real(f(x(1)+x(2)*i)),imag(f(x(1)+x(2)*i))])
opts=optimoptions('fsolve','Display','off');
result=arrayfun(@(cinput)[1 1i]*(real(fsolve(@(x)wrapper(x,myeqn),[real(cinput);imag(cinput)],opts))),cX0)
我有一个匿名函数,我想以字符串形式对其进行操作,然后与 fsolve 一起使用。 当我这样做时,匿名函数中对常量的引用丢失并且 fsolve 失败。
这个问题很容易说明。
以下作品:
A=3;
myfun=@(x)sin(A*x);
x = fsolve(@(x)myfun(x),[1 4],optimoptions('fsolve','Display','off'))
如解释的那样,以下抛出错误here:
A=3;
myfun=@(x)sin(A*x);
mystring=func2str(myfun);
%string operations would go here such as strrep(mystring,'A','A^2') or whatever
myfun2=str2func(mystring);
x = fsolve(@(x)myfun2(x),[1 4],optimoptions('fsolve','Display','off'))
有什么方法可以安全地操作匿名函数,同时保留对常量参数的引用?
更多信息
具体来说,我正在编写一个简单的包装器,以允许 fsolve 接受简单情况下的虚数。下面说明了一个 没有 常量参数的工作示例:
myeqn=@(x)0.5*x^2-5*x+14.5;
cX0=1+1*1i;
f1=strrep(func2str(myeqn),'@(x)','');
f2=strrep((f1),'x','(x(1)+(x(2))*1i)');
f3=strcat('@(x)[real(',f2,'); imag(',f2,')]');
fc=str2func(f3);
opts=optimoptions('fsolve','Display','off');
result=arrayfun(@(cinput)[1 1i]*(real(fsolve(fc,[real(cinput);imag(cinput)],opts))),cX0)
如上面的失败示例所示,如果我在我的包装器中包含一个参数,该过程将失败并出现与上面相同的错误。
尽管我不喜欢建议使用 eval
函数,但您可以这样做:
myfun2 = eval(mystring);
使用 eval
有点让人不悦,因为它使代码难以分析(因为该字符串中可能会出现任意乱七八糟的东西),但不要让其他人的编码风格阻止你做有效的事情:)
在您更长的示例中,这对应于更改行:
fc=str2func(f3);
至:
fc=eval(f3);
同样,强烈建议不要使用 eval
,因此您应该考虑替代这种函数定义的字符串操作。
我最初建议使用符号数学工具箱,但再次阅读你的问题我意识到这只是输入参数的简单替换。您可以使用函数句柄实现此目的而无需任何字符串处理。
myeqn=@(x)0.5*x^2-5*x+14.5;
cX0=1+1*1i;
wrapper=@(x,f)([real(f(x(1)+x(2)*i)),imag(f(x(1)+x(2)*i))])
opts=optimoptions('fsolve','Display','off');
result=arrayfun(@(cinput)[1 1i]*(real(fsolve(@(x)wrapper(x,myeqn),[real(cinput);imag(cinput)],opts))),cX0)