def solveWorkingDeaton(solution_next, aXtraGrid, mGrid, EGMVector, par, Util,
                       UtilP, UtilP_inv, TranInc, TranIncWeights):
    choice = 2

    choiceCount = len(solution_next.ChoiceSols)

    # Next-period initial wealth given exogenous aXtraGrid
    # This needs to be made more general like the rest of the code
    mrs_tp1 = par.Rfree * numpy.expand_dims(aXtraGrid,
                                            axis=1) + par.YWork * TranInc.T
    mws_tp1 = par.Rfree * numpy.expand_dims(aXtraGrid,
                                            axis=1) + par.YWork * TranInc.T
    m_tp1s = (mrs_tp1, mws_tp1)

    # Prepare variables for EGM step
    C_tp1s = tuple(solution_next.ChoiceSols[d].CFunc(m_tp1s[d])
                   for d in range(choiceCount))
    Vs = tuple(
        numpy.divide(-1.0, solution_next.ChoiceSols[d].V_TFunc(m_tp1s[d]))
        for d in range(choiceCount))

    # Due to the transformation on V being monotonic increasing, we can just as
    # well use the transformed values to do this discrete envelope step.
    V, ChoiceProb_tp1 = calcLogSumChoiceProbs(numpy.stack(Vs), par.sigma)
    # Calculate the expected marginal utility and expected value function
    PUtilPsum = sum(ChoiceProb_tp1[i, :] * UtilP(C_tp1s[i], i + 1)
                    for i in range(choiceCount))
    EUtilP_tp1 = par.Rfree * numpy.dot(PUtilPsum, TranIncWeights.T)
    EV_tp1 = numpy.squeeze(
        numpy.dot(numpy.expand_dims(V, axis=1), TranIncWeights.T))

    # EGM step
    m_t, C_t, Ev = calcEGMStep(EGMVector, aXtraGrid, EV_tp1, EUtilP_tp1, par,
                               Util, UtilP, UtilP_inv, choice)

    V_T = numpy.divide(-1.0, Util(C_t, choice) + par.DiscFac * Ev)

    # We do the envelope step in transformed value space for accuracy. The values
    # keep their monotonicity under our transformation.
    m_t, C_t, V_T = calcMultilineEnvelope(m_t, C_t, V_T, mGrid)

    # The solution is the working specific consumption function and value function
    # specifying lower_extrap=True for C is easier than explicitly adding a 0,
    # as it'll be linear in the constrained interval anyway.
    CFunc = LinearInterp(m_t, C_t, lower_extrap=True)
    V_TFunc = LinearInterp(m_t, V_T, lower_extrap=True)
    return ChoiceSpecificSolution(m_t, C_t, CFunc, V_T, V_TFunc)
def calcExtraSaves(saveCommon, rs, ws, par, mGrid):
    if saveCommon:
        # To save the pre-discrete choice expected consumption and value function,
        # we need to interpolate onto the same grid between the two. We know that
        # ws.C and ws.V_T are on the ws.m grid, so we use that to interpolate.

        Crs = LinearInterp(rs.m, rs.C)(mGrid)
        V_rs = numpy.divide(-1, LinearInterp(rs.m, rs.V_T)(mGrid))

        Cws = ws.C
        V_ws = numpy.divide(-1, ws.V_T)

        V, P = calcLogSumChoiceProbs(numpy.stack((V_rs, V_ws)), par.sigma)

        C = (P * numpy.stack((Crs, Cws))).sum(axis=0)
    else:
        C, V_T, P = None, None, None
    return C, numpy.divide(-1.0, V), P
Esempio n. 3
0
 def test_noShock3DBoth(self):
     # Test the value functions and policies of the 3D case
     sigma = 0.0
     V, P = interpolation.calcLogSumChoiceProbs(self.Vs3D, sigma)
     self.assertTrue((V == self.Vref3D).all)
     self.assertTrue((P == self.Pref3D).all)
Esempio n. 4
0
# \end{equation}
#
# \begin{equation}
# c_2(m_2) = c_2(m_2|w=w^*(m_2))
# \end{equation}
#
# We now construct these objects.

# %%
# We use HARK's 'calcLogSumchoiceProbs' to compute the optimal
# will decision over our grid of market resources.
# The function also returns the unconditional value function
# Use transformed values since -given sigma=0- magnitudes are unimportant. This
# avoids NaNs at m \approx 0.
vTGrid2, willChoice2 = calcLogSumChoiceProbs(np.stack(
    (vT2_cond_wi(mGrid), vT2_cond_no(mGrid))),
                                             sigma=0)
vGrid2 = vUntransf(vTGrid2)

# Plot the optimal decision rule
plt.plot(mGrid, willChoice2[0])
plt.title('$w^*(m)$')
plt.ylabel('Write will (1) or not (0)')
plt.xlabel('Market resources: m')
plt.show()

# With the decision rule we can get the unconditional consumption function
cGrid2 = (willChoice2 * np.stack(
    (c2_cond_wi(mGrid), c2_cond_no(mGrid)))).sum(axis=0)

vT2 = LinearInterp(mGrid, vTransf(vGrid2), lower_extrap=True)