MATLAB - 为fmincon()编写目标函数

时间:2016-11-21 16:26:58

标签: matlab nonlinear-optimization non-linear-regression

我需要最小化以下功能

nDOF,nprocs和T取自该表的前两列

enter image description here

所以我在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.

问题显然出现在我的目标函数中,但尽管尝试了几次,我还是无法正确编写。我已经在SO上看到了一些解决方案,但即使我的"关闭功能"只接受一个参数并调用另一个参数,但其格式不正确。

请你帮助我吗?

1 个答案:

答案 0 :(得分:1)

您忘记在循环中对ndofIN编制索引(您编写的ndofIN^beta应为ndofIN(i)^beta)。

现在,MATLAB中的运算符^表示matrix power。对于标量/标量输入,此操作与正常取幂相同,但对于矩阵/标量输入,它不完全相同。在您的情况下,MATLAB尝试使用ndofIN向量 beta进行取幂 - 这是不允许的,因为矩阵幂只是为方矩阵定义的。这就是你得到这个错误的原因。

显然,这不是你打算做的 - 你想要元素明智的指数化(.^)。使用它,您可以极大地简化和加速目标函数 - 只需编写这样的目标函数:

function t = objFunctionMatAssemble(alpha, ...
                                    beta, ...
                                    gamma, ...
                                    delta, ...
                                    ndofIN, ...
                                    nprocsIN, ...
                                    vals) 

    t = alpha *  ndofIN.^beta + ...
        gamma * (ndofIN.^delta)./nprocsIN - vals;

    t = t.' * t;

end
原始函数中的

注意也存在括号不一致。也就是说,您的括号使您的目标函数不是您在问题中显示的内容:

% 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 :你也可以这样编写你的目标函数:

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

这样你的目标函数就不需要那么多论点了。但是,这取决于你的口味。