Exemplo n.º 1
0
def find_PFd(A, B, Q, R, Rf, beta=.95):
    """
    Taking the parameters A, B, Q, R as found in the `setup_matrices`,
    we find the value function of the optimal linear regulator problem.
    This is steps 2 and 3 in the lecture notes.
    Parameters
    ----------
    (A, B, Q, R) : Array(Float, ndim=2)
        The matrices that describe the oligopoly problem
    Returns
    -------
    (P, F, d) : Array(Float, ndim=2)
        The matrix that describes the value function of the optimal
        linear regulator problem.
    """

    lq = LQ(Q, -R, A, B, beta=beta)
    P, F, d = lq.stationary_values()

    Af = np.vstack((np.hstack([A-np.dot(B,F), np.array([[0., 0., 0., 0., 0.]]).T]),np.array([[0., 0., 0., 0., 0., 1.]])))
    Bf = np.array([[0., 0., 0., 0., 0., 1.]]).T

    lqf = LQ(Q, -Rf, Af, Bf, beta=beta)
    Pf, Ff, df = lqf.stationary_values()

    return P, F, d, Pf, Ff, df
Exemplo n.º 2
0
    def canonical(self):
        """ 
        Compute canonical preference representation
        Uses auxiliary problem of 9.4.2, with the preference shock process reintroduced
        Calculates pihat, llambdahat and ubhat for the equivalent canonical household technology
        """
        Ac1 = np.hstack((self.deltah,np.zeros((self.nh,self.nz))))
        Ac2 = np.hstack((np.zeros((self.nz,self.nh)),self.a22))
        Ac = np.vstack((Ac1,Ac2))
        Bc = np.vstack((self.thetah,np.zeros((self.nz,self.nc))))
        Cc = np.vstack((np.zeros((self.nh,self.nw)),self.c2))
        Rc1 = np.hstack((self.llambda.T.dot(self.llambda),-self.llambda.T.dot(self.ub)))    
        Rc2 = np.hstack((-self.ub.T.dot(self.llambda),self.ub.T.dot(self.ub)))
        Rc = np.vstack((Rc1,Rc2))
        Qc = self.pih.T.dot(self.pih)
        Nc = np.hstack((self.pih.T.dot(self.llambda),-self.pih.T.dot(self.ub)))
        
        lq_aux = LQ(Qc, Rc, Ac, Bc, N = Nc, beta=self.beta)

        P1, F1, d1 = lq_aux.stationary_values()
        
        self.F_b = F1[:,0:self.nh]
        self.F_f = F1[:,self.nh:]
        
        self.pihat = np.linalg.cholesky(self.pih.T.dot(self.pih) + self.beta.dot(self.thetah.T).dot(P1[0:self.nh,0:self.nh]).dot(self.thetah)).T
        self.llambdahat = self.pihat.dot(self.F_b)
        self.ubhat = - self.pihat.dot(self.F_f)
        
        return 
