fminsearch error: DOUBLE cannot convert the input expression into a double array

fminsearch error: DOUBLE cannot convert the input expression into a double array

我在优化练习中遇到问题。我正在尝试在 matlab 中使用 fminsearch() 来解决它。当代码为运行时会产生如下错误:

The following error occurred converting from sym to double: Error using symengine (line 59) DOUBLE cannot convert the input expression into a double array. If the input expression contains a symbolic variable, use VPA.

Error in fminsearch (line 190) fv(:,1) = funfcn(x,varargin{:});

Error in Optimization (line 22) sol2 = fminsearch(J, x0);

我使用的脚本可以在下面看到。 f 是最小化问题,其中 g1 和 g2 是约束条件。 p 在那里,以便我稍后可以将其转换为 for 循环。

syms x1 x2 x3 x4;
syms p;

f = x1.^4 - x3.^2 + x1*x3 + x2*x4 - 5*x2 + 3;
g1 = x1.^2 + x2.^2 + x3.^2 + x4.^2 - 1;
g2 = x1 + x3 - 1;

x0 = [2 2 2 2];
p = 3;

J = @(x1,x2,x3,x4) sym(f + p * g1.^2 + g2.^2);
sol2 = fminsearch(J, x0);

这个 Whosebugpost 有同样的问题,但在另一个 perspective.According 到这个 post 中,可能是以有效方式分配的问题。我尝试了几种不同的方法来解决我的问题。我试过 matlabFunction() 并将函数放在一个单独的文件中。

If the input expression contains a symbolic variable, use the VPA function instead?

在此先感谢您的帮助。

fminsearch is designed for numerical minimization. There is little point in using symbolic math in this case (it can be used, but it will be slower, complicate your code, and the results will still be in double precison). Second, if you read the documentation and look at the examples for fminsearch, you'll see that it requires a function that takes a single vector input (as opposed to four scalars in your case). Here's how you could rewrite your equations using anonymous functions:

f = @(x)x(1).^4 - x(3).^2 + x(1).*x(3) + x(2).*x(4) - 5*x(2) + 3;
g1 = @(x)x(1).^2 + x(2).^2 + x(3).^2 + x(4).^2 - 1;
g2 = @(x)x(1) + x(3) - 1;

x0 = [2 2 2 2];
p = 3;

J = @(x)f(x) + p*g1(x).^2 + g2(x).^2;
sol2 = fminsearch(J, x0)

这个returns

sol2 =

  0.149070165097281   1.101372214292880   0.326920462283209  -0.231885482601008

使用符号数学和subs:

syms x1 x2 x3 x4;

f = x1^4 - x3^2 + x1*x3 + x2*x4 - 5*x2 + 3;
g1 = x1^2 + x2^2 + x3^2 + x4^2 - 1;
g2 = x1 + x3 - 1;

x0 = [2 2 2 2];
p = sym(3);

J = @(X)subs(f + p*g1^2 + g2^2,[x1 x2 x3 x4],X);
sol2 = fminsearch(J, x0)

returns 个相同的结果。