Skip to content

Commit d4602fc

Browse files
committed
Added two Romer model versions, fixed bug in steady state solver where ssi variables with numbers in their names were not picked up and added feature that in manual SS section substitutions now also get replaced in the intial values section
1 parent a69e016 commit d4602fc

File tree

8 files changed

+486
-57
lines changed

8 files changed

+486
-57
lines changed

pymaclab/dsge/macrolab.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1627,7 +1627,11 @@ def mkjahepp(self):
16271627
pos = ma.span()[0]
16281628
poe = ma.span()[1]
16291629
str_tmp = str_tmp[:pos]+'sympycore.exp('+str_tmp[poe:]
1630-
func.append(eval(str_tmp))
1630+
try:
1631+
func.append(eval(str_tmp))
1632+
except:
1633+
print "ERROR at: "+str_tmp
1634+
sys.exit()
16311635
self.func1 = func
16321636

16331637
# Only exp() when variable needs to be put into ln !

pymaclab/dsge/parsers/_dsgeparser.py

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ def populate_model_stage_one(self, secs):
193193

194194
# Collect info on numerical steady state
195195
if all([False if 'None' in x else True for x in secs['manualss'][0]]):
196-
_mreg_alt = '^\s*[a-zA-Z]*_bar(?!=\+|-|\*|/])\s*=\s*.*'
197-
_mreg = '\[\d+\]\s*[a-zA-Z]*_bar(?!=\+|-|\*|/])\s*=\s*.*'
196+
_mreg_alt = '^\s*[a-zA-Z]*\d*_bar(?!=\+|-|\*|/])\s*=\s*.*'
197+
_mreg = '\[\d+\]\s*[a-zA-Z]*\d*_bar(?!=\+|-|\*|/])\s*=\s*.*'
198198
_mreg2 = '\[\d+\]\s*[a-zA-Z]*(?!=\+|-|\*|/])\s*=\s*[0-9]*\.[0-9]*'
199199
_mregfocs = 'USE_FOCS=\[.*?\]'
200200
mregfocs = re.compile(_mregfocs)
@@ -207,6 +207,7 @@ def populate_model_stage_one(self, secs):
207207
mreg = re.compile(_mreg_alt+'|'+_mreg+'|'+_mreg2)
208208
indx = []
209209
ssidic={}
210+
ssili = []
210211
list_tmp = []
211212
anyssi_found = False
212213
i1=0
@@ -219,10 +220,9 @@ def populate_model_stage_one(self, secs):
219220
if ']' in ma.group(): str1 = ma.group().replace(';','').split('=')[0].split(']')[1].strip()
220221
else: str1 = ma.group().replace(';','').split('=')[0].lstrip().rstrip()
221222
str2 = ma.group().split('=')[1].strip()
222-
ssidic[str1] = eval(str2)
223-
# Expose the evaluated values for recursive smart evaluation
224-
locals().update(self.paramdic)
225-
locals()[str1] = eval(str2)
223+
# Save the result as a string here, later in mk_mssidic_subs() method we do substitutions and evaluate then
224+
ssidic[str1] = str2
225+
ssili.append([str1,str2])
226226
indx.append(i1)
227227
elif not mreg.search(x) and '...' in x:
228228
counter = counter + 1
@@ -240,6 +240,7 @@ def populate_model_stage_one(self, secs):
240240
i1=i1+1
241241
if anyssi_found:
242242
self.ssidic = deepcopy(ssidic)
243+
self.ssili = deepcopy(ssili)
243244
# Save for template instantiation
244245
self.template_paramdic['ssidic'] = deepcopy(ssidic)
245246
else:
@@ -256,6 +257,7 @@ def populate_model_stage_one(self, secs):
256257
elif use_focs and anyssi_found:
257258
self._use_focs = deepcopy(use_focs)
258259
self._ssidic = deepcopy(ssidic)
260+
self.ssili = deepcopy(ssili)
259261
# Save for template instantiation
260262
self.template_paramdic['ssys_list'] = False
261263
self.template_paramdic['use_focs'] = deepcopy(use_focs)
@@ -1977,6 +1979,30 @@ def mk_msstate_subs(self):
19771979
self.ssys_list = deepcopy(tmp_list)
19781980
return self
19791981