Exemplo n.º 3
0
    def compute_sequence(self, x0, ts_length=None, Pay=None):
        """ Simulate quantities and prices for our economy """
        lq = LQ(self.Q, self.R, self.A, self.B, self.C, N=self.W, beta=self.beta)
        xp, up, wp = lq.compute_sequence(x0, ts_length)
        self.h = self.Sh.dot(xp)
        self.k = self.Sk.dot(xp)
        self.i = self.Si.dot(xp)
        self.b = self.Sb.dot(xp)
        self.d = self.Sd.dot(xp)
        self.c = self.Sc.dot(xp)
        self.g = self.Sg.dot(xp)
        self.s = self.Ss.dot(xp)

        # === Value of J-period risk-free bonds === #
        # === See p.145: Equation (7.11.2) === #
        e1 = np.zeros((1,self.nc))
        e1[0,0] = 1
        self.R1_Price = np.empty((ts_length+1,1))
        self.R2_Price = np.empty((ts_length+1,1))
        self.R5_Price = np.empty((ts_length+1,1))
        for i in range(ts_length+1):
            self.R1_Price[i,0] = self.beta*e1.dot(self.Mc).dot(np.linalg.matrix_power(self.A0,1)).dot(xp[:,i])/e1.dot(self.Mc).dot(xp[:,i])
            self.R2_Price[i,0] = self.beta**2*e1.dot(self.Mc).dot(np.linalg.matrix_power(self.A0,2)).dot(xp[:,i])/e1.dot(self.Mc).dot(xp[:,i])
            self.R5_Price[i,0] = self.beta**5*e1.dot(self.Mc).dot(np.linalg.matrix_power(self.A0,5)).dot(xp[:,i])/e1.dot(self.Mc).dot(xp[:,i])

        # === Gross rates of return on 1-period risk-free bonds === #
        self.R1_Gross = 1/self.R1_Price

        # === Net rates of return on J-period risk-free bonds === #
        # === See p.148: log of gross rate of return, divided by j === #
        self.R1_Net = np.log(1/self.R1_Price)/1
        self.R2_Net = np.log(1/self.R2_Price)/2
        self.R5_Net = np.log(1/self.R5_Price)/5

        # === Value of asset whose payout vector is Pay*xt === #
        # See p.145: Equation (7.11.1)
        if isinstance(Pay,np.ndarray) == True:
            self.Za = Pay.T.dot(self.Mc)
            self.Q = solve_discrete_lyapunov(self.A0.T*self.beta**0.5,self.Za)
            self.q = self.beta/(1-self.beta)*np.trace(self.C.T.dot(self.Q).dot(self.C))
            self.Pay_Price = np.empty((ts_length+1,1))
            self.Pay_Gross = np.empty((ts_length+1,1))
            self.Pay_Gross[0,0] = np.nan
            for i in range(ts_length+1):
                self.Pay_Price[i,0] = (xp[:,i].T.dot(self.Q).dot(xp[:,i]) + self.q)/e1.dot(self.Mc).dot(xp[:,i])
            for i in range(ts_length):
                self.Pay_Gross[i+1,0] = self.Pay_Price[i+1,0]/(self.Pay_Price[i,0] - Pay.dot(xp[:,i]))
        return
Exemplo n.º 4
0
def find_PFd(A, B, Q, R, Rf, beta=.95):
    """
    Taking the parameters A, B, Q, R as found in the `setup_matrices`,
    we find the value function of the optimal linear regulator problem.
    This is steps 2 and 3 in the lecture notes.
    Parameters
    ----------
    (A, B, Q, R) : Array(Float, ndim=2)
        The matrices that describe the oligopoly problem
    Returns
    -------
    (P, F, d) : Array(Float, ndim=2)
        The matrix that describes the value function of the optimal
        linear regulator problem.
    """

    lq = LQ(Q, -R, A, B, beta=beta)
    P, F, d = lq.stationary_values()

    Af = np.vstack((np.hstack([A-np.dot(B,F), np.array([[0., 0., 0., 0., 0.]]).T]),np.array([[0., 0., 0., 0., 0., 1.]])))
    Bf = np.array([[0., 0., 0., 0., 0., 1.]]).T

    lqf = LQ(Q, -Rf, Af, Bf, beta=beta)
    Pf, Ff, df = lqf.stationary_values()

    return P, F, d, Pf, Ff, df
Exemplo n.º 5
0
def find_PFd(A, B, Q, R, beta=.95):
    """
    Taking the parameters A, B, Q, R as found in the `setup_matrices`,
    we find the value function of the optimal linear regulator problem.
    This is steps 2 and 3 in the lecture notes.

    Parameters
    ----------
    (A, B, Q, R) : Array(Float, ndim=2)
        The matrices that describe the oligopoly problem

    Returns
    -------
    (P, F, d) : Array(Float, ndim=2)
        The matrix that describes the value function of the optimal
        linear regulator problem.

    """

    lq = LQ(Q, -R, A, B, beta=beta)
    P, F, d = lq.stationary_values()

    return P, F, d
