def house(sol,z_plus,t,par):

    # Prepare
    a = np.repeat(par.grid_a[t],par.Nxi) # Compute a grid for each node for integration - remove

    # Next period states
    m_plus = par.R*a + par.W # Here, not considering housing
    shape = (2,m_plus.size) # One row for each choice of housing

    # Intialize
    v_plus = np.nan+np.zeros(shape)
    c_plus = np.nan+np.zeros(shape)
    marg_u_plus = np.nan+np.zeros(shape)

    for i in range(2): # Range keeping house (i = 1) and selling house (i = 0)
                
        # Choice specific house gain
        gain = (1-i)*par.ph

        # Choice specific value
        v_plus[i,:]=tools.interp_linear_1d(sol.m[t+1,i,par.N_bottom:],sol.v[t+1,i,par.N_bottom:], m_plus + gain)
            
        #Choice specific consumption
        c_plus[i,:] = tools.interp_linear_1d(sol.m[t+1,i,par.N_bottom:],sol.c[t+1,i,par.N_bottom:], m_plus + gain)
            
        # Choice specific Marginal utility
        marg_u_plus[i,:] = marg_util(c_plus[i,:],par)

    # Expected value
    V_plus, prob = logsum(v_plus[0],v_plus[1],par.sigma_eta) # logsum computes the optimal of housing in the next period
    w_raw = V_plus
    avg_marg_u_plus = prob[0,:]*marg_u_plus[0] + prob[1,:]*marg_u_plus[1] #Expected margnal utility dependend on choice probabilities

    return w_raw, avg_marg_u_plus
def retired(sol, z_plus, t, par):
    # Prepare
    w = np.ones((par.Na))
    a = par.grid_a[t, :]
    xi = np.zeros(par.Na)

    # Next period states
    m_plus = par.R * a + par.W * xi

    #value
    w_raw = tools.interp_linear_1d(sol.m[t + 1, z_plus, par.N_bottom:],
                                   sol.v[t + 1, z_plus, par.N_bottom:], m_plus)

    # Consumption
    c_plus = tools.interp_linear_1d(sol.m[t + 1, z_plus, par.N_bottom:],
                                    sol.c[t + 1, z_plus,
                                          par.N_bottom:], m_plus)

    #Marginal utility
    marg_u_plus = marg_util(c_plus, par)

    #Expected average marginal utility
    avg_marg_u_plus = marg_u_plus * w

    return w_raw, avg_marg_u_plus
Exemple #3
0
def value_of_choice(m, c, h, t, sol, par):

    # Next period ressources
    a = np.repeat(m - c, (par.xi.size))
    m_plus = par.R * a + par.W

    # Note: Siden vi laver upper-envelope på både house og no-house, så skal vi indføre et if-statement.
    # Next-period value if you choose no-house today
    if h == 0:
        v_plus0 = tools.interp_linear_1d(sol.m[t + 1, 0, par.N_bottom:],
                                         sol.v[t + 1, 0, par.N_bottom:],
                                         m_plus)  # No house
        v_plus1 = tools.interp_linear_1d(sol.m[t + 1, 1, par.N_bottom:],
                                         sol.v[t + 1, 1, par.N_bottom:],
                                         m_plus - par.ph)  # House
    # Next-period value if you choose house today.
    else:
        v_plus0 = tools.interp_linear_1d(sol.m[t + 1, 0, par.N_bottom:],
                                         sol.v[t + 1, 0, par.N_bottom:],
                                         m_plus + par.ph)  # No house
        v_plus1 = tools.interp_linear_1d(sol.m[t + 1, 1, par.N_bottom:],
                                         sol.v[t + 1, 1,
                                               par.N_bottom:], m_plus)  # House

    V_plus, _ = logsum(v_plus0, v_plus1,
                       par.sigma_eta)  # Find the maximum of v0 and v1

    # This period value
    v = util(c, h, par) + par.beta * V_plus
    return v
