diff --git a/resources/MatlabInterface/@JEInterface/JEInterface.m b/resources/MatlabInterface/@JEInterface/JEInterface.m index 06076d81..e44c8e95 100644 --- a/resources/MatlabInterface/@JEInterface/JEInterface.m +++ b/resources/MatlabInterface/@JEInterface/JEInterface.m @@ -3,19 +3,18 @@ function int = JEInterface(fhandle, range, varargin) % JEInterface(interfaceName, fhandle, range) % JEInterface(interfaceName, fhandle, range, defaultargs) % JEInterface(interfaceName, fhandle, range, defaultargs, options...) - - -% arguments: +% +% Arguments: % fhandle: a function handle defining the optimization target. % range: a 2 x dim array defining the solution subspace with lower and -% upper bounds - or a scalar defining the bitwidth for binary +% upper bounds; or a scalar defining the bitwidth for binary % problems. % defaultArgs: (optional) additional constant argument to the target % function, empty by default. % options: (optional) options as name-value pairs defining optimization parameters, % especially tolerance and maximum function calls. % Check makeOoptions for default settings. - +% % Further options may be specified using setOptions with a JE options struct. % Main options are: % TolX: convergence criterion in the solution space @@ -85,13 +84,13 @@ if (nargin>2) if (rem(nargin,2)==0) error('Invalid number of arguments!'); end - disp('Reading options...'); + disp('Reading options:'); for i=2:2:nargin-2 int=setOpt(int, varargin{i}, varargin{i+1}); end end end - +display(getOptions(int)); % finally create the java object int.mp = eva2.server.go.problems.MatlabProblem(int.dim, int.range); disp('Java object created'); diff --git a/resources/MatlabInterface/@JEInterface/makeOptions.m b/resources/MatlabInterface/@JEInterface/makeOptions.m index c0b7e65d..da9cf24c 100644 --- a/resources/MatlabInterface/@JEInterface/makeOptions.m +++ b/resources/MatlabInterface/@JEInterface/makeOptions.m @@ -1,18 +1,31 @@ function opts = makeOptions(int, varargin) % Create a JEInterface options set from scratch. Possible fields are: %'Display'; -%'MaxFunEvals';'MaxIter';'TolFun';'TolFunEvals';TolX';'TolXEvals', where -% all but 'TolFunEvals', 'TolXEvals' are used similar to the optimset. +%'MaxFunEvals';'MaxIter';'TolFun';'TolFunEvals';TolX';'TolXEvals', which, +% except for 'TolFunEvals' and 'TolXEvals', are used similar to the optimset. % The latter two are interpreted as the numbers of evaluations required % to assume convergence. Default values are TolXEvals=TolFunEvals=200, % TolX=TolFun=1e-4, MaxFunEvals uses a default from EvA2. +% Further options are 'CreateStopBox' and 'NiceSleepTime' which are +% JE-specific. The 'CreateStopBox' option toggles the GUI box with stop +% button provided for graceful interruption of an optimization run. +% In cases without X-forwarding, a deactivation by setting it to 0 may be required, +% but note that killing optimization may break the threading mechanism. Try stopOptimize with +% the 'kill' option. +% +% 'NiceSleepTime' allows setting a sleep time (in ms) for the concurrent +% threading. Technically, either the Matlab +% or the Java thread is always waiting for the other one, which may require +% full CPU if no sleep time is employed. However, for quick function evaluations, +% even minor sleep times substantially reduce allover efficiency, so we advice +% to set small sleep times (e.g. 5 ms) only if a single function evaluation +% takes considerably longer and leave the sleep time at zero otherwise. +% % Notice that this method creates a parameter set but does not assign it % to the interface instance. Use setOptions to do that. allfields = {'Display'; 'MaxFunEvals';'MaxIter';'TolFun';'TolFunEvals';... - 'TolX';'TolXEvals'}; - -specialfields={'TolFunEvals', 'TolXEvals'}; + 'TolX'; 'TolXEvals'; 'CreateStopBox'; 'NiceSleepTime'}; nvararg=nargin-1; if rem(nvararg,2)==1 @@ -36,6 +49,8 @@ opts.('TolX') = 1e-4; opts.('TolXEvals') = 200; opts.('TolFun') = 1e-4; opts.('TolFunEvals') = 200; +opts.('CreateStopBox')=1; +opts.('NiceSleepTime')=0; for i=1:nvararg/2 name=varargin{2*i-1}; @@ -48,18 +63,27 @@ for i=1:nvararg/2 if isempty(optIndex) error('Unknown option %s !', name); else - if ~isempty(strmatch(name, specialfields,'exact')) - % test for integer - if (~isscalar(value) || ~isnumeric(value) || round(value)<1) - error('invalid value type for %s, expecting numeric scalar > 1!', name); - end - value=round(value); - else - % test using optimset - optimset(stdSet, name, value); + switch name + case {'TolFunEvals', 'TolXEvals'} % for special fields, integers > 1 are allowed + if ~isscalar(value) || ~isnumeric(value) || round(value)<1 + error('Invalid value type for %s, expecting positive numeric scalar!', name); + end; + value=round(value); + case 'CreateStopBox' + if ~isscalar(value) || ~isnumeric(value) || round(value)<0 || round(value)>1 + error('Invalid value type for %s, expecting 0 or 1!', name); + end; + value=round(value); + case 'NiceSleepTime' + if ~isscalar(value) || ~isnumeric(value) || round(value)<0 ; + error('Invalid value type for %s, expecting numeric scalar >= 0!', name); + end; + value=round(value); + otherwise % test using optimset + optimset(stdSet, name, value); end % assign to struct opts.(allfields{optIndex,:}) = value; end end -end \ No newline at end of file +end diff --git a/resources/MatlabInterface/@JEInterface/runEvalLoopJE.m b/resources/MatlabInterface/@JEInterface/runEvalLoopJE.m index 753dc8f6..c44e7e43 100644 --- a/resources/MatlabInterface/@JEInterface/runEvalLoopJE.m +++ b/resources/MatlabInterface/@JEInterface/runEvalLoopJE.m @@ -19,11 +19,15 @@ if ~isempty(int.mediator) int.mediator.quit int.mediator=''; end +% disp(sprintf('creating mediator')); % set up a mediator and inform JE -int.mediator = eva2.server.go.problems.MatlabEvalMediator; +int.mediator = eva2.server.go.problems.MatlabEvalMediator(int.opts.NiceSleepTime); int.mp.setMediator(int.mediator); JEMediator=int.mediator; +createStopBox=int.opts.CreateStopBox; + +% disp(sprintf('mediator created, calling optimize')); % start the JE thread if (optOrPostProc == 1) @@ -33,6 +37,7 @@ else % post processing stopText='Stop EvA2 post processing'; int.mp.requestPostProcessing(steps, sigmaClust, nBest); end +% disp(sprintf('calling optimize done')); % handle the case when the optimization has been called from a users script % and not from the toolboxes parameter estimation function (which has an @@ -47,10 +52,15 @@ if isempty(stopOptimization), disp(sprintf('Starting optimization at %s', timeStr)); % create a cancel button box (case without SBtoolbox) stopText=sprintf('%s (%s)', stopText, timeStr); - boxHandle=figure('Position',[100 600 250 80], 'MenuBar', 'none', 'Name', 'EvA2 optimization...', 'NumberTitle','off'); - uicontrol(boxHandle,'Style', 'pushbutton', 'String', 'Cancel', 'Position', [25 25 60 30], 'Callback', 'global stopOptimization; stopOptimization=1;'); - uicontrol(boxHandle,'Style', 'text', 'String', stopText, 'Position', [100 15 130 50]); - drawnow; + if (createStopBox == 1) + boxHandle=figure('Position',[100 600 250 80], 'MenuBar', 'none', 'Name', 'EvA2 optimization...', 'NumberTitle','off'); + uicontrol(boxHandle,'Style', 'pushbutton', 'String', 'Cancel', 'Position', [25 25 60 30], 'Callback', 'global stopOptimization; stopOptimization=1;'); + uicontrol(boxHandle,'Style', 'text', 'String', stopText, 'Position', [100 15 130 50]); + drawnow; +% else +% disp(stopText); + end + % set flag for non toolbox optimization nontoolboxopt = 1; else @@ -60,13 +70,19 @@ else end stopOnce=1; - +cnt=1; +% disp(sprintf('before eval loop... %d',cnt)); % repeat the mediator thread and eval call until finished try while (~int.mediator.isFinished()) - int.mediator.run; +% disp(sprintf('running mediator id %d',cnt)); + int.mediator.run(cnt); +% disp(sprintf('after running mediator id %d',cnt)); + cnt=cnt+1; if (~int.mediator.isFinished()) + %disp('getting question'); x = int.mediator.getQuestion(); + %disp('question asked'); if (isempty(int.range)) %size(x) x=convertUnsignedJE(int, x); @@ -80,6 +96,7 @@ try else res = feval(int.f, x, int.args); end +% disp(sprintf('res is %d',res)); %res catch ME disp('function evaluation failed:'); @@ -87,6 +104,7 @@ try stopOptimization=1; end int.mediator.setAnswer(res); + %disp('answer provided'); drawnow; if ((stopOptimization==1) && (stopOnce==1)) disp('User interrupt requested ...'); @@ -108,7 +126,7 @@ catch ME % clear global stopOptimization %end end - +% disp('writing back results'); % write back results int=setResultJE(int, int.mediator.getSolution()); int=setResultArrayJE(int, int.mediator.getSolutionSet()); @@ -120,6 +138,9 @@ int.mediator=''; % and not from the toolboxes parameter estimation function (which has an % own stop button). we decide this by checking nontoolboxopt if nontoolboxopt == 1, - if (ishandle(boxHandle)) , close(boxHandle); end + if createStopBox==1 + if (ishandle(boxHandle)) , close(boxHandle); end + end clear global stopOptimization end +% disp('runEvalLoop done'); diff --git a/resources/MatlabInterface/@JEInterface/setVerbose.m b/resources/MatlabInterface/@JEInterface/setVerbose.m index 49f585fb..ce57663f 100644 --- a/resources/MatlabInterface/@JEInterface/setVerbose.m +++ b/resources/MatlabInterface/@JEInterface/setVerbose.m @@ -14,8 +14,11 @@ end if (nargin > 2) if ischar(varargin{1}) fname=varargin{1}; - disp('Writing debug output to '); - disp(fname); + if (bOn==1) + disp(['Writing debug output to ' fname]); + else + disp('Debug output deactivated'); + end else disp('Invalid third argument, expected char. Using default output file name'); end