|
| 1 | +% @file DRAMOptions |
| 2 | +% @brief A class for sanity checks of DRAM algorithm (MCMC samling) in PESTO |
| 3 | + |
| 4 | +classdef DRAMOptions < matlab.mixin.SetGet |
| 5 | + % DRAMOptions provides an option container to pass options as subclass |
| 6 | + % into the PestoSamplingOptions class. |
| 7 | + % |
| 8 | + % This file is based on AMICI amioptions.m (http://icb-dcm.github.io/AMICI/) |
| 9 | + |
| 10 | + properties |
| 11 | + %% Delayed Rejection Adaption Metropolis options |
| 12 | + % Note: This algorithm uses a delayed rejection scheme for better mixing. |
| 13 | + |
| 14 | + % --- Delayed Rejection Adaptive Metropolis --- |
| 15 | + % opt.DRAM.regFactor : This factor is used for regularization in |
| 16 | + % cases where the single-chain proposal |
| 17 | + % covariance matrices are ill conditioned. |
| 18 | + % Larger values equal stronger |
| 19 | + % regularization. |
| 20 | + % opt.DRAM.nTry : The number of tries in the delayed |
| 21 | + % rejection scheme |
| 22 | + % opt.DRAM.verbosityMode : Defines the level of verbosity 'silent', 'visual', |
| 23 | + % 'debug' or 'text' |
| 24 | + % opt.DRAM.adaptionInterval : Updates the proposal density only every opt.DRAM.adaptionInterval |
| 25 | + % time |
| 26 | + |
| 27 | + regFactor = 1e-6; |
| 28 | + nTry = 1; |
| 29 | + verbosityMode = 'text'; |
| 30 | + adaptionInterval = 1; |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | + end |
| 35 | + |
| 36 | + properties (Hidden) |
| 37 | + end |
| 38 | + |
| 39 | + methods |
| 40 | + function obj = DRAMOptions(varargin) |
| 41 | + % DRAMOptions Construct a new DRAMOptions object |
| 42 | + % |
| 43 | + % OPTS = DRAMOptions() creates a set of options with |
| 44 | + % each option set to itsdefault value. |
| 45 | + % |
| 46 | + % OPTS = DRAMOptions(PARAM, VAL, ...) creates a set |
| 47 | + % of options with the named parameters altered with the |
| 48 | + % specified values. |
| 49 | + % |
| 50 | + % OPTS = DRAMOptions(OLDOPTS, PARAM, VAL, ...) |
| 51 | + % creates a copy of OLDOPTS with the named parameters altered |
| 52 | + % with the specified value |
| 53 | + % |
| 54 | + % Note to see the parameters, check the |
| 55 | + % documentation page for DRAMOptions |
| 56 | + |
| 57 | + % adapted from SolverOptions |
| 58 | + |
| 59 | + if nargin > 0 |
| 60 | + |
| 61 | + % Deal with the case where the first input to the |
| 62 | + % constructor is a amioptions/struct object. |
| 63 | + if isa(varargin{1},'DRAMOptions') |
| 64 | + if strcmp(class(varargin{1}),class(obj)) |
| 65 | + obj = varargin{1}; |
| 66 | + else |
| 67 | + % Get the properties from options object passed |
| 68 | + % into the constructor. |
| 69 | + thisProps = properties(obj); |
| 70 | + % Set the common properties. Note that we |
| 71 | + % investigated first finding the properties that |
| 72 | + % are common to both objects and just looping over |
| 73 | + % those. We found that in most cases this was no |
| 74 | + % quicker than just looping over the properties of |
| 75 | + % the object passed in. |
| 76 | + for i = 1:length(thisProps) |
| 77 | + try %#ok |
| 78 | + % Try to set one of the properties of the |
| 79 | + % old object in the new one. |
| 80 | + obj.(thisProps{i}) = varargin{1}.(thisProps{i}); |
| 81 | + end |
| 82 | + end |
| 83 | + end |
| 84 | + firstInputObj = true; |
| 85 | + elseif isstruct(varargin{1}) |
| 86 | + fieldlist = fieldnames(varargin{1}); |
| 87 | + for ifield = 1:length(fieldlist) |
| 88 | + obj.(fieldlist{ifield}) = varargin{1}.(fieldlist{ifield}); |
| 89 | + end |
| 90 | + firstInputObj = true; |
| 91 | + elseif isempty(varargin{1}) |
| 92 | + firstInputObj = true; |
| 93 | + else |
| 94 | + firstInputObj = false; |
| 95 | + end |
| 96 | + |
| 97 | + % Extract the options that the caller of the constructor |
| 98 | + % wants to set. |
| 99 | + if firstInputObj |
| 100 | + pvPairs = varargin(2:end); |
| 101 | + else |
| 102 | + pvPairs = varargin; |
| 103 | + end |
| 104 | + |
| 105 | + % Loop through each param-value pair and just try to set |
| 106 | + % the option. When the option has been fully specified with |
| 107 | + % the correct case, this is fast. The catch clause deals |
| 108 | + % with partial matches or errors. |
| 109 | + haveCreatedInputParser = false; |
| 110 | + for i = 1:2:length(pvPairs) |
| 111 | + try |
| 112 | + obj.(pvPairs{i}) = pvPairs{i+1}; |
| 113 | + catch ME %#ok |
| 114 | + |
| 115 | + % Create the input parser if we haven't already. We |
| 116 | + % do it here to avoid creating it if possible, as |
| 117 | + % it is slow to set up. |
| 118 | + if ~haveCreatedInputParser |
| 119 | + ip = inputParser; |
| 120 | + % Structures are currently not supported as |
| 121 | + % an input to optimoptions. Setting the |
| 122 | + % StructExpand property of the input parser to |
| 123 | + % false, forces the parser to treat the |
| 124 | + % structure as a single input and not a set of |
| 125 | + % param-value pairs. |
| 126 | + ip.StructExpand = false; |
| 127 | + % Get list of option names |
| 128 | + allOptionNames = properties(obj); |
| 129 | + for j = 1:length(allOptionNames) |
| 130 | + % Just specify an empty default as we already have the |
| 131 | + % defaults in the options object. |
| 132 | + ip.addParameter(allOptionNames{j}, []); |
| 133 | + end |
| 134 | + haveCreatedInputParser = true; |
| 135 | + end |
| 136 | + |
| 137 | + % Get the p-v pair to parse. |
| 138 | + thisPair = pvPairs(i:min(i+1, length(pvPairs))); |
| 139 | + ip.parse(thisPair{:}); |
| 140 | + |
| 141 | + % Determine the option that was specified in p-v pairs. |
| 142 | + % These options will now be matched even if only partially |
| 143 | + % specified (by 13a). Now set the specified value in the |
| 144 | + % options object. |
| 145 | + optionSet = setdiff(allOptionNames, ip.UsingDefaults); |
| 146 | + obj.(optionSet{1}) = ip.Results.(optionSet{1}); |
| 147 | + end |
| 148 | + end |
| 149 | + end |
| 150 | + end |
| 151 | + |
| 152 | + function new = copy(this) |
| 153 | + new = feval(class(this)); |
| 154 | + |
| 155 | + p = properties(this); |
| 156 | + for i = 1:length(p) |
| 157 | + new.(p{i}) = this.(p{i}); |
| 158 | + end |
| 159 | + end |
| 160 | + |
| 161 | + %% Part for checking the correct setting of options |
| 162 | + function set.regFactor(this, value) |
| 163 | + if(isnumeric(value) && value > 0) |
| 164 | + this.regFactor = lower(value); |
| 165 | + else |
| 166 | + error(['Please specify a positive regularization factor for ill conditioned covariance'... |
| 167 | + ' matrices of the adapted proposal density, e.g. ' ... |
| 168 | + 'PestoSamplingOptions.DRAM.regFactor = 1e-5']); |
| 169 | + end |
| 170 | + end |
| 171 | + |
| 172 | + function set.nTry(this, value) |
| 173 | + if(isnumeric(value) && value > 0) |
| 174 | + this.nTry = lower(value); |
| 175 | + else |
| 176 | + error(['Please specify a positive number of maximum tries, e.g. ' ... |
| 177 | + 'PestoSamplingOptions.DRAM.nTry = 3']); |
| 178 | + end |
| 179 | + end |
| 180 | + |
| 181 | + function set.verbosityMode(this, value) |
| 182 | + if (strcmp(value, 'text') || strcmp(value, 'silent') || strcmp(value, 'debug')) |
| 183 | + this.verbosityMode = lower(value); |
| 184 | + else |
| 185 | + error(['Please specify a verbosity mode, e.g. ' ... |
| 186 | + 'PestoSamplingOptions.DRAM.verbosityMode = "text"']); |
| 187 | + end |
| 188 | + end |
| 189 | + |
| 190 | + function set.adaptionInterval(this, value) |
| 191 | + if(isnumeric(value) && value > 0) |
| 192 | + this.adaptionInterval = lower(value); |
| 193 | + else |
| 194 | + error(['Please specify the adaption inteval, e.g. ' ... |
| 195 | + 'PestoSamplingOptions.DRAM.adaptionInterval = 1']); |
| 196 | + end |
| 197 | + end |
| 198 | + |
| 199 | + end |
| 200 | +end |
| 201 | + |
| 202 | + |
| 203 | + |
| 204 | + |
| 205 | + |
| 206 | + |
| 207 | + |
| 208 | + |
| 209 | + |
| 210 | + |
| 211 | + |
| 212 | + |
| 213 | + |
| 214 | + |
| 215 | + |
| 216 | + |
| 217 | + |
| 218 | + |
| 219 | + |
| 220 | + |
| 221 | + |
| 222 | + |
| 223 | + |
| 224 | + |
| 225 | + |
0 commit comments