def simulate(par, sol):

    # Initialize
    class sim:
        pass

    shape = (par.simT, par.simN)
    sim.m = np.nan + np.zeros(shape)
    sim.c1 = np.nan + np.zeros(shape)
    sim.c2 = np.nan + np.zeros(shape)
    sim.a = np.nan + np.zeros(shape)
    sim.p = np.nan + np.zeros(shape)
    sim.y = np.nan + np.zeros(shape)

    # Shocks
    shocki = np.random.choice(
        par.Nshocks, (par.T, par.simN), replace=True,
        p=par.w)  #draw values between 0 and Nshocks-1, with probability w
    sim.psi = par.psi_vec[shocki]
    sim.xi = par.xi_vec[shocki]

    #check it has a mean of 1
    assert (abs(1 - np.mean(sim.xi)) <
            1e-4), 'The mean is not 1 in the simulation of xi'
    assert (abs(1 - np.mean(sim.psi)) <
            1e-4), 'The mean is not 1 in the simulation of psi'

    # Initial values
    sim.m[0, :] = par.sim_mini
    sim.p[0, :] = 0.0

    # Simulation
    for t in range(par.simT):
        sim.c1[t, :] = tools.interp_linear_1d(sol.m[t, :], sol.c1[t, :],
                                              sim.m[t, :])
        sim.c2[t, :] = tools.interp_linear_1d(sol.m[t, :], sol.c2[t, :],
                                              sim.m[t, :])
        sim.a[t, :] = sim.m[t, :] - sim.c1[t, :] - sim.c2[t, :]

        if t < par.simT - 1:
            if t + 1 > par.Tr:  #after pension
                sim.m[t + 1, :] = par.R * sim.a[t, :] / (par.G) + 1
                sim.p[t + 1, :] = np.log(par.G) + sim.p[t, :]
                sim.y[t + 1, :] = sim.p[t + 1, :]
            else:  #before pension
                sim.m[t + 1, :] = par.R * sim.a[t, :] / (
                    par.G * sim.psi[t + 1, :]) + sim.xi[t + 1, :]
                sim.p[t + 1, :] = np.log(par.G) + sim.p[t, :] + np.log(
                    sim.psi[t + 1, :])
                sim.y[t + 1, :] = sim.p[t + 1, :] + np.log(sim.xi[t + 1, :])

    #Renormalize
    sim.P = sim.p
    sim.Y = sim.y
    sim.M = sim.m * sim.P
    sim.C1 = sim.c1 * sim.P
    sim.C2 = sim.c2 * sim.P
    sim.A = sim.a * sim.P
    return sim
Exemple #5
0
    def simulate (self):

        par = self.par
        sol = self.sol
        sim = self.sim

        # Initialize
        shape = (par.simT, par.simN)
        sim.m = np.nan +np.zeros(shape)
        sim.c = np.nan +np.zeros(shape)
        sim.a = np.nan +np.zeros(shape)
        sim.p = np.nan +np.zeros(shape)
        sim.y = np.nan +np.zeros(shape)

        # Shocks
        shocki = np.random.choice(par.Nshocks,(par.T,par.simN),replace=True,p=par.w) #draw values between 0 and Nshocks-1, with probability w
        sim.psi = par.psi_vec[shocki]
        sim.xi = par.xi_vec[shocki]

            #check it has a mean of 1
        assert (abs(1-np.mean(sim.xi)) < 1e-4), 'The mean is not 1 in the simulation of xi'
        assert (abs(1-np.mean(sim.psi)) < 1e-4), 'The mean is not 1 in the simulation of psi'

        # Initial values
        sim.m[0,:] = par.sim_mini
        sim.p[0,:] = 0.0

        # Simulation 
        for t in range(par.simT):
            if par.simlifecycle == 0:
                sim.c[t,:] = tools.interp_linear_1d(sol.m[0,:],sol.c[0,:], sim.m[t,:])
            else:
                sim.c[t,:] = tools.interp_linear_1d(sol.m[t,:],sol.c[t,:], sim.m[t,:])
            
            sim.a[t,:] = sim.m[t,:] - sim.c[t,:]

            if t< par.simT-1:
                if t+1 > par.Tr: #after pension
                    sim.m[t+1,:] = par.R*sim.a[t,:]/(par.G*par.L[t])+1
                    sim.p[t+1,:] = np.log(par.G)+np.log(par.L[t])+sim.p[t,:]
                    sim.y[t+1,:] = sim.p[t+1,:]
                else:       #before pension
                    sim.m[t+1,:] = par.R*sim.a[t,:]/(par.G*par.L[t]*sim.psi[t+1,:])+sim.xi[t+1,:]
                    sim.p[t+1,:] = np.log(par.G)+np.log(par.L[t])+sim.p[t,:]+np.log(sim.psi[t+1,:])
                    sim.y[t+1,:] = sim.p[t+1,:]+np.log(sim.xi[t+1,:])
        
        #Renormalize 
        sim.P = np.exp(sim.p)
        sim.Y = np.exp(sim.y)
        sim.M = sim.m*sim.P
        sim.C = sim.c*sim.P
        sim.A = sim.a*sim.P
