Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions benchmark/benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,19 @@ function run_benchmarks!(𝓂::ℳ, SUITE::BenchmarkGroup)

SUITE[𝓂.model_name]["qme"] = BenchmarkGroup()

sol, qme_sol, solved = calculate_first_order_solution(∇₁; T = 𝓂.timings, opts = merge_calculation_options(quadratic_matrix_equation_algorithm = :schur))
sol, qme_sol, solved = calculate_first_order_solution(∇₁; T = 𝓂.timings,
opts = merge_calculation_options(quadratic_matrix_equation_algorithm = :schur),
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

clear_solution_caches!(𝓂, :first_order)

SUITE[𝓂.model_name]["qme"]["schur"] = @benchmarkable calculate_first_order_solution($∇₁; T = $𝓂.timings, opts = merge_calculation_options(quadratic_matrix_equation_algorithm = :schur)) setup = clear_solution_caches!($𝓂, :first_order)

SUITE[𝓂.model_name]["qme"]["doubling"] = @benchmarkable calculate_first_order_solution($∇₁; T = $𝓂.timings, opts = merge_calculation_options(quadratic_matrix_equation_algorithm = :doubling)) setup = clear_solution_caches!($𝓂, :first_order)
SUITE[𝓂.model_name]["qme"]["schur"] = @benchmarkable calculate_first_order_solution($∇₁; T = $𝓂.timings,
opts = merge_calculation_options(quadratic_matrix_equation_algorithm = :schur),
decomposition = $𝓂.solution.perturbation.first_order_block_decomposition) setup = clear_solution_caches!($𝓂, :first_order)

SUITE[𝓂.model_name]["qme"]["doubling"] = @benchmarkable calculate_first_order_solution($∇₁; T = $𝓂.timings,
opts = merge_calculation_options(quadratic_matrix_equation_algorithm = :doubling),
decomposition = $𝓂.solution.perturbation.first_order_block_decomposition) setup = clear_solution_caches!($𝓂, :first_order)


A = @views sol[:, 1:𝓂.timings.nPast_not_future_and_mixed] * ℒ.diagm(ones(𝓂.timings.nVars))[𝓂.timings.past_not_future_and_mixed_idx,:]
Expand Down
59 changes: 40 additions & 19 deletions src/MacroModelling.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5042,10 +5042,11 @@ function calculate_second_order_stochastic_steady_state(parameters::Vector{M},

# @timeit_debug timer "Calculate first order solution" begin

𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
opts = opts,
initial_guess = 𝓂.solution.perturbation.qme_solution)
initial_guess = 𝓂.solution.perturbation.qme_solution,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

if solved 𝓂.solution.perturbation.qme_solution = qme_sol end

Expand Down Expand Up @@ -5369,10 +5370,11 @@ function calculate_third_order_stochastic_steady_state( parameters::Vector{M},

∇₁ = calculate_jacobian(parameters, SS_and_pars, 𝓂)# |> Matrix

𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
opts = opts,
initial_guess = 𝓂.solution.perturbation.qme_solution)
initial_guess = 𝓂.solution.perturbation.qme_solution,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

if solved 𝓂.solution.perturbation.qme_solution = qme_sol end

Expand Down Expand Up @@ -5754,11 +5756,11 @@ function solve!(𝓂::ℳ;

# @timeit_debug timer "Calculate first order solution" begin

S₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
S₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
opts = opts,
initial_guess = 𝓂.solution.perturbation.qme_solution)

initial_guess = 𝓂.solution.perturbation.qme_solution,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)
if solved 𝓂.solution.perturbation.qme_solution = qme_sol end

