MATLAB - 为 fmincon() 编写 objective 函数
MATLAB - writing objective function for fmincon()
我需要最小化以下函数
nDOF、nprocs 和 T 取自此 table
的前两列
所以我在 MATLAB 中有以下向量
nDOF =
3993
3993
3993
3993
3993
3993
3993
3993
7623
7623
7623
7623
7623
7623
7623
7623
nprocs =
1
2
3
4
6
8
12
24
1
2
3
4
6
8
12
24
vals =
0.6564
0.2569
0.2719
0.1743
0.1305
0.1230
0.1739
0.1147
1.1998
0.5088
0.6419
0.2899
0.2192
0.2033
0.2126
0.1821
我想用函数 fmincon 最小化函数 $F$,如下所示:
fmincon(@(theta) objFunctionMatAssemble(theta(1), theta(2), theta(3), theta(4), ndofIN, nprocsIN, vals), [0 0 0 0]', [], [], [], [], [0 0 0 0], [+inf +inf +inf +inf] )
objFunctionMatAssemble 代码:
function [t] = objFunctionMatAssemble(alpha, beta, gamma, delta, ndofIN, nprocsIN, vals)
t = 0;
for i=1:length(nprocsIN)
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
end
end
问题是,我收到以下错误:
>> fmincon(@(theta) objFunctionMatAssemble(theta(1), theta(2), theta(3), theta(4), ndofIN, nprocsIN, vals), [0 0 0 0]', [], [], [], [], [0 0 0 0], [+inf +inf +inf +inf] )
Error using ^
Inputs must be a scalar and a square matrix.
To compute elementwise POWER, use POWER (.^) instead.
Error in objFunctionMatAssemble (line 4)
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
Error in @(theta)objFunctionMatAssemble(theta(1),theta(2),theta(3),theta(4),ndofIN,nprocsIN,vals)
Error in fmincon (line 535)
initVals.f = feval(funfcn{3},X,varargin{:});
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
问题显然出在我的 objective 函数中,但尽管尝试了几次,我还是无法正确编写它。我在这里看到了一些关于 SO 的解决方案,但即使我的 "closure function" 只接受一个参数并调用另一个参数,它的格式仍然不正确。
你能帮我解决这个问题吗?
你忘记在循环中索引ndofIN
(你写ndofIN^beta
,应该是ndofIN(i)^beta
)。
现在,MATLAB 中的运算符 ^
表示 matrix power。对于scalar/scalar输入,这个操作和普通的求幂是一样的,但是对于matrix/scalar输入,就不太一样了。在您的情况下,MATLAB 尝试用 beta
对 vector ndofIN
求幂——这是不允许的,因为矩阵幂仅针对方矩阵定义。这就是您收到该错误的原因。
显然,这不是您想要做的——您需要按元素求幂 (.^
)。使用它,您可以极大地简化和加速您的 objective 函数——只需像这样编写 objective 函数:
function t = objFunctionMatAssemble(alpha, ...
beta, ...
gamma, ...
delta, ...
ndofIN, ...
nprocsIN, ...
vals)
t = alpha * ndofIN.^beta + ...
gamma * (ndofIN.^delta)./nprocsIN - vals;
t = t.' * t;
end
NOTE 在您的原始函数中也存在括号不一致的地方。也就是说,您的括号使您的 objective 功能不同于您在问题中显示的功能:
% your version
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
% what's in the image
t = t + (alpha*ndofIN^beta + gamma* (ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
NB2:你也可以这样写你的objective函数:
function t = objFunctionMatAssemble2(theta, ...
ndofIN, ...
nprocsIN, ...
TIN)
N = bsxfun(@power, ndofIN, theta([2 4]).');
t = [N(:,1) N(:,2)./nprocsIN] * theta([1 3]) - TIN;
t = t.' * t;
end
这样您的 objective 函数就不需要那么多参数了。不过好吧,这取决于你的口味。
我需要最小化以下函数
nDOF、nprocs 和 T 取自此 table
的前两列所以我在 MATLAB 中有以下向量
nDOF =
3993
3993
3993
3993
3993
3993
3993
3993
7623
7623
7623
7623
7623
7623
7623
7623
nprocs =
1
2
3
4
6
8
12
24
1
2
3
4
6
8
12
24
vals =
0.6564
0.2569
0.2719
0.1743
0.1305
0.1230
0.1739
0.1147
1.1998
0.5088
0.6419
0.2899
0.2192
0.2033
0.2126
0.1821
我想用函数 fmincon 最小化函数 $F$,如下所示:
fmincon(@(theta) objFunctionMatAssemble(theta(1), theta(2), theta(3), theta(4), ndofIN, nprocsIN, vals), [0 0 0 0]', [], [], [], [], [0 0 0 0], [+inf +inf +inf +inf] )
objFunctionMatAssemble 代码:
function [t] = objFunctionMatAssemble(alpha, beta, gamma, delta, ndofIN, nprocsIN, vals)
t = 0;
for i=1:length(nprocsIN)
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
end
end
问题是,我收到以下错误:
>> fmincon(@(theta) objFunctionMatAssemble(theta(1), theta(2), theta(3), theta(4), ndofIN, nprocsIN, vals), [0 0 0 0]', [], [], [], [], [0 0 0 0], [+inf +inf +inf +inf] )
Error using ^
Inputs must be a scalar and a square matrix.
To compute elementwise POWER, use POWER (.^) instead.
Error in objFunctionMatAssemble (line 4)
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
Error in @(theta)objFunctionMatAssemble(theta(1),theta(2),theta(3),theta(4),ndofIN,nprocsIN,vals)
Error in fmincon (line 535)
initVals.f = feval(funfcn{3},X,varargin{:});
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
问题显然出在我的 objective 函数中,但尽管尝试了几次,我还是无法正确编写它。我在这里看到了一些关于 SO 的解决方案,但即使我的 "closure function" 只接受一个参数并调用另一个参数,它的格式仍然不正确。
你能帮我解决这个问题吗?
你忘记在循环中索引ndofIN
(你写ndofIN^beta
,应该是ndofIN(i)^beta
)。
现在,MATLAB 中的运算符 ^
表示 matrix power。对于scalar/scalar输入,这个操作和普通的求幂是一样的,但是对于matrix/scalar输入,就不太一样了。在您的情况下,MATLAB 尝试用 beta
对 vector ndofIN
求幂——这是不允许的,因为矩阵幂仅针对方矩阵定义。这就是您收到该错误的原因。
显然,这不是您想要做的——您需要按元素求幂 (.^
)。使用它,您可以极大地简化和加速您的 objective 函数——只需像这样编写 objective 函数:
function t = objFunctionMatAssemble(alpha, ...
beta, ...
gamma, ...
delta, ...
ndofIN, ...
nprocsIN, ...
vals)
t = alpha * ndofIN.^beta + ...
gamma * (ndofIN.^delta)./nprocsIN - vals;
t = t.' * t;
end
NOTE 在您的原始函数中也存在括号不一致的地方。也就是说,您的括号使您的 objective 功能不同于您在问题中显示的功能:
% your version
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
% what's in the image
t = t + (alpha*ndofIN^beta + gamma* (ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
NB2:你也可以这样写你的objective函数:
function t = objFunctionMatAssemble2(theta, ...
ndofIN, ...
nprocsIN, ...
TIN)
N = bsxfun(@power, ndofIN, theta([2 4]).');
t = [N(:,1) N(:,2)./nprocsIN] * theta([1 3]) - TIN;
t = t.' * t;
end
这样您的 objective 函数就不需要那么多参数了。不过好吧,这取决于你的口味。