def value_of_choice(m,c,h,t,sol,par):

    # Next period ressources
    a = np.repeat(m-c,(par.xi.size))
    m_plus = par.R * a + par.W

    # Next-period value
    v_plus0 = tools.interp_linear_1d(sol.m[t+1,0,par.N_bottom:],sol.v[t+1,0,par.N_bottom:], m_plus)
    v_plus1 = tools.interp_linear_1d(sol.m[t+1,1,par.N_bottom:],sol.v[t+1,1,par.N_bottom:], m_plus)
    V_plus, _ = logsum(v_plus0,v_plus1,par.sigma_eta) # Find the maximum of v0 and v1

    # This period value
    v = util(c,h,par) + par.beta*V_plus
    return v
def EGM_vec(sol, t, par):

    if t + 1 <= par.Tr:
        fac = np.tile(par.G * par.L[t] * par.psi_vec, par.Na)
        xi = np.tile(par.xi_vec, par.Na)
        a = np.repeat(par.grid_a[t], par.Nshocks)

        w = np.tile(par.w, (par.Na, 1))
        dim = par.Nshocks
    else:
        fac = par.G * par.L[t] * np.ones((par.Na))
        xi = np.ones((par.Na))
        a = par.grid_a[t, :]

        w = np.ones((par.Na, 1))
        dim = 1

    inv_fac = 1 / fac

    # Futute m and c
    m_plus = inv_fac * par.R * a + xi
    c_plus = tools.interp_linear_1d(sol.m[t + 1, :], sol.c[t + 1, :], m_plus)

    # Future marginal utility
    marg_u_plus = marg_util(fac * c_plus, par)
    marg_u_plus = np.reshape(marg_u_plus, (par.Na, dim))
    avg_marg_u_plus = np.sum(w * marg_u_plus, 1)

    # Currect C and m
    sol.c[t, 1:] = inv_marg_util(par.beta * par.R * avg_marg_u_plus, par)
    sol.m[t, 1:] = par.grid_a[t, :] + sol.c[t, 1:]

    return sol
def EGM_loop(sol, t, par):
    for i_a, a in enumerate(par.grid_a[t, :]):

        if t + 1 <= par.Tr:  # No pension in the next period
            fac = par.G * par.L[t] * par.psi_vec
            w = par.w
            xi = par.xi_vec
            inv_fac = 1 / fac

            # Futute m and c
            m_plus = inv_fac * par.R * a + xi
            c_plus = tools.interp_linear_1d(sol.m[t + 1, :], sol.c[t + 1, :],
                                            m_plus)
        else:
            fac = par.G * par.L[t]
            w = 1
            xi = 1
            inv_fac = 1 / fac

            # Futute m and c
            m_plus = inv_fac * par.R * a + xi
            c_plus = tools.interp_linear_1d_scalar(sol.m[t + 1, :],
                                                   sol.c[t + 1, :], m_plus)

        # Future marginal utility
        marg_u_plus = marg_util(fac * c_plus, par)
        avg_marg_u_plus = np.sum(w * marg_u_plus)

        # Currect C and m
        sol.c[t, i_a + 1] = inv_marg_util(par.beta * par.R * avg_marg_u_plus,
                                          par)
        sol.m[t, i_a + 1] = a + sol.c[t, i_a + 1]

    return sol
