Matlab:如何将多变量符号表达式转换为fminsearch可以使用的函数?

时间:2015-09-02 23:16:35

标签: matlab symbolic-math

我有一个多变量的符号表达式

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{:}):

1 个答案:

答案 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));

这不一定是最佳的但是有效。