BFGS拟牛顿算法不计算步长

时间:2018-12-17 15:14:43

标签: matlab optimization newtons-method

我正在编写一种算法来实现BFGS方法,以优化无约束的问题。它适用于一维问题,但是当我使用Rosenbrock函数(或类似函数)运行它时,它将运行几次迭代,然后不返回新的步长alpha。我要去哪里错了?以下是拟牛顿线段:

% Quasi-Newton algorithm: BFGS
% Rosenbrock function
func = @(z) (1-z(1)^2)^2 + 100*(z(2)- z(1)^2)^2;
dfunc = @(z) [4*z(1)*(101*z(1)^2 - 100*z(2) - 1); 200*(z(2) - z(1)^2)];
x = [20 1];

nvar = length(x);

% Initialize H0 to identity
H = eye(nvar);

eps = 10e-6;        % relative epsilon
k = 1;

while norm(dfunc(x(k, :))) > eps
    % compute search direction p- don't need to keep pk's
    p = -H*dfunc(x(k, :))

    % get a(k) from line search that satisfies Wolfe conditions
    a = linesearch(p, func, dfunc, x(k, :))

    % get new x, keep x values
    x(k+1, :) = x(k, :) + a*p';

    % define s, y, rho
    s = a*p;
    y = dfunc(x(k+1, :)) - dfunc(x(k, :));
    rho = 1/(transpose(y)*s);

    % compute H(k+1) from 6.17
    I = eye(nvar);
    H_new = (I - rho*s*transpose(y))*H*(I - rho*y*transpose(s)) + rho*s*transpose(s)

    % increment k
    k = k+1;
    H = H_new;
end

,它使用以下行搜索功能:

function a_star = linesearch(p, func, dfunc, x0)
% function: use a line search to find alpha 
% input: 
%     p is a descent direction
%     func is the function being optimized
%     dfunc is the gradient of the function
%     x0 is the initial x value
% output: alpha that satisfies wolfe conditions

alpha_old = 0;         % initial alpha is zero
alpha = 1;             % first alpha is one
alpha_max = 1000;      % depends on problem

c1 = 1e-4;             % constant values for quasi-Newton problems
c2 = 0.9;

iter_max = 1000;

for i = 1:iter_max
if (calcPhi(alpha) > (calcPhi(0) + c1*alpha*calcdPhi(0))) || (calcPhi(alpha) >= calcPhi(alpha_old) && i>1)
    a_star = zoom(alpha_old, alpha);
    break;
end

if (abs(calcdPhi(alpha)) <= -c2*calcdPhi(0))
   a_star = alpha;
   break;
end

if (calcdPhi(alpha) >= 0)
    a_star = zoom(alpha, alpha_old);
    break;
end

alpha_old = alpha;      % update alpha values
alpha = 2*alpha;
end

function [phi] = calcPhi(a)
% function: calculate phi from alpha 
% input: step size alpha
% output: phi 
    phi = func(x0 + p.*a);
end

function [dphi] = calcdPhi(a)
% function: calculate the derivative of phi from alpha 
% input: step size alpha
% output: dphi 
    dphi = dot(p,dfunc(x0 + p.*a));      % dot product
end

function a_star = zoom(a_lo, a_hi)
% function: zoom
% inputs: low and high values for alpha
% output: alpha star
for j = 1:iter_max
    % interpolate trial step a_j between a_lo and a_hi
    a_j = (a_hi + a_lo) / 2;

    if (calcPhi(a_j) > (calcPhi(0) + c1*a_j*calcdPhi(0)) || calcPhi(a_j) >= calcPhi(a_lo))
        a_hi = a_j;
    else
        if (abs(calcdPhi(a_j)) <= -c2*calcdPhi(0))
            a_star = a_j;
            break;
        end

        if (calcdPhi(a_j)*(a_hi-a_lo) >= 0)
            a_hi = a_lo;
        end
        a_lo = a_j;
    end
end
end

end

具体来说,它将给出错误“在调用“ linesearch / zoom”期间未分配输出参数“ a_star”(可能还有其他参数)”。我试图将iter_max增加到更大的值,如100000,无济于事。为什么会发生这种情况?

0 个答案:

没有答案