Exemple #9
0
def log_likelihood(theta, model, est_par, data):

    #Update parameters
    par = model.par
    sol = model.sol

    par = updatepar(par, est_par, theta)

    # Solve the model
    model.create_grids()
    model.solve()

    # Predict consumption
    t = data.t
    c_predict = tools.interp_linear_1d(sol.m[t, :], sol.c[t, :], data.m)
    C_predict = c_predict * data.P  #Renormalize

    # Calculate errors
    error = data.logC - np.log(C_predict)

    # Calculate log-likelihood
    log_lik_vec = -0.5 * np.log(2 * np.pi * par.sigma_eta**2)
    log_lik_vec += (-(error**2) / (2 * par.sigma_eta**2))

    return np.mean(log_lik_vec)
Exemple #10
0
def solve(sol, par, c_next, m_next):

    # Copy last iteration of the value function
    v_old = sol.v.copy()

    # Expand exogenous asset grid
    a = np.tile(par.grid_a, np.size(par.y))  # 2d end-of-period asset grid

    # m_plus = (1+par.r)

    # Loop over exogneous states (post decision states)
    for a_i, a in enumerate(par.grid_a):

        #Next periods assets and consumption
        m_plus = (1 + par.r) * a + np.transpose(
            par.y)  # Transpose for dimension to fit

        # Interpolate next periods consumption - can this be combined?
        c_plus_1 = tools.interp_linear_1d(m_next[0, :], c_next[0, :],
                                          m_plus)  # State 1
        c_plus_2 = tools.interp_linear_1d(m_next[1, :], c_next[1, :],
                                          m_plus)  # State 2

        #Combine into a vector. Rows indicate income state, columns indicate asset state
        c_plus = np.vstack((c_plus_1, c_plus_2))

        # Marginal utility
        marg_u_plus = util.marg_u(c_plus, par)
        # Compute expectation below
        av_marg_u_plus = np.array([
            par.P[0, 0] * marg_u_plus[0, 0] + par.P[0, 1] * marg_u_plus[1, 1],
            par.P[1, 1] * marg_u_plus[1, 1] + par.P[1, 0] * marg_u_plus[0, 0]
        ])
        # Add optimal consumption and endogenous state
        sol.c[:, a_i + 1] = util.inv_marg_u(
            (1 + par.r) * par.beta * av_marg_u_plus, par)
        sol.m[:, a_i + 1] = a + sol.c[:, a_i + 1]
        sol.v = util.u(sol.c, par)

    #Compute value function and update iteration parameters
    sol.delta = max(max(abs(sol.v[0] - v_old[0])),
                    max(abs(sol.v[1] - v_old[1])))
    sol.it += 1

    # sol.delta = max( max(abs(sol.c[0] - c_next[0])), max(abs(sol.c[1] - c_next[1])))

    return sol
