ps3 Macro Bongioanni TXT
ps3 Macro Bongioanni TXT
ps3 Macro Bongioanni TXT
"""
Created on Mon Feb 14 10:20:38 2022
@author: gbongio
"""
import numpy as np
from matplotlib import pyplot as plt
from functools import partial
class A(object):
def __init__(self):
print ('init')
self.v = 10
self.z = [2,3,4]
def __copy__(self):
cls = self.__class__
result = cls.__new__(cls)
result.__dict__.update(self.__dict__)
return result
nkk = 400
nzz = 12
alpha = 0.36
beta = 0.96
delta = 0.025
rho = 0.95
var_e = 0.007
theta = 0.64
# a.Create a tensor which stores the optimal amount of hours worked conditional
# for each possible combination tensor = 12 matrics 400x400
tensor_l = np.empty([nzz, nkk, nkk])
tensor_u = np.empty([nzz, nkk, nkk])
# b.
# solve for ss w/o uncertainty optimal labor
l_ss = ((1-theta)*(1-alpha)) / ((1-theta)*(1-alpha) - ((alpha*beta*theta*delta)/(1-
beta*(1-delta))) + theta)
# solve for ss w/o uncertainty capital where l=l', k=k' and z=0
k_ss = l_ss * ((1-beta*(1-delta))/(alpha*beta))**(1/(alpha-1))
# grid
k_grid = np.linspace(0.5*k_ss,1.5*k_ss, num=400)
# c.
import numpy as np
from scipy.stats import norm
Parameters
----------
rho : scalar(float)
The autocorrelation coefficient
sigma_u : scalar(float)
The standard deviation of the random process
m : scalar(int), optional(default=3)
The number of standard deviations to approximate out to
n : scalar(int), optional(default=7)
The number of states to use in the approximation
Returns
-------
x : array_like(float, ndim=1)
The state space of the discretized process
P : array_like(float, ndim=2)
The Markov transition matrix where P[i, j] is the probability
of transitioning from x[i] to x[j]
"""
F = norm(loc=0, scale=sigma_u).cdf
for i in range(n):
# for every step compute the probability mass for the extreme values of the
grid
P[i, 0] = F(x[0]-rho * x[i] + half_step) #lowest value
P[i, n-1] = 1 - F(x[n-1] - rho * x[i] - half_step) #highest value
return x, P
var_z = (var_e**2)/(1-rho**2)
# d.Fill in a nkk # nkk # nzz tensor containing the utility level associated with
any feasible combination
# of (k; z; k') using the optimal labor choice u(k; z; k')
# get midpoint
m = (a + b)/2
# in this loop we are going to compute the optimal labor supply given a state
# (k,k1,z) and and the associated utilities in period t = 0.
# This information will come handy when performing VF iteration
count=0
for k in range(nkk):
count+=1
for k1 in range(nkk):
for z in range(nzz):
# define partial function where the only input becomes the labor
# this means that for each triplet (k,k1,z) we fix such values in the
# formula for the labor foc and then solve with the bisection for the
root
# of the derivative.
labor_partial = partial(labor_foc, k_grid[k], k_grid[k1], z_grid[z],
theta, alpha, delta)
if cons < 0:
tensor_u[z, k, k1] = -np.inf
else:
tensor_u[z, k, k1] = u(cons, tensor_l[z, k, k1], theta, alpha,
delta)
print(count)
# e.
# given a state we will look for the combination of 12 k1s that achieves the
# highest value.
V0 = np.zeros([nzz, nkk])
V1 = np.zeros([nzz, nkk])
error = 1
count = 0
# we economize on one loop my running vector operations for all k1 (k primes)
start = time.time()
while error > tol:
count += 1
for z in range(nzz):
for k in range(nkk):
#compute consumption not useful probably
#consump = c(k_grid[k], k_grid[k1], z_grid[z], tensor_l[k, k1, z])
# here we fix the state of the world by fixing a pair (z,k) and then
# we proceed computing the expected future value of each choice of
capital
# by taking the inner product of the probabilities' vector with the
# guesses we have made.
# first summand is the vector of today's utilities associated with
# all possible values of k1.
# the second summand is the vector of expected continuation values
# given different choices of k1.
# We then sum the two summands element-wise.
temp = tensor_u[z, k, :] + beta*(np.inner(V0.T, transition[z]))
#then we take the index of the k1 that maximizes the Value given the
# state (z,k).
pf_k_idx[z, k] = np.argmax(temp)
V1[z, k] = temp[np.argmax(temp)]
error = np.linalg.norm(V1-V0)/np.linalg.norm(V0)
V0 = copy(V1)
end = time.time()
seconds = end-start
print("The iteration converged in:",seconds," seconds")
plt.title("VF")
plt.plot(k_grid, V1[0], label = "V1")
plt.plot(k_grid, V1[5], label = "V6")
plt.plot(k_grid, V1[11], label = "V12")
plt.legend()
for k in range(nkk):
for z in range(nzz):
index = pf_k_idx[z, k]
pf_k[z, k] = k_grid[int(index)]
for k in range(nkk):
for z in range(nzz):
pf_l[z, k] = tensor_l[z, k, int(pf_k_idx[z, k])]
# simulation part
T = 50000
ts_z_idx = np.zeros(T)
ts_z_idx[0] = 1
ts_k_idx = np.zeros(T)
ts_k_idx[0] = 1
for t in range(1,T):
prev_idx = ts_z_idx[t-1]
ts_z_idx[t] = np.random.choice(np.array(range(12)),
p=list(transition[int(prev_idx)]))
ts_k = np.zeros(T)
for i in range(T):
index = ts_k_idx[i]
ts_k[i] = k_grid[int(index)]