1.3. Posterior maximization

The mode step of estimation – maximising the posterior kernel (or, with flat priors, the likelihood) – is run by an optimizer. RISE ships several and lets you plug in your own; the same machinery is used by maximum-likelihood and Bayesian estimation, by optimal simple rules, and by indirect inference (all of which reduce to “minimise an objective over a bounded parameter vector”).

1.3.1. Choosing an optimizer

The optimizer is selected with the optimizer option, either when building the model or when calling estimate:

m    = set(m, 'optimizer', 'fmincon');           % the default
mest = estimate(m, 'data', db, 'priors', priors, 'optimizer', 'wcsminwel');

To pass options through to the chosen optimizer, give a cell {name, opts}:

opt          = optimset('fmincon');
opt.MaxIter  = 2000;
opt.MaxTime  = 3600;                             % seconds
opt.TolFun   = 1e-8;  opt.TolX = 1e-8;
opt.Display  = 'iter';
mest = estimate(m, 'data', db, 'priors', priors, 'optimizer', {'fmincon', opt});

The common controls (MaxIter, MaxFunEvals, MaxTime, TolFun, TolX, Display, and – for population methods – MaxNodes) are honoured across optimizers; estimate also reports which optimizer was used in print_estimation_results.

1.3.2. Bundled optimizers

  • MATLAB’s fmincon (the default; SQP), and fminunc / fminsearch – the unconstrained ones are used through bounded wrappers (fminunc_bnd / fminsearch_bnd) so that the parameter bounds are respected. patternsearch is available if you have the Global Optimization Toolbox.

  • wcsminwel – a robust quasi-Newton optimizer (Sims’s csminwel, with a restart heuristic) that copes well with awkward likelihood surfaces.

  • wnewrat – a Newton-type optimizer with a numerically computed Hessian.

  • wgmhmaxlik – a Metropolis-Hastings-based optimizer that explores the surface while climbing it (useful as a robust pre-conditioner before a local method).

  • bee_gate – the artificial bee-colony algorithm, a population-based global metaheuristic; see also Stochastic Global Optimization for the broader family of nature-inspired global optimizers.

  • a simulated-annealing optimizer.

  • blockwise_optimization – optimises the parameters block by block, which helps when there are many of them.

These live in the m/optimizers/ folder of the toolbox.

Quick reference

Optimizer

Family

Scope

Uses Hessian

Parallel

Typical use case

fmincon

SQP / interior-point

local

approximated

via UseParallel

default; smooth, well-scaled likelihoods

fminunc_bnd

quasi-Newton (BFGS)

local

approximated

no

smooth, no constraints needed beyond bounds

fminsearch_bnd

Nelder-Mead simplex

local

no

no

very small problems; non-smooth objectives

patternsearch

direct search (GPS / MADS)

local

no

via Global Opt Toolbox

non-smooth / noisy objectives (requires Global Opt Toolbox)

wcsminwel

quasi-Newton (Sims) + restart

local

returned at end

no

robust on awkward DSGE likelihood surfaces; common default choice after fmincon

wnewrat

Newton with numerical Hessian (Ratto)

local

numerical

no

mode polishing after a global pass

wgmhmaxlik

MH-driven climb (Adjemian)

local-with-exploration

no

no

pre-conditioner before a local method on multi-modal surfaces

bee_gate

artificial bee colony

global (population)

finite-difference at end

yes

older global default; superseded by the +globalopt family

rise_lshade / rise_jso / rise_cma_es / rise_de / rise_abc / rise_aco / rise_bbo / rise_agsk / rise_mads

+globalopt family

global (population, or deterministic for rise_mads)

finite-difference at end

yes (per algorithm)

global mode search; see Stochastic Global Optimization for the per-algorithm philosophy and hyperparameters

simulated annealing (sa.gmhmaxlik)

thermal random walk

global

no

no

robust, slow; legacy

blockwise_optimization

dispatcher

same as inner

same as inner

same as inner

wraps any of the above to optimise parameters block-by-block; triggered automatically when estim_blocks is non-empty

Options accepted across optimizers

Every bundled optimizer reads the same MATLAB-style fields from its options struct where they apply:

Field

Meaning

Default

MaxIter

iteration cap

1000

MaxFunEvals

total function-eval cap

inf

MaxTime

wall-clock cap (seconds)

inf

TolFun

objective tolerance

1e-6

TolX

step tolerance

1e-6

Display

'iter' / 'on' / 'off'

'off'

MaxNodes

population size (population methods only)

algorithm-specific

ObjectiveLimit

