If a solution corresponding to 100% of the shock can’t be found in the first
informational period, marginal linearization will be performed to extrapolate a
solution.
However, in subsequent informational periods, this extrapolated solution cannot
be used for the initial conditions of endogenous variables, because the initial
conditions are not a true solution of the nonlinear model. For those subsequent
informational periods, the correct approach is to compute the two solutions
needed for marginal linearization using as initial conditions the values
obtained in the same two solutions for the previous informational
periods (stored as oo_.deterministic_simulation.{sim1,sim2}).
First simulation before doing extrapolation is stored in several fields of
oo_.deterministic_simulation.sim1.
For marginal linearization, the second simulation used to compute the marginal
contribution is stored in oo_.deterministic_simulation.sim2.
Similarly to the regular “endval” block, any variable mentioned in this
block will jump to its new value in the period where the information is learnt.
In particular, this means that any temporary shock that may have been
anticipated on that variable (as specified through a “shocks(learnt_in=...)”
block for a previous informational period) will be overwritten.
Ensure that the block is always interpreted multiplicatively relative to the
steady state, and not relative to the pre-existing shock value (if there was
already a shock declared for the same exogenous and period(s)).
For marginal linearization, an extra simulation is needed. This extra
simulation is first computed using the first simulation as guess value. If that
does not work, the present commits adds an additional attempt for computing
that extra simulation, using a full homotopy loop from the beginning.
As a consequence, the present commits puts the homotopy loop in a dedicated
function.
Only modify oo_ when the homotopy procedure is finished, now that oo_ is no
longer an input to perfect_foresight_solver_core.
By the way, fix the treatment of the exogenous steady state (it is now set
in a consistent way with the endogenous steady state, if the shock is not
simulated up to 100%).
Also fix the initial guess when doing a second attempt at recomputing the
terminal steady state and failing (in the absence of a permanent shock). It was
supposed to use the initial steady state as an initial guess for that second
attempt (through oo_.steady_state), but since that latter variable was modified
in the loop, it would actually correspond to the same initial guess as in the
first attempt.
The exogenous steady state vector was passed as a row-vector to
evaluate_steady_state, thus leading to an incorrectly-sized matrix passed to
bytecode when checking the steady state on the dynamic model (when different
from the static model).
– new option “endval_steady” to pf_setup command to recompute terminal
steady state in the homotopy loop
– new options “homotopy_linearization_fallback” and
“homotopy_marginal_linearization_fallback” to pf_solver and pfwee_solver
commands, to get an approximate solution when homotopy fails to go to 100%
– new options “homotopy_initial_step_size”, “homotopy_min_step_size”,
“homotopy_step_size_increase_success_count” and “homotopy_max_completion_share”
to pf_solver and pfwee_solver commands to fine tune the homotopy behaviour
– removed option “homotopy_alt_starting_point” to pf_solver command, not really
useful
– new options “steady_solve_algo”, “steady_tolf”, “steady_tolx”,
“steady_maxit”, “steady_markowitz” to pf_solver and pfwee_solver commands, to
control the computation of the terminal steady state (and remove the
equivalent options which previously had different names in pfwee_solver command)
– Remove the terminal_steady_state_as_guess_value option to pfwee_solver
– pfwee_setup now sets the same guess values as pf_setup (i.e. terminal steady
state at all periods)
– With constant_simulation_length option, pfwee_solver uses terminal steady
state as guess values for periods that are added to the simulation
Now uses options_.verbosity to decide what to print:
– if options_.verbosity == 0, prints nothing
– if options_.verbosity >= 1, prints iteration counter and duration, and fatal errors
– if options_.verbosity >= 2, additionally print floating point exceptions and
details about algorithmic decisions
They now only return what’s really their output (simulated paths, maximum
residual error…). This is a move towards a more functional programming style.