Example #1
0
 def update(self):
     '''
     Use primitive parameters to set basic objects.  This is an extremely stripped-down version
     of update for CobbDouglasEconomy.
     
     Parameters
     ----------
     none
         
     Returns
     -------
     none
     '''
     self.kSS = 1.0
     self.MSS = 1.0
     self.KtoLnow_init = self.kSS
     self.Rfunc = ConstantFunction(self.Rfree)
     self.wFunc = ConstantFunction(self.wRte)
     self.RfreeNow_init = self.Rfunc(self.kSS)
     self.wRteNow_init = self.wFunc(self.kSS)
     self.MaggNow_init = self.kSS
     self.AaggNow_init = self.kSS
     self.PermShkAggNow_init = 1.0
     self.TranShkAggNow_init = 1.0
     self.TranShkAggDstn = approxMeanOneLognormal(sigma=self.TranShkAggStd,
                                                  N=self.TranShkAggCount)
     self.PermShkAggDstn = approxMeanOneLognormal(sigma=self.PermShkAggStd,
                                                  N=self.PermShkAggCount)
     self.AggShkDstn = combineIndepDstns(self.PermShkAggDstn,
                                         self.TranShkAggDstn)
     self.AFunc = ConstantFunction(1.0)
Example #2
0
    def evalSocialOptimum(self):
        '''
        Execute a simulation run that calculates "socially optimal" objects.
        '''
        self.update()
        self.solve()
        self.CalcSocialOptimum = True
        self.initializeSim()
        self.simulate()
        self.iLvlSocOpt_histX = deepcopy(self.iLvlSocOpt_hist)
        self.CopaySocOpt_histX = deepcopy(self.CopaySocOpt_hist)
        self.LifePriceSocOpt_histX = deepcopy(self.LifePriceSocOpt_hist)
        self.CumLivPrb_histX = deepcopy(self.CumLivPrb_hist)
        self.CalcSocialOptimum = False

        try:
            Health = self.hLvlNow_hist.flatten()
            Weights = self.CumLivPrb_hist.flatten()
            Copays = self.CopaySocOpt_hist.flatten()
            Age = np.tile(
                np.reshape(np.arange(self.T_cycle), (self.T_cycle, 1)),
                (1, self.AgentCount)).flatten()
            AgeSq = Age**2.
            HealthSq = Health**2
            Ones = np.ones_like(Health)
            AgeHealth = Age * Health
            AgeHealthSq = Age * HealthSq
            AgeSqHealth = AgeSq * Health
            AgeSqHealthSq = AgeSq * HealthSq
            these = np.logical_not(np.isnan(Copays))
            regressors = np.transpose(
                np.vstack((Ones, Health, HealthSq, Age, AgeHealth, AgeHealthSq,
                           AgeSq, AgeSqHealth, AgeSqHealthSq)))
            copay_model = WLS(Copays[these],
                              regressors[these, :],
                              weights=Weights[these])
            coeffs = (copay_model.fit()).params

            UpperCopayFunc = ConstantFunction(1.0)
            LowerCopayFunc = ConstantFunction(0.01)
            OptimalCopayInvstFunc = []
            for t in range(self.T_cycle):
                c0 = coeffs[0] + t * coeffs[3] + t**2 * coeffs[6]
                c1 = coeffs[1] + t * coeffs[4] + t**2 * coeffs[7]
                c2 = coeffs[2] + t * coeffs[5] + t**2 * coeffs[8]
                TempFunc = QuadraticFunction(c0, c1, c2)
                OptimalCopayInvstFunc_t = UpperEnvelope(
                    LowerEnvelope(TempFunc, UpperCopayFunc), LowerCopayFunc)
                OptimalCopayInvstFunc.append(OptimalCopayInvstFunc_t)

        except:
            for t in range(self.T_cycle):
                OptimalCopayInvstFunc.append(ConstantFunction(1.0))

        self.OptimalCopayInvstFunc = OptimalCopayInvstFunc
        self.delSolution()
Example #3
0
 def updateInsuranceFuncs(self):
     '''
     Altered version of this method that makes the counterfactuals able to
     handle a subsidy policy that specifies a flat coinsurance rate for investment.
     '''
     EstimationAgentType.updateInsuranceFuncs(self)
     if hasattr(self, 'FlatCopayInvst'):
         self.CopayInvstFunc = self.T_cycle * [
             ConstantFunction(self.FlatCopayInvst)
         ]
         self.SameCopayForMedAndInvst = False
