1.6. Optimal policy
When the model file contains an @optimization_problem block,
one or more of the policy equations is replaced by the planner’s
first-order conditions. RISE supports:
commitment (Ramsey policy), with or without regime switching;
discretion, linear-quadratic or nonlinear, with or without regime switching;
loose commitment – switching between commitment and discretion with a constant probability, in a linear-quadratic system;
stochastic replanning – switching between commitment and discretion with possibly time-varying probabilities, in a nonlinear system;
non-cooperative games with multiple policymakers, Nash or Stackelberg, with a further choice between open-loop equilibrium (OLE, the historical default) and Markov-perfect equilibrium (MPE) at solve time.
If you instead want to keep all the model equations and only pick the coefficients of a given (e.g. Taylor) rule optimally, see Optimized simple rules in the legacy chapter – the surface is unchanged.
1.6.1. The modern distinctive
In the legacy toolbox, commitment vs discretion was pinned via a
@commitment marker inside the @optimization_problem block
and via a commitment parameter declared alongside the
calibration. The two paths could disagree silently.
In the modern toolbox, the model file declares the game; the
solve call selects the equilibrium concept. There is no
@commitment marker in the model file, and there is no
commitment parameter to set in your calibration (except in the
specific loose-commitment / stochastic-replanning cases that
genuinely need a switching commitment indicator). The relevant
options live on solve:
solve_policy_typeselects commitment vs discretion;solve_policy_equilibriumselects OLE vs MPE for multi-player games.
The model file does not change when you flip from commitment to discretion. See Modern architecture for the broader pattern.
1.6.2. Declaring the planner’s problem
The grammar is documented in Model file language under Optimal policy. The skeletal forms:
Single player:
@optimization_problem{
@objective = -0.5*(pi^2 + lambda_y*y^2 + lambda_i*i^2),
@discount = beta
}
When the block is present, the model must have strictly fewer
equations than endogenous variables. The missing equations are
the planner’s first-order conditions, generated by RISE. The
instrument is inferred as whichever endogenous variable does not
appear on the left-hand side of any equation in @model.
Multi-player Nash:
@optimization_problem[@no_u_turn=false]{
Monetary:
@order = 1
@discount = beta
@objective = -0.5*(pi^2 + lambda_y*y^2 + lambda_i*i^2)
@instrument = i ;
Fiscal:
@order = 1
@discount = beta
@objective = -0.5*(tau^2 + lambda_b*b^2)
@instrument = tau ;
}
When every player has the same @order, the game is Nash.
Multi-player Stackelberg:
@optimization_problem[@no_u_turn=false]{
Monetary:
@order = 1
@objective = ... @instrument = i ;
Fiscal:
@order = 2
@objective = ... @instrument = tau ;
}
When the orders differ, the game is a Stackelberg cascade with
the lower @order as the leader.
@no_u_turn = true asks RISE to skip the discretion-derivative
pipeline in exchange for a cheaper parse. Set it only if you will
only ever solve commitment / loose-commitment problems and will
not need MPE.
The grammar continues to support the legacy bracket options
(@commitment, @markov_process); they remain parseable but
the modern convention pushes commitment selection out to the solve
call.
1.6.3. Solve-time choices
Two orthogonal options on solve:
Option |
Values |
Default |
|---|---|---|
|
|
|
|
|
|
solve_policy_type:
'ramsey'– full commitment; the planner re-optimises att = 0and not again.'discretion'– time-consistent / Markov-perfect policy; the planner re-optimises every period.
solve_policy_equilibrium matters only for multi-player
games:
'OLE'– open-loop equilibrium. Each player optimises against the opponent’s path. The forward-shadow row of each FOC is the classical forward-multiplier term.'MPE'– Markov-perfect equilibrium. Each player optimises against the opponent’s policy function. The forward-shadow row picks up an additional cross-player chain-rule term that captures how the opponent’s instrument responds to the predetermined state.
All four combinations are supported:
m = solve(m, solve_policy_type = "ramsey", solve_policy_equilibrium = "OLE");
m = solve(m, solve_policy_type = "ramsey", solve_policy_equilibrium = "MPE");
m = solve(m, solve_policy_type = "discretion", solve_policy_equilibrium = "OLE");
m = solve(m, solve_policy_type = "discretion", solve_policy_equilibrium = "MPE");
Restrictions on solve_policy_equilibrium
Stochastic-replanning models reject the option. Loose-commitment and stochastic-replanning models are managed through the
commitmentswitching parameter and a Markov chain. Callingsolve_policy_equilibrium = ...on such a model errors. These model classes retain their OLE-equivalent behavior.``@no_u_turn = true`` silently degenerates MPE to OLE. The flag asks RISE to skip the discretion-derivative pipeline, which the MPE chain-rule contribution is built from; under
@no_u_turn = truethe cross-chain is zero by construction. If you want MPE, leave@no_u_turnat its default (false).Single-player consistency. With one player, MPE = OLE exactly. Toggling the option has no observable effect.
Stackelberg. The follower’s set of differentiation variables already includes the leader’s instruments and multipliers, so the cross-chain is correctly built over the same-level Nash opponents only. No user action is required.
1.6.4. Solver selection
RISE picks an appropriate solver automatically based on the model shape:
Constant-parameter problems that eigenvalue methods can handle use the default RISE solver
rise_1. Discretion can also be solved withrise_1, conditional on the solution of the forward-looking variables.Regime-switching problems use the functional-iteration solver
mfi.When
@no_u_turn = truetheloose_commitmentsolver is used; it works well in linear-quadratic setups but is less accurate for nonlinear problems, and higher-order perturbation cannot be used.
You can override the choice with solver = '+name' – per the
diagnostic protocol in Solving, this is the right move when
the default solver returns retcode 21 on a model you believe is
determinate.
1.6.5. Loose commitment and stochastic replanning
These are the cases where a switching commitment parameter
does live in the model file – the regime is whether the
planner is currently honouring commitment or has re-optimized.
Loose commitment – constant re-optimization probability, linear-quadratic:
@optimization_problem[@no_u_turn = true]{
@objective = pi^2 + lambda_y*y^2,
@discount = beta
}
@parameters(looseCommit, 2) commitment
@parameters looseCommit_tp_1_2 looseCommit_tp_2_1
The chain must have exactly two states; you choose which state has
commitment = 1 (commitment-active) vs commitment = 0
(discretion-active).
Stochastic replanning – possibly time-varying probability, nonlinear:
@optimization_problem[@no_u_turn = false]{
@objective = -0.5*(pi^2 + lambda_y*y^2),
@discount = beta
}
@parameters(stochrepl, 2) commitment
The transition probabilities may be exogenous parameters
(stochrepl_tp_1_2, stochrepl_tp_2_1) or endogenous via the
@transition_functions block – see Time-varying transition
probabilities.
To pin looseCommit_tp_1_2 = 1 - looseCommit_tp_2_1 for
estimation, use the same linear restriction syntax as for any
other parameter pair; see legacy Estimation restrictions.
1.6.6. A worked example: Tatiana’s monetary-fiscal game
The smallest fixture that exercises every
(policy, solve_policy_type, solve_policy_equilibrium) cell is
Tatiana’s monetary-fiscal game, distributed with the regression
suite. It declares four policy branches behind a rise_flags
switch – cooperative, nash, M_leader, F_leader –
without pinning commitment or the equilibrium concept, so the
{ramsey, discretion} x {OLE, MPE} cross-product is selectable
on the model object. With four policy branches this yields a
4 x 2 x 2 = 16-cell regression cube.
The model is a three-equation linearised monetary-fiscal model
with five endogenous variables (output gap, inflation, the policy
rate, a fiscal instrument, government debt), three shocks, and the
two players’ objectives written out separately. See the legacy
chapter Optimal Policy for the full tatiana.rs listing and
its driver, test_tatiana_policy_equilibria.m.
1.6.7. Nonstationary optimal policy: geometric multipliers
On a nonstationary model solved in levels (solve_bgp), the planner’s
Lagrange multipliers grow geometrically along the balanced growth path,
at heterogeneous rates, and are sign-indefinite – some negative, some
exactly zero. The additive steady-state/growth encoding used for level
variables cannot represent that, which historically left a structural
residual floor on every nonstationary optimal-policy model.
The machinery that handles it is strictly opt-in at parse time:
m = rise('mymodel', 'geometric_multipliers', true);
m = solve(m, 'solve_bgp', true, ...);
Under the option, the multiplier steady-state leads/lags are encoded
multiplicatively (lead ss*g, lag ss/g, growth slots holding gross
factors with neutral value 1), the BGP shift moves multipliers along the
geometric ray level*g^K, and the steady-state stage solves each
multiplier group’s levels and growth factors jointly (minimum-norm on
the two-point reference/shifted FOC system – the multiplier steady state
is only a point on the BGP, so the group Jacobian is singular by
construction).
Leave the option off (the default) for stationary models: the additive
encoding is what the discretion and loose-commitment machinery is
calibrated to, and the two conventions must not be mixed. Like
no_u_turn, this is a declared user intention – it is never inferred
from the model.
The power-scaling multiplier charts (multiplier_charts)
On top of geometric_multipliers, the parse option
multiplier_charts (with multiplier_numeraire, the name of one
log-declared nonstationary variable) wraps every multiplier in the
dynamic equations as MU_i = ZNUM^{B_i} * mu_i. After the
balanced-growth solve the exponents are filled from the solved growth
factors, so the scaled multipliers are stationary signed levels –
no sign classification, no zero guards; negative and exactly-zero
multipliers work natively. The static system stays chart-free by
construction, weakly-identified growths are frozen to the identity
chart with a loud warning, and the charted solve is typically faster
than the uncharted one at the same accuracy. Both representations are
exercised by the nonstationary_multipliers unit tests.
1.6.8. Where to look next
Optimal Policy (legacy DSGE chapter) – the long-form reference: full
@optimization_problemgrammar with every bracket option, the multiple-policymakers section, the MPE derivation and its equivalence with the alternative value-function-gradient formulation, the loose-commitment and stochastic-replanning treatment, and the Tatiana worked example. Canonical for the modern toolbox; folding pending review.Optimized simple rules – the alternative that keeps the policy equation and only picks its coefficients optimally.
Solving – the option surface for
solver,solve_policy_type, andsolve_policy_equilibrium, plus the diagnostic protocol when the solver returns retcode 21.Model file language (Optimal policy section) – the grammar reference for
@optimization_problem, single-player and multi-player.Time-varying transition probabilities – when the
commitmentchain’s transitions are endogenous.