PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Economics/E581/marcov_notebook.py

https://bitbucket.org/spencerlyon2/byuclasses
Python | 220 lines | 108 code | 34 blank | 78 comment | 8 complexity | 697b94e03b9f31b7734611fe4b608b04 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. # <nbformat>3.0</nbformat>
  3. # <markdowncell>
  4. # # Spencer Lyon
  5. #
  6. # ## Econ 581 homework 6: Recursive models and Markov processes
  7. #
  8. # ### Problem 1
  9. #
  10. # We are given the following
  11. #
  12. # * $Y_t = A K_t ^{\theta}$
  13. # * $K_{t+1} = I_t$
  14. # * $C_t = Y_t - I_t$
  15. # * $u(C) = ln(c)$
  16. #
  17. # We can now write the Bellman equation
  18. #
  19. # $$V(K) = \max_{K} ln(AK^{\theta} - K') + \beta V(K')$$
  20. #
  21. # The *first order condition* is $u'(c) = \beta * V'(K')$
  22. #
  23. # >(if you substitute $K' = I = Y - C$ you get a neagive sign on the $V'$ term. Then set equal to zero and solve for $u'(c)$)
  24. #
  25. # The *envelope condition* is $V'(k) = u'(c) A \theta K^{\theta - 1}$
  26. #
  27. # This makes the *Euler Equation* become $u'(c) = \beta u'(c) A \theta K^{\theta - 1}$
  28. #
  29. # With log utility $u'(c) = \frac{1}{c}$
  30. #
  31. # The simplified *Euler equation* is $$\frac{C'}{C} = \theta \beta A K'^{\theta-1}$$
  32. #
  33. # MISSING STEP FOR HOW TO VERIFY POLICY FUNCTION
  34. #
  35. # >See the "marcov_p1.png" image below this and just above the "Problem 2" header.
  36. #
  37. # The final form of the value function is the following:
  38. # $$V(K) = ln(AK^{\theta} - \beta \theta A K^{\theta}) + \beta V(\beta \theta A K^{\theta})$$
  39. # <codecell>
  40. from IPython.core.display import Image
  41. Image(filename='marcov_p1.png')
  42. # <markdowncell>
  43. # ### Problem 2
  44. # <codecell>
  45. import numpy as np
  46. import pandas as pd
  47. import pylab as pl
  48. from numpy import asarray
  49. from scipy.optimize import fmin
  50. from pandas.io.data import DataReader
  51. import datetime as dt
  52. from statsmodels.tsa.filters.hp_filter import hpfilter
  53. theta = 0.35
  54. delta = 0.02
  55. start1 = dt.datetime(1947, 1, 1)
  56. end1 = dt.datetime(2012, 4, 1)
  57. output = asarray(DataReader('GDPC1', 'fred',
  58. start=start1, end=end1)).squeeze()
  59. differ = (output[1:] - output[:-1]) / output[:-1]
  60. ave_trend = differ.mean()
  61. filtered = hpfilter(np.log(output), lamb=1600)[0]
  62. std_filt = filtered.std(ddof=1)
  63. auto_corr_filt = np.corrcoef(filtered[1:], filtered[:-1], ddof=1)[0, 1]
  64. T = 254
  65. num_sims = 10000
  66. g2 = np.array([0.01, -0.03])
  67. g3 = np.array([0.02, 0.01, -0.03])
  68. marcov2 = np.array([[0.9, 0.1],
  69. [0.5, 0.5]]).cumsum(1)
  70. marcov3 = np.array([[0.5, 0.45, 0.05],
  71. [0.05, 0.85, 0.10],
  72. [0.25, 0.25, 0.5]]).cumsum(1)
  73. def do_mc(periods=T):
  74. """does mc simulation"""
  75. s2 = 0
  76. s3 = 0
  77. epsilon = np.random.normal(0, 0.02, T) # generate random shocks
  78. y2 = np.zeros(periods)
  79. y3 = np.zeros(periods)
  80. for t in range(1, periods):
  81. r_num = np.random.rand()
  82. y2[t] = g2[s2] + y2[t - 1] + epsilon[t]
  83. y3[t] = g3[s3] + y3[t - 1] + epsilon[t]
  84. s2 = np.where(marcov2[s2, :] > r_num)[0][0]
  85. s3 = np.where(marcov3[s3, :] > r_num)[0][0]
  86. return np.array([y2, y3])
  87. y2_data = np.zeros((num_sims, T))
  88. y3_data = np.zeros((num_sims, T))
  89. for i in range(num_sims):
  90. mc_data = do_mc(T)
  91. y2_data[i, :] = mc_data[0, :]
  92. y3_data[i, :] = mc_data[1, :]
  93. # <codecell>
  94. def create_moments(data):
  95. """
  96. gets the moments he asks for (growth rate, std, autocorr)
  97. """
  98. if data.ndim == 2:
  99. df = pd.DataFrame(data).T
  100. total_obs = data.shape[0]
  101. diff = (data[:, 2:] - data[:, 1:-1]) / data[:, 1:-1]
  102. growth = np.mean(diff, axis=1).mean()
  103. filt_data = np.empty(data.shape)
  104. for i in range(total_obs):
  105. filt_data[i, :] = hpfilter(data[i,:], lamb=1600)[0]
  106. std = filt_data.std(ddof=1, axis=1).mean()
  107. filt_df = pd.DataFrame(filt_data).T
  108. all_corrs = np.zeros(total_obs)
  109. for i in range(total_obs):
  110. all_corrs[i] = filt_df[i].autocorr()
  111. autos = all_corrs.mean()
  112. else:
  113. diff = (data[2:] - data[1:-1]) / data[1:-1]
  114. growth = np.mean(diff)
  115. filt = hpfilter(np.log(data), lamb=1600)[0]
  116. std = np.std(filt, ddof=1)
  117. autos = np.corrcoef(filt[2:], filt[1:-1])[0, 1]
  118. return [growth, std, autos]
  119. y2_moms = create_moments(y2_data)
  120. y3_moms = create_moments(y3_data)
  121. data_moms = create_moments(output)
  122. all_moms = np.array([y2_moms, y3_moms, data_moms])
  123. moms_df = pd.DataFrame(all_moms)
  124. new_ind = {0: 'y2', 1: 'y3', 2: 'data'}
  125. moms_df.columns = ['mean growth', 'Std. Dev', 'Auto. Corr.']
  126. moms_df = moms_df.rename(index=new_ind)
  127. moms_df
  128. # <markdowncell>
  129. # ### Problem 3
  130. # <codecell>
  131. def opt_func(x):
  132. """
  133. do 50 mc's and return diff between moments and data moments
  134. """
  135. p11, p22, g1, g2, sigma = x
  136. marcov_mat = np.array([[p11, 1 - p11],
  137. [1 - p22, p22]], dtype=float).cumsum(1)
  138. g22 = np.array([g1, g2])
  139. sims = 10
  140. y2_sim = np.zeros((sims, T))
  141. for sim in range(sims):
  142. s2 = 0
  143. epsilon = np.random.normal(0, sigma, T)
  144. for t in range(1, T):
  145. r_num = np.random.rand()
  146. y2_sim[sim, t] = g22[s2] + y2_sim[sim, t - 1] + epsilon[t]
  147. s2 = np.where(marcov_mat[s2, :] > r_num)[0][0]
  148. sim_moms = np.asarray(create_moments(y2_sim))
  149. difference = np.linalg.norm(sim_moms - np.asarray(data_moms))
  150. return difference
  151. x0 = [.6, .3, .02, -.01, .0015]
  152. p11, p22, g1o, g2o, sigmao = fmin(opt_func, x0, xtol=1e-4, maxfun=1e8)
  153. print 'the optimal parameters are p1 = %.3f, p2 = %.3f, g1 = %.3f, g2 = %.3f, sigma = %.3f ' %(p11, p22, g1o, g2o, sigmao)
  154. # <markdowncell>
  155. # Note that because we are trying to optimize over a random process, we will never actually converge. This is pretty close, and probably the best we can hope for without reforming the problem/solution approach a bit. (see plot below for more evidence that we are close)
  156. # <codecell>
  157. opt_marcov = np.array([[p11, 1 - p11],[1 - p22, p22]]).cumsum(1)
  158. opt_g = np.array([g1o, g2o])
  159. y_opt = np.zeros(254)
  160. s2_opt = 0
  161. opt_eps = np.random.normal(0, sigmao, 254)
  162. for t in range(1, 254):
  163. y_opt[t] = opt_g[s2_opt] + y_opt[t - 1] + opt_eps[t]
  164. rand_num = np.random.rand()
  165. s2 = np.where(opt_marcov[s2_opt, :] > rand_num)[0][0]
  166. pl.plot(range(254), y_opt, label='sim. data')
  167. pl.plot(range(output.size), np.log(output), label='log data')
  168. pl.legend(loc=0)
  169. pl.show()
  170. # <markdowncell>
  171. # Note that this plot shows that the general shape of the two plots is very similar. The main difference is a scale factor. This is encouraging.