Exemple #11
0
def solve_EGM(par):

    # Initialize solution class
    class sol:
        pass

    # Initial guess is like a 'last period' choice - consume everything
    # **** Jeg tænker ikke, at vi behøver at kalde linspace-funktionen nedenunder igen, da vi jo allerede har oprettet griddet i
    # model.py klassen. Måske kan man bare slette linjen nedenunder, og erstatte
    # "sol.c = sol.a.copy()" med "sol.c = par.grid_a.copy()"
    sol.a = np.linspace(
        par.a_min, par.a_max,
        par.num_a)  # a is pre descision, so for any state consume everything
    sol.c = sol.a.copy()  # Consume everyting - this could be improved

    sol.it = 0  # Iteration counter
    sol.delta = 1000.0  # Difference between iterations

    # Iterate value function until convergence or break if no convergence
    while (sol.delta >= par.tol_egm and sol.it < par.max_iter):

        # Use last iteration to compute the continuation value
        # therefore, copy c and a grid from last iteration.
        c_next = sol.c.copy()
        a_next = sol.a.copy()
        # Loop over exogneous states (post decision states)
        for a_i, s in enumerate(par.grid_s):

            #Next periods assets and consumption
            m_plus = (1 +
                      par.r) * s + par.y  # post decision state. Note vector
            c_plus = tools.interp_linear_1d(a_next, c_next, m_plus)

            # Marginal utility of next periods consumption
            marg_u_plus = util.marg_u(c_plus, par)
            av_marg_u_plus = np.sum(
                par.Pi *
                marg_u_plus)  # Compute expected utility in next period

            # Optimal c in current period from inverted euler
            # +1 in indexation as we add zero consumption afterwards
            sol.c[a_i + 1] = util.inv_marg_u(
                (1 + par.r) * par.beta * av_marg_u_plus, par)
            sol.a[a_i + 1] = s + sol.c[a_i + 1]  # Endogenous state

        # add zero consumption
        sol.a[0] = 0
        sol.c[0] = 0

        # Update iteration parameters
        sol.it += 1
        sol.delta = max(abs(sol.c - c_next))

        # Uncomment for debugging
        # sol.test = abs(sol.c - c_next)

    return sol
def value_of_choice(m, c, L, t, sol, par):

    xi_w_mat = np.tile(par.xi_w, (c.size, 1))
    xi_mat = np.tile(par.xi, (c.size))

    # Next period ressources
    a = np.repeat(m - c, (par.xi.size))
    m_plus = par.R * a + par.W * xi_mat

    # Next-period value
    v_plus0 = tools.interp_linear_1d(sol.m[t + 1, 0, par.N_bottom:],
                                     sol.v[t + 1, 0, par.N_bottom:], m_plus)
    v_plus1 = tools.interp_linear_1d(sol.m[t + 1, 1, par.N_bottom:],
                                     sol.v[t + 1, 1, par.N_bottom:], m_plus)
    V_plus, _ = logsum(v_plus0, v_plus1, par.sigma_eta)
    V_plus = np.reshape(V_plus, (c.size, par.xi_w.size))
    V_plus = np.sum(xi_w_mat * V_plus, 1)

    # This period value
    v = util(c, L, par) + par.beta * V_plus
    return v
def working(sol, z_plus, t, par):
    # Prepare
    xi = np.tile(par.xi, par.Na)
    a = np.repeat(par.grid_a[t], par.Nxi)
    w = np.tile(par.xi_w, (par.Na, 1))

    # Next period states
    m_plus = par.R * a + par.W * xi

    shape = (2, m_plus.size)
    v_plus = np.nan + np.zeros(shape)
    c_plus = np.nan + np.zeros(shape)
    marg_u_plus = np.nan + np.zeros(shape)

    for i in range(2):  #Range over working and not working next period
        # Choice specific value
        v_plus[i, :] = tools.interp_linear_1d(sol.m[t + 1, i, par.N_bottom:],
                                              sol.v[t + 1, i,
                                                    par.N_bottom:], m_plus)

        #Choice specific consumption
        c_plus[i, :] = tools.interp_linear_1d(sol.m[t + 1, i, par.N_bottom:],
                                              sol.c[t + 1, i,
                                                    par.N_bottom:], m_plus)

        # Choice specific Marginal utility
        marg_u_plus[i, :] = marg_util(c_plus[i, :], par)

    # Expected value
    V_plus, prob = logsum(v_plus[0], v_plus[1], par.sigma_eta)
    w_raw = w * np.reshape(V_plus, (par.Na, par.Nxi))
    w_raw = np.sum(w_raw, 1)
    marg_u_plus = prob[0, :] * marg_u_plus[0] + prob[1, :] * marg_u_plus[1]

    #Expected  average marg. utility
    avg_marg_u_plus = w * np.reshape(marg_u_plus, (par.Na, par.Nxi))
    avg_marg_u_plus = np.sum(avg_marg_u_plus, 1)

    return w_raw, avg_marg_u_plus
