如何安全地操作字符串形式的MATLAB匿名函数

如何安全地操作字符串形式的MATLAB匿名函数,matlab,anonymous-function,complex-numbers,Matlab,Anonymous Function,Complex Numbers,我有一个匿名函数,我想以字符串形式操作它,然后与fsolve一起使用。 执行此操作时,匿名函数中对常量的引用将丢失,并且fsolve将失败 这个问题很容易说明 以下工作: A=3; myfun=@(x)sin(A*x); x = fsolve(@(x)myfun(x),[1 4],optimoptions('fsolve','Display','off')) 如下所述,抛出一个错误: 在保留对常量参数的引用的同时,是否有某种方法可以安全地操作匿名函数 更多信息 具体来说,我正在编写一个简单的包

我有一个匿名函数,我想以字符串形式操作它,然后与fsolve一起使用。 执行此操作时,匿名函数中对常量的引用将丢失,并且fsolve将失败

这个问题很容易说明

以下工作:

A=3;
myfun=@(x)sin(A*x);
x = fsolve(@(x)myfun(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);
致:


再次强调使用<代码> EVA/COD>,因此您应该考虑函数定义的这种字符串操作的替代方案。

我最初建议使用符号数学工具箱,但是再次阅读您的问题,我意识到这只是一个简单的替换输入参数。您可以使用函数句柄实现这一点,而无需任何字符串处理

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)

您有权访问符号数学工具箱吗?解决这个问题,它将是一个更好的工具。当匿名函数包含没有封闭形式解的问题的数值解时,符号数学工具箱是不相关的。我不打算使用符号解算器,而是使用符号工具箱(尤其是
subs
)可能非常有帮助。这是如何回答问题的?我在回答海报的第一个示例(该示例定义了
mystring
,并尝试使用
myfun2=str2func(mystring)
)并假设他/她能够推断第二个示例。我将编辑我的答案,以明确说明第二个示例。Nice。还值得一提的是,如果您想从匿名函数(实际上是任何函数)中检索参数,您可以使用
函数
er。。。功能。哇,太简单了!很好。我想这个故事的寓意是-不要使用字符串运算符修改匿名函数->使用匿名函数修改匿名函数。这些操作的一个重要警告是要非常清楚每个匿名函数的范围。ie在我的例子中,我需要确保我通过包装器传递了任何额外的参数,否则它们就失去了作用域。例如,ie wrapper=@(x,f,A)([real(f(x(1)+x(2)*i),A),imag(f(x(1)+x(2)*i),A)]。
fc=eval(f3);
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)