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 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 quadratic(self): ''' Computes the quadratic approximation ''' self.d2Y,self.d2y = {},{} self.dYGamma_Eps = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(self.dy[Eps](z_i))) self.get_d = dict_fun(self.get_df) self.compute_HFhat() self.compute_d2y_ZZ() self.compute_d2y() #Now d2Y DGhat_f = dict_fun(self.compute_DGhat) def DGhat_zY(z_i): DGi = self.DG(z_i)[nG:] temp = np.einsum('ij...,j...->i...',DGi[:,y],self.d2y[Y,S,Z](z_i)) temp = np.einsum('ijk,jlk->ilk',temp,self.d2Y[z,Z](z_i)) #don't sum over Z axis return DGhat_f(z_i)[:,:nz,nz:] + np.einsum('ilk,km',temp,IZYhat) self.DGhat = {} self.DGhat[z,z] = lambda z_i : DGhat_f(z_i)[:,:nz,:nz] self.DGhat[z,Y] = dict_fun(DGhat_zY) self.DGhat[Y,z] = lambda z_i : self.DGhat[z,Y](z_i).transpose(0,2,1) self.DGhat[Y,Y] = self.integrate(lambda z_i : DGhat_f(z_i)[:,nz:,nz:]) self.compute_d2Y() self.compute_dsigma() self.compute_d2y_Eps()
def compute_dy(self): ''' Computes dy w.r.t z_i, eps, Y ''' self.dy = {} def dy_z(z_i): DF = self.DF(z_i) df = self.df(z_i) DFi = DF[n:] # pick out the relevant equations from F. Forexample to compute dy_{z_i} we need to drop the first equation return np.linalg.solve(DFi[:,y] + DFi[:,e].dot(df)+DFi[:,v].dot(Ivy), -DFi[:,z]) self.dy[z] = dict_fun(dy_z) def dy_eps(z_i): DF = self.DF(z_i) DFi = DF[:-n,:] return np.linalg.solve(DFi[:,y] + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy), -DFi[:,eps]) self.dy[eps] = dict_fun(dy_eps) self.compute_dy_Z() def dy_Y(z_i): DF = self.DF(z_i) df = self.df(z_i) DFi = DF[n:,:] return np.linalg.solve(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy), -DFi[:,Y] - DFi[:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat)) self.dy[Y] = dict_fun(dy_Y)
def compute_d2Y(self): ''' Computes components of d2Y ''' DGhat = self.DGhat #First z_i,z_i self.d2Y[z,z] = dict_fun(lambda z_i: np.tensordot(self.DGYinv, - DGhat[z,z](z_i),1)) self.d2Y[Y,z] = dict_fun(lambda z_i: np.tensordot(self.DGYinv, - DGhat[Y,z](z_i) -DGhat[Y,Y].dot(self.dY(z_i))/2. ,1) ) self.d2Y[z,Y] = lambda z_i : self.d2Y[Y,z](z_i).transpose(0,2,1)
def compute_d2y(self): ''' 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 #Now compute d2y 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) self.d2y[S,S] = dict_fun(d2y_SS) def d2y_YSZ(z_i): DFi,df = self.DF(z_i)[n:],self.df(z_i) temp = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy)) return - np.einsum('ij...,j...->i...',temp.dot(DFi[:,v]).dot(Ivy), self.dy[Y,S,Z](z_i)) self.d2y[Y,S,Z] = dict_fun(d2y_YSZ) 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) self.d2y[S,eps] = dict_fun(d2y_Seps) self.d2y[eps,S] = dict_fun(lambda z_i : self.d2y[S,eps](z_i).transpose(0,2,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) self.d2y[eps,eps] = dict_fun(d2y_epseps)
def compute_d2y(self): ''' 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 #Now compute d2y 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) self.d2y[S,S] = dict_fun(d2y_SS) def d2y_YSZ(z_i): DFi,df = self.DF(z_i)[n:],self.df(z_i) temp = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy)) return - np.tensordot(temp, self.dy[Y,S,Z](z_i),1) self.d2y[Y,S,Z] = dict_fun(d2y_YSZ) 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],IZY.dot(d[Y,S]),dz_eps),1) , axes=1) self.d2y[S,eps] = dict_fun(d2y_Seps) self.d2y[eps,S] = dict_fun(lambda z_i : self.d2y[S,eps](z_i).transpose(0,2,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) self.d2y[eps,eps] = dict_fun(d2y_epseps)
def compute_dy_Z(self): ''' Computes linearization w/ respecto aggregate state. ''' self.dZ_Z = np.eye(nZ) #right now assume nZ =1 def dy_Z(z_i): DFi = self.DF(z_i)[n:,:] df = self.df(z_i) DFhat_Zinv = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy)*self.dZ_Z[0]) return DFhat_Zinv.dot(-DFi[:,Z]),DFhat_Zinv.dot(-DFi[:,Y]) DG = lambda z_i : self.DG(z_i)[nG:,:] def dY_Z(): A,B = lambda z_i : dy_Z(z_i)[0], lambda z_i : dy_Z(z_i)[1] temp1 = self.integrate( lambda z_i: DG(z_i)[:,y].dot(A(z_i)) + DG(z_i)[:,Z] ) temp2 = self.integrate( lambda z_i: DG(z_i)[:,y].dot(B(z_i)) + DG(z_i)[:,Y] ) return np.linalg.solve(temp2,-temp1) def residual(dZ_Z): self.dZ_Z = dZ_Z return (dY_Z()[:nZ]-dZ_Z).flatten() self.dZ_Z = root(residual,0.9*np.ones(1)).x.reshape(nZ,nZ) self.dY_Z = dY_Z() def compute_dy_Z(z_i): A,B = dy_Z(z_i) return A+B.dot(self.dY_Z) self.dy[Z] = dict_fun(compute_dy_Z)
def quadratic(self): ''' Computes the quadratic approximation ''' self.get_d = dict_fun(self.get_df) self.compute_HFhat() self.compute_d2y() #Now d2Y DGhat_f = dict_fun(self.compute_DGhat) self.DGhat = {} self.DGhat[z,z] = lambda z_i : DGhat_f(z_i)[:,:nz,:nz] self.DGhat[z,Y] = lambda z_i : DGhat_f(z_i)[:,:nz,nz:] self.DGhat[Y,z] = lambda z_i : DGhat_f(z_i)[:,nz:,:nz] self.DGhat[Y,Y] = self.integrate(lambda z_i : DGhat_f(z_i)[:,nz:,nz:]) self.compute_d2Y() self.compute_dsigma()
def compute_d2Y(self,DGhat): ''' Computes components of d2Y ''' d2Y = {} DGYinv= np.linalg.inv(self.DGY) #First z_i,z_i d2Y[z,z] = dict_fun(self.interpolate(parallel_map(lambda z_i: np.tensordot(DGYinv, - DGhat[z,z](z_i),1),self.zgrid))) d2Y[Y,z] = dict_fun(self.interpolate(parallel_map(lambda z_i: np.tensordot(DGYinv, - DGhat[Y,z](z_i) -DGhat[Y,Y].dot(self.dY(z_i))/2,1),self.zgrid ) )) d2Y[z,Y] = dict_fun(d2Y[Y,z].f.transpose(0,2,1)) self.d2Y = d2Y
def compute_dy_Z(self): ''' Computes linearization w/ respecto aggregate state. ''' global dZ_Z0 self.dZ_Z = np.eye(nZ) #right now assume nZ =1 def dy_Z(z_i): DFi = self.DF(z_i)[n:,:] df = self.df(z_i) DFhat_Zinv = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy)*self.dZ_Z[0]) return DFhat_Zinv.dot(-DFi[:,Z]),DFhat_Zinv.dot(-DFi[:,Y]) DG = lambda z_i : self.DG(z_i)[nG:,:] def dY_Z(): A,B = lambda z_i : dy_Z(z_i)[0], lambda z_i : dy_Z(z_i)[1] temp1 = self.integrate( lambda z_i: DG(z_i)[:,y].dot(A(z_i)) + DG(z_i)[:,Z] ) temp2 = self.integrate( lambda z_i: DG(z_i)[:,y].dot(B(z_i)) + DG(z_i)[:,Y] ) return np.linalg.solve(temp2,-temp1) def residual(dZ_Z): self.dZ_Z = np.array([dZ_Z]) return (dY_Z()[:nZ]-dZ_Z).flatten() res = root(residual,dZ_Z0) if not res.success or res.x >= 1.: res = root(residual,np.array([1.])) if not res.success or res.x >= 1.: state = np.random.get_state() ni = 0 while True: if rank == 0: dY_Z0 = np.random.randn(nY*nZ) else: dY_Z0 = None dY_Z0 = comm.bcast(dY_Z0) res = root(lambda dY_Z:self.dY_Z_residual(dY_Z.reshape(nY,nZ)).flatten() ,dY_Z0) if res.success and res.x[0] < 1.: break else: ni += 1 if ni>10: raise "Could not find stable dZ_Z" np.random.set_state(state) self.dZ_Z = res.x.reshape(nY,nZ)[:nZ] dZ_Z0 = self.dZ_Z.flatten() else: self.dZ_Z = res.x.reshape(nZ,nZ) dZ_Z0 = res.x.reshape(nZ) #self.dZ_Z = root(residual,0.9*np.ones(1)).x.reshape(nZ,nZ) self.dY_Z = dY_Z() def compute_dy_Z(z_i): A,B = dy_Z(z_i) return A+B.dot(self.dY_Z) self.dy[Z] = dict_fun(compute_dy_Z)
def compute_dy(self): ''' Computes dy w.r.t z_i, eps, Y ''' self.dy = {} def dy_z(z_i): DF = self.DF(z_i) df = self.df(z_i) DFi = DF[n:] # pick out the relevant equations from F. Forexample to compute dy_{z_i} we need to drop the first equation return np.linalg.solve(DFi[:,y] + DFi[:,e].dot(df)+DFi[:,v].dot(Ivy), -DFi[:,z]) self.dy[z] = dict_fun(dy_z) def dy_eps(z_i): DF = self.DF(z_i) DFi = DF[:-n,:] return np.linalg.solve(DFi[:,y] + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy), -DFi[:,eps]) self.dy[eps] = dict_fun(dy_eps) def dy_Eps(z_i): DF = self.DF(z_i) DFi = DF[:-n,:] return np.linalg.solve(DFi[:,y] + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy), -DFi[:,Eps]) self.dy[Eps] = dict_fun(dy_Eps) self.compute_dy_Z() def dy_Y(z_i): DF = self.DF(z_i) df = self.df(z_i) DFi = DF[n:,:] return np.linalg.solve(DFi[:,y] + DFi[:,e].dot(df) + DFi[:,v].dot(Ivy), -DFi[:,Y] - DFi[:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY)) self.dy[Y] = dict_fun(dy_Y) def dy_YEps(z_i): DF = self.DF(z_i) DFi = DF[:-n,:] return np.linalg.solve(DFi[:,y] + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy), -DFi[:,Y]) self.dy[Y,Eps] = dict_fun(dy_YEps)
def __init__(self,Gamma,Gamma_weights=None,fit = True): ''' Approximate the equilibrium policies given z_i ''' if Gamma_weights ==None: Gamma_weights = np.ones(len(Gamma))/len(Gamma) self.Gamma = Gamma self.Gamma_weights = Gamma_weights self.approximate_Gamma() self.ss = steadystate.steadystate(self.dist) #precompute Jacobians and Hessians self.get_w = dict_fun(self.get_wf) self.DF = dict_fun(lambda z_i:utilities.ad_Jacobian(F,self.get_w(z_i))) self.HF = dict_fun(lambda z_i:utilities.ad_Hessian(F,self.get_w(z_i))) self.DG = dict_fun(lambda z_i:utilities.ad_Jacobian(G,self.get_w(z_i))) self.HG = dict_fun(lambda z_i:utilities.ad_Hessian(G,self.get_w(z_i))) self.df = dict_fun(lambda z_i:utilities.ad_Jacobian(f,self.get_w(z_i)[y])) self.Hf = dict_fun(lambda z_i:utilities.ad_Hessian(f,self.get_w(z_i)[y])) if fit: #linearize self.linearize() self.quadratic() self.join_function()
def __init__(self,Gamma,fit = True): ''' Approximate the equilibrium policies given z_i ''' self.Gamma = Gamma self.approximate_Gamma() self.ss = steadystate.steadystate(self.dist) #precompute Jacobians and Hessians self.get_w = dict_fun(self.get_wf) self.DF = dict_fun(lambda z_i:utilities.ad_Jacobian(F,self.get_w(z_i))) self.HF = dict_fun(lambda z_i:utilities.ad_Hessian(F,self.get_w(z_i))) self.DG = dict_fun(lambda z_i:utilities.ad_Jacobian(G,self.get_w(z_i))) self.HG = dict_fun(lambda z_i:utilities.ad_Hessian(G,self.get_w(z_i))) self.df = dict_fun(lambda z_i:utilities.ad_Jacobian(f,self.get_w(z_i)[y])) self.Hf = dict_fun(lambda z_i:utilities.ad_Hessian(f,self.get_w(z_i)[y])) #linearize if fit: self.linearize() self.quadratic() self.join_function()
def compute_d2y(self): ''' Computes second derivative of y ''' self.d2y = {} #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 #Now compute d2y 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) , axes=1) self.d2y[S,S] = dict_fun(d2y_SS) 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) , axes=1) self.d2y[S,eps] = dict_fun(d2y_Seps) self.d2y[eps,S] = lambda z_i : self.d2y[S,eps](z_i).transpose(0,2,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) self.d2y[eps,eps] = dict_fun(d2y_epseps)
def quadratic(self): ''' Computes the quadratic approximation ''' self.d2y = {} temp = parallel_dict_map(self.compute_d2y,self.zgrid) for x1 in [S,eps]: for x2 in [S,eps]: self.d2y[x1,x2] = dict_fun(self.interpolate(temp[x1,x2])) #Now d2Y DGhat_f = self.interpolate(parallel_map(self.compute_DGhat,self.zgrid)) DGhat = {} DGhat[z,z] = dict_fun(DGhat_f[:,:nz,:nz]) DGhat[z,Y] = dict_fun(DGhat_f[:,:nz,nz:]) DGhat[Y,z] = dict_fun(DGhat_f[:,nz:,:nz]) DGhat[Y,Y] = self.integrate(DGhat_f[:,nz:,nz:]) self.compute_d2Y(DGhat) self.compute_dsigma()
def __init__(self,Gamma): ''' Approximate the equilibrium policies given z_i ''' self.Gamma = Gamma self.ss = steadystate.steadystate(Gamma.T) #x = [] #for i in range(nz): # x.append(np.linspace(min(Gamma[:,i])-0.05,0.05+max(Gamma[:,i]),20)) #self.zgrid = Spline.makeGrid(x) #Mu = np.zeros(nz) #Sigma = np.zeros((nz,nz)) #for i in range(nz): # xmin,xmax = min(Gamma[:,i])-0.001,max(Gamma[:,i])+0.001 # Mu[i] = (xmin+xmax)/2 # Sigma[i,i] = (xmax-xmin)/2 self.interpolate = utilities.interpolator_factory(nz,3,Gamma) self.zgrid = self.interpolate.X #precompute Jacobians and Hessians self.DF = dict_fun(lambda z_i:utilities.ad_Jacobian(F,self.get_w(z_i))) self.HF = dict_fun(lambda z_i:utilities.ad_Hessian(F,self.get_w(z_i))) self.DG = dict_fun(lambda z_i:utilities.ad_Jacobian(G,self.get_w(z_i))) self.HG = dict_fun(lambda z_i:utilities.ad_Hessian(G,self.get_w(z_i))) self.df = dict_fun(lambda z_i:utilities.ad_Jacobian(f,self.get_w(z_i)[y])) self.Hf = dict_fun(lambda z_i:utilities.ad_Hessian(f,self.get_w(z_i)[y])) #linearize self.linearize() self.quadratic()
def quadratic(self): ''' Computes the quadratic approximation ''' self.d2Y,self.d2y = {},{} #self.dYGamma_Eps = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(self.dy[Eps](z_i))) self.get_d = dict_fun(self.get_df) self.compute_HFhat() self.compute_d2y_ZZ() self.compute_d2y() #Now d2Y DGhat_f = dict_fun(self.compute_DGhat) 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)) self.DGhat = {} self.DGhat[z,z] = lambda z_i : DGhat_f(z_i)[:,:nz,:nz] self.DGhat[z,Y] = dict_fun(DGhat_zY) self.DGhat[Y,z] = lambda z_i : self.DGhat[z,Y](z_i).transpose(0,2,1) self.DGhat[Y,Y] = self.integrate(lambda z_i : DGhat_f(z_i)[:,nz:,nz:]) self.compute_d2Y() self.compute_dsigma()
def linearize(self): ''' Computes the linearization ''' self.dy = {} temp = parallel_dict_map(self.compute_dy,self.zgrid) for x in [z,eps,Y]: self.dy[x] = dict_fun(self.interpolate(temp[x])) DG = self.DG def DGY_int(z_i): DGi = DG(z_i) return DGi[:,Y]+DGi[:,y].dot(self.dy[Y](z_i)) self.DGY = self.integrate(DGY_int) def dYf(z_i): DGi = DG(z_i) return np.linalg.solve(self.DGY, -DGi[:,z]-DGi[:,y].dot(self.dy[z](z_i))) self.dY = dict_fun(self.interpolate( parallel_map(dYf,self.zgrid)))
def quadratic(self): ''' Computes the quadratic approximation ''' self.d2Y,self.d2y = {},{} self.dYGamma_Eps = self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(self.dy[Eps](z_i))) self.get_d = dict_fun(self.get_df) self.compute_HFhat() self.compute_d2y_ZZ() self.compute_d2y() #Now d2Y DGhat_f = dict_fun(self.compute_DGhat) 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)) self.DGhat = {} self.DGhat[z,z] = lambda z_i : DGhat_f(z_i)[:,:nz,:nz] self.DGhat[z,Y] = dict_fun(DGhat_zY) self.DGhat[Y,z] = lambda z_i : self.DGhat[z,Y](z_i).transpose(0,2,1) self.DGhat[Y,Y] = self.integrate(lambda z_i : DGhat_f(z_i)[:,nz:,nz:]) self.compute_d2Y() self.compute_dsigma() self.compute_d2y_Eps()
def compute_dy_Z(self): ''' Computes linearization w/ respecto aggregate state. ''' global dY_Z0 def f(dY_Z): return self.dY_Z_residual(dY_Z.reshape(nY,nZ)).flatten() while True: if rank == 0: if dY_Z0 == None: dY_Z0 =np.random.randn(nY*nZ) else: dY_Z0 = np.empty(nY*nZ) comm.Bcast([dY_Z0,MPI.DOUBLE]) try: res = root(f,dY_Z0) if res.success: lamb = np.linalg.eigvals(res.x.reshape(nY,nZ)[:nZ]) if np.max(np.abs(lamb)) <1 and all(np.isreal(lamb)) : break dY_Z0 = None except: dY_Z0 = None dY_Z = res.x.reshape(nY,nZ) dY_Z0 = res.x #Now change the basis so that dZ_Z is diagonal global IZYhat D,V = np.linalg.eig(dY_Z[:nZ]) self.dY_Z = dY_Z.dot(V) self.dZ_Z = np.diagflat(D) self.dZhat_Z = np.linalg.inv(V) IZYhat = np.linalg.solve(V,IZY) def dy_Z(z_i): DFi = self.DF(z_i)[n:,:] df = self.df(z_i) A = np.linalg.solve(DFi[:,y] + DFi[:,e].dot(df),DFi[:,v].dot(Ivy)) B = np.linalg.inv(self.dZ_Z) C = -np.linalg.solve(DFi[:,y] + DFi[:,e].dot(df),DFi[:,Y].dot(self.dY_Z)+DFi[:,Z].dot(V)).dot(B) return solve_sylvester(A,B,C) self.dy[Z] = dict_fun(dy_Z)
def linearize_aggregate(self): ''' Linearize with respect to aggregate shock. ''' dy = {} def Fhat_y(z_i): DFi = self.DF(z_i)[:-n,:] return DFi[:,y] + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy) Fhat_inv = dict_fun(lambda z_i: -np.linalg.inv(Fhat_y(z_i))) def dy_dYprime(z_i): DFi = self.DF(z_i)[:-n,:] return Fhat_inv(z_i).dot(DFi[:,v]).dot(Ivy).dot(self.dy[Y](z_i)) dy_dYprime = dict_fun(dy_dYprime) temp = np.linalg.inv( np.eye(nY) - self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(dy_dYprime(z_i))) ) self.temp_matrix_Eps = np.eye(nY) - self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(dy_dYprime(z_i))) dYprime = {} dYprime[Eps] = temp.dot( self.integrate(lambda z_i : self.dY(z_i).dot(Izy).dot(Fhat_inv(z_i)).dot(self.DF(z_i)[:-n,Eps])) ) dYprime[Y] = temp.dot( self.integrate(lambda z_i : self.dY(z_i).dot(Izy).dot(Fhat_inv(z_i)).dot(self.DF(z_i)[:-n,Y] + self.DF(z_i)[:-n,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY))) ) dy[Eps] = dict_fun( lambda z_i : Fhat_inv(z_i).dot(self.DF(z_i)[:-n,Eps]) + dy_dYprime(z_i).dot(dYprime[Eps]) ) dy[Y] = dict_fun( lambda z_i : Fhat_inv(z_i).dot(self.DF(z_i)[:-n,Y] + self.DF(z_i)[:-n,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY)) + dy_dYprime(z_i).dot(dYprime[Y]) ) #Now do derivatives w.r.t G DGi = dict_fun(lambda z_i : self.DG(z_i)[:-nG,:]) DGhat_Y = self.integrate( lambda z_i : DGi(z_i)[:,Y] + DGi(z_i)[:,y].dot(dy[Y](z_i)) ) self.dY_Eps = -np.linalg.solve(DGhat_Y,self.integrate( lambda z_i : DGi(z_i)[:,Eps] + DGi(z_i)[:,y].dot(dy[Eps](z_i)) ) ) self.dy[Eps] = dict_fun( lambda z_i : dy[Eps](z_i) + dy[Y](z_i).dot(self.dY_Eps) )
def linearize_aggregate(self): ''' Linearize with respect to aggregate shock. ''' dy = {} def Fhat_y(z_i): DFi = self.DF(z_i)[:-n,:] return DFi[:,y] + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy) Fhat_inv = dict_fun(lambda z_i: -np.linalg.inv(Fhat_y(z_i))) def dy_dYprime(z_i): DFi = self.DF(z_i)[:-n,:] return Fhat_inv(z_i).dot(DFi[:,v]).dot(Ivy).dot(self.dy[Y](z_i)) dy_dYprime = dict_fun(dy_dYprime) temp = np.linalg.inv( np.eye(nY) - self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(dy_dYprime(z_i))) ) self.temp_matrix_Eps = np.eye(nY) - self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(dy_dYprime(z_i))) dYprime = {} dYprime[Eps] = temp.dot( self.integrate(lambda z_i : self.dY(z_i).dot(Izy).dot(Fhat_inv(z_i)).dot(self.DF(z_i)[:-n,Eps])) ) dYprime[Y] = temp.dot( self.integrate(lambda z_i : self.dY(z_i).dot(Izy).dot(Fhat_inv(z_i)).dot(self.DF(z_i)[:-n,Y] + self.DF(z_i)[:-n,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat))) ) dy[Eps] = dict_fun( lambda z_i : Fhat_inv(z_i).dot(self.DF(z_i)[:-n,Eps]) + dy_dYprime(z_i).dot(dYprime[Eps]) ) dy[Y] = dict_fun( lambda z_i : Fhat_inv(z_i).dot(self.DF(z_i)[:-n,Y] + self.DF(z_i)[:-n,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat)) + dy_dYprime(z_i).dot(dYprime[Y]) ) #Now do derivatives w.r.t G DGi = dict_fun(lambda z_i : self.DG(z_i)[:-nG,:]) DGhat_Y = self.integrate( lambda z_i : DGi(z_i)[:,Y] + DGi(z_i)[:,y].dot(dy[Y](z_i)) ) self.dY_Eps = -np.linalg.solve(DGhat_Y,self.integrate( lambda z_i : DGi(z_i)[:,Eps] + DGi(z_i)[:,y].dot(dy[Eps](z_i)) ) ) self.dy[Eps] = dict_fun( lambda z_i : dy[Eps](z_i) + dy[Y](z_i).dot(self.dY_Eps) )
def linearize_parameter(self): ''' Linearize with respect to aggregate shock. ''' dy = {} def Fhat_p(z_i): DFi = self.DF(z_i)[n:,:] df = self.df(z_i) return DFi[:,y]+ DFi[:,e].dot(df) + DFi[:,v].dot(Ivy) + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy) Fhat_inv = dict_fun(lambda z_i: np.linalg.inv(Fhat_p(z_i))) def dy_dYprime(z_i): DFi = self.DF(z_i)[n:,:] return Fhat_inv(z_i).dot(DFi[:,v]).dot(Ivy).dot(self.dy[Y](z_i)) dy_dYprime = dict_fun(dy_dYprime) temp = -np.linalg.inv( np.eye(nY) + self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(dy_dYprime(z_i))) ) dYprime = {} dYprime[p] = temp.dot( self.integrate(lambda z_i : self.dY(z_i).dot(Izy).dot(Fhat_inv(z_i)).dot(self.DF(z_i)[n:,p])) ) dYprime[Y] = temp.dot( self.integrate(lambda z_i : self.dY(z_i).dot(Izy).dot(Fhat_inv(z_i)).dot(self.DF(z_i)[n:,Y])) ) dy[p] = dict_fun( lambda z_i : -Fhat_inv(z_i).dot(self.DF(z_i)[n:,p]) - dy_dYprime(z_i).dot(dYprime[p]) ) dy[Y] = dict_fun( lambda z_i : -Fhat_inv(z_i).dot(self.DF(z_i)[n:,Y]) - dy_dYprime(z_i).dot(dYprime[Y]) ) #Now do derivatives w.r.t G DGi = dict_fun(lambda z_i : self.DG(z_i)[nG:,:]) DGhatinv = np.linalg.inv(self.integrate( lambda z_i : DGi(z_i)[:,Y] + DGi(z_i)[:,y].dot(dy[Y](z_i)) )) self.dY_p = -DGhatinv.dot( self.integrate( lambda z_i : DGi(z_i)[:,p] + DGi(z_i)[:,y].dot(dy[p](z_i)) ) ) self.dy[p] = dict_fun( lambda z_i : dy[p](z_i) + dy[Y](z_i).dot(self.dY_p) )
def linearize_parameter(self): ''' Linearize with respect to aggregate shock. ''' dy = {} def Fhat_p(z_i): DFi = self.DF(z_i)[n:,:] df = self.df(z_i) return DFi[:,y]+ DFi[:,e].dot(df) + DFi[:,v].dot(Ivy) + DFi[:,v].dot(Ivy).dot(self.dy[z](z_i)).dot(Izy) Fhat_inv = dict_fun(lambda z_i: np.linalg.inv(Fhat_p(z_i))) def dy_dYprime(z_i): DFi = self.DF(z_i)[n:,:] return Fhat_inv(z_i).dot(DFi[:,v]).dot(Ivy).dot(self.dy[Y](z_i)) dy_dYprime = dict_fun(dy_dYprime) temp = -np.linalg.inv( np.eye(nY) + self.integrate(lambda z_i: self.dY(z_i).dot(Izy).dot(dy_dYprime(z_i))) ) dYprime = {} dYprime[p] = temp.dot( self.integrate(lambda z_i : self.dY(z_i).dot(Izy).dot(Fhat_inv(z_i)).dot(self.DF(z_i)[n:,p])) ) dYprime[Y] = temp.dot( self.integrate(lambda z_i : self.dY(z_i).dot(Izy).dot(Fhat_inv(z_i)).dot( self.DF(z_i)[n:,Y] + self.DF(z_i)[n:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat)) ) ) dy[p] = dict_fun( lambda z_i : -Fhat_inv(z_i).dot(self.DF(z_i)[n:,p]) - dy_dYprime(z_i).dot(dYprime[p]) ) dy[Y] = dict_fun( lambda z_i : -Fhat_inv(z_i).dot(self.DF(z_i)[n:,Y] + self.DF(z_i)[n:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat)) - dy_dYprime(z_i).dot(dYprime[Y]) ) #Now do derivatives w.r.t G DGi = dict_fun(lambda z_i : self.DG(z_i)[nG:,:]) DGhatinv = np.linalg.inv(self.integrate( lambda z_i : DGi(z_i)[:,Y] + DGi(z_i)[:,y].dot(dy[Y](z_i)) )) self.dY_p = -DGhatinv.dot( self.integrate( lambda z_i : DGi(z_i)[:,p] + DGi(z_i)[:,y].dot(dy[p](z_i)) ) ) self.dy[p] = dict_fun( lambda z_i : dy[p](z_i) + dy[Y](z_i).dot(self.dY_p) )
def linearize(self): ''' Computes the linearization ''' self.compute_dy() DG = self.DG def DGY_int(z_i): DGi = DG(z_i) return DGi[:,Y]+DGi[:,y].dot(self.dy[Y](z_i)) self.DGYinv = np.linalg.inv(self.integrate(DGY_int)) def dYf(z_i): DGi = DG(z_i) return self.DGYinv.dot(-DGi[:,z]-DGi[:,y].dot(self.dy[z](z_i))) self.dY = dict_fun(dYf)
def linearize(self): ''' Computes the linearization ''' self.compute_dy() DG = lambda z_i : self.DG(z_i)[nG:,:] #account for measurability constraints def DGY_int(z_i): DGi = DG(z_i) return DGi[:,Y]+DGi[:,y].dot(self.dy[Y](z_i)) self.DGYinv = np.linalg.inv(self.integrate(DGY_int)) def dYf(z_i): DGi = DG(z_i) return self.DGYinv.dot(-DGi[:,z]-DGi[:,y].dot(self.dy[z](z_i))) self.dY = dict_fun(dYf) self.linearize_aggregate() self.linearize_parameter()
def compute_HFhat(self): ''' Constructs the HFhat functions ''' self.HFhat = {} shock_hashes = [eps.__hash__(),Eps.__hash__()] for x1 in [S,eps,Z,Eps]: for x2 in [S,eps,Z,Eps]: #Construct a function for each pair x1,x2 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 self.HFhat[x1,x2] = dict_fun(HFhat_temp)
def compute_HFhat(self): ''' Constructs the HFhat functions ''' self.HFhat = {} shock_hashes = [eps.__hash__(),Eps.__hash__()] for x1 in [S,eps,Z,Eps]: for x2 in [S,eps,Z,Eps]: #Construct a function for each pair x1,x2 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 self.HFhat[x1,x2] = dict_fun(HFhat_temp)
def __init__(self,Gamma): ''' Approximate the equilibrium policies given z_i ''' self.Gamma = Gamma self.ss = steadystate.steadystate(Gamma.T) #precompute Jacobians and Hessians self.get_w = dict_fun(self.get_wf) self.DF = dict_fun(lambda z_i:utilities.ad_Jacobian(F,self.get_w(z_i))) self.HF = dict_fun(lambda z_i:utilities.ad_Hessian(F,self.get_w(z_i))) self.DG = dict_fun(lambda z_i:utilities.ad_Jacobian(G,self.get_w(z_i))) self.HG = dict_fun(lambda z_i:utilities.ad_Hessian(G,self.get_w(z_i))) self.df = dict_fun(lambda z_i:utilities.ad_Jacobian(f,self.get_w(z_i)[y])) self.Hf = dict_fun(lambda z_i:utilities.ad_Hessian(f,self.get_w(z_i)[y])) #linearize self.linearize() self.quadratic()
def compute_d2y_ZZ(self): ''' Copute the second derivative of y with respect to Z ''' DF = self.DF def dy_YZZ(z_i): DFi,df = DF(z_i)[n:],self.df(z_i) temp = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + self.dZ_Z[0]**2 * DFi[:,v].dot(Ivy)) return - temp.dot( DFi[:,Y] + DFi[:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY) ) dy_YZZ = dict_fun(dy_YZZ) 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) d2y_ZZ = dict_fun(d2y_ZZ) 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]: HGx1 = HG[:,x1,:] for x2 in [y,z,Y,Z]: HGhat += quadratic_dot(HGx1[:,:,x2],d[x1,y1],d[x2,y2]) return HGhat HGhat_ZZ = dict_fun(lambda z_i : HGhat(z_i,Z,Z)) temp1 = np.linalg.inv(self.integrate(lambda z_i : self.DG(z_i)[nG:,y].dot(dy_YZZ(z_i)) + self.DG(z_i)[nG:,Y])) temp2 = self.integrate(lambda z_i : np.tensordot(self.DG(z_i)[nG:,y],d2y_ZZ(z_i),1) + HGhat_ZZ(z_i)) self.d2Y[Z,Z] = -np.tensordot(temp1,temp2,axes=1) self.d2y[Z,Z] = dict_fun(lambda z_i: d2y_ZZ(z_i) + np.tensordot(dy_YZZ(z_i),self.d2Y[Z,Z],axes=1) ) #d2y_ZS 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) d2y_SZ = dict_fun(d2y_SZ) def dy_YSZ(z_i): DFi,df = DF(z_i)[n:],self.df(z_i) temp = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + self.dZ_Z[0]*DFi[:,v].dot(Ivy)) return - temp.dot(DFi[:,Y] + DFi[:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY) ) dy_YSZ = dict_fun(dy_YSZ) HGhat_SZ = dict_fun(lambda z_i : HGhat(z_i,S,Z)) HGhat_YZ = self.integrate(lambda z_i : (HGhat_SZ(z_i) + np.tensordot(self.DG(z_i)[nG:,y],d2y_SZ(z_i),1))[:,nz:,:]) HGhat_zZ = lambda z_i : (HGhat_SZ(z_i) + np.tensordot(self.DG(z_i)[nG:,y],d2y_SZ(z_i),1))[:,:nz,:] temp1 = np.linalg.inv(self.integrate(lambda z_i : self.DG(z_i)[nG:,y].dot(dy_YSZ(z_i)) + self.DG(z_i)[nG:,Y])) temp2 = self.integrate(lambda z_i : np.tensordot(self.DG(z_i)[nG:,y],d2y_SZ(z_i),1) + HGhat_SZ(z_i)) 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) self.d2Y[z,Z] = dict_fun(d2Y_zZ) self.d2Y[Z,z] = lambda z_i : self.d2Y[z,Z](z_i).transpose(0,2,1) self.d2y[S,Z] = d2y_SZ self.dy[Y,S,Z] = dy_YSZ self.d2y[Z,S] = lambda z_i : d2y_SZ(z_i).transpose(0,2,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) self.d2y[Z,eps] = dict_fun(d2y_Zeps) self.d2y[eps,Z] = lambda z_i : self.d2y[Z,eps].transpose(0,2,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 compute_d2y_ZZ(self): ''' Copute the second derivative of y with respect to Z ''' D = np.diagonal(self.dZ_Z) DF = self.DF def dy_YZZ(z_i): DFi,df,dy_Z = DF(z_i)[n:],self.df(z_i),self.dy[Z](z_i) A = DFi[:,v].dot(Ivy) B = DFi[:,y] + DFi[:,e].dot(df) C = DFi[:,Y] + mdot(DFi[:,v],Ivy,dy_Z,IZYhat) #DFi[:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat) return quadratic_solve([D,D],A,B,C) dy_YZZ = dict_fun(dy_YZZ) 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) d2y_ZZ = dict_fun(d2y_ZZ) 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]: HGx1 = HG[:,x1,:] for x2 in [y,z,Y,Z]: HGhat += quadratic_dot(HGx1[:,:,x2],d[x1,y1],d[x2,y2]) return HGhat HGhat_ZZ = dict_fun(lambda z_i : HGhat(z_i,Z,Z)) temp1 =self.integrate(lambda z_i : np.einsum('ij...,j...->i...',self.DG(z_i)[nG:,y],dy_YZZ(z_i)) + self.DG(z_i)[nG:,Y,np.newaxis,np.newaxis]) temp2 = self.integrate(lambda z_i : np.einsum('ij,jkl',self.DG(z_i)[nG:,y],d2y_ZZ(z_i)) + HGhat_ZZ(z_i)) self.d2Y[Z,Z] = quadratic_solve2(temp1,temp2) self.d2y[Z,Z] = dict_fun(lambda z_i: d2y_ZZ(z_i) + np.einsum('ijkl,jkl->ikl',dy_YZZ(z_i),self.d2Y[Z,Z]) ) #d2y_ZS 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 d2y_SZ = dict_fun(d2y_SZ) def dy_YSZ(z_i): DFi,df = DF(z_i)[n:],self.df(z_i) temp = DFi[:,Y] + DFi[:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZYhat) dy_YSZ = np.empty((ny,nY,nZ)) for i,rho in enumerate(D): temp2 = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + rho*DFi[:,v].dot(Ivy)) dy_YSZ[:,:,i] = - temp2.dot(temp) return dy_YSZ dy_YSZ = dict_fun(dy_YSZ) HGhat_SZ = dict_fun(lambda z_i : HGhat(z_i,S,Z)) HGhat_YZ = self.integrate(lambda z_i : (HGhat_SZ(z_i) + np.einsum('ij...,j...->i...',self.DG(z_i)[nG:,y],d2y_SZ(z_i)))[:,nz:,:]) HGhat_zZ = lambda z_i : (HGhat_SZ(z_i) + np.einsum('ij...,j...->i...',self.DG(z_i)[nG:,y],d2y_SZ(z_i)))[:,:nz,:] Temp = self.integrate(lambda z_i : np.einsum('ij...,j...->i...',self.DG(z_i)[nG:,y],dy_YSZ(z_i)) + self.DG(z_i)[nG:,Y,np.newaxis]) #Temp2 = self.integrate(lambda z_i : np.tensordot(self.DG(z_i)[nG:,y],d2y_SZ(z_i),1) + HGhat_SZ(z_i)) 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 self.d2Y[z,Z] = dict_fun(d2Y_zZ) self.d2Y[Z,z] = lambda z_i : self.d2Y[z,Z](z_i).transpose(0,2,1) self.d2y[S,Z] = d2y_SZ self.dy[Y,S,Z] = dy_YSZ self.d2y[Z,S] = lambda z_i : d2y_SZ(z_i).transpose(0,2,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) self.d2y[Z,eps] = dict_fun(d2y_Zeps) self.d2y[eps,Z] = lambda z_i : self.d2y[Z,eps].transpose(0,2,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: 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 compute_d2y_ZZ(self): ''' Copute the second derivative of y with respect to Z ''' DF = self.DF def dy_YZZ(z_i): DFi,df = DF(z_i)[n:],self.df(z_i) temp = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + self.dZ_Z[0]**2 * DFi[:,v].dot(Ivy)) return - temp.dot( DFi[:,Y] + DFi[:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY) ) dy_YZZ = dict_fun(dy_YZZ) 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) d2y_ZZ = dict_fun(d2y_ZZ) 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]: HGx1 = HG[:,x1,:] for x2 in [y,z,Y,Z]: HGhat += quadratic_dot(HGx1[:,:,x2],d[x1,y1],d[x2,y2]) return HGhat HGhat_ZZ = dict_fun(lambda z_i : HGhat(z_i,Z,Z)) temp1 = np.linalg.inv(self.integrate(lambda z_i : self.DG(z_i)[nG:,y].dot(dy_YZZ(z_i)) + self.DG(z_i)[nG:,Y])) temp2 = self.integrate(lambda z_i : np.tensordot(self.DG(z_i)[nG:,y],d2y_ZZ(z_i),1) + HGhat_ZZ(z_i)) self.d2Y[Z,Z] = -np.tensordot(temp1,temp2,axes=1) self.d2y[Z,Z] = dict_fun(lambda z_i: d2y_ZZ(z_i) + np.tensordot(dy_YZZ(z_i),self.d2Y[Z,Z],axes=1) ) #d2y_ZS 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) d2y_SZ = dict_fun(d2y_SZ) def dy_YSZ(z_i): DFi,df = DF(z_i)[n:],self.df(z_i) temp = np.linalg.inv(DFi[:,y] + DFi[:,e].dot(df) + self.dZ_Z[0]*DFi[:,v].dot(Ivy)) return - temp.dot(DFi[:,Y] + DFi[:,v].dot(Ivy).dot(self.dy[Z](z_i)).dot(IZY) ) dy_YSZ = dict_fun(dy_YSZ) HGhat_SZ = dict_fun(lambda z_i : HGhat(z_i,S,Z)) HGhat_YZ = self.integrate(lambda z_i : (HGhat_SZ(z_i) + np.tensordot(self.DG(z_i)[nG:,y],d2y_SZ(z_i),1))[:,nz:,:]) HGhat_zZ = lambda z_i : (HGhat_SZ(z_i) + np.tensordot(self.DG(z_i)[nG:,y],d2y_SZ(z_i),1))[:,:nz,:] Temp = self.integrate(lambda z_i : np.einsum('ij...,j...->i...',self.DG(z_i)[nG:,y],dy_YSZ(z_i)) + self.DG(z_i)[nG:,Y]) #Temp2 = self.integrate(lambda z_i : np.tensordot(self.DG(z_i)[nG:,y],d2y_SZ(z_i),1) + HGhat_SZ(z_i)) 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) self.d2Y[z,Z] = dict_fun(d2Y_zZ) self.d2Y[Z,z] = lambda z_i : self.d2Y[z,Z](z_i).transpose(0,2,1) self.d2y[S,Z] = d2y_SZ self.dy[Y,S,Z] = dy_YSZ self.d2y[Z,S] = lambda z_i : d2y_SZ(z_i).transpose(0,2,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) self.d2y[Z,eps] = dict_fun(d2y_Zeps) self.d2y[eps,Z] = lambda z_i : self.d2y[Z,eps].transpose(0,2,1)