Matlab:如何将多变量符号表达式转换为 fminsearch 可以使用的函数?
Matlab: How do I convert multivariable symbolic expression to a function that fminsearch can use?
我有一个多变量符号表达式 say
c = x^2 +y^2 + z^2
使用 matlabFunction(c)returns
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{:}):
想到的一个快速解决方法是创建另一个匿名函数作为中间人:
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
的定义嵌入到 [=17= 的本地工作区中];这意味着以这种方式调用 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));
这不一定是最优的但有效。
我有一个多变量符号表达式 say
c = x^2 +y^2 + z^2
使用 matlabFunction(c)returns
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{:}):
想到的一个快速解决方法是创建另一个匿名函数作为中间人:
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
的定义嵌入到 [=17= 的本地工作区中];这意味着以这种方式调用 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));
这不一定是最优的但有效。