Latest JEInterface

This commit is contained in:
Marcel Kronfeld 2008-04-02 12:36:34 +00:00
parent 11258ddbbf
commit 17411d6775
12 changed files with 311 additions and 25 deletions

View File

@ -17,6 +17,7 @@ int.args = [];
int.opts = optimset('MaxFunEvals', javaeva.OptimizerFactory.getDefaultFitCalls, 'TolX', 1e-4, 'TolFun', 1e-4);
int.finished = 1;
int.result = [];
int.resultArr = [];
int.callback='';
int.f = '';
int.dim = 0;
@ -24,6 +25,9 @@ int.range = [];
int.mp = [];
int.msg = '';
int.funCalls = 0;
int.mediator = '';
int.optParams = [];
int.optParamValues = [];
if (isa(interfaceName, 'char'));
int.callback = interfaceName;
@ -35,6 +39,7 @@ if (isa(fhandle, 'function_handle'))
else
error('Wrong second argument type, expected function_handle');
end
if (isa(range, 'double') && (size(range,1) == 2))
int.dim=length(range);
int.range=transpose(range);
@ -49,8 +54,9 @@ switch nargin
case {4,5}
if (isa(varargin{1}, 'struct'))
int.opts = varargin{1};
if (isempty(int.opts.TolX)) ; int.opts.TolX = 1e-4; end
if (isempty(int.opts.TolFun)) ; int.opts.TolFun = 1e-4; end
% DONT set default values if user leaves them blank
% if (isempty(int.opts.TolX)) ; int.opts.TolX = 1e-4; end
% if (isempty(int.opts.TolFun)) ; int.opts.TolFun = 1e-4; end
else
error('Wrong fifth argument type, expected optimset struct');
end

View File

@ -0,0 +1,11 @@
function desc = getDesc(int, ID)
% Return the String description of an indicated optimizer
% with member descriptions.
import javaeva.gui.BeanInspector;
import javaeva.server.modules.GOParameters;
import javaeva.OptimizerFactory;
params = OptimizerFactory.getParams(ID, int.mp);
desc = BeanInspector.getDescription(params.getOptimizer, false);

View File

@ -0,0 +1,21 @@
function [sols, fits] = getMultipleResults(int)
% Returns a set of optimization solutions if the run has been finished, or
% a singel intermediate solution if the run has not finished yet or an
% empty array if there is no intermediate solution yet.
if (isFinished(int))
sols = int.resultArr;
else
sols = int.mp.getIntermediateResult();
end
fits=zeros(size(sols,1),1);
for i=1:size(sols,1)
%disp(sols(i,:));
if (isempty(int.args))
fits(i) = feval(int.f, sols(i,:));
else
fits(i) = feval(int.f, sols(i,:), int.args);
end
end

View File

@ -0,0 +1,5 @@
function b = getProgress(int)
% Returns the number of function calls performed during optimization (not
% post processing)
b = int.mp.getProgress;

View File

@ -1,10 +1,23 @@
function v = getResult(int)
% Returns the optimization solution if the run has been finished, or an
% intermediate solution if the run has not finished yet or an empty array
function [sol, fit] = getResult(int)
% Returns the optimization solution and its fitness if the run has been finished, or an
% intermediate solution and ints fitness if the run has not finished yet or an empty array
% if there is no intermediate solution yet.
% [sol, fit] = getResult(int)
if (isFinished(int))
v = int.result;
sol = int.result;
else
v = int.mp.getIntermediateResult();
end
sol = int.mp.getIntermediateResult();
end
if (isempty(sol))
fit = NaN;
else
if (isempty(int.args))
fit = feval(int.f, sol);
else
fit = feval(int.f, sol, int.args);
end
end
%disp('Fitness: ');
%disp(y);

View File