Exemplo n.º 6
0
def find_PFd(A, B, Q, R, beta=.95):
    """
    Taking the parameters A, B, Q, R as found in the `setup_matrices`,
    we find the value function of the optimal linear regulator problem.
    This is steps 2 and 3 in the lecture notes.

    Parameters
    ----------
    (A, B, Q, R) : Array(Float, ndim=2)
        The matrices that describe the oligopoly problem

    Returns
    -------
    (P, F, d) : Array(Float, ndim=2)
        The matrix that describes the value function of the optimal
        linear regulator problem.

    """

    lq = LQ(Q, -R, A, B, beta=beta)
    P, F, d = lq.stationary_values()

    return P, F, d
Exemplo n.º 7
0
def computeG(A0, A1, d, Q0, tau0, beta, mu):
    """
    Compute government income given mu and return tax revenues and
    policy matrixes for the planner.

    Parameters
    ----------
    A0 : float
        A constant parameter for the inverse demand function
    A1 : float
        A constant parameter for the inverse demand function
    d : float
        A constant parameter for quadratic adjustment cost of production
    Q0 : float
        An initial condition for production
    tau0 : float
        An initial condition for taxes
    beta : float
        A constant parameter for discounting
    mu : float
        Lagrange multiplier

    Returns
    -------
    T0 : array(float)
        Present discounted value of government spending
    A : array(float)
        One of the transition matrices for the states
    B : array(float)
        Another transition matrix for the states
    F : array(float)
        Policy rule matrix
    P : array(float)
        Value function matrix
    """
    # Create Matrices for solving Ramsey problem
    R = np.array([[0, -A0 / 2, 0, 0], [-A0 / 2, A1 / 2, -mu / 2, 0],
                  [0, -mu / 2, 0, 0], [0, 0, 0, d / 2]])

    A = np.array([[1, 0, 0, 0], [0, 1, 0, 1], [0, 0, 0, 0],
                  [-A0 / d, A1 / d, 0, A1 / d + 1 / beta]])

    B = np.array([0, 0, 1, 1 / d]).reshape(-1, 1)

    Q = 0

    # Use LQ to solve the Ramsey Problem.
    lq = LQ(Q, -R, A, B, beta=beta)
    P, F, d = lq.stationary_values()

    # Need y_0 to compute government tax revenue.
    P21 = P[3, :3]
    P22 = P[3, 3]
    z0 = np.array([1, Q0, tau0]).reshape(-1, 1)
    u0 = -P22**(-1) * P21.dot(z0)
    y0 = np.vstack([z0, u0])

    # Define A_F and S matricies
    AF = A - B.dot(F)
    S = np.array([0, 1, 0, 0]).reshape(-1, 1).dot(np.array([[0, 0, 1, 0]]))

    # Solves equation (25)
    temp = beta * AF.T.dot(S).dot(AF)
    Omega = solve_discrete_lyapunov(np.sqrt(beta) * AF.T, temp)
    T0 = y0.T.dot(Omega).dot(y0)

    return T0, A, B, F, P
Exemplo n.º 8
0
q       = 1e6

# == Formulate as an LQ problem == #
Q = 1
R = np.zeros((2, 2)) 
Rf = np.zeros((2, 2))
Rf[0, 0] = q
A = [[1 + r, -c_bar + mu], 
     [0,     1]]
B = [[-1],
     [0]]
C = [[sigma],
     [0]]

# == Compute solutions and simulate == #
lq = LQ(Q, R, A, B, C, beta=beta, T=T, Rf=Rf)
x0 = (0, 1)
xp, up, wp = lq.compute_sequence(x0)

# == Convert back to assets, consumption and income == #
assets = xp[0, :]           # a_t 
c = up.flatten() + c_bar    # c_t
income = wp[0, 1:] + mu     # y_t

# == Plot results == #
n_rows = 2
fig, axes = plt.subplots(n_rows, 1, figsize=(12, 10))

plt.subplots_adjust(hspace=0.5)
for i in range(n_rows):
    axes[i].grid()
