Support purely backward looking models (VAR, nonlinear growth models)#214
Support purely backward looking models (VAR, nonlinear growth models)#214
Conversation
…on-Expr types Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
…/etc functions Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
|
@copilot try again to fix the parsing related issues |
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
|
@copilot add a test file with the var model and also make nonlinear backward looking models work |
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Added in db479ab. Created
Both models test |
|
@copilot add another algorithm option: newton |
|
@copilot add another algorithm option: newton |
…cobian functions Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Implemented in 884b1fa. Added:
|
| past_not_future_and_mixed_idx = 𝓂.timings.past_not_future_and_mixed_idx | ||
|
|
||
| # Create the state update function | ||
| function state_update_newton(state::Vector{T}, shock::Vector{S}) where {T, S} |
There was a problem hiding this comment.
@copilot you need to add the steady state values before evaluating the residual and jacobian functions and substract it before returning the results
There was a problem hiding this comment.
Fixed in 1359ddb. The create_newton_state_update() function now:
- Adds steady state values to past variables from the input state (converting from deviations to levels)
- Evaluates residual and jacobian functions with values in levels
- Subtracts steady state from the result before returning (converting back to deviations)
Verified: VAR model still matches first_order exactly (max diff < 1e-16), and Solow growth model produces slightly different results as expected for nonlinear models.
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
|
@copilot call the argument "plot_baseline" "reference" instead |
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
|
@copilot also rename "deviations_from" as "reference" |
thorek1
left a comment
There was a problem hiding this comment.
also for get_conditional_forecast using backward looking models the default algorithm should be :newton
| conditions[z_idx, 1] = 0.02 # Condition z in period 1 | ||
| conditions[z_idx, 2] = 0.01 # Condition z in period 2 | ||
|
|
||
| cf_newton = get_conditional_forecast(SolowGrowth, conditions, algorithm = :newton) |
There was a problem hiding this comment.
@copilot also here given a backward looking model the default should be :newton and not first order (same for the plot irf and plot conditional forecast functions)
There was a problem hiding this comment.
Done in 5948038. Updated plot_irf!, plot_conditional_forecast, and plot_conditional_forecast! to use :newton as default algorithm for backward looking models. Also fixed duplicate reference parameter in plot_irf.
…ions Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Done in 5948038. Updated |
thorek1
left a comment
There was a problem hiding this comment.
in the plot_irf, plot_irf!, plot_conditional_forecast, and plot_conditional_forecast! functions, add the reference argument and implement the logic such that when it is :steady_state, then the current behaviour is executed. when it is :baseline, then the solid black line which normally refers to the reference steady state becomes the baseline. the baseline is the dynamics in levels starting from the initial state and propagating forward without shocks
…ast, plot_conditional_forecast! Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Done in f23d759. Added
For |
| import DataStructures: OrderedSet | ||
| import SparseArrays: SparseMatrixCSC | ||
| import NLopt | ||
| import Statistics: mean |
There was a problem hiding this comment.
@copilot dont use Statistics here. this is a heavy dependency. also mean is a very easy function. find alternatives
There was a problem hiding this comment.
Done in ef33187. Removed the Statistics import and replaced mean(filter(isfinite, baseline_path)) with sum(finite_baseline_vals) / length(finite_baseline_vals).
Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
…adjust plot_data calculation
| # irf_data is in deviations from baseline, so we add baseline_path to get levels | ||
| plot_data = irf_data # .+ baseline_path | ||
| finite_baseline_vals = filter(isfinite, baseline_path) | ||
| ref_for_dual_axis = first(finite_baseline_vals) |
There was a problem hiding this comment.
@copilot use the initial state as reference instead of the first period value (which this implies)
There was a problem hiding this comment.
Done in 7b76497. The dual axis reference now uses the initial state value in levels (initial_state + NSSS) instead of the first period of the baseline simulation.
…value Co-authored-by: thorek1 <13523097+thorek1@users.noreply.github.com>
Summary
This PR adds support for purely backward looking models and implements the
:newtonalgorithm option for simulating them.Changes Made
New Features
Default algorithm for backward looking models:
DEFAULT_ALGORITHM_BACKWARD_LOOKING = :newtonconstant:newtonalgorithm when model is backward looking (nFuture_not_past_and_mixed == 0):get_irfget_conditional_forecastplot_irfplot_irf!plot_conditional_forecastplot_conditional_forecast!algorithm = :first_orderif neededNew
referencekeyword argument:referenceparameter toget_irf,plot_irf,plot_irf!,plot_conditional_forecast, andplot_conditional_forecast!with options::steady_state(default for non-backward models): deviations from relevant steady state (existing behavior), black horizontal reference line:baseline(default for backward models): deviations from the no-shock path starting frominitial_state, black line shows baseline path (can be time-varying)reference = :baseline:initial_statelevels = trueStructural Refactoring
structures.jl:
jacobian_functojacobian_state_funcfor clarityjacobian_shock_func- jacobian w.r.t. shocks (for conditional forecasting)lu_buffer::𝒮.LinearCachefor LinearSolve caching in Newton iterationsjac_state_bufferandjac_shock_bufferfor conditional forecastingmacros.jl:
backward_looking_solutionin solution struct with updated buffers:newtonto available algorithmsMacroModelling.jl:
algorithm == :newtonconditionwrite_newton_simulation_functions!()creates buffersreferenceparameterget_functions.jl:
get_irfandget_conditional_forecastto use dynamic default algorithm based on model typereferenceparameter with validation and documentationreferenceparameter\operator for matrix operationsfind_newton_shockswhen no conditions in a periodStatsPlotsExt.jl:
standard_subplotto accept optionalbaseline_pathandinitial_valueparametersplot_irfcomputes baseline path and initial state in levels whenreference = :baselinefor backward looking modelsreferenceparameter toplot_irf!,plot_conditional_forecast, andplot_conditional_forecast!meanwithsum/lengthfor computing reference valuesTests (test_backward_looking_models.jl)
:newtonalgorithm (no need to explicitly specify for backward looking models)reference = :baselinetests for explosive model identityirf_baseline + baseline_lev ≈ irf_levStatus
:newtonin all relevant functionsreferenceparameter implemented forget_irf,plot_irf,plot_irf!,plot_conditional_forecast,plot_conditional_forecast!reference = :baselineplots time-varying baseline path instead of horizontal steady state lineOriginal prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.