@ -1,18 +1,18 @@
function retInt = optimize(int, optType, varargin)
% Start a JavaEvA optimization run.
% optimize(interface, optType, [, outputFilePrefix ] )
% where
% where
% interface: instance of JEInterface
% optType: integer indicating the type of the optimization strategy
% to use.
% resultFilePrefix: (optional) char prefix for an optional verbose
% output file
if (int.finished == 0)
if (int.finished == 0)
error('please wait for the current run to finish');
end
if ((nargin == 2) || (nargin == 3))
if (nargin == 3)
if (nargin == 3)
outputFilePrefix = varargin{1};
else
outputFilePrefix = 'none';
@ -27,27 +27,60 @@ if ((nargin == 2) || (nargin == 3))
xTol = int.opts.TolX;
maxEvals = int.opts.MaxFunEvals;
fTol = int.opts.TolFun;
% construct Terminators
import javaeva.server.go.operators.terminators.PhenotypeConvergenceTerminator;
import javaeva.server.go.operators.terminators.FitnessConvergenceTerminator;
import javaeva.server.go.operators.terminators.FitnessConvergenceTerminator;
import javaeva.server.go.operators.terminators.CombinedTerminator;
import javaeva.server.go.operators.terminators.EvaluationTerminator;
import javaeva.OptimizerFactory;
% set some default values if theyre not given
if (isempty(int.opts.TolX)) ; xTol = 1e-4; end
if (isempty(int.opts.TolFun)) ; fTol = 1e-4; end
% fminsearch, for example, always uses TolX and TolFun with default
% values of 1e-4 in . Thats what we do as well
convTerm = CombinedTerminator(FitnessConvergenceTerminator(fTol, int32(5), 0, 1), PhenotypeConvergenceTerminator(xTol, 5, 0, 1), 1);
% if MaxFunEvals is defined additionally, combine an
% EvaluationTerminator in disjunction, as Matlab does.
if (~isempty(maxEvals))
javaeva.OptimizerFactory.setTerminator(convTerm);
javaeva.OptimizerFactory.addTerminator(EvaluationTerminator(maxEvals), 0);
if (isempty(int.opts.TolX)) ; xTol = 1e-4; end
if (isempty(int.opts.TolFun)) ; fTol = 1e-4; end
% construct Terminators
if ((xTol > 0) && (fTol > 0))
% both criteria are given, use combination
convTerm = CombinedTerminator(FitnessConvergenceTerminator(fTol, 100, 1, 1), PhenotypeConvergenceTerminator(xTol, 100, 1, 1), 1);
else if (xTol > 0) % only phenotye convergence
convTerm = PhenotypeConvergenceTerminator(xTol, 100, 1, 1);
else if (fTol > 0 ) % only fitness covnergence
convTerm = FitnessConvergenceTerminator(fTol, 100, 1, 1);
else
convTerm = 'undef'; % signal that there is no terminator yet
end
end
end
int.mp.optimize(optType, outputFilePrefix);
if (ischar(convTerm)) % if no convergence terminator is defined so far, use fitness calls
if (isempty(maxEvals))
error('Error: no termination criterion defined! Please check options.');
% int.opts.MaxFunEvals = OptimizerFactory.getDefaultFitCalls;
% maxEvals = OptimizerFactory.getDefaultFitCalls;
end
convTerm = EvaluationTerminator(maxEvals);
javaeva.OptimizerFactory.setTerminator(convTerm);
else % there is a convergence terminator
javaeva.OptimizerFactory.setTerminator(convTerm); % so set it
if (~isempty(maxEvals))
% if TolX/TolFun plus MaxFunEvals is defined additionally, combine an
% EvaluationTerminator in disjunction, as Matlab does.
javaeva.OptimizerFactory.addTerminator(EvaluationTerminator(maxEvals), 0);
end
end
% set display
if (strcmp(int.opts.Display,'off') || isempty(int.opts.Display))
int.mp.setStatsOutput(0);
elseif (strcmp(int.opts.Display, 'iter'))
int.mp.setStatsOutput(1);
else
error('invalid Display option, only off/iter are recognized');
end
int=runEvalLoopJE(int, 1, optType, outputFilePrefix, -1, -1, -1);
else
error('Wrong number of arguments!')
end

View File

@ -0,0 +1,57 @@
function retInt = optimizeWith(int, optType, varargin)
% Start a JavaEvA optimization run with specific optimizer parameter settings.
% optimize(interface, optType, [, outputFilePrefix ] [, memName, memVal]* )
% where
% interface: instance of JEInterface
% optType: integer indicating the type of the optimization strategy
% to use.
% resultFilePrefix: (optional) char prefix for an optional verbose
% output file
% memName: character name of a member of the optimizer
% memVal: value to set for the member.
% Note that the parameter settings will not be stored and remain valid only for
% the current optimization run.
% This just reads the parameters, sets them as interface members and then
% calls the standard optimize method.
if (int.finished == 0)
error('please wait for the current run to finish');
end
if (nargin < 2)
error('invalid number of arguments!');
end
if (nargin == 2)
% standard case, just call optimize
retInt = optimize(int, optType);
elseif (nargin == 3)
% standard case, just call optimize
retInt = optimize(int, optType, varargin{1});
else
if (mod(nargin, 2) == 1) % odd arguments! There is an outputfilePrefix!
nextMem = 2;
output = varargin{1};
else
nextMem = 1;
output = '';
end
pairCnt = (nargin-nextMem-1)/2;
parValues(1) = {-1};
% parArr = ones(2*pairCnt,1); % parameter array
for i=1:pairCnt
% load parameter/value pairs into an array
parNames(i) = cellstr(varargin{nextMem});
parValues(i) = {varargin{nextMem+1}};
% if (~ischar(parArr(i)))
% error('invalid argument, member names must be char');
% end
nextMem = nextMem+2;
end
int.optParams = parNames;
int.optParamValues = parValues;
retInt = optimize(int, optType, output);
int.optParams = [];
int.optParamValues = [];
end

View File

