jessegrabowski/gEconpy

Parameters defined as equations of other parameters are interpreted as calibrating constraints

Closed this issue · 5 comments

Hi Jesse,

I was trying to load an already log-linear model and when reading in my GCN file I came across this error message below. I was wondering whether this is due to the GCN specification or possibly something else. The GCN can be found under:
https://github.com/lukasgrahl/memoire1/blob/b3e2901e96936badc71a61cee8b097f2b3de85cc/model_files/log_lin2.gcn

Thanks for your help!

KeyError

Traceback (most recent call last)
----> 1 mod.solve_model(model_is_linear=True)

gEconpy\classes\model.py:451, in gEconModel.solve_model(self, solver, not_loglin_variable, order, model_is_linear, tol, max_iter, verbose, on_failure)
448 steady_state_dict = self.steady_state_dict
450 if self.build_perturbation_matrices is None:
--> 451 self._perturbation_setup(not_loglin_variable, order, model_is_linear, verbose, bool)
453 A, B, C, D = self.build_perturbation_matrices(
454 **param_dict.to_string(), **steady_state_dict.to_string()
455 )
456 _, variables, _ = self.perturbation_solver.make_all_variable_time_combinations()

gEconpy\classes\model.py:595, in `gEconModel._perturbation_setup(self, not_loglin_variables, order, model_is_linear, verbose, return_F_matrices, tol)
592 if variable.base_name in not_loglin_variables:
593 continue
--> 595 if abs(steady_state_dict[variable.to_ss().name]) < tol:
596 not_loglin_variables.append(variable.base_name)
597 close_to_zero_warnings.append(variable)

KeyError: 'Y_ss'

PS: adding it as code would have ruined the indents

Just to rule out the obvious -- you called mod.steady_state() before mod.solve_model() yea?

I did, but I restarted the notebook once more, just to make sure. Now it actually throws an error on the .steady_state() method, that previously wasn't shown. I get a non-zero residual in the steady state, it seems there must have been an error in the GCN all along. I'll try fix that one first then.

Since the model isn't that complicated, it would be good to include a steady_state block and provide the analytical steady states. I recommend always doing that, if possible. The automatic solver isn't bad, but it isn't great either, and can systematically fail for certain parameter boundaries (see the last 2 plots here)

Also, for linear systems, you can get the steady state super fast using Sympy by making an augmented matrix and putting it into reduced row-echelon form:

Y, pi, r, v, a = sp.symbols('Y \pi, r, v, a')
omega, sigma, beta, phi_pi, kappa, rho, psi_y, phi_y = sp.symbols('omega sigma beta, \phi_{\pi} kappa rho \psi_{ya} \phi_{y}')

a = 0
v = 0

eq_1 = Y - (omega * (sigma * Y + (1 - beta) * phi_pi * pi) + omega * (r - v))
eq_2 = pi - (omega * (sigma * kappa * Y + (kappa + beta * ( sigma + phi_y ) ) * pi ) + omega * kappa * (r - v))
eq_3 = r - (rho + sigma * psi_ya * (a - a))

A, y = sp.linear_eq_to_matrix([eq_1, eq_2, eq_3], [Y, pi, r])
sp.Matrix([[A, y]]).rref()[0]

$$ \displaystyle \left[\begin{matrix}1 & 0 & 0 & \frac{- \phi_{\pi} \beta \kappa \omega^{2} \rho + \phi_{\pi} \kappa \omega^{2} \rho - \phi_{y} \beta \omega^{2} \rho - \beta \omega^{2} \rho \sigma - \kappa \omega^{2} \rho + \omega \rho}{\phi_{\pi} \beta \kappa \omega^{2} \sigma - \phi_{\pi} \kappa \omega^{2} \sigma + \phi_{y} \beta \omega^{2} \sigma - \phi_{y} \beta \omega + \beta \omega^{2} \sigma^{2} - \beta \omega \sigma + \kappa \omega^{2} \sigma - \kappa \omega - \omega \sigma + 1} \\ 0 & 1 & 0 & \frac{\kappa \omega \rho}{\phi_{\pi} \beta \kappa \omega^{2} \sigma - \phi_{\pi} \kappa \omega^{2} \sigma + \phi_{y} \beta \omega^{2} \sigma - \phi_{y} \beta \omega + \beta \omega^{2} \sigma^{2} - \beta \omega \sigma + \kappa \omega^{2} \sigma - \kappa \omega - \omega \sigma + 1} \\ 0 & 0 & 1 & \rho\end{matrix}\right] $$

A quick check that these in fact satisfy the steady state:

ss_vals = sp.Matrix([[A, y]]).rref()[0][:, 3]
y_ss, pi_ss, r_ss = [x[0] for x in ss_vals.tolist()]

for eq in [eq_1, eq_2, eq_3]:
    assert eq.subs({Y:y_ss, pi:pi_ss, r:r_ss}).simplify() == 0

Ok I found the bug, it's related to the definition of parameters in the calibration block. The system thinks these are calibrating restrictions, and is trying to add them to the model system as variables. The correct behavior should be to ignore these equations unless there is an arrow syntax, so it's definitely a bug.