Пример #1
0
    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)))
Пример #2
0
    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_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_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)
Пример #7
0
 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)
Пример #9
0
 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)
Пример #10
0
    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)
Пример #11
0
 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()
Пример #12
0
 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)
Пример #14
0
 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()
Пример #16
0
    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()
Пример #17
0
 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)
Пример #18
0
 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()
Пример #19
0
 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()
Пример #21
0
 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)))
Пример #22
0
 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)
Пример #24
0
 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)
     )
Пример #26
0
 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)
     )
Пример #28
0
 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)
Пример #29
0
 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 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)
Пример #32
0
 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)
Пример #33
0
    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()
Пример #34
0
    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)
Пример #37
0
    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)