class Planners_Allocation_Bellman: ''' Compute the planner's allocation by solving Bellman equation. ''' def __init__(self,Para,mugrid): ''' Initializes the class from the calibration Para ''' self.beta = Para.beta self.Pi = Para.Pi self.mc = MarkovChain(self.Pi) self.G = Para.G self.S = len(Para.Pi) # number of states self.Theta = Para.Theta self.Para = Para self.mugrid = mugrid #now find the first best allocation self.solve_time1_bellman() self.T.time_0 = True #Bellman equation now solves time 0 problem def solve_time1_bellman(self): ''' Solve the time 1 Bellman equation for calibration Para and initial grid mugrid0 ''' Para,mugrid0 = self.Para,self.mugrid S = len(Para.Pi) #First get initial fit PP = Planners_Allocation_Sequential(Para) c,n,x,V = map(np.vstack, zip(*map(lambda mu: PP.time1_value(mu),mugrid0)) ) Vf,cf,nf,xprimef = {},{},{},{} for s in range(2): cf[s] = UnivariateSpline(x[:,s],c[:,s]) nf[s] = UnivariateSpline(x[:,s],n[:,s]) Vf[s] = UnivariateSpline(x[:,s],V[:,s]) for sprime in range(S): xprimef[s,sprime] = UnivariateSpline(x[:,s],x[:,s]) policies = [cf,nf,xprimef] #create xgrid xbar = [x.min(0).max(),x.max(0).min()] xgrid = np.linspace(xbar[0],xbar[1],len(mugrid0)) self.xgrid = xgrid #Now iterate on bellman equation T = BellmanEquation(Para,xgrid,policies) diff = 1. while diff > 1e-5: PF = T(Vf) Vfnew,policies = self.fit_policy_function(PF) diff = 0. for s in range(S): diff = max(diff, np.abs((Vf[s](xgrid)-Vfnew[s](xgrid))/Vf[s](xgrid)).max() ) print(diff) Vf = Vfnew #store value function policies and Bellman Equations self.Vf = Vf self.policies = policies self.T = T def fit_policy_function(self,PF): ''' Fits the policy functions PF using the points xgrid using UnivariateSpline ''' xgrid,S = self.xgrid,self.S Vf,cf,nf,xprimef = {},{},{},{} for s in range(S): PFvec = np.vstack(map(lambda x:PF(x,s),xgrid)) Vf[s] = UnivariateSpline(xgrid,PFvec[:,0],s=0) cf[s] = UnivariateSpline(xgrid,PFvec[:,1],s=0,k=1) nf[s] = UnivariateSpline(xgrid,PFvec[:,2],s=0,k=1) for sprime in range(S): xprimef[s,sprime] = UnivariateSpline(xgrid,PFvec[:,3+sprime],s=0,k=1) return Vf,[cf,nf,xprimef] def Tau(self,c,n): ''' Computes Tau given c,n ''' Para = self.Para Uc,Un = Para.Uc(c,n),Para.Un(c,n) return 1+Un/(self.Theta * Uc) def time0_allocation(self,B_,s0): ''' Finds the optimal allocation given initial government debt B_ and state s_0 ''' PF = self.T(self.Vf) z0 = PF(B_,s0) c0,n0,xprime0 = z0[1],z0[2],z0[3:] return c0,n0,xprime0 def simulate(self,B_,s_0,T,sHist=None): ''' Simulates Ramsey plan for T periods ''' Para,Pi = self.Para,self.Pi Uc = Para.Uc cf,nf,xprimef = self.policies if sHist == None: sHist = self.mc.simulate(s_0,T) cHist,nHist,Bhist,TauHist,muHist = np.zeros((5,T)) RHist = np.zeros(T-1) #time0 cHist[0],nHist[0],xprime = self.time0_allocation(B_,s_0) TauHist[0] = self.Tau(cHist[0],nHist[0])[s_0] Bhist[0] = B_ muHist[0] = 0. #time 1 onward for t in range(1,T): s,x = sHist[t],xprime[sHist[t]] c,n,xprime = np.empty(self.S),nf[s](x),np.empty(self.S) for shat in range(self.S): c[shat] = cf[shat](x) for sprime in range(self.S): xprime[sprime] = xprimef[s,sprime](x) Tau = self.Tau(c,n)[s] u_c = Uc(c,n) Eu_c = Pi[sHist[t-1]].dot(u_c) muHist[t] = self.Vf[s](x,1) RHist[t-1] = Uc(cHist[t-1],nHist[t-1])/(self.beta*Eu_c) cHist[t],nHist[t],Bhist[t],TauHist[t] = c[s],n,x/u_c[s],Tau return cHist,nHist,Bhist,TauHist,sHist,muHist,RHist
from quantecon import MarkovChain lm = LakeModel(d=0, b=0) T = 5000 # Simulation length α, λ = lm.α, lm.λ P = [[1 - λ, λ], [α, 1 - α]] mc = MarkovChain(P) xbar = lm.rate_steady_state() fig, axes = plt.subplots(2, 1, figsize=(10, 8)) s_path = mc.simulate(T, init=1) s_bar_e = s_path.cumsum() / range(1, T+1) s_bar_u = 1 - s_bar_e axes[0].plot(s_bar_u, '-b', lw=2, alpha=0.5) axes[0].hlines(xbar[0], 0, T, 'r', '--') axes[0].set_title('Percent of time unemployed') axes[1].plot(s_bar_e, '-b', lw=2, alpha=0.5) axes[1].hlines(xbar[1], 0, T, 'r', '--') axes[1].set_title('Percent of time employed') plt.tight_layout() plt.show()
class RecursiveAllocation: ''' Compute the planner's allocation by solving Bellman equation. ''' def __init__(self, model, μgrid): self.β, self.π, self.G = model.β, model.π, model.G self.mc, self.S = MarkovChain(self.π), len(model.π) # Number of states self.Θ, self.model, self.μgrid = model.Θ, model, μgrid # Find the first best allocation self.solve_time1_bellman() self.T.time_0 = True # Bellman equation now solves time 0 problem def solve_time1_bellman(self): ''' Solve the time 1 Bellman equation for calibration model and initial grid μgrid0 ''' model, μgrid0 = self.model, self.μgrid S = len(model.π) # First get initial fit pp = SequentialAllocation(model) c, n, x, V = map(np.vstack, zip(*map(lambda μ: pp.time1_value(μ), μgrid0))) Vf, cf, nf, xprimef = {}, {}, {}, {} for s in range(2): ind = np.argsort(x[:, s]) # Sort x # Sort arrays according to x c, n, x, V = c[ind], n[ind], x[ind], V[ind] cf[s] = UnivariateSpline(x[:, s], c[:, s]) nf[s] = UnivariateSpline(x[:, s], n[:, s]) Vf[s] = UnivariateSpline(x[:, s], V[:, s]) for sprime in range(S): xprimef[s, sprime] = UnivariateSpline(x[:, s], x[:, s]) policies = [cf, nf, xprimef] # Create xgrid xbar = [x.min(0).max(), x.max(0).min()] xgrid = np.linspace(xbar[0], xbar[1], len(μgrid0)) self.xgrid = xgrid # Now iterate on bellman equation T = BellmanEquation(model, xgrid, policies) diff = 1 while diff > 1e-7: PF = T(Vf) Vfnew, policies = self.fit_policy_function(PF) diff = 0 for s in range(S): diff = max( diff, np.abs( (Vf[s](xgrid) - Vfnew[s](xgrid)) / Vf[s](xgrid)).max()) Vf = Vfnew # Store value function policies and Bellman Equations self.Vf = Vf self.policies = policies self.T = T def fit_policy_function(self, PF): ''' Fits the policy functions PF using the points xgrid using UnivariateSpline ''' xgrid, S = self.xgrid, self.S Vf, cf, nf, xprimef = {}, {}, {}, {} for s in range(S): PFvec = np.vstack(tuple(map(lambda x: PF(x, s), xgrid))) Vf[s] = UnivariateSpline(xgrid, PFvec[:, 0], s=0) cf[s] = UnivariateSpline(xgrid, PFvec[:, 1], s=0, k=1) nf[s] = UnivariateSpline(xgrid, PFvec[:, 2], s=0, k=1) for sprime in range(S): xprimef[s, sprime] = UnivariateSpline(xgrid, PFvec[:, 3 + sprime], s=0, k=1) return Vf, [cf, nf, xprimef] def Τ(self, c, n): ''' Computes Τ given c, n ''' model = self.model Uc, Un = model.Uc(c, n), model.Un(c, n) return 1 + Un / (self.Θ * Uc) def time0_allocation(self, B_, s0): ''' Finds the optimal allocation given initial government debt B_ and state s_0 ''' PF = self.T(self.Vf) z0 = PF(B_, s0) c0, n0, xprime0 = z0[1], z0[2], z0[3:] return c0, n0, xprime0 def simulate(self, B_, s_0, T, sHist=None): ''' Simulates Ramsey plan for T periods ''' model, π = self.model, self.π Uc = model.Uc cf, nf, xprimef = self.policies if sHist is None: sHist = self.mc.simulate(T, s_0) cHist, nHist, Bhist, ΤHist, μHist = np.zeros((5, T)) RHist = np.zeros(T - 1) # Time 0 cHist[0], nHist[0], xprime = self.time0_allocation(B_, s_0) ΤHist[0] = self.Τ(cHist[0], nHist[0])[s_0] Bhist[0] = B_ μHist[0] = 0 # Time 1 onward for t in range(1, T): s, x = sHist[t], xprime[sHist[t]] c, n, xprime = np.empty(self.S), nf[s](x), np.empty(self.S) for shat in range(self.S): c[shat] = cf[shat](x) for sprime in range(self.S): xprime[sprime] = xprimef[s, sprime](x) Τ = self.Τ(c, n)[s] u_c = Uc(c, n) Eu_c = π[sHist[t - 1]] @ u_c μHist[t] = self.Vf[s](x, 1) RHist[t - 1] = Uc(cHist[t - 1], nHist[t - 1]) / (self.β * Eu_c) cHist[t], nHist[t], Bhist[t], ΤHist[t] = c[s], n, x / u_c[s], Τ return np.array([cHist, nHist, Bhist, ΤHist, sHist, μHist, RHist])
class Planners_Allocation_Sequential: ''' Class returns planner's allocation as a function of the multiplier on the implementability constraint mu ''' def __init__(self,Para): ''' Initializes the class from the calibration Para ''' self.beta = Para.beta self.Pi = Para.Pi self.mc = MarkovChain(self.Pi) self.G = Para.G self.S = len(Para.Pi) # number of states self.Theta = Para.Theta self.Para = Para #now find the first best allocation self.find_first_best() def find_first_best(self): ''' Find the first best allocation ''' Para = self.Para S,Theta,Uc,Un,G = self.S,self.Theta,Para.Uc,Para.Un,self.G def res(z): c = z[:S] n = z[S:] return np.hstack( [Theta*Uc(c,n)+Un(c,n), Theta*n - c - G] ) res = root(res,0.5*np.ones(2*S)) if not res.success: raise Exception('Could not find first best') self.cFB = res.x[:S] self.nFB = res.x[S:] self.XiFB = Uc(self.cFB,self.nFB) #multiplier on the resource constraint. self.zFB = np.hstack([self.cFB,self.nFB,self.XiFB]) def time1_allocation(self,mu): ''' Computes optimal allocation for time t\geq 1 for a given \mu ''' Para = self.Para S,Theta,G,Uc,Ucc,Un,Unn = self.S,self.Theta,self.G,Para.Uc,Para.Ucc,Para.Un,Para.Unn def FOC(z): c = z[:S] n = z[S:2*S] Xi = z[2*S:] return np.hstack([ Uc(c,n) - mu*(Ucc(c,n)*c+Uc(c,n)) -Xi, #foc c Un(c,n) - mu*(Unn(c,n)*n+Un(c,n)) + Theta*Xi, #foc n Theta*n - c - G #resource constraint ]) #find the root of the FOC res = root(FOC,self.zFB) if not res.success: raise Exception('Could not find LS allocation.') z = res.x c,n,Xi = z[:S],z[S:2*S],z[2*S:] #now compute x I = Uc(c,n)*c + Un(c,n)*n x = np.linalg.solve(np.eye(S) - self.beta*self.Pi, I ) return c,n,x,Xi def time0_allocation(self,B_,s_0): ''' Finds the optimal allocation given initial government debt B_ and state s_0 ''' Para,Pi,Theta,G,beta = self.Para,self.Pi,self.Theta,self.G,self.beta Uc,Ucc,Un,Unn = Para.Uc,Para.Ucc,Para.Un,Para.Unn #first order conditions of planner's problem def FOC(z): mu,c,n,Xi = z xprime = self.time1_allocation(mu)[2] return np.hstack([ Uc(c,n)*(c-B_) + Un(c,n)*n + beta*Pi[s_0].dot(xprime), Uc(c,n) - mu*(Ucc(c,n)*(c-B_) + Uc(c,n)) - Xi, Un(c,n) - mu*(Unn(c,n)*n+Un(c,n)) + Theta[s_0]*Xi, (Theta*n - c - G)[s_0] ]) #find root res = root(FOC,np.array([0.,self.cFB[s_0],self.nFB[s_0],self.XiFB[s_0]])) if not res.success: raise Exception('Could not find time 0 LS allocation.') return res.x def time1_value(self,mu): ''' Find the value associated with multiplier mu ''' c,n,x,Xi = self.time1_allocation(mu) U = self.Para.U(c,n) V = np.linalg.solve(np.eye(self.S) - self.beta*self.Pi, U ) return c,n,x,V def Tau(self,c,n): ''' Computes Tau given c,n ''' Para = self.Para Uc,Un = Para.Uc(c,n),Para.Un(c,n) return 1+Un/(self.Theta * Uc) def simulate(self,B_,s_0,T,sHist=None): ''' Simulates planners policies for T periods ''' Para,Pi,beta = self.Para,self.Pi,self.beta Uc = Para.Uc if sHist == None: sHist = self.mc.simulate(s_0,T) cHist,nHist,Bhist,TauHist,muHist = np.zeros((5,T)) RHist = np.zeros(T-1) #time0 mu,cHist[0],nHist[0],_ = self.time0_allocation(B_,s_0) TauHist[0] = self.Tau(cHist[0],nHist[0])[s_0] Bhist[0] = B_ muHist[0] = mu #time 1 onward for t in range(1,T): c,n,x,Xi = self.time1_allocation(mu) Tau = self.Tau(c,n) u_c = Uc(c,n) s = sHist[t] Eu_c = Pi[sHist[t-1]].dot(u_c) cHist[t],nHist[t],Bhist[t],TauHist[t] = c[s],n[s],x[s]/u_c[s],Tau[s] RHist[t-1] = Uc(cHist[t-1],nHist[t-1])/(beta*Eu_c) muHist[t] = mu return cHist,nHist,Bhist,TauHist,sHist,muHist,RHist
class SequentialAllocation: ''' Class returns planner's allocation as a function of the multiplier on the implementability constraint μ ''' def __init__(self, model): ''' Initializes the class from the calibration model ''' self.β, self.π, self.G = model.β, model.π, model.G self.mc = MarkovChain(self.π) self.S = len(model.π) # number of states self.Θ = model.Θ self.model = model # now find the first best allocation self.find_first_best() def find_first_best(self): ''' Find the first best allocation ''' model = self.model S, Θ, Uc, Un, G = self.S, self.Θ, model.Uc, model.Un, self.G def res(z): c = z[:S] n = z[S:] return np.hstack([Θ * Uc(c, n) + Un(c, n), Θ * n - c - G]) res = root(res, 0.5 * np.ones(2 * S)) if not res.success: raise Exception('Could not find first best') self.cFB = res.x[:S] self.nFB = res.x[S:] # multiplier on the resource constraint. self.ΞFB = Uc(self.cFB, self.nFB) self.zFB = np.hstack([self.cFB, self.nFB, self.ΞFB]) def time1_allocation(self, μ): ''' Computes optimal allocation for time t\geq 1 for a given \mu ''' model = self.model S, Θ, G, Uc, Ucc, Un, Unn = self.S, self.Θ, self.G, model.Uc, model.Ucc, model.Un, model.Unn def FOC(z): c = z[:S] n = z[S:2 * S] Ξ = z[2 * S:] return np.hstack([ Uc(c, n) - μ * (Ucc(c, n) * c + Uc(c, n)) - Ξ, # foc c Un(c, n) - μ * (Unn(c, n) * n + Un(c, n)) + Θ * Ξ, # foc n Θ * n - c - G # resource constraint ]) # find the root of the FOC res = root(FOC, self.zFB) if not res.success: raise Exception('Could not find LS allocation.') z = res.x c, n, Ξ = z[:S], z[S:2 * S], z[2 * S:] # now compute x I = Uc(c, n) * c + Un(c, n) * n x = np.linalg.solve(np.eye(S) - self.β * self.π, I) return c, n, x, Ξ def time0_allocation(self, B_, s_0): ''' Finds the optimal allocation given initial government debt B_ and state s_0 ''' model, π, Θ, G, β = self.model, self.π, self.Θ, self.G, self.β Uc, Ucc, Un, Unn = model.Uc, model.Ucc, model.Un, model.Unn # first order conditions of planner's problem def FOC(z): μ, c, n, Ξ = z xprime = self.time1_allocation(μ)[2] return np.hstack([ Uc(c, n) * (c - B_) + Un(c, n) * n + β * π[s_0].dot(xprime), Uc(c, n) - μ * (Ucc(c, n) * (c - B_) + Uc(c, n)) - Ξ, Un(c, n) - μ * (Unn(c, n) * n + Un(c, n)) + Θ[s_0] * Ξ, (Θ * n - c - G)[s_0] ]) # find root res = root(FOC, np.array([0., self.cFB[s_0], self.nFB[s_0], self.ΞFB[s_0]])) if not res.success: raise Exception('Could not find time 0 LS allocation.') return res.x def time1_value(self, μ): ''' Find the value associated with multiplier μ ''' c, n, x, Ξ = self.time1_allocation(μ) U = self.model.U(c, n) V = np.linalg.solve(np.eye(self.S) - self.β * self.π, U) return c, n, x, V def Τ(self, c, n): ''' Computes Τ given c,n ''' model = self.model Uc, Un = model.Uc(c, n), model.Un(c, n) return 1 + Un / (self.Θ * Uc) def simulate(self, B_, s_0, T, sHist=None): ''' Simulates planners policies for T periods ''' model, π, β = self.model, self.π, self.β Uc = model.Uc if sHist is None: sHist = self.mc.simulate(T, s_0) cHist, nHist, Bhist, ΤHist, μHist = np.zeros((5, T)) RHist = np.zeros(T - 1) # time0 μ, cHist[0], nHist[0], _ = self.time0_allocation(B_, s_0) ΤHist[0] = self.Τ(cHist[0], nHist[0])[s_0] Bhist[0] = B_ μHist[0] = μ # time 1 onward for t in range(1, T): c, n, x, Ξ = self.time1_allocation(μ) Τ = self.Τ(c, n) u_c = Uc(c, n) s = sHist[t] Eu_c = π[sHist[t - 1]].dot(u_c) cHist[t], nHist[t], Bhist[t], ΤHist[t] = c[s], n[s], x[s] / \ u_c[s], Τ[s] RHist[t - 1] = Uc(cHist[t - 1], nHist[t - 1]) / (β * Eu_c) μHist[t] = μ return np.array([cHist, nHist, Bhist, ΤHist, sHist, μHist, RHist])
class SequentialAllocation: ''' Class that takes CESutility or BGPutility object as input returns planner's allocation as a function of the multiplier on the implementability constraint mu. ''' def __init__(self, model): # Initialize from model object attributes self.beta, self.pi, self.G = model.beta, model.pi, model.G self.mc, self.Theta = MarkovChain(self.pi), model.Theta self.S = len(model.pi) # Number of states self.model = model # Find the first best allocation self.find_first_best() def find_first_best(self): ''' Find the first best allocation ''' model = self.model S, Theta, G = self.S, self.Theta, self.G Uc, Un = model.Uc, model.Un def res(z): c = z[:S] n = z[S:] return np.hstack([Theta * Uc(c, n) + Un(c, n), Theta * n - c - G]) res = root(res, 0.5 * np.ones(2 * S)) if not res.success: raise Exception('Could not find first best') self.cFB = res.x[:S] self.nFB = res.x[S:] # Multiplier on the resource constraint self.XiFB = Uc(self.cFB, self.nFB) self.zFB = np.hstack([self.cFB, self.nFB, self.XiFB]) def time1_allocation(self, mu): ''' Computes optimal allocation for time t\geq 1 for a given \mu ''' model = self.model S, Theta, G = self.S, self.Theta, self.G Uc, Ucc, Un, Unn = model.Uc, model.Ucc, model.Un, model.Unn def FOC(z): c = z[:S] n = z[S:2 * S] Xi = z[2 * S:] return np.hstack([Uc(c, n) - mu * (Ucc(c, n) * c + Uc(c, n)) - Xi, # FOC of c Un(c, n) - mu * (Unn(c, n) * n + Un(c, n)) + \ Theta * Xi, # FOC of n Theta * n - c - G]) # Find the root of the first order condition res = root(FOC, self.zFB) if not res.success: raise Exception('Could not find LS allocation.') z = res.x c, n, Xi = z[:S], z[S:2 * S], z[2 * S:] # Compute x I = Uc(c, n) * c + Un(c, n) * n x = np.linalg.solve(np.eye(S) - self.beta * self.pi, I) return c, n, x, Xi def time0_allocation(self, B_, s_0): ''' Finds the optimal allocation given initial government debt B_ and state s_0 ''' model, pi, Theta, G, beta = self.model, self.pi, self.Theta, self.G, self.beta Uc, Ucc, Un, Unn = model.Uc, model.Ucc, model.Un, model.Unn # First order conditions of planner's problem def FOC(z): mu, c, n, Xi = z xprime = self.time1_allocation(mu)[2] return np.hstack([ Uc(c, n) * (c - B_) + Un(c, n) * n + beta * pi[s_0] @ xprime, Uc(c, n) - mu * (Ucc(c, n) * (c - B_) + Uc(c, n)) - Xi, Un(c, n) - mu * (Unn(c, n) * n + Un(c, n)) + Theta[s_0] * Xi, (Theta * n - c - G)[s_0] ]) # Find root res = root(FOC, np.array([0, self.cFB[s_0], self.nFB[s_0], self.XiFB[s_0]])) if not res.success: raise Exception('Could not find time 0 LS allocation.') return res.x def time1_value(self, mu): ''' Find the value associated with multiplier mu ''' c, n, x, Xi = self.time1_allocation(mu) U = self.model.U(c, n) V = np.linalg.solve(np.eye(self.S) - self.beta * self.pi, U) return c, n, x, V def Tau(self, c, n): ''' Computes Tau given c, n ''' model = self.model Uc, Un = model.Uc(c, n), model.Un(c, n) return 1 + Un / (self.Theta * Uc) def simulate(self, B_, s_0, T, sHist=None): ''' Simulates planners policies for T periods ''' model, pi, beta = self.model, self.pi, self.beta Uc = model.Uc if sHist is None: sHist = self.mc.simulate(T, s_0) cHist, nHist, Bhist, TauHist, muHist = np.zeros((5, T)) RHist = np.zeros(T - 1) # Time 0 mu, cHist[0], nHist[0], _ = self.time0_allocation(B_, s_0) TauHist[0] = self.Tau(cHist[0], nHist[0])[s_0] Bhist[0] = B_ muHist[0] = mu # Time 1 onward for t in range(1, T): c, n, x, Xi = self.time1_allocation(mu) Tau = self.Tau(c, n) u_c = Uc(c, n) s = sHist[t] Eu_c = pi[sHist[t - 1]] @ u_c cHist[t], nHist[t], Bhist[t], TauHist[t] = c[s], n[s], x[s] / \ u_c[s], Tau[s] RHist[t - 1] = Uc(cHist[t - 1], nHist[t - 1]) / (beta * Eu_c) muHist[t] = mu return np.array([cHist, nHist, Bhist, TauHist, sHist, muHist, RHist])
cp.gamma_c = model_in["gamma_c"] cp.gamma_l = model_in["gamma_l"] cp.A_L = model_in["A_L"] cp.Pi = np.asarray(model_in["Pi"]) cp.z_vals = np.asarray(model_in["z_vals"]) model.close() #====Normalize mean of Labour distributuons===# mc = MarkovChain(cp.Pi) stationary_distributions = mc.stationary_distributions mean = np.dot(stationary_distributions, cp.z_vals) cp.z_vals = cp.z_vals/ mean ## Standardise mean of avaible labour supply to 1 z_seq = mc.simulate(T) #===Create Dict for Saving Results===# Results = {} Results["Name of Model"] = model_in["name"] #====Calcuate First Best===# fb_r, fb_K, fb_H, fb_L, fb_Y, fb_w = firstbest(fp,cp) print('Runnung model {}, with grid_zize {}, max assets {}, T length of {}, prob matrix {}, z_vals {}, gamma_c {}, gamma_l{}'.format(name, len(cp.asset_grid), np.max(cp.asset_grid), T, cp.Pi, cp.z_vals, cp.gamma_c, cp.gamma_l)) print('First best output {}, capital {}, interest rate {}, hours {} and labour supply {}'.format(fb_Y, fb_K, fb_r, fb_H, fb_L))
def analyze_dtmc(P, states=None, sim_kwargs=None, trans_kwargs=None, cost_kwargs=None): """ Perform Markov Analysis of discrete time discrete state markov chain (DTMC) process. Parameters ---------- P : array-like The transition matrix. Must be of shape n x n. states : array-like Array_like of length n containing the values associated with the states, which must be homogeneous in type. If None, the values default to integers 0 through n-1. sim_kwargs : dict Dictionary of key word arguments to be passed to the simulation of the markov process. If None, then no simulation will be performed. These include ts_length (length of each simulation) and init (Initial state values). trans_kwargs : dict Dictionary of options for the transient probability analysis (tsa). If None is passed instead of dict, no tsa will be done. ts_length is the number of time periods to analyze, while init is the initial state probability vector. cost_kwargs : dict Dictionary of cost parameters for cost analysis. If None, then no cost analysis will be performed. These include state (vector of costs of being in each state), transition (matrix of costs of transitioning from one state to another), and num (number of these processes - total cost multiplied by this, default 1). Returns ------- analysis : dict Dictionary with results of markov analysis Raises ------ ValueError If sim_kwargs, trans_kwargs, or cost_kwargs is given, but their required arguments are not passed. These are described in the Notes section. Notes ----- The required arguments if the kwargs are passed are: * sim_kwargs: `ts_length` is required, the length of the sim. * trans_kwargs: `ts_length` is required, the number of periods to analyze * cost_kwargs: `state` and `transition` are required, which are the costs of being in any state and the costs of transitioning from one state to another. """ analysis = {} markov = MarkovChain(P, states) analysis["cdfs"] = markov.cdfs steady_state = markov.stationary_distributions[0] analysis["steady_state"] = {"output": steady_state} if sim_kwargs: if "ts_length" not in sim_kwargs: raise ValueError(("Required argument `ts_length` in sim_kwargs! " "None was given.")) if "init" not in sim_kwargs: sim_kwargs["init"] = None analysis["sim"] = { "kwargs": sim_kwargs, "output": markov.simulate(**sim_kwargs) } if trans_kwargs: if "ts_length" not in trans_kwargs: raise ValueError(("Required argument `ts_length` in trans_kwargs! " "None was given.")) if "init" not in trans_kwargs: trans_kwargs["init"] = None trans_probs = _transient_probs(P, states, **trans_kwargs) analysis["transient"] = {"kwargs": trans_kwargs, "output": trans_probs} if cost_kwargs: if "state" not in cost_kwargs: raise ValueError(("Required argument `state` in trans_kwargs! " "None was given.")) if "transition" not in cost_kwargs: raise ValueError(("Required argument `transition` in trans_kwargs!" " None was given.")) if "num" not in cost_kwargs: cost_kwargs["num"] = 1 # Cost of steady state cost_vector, cost_total = _cost_analysis(P, steady_state, **cost_kwargs) # Cost of transient analysis analysis["steady_state"]["cost"] = \ {"kwargs": cost_kwargs, "total": cost_total, "vector": cost_vector} if trans_kwargs: cost_vector, cost_total = _cost_analysis(P, trans_probs, **cost_kwargs) analysis["transient"]["cost"] = { "kwargs": cost_kwargs, "total": cost_total, "vector": cost_vector } return analysis
matplotlib.style.use('ggplot') lm = LakeModel(d=0, b=0) T = 5000 # Simulation length alpha, lmda = lm.alpha, lm.lmda P = [[1 - lmda, lmda], [alpha, 1 - alpha]] mc = MarkovChain(P) xbar = lm.rate_steady_state() fig, axes = plt.subplots(2, 1, figsize=(10, 8)) s_path = mc.simulate(T, init=1) s_bar_e = s_path.cumsum() / range(1, T+1) s_bar_u = 1 - s_bar_e ax = axes[0] ax.plot(s_bar_u, '-b', lw=2, alpha=0.5) ax.hlines(xbar[1], 0, T, 'r', '--') ax.set_title(r'Percent of time unemployed') ax = axes[1] ax.plot(s_bar_e, '-b', lw=2, alpha=0.5) ax.hlines(xbar[0], 0, T, 'r', '--') ax.set_title(r'Percent of time employed') plt.tight_layout() plt.show()