Exemplo n.º 9
0
def computeG(A0, A1, d, Q0, tau0, beta, mu):
    """
    Compute government income given mu and return tax revenues and
    policy matrixes for the planner.  

    Parameters
    ----------
    A0 : float
        A constant parameter for the inverse demand function
    A1 : float
        A constant parameter for the inverse demand function
    d : float
        A constant parameter for quadratic adjustment cost of production
    Q0 : float
        An initial condition for production
    tau0 : float
        An initial condition for taxes
    beta : float
        A constant parameter for discounting
    mu : float
        Lagrange multiplier

    Returns
    -------
    T0 : array(float)
        Present discounted value of government spending
    A : array(float)
        One of the transition matrices for the states
    B : array(float)
        Another transition matrix for the states
    F : array(float)
        Policy rule matrix
    P : array(float)
        Value function matrix
    """
    # Create Matrices for solving Ramsey problem
    R = np.array([[0, -A0/2, 0, 0],
                 [-A0/2, A1/2, -mu/2, 0],
                 [0, -mu/2, 0, 0],
                 [0, 0, 0, d/2]])

    A = np.array([[1, 0, 0, 0],
                 [0, 1, 0, 1],
                 [0, 0, 0, 0],
                 [-A0/d, A1/d, 0, A1/d+1/beta]])

    B = np.array([0, 0, 1, 1/d]).reshape(-1, 1)

    Q = 0

    # Use LQ to solve the Ramsey Problem.
    lq = LQ(Q, -R, A, B, beta=beta)
    P, F, d = lq.stationary_values()

    # Need y_0 to compute government tax revenue.
    P21 = P[3, :3]
    P22 = P[3, 3]
    z0 = np.array([1, Q0, tau0]).reshape(-1, 1)
    u0 = -P22**(-1) * P21.dot(z0)
    y0 = np.vstack([z0, u0])

    # Define A_F and S matricies
    AF = A - B.dot(F)
    S = np.array([0, 1, 0, 0]).reshape(-1, 1).dot(np.array([[0, 0, 1, 0]]))

    # Solves equation (25)
    temp = beta * AF.T.dot(S).dot(AF)
    Omega = solve_discrete_lyapunov(np.sqrt(beta) * AF.T, temp)
    T0 = y0.T.dot(Omega).dot(y0)

    return T0, A, B, F, P