Exemple #14
0
def no_house(sol, z_plus, t, par):

    # Prepare
    a = np.repeat(par.grid_a[t], par.Nxi)

    # Next period states
    m_plus = par.R * a + par.W

    shape = (2, m_plus.size)
    v_plus = np.nan + np.zeros(shape)
    c_plus = np.nan + np.zeros(shape)
    marg_u_plus = np.nan + np.zeros(shape)

    for i in range(2):  # Range over buying house (i = 1) and no house (i = 0)

        # Choice specific cost of the house
        cost = i * par.ph

        # Choice specific value
        v_plus[i, :] = tools.interp_linear_1d(sol.m[t + 1, i, par.N_bottom:],
                                              sol.v[t + 1, i, par.N_bottom:],
                                              m_plus - cost)

        #Choice specific consumption
        c_plus[i, :] = tools.interp_linear_1d(sol.m[t + 1, i, par.N_bottom:],
                                              sol.c[t + 1, i, par.N_bottom:],
                                              m_plus - cost)

        # Choice specific Marginal utility
        marg_u_plus[i, :] = marg_util(c_plus[i, :], par)

    # Expected value
    V_plus, prob = logsum(v_plus[0], v_plus[1], par.sigma_eta)
    w_raw = V_plus
    avg_marg_u_plus = prob[0, :] * marg_u_plus[0] + prob[1, :] * marg_u_plus[
        1]  #Expected margnal utility dependend on choice probabilities

    return w_raw, avg_marg_u_plus
Exemple #15
0
def EGM (sol,t,par):
    for i_a,a in enumerate(par.grid_a[t,:]):

        if t+1<= par.Tr: # No pension in the next period
            fac = par.G*par.psi_vec
            w = par.w
            xi = par.xi_vec
            inv_fac = 1/fac

            # Future m and c
            m_plus = inv_fac*par.R*a+xi
            c1_plus = tools.interp_linear_1d(sol.m[t+1,:],sol.c1[t+1,:], m_plus) 
            c2_plus = tools.interp_linear_1d(sol.m[t+1,:],sol.c2[t+1,:], m_plus)
        else:
            fac = par.G
            w = 1
            xi = 1
            inv_fac = 1/fac

            # Future m and c
            m_plus = inv_fac*par.R*a+xi
            c1_plus = tools.interp_linear_1d_scalar(sol.m[t+1,:],sol.c1[t+1,:], m_plus)
            c2_plus = tools.interp_linear_1d_scalar(sol.m[t+1,:],sol.c2[t+1,:], m_plus)

        # Future marginal utility
        marg_u_plus1 = marg_util_c1(fac*c1_plus,par)
        marg_u_plus2 = marg_util_c2(fac*c2_plus,par)
        avg_marg_u_plus1 = np.sum(w*marg_u_plus1)
        avg_marg_u_plus2 = np.sum(w*marg_u_plus2)

        # Current C and m
        sol.c1[t,i_a+1]=inv_marg_util(par.beta*par.R*avg_marg_u_plus1,par)
        sol.c2[t,i_a+1]=inv_marg_util(par.beta*par.R*avg_marg_u_plus2,par)
        sol.m[t,i_a+1]=a+sol.c1[t,i_a+1]+sol.c2[t,i_a+1]

    return sol
Exemple #16
0
    #      break

    V_stacked = z + Vstar_stacked  # calculate value function
    V = np.hstack([V_stacked[:I], V_stacked[I:2 * I]])

    Vchange = V - v
    v = V

    delta = np.max(np.absolute(Vchange[:, :]))

    it += 1

######################
## Measure accuracy ##
######################

# Unpack true policy
c_true = c[5:-5, :].copy()
m_true = a[5:-5].copy()