Example #4
0
 def updateSolutionTerminal(self):
     '''
     Updates the terminal period solution for an aggregate shock consumer.
     Only fills in the consumption function and marginal value function.
     
     Parameters
     ----------
     None
         
     Returns
     -------
     None
     '''
     cFunc_terminal = BilinearInterp(np.array([[0.0, 0.0], [1.0, 1.0]]),
                                     np.array([0.0, 1.0]),
                                     np.array([0.0, 1.0]))
     vPfunc_terminal = MargValueFunc2D(cFunc_terminal, self.CRRA)
     mNrmMin_terminal = ConstantFunction(0)
     self.solution_terminal = ConsumerSolution(cFunc=cFunc_terminal,
                                               vPfunc=vPfunc_terminal,
                                               mNrmMin=mNrmMin_terminal)
Example #5
0
def solveConsAggShock(solution_next, IncomeDstn, LivPrb, DiscFac, CRRA,
                      PermGroFac, aXtraGrid, BoroCnstArt, Mgrid, AFunc, Rfunc,
                      wFunc, DeprFac):
    '''
    Solve one period of a consumption-saving problem with idiosyncratic and 
    aggregate shocks (transitory and permanent).  This is a basic solver that
    can't handle borrowing (assumes liquidity constraint) or cubic splines, nor
    can it calculate a value function.
    
    Parameters
    ----------
    solution_next : ConsumerSolution
        The solution to the succeeding one period problem.
    IncomeDstn : [np.array]
        A list containing five arrays of floats, representing a discrete
        approximation to the income process between the period being solved
        and the one immediately following (in solution_next). Order: event
        probabilities, idisyncratic permanent shocks, idiosyncratic transitory
        shocks, aggregate permanent shocks, aggregate transitory shocks.
    LivPrb : float
        Survival probability; likelihood of being alive at the beginning of
        the succeeding period.    
    DiscFac : float
        Intertemporal discount factor for future utility.        
    CRRA : float
        Coefficient of relative risk aversion.
    PermGroGac : float
        Expected permanent income growth factor at the end of this period.
    aXtraGrid : np.array
        Array of "extra" end-of-period asset values-- assets above the
        absolute minimum acceptable level.
    BoroCnstArt : float
        Artificial borrowing constraint; minimum allowable end-of-period asset-to-
        permanent-income ratio.  Unlike other models, this *can't* be None.
    Mgrid : np.array
        A grid of aggregate market resourses to permanent income in the economy.
    AFunc : function
        Aggregate savings as a function of aggregate market resources.
    Rfunc : function
        The net interest factor on assets as a function of capital ratio k.
    wFunc : function
        The wage rate for labor as a function of capital-to-labor ratio k.
    DeprFac : float
        Capital Depreciation Rate
                    
    Returns
    -------
    solution_now : ConsumerSolution
        The solution to the single period consumption-saving problem.  Includes
        a consumption function cFunc (linear interpolation over linear interpola-
        tions) and marginal value function vPfunc.
    '''
    # Unpack next period's solution
    vPfuncNext = solution_next.vPfunc
    mNrmMinNext = solution_next.mNrmMin

    # Unpack the income shocks
    ShkPrbsNext = IncomeDstn[0]
    PermShkValsNext = IncomeDstn[1]
    TranShkValsNext = IncomeDstn[2]
    PermShkAggValsNext = IncomeDstn[3]
    TranShkAggValsNext = IncomeDstn[4]
    ShkCount = ShkPrbsNext.size

    # Make the grid of end-of-period asset values, and a tiled version
    aNrmNow = np.insert(aXtraGrid, 0, 0.0)
    aNrmNow_tiled = np.tile(aNrmNow, (ShkCount, 1))
    aCount = aNrmNow.size

    # Make tiled versions of the income shocks
    ShkPrbsNext_tiled = (np.tile(ShkPrbsNext, (aCount, 1))).transpose()
    PermShkValsNext_tiled = (np.tile(PermShkValsNext, (aCount, 1))).transpose()
    TranShkValsNext_tiled = (np.tile(TranShkValsNext, (aCount, 1))).transpose()
    PermShkAggValsNext_tiled = (np.tile(PermShkAggValsNext,
                                        (aCount, 1))).transpose()
    TranShkAggValsNext_tiled = (np.tile(TranShkAggValsNext,
                                        (aCount, 1))).transpose()

    # Loop through the values in Mgrid and calculate a linear consumption function for each
    cFuncBaseByM_list = []
    BoroCnstNat_array = np.zeros(Mgrid.size)
    mNrmMinNext_array = mNrmMinNext(AFunc(Mgrid) * (1 - DeprFac))
    for j in range(Mgrid.size):
        MNow = Mgrid[j]
        AaggNow = AFunc(MNow)

        # Calculate returns to capital and labor in the next period
        kNext_array = AaggNow * (1 - DeprFac) / (
            PermGroFac * PermShkAggValsNext_tiled * TranShkAggValsNext_tiled)
        kNextEff_array = kNext_array / TranShkAggValsNext_tiled
        R_array = Rfunc(kNextEff_array)  # Interest factor on aggregate assets
        Reff_array = R_array / LivPrb  # Effective interest factor on individual assets *for survivors*
        wEff_array = wFunc(
            kNextEff_array
        ) * TranShkAggValsNext_tiled  # Effective wage rate (accounts for labor supply)
        PermShkTotal_array = PermGroFac * PermShkValsNext_tiled * PermShkAggValsNext_tiled  # total / combined permanent shock
        Mnext_array = kNext_array * (R_array + DeprFac) + wEff_array

        # Find the natural borrowing constraint for this capital-to-labor ratio
        aNrmMin_candidates = PermGroFac * PermShkValsNext * PermShkAggValsNext / Reff_array[:, 0] * (
            mNrmMinNext_array[j] - wEff_array[:, 0] * TranShkValsNext)
        aNrmMin = np.max(aNrmMin_candidates)
        BoroCnstNat = aNrmMin
        BoroCnstNat_array[j] = BoroCnstNat

        # Calculate market resources next period (and a constant array of capital-to-labor ratio)
        mNrmNext_array = Reff_array * (
            aNrmNow_tiled +
            aNrmMin) / PermShkTotal_array + TranShkValsNext_tiled * wEff_array

        # Find marginal value next period at every income shock realization and every aggregate market resource gridpoint
        vPnext_array = Reff_array * PermShkTotal_array**(-CRRA) * vPfuncNext(
            mNrmNext_array, Mnext_array)

        # Calculate expectated marginal value at the end of the period at every asset gridpoint
        EndOfPrdvP = DiscFac * LivPrb * PermGroFac**(-CRRA) * np.sum(
            vPnext_array * ShkPrbsNext_tiled, axis=0)

        # Calculate optimal consumption from each asset gridpoint, and construct a linear interpolation
        cNrmNow = EndOfPrdvP**(-1.0 / CRRA)
        mNrmNow = (aNrmNow + aNrmMin) + cNrmNow
        c_for_interpolation = np.insert(
            cNrmNow, 0, 0.0)  # Add liquidity constrained portion
        m_for_interpolation = np.insert(mNrmNow - BoroCnstNat, 0, 0.0)
        cFuncBase_j = LinearInterp(m_for_interpolation, c_for_interpolation)

        # Add the M-specific consumption function to the list
        cFuncBaseByM_list.append(cFuncBase_j)

    # Construct the overall unconstrained consumption function by combining the M-specific functions
    BoroCnstNat = LinearInterp(np.insert(Mgrid, 0, 0.0),
                               np.insert(BoroCnstNat_array, 0, 0.0))
    cFuncBase = LinearInterpOnInterp1D(cFuncBaseByM_list, Mgrid)
    cFuncUnc = VariableLowerBoundFunc2D(cFuncBase, BoroCnstNat)

    # Make the constrained consumption function and combine it with the unconstrained component
    cFuncCnst = BilinearInterp(np.array([[0.0, 0.0], [1.0, 1.0]]),
                               np.array([BoroCnstArt, BoroCnstArt + 1.0]),
                               np.array([0.0, 1.0]))
    cFuncNow = LowerEnvelope2D(cFuncUnc, cFuncCnst)

    # Make the minimum m function as the greater of the natural and artificial constraints
    mNrmMinNow = UpperEnvelope(BoroCnstNat, ConstantFunction(BoroCnstArt))

    # Construct the marginal value function using the envelope condition
    vPfuncNow = MargValueFunc2D(cFuncNow, CRRA)

    # Pack up and return the solution
    solution_now = ConsumerSolution(cFunc=cFuncNow,
                                    vPfunc=vPfuncNow,
                                    mNrmMin=mNrmMinNow)
    return solution_now