# end # timeit_debug
Expand All @@ -5776,11 +5778,12 @@ function solve!(𝓂::ℳ;

∇̂₁ = calculate_jacobian(𝓂.parameter_values, SS_and_pars, 𝓂)# |> Matrix

Ŝ₁, qme_sol, solved = calculate_first_order_solution(∇̂₁;
T = 𝓂.timings,
Ŝ₁, qme_sol, solved = calculate_first_order_solution(∇̂₁;
T = 𝓂.timings,
opts = opts,
initial_guess = 𝓂.solution.perturbation.qme_solution)

initial_guess = 𝓂.solution.perturbation.qme_solution,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

if solved 𝓂.solution.perturbation.qme_solution = qme_sol end

write_parameters_input!(𝓂, :activeᵒᵇᶜshocks => 0, verbose = false)
Expand Down Expand Up @@ -6622,6 +6625,23 @@ function write_functions_mapping!(𝓂::ℳ, max_perturbation_order::Int;

𝓂.jacobian_SS_and_pars = buffer_SS_and_pars, func_∇₁_SS_and_pars

# precompute block decomposition for first order solution
rows, cols, _ = findnz(∇₁_dyn)
pattern_full = sparse(rows, cols, ones(Int, length(rows)), size(∇₁_dyn,1), size(∇₁_dyn,2))

T = 𝓂.timings
dynIndex = T.nPresent_only+1:T.nVars
comb = union(T.future_not_past_and_mixed_idx, T.past_not_future_idx)
sort!(comb)
f_in = indexin(T.future_not_past_and_mixed_idx, comb)
Ir = ℒ.I(length(comb))

Aplus_pattern = pattern_full[dynIndex,1:T.nFuture_not_past_and_mixed] * Ir[f_in,:]
A0_pattern = pattern_full[dynIndex,T.nFuture_not_past_and_mixed .+ range(1,T.nVars)][:,comb]
block_pattern = (Aplus_pattern .+ A0_pattern) .> 0
Q, P, R, _, _ = BlockTriangularForm.order(block_pattern)
𝓂.solution.perturbation.first_order_block_decomposition = (Vector{Int}(Q), Vector{Int}(P), Vector{Int}(R))




Expand Down Expand Up @@ -8358,11 +8378,12 @@ function get_relevant_steady_state_and_state_update(::Val{:first_order},

∇₁ = calculate_jacobian(parameter_values, SS_and_pars, 𝓂) # , timer = timer)# |> Matrix

𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = TT,
# timer = timer,
initial_guess = 𝓂.solution.perturbation.qme_solution,
opts = opts)
𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = TT,
# timer = timer,
initial_guess = 𝓂.solution.perturbation.qme_solution,
opts = opts,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

if solved 𝓂.solution.perturbation.qme_solution = qme_sol end

Expand Down
9 changes: 5 additions & 4 deletions src/filter/inversion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3457,10 +3457,11 @@ function filter_data_with_model(𝓂::ℳ,

∇₁ = calculate_jacobian(𝓂.parameter_values, SS_and_pars, 𝓂)# |> Matrix

𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = T,
initial_guess = 𝓂.solution.perturbation.qme_solution,
opts = opts)
𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = T,
initial_guess = 𝓂.solution.perturbation.qme_solution,
opts = opts,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

if solved 𝓂.solution.perturbation.qme_solution = qme_sol end

Expand Down
3 changes: 2 additions & 1 deletion src/filter/kalman.jl
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,8 @@ function filter_and_smooth(𝓂::ℳ,

∇₁ = calculate_jacobian(parameters, SS_and_pars, 𝓂)# |> Matrix

sol, qme_sol, solved = calculate_first_order_solution(∇₁; T = 𝓂.timings, opts = opts)
sol, qme_sol, solved = calculate_first_order_solution(∇₁; T = 𝓂.timings, opts = opts,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

if solved 𝓂.solution.perturbation.qme_solution = qme_sol end

Expand Down
1 change: 1 addition & 0 deletions src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,7 @@ macro model(𝓂,ex...)
third_order_perturbation_solution([], (x,y)->nothing, (x,y)->nothing),
third_order_perturbation_solution([], (x,y)->nothing, (x,y)->nothing),
zeros(0,0), # 1st order sol
(Int[], Int[], Int[]),
SparseMatrixCSC{Float64, Int64}(ℒ.I,0,0), # 2nd order sol
SparseMatrixCSC{Float64, Int64}(ℒ.I,0,0), # 3rd order sol
auxilliary_indices(Int[],Int[],Int[],Int[],Int[]),
Expand Down
18 changes: 10 additions & 8 deletions src/moments.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ function calculate_covariance(parameters::Vector{R},

∇₁ = calculate_jacobian(parameters, SS_and_pars, 𝓂)

sol, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
initial_guess = 𝓂.solution.perturbation.qme_solution,
opts = opts)
sol, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
initial_guess = 𝓂.solution.perturbation.qme_solution,
opts = opts,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

if solved 𝓂.solution.perturbation.qme_solution = qme_sol end

Expand Down Expand Up @@ -56,10 +57,11 @@ function calculate_mean(parameters::Vector{T},
else
∇₁ = calculate_jacobian(parameters, SS_and_pars, 𝓂)# |> Matrix

𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
initial_guess = 𝓂.solution.perturbation.qme_solution,
opts = opts)
𝐒₁, qme_sol, solved = calculate_first_order_solution(∇₁;
T = 𝓂.timings,
initial_guess = 𝓂.solution.perturbation.qme_solution,
opts = opts,
decomposition = 𝓂.solution.perturbation.first_order_block_decomposition)

if !solved
mean_of_variables = SS_and_pars[1:𝓂.timings.nVars]
Expand Down
Loading
Loading