# Interpolate on 'true' grid
c_interp_1 = tools.interp_linear_1d(sol_m, sol_c[:, 0], m_true)
c_interp_2 = tools.interp_linear_1d(sol_m, sol_c[:, 1], m_true)

error_1 = 100 * 1 / 2 * 1 / 6000 * np.sum(
    np.abs(c_interp_1 - c_true[:, 0]) / c_true[:, 0])
error_2 = 100 * 1 / 2 * 1 / 6000 * np.sum(
    np.abs(c_interp_2 - c_true[:, 1]) / c_true[:, 1])
error = error_1 + error_2
print(error)
Exemple #17
0
def solve_EGM_2d(par):

    # Initialize solution class
    class sol:
        pass

    # Shape parameter for the solution vector
    shape = (np.size(par.y), 1)

    # Initial guess is like a 'last period' choice - consume everything
    sol.a = np.tile(
        np.linspace(par.a_min, par.a_max, par.num_a + 1),
        shape)  # a is pre descision, so for any state consume everything.
    sol.c = sol.a.copy()  # Consume everyting - this could be improved

    sol.it = 0  # Iteration counter
    sol.delta = 1000.0  # Difference between iterations

    # Iterate value function until convergence or break if no convergence
    while (sol.delta >= par.tol_egm and sol.it < par.max_iter):

        # Use last iteration to compute the continuation value
        # therefore, copy c and a grid from last iteration.
        c_next = sol.c.copy()
        a_next = sol.a.copy()

        # Loop over exogneous states (post decision states)
        for a_i, s in enumerate(par.grid_s):

            #Next periods assets and consumption
            m_plus = (1 + par.r) * s + np.transpose(
                par.y)  # Transpose for dimension to fit

            # Interpolate next periods consumption - can this be combined?
            c_plus_1 = tools.interp_linear_1d(a_next[0, :], c_next[0, :],
                                              m_plus)  # State 1
            c_plus_2 = tools.interp_linear_1d(a_next[1, :], c_next[1, :],
                                              m_plus)  # State 2

            #Combine into a vector. Rows indicate income state, columns indicate asset state
            c_plus = np.vstack((c_plus_1, c_plus_2))

            # Marginal utility
            marg_u_plus = util.marg_u(c_plus, par)
            av_marg_u_plus = np.sum(par.P * marg_u_plus,
                                    axis=1)  # Dot product by row (axis = 1)

            # Add optimal consumption and endogenous state
            sol.c[:, a_i + 1] = util.inv_marg_u(
                (1 + par.r) * par.beta * av_marg_u_plus, par)
            sol.a[:, a_i + 1] = s + sol.c[:, a_i + 1]

        # Update iteration parameters
        sol.it += 1
        sol.delta = max(max(abs(sol.c[0] - c_next[0])),
                        max(abs(sol.c[1] -
                                c_next[1])))  # check this, is this optimal

    # add zero consumption
    sol.a[:, 0] = 0
    sol.c[:, 0] = 0

    return sol
