Matlab 优化:记录迭代中的数据

Matlab optimization: record data over iterations

是否可以使用Matlab进行优化,使用仅包含Output function的函数m文件记录从一次迭代到下一次迭代的数据?

所提供的 Example 表明需要从 "runOptimization" 函数中调用优化函数,嵌套输出函数也位于该函数中。

function [history,searchdir] = runOptimization

% Set up shared variables with OUTFUN
history.x = [];
history.fval = [];
searchdir = [];

% call optimization
x0 = [-1 1];
options = optimoptions(@fmincon,'OutputFcn',@outfun,... 

% nested output function
function stop = outfun(x,optimValues,state)
    stop = false;
    switch state
    % ... store history and search directions over all iterations

另外 this site 声称,如果您希望输出函数从一个迭代记录到下一个迭代的数据,您应该编写一个执行以下操作的文件:

但是,我想知道是否可以创建一个仅包含输出函数并使用额外参数 historysearchdir 作为输入的 m 文件。

我尝试使用以下匿名函数方法,其中共享变量 historysearchdir 在我的主 m 文件(非全局)中声明为 "outside"。对于 objective 函数和输出函数,我使用单独的 m 文件。

% main m-file
% Set up shared variables with OUTFUN
history.x = [];
history.fval = [];
searchdir = [];

outf = @(x,optimValues,state)outfun(x,optimValues,state,history,searchdir);

objective = @(x) objective_function(x,y,h);

x0 = [-1 1];
x = fmincon(objective,x0,[],[],[],[],[],[],[],options);

虽然每次输出函数returns,共享变量又是空的。是否有另一种解决方案而不是全局变量,比如通过引用传递而不是复制作为参数。

至少有三种解决方案,每一种都比另一种更糟糕:

1.使用句柄 类.

主文件:

clear all
history= histclass;
outf= @(x,optimValues,state)outfun3(x,optimValues,state,history);
objective= @(x) x(1)^2+x(2)^4; % just for example
options = optimset('OutputFcn',outf);
x0 = [-1 1];
x = fmincon(objective,x0,[],[],[],[],[],[],[],options);
disp(history.x);
disp(history.fval);

histclass定义:

classdef histclass < handle
    properties 
        x= [];
        fval= [];
    end
    methods 
        function add(obj,newx,newfval)
            obj.x= [obj.x; newx];
            obj.fval= [obj.fval  newfval];
        end
    end
end

输出函数:

function stop = outfun3(x,optimValues,state,history)
    stop = false;
    history.add(x,optimValues.fval);
end

2。使用 evalin.

主文件:

history= struct('x',[],'fval',[]); % create the structure with empty fields
history(1)= []; % create the empty structure array with the specified fields
add_history= @(x,fval,varname)evalin('base',...
    ['history(end+1)= struct(''x'',' mat2str(x) ',''fval'',' num2str(fval) ')']);
outf= @(x,optimValues,state)outfun(x,optimValues,state,add_history);
objective= @(x) x(1)^2+x(2)^4; % just for example
options = optimset('OutputFcn',outf);
x0 = [-1 1];
x = fmincon(objective,x0,[],[],[],[],[],[],[],options);
disp([history.x]);

输出函数:

function stop = outfun(x,optimValues,state,add_history)
    stop = false;
    add_history(x,optimValues.fval);
end

3。使用文件

主文件:

clear all
history= struct('x',[],'fval',[]); % create the structure with empty fields
history(1)= []; % create the empty structure array with the specified fields
save('history.mat')
objective= @(x) x(1)^2+x(2)^4; % just for example
options = optimset('OutputFcn',@outfun2);
x0 = [-1 1];
x = fmincon(objective,x0,[],[],[],[],[],[],[],options);
load('history.mat')
disp([history.x]);

输出函数:

function stop = outfun2(x,optimValues,state)
    stop = false;
    load('history.mat','history')
    history(end+1)= struct('x',x,'fval',optimValues.fval);
    save('history.mat')
end