@ -0,0 +1,35 @@
function int = postProcess(int, steps, sigmaClust, varargin)
% Do post processing of the last optimization results and export
% the solution set to the JEInterface.
% int=postProcess(int, steps, sigmaClust [, nBest])
% Either of the parameters steps and sigmaClust may be 0 to leave out
% hill-climbing or clustering step. Setting both to 0 is not meaningful.
% The optional nBest parameter gives an upper bound to the number of
% returned solutions, which are sorted by fitness. Leaving this parameter
% out means that all solutions suggested by the optimizer (after
% clustering if activated) are returned, the number of which is usually,
% but not for all optimizers (e.g., not for CBN), limited to the population size.
%
% Arguments:
% int: the JEInterface instance
% steps: number of hill climbing steps to perform or 0
% sigmaClust: paramter for the density based clustering to perform or 0,
% relative to the problem range
% nBest: (optional) maximum number of solutions to return
% stepSize: (optional) step size of the stochastic hill climber.
if (int.finished == 0)
error('please wait for the current run to finish');
end
int.finished = 0;
if (nargin > 3) && (isnumeric(varargin{1}))
nBest = varargin{1};
else
nBest = -1;
end
int=runEvalLoopJE(int, 2, -1, '', steps, sigmaClust, nBest);

View File

@ -0,0 +1,86 @@
function int=runEvalLoopJE(int, optOrPostProc, optType, outputFilePrefix, steps, sigmaClust, nBest)
% Internal method starting a JavaEvA optimization loop.
% Calling this directly may interfere with optimization.
% optOrPostProc: 1 for optimize, 2 for postProcess
% optType, outputFilePrefix are parameters for optimize, dont care when
% postprocessing.
% steps, sigmaClust and nBest are parameters for postProcess, dont care
% when optimizing. nBest may be -1 to show all.
global stopOptimization
if ~isempty(int.mediator)
int.mediator.quit
int.mediator='';
end
% set up a mediator and inform JE
int.mediator = javaeva.server.go.problems.MatlabEvalMediator;
int.mp.setMediator(int.mediator);
% start the JE thread
if (optOrPostProc == 1)
stopText='Stop JavaEvA optimization';
int.mp.optimize(optType, outputFilePrefix, int.optParams, int.optParamValues);
else % post processing
stopText='Stop JavaEvA post processing';
int.mp.requestPostProcessing(steps, sigmaClust, nBest);
end
% handle the case when the optimization has been called from a users script
% and not from the toolboxes parameter estimation function (which has an
% own stop button). we decide this by checking if the global variable
% stopOptimization is empty. if it is then it is not the toolbox calling
% and we create an own button to stop it.
if isempty(stopOptimization),
% create a cancel button box (only in the case that
h=figure('Position',[100 600 250 80], 'MenuBar', 'none', 'Name', 'JavaEvA optimization running...', 'NumberTitle','off');
uicontrol(h,'Style', 'pushbutton', 'String', 'Cancel', 'Position', [25 25 60 30], 'Callback', 'global stopOptimization; stopOptimization=1;');
uicontrol(h,'Style', 'text', 'String', stopText, 'Position', [100 25 120 30]);
drawnow;
% set it to 0 now
stopOptimization = 0;
% set flag for non toolbox optimization
nontoolboxopt = 1;
else
% its an estimation using the toolbox' parameter estimation thing
nontoolboxopt = 0;
end
stopOnce=1;
% repeat the mediator thread and eval call until finished
while (~int.mediator.isFinished())
int.mediator.run;
if (~int.mediator.isFinished())
x = int.mediator.getQuestion();
if (isempty(int.args))
res = feval(int.f, x);
else
res = feval(int.f, x, int.args);
end
int.mediator.setAnswer(res);
drawnow;
if ((stopOptimization==1) && (stopOnce==1))
disp('User interrupt requested ...');
stopOptimize(int);
stopOnce=0;
end
end
end
% write back results
int=setResultJE(int, int.mediator.getSolution());
int=setResultArrayJE(int, int.mediator.getSolutionSet());
int.mediator.quit; % just in case
int.mediator='';
% handle the case when the optimization has been called from a users script
% and not from the toolboxes parameter estimation function (which has an
% own stop button). we decide this by checking nontoolboxopt
if nontoolboxopt == 1,
close(h);
clear global stopOptimization
end

View File

@ -0,0 +1,9 @@
function int = setResultArrayJE(int, arrData)
% Interface function to be called by JavaEvA 2.
% Write back a whole solution set
int.finished = 1;
int.msg=int.mp.getInfoString;
int.funCalls=int.mp.getFunctionCalls;
int.resultArr = arrData;

View File

@ -0,0 +1,5 @@
function showOptimizers(int)
% Show a list of JavaEvA optimizers accessible through the JEInterface
% and their access ID numbers.
javaeva.OptimizerFactory.showOptimizers

View File

@ -1,4 +1,9 @@
function int = stopOptimize(int)
% Stop a running optimization
int.mp.stopOptimize
%disp('in Stop!');
int.mp.stopOptimize;
%if (~isempty(int.mediator))
% int.mediator.quit; % just in case
% int.mediator='';
%end