Exemple #18
0
def solve(sol, par, c_next, m_next):

    # Copy last iteration of the value function
    v_old = sol.v.copy()

    # Expand exogenous asset grid
    a = np.tile(par.grid_a, np.size(par.y))  # does this work?

    m_plus = (1 + par.r)

    # Loop over exogneous states (post decision states)
    for a_i, a in enumerate(par.grid_a):

        #Next periods assets and consumption
        m_plus = (1 + par.r) * a + np.transpose(
            par.y)  # Transpose for dimension to fit

        # Interpolate next periods consumption - can this be combined?
        c_plus_1 = tools.interp_linear_1d(m_next[0, :], c_next[0, :],
                                          m_plus)  # State 1
        c_plus_2 = tools.interp_linear_1d(m_next[1, :], c_next[1, :],
                                          m_plus)  # State 2

        #Combine into a vector. Rows indicate income state, columns indicate asset state
        c_plus = np.vstack((c_plus_1, c_plus_2))

        # Marginal utility
        marg_u_plus = util.marg_u(c_plus, par)
        av_marg_u_plus = np.sum(par.P * marg_u_plus,
                                axis=1)  # Dot product by row (axis = 1)

        # Add optimal consumption and endogenous state
        sol.c[:, a_i + 1] = util.inv_marg_u(
            (1 + par.r) * par.beta * av_marg_u_plus, par)
        sol.m[:, a_i + 1] = a + sol.c[:, a_i + 1]
        sol.v = util.u(sol.c, par)

    #Compute valu function and update iteration parameters
    sol.delta = max(max(abs(sol.v[0] - v_old[0])),
                    max(abs(sol.v[1] - v_old[1])))
    sol.it += 1

    # sol.delta = max( max(abs(sol.c[0] - c_next[0])), max(abs(sol.c[1] - c_next[1])))

    return sol

    ## Attempt at vectorizing the code
    # def solve_vec(sol, par, c_next, m_next):

    #     # Copy last iteration of the value function
    #     v_old = sol.v.copy()

    #     # Expand exogenous asset grid
    #     shape = (np.size(par.y),1)

    #     a = np.tile(par.grid_a, shape) # does this work?

    #     y_help = np.array([par.y])
    #     y_help = np.transpose(y_help)
    #     y = np.tile(y_help, (1,par.Na))

    #     m_plus = (1+par.r)*a + y
    #     # m_plus = (1+par.r)*a + np.transpose(par.y)

    #     # Interpolate next periods consumption
    #     c_plus_1 = tools.interp_linear_1d(m_next[0,:], c_next[0,:], m_plus[0,:]) # State 1
    #     c_plus_2 = tools.interp_linear_1d(m_next[1,:], c_next[1,:], m_plus[1,:]) # State 2

    #     #Combine into a vector. Rows indicate income state, columns indicate asset state
    #     c_plus = np.vstack((c_plus_1, c_plus_2))

    #     # Marginal utility
    #     marg_u_plus = util.marg_u(c_plus,par)
    #     av_marg_u_plus = np.sum(par.P*marg_u_plus)

    #     av_marg_u_plus = np.sum(par.P*marg_u_plus, axis = 1) # Dot product by row (axis = 1)

    #     # Add optimal consumption and endogenous state
    #     sol.c = util.inv_marg_u((1+par.r)*par.beta*av_marg_u_plus,par)
    #     sol.m = a + sol.c[:,a_i+1]
    #     sol.v = util.u(sol.c,par)

    # Loop over exogneous states (post decision states)
    for a_i, a in enumerate(par.grid_a):

        #Next periods assets and consumption
        m_plus = (1 + par.r) * a + np.transpose(
            par.y)  # Transpose for dimension to fit

        # Interpolate next periods consumption - can this be combined?
        c_plus_1 = tools.interp_linear_1d(m_next[0, :], c_next[0, :],
                                          m_plus)  # State 1
        c_plus_2 = tools.interp_linear_1d(m_next[1, :], c_next[1, :],
                                          m_plus)  # State 2

        #Combine into a vector. Rows indicate income state, columns indicate asset state
        c_plus = np.vstack((c_plus_1, c_plus_2))

        # Marginal utility
        marg_u_plus = util.marg_u(c_plus, par)
        av_marg_u_plus = np.sum(par.P * marg_u_plus,
                                axis=1)  # Dot product by row (axis = 1)

        # Add optimal consumption and endogenous state
        sol.c[:, a_i + 1] = util.inv_marg_u(
            (1 + par.r) * par.beta * av_marg_u_plus, par)
        sol.m[:, a_i + 1] = a + sol.c[:, a_i + 1]
        sol.v = util.u(sol.c, par)

    #Compute valu function and update iteration parameters
    sol.delta = max(max(abs(sol.v[0] - v_old[0])),
                    max(abs(sol.v[1] - v_old[1])))
    sol.it += 1

    # sol.delta = max( max(abs(sol.c[0] - c_next[0])), max(abs(sol.c[1] - c_next[1])))

    return sol