early-stop floor for the objective

-inf

Algorithm-specific hyperparameters (F, CR for rise_de; sigma0 for rise_cma_es; limit for rise_abc; etc.) are not part of this common surface. They are documented per algorithm in Stochastic Global Optimization and can be threaded through estimate by writing a thin wrapper that closes over the desired hyper struct.

1.3.3. Running several optimizers in turn

A common strategy is to locate the right basin with a global search and then polish the mode with a fast local method. RISE supports running optimizers one after another – each starting from the previous one’s solution; see help dsge/estimate for the exact syntax.

1.3.4. User-defined optimizers

optimizer may also be a function (a function name or a handle) implementing RISE’s optimizer interface – roughly

[x, f, exitflag, output] = myOptimizer(objfun, x0, lb, ub, options)

where objfun(x) returns the value to minimise, x0 is the starting point, lb/ub the bounds, and options the (RISE-augmented) options struct. Any of the bundled optimizers (e.g. wcsminwel.m) is a usable template; see Extending the DSGE functionalities.

Interface specification

The exact signature the estimation engine calls, lifted from @dsge/estimate.m:

[xfinal, ffinal, exitflag, H] = optimizer(fh, x0, lb, ub, options, varargin)

Inputs:

  • fh – function handle. The engine calls fval = fh(x) where x is a column vector inside [lb, ub]. RISE wraps the posterior kernel here, so fh returns a scalar to be minimised (the negative log posterior). The wrapper handles all the bookkeeping (parameter assignment, model resolve, filter, prior, penalties for general restrictions); the optimizer just sees a scalar objective on a box.

  • x0 – starting point as a column vector, dimension n.

  • lb, ub – column vectors of lower and upper bounds, also dimension n. RISE guarantees lb <= x0 <= ub.

  • options – struct with the MATLAB-style fields listed in the Options accepted across optimizers table above. Optimizers should read what they understand and ignore the rest.

  • varargin – the trailing entries of the {name, ...} cell the user passed under 'optimizer'. For example, estimate(m, 'optimizer', {'fmincon', 'MaxFunEvals', 1000}) forwards {'MaxFunEvals', 1000} to the optimizer as varargin.

Outputs:

  • xfinal – column vector of length n with the best parameter vector found. Must satisfy lb <= xfinal <= ub.

  • ffinal – scalar value fh(xfinal).

  • exitflag – integer, in the style of MATLAB’s optimizers (1 = converged successfully, 0 = budget exhausted, negative = failed).

  • Hn x n estimate of the Hessian at xfinal. May be a finite-difference Hessian or one produced by the algorithm itself. Returning a positive-definite H is helpful but not required; if the optimizer cannot produce one, return [] and the estimation engine falls back to a finite-difference pass.

RISE-added options

The options struct is a plain MATLAB-style optimisation options struct. RISE itself does not inject extra fields into it. What RISE does add to the estimation call is a separate option, estim_blocks: when non-empty, the engine routes the user-chosen optimizer through blockwise_optimization, which calls the optimizer once per parameter block. The optimizer sees a smaller x0 / lb / ub corresponding to one block at a time, but its own interface is unchanged.

Manual stopping is honoured by every optimizer in the +globalopt family (rise_lshade etc.): drop a file named ManualStoppingFile.txt in the working directory and the next iteration boundary returns the current best.

Minimal worked example

A trivial user-defined optimizer that wraps fmincon and prints a banner before delegating. The pattern is the same for anything more elaborate:

function [xfinal, ffinal, exitflag, H] = myOptimizer(fh, x0, lb, ub, options, varargin)

fprintf('myOptimizer: %d parameters, MaxIter=%d\n', ...
        numel(x0), options.MaxIter);

opt = optimoptions('fmincon', ...
    'MaxIterations',           options.MaxIter, ...
    'MaxFunctionEvaluations',  options.MaxFunEvals, ...
    'OptimalityTolerance',     options.TolFun, ...
    'StepTolerance',           options.TolX, ...
    'Display',                 options.Display);

[xfinal, ffinal, exitflag, ~, ~, ~, H] = ...
    fmincon(fh, x0, [], [], [], [], lb, ub, [], opt);

end

Plug in by name (the function must be on the MATLAB path) or by handle:

m = estimate(m, 'data', db, 'priors', priors, 'optimizer', @myOptimizer);

Any of the bundled wrappers (wcsminwel.m, wnewrat.m, wgmhmaxlik.m, bee_gate.m) is a fuller worked example of the same pattern, including the translation between RISE option names and the underlying solver’s argument list.