gradient 函数将符号表达式作为输入,而不是函数指针。 MATLAB 抱怨,因为它试图将你的函数指针转换为符号表达式,但它不能。
在这种情况下,以下工作
N = 4; I = 3;
x = sym('x',[N,I]); % Define a matrix of symbolic variables
f = objfun(x); % Get symbolic expression for objfun in terms of x
免责声明 这是因为objfun 中的所有操作都支持符号变量。对于更复杂的目标函数,这种方法可能不起作用。
这将x 定义为N-by-I 符号变量矩阵
>> x
x =
[ x1_1, x1_2, x1_3]
[ x2_1, x2_2, x2_3]
[ x3_1, x3_2, x3_3]
[ x4_1, x4_2, x4_3]
并将f 定义为
>> f
f =
6000 - 500*x1_2 - 500*x1_3 - 500*x2_1 - 500*x2_2 - 500*x2_3 - 500*x3_1 - 500*x3_2 - 500*x3_3 - 500*x4_1 - 500*x4_2 - 500*x4_3 - 500*x1_1
那么我们发现f相对于x的梯度为
>> g = reshape(gradient(f,x(:)), size(x))
g =
[ -500, -500, -500]
[ -500, -500, -500]
[ -500, -500, -500]
[ -500, -500, -500]
额外的reshape 是为了符合对梯度作为与x 相同维度的张量的常见解释。
编辑
回应评论。如果您想将它与fmincon 一起使用,以便您拥有一个同时给出目标值和梯度的函数,那么您可以按如下方式构造这样的函数句柄。
grad_fun = matlabFunction(g,'Vars',x);
obj_with_grad = @(x) deal(objfun(x), grad_fun(x));
现在您可以在任意点获得目标和梯度。例如在 x=ones(N,I);
>> [obj_val, grad_val] = obj_with_grad(ones(N,I))
obj_val =
0
grad_val =
-500 -500 -500
-500 -500 -500
-500 -500 -500
-500 -500 -500
我没有测试,但您现在应该可以通过将fmincon 的'SpecifyObjectiveGradient' 选项设置为true 来使用obj_with_grad 和fmincon。