1982+
def mk_mssidic_subs(self):
1983+
"""
1984+
This function takes the manually defined numerical sstate's ssidic and then replaces
1985+
any @terms with the corresponding substitutions and evaluates as it goes along
1986+
"""
1987+
_mreg = '@[a-zA-Z]*\d*_bar'
1988+
mreg = re.compile(_mreg)
1989+
tmp_list = deepcopy(self.ssili)
1990+
sub_dic = deepcopy(self.nlsubs)
1991+
for i1,x in enumerate(tmp_list):
1992+
while mreg.search(tmp_list[i1][1]):
1993+
ma = mreg.search(tmp_list[i1][1])
1994+
str_tmp = ma.group()
1995+
tmp_list[i1][1] = tmp_list[i1][1].replace(str_tmp,'('+sub_dic[str_tmp]+')')
1996+
tmp_dic = {}
1997+
tmp_dic[tmp_list[i1][0]] = eval(tmp_list[i1][1])
1998+
locals().update(self.paramdic)
1999+
locals().update(tmp_dic)
2000+
self.ssidic[tmp_list[i1][0]] = eval(tmp_list[i1][1])
2001+
self.ssili = deepcopy(tmp_list)
2002+
# At the end delete ssili from model instance
2003+
del self.ssili
2004+
return self
2005+
19802006
#This function is needed in population stage 1, at the end
19812007
def mk_cfstate_subs(self):
19822008
"""
@@ -2039,6 +2065,11 @@ def populate_model_stage_one_bb(self, secs):
20392065
all([False if 'None' in x else True for x in secs['manualss'][0]]):
20402066
# Do this only if USE_FOCS has not been used, otherwise ssys_list would be missing
20412067
if '_internal_focs_used' not in dir(self): self = mk_msstate_subs(self)
2068+
# Do substitutions inside the numerical steady state list, but the ssidic
2069+
# Check and do substitutions
2070+
if all([False if 'None' in x else True for x in secs['vsfocs'][0]]) and\
2071+
all([False if 'None' in x else True for x in secs['manualss'][0]]):
2072+
self = mk_mssidic_subs(self)
20422073
# Do substitutions inside the closed form steady state list
20432074
# Check and do substitutions
20442075
if all([False if 'None' in x else True for x in secs['vsfocs'][0]]) and\

pymaclab/dsge/solvers/modsolvers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,6 +1530,9 @@ def show_act(self):
15301530
print vari+(vnmax-len(vari))*' '+' |'+str(actm[i1,:])[2:-2]
15311531

15321532
def show_sim(self,intup,filtup=None,insim='insim'):
1533+
# Deals with 0-tuples
1534+
if type(intup) != type((1,2,3)) and type(intup) == type('abc'):
1535+
intup = (intup,)
15331536
# Check if simulations have been carried out
15341537
if insim not in dir(self):
15351538
return 'Error: You have not produced any simulations yet! Nothing to graph!'
@@ -1972,6 +1975,9 @@ def save_sim(self,intup,fpath=None,filtup=None,insim='insim'):
19721975

19731976

19741977
def irf(self,tlen,sntup):
1978+
# Deals with 0-tuples
1979+
if type(sntup) != type((1,2,3)) and type(sntup) == type('abc'):
1980+
sntup = (sntup,)
19751981
tlen = tlen + 1
19761982
ncon = self.ncon
19771983
nexo = self.nexo
@@ -2539,6 +2545,9 @@ def sim(self,tlen,sntup=None,shockvec=None):
25392545
self.insim = self.insim + [self.sim_o_one,]
25402546

25412547
def irf(self,tlen,sntup):
2548+
# Deals with 0-tuples
2549+
if type(sntup) != type((1,2,3)) and type(sntup) == type('abc'):
2550+
sntup = (sntup,)
25422551
tlen = tlen + 1
25432552
ncon = self.ncon
25442553
nexo = self.nexo

pymaclab/modfiles/models/development/RBC_Romer.txt

Lines changed: 76 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ this key feature of the data is because the exogenous productivity (and
1111
government spending shocks) are assumed to be highly persistent. Such large and
1212
persistent shocks to productivity/technology are hard to identify in the data.
1313

14-
Model suffers from other issues common to RBC models, for examples the model has
14+
Model suffers from other issues common to RBC models, for example the model has
1515
no room for involuntary unemployment. In this model, workers choose to be
1616
unemployed (or under employed!): workers optimally adjust their labor supply
1717
across time in response to changes in the real wage (which in turn are driven by
1818
exogenous productivity/technology shocks).
1919

2020
Note that there are two sources of growth in Romer's RBC: technology growth and
2121
population growth. Thus we will need to detrend variables accordingly in order
22-
to have a stationary model. Below I work with per effective worker variables
23-
unless otherwise noted.
22+
to have a stationary model. All variables, with the exception of l(t), are
23+
expressed in per effective worker terms. The labor supply, l(t), is in per
24+
capita terms.
2425

2526
%Model Information++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2627
Name = Romer's RBC model;
@@ -31,8 +32,8 @@ Name = Romer's RBC model;
3132
# discount rate
3233
rho = 0.01;
3334

34-
# weight (relative to consumption) that worker places on utility from leisure
35-
b = 2.5;
35+
# Calibrated steady state labour, in the SS solver the parameter b now gets determined
36+
l_bar = 2.0 / 3.0;
3637

3738
# Household size (normalized to unity)
3839
H = 1.0;
@@ -47,11 +48,12 @@ n = 0.0025;
4748
delta = 0.025;
4849

4950
# capital's share of output
50-
alpha = 1.0/3.0;
51+
alpha = 1.0 / 3.0;
5152

5253
# government spending per effective worker is chosen so that in SS government
5354
# spending roughly is 20% of output (which matches U.S. data)
54-
gov = 0.5774;
55+
# g_bar now gets determined residually in the SS solver
56+
gov_share = 0.20;
5557

5658
# persistence of technology shocks
5759
rho_A = 0.95;
@@ -65,66 +67,91 @@ sigma_A = 0.011;
6567
# standard deviation of government spending shocks
6668
sigma_G = 0.011;
6769

70+
# Various easily computed steady-state values
6871
z_A_bar = 1.0;
6972
z_G_bar = 1.0;
70-
A_bar = 1.0;
71-
G_bar = 1.0;
72-
g_bar = gov;
7373

7474
%Variable Vectors+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
75-
# Per capita consumption, c, and labor_supply, l, are the control variables; the
75+
# Only endogenous state variable is capital per effective worker, k; the
7676
# two exogenous variables are technology, A, and government spending, G. Both
7777
# are driven by AR(1) processes z_A and z_G, respectively.
7878

79-
[1] y(t):output{con}[log,hp]
80-
[2] k(t):physical_capital{endo}[log,hp]
81-
[3] L(t):leisure{con}[log,hp]
82-
[4] N(t):labur{con}[log,hp]
83-
[4] c(t):consumption{con}[log,hp]
84-
[5] i(t):investment{con}[log,hp]
85-
[6] w(t):real_wage{con}[log,hp]
86-
[7] R(t):gross_interest_rate{con}[log,hp]
87-
[8] A(t):technology{con}[log,hp]
88-
[9] g(t):gov_spending{con}[log,hp]
89-
[10] z_A(t):eps_A(t):tech_shocks{exo}[log,hp]
90-
[11] z_G(t):eps_G(t):gov_shocks{exo}[log,hp]
79+
[0] y(t):output{con}[log,cf]
80+
[1] k(t):physical_capital{endo}[log,cf]
81+
[2] l(t):labor{con}[log,cf]
82+
[3] c(t):consumption{con}[log,cf]
83+
[4] i(t):investment{con}[log,cf]
84+
[5] w(t):real_wage{con}[log]
85+
[6] R(t):gross_interest_rate{con}
86+
[7] g(t):gov_spending{con}[log,cf]
87+
[8] z_A(t):eps_A(t):tech_shocks{exo}[log,cf]
88+
[9] z_G(t):eps_G(t):gov_shocks{exo}[log,cf]
9189

9290
%Boundary Conditions++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9391
None
9492

9593
%Variable Substitution Non-Linear System++++++++++++++++++++++++++++++++++++++++
96-
# Following Romer, I work with per effective worker variables.
97-
None
94+
[0] @U(t) = LOG(c(t)) + b*LOG(1-l(t));
95+
[1] @Uc(t) = DIFF{@U(t),c(t)};
96+
[2] @Uc(t+1) = FF_1{@Uc(t)};
97+
[10] @F(t) = k(t-1)**alpha;
98+
[11] @Fk(t) = alpha * k(t-1)**(alpha - 1);
99+
[12] @Fl(t) = z_A(t) * (1 - alpha) * k(t-1)**alpha;
98100

99101
%Non-Linear First-Order Conditions++++++++++++++++++++++++++++++++++++++++++++++
100-
[1] EXP(n + g) * k(t) - ((1 - delta) * k(t-1) + i(t)) = 0;
101-
[2] y(t) - (c(t) + i(t) + g(t)) = 0;
102-
[3] y(t) - k(t-1)**alpha = 0;
103-
[4] 1 - L(t) - N(t) = 0;
104-
[4] w(t) - (1 - alpha) * k(t-1)**alpha = 0;
105-
[5] R(t) - (alpha * k(t-1)**(alpha - 1) + (1 - delta)) = 0;
106-
[6] (1 / c(t)) - EXP(-(rho + g)) * (1 / E(t)|c(t+1)) * E(t)|R(t+1) = 0;
107-
[7] b * c(t) * L(t) - (1 - L(t))*w(t) = 0;
108-
[8] E(t)|A(t+1) - EXP(g + E(t)|z_A(t+1)) * A(t) = 0;
109-
[9] E(t)|g(t+1) - EXP(n + g + E(t)|z_G(t+1)) * g(t) = 0;
110-
[10] E(t)|z_A(t+1) - rho_A * z_A(t) = 0;
111-
[11] E(t)|z_G(t+1) - rho_G * z_G(t) = 0;
102+
# Evolution of physical capital
103+
[0] (E(t)|z_A(t+1) * E(t)|l(t+1))*k(t) * EXP(n + g) - (z_A(t) * l(t))*((1 - delta) * k(t-1) + i(t)) = 0;
104+
105+
# Aggregate resource constraint
106+
[1] (z_A(t) * l(t))*(y(t) - c(t) - i(t) - g(t)) = 0;
107+
108+
# production process
109+
[2] y(t)*(z_A(t) * l(t)) - w(t)*l(t) - (R(t)-1.0)*k(t-1)*(z_A(t) * l(t)) = 0;
110+
111+
# labor is paid its marginal product
112+
[3] w(t)/(z_A(t) * l(t)) - @Fl(t) = 0;
113+
114+
# capital is paid its marginal product
115+
[4] R(t) - (1 + @Fk(t) - delta) = 0;
116+
117+
# consumption Euler equation
118+
[5] 1 - EXP(-(rho + g)) * ((z_A(t)*l(t)*c(t)) / (E(t)|z_A(t+1)*E(t)|l(t+1)*E(t)|c(t+1))) * E(t)|R(t+1) = 0;
119+
120+
# intra-temporal consumption/labor supply trade-off
121+
[6] b * c(t) * (z_A(t) * l(t)) - w(t)*(1 - l(t)) = 0;
122+
123+
# evolution of government spending (per effective worker!)
124+
[7] LOG((E(t)|g(t+1)* (E(t)|z_A(t+1) * E(t)|l(t+1)))/(g(t)* (z_A(t) * l(t)))) - (n+g) - (E(t)|z_G(t+1)/z_G(t)) = 0;
125+
126+
# technology shocks
127+
[8] LOG(E(t)|z_A(t+1)) - rho_A * LOG(z_A(t)) = 0;
128+
129+
# government spending shocks
130+
[9] LOG(E(t)|z_G(t+1)) - rho_G * LOG(z_G(t)) = 0;
112131

113132
%Steady States [Closed form]++++++++++++++++++++++++++++++++++++++++++++++++++++
114133
None
115134

116-
135+
117136
%Steady State Non-Linear System [Manual]++++++++++++++++++++++++++++++++++++++++
118-
USE_FOCS=[0,1,2,3,4,5,6,7];
119-
120-
[1] k_bar = 35.0;
121-
[2] y_bar = k_bar**alpha;
122-
[3] w_bar = (1-alpha)*k_bar**alpha;
123-
[4] R_bar = (alpha*k_bar**(alpha-1)+(1- delta));
124-
[5] L_bar = 0.7;
125-
[6] N_bar = 0.3;
126-
[7] c_bar = 2.0;
127-
[8] i_bar = y_bar-c_bar-g_bar;
137+
[0] (EXP(n + g) - 1 + delta) * k_bar - i_bar = 0;
138+
[1] y_bar - c_bar - i_bar - g_bar = 0;
139+
[2] y_bar - k_bar**alpha = 0;
140+
[3] w_bar - (1 - alpha) * k_bar**alpha = 0;
141+
[4] R_bar - (1 + alpha * k_bar**(alpha - 1) - delta) = 0;
142+
[5] 1 - EXP(-(rho + g)) * R_bar = 0;
143+
[6] b * c_bar * l_bar - (1 - l_bar) * w_bar = 0;
144+
[7] g_bar - y_bar * gov_share = 0;
145+
146+
# initial values for numerical steady-state computation
147+
[0] k_bar = 20.0;
148+
[1] y_bar = k_bar**alpha;
149+
[2] w_bar = (1 - alpha) * k_bar**alpha;
150+
[3] R_bar = 1 + alpha * k_bar**(alpha - 1) - delta;
151+
[4] b = 1.0;
152+
[5] c_bar = 2.0;
153+
[6] g_bar = y_bar * gov_share;
154+
[7] i_bar = y_bar - c_bar - g_bar;
128155

129156
%Log-Linearized Model Equations+++++++++++++++++++++++++++++++++++++++++++++++++
130157
None
@@ -134,3 +161,4 @@ Sigma = [sigma_A**2 0;
134161
0 sigma_G**2];
135162

136163
%End Of Model File++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
164+

0 commit comments

Comments
 (0)