Troubleshooting ================ This page gathers the most common things that go wrong in a RISE workflow, how to diagnose them, and what to try. The single most useful diagnostic is ``decipher`` -- always run it first when a ``retcode`` comes back non-zero. Deciphering return codes ------------------------ Most RISE entry points (``solve``, ``filter``, ``estimate``, ``forecast``, ``simulate``) return a ``retcode`` integer alongside their main outputs. A non-zero value signals a problem; ``decipher`` turns it into a sentence:: [m, retcode] = solve(m); if retcode ~= 0 decipher(retcode) % prints the explanation msg = decipher(retcode); % or capture as a string end ``decipher`` accepts a scalar or a vector of codes. Codes are organised by the stage of the pipeline that emits them. Codes by category ~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 18 25 57 * - Range - Stage - Codes * - 1-7, 11 - **Evaluating the system** - ``1`` steady state could not solve; ``2`` NaNs in Jacobian; ``3`` problem in transition matrix; ``4`` parameter restrictions violated; ``5`` NaN/Inf/complex definitions; ``6`` NaN/Inf in planner objective; ``7`` bounds or restrictions violated; ``11`` complex or NaN steady-state residuals. * - 21-28, 201-263 - **Solving the system** - ``21`` max iterations or multiple solutions; ``22`` NaNs in solution / no solution; ``23`` explosion limit reached; ``24`` explosive solution; ``25`` system unstable; ``26`` VAR approximation to the DSGE failed; ``27`` log-expansion of a near-zero steady state; ``28`` transition matrix must be diagonal for this solver; ``201``/``202`` non-DSGE max iters / NaNs in solution; ``210``/``230`` discretionary outer loop hit max-iter / explosion-limit; ``223`` complex solution; ``251`` DSGE-VAR solution: system unstable; ``261`` DSGE prior not proper (need lambda*T > k); ``262`` DSGE-VAR covariance not positive definite; ``263`` SVAR solution matrix not invertible. * - 301-313 - **Filtering / likelihood** - ``301`` Lyapunov solve out of iterations; ``302`` NaNs in Lyapunov; ``303`` Lyapunov explosion limit reached; ``304`` failure of covariance in sigma points; ``305`` covariance of forecast errors not positive definite; ``306`` unlikely parameter vector; ``307`` NaN/Inf/complex log prior; ``308`` inconsistent ergodic probabilities; ``309`` user-defined endogenous priors failed; ``310`` NaN/Inf in initial state vector; ``311`` NaN/Inf in initial covariance matrix; ``312`` NaN/Inf/complex likelihood; ``313`` forecast covariance positive definite but determinant 0. * - -403 to 405, 4002 - **Optimization** (mode search) - ``400`` too many function evaluations or iterations; ``402-405`` step / objective / search-direction change too small (normal convergence stops, not errors); ``-401`` terminated by output / plot function; ``-402`` no feasible point / bounds inconsistent; ``-403`` trust-region radius too small (problem unbounded); ``4002`` finding hyperparameters failed. * - 500 - **Data** - ``500`` no actual data or simulation provided for filtering / estimation. * - 603-604 - **Code generation** (writing functions to disk) - ``603`` empty cell; ``604`` cell content is not a function handle. * - 701-707 - **Forecasting / simulation** - ``701`` constraint violation; ``702`` rank deficiency in null and column spaces; ``703`` no feasible path; ``704`` invalid simulation (complex solutions or pruning needed); ``705`` more restrictions than shocks; ``706`` too few forward-looking steps to handle the constraint(s); ``707`` invalid simulation (generic). * - 801 - **VAR** - ``801`` no suitable rotation could be found. The canonical table (the single source of truth) lives in ``m/+utils/+error/registry.m``; ``decipher`` reads it and prints the message for a given code. ``decipher`` is also re-exposed as a top-level shortcut (``m/shortcuts/decipher.m``), and the codes are available as named constants via ``utils.error.codes``. When the steady state does not solve ------------------------------------ The first thing ``solve`` does is build a steady state. The most common causes of failure (retcodes ``1``, ``11``): #. **Parameters not all assigned.** Check ``any(isnan(m.parameter_values))`` (or ``isnan(m)`` for the same thing on the model object). Missing parameters surface as NaN propagation through the residual function. #. **Non-stationary model on a stationary solver.** If the model has a balanced growth path, tell RISE:: m = set(m, 'solve_bgp', true); #. **User-supplied analytical steady state.** If a ``@steady_state_model`` block or an external ``sstate_file`` is in play, the most likely cause of failure is a bug in that block or file rather than in RISE. Verify against a small test case (parameters where the steady state is known by hand). #. **Variables that can only be positive** (consumption, capital, prices) freely sampled into the negative orthant by the steady-state solver. Either set their bounds accordingly, or declare them as log variables:: @endogenous(log) C, K, P #. **Starting point.** The default ``solve_initialization='backward'`` suits most models; for a model where backward solution diverges, try ``'zeros'`` or ``'random'``:: m = set(m, 'solve_initialization', 'zeros'); #. **Tolerances or iteration caps.** The steady-state solver is controlled by ``fix_point_TolFun`` and ``fix_point_maxiter``. Loosen the tolerance or bump the iteration cap if the residuals are merely *close* to zero. When the model does not solve (but the steady state does) --------------------------------------------------------- If the steady state is fine but the policy / state-space solution fails, you are looking at a Blanchard-Kahn-style problem (retcodes ``22``, ``24``, ``25``) or numerical breakdown (``23``, ``223``): - **Indeterminacy / no solution** (``22``, ``25``): typically a mis-specified expectations channel or a missing equation pinning a forward-looking variable. Check that the number of forward-looking variables matches the number of structural shocks plus exogenous jumps. - **Explosive solution** (``24``): a sunspot in disguise, or a parameter region where the system has no stable rational-expectations equilibrium. Move the parameter vector, or constrain the prior. - **Explosion limit reached** (``23``): the solver's iterates grew beyond ``fix_point_explosion_limit`` (default ``1e12``); often a symptom of a bad starting policy from regime switching with too few outer iterations -- increase ``fix_point_maxiter``. - **Complex solution** (``223``): generally means the chosen solver is not appropriate for the model class (e.g. a non-Markovian solver on a regime-switching model). Try a different solver:: m = set(m, 'solver', 'mfi'); - **Log-expansion of a near-zero steady state** (``27``): a variable declared ``@endogenous(log)`` has a steady state too close to zero. Either remove the ``log`` annotation or rescale the model so the steady state is well away from the floor. When filtering or likelihood fails ---------------------------------- The estimation engine wraps the filter inside the objective; a ``retcode`` from the filter propagates up as a ``-Inf`` log likelihood. The frequent codes: - **305** / **313** (covariance of forecast errors not positive definite, or positive definite but determinant 0): typically a sign that two observables are nearly collinear, or that an observable has near-zero variance in the simulated distribution. Check ``cov(data)`` and add a small measurement error if needed. - **306** (unlikely parameter vector): the prior puts essentially zero mass on the candidate. Verify the prior bounds match the model scale. - **307** (NaN/Inf/complex log prior): a prior distribution returned a non-finite value on the candidate vector. Print the candidate and check it against each prior's support. - **308** (inconsistent ergodic probabilities): the regime-switching transition matrix is mis-built; verify ``sum(m.markov_chains.transition_matrix, 2) == 1``. - **309** (endogenous priors failed): the user-supplied ``estim_endogenous_priors`` callback errored or returned a non-finite value. - **310** / **311** (NaN/Inf in initial state vector / covariance matrix): the unconditional moments don't exist; usually a unit-root variable that was not declared as such. - **312** (NaN/Inf/complex likelihood): the filter completed but the log-likelihood is not a real finite scalar. Usually a downstream consequence of a near-singular forecast covariance. Debug toggles ------------- .. list-table:: :header-rows: 1 :widths: 25 75 * - Toggle - Effect * - ``debug`` - general verbose mode; prints intermediate diagnostics in ``solve`` and ``estimate``:: m = set(m, 'debug', true); * - ``parse_debug`` - detailed parser tracing (model-file processing):: m = rise('mymodel', 'parse_debug', true); * - ``fix_point_verbose`` - per-iteration diagnostics from the fixed-point solvers (steady state, regime-switching solve, loose commitment):: m = set(m, 'fix_point_verbose', true); * - ``Display`` - ``'iter'`` / ``'on'`` / ``'off'`` for any bundled optimizer; surfaces objective values and step sizes during the mode search. Tightening tolerances and iteration caps ---------------------------------------- When a solve / filter / estimate "almost works", these are the knobs: .. list-table:: :header-rows: 1 :widths: 35 45 20 * - Option - Controls - Default * - ``fix_point_TolFun`` - convergence tolerance for fixed-point solvers (steady state, MS solve, loose commitment) - ``sqrt(eps)`` * - ``fix_point_maxiter`` - max iterations for the same - ``1000`` * - ``fix_point_discretion_maxiter`` - max iterations for the discretion / stochastic-replanning fixed point - ``100`` * - ``fix_point_explosion_limit`` - absolute-value cutoff that triggers a "diverged" early stop - ``1e12`` * - ``TolFun`` / ``TolX`` - optimizer-side tolerances - ``1e-6`` / ``1e-6`` * - ``MaxIter`` / ``MaxFunEvals`` - optimizer-side iteration / eval caps - optimizer-specific Profiling --------- When a workflow is slow but correct, the recipe is the same as for any MATLAB code: .. code-block:: matlab profile -timer 'cpu' on % the slow call (e.g. an estimation) m = estimate(m, 'data', db, 'priors', priors); profile off profile viewer Reading the resulting report, the bottleneck candidates ranked by how often they bite in RISE: #. **Symbolic differentiation** (one-shot, parse time). Dominant on large models -- 5000+ equations may take minutes. Once paid, it is cached in the model's ``+routines`` package and not redone unless the model file changes. #. **Evaluation of compiled derivatives**, per iteration of the objective. The standard bottleneck inside MCMC and posterior maximization. #. **Forecasting step inside filtration.** For multi-regime models the regime-conditional forecast is the most expensive part of the likelihood evaluation. #. **Loops in filtration** for long sample / many regimes -- usually vectorised already, but worth checking after a user-defined filter change. #. **Automatic differentiation** if ``solve_order >= 2`` and higher-order derivatives are recomputed every iteration -- consider caching at compile time where the model structure allows. #. **Inaccuracies in numerical derivatives** -- not a speed problem per se, but a convergence problem that looks like one when the optimizer wastes iterations on noisy gradients. #. **Disk I/O** if ``solve_function_mode = 'disk'`` is set; default is in-memory. Disk mode is opt-in; switch back if your model is small enough. The estimation summary printed by ``print_estimation_results`` reports the wall-clock time, the number of function evaluations, and the optimizer used -- a useful first cut before reaching for ``profile``.