我有一个多变量的符号表达式
c = x^2 +y^2 + z^2
使用matlabFunction(c)返回
ans = @(x,y,z)x.^2+y.^2+z.^2
我无法将其输入到fminsearch中(因为它有多个标量输入吗?)。如何更改输出的格式,以便fminsearch实际允许的内容,如
@(x)x(1)^2+x(2)^2+x(3)^2
对于3个变量手动执行此操作是可行的,但不是数百个。
错误看起来像是否有帮助:
Error using symengine?makeFhandle/@(......) Not enough input arguments.
Error in fminsearch (line 190) fv(:,1) = funfcn(x,varargin{:}):
答案 0 :(得分:3)
想到一个快速的解决方法是创建另一个匿名函数作为中间人:
fun = @(x,y,z)x.^2+y.^2+z.^2;
funMiddleMan = @(x) fun(x(1),x(2),x(3));
对于大量的论点,解决方案变得有点复杂。
我的第一直觉是以下列方式使用str2func
nVar = 3;
funMiddleMan = str2func(['@(x)fun(',sprintf('x(%d),',1:nVar-1),'x(',num2str(nVar),'))']);
但是,无法使用,因为str2func
无法(当前)将fun
的定义嵌入到funMiddleMan
附加的本地工作空间中;意味着以这种方式调用funMiddleMan
会产生“Undefined function 'fun'
”错误。使用eval
:
funMiddleMan = eval(['@(x)fun(',sprintf('x(%d),',1:nVar-1),'x(',num2str(nVar),'))']);
这将起作用,因为字符串实际被评估;但是,出于多种原因使用eval
typically discouraged只是为了完整性(以及快速而肮脏的方式让球滚动)。
另一种选择是使用将矢量x
转换为单元格数组并按以下方式使用comma-separated list扩展:
splay = @(x) fun(x{:});
funMiddleMan = @(x) splay(mat2cell(x(:),ones(1,numel(x)),1));
这不一定是最佳的但是有效。