【问题标题】:MATLAB - writing objective function for fmincon()MATLAB - 为 fmincon() 编写目标函数
【发布时间】:2016-11-21 16:26:57
【问题描述】:

我需要最小化以下功能

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

所以我在 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 的解决方案,但是即使我的“闭包函数”只接受一个参数并调用另一个参数,它的格式仍然不正确。

你能帮我解决这个问题吗?

【问题讨论】:

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


    【解决方案1】:

    你忘了在循环中索引ndofIN(你写了ndofIN^beta,应该是ndofIN(i)^beta)。

    现在,MATLAB 中的运算符^ 表示matrix power。对于标量/标量输入,此运算与普通取幂相同,但对于矩阵/标量输入,则不完全相同。在您的情况下,MATLAB 尝试用 beta 对 vector ndofIN 求幂 - 这是不允许的,因为矩阵幂仅针对方阵定义。这就是您收到该错误的原因。

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

    function t = objFunctionMatAssemble(alpha, ...
                                        beta, ...
                                        gamma, ...
                                        delta, ...
                                        ndofIN, ...
                                        nprocsIN, ...
                                        vals) 
    
        t = alpha *  ndofIN.^beta + ...
            gamma * (ndofIN.^delta)./nprocsIN - vals;
    
        t = t.' * t;
    
    end
    

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

    % 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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 2023-03-29
      • 1970-01-01
      • 2016-02-21
      • 2021-08-17
      • 2017-11-02
      • 1970-01-01
      相关资源
      最近更新 更多