function [ options ] = forest_opt_set( varargin ) %FOREST_OPT_SET Sets the options used in the main genetic algorithm function. % forest_opt_set() displays the options available. % % OPTIONS = forest_opt_set() creates a structure with default parameters % % OPTIONS = forest_opt_set('PARAM1',VALUE1,'PARAM2',VALUE2,....) will create % a structure using default parameters. PARAMs specified in the input % will be assigned the corresponding VALUE. % % OPTIONS = forest_opt_set(OLDOPTS,'PARAM',VALUE) will create a structure % using a prior options structure and reassigning fields corresponding to % the parameter value pairs. % %forest_opt_set PARAMETERS % % Trees - The number of trees in each forest % [ positive integer | {500} ] % UpdatedTrees - The number of trees updated at each iteration % [ positive integer | {2} ] % Iterations - The number of iterations per MCMC run % [ positive integer | {20000} ] % Resets - The number of MCMC resets % [ positive integer | {2} ] % Save - The frequency to save the model after burn-in % [ positive integer | {2000} ] % BurnIn - The percent of iterations to use for burn in % [ positive double between 0 and 100 | {20} ] % Width - The width of the prior used for the intercept % [ positive double | {data dependent} ] % Sigma - The width of the prior used for the variance % [ positive double | {data dependent} ] % Group - Optional groups for correlated observations % [ positive categorical integers | {data dependent} ] % GroupPower - Strength of the correlation within groups % 0 = no appreciable correlation % 1 = very strong correlation % [ positive integer between 0 and 1 | {data dependent} ] % $LastChangedBy: alistair $ % $LastChangedDate: 2012-05-30 12:21:30 +0100 (Wed, 30 May 2012) $ % $Revision: 21 $ % Originally written on GLNXA64 by Alistair Johnson, 13-May-2012 20:32:27 % Contact: alistairewj@gmail.com %=== create defaults if nargout==0 displayForestOptions; % Call subfunction to display options return; else options=struct( ... 'Trees', 500, ... 'UpdatedTrees', 2, ... 'Iterations', 100000, ... 'Resets', 5, ... 'Save', 2000, ... 'BurnIn', 20, ... 'Width', [], ... 'Sigma', [], ... 'Family', [], ... 'Group', [], ... 'GroupPower', [] ... ); end if nargin==0 return; end %=== allowed parameters okargs=fieldnames(options); numargs=length(varargin); %=== Loop through input arguments k=1; % Varargin index %=== Check if first input is a structure if isstruct(varargin{k}) %=== Scan through structure, use values if appropriate fn=fieldnames(varargin{k}); fn_L=length(fn); %=== Loop through input options for s=1:fn_L %=== Commented code left for readability % pname = fn{s}; pval = varargin{k}.(fn{s}); % param = find(strcmpi(pname, okargs)==1,1); [options] = updateOptionsField(options, ... fn{s}, varargin{k}.(fn{s}), find(strcmpi(fn{s}, okargs)==1,1)); end k=k+1; end %=== check for incorrect number of inputs if (k==1 && rem(nargin,2) == 1) || ... % No structure, odd number of inputs (k==2 && rem(nargin,2) == 0) % Structure, even number of inputs error(sprintf('Options:%s:IncorrectNumberOfArguments',mfilename),... 'Incorrect number of arguments to %s.',mfilename); end %=== Parse remaining Parameter/Value inputs while k<=numargs [options] = updateOptionsField(options, ... varargin{k}, varargin{k+1}, find(strcmpi(varargin{k}, okargs)==1,1)); k=k+2; end %=== Validate intraconsistency of options parameters [options] = validateConsistency(options); end function [options] = updateOptionsField(options, pname, pval, param) % This function validates the input parameter name/value and updates the % associated value in options % This function calls the following other subfunctions: % validateParamType - Validates that the parameter is of the right type % validateParamIsSubset - Validates that the parameter has a correct value from a % set of acceptable values if isempty(param) % Parameter name not found in okargs warning(sprintf('forest_opt_set:%s:UnknownParameterName', mfilename), ... 'Unknown parameter %s was ignored.',pname); return; else % Parameter name found %=== Check if parameter is the right type [valid1,errmsg1]=validateParamType(pname,pval); if valid1==0 % Parameter is not of the right type error(sprintf('forest_opt_set:%s:invalidParamVal',mfilename),errmsg1); else %=== Check if parameter is one of a set of acceptable values [valid2,errmsg2]=validateParamIsSubset(pname,pval); end if valid2==0 error(sprintf('forest_opt_set:%s:invalidParamVal',mfilename),errmsg2); else % Everything is OK, don't panic. options.(pname)=pval; end end end function [valid, errmsg] = validateParamType(param, val) valid=1; errmsg=''; if isempty(val) % Default used return; end switch param case {'Iterations','Resets','Save','Trees','UpdatedTrees'} % Positive definite integers if ~isnumeric(val) || val<0 valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive numeric',param); end if abs(val-floor(val))>1e-15 % Not an integer valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive numeric',param); end case 'Group' % Positive definite integer vectors if ~isnumeric(val) valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be numeric',param); end if any(val<0) valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive number',param); end if any(abs(val-floor(val))>1e-15) % Not an integer valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive numeric',param); end case 'GroupPower'% Doubles between 0 and 1 if ~isnumeric(val) || val<0 valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive numeric',param); end if val>1 valid=0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be between 0 and 1',param); end case {'BurnIn'} % Positive definite doubles between 0 and 100 if ~isnumeric(val) || val<0 || val>100 valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive numeric between 0 and 100',param); end case {'Width','Sigma'} % Positive definite doubles if ~isempty(val) && (~isnumeric(val) || val<0) valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive numeric above 0',param); end case {'Family'} % String if ~isempty(val) && ~ischar(val) valid = 0; errmsg = sprintf('Invalid value for OPTIONS parameter %s: must be a positive numeric above 0',param); end otherwise valid=0; errmsg = sprintf('Unknown parameter field %s', param); end end function [valid,errmsg] = validateParamIsSubset(pname,pval) % This function ensures that the given functions are members of a % pre-defined set. % Ensure pval is a valid member of the costFcn set - i.e. that pval exists % in the directory as a function valid=1; errmsg=''; %=== Get pname if strcmp(pname,'Family') if ~isempty(pval) switch pval case 'binomial' % ok case 'normal' % ok otherwise % not ok valid=0; errmsg='Family must be ''binomial'' or ''normal''.'; end end end end function [options] = validateConsistency(options) paramsChecked = {'Save'}; for k=1:length(paramsChecked) param = paramsChecked{k}; pval = options.(param); switch param case 'Save' if mod(options.Iterations,pval)>0 warning(sprintf('forest_opt_set:%s:NotIntegerMultiple', mfilename), ... 'Value of ''Iterations'', %g, is not an integer multiple of''Save'', %g..',... options.Iterations,pval); end case 'Family' pval = lower(pval); options.(param) = pval; otherwise % Recite Acadian Poetry ... or do nothing, your choice! % there is beauttiful Acadian Poem at http://www.gov.ns.ca/legislature/library/digitalcollection/bookpart1.stm end end end function [] = displayForestOptions fprintf('forest_opt_set PARAMETERS\n'); fprintf('\n'); fprintf(' Trees - The number of trees in each forest\n'); fprintf(' [ positive integer | {200} (1,Inf) ]\n'); fprintf(' Iterations - The number of iterations per MCMC run\n'); fprintf(' [ positive integer | {20000} (1,Inf) ]\n'); fprintf(' Resets - The number of MCMC resets\n'); fprintf(' [ positive integer | {2} (1,Inf) ]\n'); fprintf(' Save - The frequency to save the model after burn-in\n'); fprintf(' [ positive integer | {2000} (1,Inf) ]\n'); fprintf(' BurnIn - The percent of iterations to use for burn in\n'); fprintf(' [ positive integer | {20} (0,1) ]\n'); fprintf(' Groups - Optional groups for correlated observations\n'); fprintf(' [ positive categorical integers | {data dependent} ]\n'); end