module PerfectForesightModelSolver ## # Copyright (C) 2016 Dynare Team # # This file is part of Dynare. # # Dynare is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Dynare is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Dynare. If not, see . ## import DynareModel.Model import DynareOutput.Output import DynareOptions.Options export simulate_perfect_foresight_model! function simulate_perfect_foresight_model!(endogenousvariables::Matrix{Float64}, exogenousvariables::Matrix{Float64}, steadystate::Vector{Float64}, model::Model, options::Options) lead_lag_incidence = model.lead_lag_incidence nyp = countnz(lead_lag_incidence[1,:]) ny0 = countnz(lead_lag_incidence[2,:]) nyf = countnz(lead_lag_incidence[3,:]) ny = length(model.endo) nd = nyp+ny0+nyf periods = options.pfmsolver.periods params = model.params tmp = lead_lag_incidence[2:3,:]' i_cols_A1 = find(tmp) i_cols_1 = tmp[i_cols_A1] tmp = lead_lag_incidence[1:2,:]' i_cols_AT = find(tmp) i_cols_T = tmp[i_cols_AT] tmp = lead_lag_incidence[2,:]' i_cols_A0 = find(tmp) i_cols_0 = tmp[i_cols_A0] i_cols_j = collect(1:nd) i_upd = ny+collect(1:periods*ny) Y = vec(endogenousvariables) z = Y[find(lead_lag_incidence')] jacobian = zeros(Float64, ny, length(z)+length(model.exo)) residuals = zeros(Float64, ny) println("\nMODEL SIMULATION:\n") rd = zeros(Float64, periods*ny) iA = zeros(Int64, periods*model.nnzderivatives[1]) jA = zeros(Int64, periods*model.nnzderivatives[1]) vA = zeros(Float64, periods*model.nnzderivatives[1]) convergence = false iteration = 0 while !convergence iteration += 1 i_rows = collect(1:ny) i_cols_A = find(lead_lag_incidence') i_cols = i_cols_A m = 0 for it = 2:(periods+1) model.dynamic(Y[i_cols], exogenousvariables, params, steadystate, it, residuals, jacobian) if it==(periods+1) & it==2 (r, c, v) = findnz(jacobian[:,i_cols_0]) k = collect(1:length(v))+m iA[k] = i_rows[r] jA[k] = i_cols_A0[c] vA[k] = v elseif it==(periods+1) (r, c, v) = findnz(jacobian[:,i_cols_T]) k = collect(1:length(v))+m iA[k] = i_rows[r] jA[k] = i_cols_A[i_cols_T[c]] vA[k] = v elseif it==2 (r, c, v) = findnz(jacobian[:,i_cols_1]) k = collect(1:length(v))+m iA[k] = i_rows[r] jA[k] = i_cols_A1[c] vA[k] = v else (r, c, v) = findnz(jacobian[:,i_cols_j]) k = collect(1:length(v))+m iA[k] = i_rows[r] jA[k] = i_cols_A[c] vA[k] = v end m += length(v) rd[i_rows] = residuals i_rows += ny i_cols += ny if it>2 i_cols_A += ny end end err = maximum(abs(rd)) println("Iter. ", iteration, "\t err. ", round(err, 12)) if err