Exemplo n.º 10
0
    def __init__(self, information, technology, preferences):

        # === Unpack the tuples which define information, technology and preferences === #
        self.a22, self.c2, self.ub, self.ud = information
        self.phic, self.phig, self.phii, self.gamma, self.deltak, self.thetak = technology
        self.beta, self.llambda, self.pih, self.deltah, self.thetah = preferences
        
        # === Computation of the dimension of the structural parameter matrices === #
        self.nb,self.nh = self.llambda.shape
        self.nd,self.nc = self.phic.shape
        self.nz,self.nw = self.c2.shape
        junk,self.ng = self.phig.shape
        self.nk,self.ni = self.thetak.shape

        # === Creation of various useful matrices === #
        uc = np.hstack((np.eye(self.nc),np.zeros((self.nc,self.ng))))
        ug = np.hstack((np.zeros((self.ng,self.nc)),np.eye(self.ng)))
        phiin = np.linalg.inv(np.hstack((self.phic,self.phig)))
        phiinc = uc.dot(phiin)
        phiing = ug.dot(phiin)
        b11 = - self.thetah.dot(phiinc).dot(self.phii)
        a1 = self.thetah.dot(phiinc).dot(self.gamma)
        a12 = np.vstack((self.thetah.dot(phiinc).dot(self.ud), np.zeros((self.nk,self.nz))))

        # === Creation of the A Matrix for the state transition of the LQ problem === #

        a11 = np.vstack((np.hstack((self.deltah,a1)), np.hstack((np.zeros((self.nk,self.nh)),self.deltak))))
        self.A = np.vstack((np.hstack((a11,a12)), np.hstack((np.zeros((self.nz,self.nk+self.nh)),self.a22))))

        # === Creation of the B Matrix for the state transition of the LQ problem === #

        b1 = np.vstack((b11,self.thetak))
        self.B = np.vstack((b1,np.zeros((self.nz,self.ni))))

        # === Creation of the C Matrix for the state transition of the LQ problem === #

        self.C = np.vstack((np.zeros((self.nk+self.nh,self.nw)),self.c2))

        # === Define R,W and Q for the payoff function of the LQ problem === #

        self.H = np.hstack((self.llambda,self.pih.dot(uc).dot(phiin).dot(self.gamma),self.pih.dot(uc).dot(phiin).dot(self.ud)-self.ub,-self.pih.dot(uc).dot(phiin).dot(self.phii)))
        self.G = ug.dot(phiin).dot(np.hstack((np.zeros((self.nd,self.nh)),self.gamma,self.ud,-self.phii)))
        self.S = (self.G.T.dot(self.G) + self.H.T.dot(self.H))/2

        self.nx = self.nh+self.nk+self.nz
        self.n = self.ni+self.nh+self.nk+self.nz

        self.R = self.S[0:self.nx,0:self.nx]
        self.W = self.S[self.nx:self.n,0:self.nx]
        self.Q = self.S[self.nx:self.n,self.nx:self.n]

        # === Use quantecon's LQ code to solve our LQ problem === #

        lq = LQ(self.Q, self.R, self.A, self.B, self.C, N=self.W, beta=self.beta)

        self.P, self.F, self.d = lq.stationary_values()

        # === Construct output matrices for our economy using the solution to the LQ problem === #

        self.A0 = self.A - self.B.dot(self.F)

        self.Sh = self.A0[0:self.nh,0:self.nx]
        self.Sk = self.A0[self.nh:self.nh+self.nk,0:self.nx]
        self.Sk1 = np.hstack((np.zeros((self.nk,self.nh)),np.eye(self.nk),np.zeros((self.nk,self.nz))))
        self.Si = -self.F
        self.Sd = np.hstack((np.zeros((self.nd,self.nh+self.nk)),self.ud))
        self.Sb = np.hstack((np.zeros((self.nb,self.nh+self.nk)),self.ub))
        self.Sc = uc.dot(phiin).dot(-self.phii.dot(self.Si) + self.gamma.dot(self.Sk1) + self.Sd)
        self.Sg = ug.dot(phiin).dot(-self.phii.dot(self.Si) + self.gamma.dot(self.Sk1) + self.Sd)
        self.Ss = self.llambda.dot(np.hstack((np.eye(self.nh),np.zeros((self.nh,self.nk+self.nz))))) + self.pih.dot(self.Sc)

        # ===  Calculate eigenvalues of A0 === #
        self.A110 = self.A0[0:self.nh+self.nk,0:self.nh+self.nk]
        self.endo = np.linalg.eigvals(self.A110)
        self.exo = np.linalg.eigvals(self.a22)

        # === Construct matrices for Lagrange Multipliers === #

        self.Mk = -2*np.asscalar(self.beta)*(np.hstack((np.zeros((self.nk,self.nh)),np.eye(self.nk),np.zeros((self.nk,self.nz))))).dot(self.P).dot(self.A0)
        self.Mh = -2*np.asscalar(self.beta)*(np.hstack((np.eye(self.nh),np.zeros((self.nh,self.nk)),np.zeros((self.nh,self.nz))))).dot(self.P).dot(self.A0)
        self.Ms = -(self.Sb - self.Ss)
        self.Md = -(np.linalg.inv(np.vstack((self.phic.T,self.phig.T))).dot(np.vstack((self.thetah.T.dot(self.Mh) + self.pih.T.dot(self.Ms),-self.Sg))))
        self.Mc = -(self.thetah.T.dot(self.Mh) + self.pih.T.dot(self.Ms))
        self.Mi = -(self.thetak.T.dot(self.Mk))