def d2y_SZ(z_i): DFi,df,Hf = DF(z_i)[n:],self.df(z_i),self.Hf(z_i) d,d2y_ZZ = self.get_d(z_i),self.d2y[Z,Z](z_i) temp = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + self.dZ_Z[0]*DFi[:,v].dot(Ivy)) return -np.tensordot(temp, self.HFhat[S,Z](z_i) + np.tensordot(DFi[:,e],quadratic_dot(Hf,d[y,S],d[y,Z]),1) + np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(d2y_ZZ,IZY.dot(d[Y,S]),self.dZ_Z),1),1)
def compute_ye(x): z_i,zbar = x extreme = Para.check_extreme(z_i) zhat = z_i-zbar r = np.random.randn(neps) for i in range(neps): r[i] = min(3.,max(-3.,r[i])) e = r*sigma Shat = np.hstack([zhat,Y1hat]) if not extreme: return np.hstack(( self.ss.get_y(zbar).flatten() + self.dy[eps](zbar).dot(e).flatten() + (self.dy[Eps](zbar).flatten())*0. + self.dy[p](zbar).dot(phat).flatten() + self.dy[z](zbar).dot(zhat).flatten() + self.dy[Y](zbar).dot(Y1hat).flatten() + self.dy[Z](zbar).dot(Zhat).flatten() + 0.5*quadratic*(quadratic_dot(self.d2y[eps,eps](zbar),e,e).flatten() + self.d2y[sigma](zbar).dot(sigma**2).flatten() +quadratic_dot(self.d2y[S,S](zbar),Shat,Shat) + 2*quadratic_dot(self.d2y[S,eps](zbar),Shat,e) +self.dy[Y](zbar).dot(Y2hat) +2*quadratic_dot(self.d2y[Z,S](zbar),Zhat,Shat) +2*quadratic_dot(self.d2y[Z,eps](zbar),Zhat,e) +quadratic_dot(self.d2y[Z,Z](zbar),Zhat,Zhat) +2*np.einsum('ijk,jk,k',self.dy[Y,S,Z](zbar),Y2hat_GZ,Zhat) +2*np.einsum('ijk,jk,k',self.d2y[Y,S,Z](zbar),Y2hat_GZ,IZYhat.dot(Y1hat)) +self.d2y[Eps,Eps](zbar).flatten()*sigma_E**2 +self.d2y[sigma_E](zbar).flatten()*sigma_E**2 ).flatten() ,e))
def compute_ye(x): z_i,zbar = x zhat = z_i-zbar r = np.random.randn(neps) for i in range(neps): r[i] = min(3.,max(-3.,r[i])) e = r*sigma Shat = np.hstack([zhat,Y1hat]) return np.hstack(( self.ss.get_y(zbar).flatten() + self.dy[eps](zbar).dot(e).flatten() + (self.dy[Eps](zbar).flatten())*0. + self.dy[p](zbar).dot(phat).flatten() + self.dy[z](zbar).dot(zhat).flatten() + self.dy[Y](zbar).dot(Y1hat).flatten() + self.dy[Z](zbar).dot(Zhat).flatten() + 0.5*(quadratic_dot(self.d2y[eps,eps](zbar),e,e).flatten() + self.d2y[sigma](zbar).dot(sigma**2).flatten() +quadratic_dot(self.d2y[S,S](zbar),Shat,Shat) + 2*quadratic_dot(self.d2y[S,eps](zbar),Shat,e) +self.dy[Y](zbar).dot(Y2hat) +2*quadratic_dot(self.d2y[Z,S](zbar),Zhat,Shat) +2*quadratic_dot(self.d2y[Z,eps](zbar),Zhat,e) +quadratic_dot(self.d2y[Z,Z](zbar),Zhat,Zhat) +2*self.dy[Y,S,Z](zbar).dot(Y2hat_GZ).dot(Zhat) +2*self.d2y[Y,S,Z](zbar).dot(Y2hat_GZ).dot(IZY).dot(Y1hat) +self.d2y[Eps,Eps](zbar).flatten()*sigma_E**2 +self.d2y[sigma_E](zbar).flatten()*sigma_E**2 ).flatten() ,e))
def d2y_SS(z_i): DF,df,Hf = self.DF(z_i),self.df(z_i),self.Hf(z_i) d = self.get_d(z_i) DFi = DF[n:] return np.tensordot(np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy)), -self.HFhat[S,S](z_i) - np.tensordot(DFi[:,e],quadratic_dot(Hf,d[y,S],d[y,S]),1) -np.tensordot(DFi[:,v].dot(Ivy),quadratic_dot(self.d2y[Z,Z](z_i),IZY.dot(d[Y,S]),IZY.dot(d[Y,S])),1) , axes=1)
def d2y_SS(z_i): DF,df,Hf = self.DF(z_i),self.df(z_i),self.Hf(z_i) d = self.get_d(z_i) DFi = DF[n:] return np.tensordot(np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy)), -self.HFhat[S,S](z_i) - np.tensordot(DFi[:,e],quadratic_dot(Hf,d[y,S],d[y,S]),1) -np.tensordot(DFi[:,v].dot(Ivy),quadratic_dot(self.d2y[Z,Z](z_i),IZYhat.dot(d[Y,S]),IZYhat.dot(d[Y,S])),1) -2*np.einsum('ij...,j...->i...',DFi[:,v].dot(Ivy),quadratic_dot(self.d2y[Z,S](z_i),IZYhat.dot(d[Y,S]),np.eye(nY+nz))) , axes=1)
def DFhat_EpsEps(z_i): dSprime_Eps_i,dZprime_Eps = dSprime_Eps(z_i),IZY.dot(self.dY_Eps) DFi = DF(z_i)[:-n] return self.HFhat[Eps,Eps](z_i) + np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(self.d2y[S,S](z_i),dSprime_Eps_i,dSprime_Eps_i) +2*quadratic_dot(self.d2y[S,Z](z_i),dSprime_Eps_i,dZprime_Eps) +quadratic_dot(self.d2y[Z,Z](z_i),dZprime_Eps,dZprime_Eps) +np.tensordot(self.dy[Y](z_i),d2Yprime_EpsEps,1) +2*np.tensordot(self.dy[Y,S,Z](z_i),d2YprimeGZ_EpsEps1,1) #from dy_GammaZ +2*np.tensordot(self.d2y[Y,S,Z](z_i),d2YprimeGZ_EpsEps2,1) #from dy_GammaGamma ,axes=1)
def d2y_SZ(z_i): DFi,df,Hf = DF(z_i)[n:],self.df(z_i),self.Hf(z_i) d,d2y_ZZ = self.get_d(z_i),self.d2y[Z,Z](z_i) temp = -(self.HFhat[S,Z](z_i) + np.tensordot(DFi[:,e],quadratic_dot(Hf,d[y,S],d[y,Z]),1) + np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(d2y_ZZ,IZYhat.dot(d[Y,S]),self.dZ_Z),1) ) d2y_SZ = np.empty((ny,nY+nz,nZ)) for i,rho in enumerate(D): temp2 = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + rho*DFi[:,v].dot(Ivy)) d2y_SZ[:,:,i] = temp2.dot(temp[:,:,i]) return d2y_SZ
def DFhat_EpsEps(z_i): dSprime_Eps_i,dZprime_Eps = dSprime_Eps(z_i),IZYhat.dot(self.dY_Eps) DFi = DF(z_i)[:-n] return self.HFhat[Eps,Eps](z_i) + np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(self.d2y[S,S](z_i),dSprime_Eps_i,dSprime_Eps_i) +2*quadratic_dot(self.d2y[S,Z](z_i),dSprime_Eps_i,dZprime_Eps) +quadratic_dot(self.d2y[Z,Z](z_i),dZprime_Eps,dZprime_Eps) +np.tensordot(self.dy[Y](z_i),d2Yprime_EpsEps,1) +2*np.einsum('ijk,jlkm',self.dy[Y,S,Z](z_i),d2YprimeGZ_EpsEps1) #from dy_GammaZ +2*np.einsum('ijk,jlkm',self.d2y[Y,S,Z](z_i),d2YprimeGZ_EpsEps2) #from dy_GammaGamma ,axes=1)
def HFhat_temp(z_i,x1=x1,x2=x2): HF = self.HF(z_i) d = self.get_d(z_i) HFhat = 0. for y1 in [y,e,Y,z,v,eps,Eps]: HFy1 = HF[:,y1,:] for y2 in [y,e,Y,z,v,eps,Eps]: if x1.__hash__() in shock_hashes or x2.__hash__() in shock_hashes: HFhat += quadratic_dot(HFy1[:-n,:,y2],d[y1,x1],d[y2,x2]) else: HFhat += quadratic_dot(HFy1[n:,:,y2],d[y1,x1],d[y2,x2]) return HFhat
def HFhat_temp(z_i,x1=x1,x2=x2): HF = self.HF(z_i) d = self.get_d(z_i) HFhat = 0. for y1 in [y,e,Y,Z,z,v,eps,Eps]: HFy1 = HF[:,y1,:] for y2 in [y,e,Y,Z,z,v,eps,Eps]: if x1.__hash__() in shock_hashes or x2.__hash__() in shock_hashes: HFhat += quadratic_dot(HFy1[:-n,:,y2],d[y1,x1],d[y2,x2]) else: HFhat += quadratic_dot(HFy1[n:,:,y2],d[y1,x1],d[y2,x2]) return HFhat
def HFhat_temp(z_i,x1=x1,x2=x2): HF = self.HF(z_i) d = self.get_d(z_i) HFhat = 0. for y1 in [y,e,Y,z,v,eps]: HFy1 = HF[:,y1,:] for y2 in [y,e,Y,z,v,eps]: if x1 == S and x2 == S: HFhat += quadratic_dot(HFy1[n:,:,y2],d[y1,x1],d[y2,x2]) else: HFhat += quadratic_dot(HFy1[:-n,:,y2],d[y1,x1],d[y2,x2]) return HFhat
def compute_dsigma(self): ''' Computes how dY and dy_i depend on sigma ''' DG = lambda z_i : self.DG(z_i)[nG:,:] #Now how do things depend with sigma self.integral_term =self.integrate(lambda z_i: quadratic_dot(self.d2Y[z,z](z_i),Izy.dot(self.dy[eps](z_i)),Izy.dot(self.dy[eps](z_i))).diagonal(0,1,2) + self.dY(z_i).dot(Izy).dot(self.d2y[eps,eps](z_i).diagonal(0,1,2))) ABCi = dict_fun(self.compute_d2y_sigma ) Ai,Bi,Ci = lambda z_i : ABCi(z_i)[:,:neps], lambda z_i : ABCi(z_i)[:,neps:nY+neps], lambda z_i : ABCi(z_i)[:,nY+neps:] Atild = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(Ai(z_i))) Btild = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(Bi(z_i))) Ctild = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(Ci(z_i))) tempC = np.linalg.inv(np.eye(nY)-Ctild) DGhat = self.integrate(self.compute_DGhat_sigma) temp1 = self.integrate(lambda z_i:DG(z_i)[:,Y] + DG(z_i)[:,y].dot(Bi(z_i)+Ci(z_i).dot(tempC).dot(Btild)) ) temp2 = self.integrate(lambda z_i:DG(z_i)[:,y].dot(Ai(z_i)+Ci(z_i).dot(tempC).dot(Atild)) ) self.d2Y[sigma] = np.linalg.solve(temp1,-DGhat-temp2) self.d2y[sigma] = dict_fun(lambda z_i: Ai(z_i) + Ci(z_i).dot(tempC).dot(Atild) + ( Bi(z_i)+Ci(z_i).dot(tempC).dot(Btild) ).dot(self.d2Y[sigma]))
def compute_dsigma(self): ''' Computes how dY and dy_i depend on sigma ''' DG = self.DG #Now how do things depend with sigma integral_term =self.integrate(lambda z_i: quadratic_dot(self.d2Y[z,z](z_i),Izy.dot(self.dy[eps](z_i)),Izy.dot(self.dy[eps](z_i))).flatten() + self.dY(z_i).dot(Izy).dot(self.d2y[eps,eps](z_i).flatten())) ABCi = self.interpolate(parallel_map(lambda z_i:self.compute_d2y_sigma(z_i,integral_term),self.zgrid) ) Ai,Bi,Ci = dict_fun(ABCi[:,0]),dict_fun(ABCi[:,1:nY+1]),dict_fun(ABCi[:,nY+1:]) Atild = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(Ai(z_i))) Btild = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(Bi(z_i))) Ctild = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(Ci(z_i))) tempC = np.linalg.inv(np.eye(nY)-Ctild) DGhat = self.integrate(self.interpolate(parallel_map(self.compute_DGhat_sigma,self.zgrid))) temp1 = self.integrate(lambda z_i:DG(z_i)[:,Y] + DG(z_i)[:,y].dot(Bi(z_i)+Ci(z_i).dot(tempC).dot(Btild)) ) temp2 = self.integrate(lambda z_i:DG(z_i)[:,y].dot(Ai(z_i)+Ci(z_i).dot(tempC).dot(Atild)) ) self.d2Y[sigma] = np.linalg.solve(temp1,-DGhat-temp2) self.d2y[sigma] = dict_fun(self.interpolate( parallel_map(lambda z_i: Ai(z_i) + Ci(z_i).dot(tempC).dot(Atild) + ( Bi(z_i)+Ci(z_i).dot(tempC).dot(Btild) ).dot(self.d2Y[sigma]),self.zgrid)))
def d2y_epseps(z_i): DF = self.DF(z_i) d = self.get_d(z_i) DFi = DF[:-n] return np.tensordot(np.linalg.inv(DFi[:,y] + DFi[:,v].dot(Ivy).dot(d[y,z]).dot(Izy)), -self.HFhat[eps,eps](z_i) - np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(self.d2y[S,S](z_i)[:,:nz,:nz],d[z,eps],d[z,eps]),1) ,axes=1)
def d2y_epseps(z_i): DF = self.DF(z_i) d = self.get_d(z_i) DFi = DF[:-n] dz_eps= Izy.dot(d[y,eps]) return np.tensordot(np.linalg.inv(DFi[:,y] + DFi[:,v].dot(Ivy).dot(d[y,z]).dot(Izy)), -self.HFhat[eps,eps](z_i) - np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(self.d2y[S,S](z_i)[:,:nz,:nz],dz_eps,dz_eps),1) ,axes=1)
def HGhat(z_i,y1,y2): HG = self.HG(z_i)[:-nG,:] d = self.get_d(z_i) HGhat = np.zeros((nY,len(y1),len(y2))) for x1 in [y,z,Y,Z,Eps]: HGx1 = HG[:,x1,:] for x2 in [y,z,Y,Z,Eps]: HGhat += quadratic_dot(HGx1[:,:,x2],d[x1,y1],d[x2,y2]) return HGhat
def d2y_Seps(z_i): DF = self.DF(z_i) d = self.get_d(z_i) DFi = DF[:-n] dz_eps= Izy.dot(d[y,eps]) return np.tensordot(np.linalg.inv(DFi[:,y] + DFi[:,v].dot(Ivy).dot(d[y,z]).dot(Izy)), -self.HFhat[S,eps](z_i) - np.tensordot(DFi[:,v].dot(Ivy), self.d2y[S,S](z_i)[:,:,:nz].dot(dz_eps),1) -np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(self.d2y[Z,S](z_i)[:,:,:nz],IZYhat.dot(d[Y,S]),dz_eps),1) , axes=1)
def compute_ye(z_i): r = np.random.randn(neps) for i in range(neps): if z_i[0] > logm_min and z_i[1] > muhat_min: r[i] = min(3.,max(-3.,r[i])) else: r[i] = min(1.,max(logm_min-z_i[0]+0.1,(muhat_min-z_i[1])/10. +0.1)) e = r*sigma return np.hstack(( self.ss.get_y(z_i).flatten() + self.dy[eps](z_i).dot(e).flatten() + self.dy[Eps](z_i).flatten()*E + self.dy[p](z_i).dot(phat).flatten() + 0.5*quadratic*(quadratic_dot(self.d2y[eps,eps](z_i),e,e).flatten() + self.d2y[sigma](z_i).dot(sigma**2).flatten()).flatten() ,e))
def compute_DGhat(self,z_i): ''' Computes the second order approximation for agent of type z_i ''' DG,HG = self.DG(z_i)[nG:,:],self.HG(z_i)[nG:,:,:] d = self.get_d(z_i) d2y = self.d2y DGhat = np.zeros((nY,nz+nY,nz+nY)) DGhat += np.tensordot(DG[:,y],d2y[S,S](z_i),1) for x1 in [y,Y,z]: HGx1 = HG[:,x1,:] for x2 in [y,Y,z]: DGhat += quadratic_dot(HGx1[:,:,x2],d[x1,S],d[x2,S]) return DGhat
def compute_DGhat_sigma(self,z_i): ''' Computes the second order approximation for agent of type z_i ''' DG,HG = self.DG(z_i)[nG:,:],self.HG(z_i)[nG:,:,:] d = self.get_d(z_i) d2y = self.d2y DGhat = np.zeros((nY,neps)) DGhat += DG[:,y].dot(d2y[eps,eps](z_i).diagonal(0,1,2)) d[eps,eps] =np.eye(neps) for x1 in [y,eps]: HGx1 = HG[:,x1,:] for x2 in [y,eps]: DGhat += quadratic_dot(HGx1[:,:,x2],d[x1,eps],d[x2,eps]).diagonal(0,1,2) return DGhat
def compute_DGhat_sigma(self,z_i): ''' Computes the second order approximation for agent of type z_i ''' DG,HG = self.DG(z_i),self.HG(z_i) d = self.get_d(z_i) d2y = self.d2y DGhat = np.zeros(nY) DGhat += DG[:,y].dot(d2y[eps,eps](z_i).flatten()) d[eps,eps] =np.array([[1]]) for x1 in [y,eps]: HGx1 = HG[:,x1,:] for x2 in [y,eps]: DGhat += quadratic_dot(HGx1[:,:,x2],d[x1,eps],d[x2,eps]).flatten() return DGhat
def compute_d2y_sigma(self,z_i): ''' Computes linear contribution of sigma, dYsigma and dY1sigma ''' DF = self.DF(z_i) df,Hf = self.df(z_i),self.Hf(z_i) #first compute DFhat, need loadings of S and epsilon on variables d = self.get_d(z_i) d[y,Y] = d[y,S][:,nz:] DFi = DF[n:] #conditions like x_i = Ex_i don't effect this temp = np.linalg.inv(DFi[:,y]+DFi[:,e].dot(df)+DFi[:,v].dot(Ivy+Ivy.dot(d[y,z]).dot(Izy))) Ahat = (-DFi[:,e].dot(df).dot(self.d2y[eps,eps](z_i).diagonal(0,1,2)) -DFi[:,e].dot(quadratic_dot(Hf,d[y,eps],d[y,eps]).diagonal(0,1,2)) -DFi[:,v].dot(Ivy).dot(d[y,Y]).dot(self.integral_term) ) Bhat = -DFi[:,Y]- DFi[:,v].dot(Ivy).dot(d[y,Z]).dot(IZY) Chat = -DFi[:,v].dot(Ivy).dot(d[y,Y]) return temp.dot(np.hstack((Ahat.reshape(-1,neps),Bhat,Chat)))
def compute_d2y_sigma(self,z_i): ''' Computes linear contribution of sigma, dYsigma and dY1sigma ''' DF = self.DF(z_i) df,Hf = self.df(z_i),self.Hf(z_i) #first compute DFhat, need loadings of S and epsilon on variables d = self.get_d(z_i) d[y,Y] = d[y,S][:,nz:] DFi = DF[n:] #conditions like x_i = Ex_i don't effect this temp = np.linalg.inv(DFi[:,y]+DFi[:,e].dot(df)+DFi[:,v].dot(Ivy+Ivy.dot(d[y,z]).dot(Izy))) Ahat = (-DFi[:,e].dot(df).dot(self.d2y[eps,eps](z_i).diagonal(0,1,2)) -DFi[:,e].dot(quadratic_dot(Hf,d[y,eps],d[y,eps]).diagonal(0,1,2)) -DFi[:,v].dot(Ivy).dot(d[y,Y]).dot(self.integral_term) ) Bhat = -DFi[:,Y]- DFi[:,v].dot(Ivy).dot(d[y,Z]).dot(IZYhat) Chat = -DFi[:,v].dot(Ivy).dot(d[y,Y]) return temp.dot(np.hstack((Ahat.reshape(-1,neps),Bhat,Chat)))
def compute_d2y(self,z_i): ''' Computes second derivative of y ''' DF,HF = self.DF(z_i),self.HF(z_i) df,Hf = self.df(z_i),self.Hf(z_i) #first compute DFhat, need loadings of S and epsilon on variables d = self.get_d(z_i) #Now compute Fhat HFhat = {} HFhat[S,S],HFhat[S,eps],HFhat[eps,S],HFhat[eps,eps] = 0.,0.,0.,0. for x1 in [y,e,Y,z,v,eps]: HFx1 = HF[:,x1,:] for x2 in [y,e,Y,z,v,eps]: HFhat[S,S] += quadratic_dot(HFx1[n:,:,x2],d[x1,S],d[x2,S]) HFhat[S,eps] += quadratic_dot(HFx1[:-n,:,x2],d[x1,S],d[x2,eps]) HFhat[eps,S] += quadratic_dot(HFx1[:-n,:,x2],d[x1,eps],d[x2,S]) HFhat[eps,eps] += quadratic_dot(HFx1[:-n,:,x2],d[x1,eps],d[x2,eps]) #Now compute d2y d2y = {} DFi = DF[n:] d2y[S,S] = np.tensordot(np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy)), -HFhat[S,S] - np.tensordot(DFi[:,e],quadratic_dot(Hf,d[y,S],d[y,S]),1) , axes=1) DFi = DF[:-n] d2y[S,eps] =np.tensordot(np.linalg.inv(DFi[:,y] + DFi[:,v].dot(Ivy).dot(d[y,z]).dot(Izy)), -HFhat[S,eps] - np.tensordot(DFi[:,v].dot(Ivy), d2y[S,S][:,:,:nz].dot(d[z,eps]),1) , axes=1) d2y[eps,S] = copy(d2y[S,eps]) d2y[eps,S].transpose(0,2,1) d2y[eps,eps] = np.tensordot(np.linalg.inv(DFi[:,y] + DFi[:,v].dot(Ivy).dot(d[y,z]).dot(Izy)), -HFhat[eps,eps] - np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(d2y[S,S][:,:nz,:nz],d[z,eps],d[z,eps]),1) ,axes=1) return d2y
def d2Y_zZ(z_i): temp1 = np.linalg.inv(self.DG(z_i)[nG:,y].dot(dy_YSZ(z_i)) + self.DG(z_i)[nG:,Y]) temp2 = HGhat_zZ(z_i) + quadratic_dot(HGhat_YZ,self.dY(z_i),np.eye(nZ)) return - np.tensordot(temp1,temp2,1)
def A2_i(z_i): #the pure term DFi = DF(z_i)[n:] df,hf = self.df(z_i),self.Hf(z_i) return np.tensordot(temp2(z_i),np.tensordot(DFi[:,e].dot(df),self.d2y[Eps,Eps](z_i),1) +np.tensordot(DFi[:,e],quadratic_dot(hf,self.dy[Eps](z_i),self.dy[Eps](z_i)),1) ,axes=1)
def d2y_Zeps(z_i): DFi = DF(z_i)[:-n] temp = np.linalg.inv(DFi[:,y] + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy)) return -np.tensordot(temp, self.HFhat[Z,eps](z_i) + np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(self.d2y[Z,S](z_i)[:,:,:nz],self.dZ_Z,Izy.dot(self.dy[eps](z_i))) ,1),1)
def compute_d2y_Eps(self): ''' Computes the 2nd derivatives of y with respect to the aggregate shock. ''' def HGhat(z_i,y1,y2): HG = self.HG(z_i)[:-nG,:] d = self.get_d(z_i) HGhat = np.zeros((nY,len(y1),len(y2))) for x1 in [y,z,Y,Z,Eps]: HGx1 = HG[:,x1,:] for x2 in [y,z,Y,Z,Eps]: HGhat += quadratic_dot(HGx1[:,:,x2],d[x1,y1],d[x2,y2]) return HGhat DF = self.DF def dSprime_Eps(z_i): return np.vstack((Izy.dot(self.dy[Eps](z_i)),self.dYGamma_Eps)) d2Yprime_EpsEps = self.integrate(lambda z_i : quadratic_dot(self.d2Y[z,z](z_i),Izy.dot(self.dy[Eps](z_i)),Izy.dot(self.dy[Eps](z_i))) +2*quadratic_dot(self.d2Y[z,Y](z_i),Izy.dot(self.dy[Eps](z_i)),self.dYGamma_Eps)) d2YprimeGZ_EpsEps1 = self.integrate(lambda z_i: np.einsum('ijk,jl,km->ilkm',self.d2Y[z,Z](z_i),Izy.dot(self.dy[Eps](z_i)),IZYhat.dot(self.dY_Eps))) d2YprimeGZ_EpsEps2 = self.integrate(lambda z_i: np.einsum('ijk,jl,km->ilkm',self.d2Y[z,Z](z_i),Izy.dot(self.dy[Eps](z_i)),IZYhat.dot(self.dYGamma_Eps))) def DFhat_EpsEps(z_i): dSprime_Eps_i,dZprime_Eps = dSprime_Eps(z_i),IZYhat.dot(self.dY_Eps) DFi = DF(z_i)[:-n] return self.HFhat[Eps,Eps](z_i) + np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(self.d2y[S,S](z_i),dSprime_Eps_i,dSprime_Eps_i) +2*quadratic_dot(self.d2y[S,Z](z_i),dSprime_Eps_i,dZprime_Eps) +quadratic_dot(self.d2y[Z,Z](z_i),dZprime_Eps,dZprime_Eps) +np.tensordot(self.dy[Y](z_i),d2Yprime_EpsEps,1) +2*np.einsum('ijk,jlkm',self.dy[Y,S,Z](z_i),d2YprimeGZ_EpsEps1) #from dy_GammaZ +2*np.einsum('ijk,jlkm',self.d2y[Y,S,Z](z_i),d2YprimeGZ_EpsEps2) #from dy_GammaGamma ,axes=1) def temp(z_i): DFi = DF(z_i)[:-n] return -np.linalg.inv(DFi[:,y]+DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy)) temp = dict_fun(temp) A_i = dict_fun(lambda z_i: np.tensordot(temp(z_i),DFhat_EpsEps(z_i),1)) B_i = dict_fun(lambda z_i: temp(z_i).dot(DF(z_i)[:-n,Y] + DF(z_i)[:-n,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat) )) C_i = dict_fun(lambda z_i: temp(z_i).dot(DF(z_i)[:-n,v].dot(Ivy).dot(self.dy[Y](z_i)))) A = self.integrate(lambda z_i : np.tensordot(self.dY(z_i).dot(Izy),A_i(z_i),1)) B,C = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(B_i(z_i))),self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(C_i(z_i))) tempC = np.linalg.inv(np.eye(nY)-C) d2y_EE =lambda z_i: A_i(z_i) + np.tensordot(C_i(z_i).dot(tempC),A,1) dy_YEE = lambda z_i: B_i(z_i) + C_i(z_i).dot(tempC).dot(B) HGhat_EE = self.integrate(lambda z_i: HGhat(z_i,Eps,Eps) + np.tensordot(self.DG(z_i)[:-nG,y],d2y_EE(z_i),1)) DGhat_YEEinv = np.linalg.inv(self.integrate(lambda z_i : self.DG(z_i)[:-nG,Y] + self.DG(z_i)[:-nG,y].dot(dy_YEE(z_i)))) self.d2Y[Eps,Eps] = -np.tensordot(DGhat_YEEinv,HGhat_EE,1) self.d2y[Eps,Eps] = dict_fun(lambda z_i: d2y_EE(z_i) + np.tensordot(dy_YEE(z_i),self.d2Y[Eps,Eps],1)) #Now derivative with respect to sigma_E def temp2(z_i): DFi,df = DF(z_i)[n:],self.df(z_i) return -np.linalg.inv(DFi[:,y]+DFi[:,e].dot(df)+DFi[:,v].dot(Ivy)+DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy)) temp2 = dict_fun(temp2) def A2_i(z_i): #the pure term DFi = DF(z_i)[n:] df,hf = self.df(z_i),self.Hf(z_i) return np.tensordot(temp2(z_i),np.tensordot(DFi[:,e].dot(df),self.d2y[Eps,Eps](z_i),1) +np.tensordot(DFi[:,e],quadratic_dot(hf,self.dy[Eps](z_i),self.dy[Eps](z_i)),1) ,axes=1) A2_i = dict_fun(A2_i) B2_i = dict_fun(lambda z_i : temp2(z_i).dot(DF(z_i)[n:,Y] + DF(z_i)[n:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat) )) C2_i = dict_fun(lambda z_i : temp2(z_i).dot(DF(z_i)[n:,v].dot(Ivy).dot(self.dy[Y](z_i))) ) A2 = self.integrate(lambda z_i : np.tensordot(self.dY(z_i).dot(Izy),A2_i(z_i),1)) B2,C2 = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(B2_i(z_i))),self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(C2_i(z_i))) tempC2 = np.linalg.inv(np.eye(nY)-C2) d2y_sigmaE =lambda z_i: A2_i(z_i) + np.tensordot(C2_i(z_i).dot(tempC2),A2,1) dy_YsigmaE = lambda z_i: B2_i(z_i) + C2_i(z_i).dot(tempC2).dot(B2) HGhat_sigmaE = self.integrate(lambda z_i: np.tensordot(self.DG(z_i)[nG:,y],d2y_sigmaE(z_i),1)) DGhat_YsigmaEinv = np.linalg.inv(self.integrate(lambda z_i : self.DG(z_i)[nG:,Y] + self.DG(z_i)[nG:,y].dot(dy_YsigmaE(z_i)))) self.d2Y[sigma_E] = - np.tensordot(DGhat_YsigmaEinv,HGhat_sigmaE,1) self.d2y[sigma_E] = dict_fun(lambda z_i : d2y_sigmaE(z_i) + np.tensordot(dy_YsigmaE(z_i),self.d2Y[sigma_E],1))
def d2y_ZZ(z_i): DFi,df,Hf = DF(z_i)[n:],self.df(z_i),self.Hf(z_i) dy_Z = self.dy[Z](z_i) temp = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + self.dZ_Z[0]**2 * DFi[:,v].dot(Ivy)) return - np.tensordot(temp, self.HFhat[Z,Z](z_i) +np.tensordot(DFi[:,e],quadratic_dot(Hf,dy_Z,dy_Z),1),axes=1)
def Y2_int(x): z_i,zbar = x zhat = z_i-zbar return (quadratic_dot(self.d2Y[z,z](zbar),zhat,zhat) + 2* quadratic_dot(self.d2Y[z,Y](zbar),zhat,Y1hat)).flatten()
def d2Y_zZ(z_i): temp2 = HGhat_zZ(z_i) + quadratic_dot(HGhat_YZ,self.dY(z_i),np.eye(nZ)) return -np.einsum('ij...,j...->i...',np.linalg.inv(Temp),temp2)
def d2Y_zZ(z_i): temp2 = HGhat_zZ(z_i) + quadratic_dot(HGhat_YZ,self.dY(z_i),np.eye(nZ)) d2Y_zZ = np.empty((nY,nz,nZ)) for i in range(nZ): d2Y_zZ[:,:,i] = -np.einsum('ij...,j...->i...',np.linalg.inv(Temp[:,:,i]),temp2[:,:,i]) return d2Y_zZ
def DGhat_zY(z_i): DGi = self.DG(z_i)[nG:] return (DGhat_f(z_i)[:,:nz,nz:] + np.tensordot(DGi[:,y].dot(self.d2y[Y,S,Z](z_i)), quadratic_dot(self.d2Y[z,Z](z_i),np.eye(nz),IZY),1))
def d2y_ZZ(z_i): DFi,df,Hf,dy_Z = DF(z_i)[n:],self.df(z_i),self.Hf(z_i),self.dy[Z](z_i) A = DFi[:,v].dot(Ivy) B = DFi[:,y] + DFi[:,e].dot(df) C = self.HFhat[Z,Z](z_i) +np.einsum('ij...,j...->i...',DFi[:,e],quadratic_dot(Hf,dy_Z,dy_Z)) return quadratic_solve([D,D],A,B,C)
def compute_d2y_Eps(self): ''' Computes the 2nd derivatives of y with respect to the aggregate shock. ''' def HGhat(z_i,y1,y2): HG = self.HG(z_i)[:-nG,:] d = self.get_d(z_i) HGhat = np.zeros((nY,len(y1),len(y2))) for x1 in [y,z,Y,Z,Eps]: HGx1 = HG[:,x1,:] for x2 in [y,z,Y,Z,Eps]: HGhat += quadratic_dot(HGx1[:,:,x2],d[x1,y1],d[x2,y2]) return HGhat DF = self.DF def dSprime_Eps(z_i): return np.vstack((Izy.dot(self.dy[Eps](z_i)),self.dYGamma_Eps)) d2Yprime_EpsEps = self.integrate(lambda z_i : quadratic_dot(self.d2Y[z,z](z_i),Izy.dot(self.dy[Eps](z_i)),Izy.dot(self.dy[Eps](z_i))) +2*quadratic_dot(self.d2Y[z,Y](z_i),Izy.dot(self.dy[Eps](z_i)),self.dYGamma_Eps)) d2YprimeGZ_EpsEps1 = self.integrate(lambda z_i: quadratic_dot(self.d2Y[z,Z](z_i),Izy.dot(self.dy[Eps](z_i)),IZY.dot(self.dY_Eps))) d2YprimeGZ_EpsEps2 = self.integrate(lambda z_i: quadratic_dot(self.d2Y[z,Z](z_i),Izy.dot(self.dy[Eps](z_i)),IZY.dot(self.dYGamma_Eps))) def DFhat_EpsEps(z_i): dSprime_Eps_i,dZprime_Eps = dSprime_Eps(z_i),IZY.dot(self.dY_Eps) DFi = DF(z_i)[:-n] return self.HFhat[Eps,Eps](z_i) + np.tensordot(DFi[:,v].dot(Ivy), quadratic_dot(self.d2y[S,S](z_i),dSprime_Eps_i,dSprime_Eps_i) +2*quadratic_dot(self.d2y[S,Z](z_i),dSprime_Eps_i,dZprime_Eps) +quadratic_dot(self.d2y[Z,Z](z_i),dZprime_Eps,dZprime_Eps) +np.tensordot(self.dy[Y](z_i),d2Yprime_EpsEps,1) +2*np.tensordot(self.dy[Y,S,Z](z_i),d2YprimeGZ_EpsEps1,1) #from dy_GammaZ +2*np.tensordot(self.d2y[Y,S,Z](z_i),d2YprimeGZ_EpsEps2,1) #from dy_GammaGamma ,axes=1) def temp(z_i): DFi = DF(z_i)[:-n] return -np.linalg.inv(DFi[:,y]+DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy)) temp = dict_fun(temp) A_i = dict_fun(lambda z_i: np.tensordot(temp(z_i),DFhat_EpsEps(z_i),1)) B_i = dict_fun(lambda z_i: temp(z_i).dot(DF(z_i)[:-n,Y] + DF(z_i)[:-n,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY) )) C_i = dict_fun(lambda z_i: temp(z_i).dot(DF(z_i)[:-n,v].dot(Ivy).dot(self.dy[Y](z_i)))) A = self.integrate(lambda z_i : np.tensordot(self.dY(z_i).dot(Izy),A_i(z_i),1)) B,C = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(B_i(z_i))),self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(C_i(z_i))) tempC = np.linalg.inv(np.eye(nY)-C) d2y_EE =lambda z_i: A_i(z_i) + np.tensordot(C_i(z_i).dot(tempC),A,1) dy_YEE = lambda z_i: B_i(z_i) + C_i(z_i).dot(tempC).dot(B) HGhat_EE = self.integrate(lambda z_i: HGhat(z_i,Eps,Eps) + np.tensordot(self.DG(z_i)[:-nG,y],d2y_EE(z_i),1)) DGhat_YEEinv = np.linalg.inv(self.integrate(lambda z_i : self.DG(z_i)[:-nG,Y] + self.DG(z_i)[:-nG,y].dot(dy_YEE(z_i)))) self.d2Y[Eps,Eps] = -np.tensordot(DGhat_YEEinv,HGhat_EE,1) self.d2y[Eps,Eps] = dict_fun(lambda z_i: d2y_EE(z_i) + np.tensordot(dy_YEE(z_i),self.d2Y[Eps,Eps],1)) #Now derivative with respect to sigma_E def temp2(z_i): DFi,df = DF(z_i)[n:],self.df(z_i) return -np.linalg.inv(DFi[:,y]+DFi[:,e].dot(df)+DFi[:,v].dot(Ivy)+DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy)) temp2 = dict_fun(temp2) def A2_i(z_i): #the pure term DFi = DF(z_i)[n:] df,hf = self.df(z_i),self.Hf(z_i) return np.tensordot(temp2(z_i),np.tensordot(DFi[:,e].dot(df),self.d2y[Eps,Eps](z_i),1) +np.tensordot(DFi[:,e],quadratic_dot(hf,self.dy[Eps](z_i),self.dy[Eps](z_i)),1) ,axes=1) A2_i = dict_fun(A2_i) B2_i = dict_fun(lambda z_i : temp2(z_i).dot(DF(z_i)[n:,Y] + DF(z_i)[n:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY) )) C2_i = dict_fun(lambda z_i : temp2(z_i).dot(DF(z_i)[n:,v].dot(Ivy).dot(self.dy[Y](z_i))) ) A2 = self.integrate(lambda z_i : np.tensordot(self.dY(z_i).dot(Izy),A2_i(z_i),1)) B2,C2 = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(B2_i(z_i))),self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(C2_i(z_i))) tempC2 = np.linalg.inv(np.eye(nY)-C2) d2y_sigmaE =lambda z_i: A2_i(z_i) + np.tensordot(C2_i(z_i).dot(tempC2),A2,1) dy_YsigmaE = lambda z_i: B2_i(z_i) + C2_i(z_i).dot(tempC2).dot(B2) HGhat_sigmaE = self.integrate(lambda z_i: np.tensordot(self.DG(z_i)[nG:,y],d2y_sigmaE(z_i),1)) DGhat_YsigmaEinv = np.linalg.inv(self.integrate(lambda z_i : self.DG(z_i)[nG:,Y] + self.DG(z_i)[nG:,y].dot(dy_YsigmaE(z_i)))) self.d2Y[sigma_E] = - np.tensordot(DGhat_YsigmaEinv,HGhat_sigmaE,1) self.d2y[sigma_E] = dict_fun(lambda z_i : d2y_sigmaE(z_i) + np.tensordot(dy_YsigmaE(z_i),self.d2Y[sigma_E],1))
def iterate(self,Zbar,quadratic = True): ''' Iterates the distribution by randomly sampling ''' Zhat = self.dZhat_Z.dot(Zbar-self.ss.get_Y()[:nZ]) if rank == 0: r = np.random.randn() if not shock == None: r = shock r = min(3.,max(-3.,r)) E = r*sigma_E else: E = None E = comm.bcast(E) phat = Para.phat Gamma_dist = zip(self.Gamma,self.Gamma_ss) Y1hat = parallel_sum(lambda z : self.dY(z[1]).dot((z[0]-z[1])) ,Gamma_dist)/len(self.Gamma) def Y2_int(x): z_i,zbar = x zhat = z_i-zbar return (quadratic_dot(self.d2Y[z,z](zbar),zhat,zhat) + 2* quadratic_dot(self.d2Y[z,Y](zbar),zhat,Y1hat)).flatten() Y2hat = parallel_sum(Y2_int,Gamma_dist)/len(self.Gamma) def Y2_GZ_int(x): z_i,zbar = x zhat = z_i-zbar return quadratic_dot(self.d2Y[z,Z](zbar),zhat,np.eye(nZ)).reshape(nY,nZ) Y2hat_GZ = parallel_sum(Y2_GZ_int,Gamma_dist)/len(self.Gamma) def compute_ye(x): z_i,zbar = x extreme = Para.check_extreme(z_i) zhat = z_i-zbar r = np.random.randn(neps) for i in range(neps): r[i] = min(3.,max(-3.,r[i])) e = r*sigma Shat = np.hstack([zhat,Y1hat]) if not extreme: return np.hstack(( self.ss.get_y(zbar).flatten() + self.dy[eps](zbar).dot(e).flatten() + (self.dy[Eps](zbar).flatten())*E + self.dy[p](zbar).dot(phat).flatten() + self.dy[z](zbar).dot(zhat).flatten() + self.dy[Y](zbar).dot(Y1hat).flatten() + self.dy[Z](zbar).dot(Zhat).flatten() + 0.5*quadratic*(quadratic_dot(self.d2y[eps,eps](zbar),e,e).flatten() + self.d2y[sigma](zbar).dot(sigma**2).flatten() +quadratic_dot(self.d2y[S,S](zbar),Shat,Shat) + 2*quadratic_dot(self.d2y[S,eps](zbar),Shat,e) +self.dy[Y](zbar).dot(Y2hat) +2*quadratic_dot(self.d2y[Z,S](zbar),Zhat,Shat) +2*quadratic_dot(self.d2y[Z,eps](zbar),Zhat,e) +quadratic_dot(self.d2y[Z,Z](zbar),Zhat,Zhat) +2*np.einsum('ijk,jk,k',self.dy[Y,S,Z](zbar),Y2hat_GZ,Zhat) +2*np.einsum('ijk,jk,k',self.d2y[Y,S,Z](zbar),Y2hat_GZ,IZYhat.dot(Y1hat)) +self.d2y[Eps,Eps](zbar).flatten()*E**2 +self.d2y[sigma_E](zbar).flatten()*sigma_E**2 ).flatten() ,e)) else: return np.hstack(( self.ss.get_y(zbar).flatten() + self.dy[Eps](zbar).flatten()*E + self.dy[p](zbar).dot(phat).flatten() + self.dy[z](zbar).dot(zhat).flatten() + self.dy[Y](zbar).dot(Y1hat).flatten() + self.dy[Z](zbar).dot(Zhat).flatten() + 0.5*quadratic*(quadratic_dot(self.d2y[eps,eps](zbar),sigma,sigma).flatten() + self.d2y[sigma](zbar).dot(sigma**2).flatten() +quadratic_dot(self.d2y[S,S](zbar),Shat,Shat) +self.dy[Y](zbar).dot(Y2hat) +2*quadratic_dot(self.d2y[Z,S](zbar),Zhat,Shat) +quadratic_dot(self.d2y[Z,Z](zbar),Zhat,Zhat) +2*np.einsum('ijk,jk,k',self.dy[Y,S,Z](zbar),Y2hat_GZ,Zhat) +2*np.einsum('ijk,jk,k',self.d2y[Y,S,Z](zbar),Y2hat_GZ,IZYhat.dot(Y1hat)) +self.d2y[Eps,Eps](zbar).flatten()*E**2 +self.d2y[sigma_E](zbar).flatten()*sigma_E**2 ).flatten() ,0.*e)) if rank == 0: ye = np.vstack(parallel_map(compute_ye,Gamma_dist)) y,epsilon = ye[:,:-neps],ye[:,-neps] Gamma = y.dot(Izy.T) Ynew = (self.ss.get_Y() + Y1hat + self.dY_Eps.flatten()*E + self.dY_p.dot(phat).flatten() + self.dY_Z.dot(Zhat) + 0.5*quadratic*(self.d2Y[sigma].dot(sigma**2) + Y2hat + 2*Y2hat_GZ.dot(Zhat)).flatten() + 0.5*(self.d2Y[Eps,Eps].flatten()*E**2 + self.d2Y[sigma_E].flatten()*sigma_E**2) + 0.5*quadratic_dot(self.d2Y[Z,Z],Zhat,Zhat)) Znew = Ynew[:nZ] return Gamma,Znew,Ynew,epsilon,y else: parallel_map(compute_ye,Gamma_dist) return None
def Y2_GZ_int(x): z_i,zbar = x zhat = z_i-zbar return quadratic_dot(self.d2Y[z,Z](zbar),zhat,np.eye(nZ)).reshape(nY,nZ)